2 * (C) Copyright 2015-2016
3 * Texas Instruments Incorporated - http://www.ti.com/
4 * SPDX-License-Identifier: GPL-2.0+
6 #define pr_fmt(fmt) "%s: " fmt, __func__
11 #include <remoteproc.h>
12 #include <mach/psc_defs.h>
14 DECLARE_GLOBAL_DATA_PTR
;
17 * struct ti_powerproc_privdata - power processor private data
18 * @loadaddr: base address for loading the power processor
19 * @psc_module: psc module address.
21 struct ti_powerproc_privdata
{
27 * ti_of_to_priv() - generate private data from device tree
28 * @dev: corresponding ti remote processor device
29 * @priv: pointer to driver specific private data
31 * Return: 0 if all went ok, else corresponding -ve error
33 static int ti_of_to_priv(struct udevice
*dev
,
34 struct ti_powerproc_privdata
*priv
)
36 int node
= dev_of_offset(dev
);
37 const void *blob
= gd
->fdt_blob
;
41 debug("'%s' no dt?\n", dev
->name
);
45 priv
->loadaddr
= fdtdec_get_addr(blob
, node
, "reg");
46 if (priv
->loadaddr
== FDT_ADDR_T_NONE
) {
47 debug("'%s': no 'reg' property\n", dev
->name
);
51 tmp
= fdtdec_get_int(blob
, node
, "ti,lpsc_module", -EINVAL
);
53 debug("'%s': no 'ti,lpsc_module' property\n", dev
->name
);
56 priv
->psc_module
= tmp
;
62 * ti_powerproc_probe() - Basic probe
63 * @dev: corresponding ti remote processor device
65 * Return: 0 if all went ok, else corresponding -ve error
67 static int ti_powerproc_probe(struct udevice
*dev
)
69 struct dm_rproc_uclass_pdata
*uc_pdata
;
70 struct ti_powerproc_privdata
*priv
;
73 uc_pdata
= dev_get_uclass_platdata(dev
);
74 priv
= dev_get_priv(dev
);
76 ret
= ti_of_to_priv(dev
, priv
);
78 debug("%s probed with slave_addr=0x%08lX module=%d(%d)\n",
79 uc_pdata
->name
, priv
->loadaddr
, priv
->psc_module
, ret
);
85 * ti_powerproc_load() - Loadup the TI remote processor
86 * @dev: corresponding ti remote processor device
87 * @addr: Address in memory where image binary is stored
88 * @size: Size in bytes of the image binary
90 * Return: 0 if all went ok, else corresponding -ve error
92 static int ti_powerproc_load(struct udevice
*dev
, ulong addr
, ulong size
)
94 struct dm_rproc_uclass_pdata
*uc_pdata
;
95 struct ti_powerproc_privdata
*priv
;
98 uc_pdata
= dev_get_uclass_platdata(dev
);
100 debug("%s: no uc pdata!\n", dev
->name
);
104 priv
= dev_get_priv(dev
);
105 ret
= psc_module_keep_in_reset_enabled(priv
->psc_module
, false);
107 debug("%s Unable to disable module '%d'(ret=%d)\n",
108 uc_pdata
->name
, priv
->psc_module
, ret
);
112 debug("%s: Loading binary from 0x%08lX, size 0x%08lX to 0x%08lX\n",
113 uc_pdata
->name
, addr
, size
, priv
->loadaddr
);
115 memcpy((void *)priv
->loadaddr
, (void *)addr
, size
);
117 debug("%s: Complete!\n", uc_pdata
->name
);
122 * ti_powerproc_start() - (replace: short desc)
123 * @dev: corresponding ti remote processor device
125 * Return: 0 if all went ok, else corresponding -ve error
127 static int ti_powerproc_start(struct udevice
*dev
)
129 struct dm_rproc_uclass_pdata
*uc_pdata
;
130 struct ti_powerproc_privdata
*priv
;
133 uc_pdata
= dev_get_uclass_platdata(dev
);
135 debug("%s: no uc pdata!\n", dev
->name
);
139 priv
= dev_get_priv(dev
);
140 ret
= psc_disable_module(priv
->psc_module
);
142 debug("%s Unable to disable module '%d'(ret=%d)\n",
143 uc_pdata
->name
, priv
->psc_module
, ret
);
147 ret
= psc_module_release_from_reset(priv
->psc_module
);
149 debug("%s Failed to wait for module '%d'(ret=%d)\n",
150 uc_pdata
->name
, priv
->psc_module
, ret
);
153 ret
= psc_enable_module(priv
->psc_module
);
155 debug("%s Unable to disable module '%d'(ret=%d)\n",
156 uc_pdata
->name
, priv
->psc_module
, ret
);
163 static const struct dm_rproc_ops ti_powerproc_ops
= {
164 .load
= ti_powerproc_load
,
165 .start
= ti_powerproc_start
,
168 static const struct udevice_id ti_powerproc_ids
[] = {
169 {.compatible
= "ti,power-processor"},
173 U_BOOT_DRIVER(ti_powerproc
) = {
174 .name
= "ti_power_proc",
175 .of_match
= ti_powerproc_ids
,
176 .id
= UCLASS_REMOTEPROC
,
177 .ops
= &ti_powerproc_ops
,
178 .probe
= ti_powerproc_probe
,
179 .priv_auto_alloc_size
= sizeof(struct ti_powerproc_privdata
),