1 // SPDX-License-Identifier: BSD-2-Clause 2 /* 3 * Copyright (c) 2019, STMicroelectronics 4 */ 5 #include <assert.h> 6 #include <compiler.h> 7 #include <drivers/scmi-msg.h> 8 #include <drivers/scmi.h> 9 #include <dt-bindings/reset/stm32mp1-resets.h> 10 #include <initcall.h> 11 #include <mm/core_memprot.h> 12 #include <mm/core_mmu.h> 13 #include <platform_config.h> 14 #include <stdint.h> 15 #include <speculation_barrier.h> 16 #include <stm32_util.h> 17 #include <string.h> 18 #include <tee_api_defines.h> 19 #include <util.h> 20 21 #define TIMEOUT_US_1MS 1000 22 23 #define SCMI_RD_NAME_SIZE 16 24 25 /* 26 * struct stm32_scmi_rd - Data for the exposed reset controller 27 * @reset_id: Reset identifier in RCC reset driver 28 * @name: Reset string ID exposed to agent 29 */ 30 struct stm32_scmi_rd { 31 unsigned long reset_id; 32 const char *name; 33 }; 34 35 /* Locate all non-secure SMT message buffers in last page of SYSRAM */ 36 #define SMT_BUFFER_BASE CFG_STM32MP1_SCMI_SHM_BASE 37 #define SMT_BUFFER0_BASE SMT_BUFFER_BASE 38 #define SMT_BUFFER1_BASE (SMT_BUFFER_BASE + 0x200) 39 40 #if (SMT_BUFFER1_BASE + SMT_BUF_SLOT_SIZE > \ 41 CFG_STM32MP1_SCMI_SHM_BASE + CFG_STM32MP1_SCMI_SHM_SIZE) 42 #error "SCMI shared memory mismatch" 43 #endif 44 45 register_phys_mem(MEM_AREA_IO_NSEC, CFG_STM32MP1_SCMI_SHM_BASE, 46 CFG_STM32MP1_SCMI_SHM_SIZE); 47 48 static struct scmi_msg_channel scmi_channel[] = { 49 [0] = { 50 .agent_name = "stm32mp1-agent-0", 51 .shm_addr = { .pa = SMT_BUFFER0_BASE, }, 52 .shm_size = SMT_BUF_SLOT_SIZE, 53 }, 54 [1] = { 55 .agent_name = "stm32mp1-agent-1", 56 .shm_addr = { .pa = SMT_BUFFER1_BASE, }, 57 .shm_size = SMT_BUF_SLOT_SIZE, 58 }, 59 }; 60 61 struct scmi_msg_channel *plat_scmi_get_channel(unsigned int agent_id) 62 { 63 assert(agent_id < ARRAY_SIZE(scmi_channel)); 64 65 return &scmi_channel[agent_id]; 66 } 67 68 struct scmi_agent_resources { 69 struct stm32_scmi_clk *clock; 70 size_t clock_count; 71 struct stm32_scmi_rd *rd; 72 size_t rd_count; 73 struct stm32_scmi_pd *pd; 74 size_t pd_count; 75 struct stm32_scmi_perfs *perfs; 76 size_t perfs_count; 77 }; 78 79 const struct scmi_agent_resources agent_resources[] = { 80 [0] = { }, 81 [1] = { }, 82 }; 83 84 static size_t __maybe_unused plat_scmi_protocol_count_paranoid(void) 85 { 86 unsigned int n = 0; 87 unsigned int count = 0; 88 const size_t agent_count = ARRAY_SIZE(agent_resources); 89 90 for (n = 0; n < agent_count; n++) 91 if (agent_resources[n].clock_count) 92 break; 93 if (n < agent_count) 94 count++; 95 96 for (n = 0; n < agent_count; n++) 97 if (agent_resources[n].rd_count) 98 break; 99 if (n < agent_count) 100 count++; 101 102 for (n = 0; n < agent_count; n++) 103 if (agent_resources[n].pd_count) 104 break; 105 if (n < agent_count) 106 count++; 107 108 for (n = 0; n < agent_count; n++) 109 if (agent_resources[n].perfs_count) 110 break; 111 if (n < agent_count) 112 count++; 113 114 return count; 115 } 116 117 static const char vendor[] = "ST"; 118 static const char sub_vendor[] = ""; 119 120 const char *plat_scmi_vendor_name(void) 121 { 122 return vendor; 123 } 124 125 const char *plat_scmi_sub_vendor_name(void) 126 { 127 return sub_vendor; 128 } 129 130 /* Currently supporting only SCMI Base protocol */ 131 static const uint8_t plat_protocol_list[] = { 132 0 /* Null termination */ 133 }; 134 135 size_t plat_scmi_protocol_count(void) 136 { 137 const size_t count = ARRAY_SIZE(plat_protocol_list) - 1; 138 139 assert(count == plat_scmi_protocol_count_paranoid()); 140 141 return count; 142 } 143 144 const uint8_t *plat_scmi_protocol_list(unsigned int agent_id __unused) 145 { 146 assert(plat_scmi_protocol_count_paranoid() == 147 (ARRAY_SIZE(plat_protocol_list) - 1)); 148 149 return plat_protocol_list; 150 } 151 152 /* 153 * Initialize platform SCMI resources 154 */ 155 static TEE_Result stm32mp1_init_scmi_server(void) 156 { 157 size_t i = 0; 158 159 for (i = 0; i < ARRAY_SIZE(scmi_channel); i++) { 160 struct scmi_msg_channel *chan = &scmi_channel[i]; 161 162 /* Enforce non-secure shm mapped as device memory */ 163 chan->shm_addr.va = (vaddr_t)phys_to_virt(chan->shm_addr.pa, 164 MEM_AREA_IO_NSEC); 165 assert(chan->shm_addr.va); 166 167 scmi_smt_init_agent_channel(chan); 168 } 169 170 return TEE_SUCCESS; 171 } 172 173 driver_init_late(stm32mp1_init_scmi_server); 174