xref: /linux/drivers/mfd/macsmc.c (revision 7a5f1cd22d47f8ca4b760b6334378ae42c1bd24b)
1 // SPDX-License-Identifier: GPL-2.0-only OR MIT
2 /*
3  * Apple SMC (System Management Controller) MFD driver
4  *
5  * Copyright The Asahi Linux Contributors
6  */
7 
8 #include <linux/bitfield.h>
9 #include <linux/delay.h>
10 #include <linux/device.h>
11 #include <linux/io.h>
12 #include <linux/ioport.h>
13 #include <linux/math.h>
14 #include <linux/mfd/core.h>
15 #include <linux/mfd/macsmc.h>
16 #include <linux/notifier.h>
17 #include <linux/of.h>
18 #include <linux/of_platform.h>
19 #include <linux/overflow.h>
20 #include <linux/platform_device.h>
21 #include <linux/soc/apple/rtkit.h>
22 #include <linux/unaligned.h>
23 
24 #define SMC_ENDPOINT			0x20
25 
26 /* We don't actually know the true size here but this seem reasonable */
27 #define SMC_SHMEM_SIZE			0x1000
28 #define SMC_MAX_SIZE			255
29 
30 #define SMC_MSG_READ_KEY		0x10
31 #define SMC_MSG_WRITE_KEY		0x11
32 #define SMC_MSG_GET_KEY_BY_INDEX	0x12
33 #define SMC_MSG_GET_KEY_INFO		0x13
34 #define SMC_MSG_INITIALIZE		0x17
35 #define SMC_MSG_NOTIFICATION		0x18
36 #define SMC_MSG_RW_KEY			0x20
37 
38 #define SMC_DATA			GENMASK_ULL(63, 32)
39 #define SMC_WSIZE			GENMASK_ULL(31, 24)
40 #define SMC_SIZE			GENMASK_ULL(23, 16)
41 #define SMC_ID				GENMASK_ULL(15, 12)
42 #define SMC_MSG				GENMASK_ULL(7, 0)
43 #define SMC_RESULT			SMC_MSG
44 
45 #define SMC_TIMEOUT_MS		500
46 
47 static const struct mfd_cell apple_smc_devs[] = {
48 	MFD_CELL_NAME("macsmc-input"),
49 	MFD_CELL_NAME("macsmc-power"),
50 	MFD_CELL_OF("macsmc-gpio", NULL, NULL, 0, 0, "apple,smc-gpio"),
51 	MFD_CELL_OF("macsmc-hwmon", NULL, NULL, 0, 0, "apple,smc-hwmon"),
52 	MFD_CELL_OF("macsmc-reboot", NULL, NULL, 0, 0, "apple,smc-reboot"),
53 	MFD_CELL_OF("macsmc-rtc", NULL, NULL, 0, 0, "apple,smc-rtc"),
54 };
55 
56 static int apple_smc_cmd_locked(struct apple_smc *smc, u64 cmd, u64 arg,
57 				  u64 size, u64 wsize, u32 *ret_data)
58 {
59 	u8 result;
60 	int ret;
61 	u64 msg;
62 
63 	lockdep_assert_held(&smc->mutex);
64 
65 	if (smc->boot_stage != APPLE_SMC_INITIALIZED)
66 		return -EIO;
67 	if (smc->atomic_mode)
68 		return -EIO;
69 
70 	reinit_completion(&smc->cmd_done);
71 
72 	smc->msg_id = (smc->msg_id + 1) & 0xf;
73 	msg = (FIELD_PREP(SMC_MSG, cmd) |
74 	       FIELD_PREP(SMC_SIZE, size) |
75 	       FIELD_PREP(SMC_WSIZE, wsize) |
76 	       FIELD_PREP(SMC_ID, smc->msg_id) |
77 	       FIELD_PREP(SMC_DATA, arg));
78 
79 	ret = apple_rtkit_send_message(smc->rtk, SMC_ENDPOINT, msg, NULL, false);
80 	if (ret) {
81 		dev_err(smc->dev, "Failed to send command\n");
82 		return ret;
83 	}
84 
85 	if (wait_for_completion_timeout(&smc->cmd_done, msecs_to_jiffies(SMC_TIMEOUT_MS)) <= 0) {
86 		dev_err(smc->dev, "Command timed out (%llx)", msg);
87 		return -ETIMEDOUT;
88 	}
89 
90 	if (FIELD_GET(SMC_ID, smc->cmd_ret) != smc->msg_id) {
91 		dev_err(smc->dev, "Command sequence mismatch (expected %d, got %d)\n",
92 			smc->msg_id, (unsigned int)FIELD_GET(SMC_ID, smc->cmd_ret));
93 		return -EIO;
94 	}
95 
96 	result = FIELD_GET(SMC_RESULT, smc->cmd_ret);
97 	if (result)
98 		return -EIO;
99 
100 	if (ret_data)
101 		*ret_data = FIELD_GET(SMC_DATA, smc->cmd_ret);
102 
103 	return FIELD_GET(SMC_SIZE, smc->cmd_ret);
104 }
105 
106 static int apple_smc_cmd(struct apple_smc *smc, u64 cmd, u64 arg,
107 			 u64 size, u64 wsize, u32 *ret_data)
108 {
109 	guard(mutex)(&smc->mutex);
110 
111 	return apple_smc_cmd_locked(smc, cmd, arg, size, wsize, ret_data);
112 }
113 
114 static int apple_smc_rw_locked(struct apple_smc *smc, smc_key key,
115 				const void *wbuf, size_t wsize,
116 				void *rbuf, size_t rsize)
117 {
118 	u64 smc_size, smc_wsize;
119 	u32 rdata;
120 	int ret;
121 	u64 cmd;
122 
123 	lockdep_assert_held(&smc->mutex);
124 
125 	if (rsize > SMC_MAX_SIZE)
126 		return -EINVAL;
127 	if (wsize > SMC_MAX_SIZE)
128 		return -EINVAL;
129 
130 	if (rsize && wsize) {
131 		cmd = SMC_MSG_RW_KEY;
132 		memcpy_toio(smc->shmem.iomem, wbuf, wsize);
133 		smc_size = rsize;
134 		smc_wsize = wsize;
135 	} else if (wsize && !rsize) {
136 		cmd = SMC_MSG_WRITE_KEY;
137 		memcpy_toio(smc->shmem.iomem, wbuf, wsize);
138 		/*
139 		 * Setting size to the length we want to write and wsize to 0
140 		 * looks silly but that's how the SMC protocol works ¯\_(ツ)_/¯
141 		 */
142 		smc_size = wsize;
143 		smc_wsize = 0;
144 	} else if (!wsize && rsize) {
145 		cmd = SMC_MSG_READ_KEY;
146 		smc_size = rsize;
147 		smc_wsize = 0;
148 	} else {
149 		return -EINVAL;
150 	}
151 
152 	ret = apple_smc_cmd_locked(smc, cmd, key, smc_size, smc_wsize, &rdata);
153 	if (ret < 0)
154 		return ret;
155 
156 	if (rsize) {
157 		/*
158 		 * Small data <= 4 bytes is returned as part of the reply
159 		 * message which is sent over the mailbox FIFO. Everything
160 		 * bigger has to be copied from SRAM which is mapped as
161 		 * Device memory.
162 		 */
163 		if (rsize <= 4)
164 			memcpy(rbuf, &rdata, rsize);
165 		else
166 			memcpy_fromio(rbuf, smc->shmem.iomem, rsize);
167 	}
168 
169 	return ret;
170 }
171 
172 int apple_smc_read(struct apple_smc *smc, smc_key key, void *buf, size_t size)
173 {
174 	guard(mutex)(&smc->mutex);
175 
176 	return apple_smc_rw_locked(smc, key, NULL, 0, buf, size);
177 }
178 EXPORT_SYMBOL(apple_smc_read);
179 
180 int apple_smc_write(struct apple_smc *smc, smc_key key, const void *buf, size_t size)
181 {
182 	guard(mutex)(&smc->mutex);
183 
184 	return apple_smc_rw_locked(smc, key, buf, size, NULL, 0);
185 }
186 EXPORT_SYMBOL(apple_smc_write);
187 
188 int apple_smc_rw(struct apple_smc *smc, smc_key key, const void *wbuf, size_t wsize,
189 		 void *rbuf, size_t rsize)
190 {
191 	guard(mutex)(&smc->mutex);
192 
193 	return apple_smc_rw_locked(smc, key, wbuf, wsize, rbuf, rsize);
194 }
195 EXPORT_SYMBOL(apple_smc_rw);
196 
197 int apple_smc_get_key_by_index(struct apple_smc *smc, int index, smc_key *key)
198 {
199 	int ret;
200 
201 	ret = apple_smc_cmd(smc, SMC_MSG_GET_KEY_BY_INDEX, index, 0, 0, key);
202 
203 	*key = swab32(*key);
204 	return ret;
205 }
206 EXPORT_SYMBOL(apple_smc_get_key_by_index);
207 
208 int apple_smc_get_key_info(struct apple_smc *smc, smc_key key, struct apple_smc_key_info *info)
209 {
210 	u8 key_info[6];
211 	int ret;
212 
213 	ret = apple_smc_cmd(smc, SMC_MSG_GET_KEY_INFO, key, 0, 0, NULL);
214 	if (ret >= 0 && info) {
215 		memcpy_fromio(key_info, smc->shmem.iomem, sizeof(key_info));
216 		info->size = key_info[0];
217 		info->type_code = get_unaligned_be32(&key_info[1]);
218 		info->flags = key_info[5];
219 	}
220 	return ret;
221 }
222 EXPORT_SYMBOL(apple_smc_get_key_info);
223 
224 int apple_smc_enter_atomic(struct apple_smc *smc)
225 {
226 	guard(mutex)(&smc->mutex);
227 
228 	/*
229 	 * Disable notifications since this is called before shutdown and no
230 	 * notification handler will be able to handle the notification
231 	 * using atomic operations only. Also ignore any failure here
232 	 * because we're about to shut down or reboot anyway.
233 	 * We can't use apple_smc_write_flag here since that would try to lock
234 	 * smc->mutex again.
235 	 */
236 	const u8 flag = 0;
237 
238 	apple_smc_rw_locked(smc, SMC_KEY(NTAP), &flag, sizeof(flag), NULL, 0);
239 
240 	smc->atomic_mode = true;
241 
242 	return 0;
243 }
244 EXPORT_SYMBOL(apple_smc_enter_atomic);
245 
246 int apple_smc_write_atomic(struct apple_smc *smc, smc_key key, const void *buf, size_t size)
247 {
248 	guard(spinlock_irqsave)(&smc->lock);
249 	u8 result;
250 	int ret;
251 	u64 msg;
252 
253 	if (size > SMC_MAX_SIZE || size == 0)
254 		return -EINVAL;
255 
256 	if (smc->boot_stage != APPLE_SMC_INITIALIZED)
257 		return -EIO;
258 	if (!smc->atomic_mode)
259 		return -EIO;
260 
261 	memcpy_toio(smc->shmem.iomem, buf, size);
262 	smc->msg_id = (smc->msg_id + 1) & 0xf;
263 	msg = (FIELD_PREP(SMC_MSG, SMC_MSG_WRITE_KEY) |
264 	       FIELD_PREP(SMC_SIZE, size) |
265 	       FIELD_PREP(SMC_ID, smc->msg_id) |
266 	       FIELD_PREP(SMC_DATA, key));
267 	smc->atomic_pending = true;
268 
269 	ret = apple_rtkit_send_message(smc->rtk, SMC_ENDPOINT, msg, NULL, true);
270 	if (ret < 0) {
271 		dev_err(smc->dev, "Failed to send command (%d)\n", ret);
272 		return ret;
273 	}
274 
275 	while (smc->atomic_pending) {
276 		ret = apple_rtkit_poll(smc->rtk);
277 		if (ret < 0) {
278 			dev_err(smc->dev, "RTKit poll failed (%llx)", msg);
279 			return ret;
280 		}
281 		udelay(100);
282 	}
283 
284 	if (FIELD_GET(SMC_ID, smc->cmd_ret) != smc->msg_id) {
285 		dev_err(smc->dev, "Command sequence mismatch (expected %d, got %d)\n",
286 			smc->msg_id, (unsigned int)FIELD_GET(SMC_ID, smc->cmd_ret));
287 		return -EIO;
288 	}
289 
290 	result = FIELD_GET(SMC_RESULT, smc->cmd_ret);
291 	if (result)
292 		return -EIO;
293 
294 	return FIELD_GET(SMC_SIZE, smc->cmd_ret);
295 }
296 EXPORT_SYMBOL(apple_smc_write_atomic);
297 
298 static void apple_smc_rtkit_crashed(void *cookie, const void *bfr, size_t bfr_len)
299 {
300 	struct apple_smc *smc = cookie;
301 
302 	smc->boot_stage = APPLE_SMC_ERROR_CRASHED;
303 	dev_err(smc->dev, "SMC crashed! Your system will reboot in a few seconds...\n");
304 }
305 
306 static int apple_smc_rtkit_shmem_setup(void *cookie, struct apple_rtkit_shmem *bfr)
307 {
308 	struct apple_smc *smc = cookie;
309 	size_t bfr_end;
310 
311 	if (!bfr->iova) {
312 		dev_err(smc->dev, "RTKit wants a RAM buffer\n");
313 		return -EIO;
314 	}
315 
316 	if (check_add_overflow(bfr->iova, bfr->size - 1, &bfr_end))
317 		return -EFAULT;
318 
319 	if (bfr->iova < smc->sram->start || bfr->iova > smc->sram->end ||
320 	    bfr_end > smc->sram->end) {
321 		dev_err(smc->dev, "RTKit buffer request outside SRAM region: [0x%llx, 0x%llx]\n",
322 			(unsigned long long)bfr->iova,
323 			(unsigned long long)bfr_end);
324 		return -EFAULT;
325 	}
326 
327 	bfr->iomem = smc->sram_base + (bfr->iova - smc->sram->start);
328 	bfr->is_mapped = true;
329 
330 	return 0;
331 }
332 
333 static bool apple_smc_rtkit_recv_early(void *cookie, u8 endpoint, u64 message)
334 {
335 	struct apple_smc *smc = cookie;
336 
337 	if (endpoint != SMC_ENDPOINT) {
338 		dev_warn(smc->dev, "Received message for unknown endpoint 0x%x\n", endpoint);
339 		return false;
340 	}
341 
342 	if (smc->boot_stage == APPLE_SMC_BOOTING) {
343 		int ret;
344 
345 		smc->shmem.iova = message;
346 		smc->shmem.size = SMC_SHMEM_SIZE;
347 		ret = apple_smc_rtkit_shmem_setup(smc, &smc->shmem);
348 		if (ret < 0) {
349 			smc->boot_stage = APPLE_SMC_ERROR_NO_SHMEM;
350 			dev_err(smc->dev, "Failed to initialize shared memory (%d)\n", ret);
351 		} else {
352 			smc->boot_stage = APPLE_SMC_INITIALIZED;
353 		}
354 		complete(&smc->init_done);
355 	} else if (FIELD_GET(SMC_MSG, message) == SMC_MSG_NOTIFICATION) {
356 		/* Handle these in the RTKit worker thread */
357 		return false;
358 	} else {
359 		smc->cmd_ret = message;
360 		if (smc->atomic_pending)
361 			smc->atomic_pending = false;
362 		else
363 			complete(&smc->cmd_done);
364 	}
365 
366 	return true;
367 }
368 
369 static void apple_smc_rtkit_recv(void *cookie, u8 endpoint, u64 message)
370 {
371 	struct apple_smc *smc = cookie;
372 
373 	if (endpoint != SMC_ENDPOINT) {
374 		dev_warn(smc->dev, "Received message for unknown endpoint 0x%x\n", endpoint);
375 		return;
376 	}
377 
378 	if (FIELD_GET(SMC_MSG, message) != SMC_MSG_NOTIFICATION) {
379 		dev_warn(smc->dev, "Received unknown message from worker: 0x%llx\n", message);
380 		return;
381 	}
382 
383 	blocking_notifier_call_chain(&smc->event_handlers, FIELD_GET(SMC_DATA, message), NULL);
384 }
385 
386 static const struct apple_rtkit_ops apple_smc_rtkit_ops = {
387 	.crashed = apple_smc_rtkit_crashed,
388 	.recv_message = apple_smc_rtkit_recv,
389 	.recv_message_early = apple_smc_rtkit_recv_early,
390 	.shmem_setup = apple_smc_rtkit_shmem_setup,
391 };
392 
393 static void apple_smc_rtkit_shutdown(void *data)
394 {
395 	struct apple_smc *smc = data;
396 
397 	/* Shut down SMC firmware, if it's not completely wedged */
398 	if (apple_rtkit_is_running(smc->rtk))
399 		apple_rtkit_quiesce(smc->rtk);
400 }
401 
402 static void apple_smc_disable_notifications(void *data)
403 {
404 	struct apple_smc *smc = data;
405 
406 	apple_smc_write_flag(smc, SMC_KEY(NTAP), false);
407 }
408 
409 static int apple_smc_probe(struct platform_device *pdev)
410 {
411 	struct device *dev = &pdev->dev;
412 	struct apple_smc *smc;
413 	u32 count;
414 	int ret;
415 
416 	smc = devm_kzalloc(dev, sizeof(*smc), GFP_KERNEL);
417 	if (!smc)
418 		return -ENOMEM;
419 
420 	mutex_init(&smc->mutex);
421 	smc->dev = &pdev->dev;
422 	smc->sram_base = devm_platform_get_and_ioremap_resource(pdev, 1, &smc->sram);
423 	if (IS_ERR(smc->sram_base))
424 		return dev_err_probe(dev, PTR_ERR(smc->sram_base), "Failed to map SRAM region");
425 
426 	smc->rtk = devm_apple_rtkit_init(dev, smc, NULL, 0, &apple_smc_rtkit_ops);
427 	if (IS_ERR(smc->rtk))
428 		return dev_err_probe(dev, PTR_ERR(smc->rtk), "Failed to initialize RTKit");
429 
430 	smc->boot_stage = APPLE_SMC_BOOTING;
431 	ret = apple_rtkit_wake(smc->rtk);
432 	if (ret)
433 		return dev_err_probe(dev, ret, "Failed to wake up SMC");
434 
435 	ret = devm_add_action_or_reset(dev, apple_smc_rtkit_shutdown, smc);
436 	if (ret)
437 		return ret;
438 
439 	ret = apple_rtkit_start_ep(smc->rtk, SMC_ENDPOINT);
440 	if (ret)
441 		return dev_err_probe(dev, ret, "Failed to start SMC endpoint");
442 
443 	init_completion(&smc->init_done);
444 	init_completion(&smc->cmd_done);
445 
446 	ret = apple_rtkit_send_message(smc->rtk, SMC_ENDPOINT,
447 				       FIELD_PREP(SMC_MSG, SMC_MSG_INITIALIZE), NULL, false);
448 	if (ret)
449 		return dev_err_probe(dev, ret, "Failed to send init message");
450 
451 	if (wait_for_completion_timeout(&smc->init_done, msecs_to_jiffies(SMC_TIMEOUT_MS)) == 0) {
452 		dev_err(dev, "Timed out initializing SMC");
453 		return -ETIMEDOUT;
454 	}
455 
456 	if (smc->boot_stage != APPLE_SMC_INITIALIZED) {
457 		dev_err(dev, "SMC failed to boot successfully, boot stage=%d\n", smc->boot_stage);
458 		return -EIO;
459 	}
460 
461 	dev_set_drvdata(&pdev->dev, smc);
462 	BLOCKING_INIT_NOTIFIER_HEAD(&smc->event_handlers);
463 
464 	ret = apple_smc_read_u32(smc, SMC_KEY(#KEY), &count);
465 	if (ret)
466 		return dev_err_probe(smc->dev, ret, "Failed to get key count");
467 	smc->key_count = be32_to_cpu(count);
468 
469 	/* Enable notifications */
470 	apple_smc_write_flag(smc, SMC_KEY(NTAP), true);
471 	ret = devm_add_action_or_reset(dev, apple_smc_disable_notifications, smc);
472 	if (ret)
473 		return ret;
474 
475 	ret = devm_mfd_add_devices(smc->dev, PLATFORM_DEVID_NONE,
476 				   apple_smc_devs, ARRAY_SIZE(apple_smc_devs),
477 				   NULL, 0, NULL);
478 	if (ret)
479 		return dev_err_probe(smc->dev, ret, "Failed to register sub-devices");
480 
481 
482 	return 0;
483 }
484 
485 static const struct of_device_id apple_smc_of_match[] = {
486 	{ .compatible = "apple,t8103-smc" },
487 	{ .compatible = "apple,smc" },
488 	{},
489 };
490 MODULE_DEVICE_TABLE(of, apple_smc_of_match);
491 
492 static struct platform_driver apple_smc_driver = {
493 	.driver = {
494 		.name = "macsmc",
495 		.of_match_table = apple_smc_of_match,
496 	},
497 	.probe = apple_smc_probe,
498 };
499 module_platform_driver(apple_smc_driver);
500 
501 MODULE_AUTHOR("Hector Martin <marcan@marcan.st>");
502 MODULE_AUTHOR("Sven Peter <sven@kernel.org>");
503 MODULE_LICENSE("Dual MIT/GPL");
504 MODULE_DESCRIPTION("Apple SMC driver");
505