1 /*
2  * Copyright (C) 2020 Sartura Ltd.
3  * Author: Luka Kovacic <luka.kovacic@sartura.hr>
4  *
5  * SPDX-License-Identifier:     BSD-3-Clause
6  * https://spdx.org/licenses
7  */
8 
9 #include <armada_common.h>
10 #include <common/debug.h>
11 #include <drivers/delay_timer.h>
12 #include <drivers/ti/uart/uart_16550.h>
13 #include <drivers/console.h>
14 #include <plat_marvell.h>
15 
16 /*****************************************************************************
17  * Platform specific power off functions
18  * Power off PSU / Send command to power management MCU / ...
19  *****************************************************************************
20  */
21 
add_xor_checksum(unsigned char * buf,unsigned char xor_len)22 unsigned char add_xor_checksum(unsigned char *buf, unsigned char xor_len)
23 {
24 	unsigned char xor_sum = 0;
25 	unsigned int i;
26 
27 	for (i = 0; i < xor_len; i++)
28 		xor_sum ^= buf[i];
29 
30 	return xor_sum;
31 }
32 
system_power_off(void)33 int system_power_off(void)
34 {
35 	static console_t console;
36 
37 	/* WT61P803 MCU system_off_now command */
38 	unsigned char system_off_now[4] = { '@', 'C', '0' };
39 	int i, len;
40 
41 	len = sizeof(system_off_now);
42 	system_off_now[len - 1] = add_xor_checksum(system_off_now, len);
43 
44 	console_16550_register(PLAT_MARVELL_UART_BASE + 0x100,
45 		PLAT_MARVELL_UART_CLK_IN_HZ, 115200, &console);
46 
47 	/* Send system_off_now to console */
48 	for (i = 0; i < len; i++) {
49 		console.putc(system_off_now[i],	&console);
50 		udelay(1000);
51 	}
52 
53 	console.flush(&console);
54 	(void)console_unregister(&console);
55 
56 	mdelay(100);
57 
58 	return 0;
59 }
60