2 * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
4 * SPDX-License-Identifier: BSD-3-Clause
7 #include <arch_helpers.h>
10 #include <common/debug.h>
11 #include <drivers/delay_timer.h>
14 #include <plat/common/platform.h>
17 #include <tegra_def.h>
19 #define BPMP_TIMEOUT 500 /* 500ms */
21 static uint32_t channel_base
[NR_CHANNELS
];
22 static uint32_t bpmp_init_state
= BPMP_INIT_PENDING
;
24 static uint32_t channel_field(unsigned int ch
)
26 return mmio_read_32(TEGRA_RES_SEMA_BASE
+ STA_OFFSET
) & CH_MASK(ch
);
29 static bool master_free(unsigned int ch
)
31 return channel_field(ch
) == MA_FREE(ch
);
34 static bool master_acked(unsigned int ch
)
36 return channel_field(ch
) == MA_ACKD(ch
);
39 static void signal_slave(unsigned int ch
)
41 mmio_write_32(TEGRA_RES_SEMA_BASE
+ CLR_OFFSET
, CH_MASK(ch
));
44 static void free_master(unsigned int ch
)
46 mmio_write_32(TEGRA_RES_SEMA_BASE
+ CLR_OFFSET
,
47 MA_ACKD(ch
) ^ MA_FREE(ch
));
50 /* should be called with local irqs disabled */
51 int32_t tegra_bpmp_send_receive_atomic(int mrq
, const void *ob_data
, int ob_sz
,
52 void *ib_data
, int ib_sz
)
54 unsigned int ch
= (unsigned int)plat_my_core_pos();
55 mb_data_t
*p
= (mb_data_t
*)(uintptr_t)channel_base
[ch
];
56 int32_t ret
= -ETIMEDOUT
, timeout
= 0;
58 if (bpmp_init_state
== BPMP_INIT_COMPLETE
) {
60 /* loop until BPMP is free */
61 for (timeout
= 0; timeout
< BPMP_TIMEOUT
; timeout
++) {
62 if (master_free(ch
) == true) {
69 if (timeout
!= BPMP_TIMEOUT
) {
71 /* generate the command struct */
74 (void)memcpy((void *)p
->data
, ob_data
, (size_t)ob_sz
);
76 /* signal command ready to the BPMP */
78 mmio_write_32(TEGRA_PRI_ICTLR_BASE
+ CPU_IEP_FIR_SET
,
79 (1U << INT_SHR_SEM_OUTBOX_FULL
));
81 /* loop until the command is executed */
82 for (timeout
= 0; timeout
< BPMP_TIMEOUT
; timeout
++) {
83 if (master_acked(ch
) == true) {
90 if (timeout
!= BPMP_TIMEOUT
) {
92 /* get the command response */
93 (void)memcpy(ib_data
, (const void *)p
->data
,
96 /* return error code */
99 /* free this channel */
105 /* return error code */
109 if (timeout
== BPMP_TIMEOUT
) {
110 ERROR("Timed out waiting for bpmp's response\n");
116 int tegra_bpmp_init(void)
118 uint32_t val
, base
, timeout
= BPMP_TIMEOUT
;
122 if (bpmp_init_state
== BPMP_INIT_PENDING
) {
124 /* check if the bpmp processor is alive. */
126 val
= mmio_read_32(TEGRA_RES_SEMA_BASE
+ STA_OFFSET
);
127 if (val
!= SIGN_OF_LIFE
) {
132 } while ((val
!= SIGN_OF_LIFE
) && (timeout
> 0U));
134 if (val
== SIGN_OF_LIFE
) {
136 /* check if clock for the atomics block is enabled */
137 val
= mmio_read_32(TEGRA_CAR_RESET_BASE
+ TEGRA_CLK_ENB_V
);
138 if ((val
& CAR_ENABLE_ATOMICS
) == 0) {
139 ERROR("Clock to the atomics block is disabled\n");
142 /* check if the atomics block is out of reset */
143 val
= mmio_read_32(TEGRA_CAR_RESET_BASE
+ TEGRA_RST_DEV_CLR_V
);
144 if ((val
& CAR_ENABLE_ATOMICS
) == CAR_ENABLE_ATOMICS
) {
145 ERROR("Reset to the atomics block is asserted\n");
148 /* base address to get the result from Atomics */
149 base
= TEGRA_ATOMICS_BASE
+ RESULT0_REG_OFFSET
;
151 /* channel area is setup by BPMP before signaling handshake */
152 for (ch
= 0; ch
< NR_CHANNELS
; ch
++) {
154 /* issue command to get the channel base address */
155 mmio_write_32(base
, (ch
<< TRIGGER_ID_SHIFT
) |
158 /* get the base address for the channel */
159 channel_base
[ch
] = mmio_read_32(base
);
161 /* increment result register offset */
165 /* mark state as "initialized" */
166 bpmp_init_state
= BPMP_INIT_COMPLETE
;
168 /* the channel values have to be visible across all cpus */
169 flush_dcache_range((uint64_t)channel_base
,
170 sizeof(channel_base
));
171 flush_dcache_range((uint64_t)&bpmp_init_state
,
172 sizeof(bpmp_init_state
));
174 INFO("%s: done\n", __func__
);
177 ERROR("BPMP not powered on\n");
179 /* bpmp is not present in the system */
180 bpmp_init_state
= BPMP_NOT_PRESENT
;
182 /* communication timed out */
190 void tegra_bpmp_suspend(void)
192 /* freeze the interface */
193 if (bpmp_init_state
== BPMP_INIT_COMPLETE
) {
194 bpmp_init_state
= BPMP_SUSPEND_ENTRY
;
195 flush_dcache_range((uint64_t)&bpmp_init_state
,
196 sizeof(bpmp_init_state
));
200 void tegra_bpmp_resume(void)
202 uint32_t val
, timeout
= 0;
204 if (bpmp_init_state
== BPMP_SUSPEND_ENTRY
) {
206 /* check if the bpmp processor is alive. */
209 val
= mmio_read_32(TEGRA_RES_SEMA_BASE
+ STA_OFFSET
);
210 if (val
!= SIGN_OF_LIFE
) {
215 } while ((val
!= SIGN_OF_LIFE
) && (timeout
< BPMP_TIMEOUT
));
217 if (val
== SIGN_OF_LIFE
) {
219 INFO("%s: BPMP took %d ms to resume\n", __func__
, timeout
);
221 /* mark state as "initialized" */
222 bpmp_init_state
= BPMP_INIT_COMPLETE
;
224 /* state has to be visible across all cpus */
225 flush_dcache_range((uint64_t)&bpmp_init_state
,
226 sizeof(bpmp_init_state
));
228 ERROR("BPMP not powered on\n");