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