1*91f16700Schasinglulu /* 2*91f16700Schasinglulu * Copyright (c) 2018-2019, ARM Limited and Contributors. All rights reserved. 3*91f16700Schasinglulu * 4*91f16700Schasinglulu * SPDX-License-Identifier: BSD-3-Clause 5*91f16700Schasinglulu */ 6*91f16700Schasinglulu 7*91f16700Schasinglulu #include <assert.h> 8*91f16700Schasinglulu #include <crypto/sha_dma.h> 9*91f16700Schasinglulu #include <lib/mmio.h> 10*91f16700Schasinglulu #include <plat/common/platform.h> 11*91f16700Schasinglulu #include <platform_def.h> 12*91f16700Schasinglulu #include <string.h> 13*91f16700Schasinglulu 14*91f16700Schasinglulu #include "aml_private.h" 15*91f16700Schasinglulu 16*91f16700Schasinglulu #define SIZE_SHIFT 20 17*91f16700Schasinglulu #define SIZE_MASK 0x1FF 18*91f16700Schasinglulu #define SIZE_FWBLK 0x200UL 19*91f16700Schasinglulu 20*91f16700Schasinglulu /* 21*91f16700Schasinglulu * Note: The Amlogic SCP firmware uses the legacy SCPI protocol. 22*91f16700Schasinglulu */ 23*91f16700Schasinglulu #define SCPI_CMD_SET_CSS_POWER_STATE 0x04 24*91f16700Schasinglulu #define SCPI_CMD_SET_SYS_POWER_STATE 0x08 25*91f16700Schasinglulu 26*91f16700Schasinglulu #define SCPI_CMD_JTAG_SET_STATE 0xC0 27*91f16700Schasinglulu #define SCPI_CMD_EFUSE_READ 0xC2 28*91f16700Schasinglulu #define SCPI_CMD_CHIP_ID 0xC6 29*91f16700Schasinglulu 30*91f16700Schasinglulu #define SCPI_CMD_COPY_FW 0xd4 31*91f16700Schasinglulu #define SCPI_CMD_SET_FW_ADDR 0xd3 32*91f16700Schasinglulu #define SCPI_CMD_FW_SIZE 0xd2 33*91f16700Schasinglulu 34*91f16700Schasinglulu static inline uint32_t aml_scpi_cmd(uint32_t command, uint32_t size) 35*91f16700Schasinglulu { 36*91f16700Schasinglulu return command | (size << SIZE_SHIFT); 37*91f16700Schasinglulu } 38*91f16700Schasinglulu 39*91f16700Schasinglulu static void aml_scpi_secure_message_send(uint32_t command, uint32_t size) 40*91f16700Schasinglulu { 41*91f16700Schasinglulu aml_mhu_secure_message_send(aml_scpi_cmd(command, size)); 42*91f16700Schasinglulu } 43*91f16700Schasinglulu 44*91f16700Schasinglulu static uint32_t aml_scpi_secure_message_receive(void **message_out, size_t *size_out) 45*91f16700Schasinglulu { 46*91f16700Schasinglulu uint32_t response = aml_mhu_secure_message_wait(); 47*91f16700Schasinglulu 48*91f16700Schasinglulu size_t size = (response >> SIZE_SHIFT) & SIZE_MASK; 49*91f16700Schasinglulu 50*91f16700Schasinglulu response &= ~(SIZE_MASK << SIZE_SHIFT); 51*91f16700Schasinglulu 52*91f16700Schasinglulu if (size_out != NULL) 53*91f16700Schasinglulu *size_out = size; 54*91f16700Schasinglulu 55*91f16700Schasinglulu if (message_out != NULL) 56*91f16700Schasinglulu *message_out = (void *)AML_MHU_SECURE_SCP_TO_AP_PAYLOAD; 57*91f16700Schasinglulu 58*91f16700Schasinglulu return response; 59*91f16700Schasinglulu } 60*91f16700Schasinglulu 61*91f16700Schasinglulu void aml_scpi_set_css_power_state(u_register_t mpidr, uint32_t cpu_state, 62*91f16700Schasinglulu uint32_t cluster_state, uint32_t css_state) 63*91f16700Schasinglulu { 64*91f16700Schasinglulu uint32_t state = (mpidr & 0x0F) | /* CPU ID */ 65*91f16700Schasinglulu ((mpidr & 0xF00) >> 4) | /* Cluster ID */ 66*91f16700Schasinglulu (cpu_state << 8) | 67*91f16700Schasinglulu (cluster_state << 12) | 68*91f16700Schasinglulu (css_state << 16); 69*91f16700Schasinglulu 70*91f16700Schasinglulu aml_mhu_secure_message_start(); 71*91f16700Schasinglulu mmio_write_32(AML_MHU_SECURE_AP_TO_SCP_PAYLOAD, state); 72*91f16700Schasinglulu aml_mhu_secure_message_send(aml_scpi_cmd(SCPI_CMD_SET_CSS_POWER_STATE, 4)); 73*91f16700Schasinglulu aml_mhu_secure_message_wait(); 74*91f16700Schasinglulu aml_mhu_secure_message_end(); 75*91f16700Schasinglulu } 76*91f16700Schasinglulu 77*91f16700Schasinglulu uint32_t aml_scpi_sys_power_state(uint64_t system_state) 78*91f16700Schasinglulu { 79*91f16700Schasinglulu uint32_t *response; 80*91f16700Schasinglulu size_t size; 81*91f16700Schasinglulu 82*91f16700Schasinglulu aml_mhu_secure_message_start(); 83*91f16700Schasinglulu mmio_write_8(AML_MHU_SECURE_AP_TO_SCP_PAYLOAD, system_state); 84*91f16700Schasinglulu aml_mhu_secure_message_send(aml_scpi_cmd(SCPI_CMD_SET_SYS_POWER_STATE, 1)); 85*91f16700Schasinglulu aml_scpi_secure_message_receive((void *)&response, &size); 86*91f16700Schasinglulu aml_mhu_secure_message_end(); 87*91f16700Schasinglulu 88*91f16700Schasinglulu return *response; 89*91f16700Schasinglulu } 90*91f16700Schasinglulu 91*91f16700Schasinglulu void aml_scpi_jtag_set_state(uint32_t state, uint8_t select) 92*91f16700Schasinglulu { 93*91f16700Schasinglulu assert(state <= AML_JTAG_STATE_OFF); 94*91f16700Schasinglulu 95*91f16700Schasinglulu if (select > AML_JTAG_A53_EE) { 96*91f16700Schasinglulu WARN("BL31: Invalid JTAG select (0x%x).\n", select); 97*91f16700Schasinglulu return; 98*91f16700Schasinglulu } 99*91f16700Schasinglulu 100*91f16700Schasinglulu aml_mhu_secure_message_start(); 101*91f16700Schasinglulu mmio_write_32(AML_MHU_SECURE_AP_TO_SCP_PAYLOAD, 102*91f16700Schasinglulu (state << 8) | (uint32_t)select); 103*91f16700Schasinglulu aml_mhu_secure_message_send(aml_scpi_cmd(SCPI_CMD_JTAG_SET_STATE, 4)); 104*91f16700Schasinglulu aml_mhu_secure_message_wait(); 105*91f16700Schasinglulu aml_mhu_secure_message_end(); 106*91f16700Schasinglulu } 107*91f16700Schasinglulu 108*91f16700Schasinglulu uint32_t aml_scpi_efuse_read(void *dst, uint32_t base, uint32_t size) 109*91f16700Schasinglulu { 110*91f16700Schasinglulu uint32_t *response; 111*91f16700Schasinglulu size_t resp_size; 112*91f16700Schasinglulu 113*91f16700Schasinglulu if (size > 0x1FC) 114*91f16700Schasinglulu return 0; 115*91f16700Schasinglulu 116*91f16700Schasinglulu aml_mhu_secure_message_start(); 117*91f16700Schasinglulu mmio_write_32(AML_MHU_SECURE_AP_TO_SCP_PAYLOAD, base); 118*91f16700Schasinglulu mmio_write_32(AML_MHU_SECURE_AP_TO_SCP_PAYLOAD + 4, size); 119*91f16700Schasinglulu aml_mhu_secure_message_send(aml_scpi_cmd(SCPI_CMD_EFUSE_READ, 8)); 120*91f16700Schasinglulu aml_scpi_secure_message_receive((void *)&response, &resp_size); 121*91f16700Schasinglulu aml_mhu_secure_message_end(); 122*91f16700Schasinglulu 123*91f16700Schasinglulu /* 124*91f16700Schasinglulu * response[0] is the size of the response message. 125*91f16700Schasinglulu * response[1 ... N] are the contents. 126*91f16700Schasinglulu */ 127*91f16700Schasinglulu if (*response != 0) 128*91f16700Schasinglulu memcpy(dst, response + 1, *response); 129*91f16700Schasinglulu 130*91f16700Schasinglulu return *response; 131*91f16700Schasinglulu } 132*91f16700Schasinglulu 133*91f16700Schasinglulu void aml_scpi_unknown_thermal(uint32_t arg0, uint32_t arg1, 134*91f16700Schasinglulu uint32_t arg2, uint32_t arg3) 135*91f16700Schasinglulu { 136*91f16700Schasinglulu aml_mhu_secure_message_start(); 137*91f16700Schasinglulu mmio_write_32(AML_MHU_SECURE_AP_TO_SCP_PAYLOAD + 0x0, arg0); 138*91f16700Schasinglulu mmio_write_32(AML_MHU_SECURE_AP_TO_SCP_PAYLOAD + 0x4, arg1); 139*91f16700Schasinglulu mmio_write_32(AML_MHU_SECURE_AP_TO_SCP_PAYLOAD + 0x8, arg2); 140*91f16700Schasinglulu mmio_write_32(AML_MHU_SECURE_AP_TO_SCP_PAYLOAD + 0xC, arg3); 141*91f16700Schasinglulu aml_mhu_secure_message_send(aml_scpi_cmd(0xC3, 16)); 142*91f16700Schasinglulu aml_mhu_secure_message_wait(); 143*91f16700Schasinglulu aml_mhu_secure_message_end(); 144*91f16700Schasinglulu } 145*91f16700Schasinglulu 146*91f16700Schasinglulu uint32_t aml_scpi_get_chip_id(uint8_t *obuff, uint32_t osize) 147*91f16700Schasinglulu { 148*91f16700Schasinglulu uint32_t *response; 149*91f16700Schasinglulu size_t resp_size; 150*91f16700Schasinglulu 151*91f16700Schasinglulu if ((osize != 16) && (osize != 12)) 152*91f16700Schasinglulu return 0; 153*91f16700Schasinglulu 154*91f16700Schasinglulu aml_mhu_secure_message_start(); 155*91f16700Schasinglulu aml_mhu_secure_message_send(aml_scpi_cmd(SCPI_CMD_CHIP_ID, osize)); 156*91f16700Schasinglulu aml_scpi_secure_message_receive((void *)&response, &resp_size); 157*91f16700Schasinglulu aml_mhu_secure_message_end(); 158*91f16700Schasinglulu 159*91f16700Schasinglulu if (!((resp_size == 16) && (osize == 16)) && 160*91f16700Schasinglulu !((resp_size == 0) && (osize == 12))) 161*91f16700Schasinglulu return 0; 162*91f16700Schasinglulu 163*91f16700Schasinglulu memcpy((void *)obuff, (const void *)response, osize); 164*91f16700Schasinglulu 165*91f16700Schasinglulu return osize; 166*91f16700Schasinglulu } 167*91f16700Schasinglulu 168*91f16700Schasinglulu static inline void aml_scpi_copy_scp_data(uint8_t *data, size_t len) 169*91f16700Schasinglulu { 170*91f16700Schasinglulu void *dst = (void *)AML_MHU_SECURE_AP_TO_SCP_PAYLOAD; 171*91f16700Schasinglulu size_t sz; 172*91f16700Schasinglulu 173*91f16700Schasinglulu mmio_write_32(AML_MHU_SECURE_AP_TO_SCP_PAYLOAD, len); 174*91f16700Schasinglulu aml_scpi_secure_message_send(SCPI_CMD_FW_SIZE, len); 175*91f16700Schasinglulu aml_mhu_secure_message_wait(); 176*91f16700Schasinglulu 177*91f16700Schasinglulu for (sz = 0; sz < len; sz += SIZE_FWBLK) { 178*91f16700Schasinglulu memcpy(dst, data + sz, MIN(SIZE_FWBLK, len - sz)); 179*91f16700Schasinglulu aml_mhu_secure_message_send(SCPI_CMD_COPY_FW); 180*91f16700Schasinglulu } 181*91f16700Schasinglulu } 182*91f16700Schasinglulu 183*91f16700Schasinglulu static inline void aml_scpi_set_scp_addr(uint64_t addr, size_t len) 184*91f16700Schasinglulu { 185*91f16700Schasinglulu volatile uint64_t *dst = (uint64_t *)AML_MHU_SECURE_AP_TO_SCP_PAYLOAD; 186*91f16700Schasinglulu 187*91f16700Schasinglulu /* 188*91f16700Schasinglulu * It is ok as AML_MHU_SECURE_AP_TO_SCP_PAYLOAD is mapped as 189*91f16700Schasinglulu * non cachable 190*91f16700Schasinglulu */ 191*91f16700Schasinglulu *dst = addr; 192*91f16700Schasinglulu aml_scpi_secure_message_send(SCPI_CMD_SET_FW_ADDR, sizeof(addr)); 193*91f16700Schasinglulu aml_mhu_secure_message_wait(); 194*91f16700Schasinglulu 195*91f16700Schasinglulu mmio_write_32(AML_MHU_SECURE_AP_TO_SCP_PAYLOAD, len); 196*91f16700Schasinglulu aml_scpi_secure_message_send(SCPI_CMD_FW_SIZE, len); 197*91f16700Schasinglulu aml_mhu_secure_message_wait(); 198*91f16700Schasinglulu } 199*91f16700Schasinglulu 200*91f16700Schasinglulu static inline void aml_scpi_send_fw_hash(uint8_t hash[], size_t len) 201*91f16700Schasinglulu { 202*91f16700Schasinglulu void *dst = (void *)AML_MHU_SECURE_AP_TO_SCP_PAYLOAD; 203*91f16700Schasinglulu 204*91f16700Schasinglulu memcpy(dst, hash, len); 205*91f16700Schasinglulu aml_mhu_secure_message_send(0xd0); 206*91f16700Schasinglulu aml_mhu_secure_message_send(0xd1); 207*91f16700Schasinglulu aml_mhu_secure_message_send(0xd5); 208*91f16700Schasinglulu aml_mhu_secure_message_end(); 209*91f16700Schasinglulu } 210*91f16700Schasinglulu 211*91f16700Schasinglulu /** 212*91f16700Schasinglulu * Upload a FW to SCP. 213*91f16700Schasinglulu * 214*91f16700Schasinglulu * @param addr: firmware data address 215*91f16700Schasinglulu * @param size: size of firmware 216*91f16700Schasinglulu * @param send: If set, actually copy the firmware in SCP memory otherwise only 217*91f16700Schasinglulu * send the firmware address. 218*91f16700Schasinglulu */ 219*91f16700Schasinglulu void aml_scpi_upload_scp_fw(uintptr_t addr, size_t size, int send) 220*91f16700Schasinglulu { 221*91f16700Schasinglulu struct asd_ctx ctx; 222*91f16700Schasinglulu 223*91f16700Schasinglulu asd_sha_init(&ctx, ASM_SHA256); 224*91f16700Schasinglulu asd_sha_update(&ctx, (void *)addr, size); 225*91f16700Schasinglulu asd_sha_finalize(&ctx); 226*91f16700Schasinglulu 227*91f16700Schasinglulu aml_mhu_secure_message_start(); 228*91f16700Schasinglulu if (send == 0) 229*91f16700Schasinglulu aml_scpi_set_scp_addr(addr, size); 230*91f16700Schasinglulu else 231*91f16700Schasinglulu aml_scpi_copy_scp_data((void *)addr, size); 232*91f16700Schasinglulu 233*91f16700Schasinglulu aml_scpi_send_fw_hash(ctx.digest, sizeof(ctx.digest)); 234*91f16700Schasinglulu } 235