blob: 3917638182ac316e3c581063f3d5629d6944e890 [file] [log] [blame]
developerda573122019-08-21 21:17:49 +08001/*
2 * Copyright (c) 2019, ARM Limited and Contributors. All rights reserved.
3 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 */
6#include <arch_helpers.h>
7#include <common/debug.h>
8#include <drivers/delay_timer.h>
9#include <errno.h>
10#include <lib/mmio.h>
11#include <sspm.h>
12
13static void memcpy_to_sspm(uint32_t dst, uint32_t *src, uint32_t len)
14{
15 while (len--) {
16 mmio_write_32(dst, *src);
17 dst += sizeof(uint32_t);
18 src++;
19 }
20}
21
22static void memcpy_from_sspm(uint32_t *dst, uint32_t src, uint32_t len)
23{
24 while (len--) {
25 *dst = mmio_read_32(src);
26 dst++;
27 src += sizeof(uint32_t);
28 }
29}
30
31int sspm_mbox_read(uint32_t slot, uint32_t *data, uint32_t len)
32{
33 if (slot >= 32) {
34 ERROR("%s:slot = %d\n", __func__, slot);
35 return -EINVAL;
36 }
37
38 if (data)
39 memcpy_from_sspm(data,
40 MBOX3_BASE + slot * 4,
41 len);
42
43 return 0;
44}
45
46int sspm_mbox_write(uint32_t slot, uint32_t *data, uint32_t len)
47{
48 if (slot >= 32) {
49 ERROR("%s:slot = %d\n", __func__, slot);
50 return -EINVAL;
51 }
52
53 if (data)
54 memcpy_to_sspm(MBOX3_BASE + slot * 4,
55 data,
56 len);
57
58 return 0;
59}
60
61static int sspm_ipi_check_ack(uint32_t id)
62{
63 int ret = 0;
64
65 if (id == IPI_ID_PLATFORM) {
66 if ((mmio_read_32(MBOX0_BASE + MBOX_IN_IRQ_OFS) & 0x1) == 0x1)
67 ret = -EINPROGRESS;
68 } else if (id == IPI_ID_SUSPEND) {
69 if ((mmio_read_32(MBOX1_BASE + MBOX_IN_IRQ_OFS) & 0x2) == 0x2)
70 ret = -EINPROGRESS;
71 } else {
72 ERROR("%s: id = %d\n", __func__, id);
73 ret = -EINVAL;
74 }
75
76 return ret;
77}
78
79int sspm_ipi_send_non_blocking(uint32_t id, uint32_t *data)
80{
81 int ret = 0;
82
83 ret = sspm_ipi_check_ack(id);
84 if (ret)
85 return ret;
86
87 if (id == IPI_ID_PLATFORM) {
88 memcpy_to_sspm(MBOX0_BASE + PINR_OFFSET_PLATFORM * 4,
89 data,
90 PINR_SIZE_PLATFORM);
91 dsb();
92 mmio_write_32(MBOX0_BASE + MBOX_OUT_IRQ_OFS, 0x1);
93 } else if (id == IPI_ID_SUSPEND) {
94 memcpy_to_sspm(MBOX1_BASE + PINR_OFFSET_SUSPEND * 4,
95 data,
96 PINR_SIZE_SUSPEND);
97 dsb();
98 mmio_write_32(MBOX1_BASE + MBOX_OUT_IRQ_OFS,
99 0x2);
100 }
101
102 return 0;
103}
104
105int sspm_ipi_recv_non_blocking(uint32_t id, uint32_t *data, uint32_t len)
106{
107 int ret = 0;
108
109 ret = sspm_ipi_check_ack(id);
110 if (ret == -EINPROGRESS) {
111 if (id == IPI_ID_PLATFORM) {
112 memcpy_from_sspm(data,
113 MBOX0_BASE + PINR_OFFSET_PLATFORM * 4,
114 len);
115 dsb();
116 /* clear interrupt bit*/
117 mmio_write_32(MBOX0_BASE + MBOX_IN_IRQ_OFS,
118 0x1);
119 ret = 0;
120 } else if (id == IPI_ID_SUSPEND) {
121 memcpy_from_sspm(data,
122 MBOX1_BASE + PINR_OFFSET_SUSPEND * 4,
123 len);
124 dsb();
125 /* clear interrupt bit*/
126 mmio_write_32(MBOX1_BASE + MBOX_IN_IRQ_OFS,
127 0x2);
128 ret = 0;
129 }
130 } else if (ret == 0) {
131 ret = -EBUSY;
132 }
133
134 return ret;
135}
136
137int sspm_alive_show(void)
138{
139 uint32_t ipi_data, count;
140 int ret = 0;
141
142 count = 5;
143 ipi_data = 0xdead;
144
145 if (sspm_ipi_send_non_blocking(IPI_ID_PLATFORM, &ipi_data) != 0) {
146 ERROR("sspm init send fail! ret=%d\n", ret);
147 return -1;
148 }
149
150 while (sspm_ipi_recv_non_blocking(IPI_ID_PLATFORM,
151 &ipi_data,
152 sizeof(ipi_data))
153 && count) {
154 mdelay(100);
155 count--;
156 }
157
158 return (ipi_data == 1) ? 0 : -1;
159}