]> git.sur5r.net Git - u-boot/blob - drivers/remoteproc/sandbox_testproc.c
004c7792d186b1c2495930f49bb1393af3f1ad5c
[u-boot] / drivers / remoteproc / sandbox_testproc.c
1 /*
2  * (C) Copyright 2015
3  * Texas Instruments Incorporated - http://www.ti.com/
4  * SPDX-License-Identifier:     GPL-2.0+
5  */
6 #define pr_fmt(fmt) "%s: " fmt, __func__
7 #include <common.h>
8 #include <dm.h>
9 #include <errno.h>
10 #include <remoteproc.h>
11
12 /**
13  * enum sandbox_state - different device states
14  * @sb_booted:  Entry condition, just booted
15  * @sb_init:    Initialized (basic environment is ready)
16  * @sb_reset:   Held in reset (accessible, but not running)
17  * @sb_loaded:  Loaded with image (but not running)
18  * @sb_running: Processor is running
19  */
20 enum sandbox_state {
21         sb_booted,
22         sb_init,
23         sb_reset,
24         sb_loaded,
25         sb_running
26 };
27
28 /**
29  * struct sandbox_test_devdata - private data per device
30  * @current_state:      device current state
31  */
32 struct sandbox_test_devdata {
33         enum sandbox_state current_state;
34 };
35
36 /**
37  * sandbox_dev_move_to_state() - statemachine for our dummy device
38  * @dev:        device to switch state
39  * @next_state: next proposed state
40  *
41  * This tries to follow the following statemachine:
42  *           Entry
43  *            |
44  *            v
45  *         +-------+
46  *     +---+ init  |
47  *     |   |       | <---------------------+
48  *     |   +-------+                       |
49  *     |                                   |
50  *     |                                   |
51  *     |   +--------+                      |
52  * Load|   |  reset |                      |
53  *     |   |        | <----------+         |
54  *     |   +--------+            |         |
55  *     |        |Load            |         |
56  *     |        |                |         |
57  *     |   +----v----+   reset   |         |
58  *     +-> |         |    (opt)  |         |
59  *         |  Loaded +-----------+         |
60  *         |         |                     |
61  *         +----+----+                     |
62  *              | Start                    |
63  *          +---v-----+        (opt)       |
64  *       +->| Running |        Stop        |
65  * Ping  +- |         +--------------------+
66  * (opt)    +---------+
67  *
68  * (is_running does not change state)
69  *
70  * Return: 0 when valid state transition is seen, else returns -EINVAL
71  */
72 static int sandbox_dev_move_to_state(struct udevice *dev,
73                                      enum sandbox_state next_state)
74 {
75         struct sandbox_test_devdata *ddata = dev_get_priv(dev);
76
77         /* No state transition is OK */
78         if (ddata->current_state == next_state)
79                 return 0;
80
81         debug("current_state=%d, next_state=%d\n", ddata->current_state,
82               next_state);
83         switch (ddata->current_state) {
84         case sb_booted:
85                 if (next_state == sb_init)
86                         goto ok_state;
87                 break;
88
89         case sb_init:
90                 if (next_state == sb_reset || next_state == sb_loaded)
91                         goto ok_state;
92                 break;
93
94         case sb_reset:
95                 if (next_state == sb_loaded || next_state == sb_init)
96                         goto ok_state;
97                 break;
98
99         case sb_loaded:
100                 if (next_state == sb_reset || next_state == sb_init ||
101                     next_state == sb_running)
102                         goto ok_state;
103                 break;
104
105         case sb_running:
106                 if (next_state == sb_reset || next_state == sb_init)
107                         goto ok_state;
108                 break;
109         };
110         return -EINVAL;
111
112 ok_state:
113         ddata->current_state = next_state;
114         return 0;
115 }
116
117 /**
118  * sandbox_testproc_probe() - basic probe function
119  * @dev:        test proc device that is being probed.
120  *
121  * Return: 0 if all went ok, else return appropriate error
122  */
123 static int sandbox_testproc_probe(struct udevice *dev)
124 {
125         struct dm_rproc_uclass_pdata *uc_pdata;
126         struct sandbox_test_devdata *ddata;
127         int ret;
128
129         uc_pdata = dev_get_uclass_platdata(dev);
130         ddata = dev_get_priv(dev);
131         if (!ddata) {
132                 debug("%s: platform private data missing\n", uc_pdata->name);
133                 return -EINVAL;
134         }
135         ret = sandbox_dev_move_to_state(dev, sb_booted);
136         debug("%s: called(%d)\n", uc_pdata->name, ret);
137
138         return ret;
139 }
140
141 /**
142  * sandbox_testproc_init() - Simple initialization function
143  * @dev:        device to operate upon
144  *
145  * Return: 0 if all went ok, else return appropriate error
146  */
147 static int sandbox_testproc_init(struct udevice *dev)
148 {
149         struct dm_rproc_uclass_pdata *uc_pdata;
150         int ret;
151
152         uc_pdata = dev_get_uclass_platdata(dev);
153
154         ret = sandbox_dev_move_to_state(dev, sb_init);
155
156         debug("%s: called(%d)\n", uc_pdata->name, ret);
157         if (ret)
158                 debug("%s init failed\n", uc_pdata->name);
159
160         return ret;
161 }
162
163 /**
164  * sandbox_testproc_reset() - Reset the remote processor
165  * @dev:        device to operate upon
166  *
167  * Return: 0 if all went ok, else return appropriate error
168  */
169 static int sandbox_testproc_reset(struct udevice *dev)
170 {
171         struct dm_rproc_uclass_pdata *uc_pdata;
172         int ret;
173
174         uc_pdata = dev_get_uclass_platdata(dev);
175
176         ret = sandbox_dev_move_to_state(dev, sb_reset);
177
178         debug("%s: called(%d)\n", uc_pdata->name, ret);
179
180         if (ret)
181                 debug("%s reset failed\n", uc_pdata->name);
182         return ret;
183 }
184
185 /**
186  * sandbox_testproc_load() - (replace: short desc)
187  * @dev:        device to operate upon
188  * @addr:       Address of the binary image to load
189  * @size:       Size (in bytes) of the binary image to load
190  *
191  * Return: 0 if all went ok, else return appropriate error
192  */
193 static int sandbox_testproc_load(struct udevice *dev, ulong addr, ulong size)
194 {
195         struct dm_rproc_uclass_pdata *uc_pdata;
196         int ret;
197
198         uc_pdata = dev_get_uclass_platdata(dev);
199
200         ret = sandbox_dev_move_to_state(dev, sb_loaded);
201
202         debug("%s: called(%d) Loading to %08lX %lu size\n",
203               uc_pdata->name, ret, addr, size);
204
205         if (ret)
206                 debug("%s load failed\n", uc_pdata->name);
207         return ret;
208 }
209
210 /**
211  * sandbox_testproc_start() - Start the remote processor
212  * @dev:        device to operate upon
213  *
214  * Return: 0 if all went ok, else return appropriate error
215  */
216 static int sandbox_testproc_start(struct udevice *dev)
217 {
218         struct dm_rproc_uclass_pdata *uc_pdata;
219         int ret;
220
221         uc_pdata = dev_get_uclass_platdata(dev);
222
223         ret = sandbox_dev_move_to_state(dev, sb_running);
224
225         debug("%s: called(%d)\n", uc_pdata->name, ret);
226
227         if (ret)
228                 debug("%s start failed\n", uc_pdata->name);
229         return ret;
230 }
231
232 /**
233  * sandbox_testproc_stop() - Stop the remote processor
234  * @dev:        device to operate upon
235  *
236  * Return: 0 if all went ok, else return appropriate error
237  */
238 static int sandbox_testproc_stop(struct udevice *dev)
239 {
240         struct dm_rproc_uclass_pdata *uc_pdata;
241         int ret;
242
243         uc_pdata = dev_get_uclass_platdata(dev);
244
245         ret = sandbox_dev_move_to_state(dev, sb_init);
246
247         debug("%s: called(%d)\n", uc_pdata->name, ret);
248
249         if (ret)
250                 debug("%s stop failed\n", uc_pdata->name);
251         return ret;
252 }
253
254 /**
255  * sandbox_testproc_is_running() - Check if remote processor is running
256  * @dev:        device to operate upon
257  *
258  * Return: 0 if running, 1 if not running
259  */
260 static int sandbox_testproc_is_running(struct udevice *dev)
261 {
262         struct dm_rproc_uclass_pdata *uc_pdata;
263         struct sandbox_test_devdata *ddata;
264         int ret = 1;
265
266         uc_pdata = dev_get_uclass_platdata(dev);
267         ddata = dev_get_priv(dev);
268
269         if (ddata->current_state == sb_running)
270                 ret = 0;
271         debug("%s: called(%d)\n", uc_pdata->name, ret);
272
273         return ret;
274 }
275
276 /**
277  * sandbox_testproc_ping() - Try pinging remote processor
278  * @dev:        device to operate upon
279  *
280  * Return: 0 if running, -EINVAL if not running
281  */
282 static int sandbox_testproc_ping(struct udevice *dev)
283 {
284         struct dm_rproc_uclass_pdata *uc_pdata;
285         struct sandbox_test_devdata *ddata;
286         int ret;
287
288         uc_pdata = dev_get_uclass_platdata(dev);
289         ddata = dev_get_priv(dev);
290
291         if (ddata->current_state == sb_running)
292                 ret = 0;
293         else
294                 ret = -EINVAL;
295
296         debug("%s: called(%d)\n", uc_pdata->name, ret);
297         if (ret)
298                 debug("%s: No response.(Not started?)\n", uc_pdata->name);
299
300         return ret;
301 }
302
303 static const struct dm_rproc_ops sandbox_testproc_ops = {
304         .init = sandbox_testproc_init,
305         .reset = sandbox_testproc_reset,
306         .load = sandbox_testproc_load,
307         .start = sandbox_testproc_start,
308         .stop = sandbox_testproc_stop,
309         .is_running = sandbox_testproc_is_running,
310         .ping = sandbox_testproc_ping,
311 };
312
313 static const struct udevice_id sandbox_ids[] = {
314         {.compatible = "sandbox,test-processor"},
315         {}
316 };
317
318 U_BOOT_DRIVER(sandbox_testproc) = {
319         .name = "sandbox_test_proc",
320         .of_match = sandbox_ids,
321         .id = UCLASS_REMOTEPROC,
322         .ops = &sandbox_testproc_ops,
323         .probe = sandbox_testproc_probe,
324         .priv_auto_alloc_size = sizeof(struct sandbox_test_devdata),
325 };
326
327 /* TODO(nm@ti.com): Remove this along with non-DT support */
328 static struct dm_rproc_uclass_pdata proc_3_test = {
329         .name = "proc_3_legacy",
330         .mem_type = RPROC_INTERNAL_MEMORY_MAPPED,
331 };
332
333 U_BOOT_DEVICE(proc_3_demo) = {
334         .name = "sandbox_test_proc",
335         .platdata = &proc_3_test,
336 };