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