xref: /rk3399_ARM-atf/plat/marvell/armada/a8k/a80x0_puzzle/board/system_power.c (revision 203d48adcad8d90eb8fb5eb4bb2de4c65c9837af)
170ec0d72SLuka Kovacic /*
270ec0d72SLuka Kovacic  * Copyright (C) 2020 Sartura Ltd.
370ec0d72SLuka Kovacic  * Author: Luka Kovacic <luka.kovacic@sartura.hr>
470ec0d72SLuka Kovacic  *
570ec0d72SLuka Kovacic  * SPDX-License-Identifier:     BSD-3-Clause
670ec0d72SLuka Kovacic  * https://spdx.org/licenses
770ec0d72SLuka Kovacic  */
870ec0d72SLuka Kovacic 
970ec0d72SLuka Kovacic #include <armada_common.h>
1070ec0d72SLuka Kovacic #include <common/debug.h>
1170ec0d72SLuka Kovacic #include <drivers/delay_timer.h>
1270ec0d72SLuka Kovacic #include <drivers/ti/uart/uart_16550.h>
1370ec0d72SLuka Kovacic #include <drivers/console.h>
1470ec0d72SLuka Kovacic #include <plat_marvell.h>
1570ec0d72SLuka Kovacic 
1670ec0d72SLuka Kovacic /*****************************************************************************
1770ec0d72SLuka Kovacic  * Platform specific power off functions
1870ec0d72SLuka Kovacic  * Power off PSU / Send command to power management MCU / ...
1970ec0d72SLuka Kovacic  *****************************************************************************
2070ec0d72SLuka Kovacic  */
2170ec0d72SLuka Kovacic 
add_xor_checksum(unsigned char * buf,unsigned char xor_len)2270ec0d72SLuka Kovacic unsigned char add_xor_checksum(unsigned char *buf, unsigned char xor_len)
2370ec0d72SLuka Kovacic {
2470ec0d72SLuka Kovacic 	unsigned char xor_sum = 0;
2570ec0d72SLuka Kovacic 	unsigned int i;
2670ec0d72SLuka Kovacic 
2770ec0d72SLuka Kovacic 	for (i = 0; i < xor_len; i++)
2870ec0d72SLuka Kovacic 		xor_sum ^= buf[i];
2970ec0d72SLuka Kovacic 
3070ec0d72SLuka Kovacic 	return xor_sum;
3170ec0d72SLuka Kovacic }
3270ec0d72SLuka Kovacic 
system_power_off(void)3370ec0d72SLuka Kovacic int system_power_off(void)
3470ec0d72SLuka Kovacic {
3570ec0d72SLuka Kovacic 	static console_t console;
3670ec0d72SLuka Kovacic 
3770ec0d72SLuka Kovacic 	/* WT61P803 MCU system_off_now command */
3870ec0d72SLuka Kovacic 	unsigned char system_off_now[4] = { '@', 'C', '0' };
3970ec0d72SLuka Kovacic 	int i, len;
4070ec0d72SLuka Kovacic 
4170ec0d72SLuka Kovacic 	len = sizeof(system_off_now);
4270ec0d72SLuka Kovacic 	system_off_now[len - 1] = add_xor_checksum(system_off_now, len);
4370ec0d72SLuka Kovacic 
44*31336258SPali Rohár 	console_16550_register(PLAT_MARVELL_UART_BASE + 0x100,
45*31336258SPali Rohár 		PLAT_MARVELL_UART_CLK_IN_HZ, 115200, &console);
4670ec0d72SLuka Kovacic 
4770ec0d72SLuka Kovacic 	/* Send system_off_now to console */
4870ec0d72SLuka Kovacic 	for (i = 0; i < len; i++) {
4970ec0d72SLuka Kovacic 		console.putc(system_off_now[i],	&console);
5070ec0d72SLuka Kovacic 		udelay(1000);
5170ec0d72SLuka Kovacic 	}
5270ec0d72SLuka Kovacic 
5370ec0d72SLuka Kovacic 	console.flush(&console);
5470ec0d72SLuka Kovacic 	(void)console_unregister(&console);
5570ec0d72SLuka Kovacic 
5670ec0d72SLuka Kovacic 	mdelay(100);
5770ec0d72SLuka Kovacic 
5870ec0d72SLuka Kovacic 	return 0;
5970ec0d72SLuka Kovacic }
60