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