1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * Texas Instruments' K3 System Controller Driver
4  *
5  * Copyright (C) 2017-2018 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 <log.h>
12 #include <remoteproc.h>
13 #include <errno.h>
14 #include <mailbox.h>
15 #include <dm/device_compat.h>
16 #include <linux/soc/ti/k3-sec-proxy.h>
17 
18 #define K3_MSG_R5_TO_M3_M3FW			0x8105
19 #define K3_MSG_M3_TO_R5_CERT_RESULT		0x8805
20 #define K3_MSG_M3_TO_R5_BOOT_NOTIFICATION	0x000A
21 
22 #define K3_FLAGS_MSG_CERT_AUTH_PASS		0x555555
23 #define K3_FLAGS_MSG_CERT_AUTH_FAIL		0xffffff
24 
25 /**
26  * struct k3_sysctrler_msg_hdr - Generic Header for Messages and responses.
27  * @cmd_id:	Message ID. One of K3_MSG_*
28  * @host_id:	Host ID of the message
29  * @seq_ne:	Message identifier indicating a transfer sequence.
30  * @flags:	Flags for the message.
31  */
32 struct k3_sysctrler_msg_hdr {
33 	u16 cmd_id;
34 	u8 host_id;
35 	u8 seq_nr;
36 	u32 flags;
37 } __packed;
38 
39 /**
40  * struct k3_sysctrler_load_msg - Message format for Firmware loading
41  * @hdr:		Generic message hdr
42  * @buffer_address:	Address at which firmware is located.
43  * @buffer_size:	Size of the firmware.
44  */
45 struct k3_sysctrler_load_msg {
46 	struct k3_sysctrler_msg_hdr hdr;
47 	u32 buffer_address;
48 	u32 buffer_size;
49 } __packed;
50 
51 /**
52  * struct k3_sysctrler_boot_notification_msg - Message format for boot
53  *					       notification
54  * @checksum:		Checksum for the entire message
55  * @reserved:		Reserved for future use.
56  * @hdr:		Generic message hdr
57  */
58 struct k3_sysctrler_boot_notification_msg {
59 	u16 checksum;
60 	u16 reserved;
61 	struct k3_sysctrler_msg_hdr hdr;
62 } __packed;
63 
64 /**
65  * struct k3_sysctrler_desc - Description of SoC integration.
66  * @host_id:	Host identifier representing the compute entity
67  * @max_rx_timeout_ms:	Timeout for communication with SoC (in Milliseconds)
68  * @max_msg_size: Maximum size of data per message that can be handled.
69  */
70 struct k3_sysctrler_desc {
71 	u8 host_id;
72 	int max_rx_timeout_us;
73 	int max_msg_size;
74 };
75 
76 /**
77  * struct k3_sysctrler_privdata - Structure representing System Controller data.
78  * @chan_tx:	Transmit mailbox channel
79  * @chan_rx:	Receive mailbox channel
80  * @desc:	SoC description for this instance
81  * @seq_nr:	Counter for number of messages sent.
82  */
83 struct k3_sysctrler_privdata {
84 	struct mbox_chan chan_tx;
85 	struct mbox_chan chan_rx;
86 	struct k3_sysctrler_desc *desc;
87 	u32 seq_nr;
88 };
89 
90 static inline
k3_sysctrler_load_msg_setup(struct k3_sysctrler_load_msg * fw,struct k3_sysctrler_privdata * priv,ulong addr,ulong size)91 void k3_sysctrler_load_msg_setup(struct k3_sysctrler_load_msg *fw,
92 				 struct k3_sysctrler_privdata *priv,
93 				 ulong addr, ulong size)
94 {
95 	fw->hdr.cmd_id = K3_MSG_R5_TO_M3_M3FW;
96 	fw->hdr.host_id = priv->desc->host_id;
97 	fw->hdr.seq_nr = priv->seq_nr++;
98 	fw->hdr.flags = 0x0;
99 	fw->buffer_address = addr;
100 	fw->buffer_size = size;
101 }
102 
k3_sysctrler_load_response(struct udevice * dev,u32 * buf)103 static int k3_sysctrler_load_response(struct udevice *dev, u32 *buf)
104 {
105 	struct k3_sysctrler_load_msg *fw;
106 
107 	fw = (struct k3_sysctrler_load_msg *)buf;
108 
109 	/* Check for proper response ID */
110 	if (fw->hdr.cmd_id != K3_MSG_M3_TO_R5_CERT_RESULT) {
111 		dev_err(dev, "%s: Command expected 0x%x, but received 0x%x\n",
112 			__func__, K3_MSG_M3_TO_R5_CERT_RESULT, fw->hdr.cmd_id);
113 		return -EINVAL;
114 	}
115 
116 	/* Check for certificate authentication result */
117 	if (fw->hdr.flags == K3_FLAGS_MSG_CERT_AUTH_FAIL) {
118 		dev_err(dev, "%s: Firmware certificate authentication failed\n",
119 			__func__);
120 		return -EINVAL;
121 	} else if (fw->hdr.flags != K3_FLAGS_MSG_CERT_AUTH_PASS) {
122 		dev_err(dev, "%s: Firmware Load response Invalid %d\n",
123 			__func__, fw->hdr.flags);
124 		return -EINVAL;
125 	}
126 
127 	debug("%s: Firmware authentication passed\n", __func__);
128 
129 	return 0;
130 }
131 
k3_sysctrler_boot_notification_response(struct udevice * dev,u32 * buf)132 static int k3_sysctrler_boot_notification_response(struct udevice *dev,
133 						   u32 *buf)
134 {
135 	struct k3_sysctrler_boot_notification_msg *boot;
136 
137 	boot = (struct k3_sysctrler_boot_notification_msg *)buf;
138 
139 	/* ToDo: Verify checksum */
140 
141 	/* Check for proper response ID */
142 	if (boot->hdr.cmd_id != K3_MSG_M3_TO_R5_BOOT_NOTIFICATION) {
143 		dev_err(dev, "%s: Command expected 0x%x, but received 0x%x\n",
144 			__func__, K3_MSG_M3_TO_R5_BOOT_NOTIFICATION,
145 			boot->hdr.cmd_id);
146 		return -EINVAL;
147 	}
148 
149 	debug("%s: Boot notification received\n", __func__);
150 
151 	return 0;
152 }
153 
154 /**
155  * k3_sysctrler_load() - Loadup the K3 remote processor
156  * @dev:	corresponding K3 remote processor device
157  * @addr:	Address in memory where image binary is stored
158  * @size:	Size in bytes of the image binary
159  *
160  * Return: 0 if all goes good, else appropriate error message.
161  */
k3_sysctrler_load(struct udevice * dev,ulong addr,ulong size)162 static int k3_sysctrler_load(struct udevice *dev, ulong addr, ulong size)
163 {
164 	struct k3_sysctrler_privdata *priv = dev_get_priv(dev);
165 	struct k3_sysctrler_load_msg firmware;
166 	struct k3_sec_proxy_msg msg;
167 	int ret;
168 
169 	debug("%s: Loading binary from 0x%08lX, size 0x%08lX\n",
170 	      __func__, addr, size);
171 
172 	memset(&firmware, 0, sizeof(firmware));
173 	memset(&msg, 0, sizeof(msg));
174 
175 	/* Setup the message */
176 	k3_sysctrler_load_msg_setup(&firmware, priv, addr, size);
177 	msg.len = sizeof(firmware);
178 	msg.buf = (u32 *)&firmware;
179 
180 	/* Send the message */
181 	ret = mbox_send(&priv->chan_tx, &msg);
182 	if (ret) {
183 		dev_err(dev, "%s: Firmware Loading failed. ret = %d\n",
184 			__func__, ret);
185 		return ret;
186 	}
187 
188 	/* Receive the response */
189 	ret = mbox_recv(&priv->chan_rx, &msg, priv->desc->max_rx_timeout_us);
190 	if (ret) {
191 		dev_err(dev, "%s: Firmware Load response failed. ret = %d\n",
192 			__func__, ret);
193 		return ret;
194 	}
195 
196 	/* Process the response */
197 	ret = k3_sysctrler_load_response(dev, msg.buf);
198 	if (ret)
199 		return ret;
200 
201 	debug("%s: Firmware Loaded successfully on dev %s\n",
202 	      __func__, dev->name);
203 
204 	return 0;
205 }
206 
207 /**
208  * k3_sysctrler_start() - Start the remote processor
209  *		Note that while technically the K3 system controller starts up
210  *		automatically after its firmware got loaded we still want to
211  *		utilize the rproc start operation for other startup-related
212  *		tasks.
213  * @dev:	device to operate upon
214  *
215  * Return: 0 if all went ok, else return appropriate error
216  */
k3_sysctrler_start(struct udevice * dev)217 static int k3_sysctrler_start(struct udevice *dev)
218 {
219 	struct k3_sysctrler_privdata *priv = dev_get_priv(dev);
220 	struct k3_sec_proxy_msg msg;
221 	int ret;
222 
223 	debug("%s(dev=%p)\n", __func__, dev);
224 
225 	/* Receive the boot notification. Note that it is sent only once. */
226 	ret = mbox_recv(&priv->chan_rx, &msg, priv->desc->max_rx_timeout_us);
227 	if (ret) {
228 		dev_err(dev, "%s: Boot Notification response failed. ret = %d\n",
229 			__func__, ret);
230 		return ret;
231 	}
232 
233 	/* Process the response */
234 	ret = k3_sysctrler_boot_notification_response(dev, msg.buf);
235 	if (ret)
236 		return ret;
237 
238 	debug("%s: Boot notification received successfully on dev %s\n",
239 	      __func__, dev->name);
240 
241 	return 0;
242 }
243 
244 static const struct dm_rproc_ops k3_sysctrler_ops = {
245 	.load = k3_sysctrler_load,
246 	.start = k3_sysctrler_start,
247 };
248 
249 /**
250  * k3_of_to_priv() - generate private data from device tree
251  * @dev:	corresponding k3 remote processor device
252  * @priv:	pointer to driver specific private data
253  *
254  * Return: 0 if all goes good, else appropriate error message.
255  */
k3_of_to_priv(struct udevice * dev,struct k3_sysctrler_privdata * priv)256 static int k3_of_to_priv(struct udevice *dev,
257 			 struct k3_sysctrler_privdata *priv)
258 {
259 	int ret;
260 
261 	ret = mbox_get_by_name(dev, "tx", &priv->chan_tx);
262 	if (ret) {
263 		dev_err(dev, "%s: Acquiring Tx channel failed. ret = %d\n",
264 			__func__, ret);
265 		return ret;
266 	}
267 
268 	ret = mbox_get_by_name(dev, "rx", &priv->chan_rx);
269 	if (ret) {
270 		dev_err(dev, "%s: Acquiring Rx channel failed. ret = %d\n",
271 			__func__, ret);
272 		return ret;
273 	}
274 
275 	return 0;
276 }
277 
278 /**
279  * k3_sysctrler_probe() - Basic probe
280  * @dev:	corresponding k3 remote processor device
281  *
282  * Return: 0 if all goes good, else appropriate error message.
283  */
k3_sysctrler_probe(struct udevice * dev)284 static int k3_sysctrler_probe(struct udevice *dev)
285 {
286 	struct k3_sysctrler_privdata *priv;
287 	int ret;
288 
289 	debug("%s(dev=%p)\n", __func__, dev);
290 
291 	priv = dev_get_priv(dev);
292 
293 	ret = k3_of_to_priv(dev, priv);
294 	if (ret) {
295 		dev_err(dev, "%s: Probe failed with error %d\n", __func__, ret);
296 		return ret;
297 	}
298 
299 	priv->desc = (void *)dev_get_driver_data(dev);
300 	priv->seq_nr = 0;
301 
302 	return 0;
303 }
304 
305 static const struct k3_sysctrler_desc k3_sysctrler_am654_desc = {
306 	.host_id = 4,				/* HOST_ID_R5_1 */
307 	.max_rx_timeout_us = 800000,
308 	.max_msg_size = 60,
309 };
310 
311 static const struct udevice_id k3_sysctrler_ids[] = {
312 	{
313 		.compatible = "ti,am654-system-controller",
314 		.data = (ulong)&k3_sysctrler_am654_desc,
315 	},
316 	{}
317 };
318 
319 U_BOOT_DRIVER(k3_sysctrler) = {
320 	.name = "k3_system_controller",
321 	.of_match = k3_sysctrler_ids,
322 	.id = UCLASS_REMOTEPROC,
323 	.ops = &k3_sysctrler_ops,
324 	.probe = k3_sysctrler_probe,
325 	.priv_auto	= sizeof(struct k3_sysctrler_privdata),
326 };
327