1 // SPDX-License-Identifier: GPL-2.0+
3 * Texas Instruments' K3 DSP Remoteproc driver
5 * Copyright (C) 2018-2020 Texas Instruments Incorporated - https://www.ti.com/
6 * Lokesh Vutla <lokeshvutla@ti.com>
7 * Suman Anna <s-anna@ti.com>
14 #include <remoteproc.h>
19 #include <power-domain.h>
20 #include <dm/device_compat.h>
21 #include <linux/err.h>
22 #include <linux/sizes.h>
23 #include <linux/soc/ti/ti_sci_protocol.h>
24 #include "ti_sci_proc.h"
26 #define KEYSTONE_RPROC_LOCAL_ADDRESS_MASK (SZ_16M - 1)
29 * struct k3_dsp_mem - internal memory structure
30 * @cpu_addr: MPU virtual address of the memory region
31 * @bus_addr: Bus address used to access the memory region
32 * @dev_addr: Device address from remoteproc view
33 * @size: Size of the memory region
36 void __iomem
*cpu_addr
;
43 * struct k3_dsp_boot_data - internal data structure used for boot
44 * @boot_align_addr: Boot vector address alignment granularity
45 * @uses_lreset: Flag to denote the need for local reset management
47 struct k3_dsp_boot_data
{
53 * struct k3_dsp_privdata - Structure representing Remote processor data.
54 * @rproc_rst: rproc reset control data
55 * @tsp: Pointer to TISCI proc contrl handle
56 * @data: Pointer to DSP specific boot data structure
57 * @mem: Array of available memories
58 * @num_mem: Number of available memories
59 * @in_use: flag to tell if the core is already in use.
61 struct k3_dsp_privdata
{
62 struct reset_ctl dsp_rst
;
63 struct ti_sci_proc tsp
;
64 struct k3_dsp_boot_data
*data
;
65 struct k3_dsp_mem
*mem
;
71 * The C66x DSP cores have a local reset that affects only the CPU, and a
72 * generic module reset that powers on the device and allows the DSP internal
73 * memories to be accessed while the local reset is asserted. This function is
74 * used to release the global reset on C66x DSPs to allow loading into the DSP
75 * internal RAMs. This helper function is invoked in k3_dsp_load() before any
76 * actual firmware loading and is undone only in k3_dsp_stop(). The local reset
77 * on C71x cores is a no-op and the global reset cannot be released on C71x
78 * cores until after the firmware images are loaded, so this function does
79 * nothing for C71x cores.
81 static int k3_dsp_prepare(struct udevice
*dev
)
83 struct k3_dsp_privdata
*dsp
= dev_get_priv(dev
);
84 struct k3_dsp_boot_data
*data
= dsp
->data
;
87 /* local reset is no-op on C71x processors */
88 if (!data
->uses_lreset
)
91 ret
= ti_sci_proc_power_domain_on(&dsp
->tsp
);
93 dev_err(dev
, "cannot enable internal RAM loading, ret = %d\n",
100 * This function is the counterpart to k3_dsp_prepare() and is used to assert
101 * the global reset on C66x DSP cores (no-op for C71x DSP cores). This completes
102 * the second step of powering down the C66x DSP cores. The cores themselves
103 * are halted through the local reset in first step. This function is invoked
104 * in k3_dsp_stop() after the local reset is asserted.
106 static int k3_dsp_unprepare(struct udevice
*dev
)
108 struct k3_dsp_privdata
*dsp
= dev_get_priv(dev
);
109 struct k3_dsp_boot_data
*data
= dsp
->data
;
111 /* local reset is no-op on C71x processors */
112 if (!data
->uses_lreset
)
115 return ti_sci_proc_power_domain_off(&dsp
->tsp
);
119 * k3_dsp_load() - Load up the Remote processor image
120 * @dev: rproc device pointer
121 * @addr: Address at which image is available
122 * @size: size of the image
124 * Return: 0 if all goes good, else appropriate error message.
126 static int k3_dsp_load(struct udevice
*dev
, ulong addr
, ulong size
)
128 struct k3_dsp_privdata
*dsp
= dev_get_priv(dev
);
129 struct k3_dsp_boot_data
*data
= dsp
->data
;
135 "Invalid op: Trying to load/start on already running core %d\n",
140 dev_dbg(dev
, "%s addr = 0x%lx, size = 0x%lx\n", __func__
, addr
, size
);
141 ret
= ti_sci_proc_request(&dsp
->tsp
);
145 ret
= k3_dsp_prepare(dev
);
147 dev_err(dev
, "DSP prepare failed for core %d\n",
152 ret
= rproc_elf_load_image(dev
, addr
, size
);
154 dev_err(dev
, "Loading elf failed %d\n", ret
);
158 boot_vector
= rproc_elf_get_boot_addr(dev
, addr
);
159 if (boot_vector
& (data
->boot_align_addr
- 1)) {
161 dev_err(dev
, "Boot vector 0x%x not aligned on 0x%x boundary\n",
162 boot_vector
, data
->boot_align_addr
);
166 dev_dbg(dev
, "%s: Boot vector = 0x%x\n", __func__
, boot_vector
);
168 ret
= ti_sci_proc_set_config(&dsp
->tsp
, boot_vector
, 0, 0);
171 k3_dsp_unprepare(dev
);
173 ti_sci_proc_release(&dsp
->tsp
);
178 * k3_dsp_start() - Start the remote processor
179 * @dev: rproc device pointer
181 * Return: 0 if all went ok, else return appropriate error
183 static int k3_dsp_start(struct udevice
*dev
)
185 struct k3_dsp_privdata
*dsp
= dev_get_priv(dev
);
186 struct k3_dsp_boot_data
*data
= dsp
->data
;
189 dev_dbg(dev
, "%s\n", __func__
);
191 ret
= ti_sci_proc_request(&dsp
->tsp
);
195 if (!data
->uses_lreset
) {
196 ret
= ti_sci_proc_power_domain_on(&dsp
->tsp
);
201 ret
= reset_deassert(&dsp
->dsp_rst
);
203 if (!data
->uses_lreset
)
204 ti_sci_proc_power_domain_off(&dsp
->tsp
);
209 ti_sci_proc_release(&dsp
->tsp
);
214 static int k3_dsp_stop(struct udevice
*dev
)
216 struct k3_dsp_privdata
*dsp
= dev_get_priv(dev
);
218 dev_dbg(dev
, "%s\n", __func__
);
221 ti_sci_proc_request(&dsp
->tsp
);
222 reset_assert(&dsp
->dsp_rst
);
223 ti_sci_proc_power_domain_off(&dsp
->tsp
);
224 ti_sci_proc_release(&dsp
->tsp
);
230 * k3_dsp_init() - Initialize the remote processor
231 * @dev: rproc device pointer
233 * Return: 0 if all went ok, else return appropriate error
235 static int k3_dsp_init(struct udevice
*dev
)
237 dev_dbg(dev
, "%s\n", __func__
);
242 static int k3_dsp_reset(struct udevice
*dev
)
244 dev_dbg(dev
, "%s\n", __func__
);
249 static void *k3_dsp_da_to_va(struct udevice
*dev
, ulong da
, ulong len
)
251 struct k3_dsp_privdata
*dsp
= dev_get_priv(dev
);
252 phys_addr_t bus_addr
, dev_addr
;
253 void __iomem
*va
= NULL
;
258 dev_dbg(dev
, "%s\n", __func__
);
263 for (i
= 0; i
< dsp
->num_mems
; i
++) {
264 bus_addr
= dsp
->mem
[i
].bus_addr
;
265 dev_addr
= dsp
->mem
[i
].dev_addr
;
266 size
= dsp
->mem
[i
].size
;
268 if (da
>= dev_addr
&& ((da
+ len
) <= (dev_addr
+ size
))) {
269 offset
= da
- dev_addr
;
270 va
= dsp
->mem
[i
].cpu_addr
+ offset
;
271 return (__force
void *)va
;
274 if (da
>= bus_addr
&& (da
+ len
) <= (bus_addr
+ size
)) {
275 offset
= da
- bus_addr
;
276 va
= dsp
->mem
[i
].cpu_addr
+ offset
;
277 return (__force
void *)va
;
281 /* Assume it is DDR region and return da */
282 return map_physmem(da
, len
, MAP_NOCACHE
);
285 static const struct dm_rproc_ops k3_dsp_ops
= {
288 .start
= k3_dsp_start
,
290 .reset
= k3_dsp_reset
,
291 .device_to_virt
= k3_dsp_da_to_va
,
294 static int ti_sci_proc_of_to_priv(struct udevice
*dev
, struct ti_sci_proc
*tsp
)
299 dev_dbg(dev
, "%s\n", __func__
);
301 tsp
->sci
= ti_sci_get_by_phandle(dev
, "ti,sci");
302 if (IS_ERR(tsp
->sci
)) {
303 dev_err(dev
, "ti_sci get failed: %ld\n", PTR_ERR(tsp
->sci
));
304 return PTR_ERR(tsp
->sci
);
307 ret
= dev_read_u32_array(dev
, "ti,sci-proc-ids", ids
, 2);
309 dev_err(dev
, "Proc IDs not populated %d\n", ret
);
313 tsp
->ops
= &tsp
->sci
->ops
.proc_ops
;
314 tsp
->proc_id
= ids
[0];
315 tsp
->host_id
= ids
[1];
316 tsp
->dev_id
= dev_read_u32_default(dev
, "ti,sci-dev-id",
317 TI_SCI_RESOURCE_NULL
);
318 if (tsp
->dev_id
== TI_SCI_RESOURCE_NULL
) {
319 dev_err(dev
, "Device ID not populated %d\n", ret
);
326 static int k3_dsp_of_get_memories(struct udevice
*dev
)
328 static const char * const mem_names
[] = {"l2sram", "l1pram", "l1dram"};
329 struct k3_dsp_privdata
*dsp
= dev_get_priv(dev
);
332 dev_dbg(dev
, "%s\n", __func__
);
334 dsp
->num_mems
= ARRAY_SIZE(mem_names
);
335 dsp
->mem
= calloc(dsp
->num_mems
, sizeof(*dsp
->mem
));
339 for (i
= 0; i
< dsp
->num_mems
; i
++) {
340 /* C71 cores only have a L1P Cache, there are no L1P SRAMs */
341 if (((device_is_compatible(dev
, "ti,j721e-c71-dsp")) ||
342 (device_is_compatible(dev
, "ti,j721s2-c71-dsp"))) &&
343 !strcmp(mem_names
[i
], "l1pram")) {
344 dsp
->mem
[i
].bus_addr
= FDT_ADDR_T_NONE
;
345 dsp
->mem
[i
].dev_addr
= FDT_ADDR_T_NONE
;
346 dsp
->mem
[i
].cpu_addr
= NULL
;
347 dsp
->mem
[i
].size
= 0;
351 dsp
->mem
[i
].bus_addr
= dev_read_addr_size_name(dev
, mem_names
[i
],
352 (fdt_addr_t
*)&dsp
->mem
[i
].size
);
353 if (dsp
->mem
[i
].bus_addr
== FDT_ADDR_T_NONE
) {
354 dev_err(dev
, "%s bus address not found\n", mem_names
[i
]);
357 dsp
->mem
[i
].cpu_addr
= map_physmem(dsp
->mem
[i
].bus_addr
,
360 dsp
->mem
[i
].dev_addr
= dsp
->mem
[i
].bus_addr
&
361 KEYSTONE_RPROC_LOCAL_ADDRESS_MASK
;
363 dev_dbg(dev
, "memory %8s: bus addr %pa size 0x%zx va %p da %pa\n",
364 mem_names
[i
], &dsp
->mem
[i
].bus_addr
,
365 dsp
->mem
[i
].size
, dsp
->mem
[i
].cpu_addr
,
366 &dsp
->mem
[i
].dev_addr
);
373 * k3_of_to_priv() - generate private data from device tree
374 * @dev: corresponding k3 dsp processor device
375 * @dsp: pointer to driver specific private data
377 * Return: 0 if all goes good, else appropriate error message.
379 static int k3_dsp_of_to_priv(struct udevice
*dev
, struct k3_dsp_privdata
*dsp
)
383 dev_dbg(dev
, "%s\n", __func__
);
385 ret
= reset_get_by_index(dev
, 0, &dsp
->dsp_rst
);
387 dev_err(dev
, "reset_get() failed: %d\n", ret
);
391 ret
= ti_sci_proc_of_to_priv(dev
, &dsp
->tsp
);
395 ret
= k3_dsp_of_get_memories(dev
);
399 dsp
->data
= (struct k3_dsp_boot_data
*)dev_get_driver_data(dev
);
405 * k3_dsp_probe() - Basic probe
406 * @dev: corresponding k3 remote processor device
408 * Return: 0 if all goes good, else appropriate error message.
410 static int k3_dsp_probe(struct udevice
*dev
)
412 struct k3_dsp_privdata
*dsp
;
415 dev_dbg(dev
, "%s\n", __func__
);
417 dsp
= dev_get_priv(dev
);
419 ret
= k3_dsp_of_to_priv(dev
, dsp
);
421 dev_dbg(dev
, "%s: Probe failed with error %d\n", __func__
, ret
);
426 * The DSP local resets are deasserted by default on Power-On-Reset.
427 * Assert the local resets to ensure the DSPs don't execute bogus code
428 * in .load() callback when the module reset is released to support
429 * internal memory loading. This is needed for C66x DSPs, and is a
430 * no-op on C71x DSPs.
432 reset_assert(&dsp
->dsp_rst
);
434 dev_dbg(dev
, "Remoteproc successfully probed\n");
439 static int k3_dsp_remove(struct udevice
*dev
)
441 struct k3_dsp_privdata
*dsp
= dev_get_priv(dev
);
448 static const struct k3_dsp_boot_data c66_data
= {
449 .boot_align_addr
= SZ_1K
,
453 static const struct k3_dsp_boot_data c71_data
= {
454 .boot_align_addr
= SZ_2M
,
455 .uses_lreset
= false,
458 static const struct udevice_id k3_dsp_ids
[] = {
459 { .compatible
= "ti,j721e-c66-dsp", .data
= (ulong
)&c66_data
, },
460 { .compatible
= "ti,j721e-c71-dsp", .data
= (ulong
)&c71_data
, },
461 { .compatible
= "ti,j721s2-c71-dsp", .data
= (ulong
)&c71_data
, },
465 U_BOOT_DRIVER(k3_dsp
) = {
467 .of_match
= k3_dsp_ids
,
468 .id
= UCLASS_REMOTEPROC
,
470 .probe
= k3_dsp_probe
,
471 .remove
= k3_dsp_remove
,
472 .priv_auto
= sizeof(struct k3_dsp_privdata
),