xref: /rk3399_ARM-atf/plat/marvell/armada/a8k/common/mss/mss_pm_ipc.c (revision 9935047b2086faa3bf3ccf0b95a76510eb5a160b)
1*a2847172SGrzegorz Jaszczyk /*
2*a2847172SGrzegorz Jaszczyk  * Copyright (C) 2018 Marvell International Ltd.
3*a2847172SGrzegorz Jaszczyk  *
4*a2847172SGrzegorz Jaszczyk  * SPDX-License-Identifier:     BSD-3-Clause
5*a2847172SGrzegorz Jaszczyk  * https://spdx.org/licenses
6*a2847172SGrzegorz Jaszczyk  */
7*a2847172SGrzegorz Jaszczyk 
8*a2847172SGrzegorz Jaszczyk #include <string.h>
9*a2847172SGrzegorz Jaszczyk 
10*a2847172SGrzegorz Jaszczyk #include <common/debug.h>
11*a2847172SGrzegorz Jaszczyk #include <lib/psci/psci.h>
12*a2847172SGrzegorz Jaszczyk #include <lib/mmio.h>
13*a2847172SGrzegorz Jaszczyk 
14*a2847172SGrzegorz Jaszczyk #include <mss_pm_ipc.h>
15*a2847172SGrzegorz Jaszczyk 
16*a2847172SGrzegorz Jaszczyk /*
17*a2847172SGrzegorz Jaszczyk  * SISR is 32 bit interrupt register representing 32 interrupts
18*a2847172SGrzegorz Jaszczyk  *
19*a2847172SGrzegorz Jaszczyk  * +======+=============+=============+
20*a2847172SGrzegorz Jaszczyk  * + Bits + 31          + 30 - 00     +
21*a2847172SGrzegorz Jaszczyk  * +======+=============+=============+
22*a2847172SGrzegorz Jaszczyk  * + Desc + MSS Msg Int + Reserved    +
23*a2847172SGrzegorz Jaszczyk  * +======+=============+=============+
24*a2847172SGrzegorz Jaszczyk  */
25*a2847172SGrzegorz Jaszczyk #define MSS_SISR		(MVEBU_REGS_BASE + 0x5800D0)
26*a2847172SGrzegorz Jaszczyk #define MSS_SISTR		(MVEBU_REGS_BASE + 0x5800D8)
27*a2847172SGrzegorz Jaszczyk 
28*a2847172SGrzegorz Jaszczyk #define MSS_MSG_INT_MASK	(0x80000000)
29*a2847172SGrzegorz Jaszczyk #define MSS_TIMER_BASE		(MVEBU_REGS_BASE_MASK + 0x580110)
30*a2847172SGrzegorz Jaszczyk #define MSS_TRIGGER_TIMEOUT	(2000)
31*a2847172SGrzegorz Jaszczyk 
32*a2847172SGrzegorz Jaszczyk /*****************************************************************************
33*a2847172SGrzegorz Jaszczyk  * mss_pm_ipc_msg_send
34*a2847172SGrzegorz Jaszczyk  *
35*a2847172SGrzegorz Jaszczyk  * DESCRIPTION: create and transmit IPC message
36*a2847172SGrzegorz Jaszczyk  *****************************************************************************
37*a2847172SGrzegorz Jaszczyk  */
mss_pm_ipc_msg_send(unsigned int channel_id,unsigned int msg_id,const psci_power_state_t * target_state)38*a2847172SGrzegorz Jaszczyk int mss_pm_ipc_msg_send(unsigned int channel_id, unsigned int msg_id,
39*a2847172SGrzegorz Jaszczyk 			const psci_power_state_t *target_state)
40*a2847172SGrzegorz Jaszczyk {
41*a2847172SGrzegorz Jaszczyk 	/* Transmit IPC message */
42*a2847172SGrzegorz Jaszczyk #ifndef DISABLE_CLUSTER_LEVEL
43*a2847172SGrzegorz Jaszczyk 	mv_pm_ipc_msg_tx(channel_id, msg_id,
44*a2847172SGrzegorz Jaszczyk 			 (unsigned int)target_state->pwr_domain_state[
45*a2847172SGrzegorz Jaszczyk 					MPIDR_AFFLVL1]);
46*a2847172SGrzegorz Jaszczyk #else
47*a2847172SGrzegorz Jaszczyk 	mv_pm_ipc_msg_tx(channel_id, msg_id, 0);
48*a2847172SGrzegorz Jaszczyk #endif
49*a2847172SGrzegorz Jaszczyk 
50*a2847172SGrzegorz Jaszczyk 	return 0;
51*a2847172SGrzegorz Jaszczyk }
52*a2847172SGrzegorz Jaszczyk 
53*a2847172SGrzegorz Jaszczyk /*****************************************************************************
54*a2847172SGrzegorz Jaszczyk  * mss_pm_ipc_msg_trigger
55*a2847172SGrzegorz Jaszczyk  *
56*a2847172SGrzegorz Jaszczyk  * DESCRIPTION: Trigger IPC message interrupt to MSS
57*a2847172SGrzegorz Jaszczyk  *****************************************************************************
58*a2847172SGrzegorz Jaszczyk  */
mss_pm_ipc_msg_trigger(void)59*a2847172SGrzegorz Jaszczyk int mss_pm_ipc_msg_trigger(void)
60*a2847172SGrzegorz Jaszczyk {
61*a2847172SGrzegorz Jaszczyk 	unsigned int timeout;
62*a2847172SGrzegorz Jaszczyk 	unsigned int t_end;
63*a2847172SGrzegorz Jaszczyk 	unsigned int t_start = mmio_read_32(MSS_TIMER_BASE);
64*a2847172SGrzegorz Jaszczyk 
65*a2847172SGrzegorz Jaszczyk 	mmio_write_32(MSS_SISR, MSS_MSG_INT_MASK);
66*a2847172SGrzegorz Jaszczyk 
67*a2847172SGrzegorz Jaszczyk 	do {
68*a2847172SGrzegorz Jaszczyk 		/* wait while SCP process incoming interrupt */
69*a2847172SGrzegorz Jaszczyk 		if (mmio_read_32(MSS_SISTR) != MSS_MSG_INT_MASK)
70*a2847172SGrzegorz Jaszczyk 			break;
71*a2847172SGrzegorz Jaszczyk 
72*a2847172SGrzegorz Jaszczyk 		/* check timeout */
73*a2847172SGrzegorz Jaszczyk 		t_end = mmio_read_32(MSS_TIMER_BASE);
74*a2847172SGrzegorz Jaszczyk 
75*a2847172SGrzegorz Jaszczyk 		timeout = ((t_start > t_end) ?
76*a2847172SGrzegorz Jaszczyk 			   (t_start - t_end) : (t_end - t_start));
77*a2847172SGrzegorz Jaszczyk 		if (timeout > MSS_TRIGGER_TIMEOUT) {
78*a2847172SGrzegorz Jaszczyk 			ERROR("PM MSG Trigger Timeout\n");
79*a2847172SGrzegorz Jaszczyk 			break;
80*a2847172SGrzegorz Jaszczyk 		}
81*a2847172SGrzegorz Jaszczyk 
82*a2847172SGrzegorz Jaszczyk 	} while (1);
83*a2847172SGrzegorz Jaszczyk 
84*a2847172SGrzegorz Jaszczyk 	return 0;
85*a2847172SGrzegorz Jaszczyk }
86