dm: core: Require users of devres to include the header
[oweals/u-boot.git] / drivers / remoteproc / ti_k3_r5f_rproc.c
1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * Texas Instruments' K3 R5 Remoteproc driver
4  *
5  * Copyright (C) 2018-2019 Texas Instruments Incorporated - http://www.ti.com/
6  *      Lokesh Vutla <lokeshvutla@ti.com>
7  */
8
9 #include <common.h>
10 #include <dm.h>
11 #include <remoteproc.h>
12 #include <errno.h>
13 #include <clk.h>
14 #include <reset.h>
15 #include <asm/io.h>
16 #include <linux/err.h>
17 #include <linux/kernel.h>
18 #include <linux/soc/ti/ti_sci_protocol.h>
19 #include "ti_sci_proc.h"
20
21 /*
22  * R5F's view of this address can either be for ATCM or BTCM with the other
23  * at address 0x0 based on loczrama signal.
24  */
25 #define K3_R5_TCM_DEV_ADDR      0x41010000
26
27 /* R5 TI-SCI Processor Configuration Flags */
28 #define PROC_BOOT_CFG_FLAG_R5_DBG_EN                    0x00000001
29 #define PROC_BOOT_CFG_FLAG_R5_DBG_NIDEN                 0x00000002
30 #define PROC_BOOT_CFG_FLAG_R5_LOCKSTEP                  0x00000100
31 #define PROC_BOOT_CFG_FLAG_R5_TEINIT                    0x00000200
32 #define PROC_BOOT_CFG_FLAG_R5_NMFI_EN                   0x00000400
33 #define PROC_BOOT_CFG_FLAG_R5_TCM_RSTBASE               0x00000800
34 #define PROC_BOOT_CFG_FLAG_R5_BTCM_EN                   0x00001000
35 #define PROC_BOOT_CFG_FLAG_R5_ATCM_EN                   0x00002000
36 #define PROC_BOOT_CFG_FLAG_GEN_IGN_BOOTVECTOR           0x10000000
37
38 /* R5 TI-SCI Processor Control Flags */
39 #define PROC_BOOT_CTRL_FLAG_R5_CORE_HALT                0x00000001
40
41 /* R5 TI-SCI Processor Status Flags */
42 #define PROC_BOOT_STATUS_FLAG_R5_WFE                    0x00000001
43 #define PROC_BOOT_STATUS_FLAG_R5_WFI                    0x00000002
44 #define PROC_BOOT_STATUS_FLAG_R5_CLK_GATED              0x00000004
45 #define PROC_BOOT_STATUS_FLAG_R5_LOCKSTEP_PERMITTED     0x00000100
46
47 #define NR_CORES        2
48
49 enum cluster_mode {
50         CLUSTER_MODE_SPLIT = 0,
51         CLUSTER_MODE_LOCKSTEP,
52 };
53
54 /**
55  * struct k3_r5_mem - internal memory structure
56  * @cpu_addr: MPU virtual address of the memory region
57  * @bus_addr: Bus address used to access the memory region
58  * @dev_addr: Device address from remoteproc view
59  * @size: Size of the memory region
60  */
61 struct k3_r5f_mem {
62         void __iomem *cpu_addr;
63         phys_addr_t bus_addr;
64         u32 dev_addr;
65         size_t size;
66 };
67
68 /**
69  * struct k3_r5f_core - K3 R5 core structure
70  * @dev: cached device pointer
71  * @cluster: pointer to the parent cluster.
72  * @reset: reset control handle
73  * @tsp: TI-SCI processor control handle
74  * @mem: Array of available internal memories
75  * @num_mem: Number of available memories
76  * @atcm_enable: flag to control ATCM enablement
77  * @btcm_enable: flag to control BTCM enablement
78  * @loczrama: flag to dictate which TCM is at device address 0x0
79  * @in_use: flag to tell if the core is already in use.
80  */
81 struct k3_r5f_core {
82         struct udevice *dev;
83         struct k3_r5f_cluster *cluster;
84         struct reset_ctl reset;
85         struct ti_sci_proc tsp;
86         struct k3_r5f_mem *mem;
87         int num_mems;
88         u32 atcm_enable;
89         u32 btcm_enable;
90         u32 loczrama;
91         bool in_use;
92 };
93
94 /**
95  * struct k3_r5f_cluster - K3 R5F Cluster structure
96  * @mode: Mode to configure the Cluster - Split or LockStep
97  * @cores: Array of pointers to R5 cores within the cluster
98  */
99 struct k3_r5f_cluster {
100         enum cluster_mode mode;
101         struct k3_r5f_core *cores[NR_CORES];
102 };
103
104 static bool is_primary_core(struct k3_r5f_core *core)
105 {
106         return core == core->cluster->cores[0];
107 }
108
109 static int k3_r5f_proc_request(struct k3_r5f_core *core)
110 {
111         struct k3_r5f_cluster *cluster = core->cluster;
112         int i, ret;
113
114         if (cluster->mode == CLUSTER_MODE_LOCKSTEP) {
115                 for (i = 0; i < NR_CORES; i++) {
116                         ret = ti_sci_proc_request(&cluster->cores[i]->tsp);
117                         if (ret)
118                                 goto proc_release;
119                 }
120         } else {
121                 ret = ti_sci_proc_request(&core->tsp);
122         }
123
124         return 0;
125
126 proc_release:
127         while (i >= 0) {
128                 ti_sci_proc_release(&cluster->cores[i]->tsp);
129                 i--;
130         }
131         return ret;
132 }
133
134 static void k3_r5f_proc_release(struct k3_r5f_core *core)
135 {
136         struct k3_r5f_cluster *cluster = core->cluster;
137         int i;
138
139         if (cluster->mode == CLUSTER_MODE_LOCKSTEP)
140                 for (i = 0; i < NR_CORES; i++)
141                         ti_sci_proc_release(&cluster->cores[i]->tsp);
142         else
143                 ti_sci_proc_release(&core->tsp);
144 }
145
146 static int k3_r5f_lockstep_release(struct k3_r5f_cluster *cluster)
147 {
148         int ret, c;
149
150         dev_dbg(dev, "%s\n", __func__);
151
152         for (c = NR_CORES - 1; c >= 0; c--) {
153                 ret = ti_sci_proc_power_domain_on(&cluster->cores[c]->tsp);
154                 if (ret)
155                         goto unroll_module_reset;
156         }
157
158         /* deassert local reset on all applicable cores */
159         for (c = NR_CORES - 1; c >= 0; c--) {
160                 ret = reset_deassert(&cluster->cores[c]->reset);
161                 if (ret)
162                         goto unroll_local_reset;
163         }
164
165         return 0;
166
167 unroll_local_reset:
168         while (c < NR_CORES) {
169                 reset_assert(&cluster->cores[c]->reset);
170                 c++;
171         }
172         c = 0;
173 unroll_module_reset:
174         while (c < NR_CORES) {
175                 ti_sci_proc_power_domain_off(&cluster->cores[c]->tsp);
176                 c++;
177         }
178
179         return ret;
180 }
181
182 static int k3_r5f_split_release(struct k3_r5f_core *core)
183 {
184         int ret;
185
186         dev_dbg(dev, "%s\n", __func__);
187
188         ret = ti_sci_proc_power_domain_on(&core->tsp);
189         if (ret) {
190                 dev_err(core->dev, "module-reset deassert failed, ret = %d\n",
191                         ret);
192                 return ret;
193         }
194
195         ret = reset_deassert(&core->reset);
196         if (ret) {
197                 dev_err(core->dev, "local-reset deassert failed, ret = %d\n",
198                         ret);
199                 if (ti_sci_proc_power_domain_off(&core->tsp))
200                         dev_warn(core->dev, "module-reset assert back failed\n");
201         }
202
203         return ret;
204 }
205
206 static int k3_r5f_prepare(struct udevice *dev)
207 {
208         struct k3_r5f_core *core = dev_get_priv(dev);
209         struct k3_r5f_cluster *cluster = core->cluster;
210         int ret = 0;
211
212         dev_dbg(dev, "%s\n", __func__);
213
214         if (cluster->mode == CLUSTER_MODE_LOCKSTEP)
215                 ret = k3_r5f_lockstep_release(cluster);
216         else
217                 ret = k3_r5f_split_release(core);
218
219         if (ret)
220                 dev_err(dev, "Unable to enable cores for TCM loading %d\n",
221                         ret);
222
223         return ret;
224 }
225
226 static int k3_r5f_core_sanity_check(struct k3_r5f_core *core)
227 {
228         struct k3_r5f_cluster *cluster = core->cluster;
229
230         if (core->in_use) {
231                 dev_err(dev, "Invalid op: Trying to load/start on already running core %d\n",
232                         core->tsp.proc_id);
233                 return -EINVAL;
234         }
235
236         if (cluster->mode == CLUSTER_MODE_LOCKSTEP && !cluster->cores[1]) {
237                 printf("Secondary core is not probed in this cluster\n");
238                 return -EAGAIN;
239         }
240
241         if (cluster->mode == CLUSTER_MODE_LOCKSTEP && !is_primary_core(core)) {
242                 dev_err(dev, "Invalid op: Trying to start secondary core %d in lockstep mode\n",
243                         core->tsp.proc_id);
244                 return -EINVAL;
245         }
246
247         if (cluster->mode == CLUSTER_MODE_SPLIT && !is_primary_core(core)) {
248                 if (!core->cluster->cores[0]->in_use) {
249                         dev_err(dev, "Invalid seq: Enable primary core before loading secondary core\n");
250                         return -EINVAL;
251                 }
252         }
253
254         return 0;
255 }
256
257 /**
258  * k3_r5f_load() - Load up the Remote processor image
259  * @dev:        rproc device pointer
260  * @addr:       Address at which image is available
261  * @size:       size of the image
262  *
263  * Return: 0 if all goes good, else appropriate error message.
264  */
265 static int k3_r5f_load(struct udevice *dev, ulong addr, ulong size)
266 {
267         struct k3_r5f_core *core = dev_get_priv(dev);
268         u32 boot_vector;
269         int ret;
270
271         dev_dbg(dev, "%s addr = 0x%lx, size = 0x%lx\n", __func__, addr, size);
272
273         ret = k3_r5f_core_sanity_check(core);
274         if (ret)
275                 return ret;
276
277         ret = k3_r5f_proc_request(core);
278         if (ret)
279                 return ret;
280
281         ret = k3_r5f_prepare(dev);
282         if (ret) {
283                 dev_err(dev, "R5f prepare failed for core %d\n",
284                         core->tsp.proc_id);
285                 goto proc_release;
286         }
287
288         /* Zero out TCMs so that ECC can be effective on all TCM addresses */
289         if (core->atcm_enable)
290                 memset(core->mem[0].cpu_addr, 0x00, core->mem[0].size);
291         if (core->btcm_enable)
292                 memset(core->mem[1].cpu_addr, 0x00, core->mem[1].size);
293
294         ret = rproc_elf_load_image(dev, addr, size);
295         if (ret < 0) {
296                 dev_err(dev, "Loading elf failedi %d\n", ret);
297                 goto proc_release;
298         }
299
300         boot_vector = rproc_elf_get_boot_addr(dev, addr);
301
302         dev_dbg(dev, "%s: Boot vector = 0x%x\n", __func__, boot_vector);
303
304         ret = ti_sci_proc_set_config(&core->tsp, boot_vector, 0, 0);
305
306 proc_release:
307         k3_r5f_proc_release(core);
308
309         return ret;
310 }
311
312 static int k3_r5f_core_halt(struct k3_r5f_core *core)
313 {
314         int ret;
315
316         ret = ti_sci_proc_set_control(&core->tsp,
317                                       PROC_BOOT_CTRL_FLAG_R5_CORE_HALT, 0);
318         if (ret)
319                 dev_err(core->dev, "Core %d failed to stop\n",
320                         core->tsp.proc_id);
321
322         return ret;
323 }
324
325 static int k3_r5f_core_run(struct k3_r5f_core *core)
326 {
327         int ret;
328
329         ret = ti_sci_proc_set_control(&core->tsp,
330                                       0, PROC_BOOT_CTRL_FLAG_R5_CORE_HALT);
331         if (ret) {
332                 dev_err(core->dev, "Core %d failed to start\n",
333                         core->tsp.proc_id);
334                 return ret;
335         }
336
337         return 0;
338 }
339
340 /**
341  * k3_r5f_start() - Start the remote processor
342  * @dev:        rproc device pointer
343  *
344  * Return: 0 if all went ok, else return appropriate error
345  */
346 static int k3_r5f_start(struct udevice *dev)
347 {
348         struct k3_r5f_core *core = dev_get_priv(dev);
349         struct k3_r5f_cluster *cluster = core->cluster;
350         int ret, c;
351
352         dev_dbg(dev, "%s\n", __func__);
353
354         ret = k3_r5f_core_sanity_check(core);
355         if (ret)
356                 return ret;
357
358         ret = k3_r5f_proc_request(core);
359         if (ret)
360                 return ret;
361
362         if (cluster->mode == CLUSTER_MODE_LOCKSTEP) {
363                 if (is_primary_core(core)) {
364                         for (c = NR_CORES - 1; c >= 0; c--) {
365                                 ret = k3_r5f_core_run(cluster->cores[c]);
366                                 if (ret)
367                                         goto unroll_core_run;
368                         }
369                 } else {
370                         dev_err(dev, "Invalid op: Trying to start secondary core %d in lockstep mode\n",
371                                 core->tsp.proc_id);
372                         ret = -EINVAL;
373                         goto proc_release;
374                 }
375         } else {
376                 ret = k3_r5f_core_run(core);
377                 if (ret)
378                         goto proc_release;
379         }
380
381         core->in_use = true;
382
383         k3_r5f_proc_release(core);
384         return 0;
385
386 unroll_core_run:
387         while (c < NR_CORES) {
388                 k3_r5f_core_halt(cluster->cores[c]);
389                 c++;
390         }
391 proc_release:
392         k3_r5f_proc_release(core);
393
394         return ret;
395 }
396
397 static int k3_r5f_split_reset(struct k3_r5f_core *core)
398 {
399         int ret;
400
401         dev_dbg(dev, "%s\n", __func__);
402
403         if (reset_assert(&core->reset))
404                 ret = -EINVAL;
405
406         if (ti_sci_proc_power_domain_off(&core->tsp))
407                 ret = -EINVAL;
408
409         return ret;
410 }
411
412 static int k3_r5f_lockstep_reset(struct k3_r5f_cluster *cluster)
413 {
414         int ret = 0, c;
415
416         dev_dbg(dev, "%s\n", __func__);
417
418         for (c = 0; c < NR_CORES; c++)
419                 if (reset_assert(&cluster->cores[c]->reset))
420                         ret = -EINVAL;
421
422         /* disable PSC modules on all applicable cores */
423         for (c = 0; c < NR_CORES; c++)
424                 if (ti_sci_proc_power_domain_off(&cluster->cores[c]->tsp))
425                         ret = -EINVAL;
426
427         return ret;
428 }
429
430 static int k3_r5f_unprepare(struct udevice *dev)
431 {
432         struct k3_r5f_core *core = dev_get_priv(dev);
433         struct k3_r5f_cluster *cluster = core->cluster;
434         int ret;
435
436         dev_dbg(dev, "%s\n", __func__);
437
438         if (cluster->mode == CLUSTER_MODE_LOCKSTEP) {
439                 if (is_primary_core(core))
440                         ret = k3_r5f_lockstep_reset(cluster);
441         } else {
442                 ret = k3_r5f_split_reset(core);
443         }
444
445         if (ret)
446                 dev_warn(dev, "Unable to enable cores for TCM loading %d\n",
447                          ret);
448
449         return 0;
450 }
451
452 static int k3_r5f_stop(struct udevice *dev)
453 {
454         struct k3_r5f_core *core = dev_get_priv(dev);
455         struct k3_r5f_cluster *cluster = core->cluster;
456         int c, ret;
457
458         dev_dbg(dev, "%s\n", __func__);
459
460         ret = k3_r5f_proc_request(core);
461         if (ret)
462                 return ret;
463
464         core->in_use = false;
465
466         if (cluster->mode == CLUSTER_MODE_LOCKSTEP) {
467                 if (is_primary_core(core)) {
468                         for (c = 0; c < NR_CORES; c++)
469                                 k3_r5f_core_halt(cluster->cores[c]);
470                 } else {
471                         dev_err(dev, "Invalid op: Trying to stop secondary core in lockstep mode\n");
472                         ret = -EINVAL;
473                         goto proc_release;
474                 }
475         } else {
476                 k3_r5f_core_halt(core);
477         }
478
479         ret = k3_r5f_unprepare(dev);
480 proc_release:
481         k3_r5f_proc_release(core);
482         return ret;
483 }
484
485 static void *k3_r5f_da_to_va(struct udevice *dev, ulong da, ulong size)
486 {
487         struct k3_r5f_core *core = dev_get_priv(dev);
488         void __iomem *va = NULL;
489         phys_addr_t bus_addr;
490         u32 dev_addr, offset;
491         ulong mem_size;
492         int i;
493
494         dev_dbg(dev, "%s\n", __func__);
495
496         if (size <= 0)
497                 return NULL;
498
499         for (i = 0; i < core->num_mems; i++) {
500                 bus_addr = core->mem[i].bus_addr;
501                 dev_addr = core->mem[i].dev_addr;
502                 mem_size = core->mem[i].size;
503
504                 if (da >= bus_addr && (da + size) <= (bus_addr + mem_size)) {
505                         offset = da - bus_addr;
506                         va = core->mem[i].cpu_addr + offset;
507                         return (__force void *)va;
508                 }
509
510                 if (da >= dev_addr && (da + size) <= (dev_addr + mem_size)) {
511                         offset = da - dev_addr;
512                         va = core->mem[i].cpu_addr + offset;
513                         return (__force void *)va;
514                 }
515         }
516
517         /* Assume it is DDR region and return da */
518         return map_physmem(da, size, MAP_NOCACHE);
519 }
520
521 static int k3_r5f_init(struct udevice *dev)
522 {
523         return 0;
524 }
525
526 static int k3_r5f_reset(struct udevice *dev)
527 {
528         return 0;
529 }
530
531 static const struct dm_rproc_ops k3_r5f_rproc_ops = {
532         .init = k3_r5f_init,
533         .reset = k3_r5f_reset,
534         .start = k3_r5f_start,
535         .stop = k3_r5f_stop,
536         .load = k3_r5f_load,
537         .device_to_virt = k3_r5f_da_to_va,
538 };
539
540 static int k3_r5f_rproc_configure(struct k3_r5f_core *core)
541 {
542         struct k3_r5f_cluster *cluster = core->cluster;
543         u32 set_cfg = 0, clr_cfg = 0, cfg, ctrl, sts;
544         u64 boot_vec = 0;
545         int ret;
546
547         dev_dbg(dev, "%s\n", __func__);
548
549         ret = ti_sci_proc_request(&core->tsp);
550         if (ret < 0)
551                 return ret;
552
553         /* Do not touch boot vector now. Load will take care of it. */
554         clr_cfg |= PROC_BOOT_CFG_FLAG_GEN_IGN_BOOTVECTOR;
555
556         ret = ti_sci_proc_get_status(&core->tsp, &boot_vec, &cfg, &ctrl, &sts);
557         if (ret)
558                 goto out;
559
560         /* Sanity check for Lockstep mode */
561         if (cluster->mode && is_primary_core(core) &&
562             !(sts & PROC_BOOT_STATUS_FLAG_R5_LOCKSTEP_PERMITTED)) {
563                 dev_err(core->dev, "LockStep mode not permitted on this device\n");
564                 ret = -EINVAL;
565                 goto out;
566         }
567
568         /* Primary core only configuration */
569         if (is_primary_core(core)) {
570                 /* always enable ARM mode */
571                 clr_cfg |= PROC_BOOT_CFG_FLAG_R5_TEINIT;
572                 if (cluster->mode == CLUSTER_MODE_LOCKSTEP)
573                         set_cfg |= PROC_BOOT_CFG_FLAG_R5_LOCKSTEP;
574                 else
575                         clr_cfg |= PROC_BOOT_CFG_FLAG_R5_LOCKSTEP;
576         }
577
578         if (core->atcm_enable)
579                 set_cfg |= PROC_BOOT_CFG_FLAG_R5_ATCM_EN;
580         else
581                 clr_cfg |= PROC_BOOT_CFG_FLAG_R5_ATCM_EN;
582
583         if (core->btcm_enable)
584                 set_cfg |= PROC_BOOT_CFG_FLAG_R5_BTCM_EN;
585         else
586                 clr_cfg |= PROC_BOOT_CFG_FLAG_R5_BTCM_EN;
587
588         if (core->loczrama)
589                 set_cfg |= PROC_BOOT_CFG_FLAG_R5_TCM_RSTBASE;
590         else
591                 clr_cfg |= PROC_BOOT_CFG_FLAG_R5_TCM_RSTBASE;
592
593         ret = k3_r5f_core_halt(core);
594         if (ret)
595                 goto out;
596
597         ret = ti_sci_proc_set_config(&core->tsp, boot_vec, set_cfg, clr_cfg);
598 out:
599         ti_sci_proc_release(&core->tsp);
600         return ret;
601 }
602
603 static int ti_sci_proc_of_to_priv(struct udevice *dev, struct ti_sci_proc *tsp)
604 {
605         u32 ids[2];
606         int ret;
607
608         dev_dbg(dev, "%s\n", __func__);
609
610         tsp->sci = ti_sci_get_by_phandle(dev, "ti,sci");
611         if (IS_ERR(tsp->sci)) {
612                 dev_err(dev, "ti_sci get failed: %ld\n", PTR_ERR(tsp->sci));
613                 return PTR_ERR(tsp->sci);
614         }
615
616         ret = dev_read_u32_array(dev, "ti,sci-proc-ids", ids, 2);
617         if (ret) {
618                 dev_err(dev, "Proc IDs not populated %d\n", ret);
619                 return ret;
620         }
621
622         tsp->ops = &tsp->sci->ops.proc_ops;
623         tsp->proc_id = ids[0];
624         tsp->host_id = ids[1];
625         tsp->dev_id = dev_read_u32_default(dev, "ti,sci-dev-id",
626                                            TI_SCI_RESOURCE_NULL);
627         if (tsp->dev_id == TI_SCI_RESOURCE_NULL) {
628                 dev_err(dev, "Device ID not populated %d\n", ret);
629                 return -ENODEV;
630         }
631
632         return 0;
633 }
634
635 static int k3_r5f_of_to_priv(struct k3_r5f_core *core)
636 {
637         int ret;
638
639         dev_dbg(dev, "%s\n", __func__);
640
641         core->atcm_enable = dev_read_u32_default(core->dev, "atcm-enable", 0);
642         core->btcm_enable = dev_read_u32_default(core->dev, "btcm-enable", 1);
643         core->loczrama = dev_read_u32_default(core->dev, "loczrama", 1);
644
645         ret = ti_sci_proc_of_to_priv(core->dev, &core->tsp);
646         if (ret)
647                 return ret;
648
649         ret = reset_get_by_index(core->dev, 0, &core->reset);
650         if (ret) {
651                 dev_err(core->dev, "Reset lines not available: %d\n", ret);
652                 return ret;
653         }
654
655         return 0;
656 }
657
658 static int k3_r5f_core_of_get_memories(struct k3_r5f_core *core)
659 {
660         static const char * const mem_names[] = {"atcm", "btcm"};
661         struct udevice *dev = core->dev;
662         int i;
663
664         dev_dbg(dev, "%s\n", __func__);
665
666         core->num_mems = ARRAY_SIZE(mem_names);
667         core->mem = calloc(core->num_mems, sizeof(*core->mem));
668         if (!core->mem)
669                 return -ENOMEM;
670
671         for (i = 0; i < core->num_mems; i++) {
672                 core->mem[i].bus_addr = dev_read_addr_size_name(dev,
673                                                                 mem_names[i],
674                                         (fdt_addr_t *)&core->mem[i].size);
675                 if (core->mem[i].bus_addr == FDT_ADDR_T_NONE) {
676                         dev_err(dev, "%s bus address not found\n",
677                                 mem_names[i]);
678                         return -EINVAL;
679                 }
680                 core->mem[i].cpu_addr = map_physmem(core->mem[i].bus_addr,
681                                                     core->mem[i].size,
682                                                     MAP_NOCACHE);
683                 if (!strcmp(mem_names[i], "atcm")) {
684                         core->mem[i].dev_addr = core->loczrama ?
685                                                         0 : K3_R5_TCM_DEV_ADDR;
686                 } else {
687                         core->mem[i].dev_addr = core->loczrama ?
688                                                         K3_R5_TCM_DEV_ADDR : 0;
689                 }
690
691                 dev_dbg(dev, "memory %8s: bus addr %pa size 0x%zx va %p da 0x%x\n",
692                         mem_names[i], &core->mem[i].bus_addr,
693                         core->mem[i].size, core->mem[i].cpu_addr,
694                         core->mem[i].dev_addr);
695         }
696
697         return 0;
698 }
699
700 /**
701  * k3_r5f_probe() - Basic probe
702  * @dev:        corresponding k3 remote processor device
703  *
704  * Return: 0 if all goes good, else appropriate error message.
705  */
706 static int k3_r5f_probe(struct udevice *dev)
707 {
708         struct k3_r5f_cluster *cluster = dev_get_priv(dev->parent);
709         struct k3_r5f_core *core = dev_get_priv(dev);
710         bool r_state;
711         int ret;
712
713         dev_dbg(dev, "%s\n", __func__);
714
715         core->dev = dev;
716         ret = k3_r5f_of_to_priv(core);
717         if (ret)
718                 return ret;
719
720         core->cluster = cluster;
721         /* Assume Primary core gets probed first */
722         if (!cluster->cores[0])
723                 cluster->cores[0] = core;
724         else
725                 cluster->cores[1] = core;
726
727         ret = k3_r5f_core_of_get_memories(core);
728         if (ret) {
729                 dev_err(dev, "Rproc getting internal memories failed\n");
730                 return ret;
731         }
732
733         ret = core->tsp.sci->ops.dev_ops.is_on(core->tsp.sci, core->tsp.dev_id,
734                                                &r_state, &core->in_use);
735         if (ret)
736                 return ret;
737
738         if (core->in_use) {
739                 dev_info(dev, "Core %d is already in use. No rproc commands work\n",
740                          core->tsp.proc_id);
741                 return 0;
742         }
743
744         /* Make sure Local reset is asserted. Redundant? */
745         reset_assert(&core->reset);
746
747         ret = k3_r5f_rproc_configure(core);
748         if (ret) {
749                 dev_err(dev, "rproc configure failed %d\n", ret);
750                 return ret;
751         }
752
753         dev_dbg(dev, "Remoteproc successfully probed\n");
754
755         return 0;
756 }
757
758 static int k3_r5f_remove(struct udevice *dev)
759 {
760         struct k3_r5f_core *core = dev_get_priv(dev);
761
762         free(core->mem);
763
764         ti_sci_proc_release(&core->tsp);
765
766         return 0;
767 }
768
769 static const struct udevice_id k3_r5f_rproc_ids[] = {
770         { .compatible = "ti,am654-r5f"},
771         { .compatible = "ti,j721e-r5f"},
772         {}
773 };
774
775 U_BOOT_DRIVER(k3_r5f_rproc) = {
776         .name = "k3_r5f_rproc",
777         .of_match = k3_r5f_rproc_ids,
778         .id = UCLASS_REMOTEPROC,
779         .ops = &k3_r5f_rproc_ops,
780         .probe = k3_r5f_probe,
781         .remove = k3_r5f_remove,
782         .priv_auto_alloc_size = sizeof(struct k3_r5f_core),
783 };
784
785 static int k3_r5f_cluster_probe(struct udevice *dev)
786 {
787         struct k3_r5f_cluster *cluster = dev_get_priv(dev);
788
789         dev_dbg(dev, "%s\n", __func__);
790
791         cluster->mode = dev_read_u32_default(dev, "lockstep-mode",
792                                              CLUSTER_MODE_LOCKSTEP);
793
794         if (device_get_child_count(dev) != 2) {
795                 dev_err(dev, "Invalid number of R5 cores");
796                 return -EINVAL;
797         }
798
799         dev_dbg(dev, "%s: Cluster successfully probed in %s mode\n",
800                 __func__, cluster->mode ? "lockstep" : "split");
801
802         return 0;
803 }
804
805 static const struct udevice_id k3_r5fss_ids[] = {
806         { .compatible = "ti,am654-r5fss"},
807         { .compatible = "ti,j721e-r5fss"},
808         {}
809 };
810
811 U_BOOT_DRIVER(k3_r5fss) = {
812         .name = "k3_r5fss",
813         .of_match = k3_r5fss_ids,
814         .id = UCLASS_MISC,
815         .probe = k3_r5f_cluster_probe,
816         .priv_auto_alloc_size = sizeof(struct k3_r5f_cluster),
817 };