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