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