1*91f16700Schasinglulu /* 2*91f16700Schasinglulu * Copyright (c) 2019-2021, STMicroelectronics - All Rights Reserved 3*91f16700Schasinglulu * 4*91f16700Schasinglulu * SPDX-License-Identifier: BSD-3-Clause 5*91f16700Schasinglulu */ 6*91f16700Schasinglulu #include <assert.h> 7*91f16700Schasinglulu #include <stdint.h> 8*91f16700Schasinglulu 9*91f16700Schasinglulu #include <platform_def.h> 10*91f16700Schasinglulu 11*91f16700Schasinglulu #include <drivers/clk.h> 12*91f16700Schasinglulu #include <drivers/scmi-msg.h> 13*91f16700Schasinglulu #include <drivers/scmi.h> 14*91f16700Schasinglulu #include <drivers/st/stm32mp1_clk.h> 15*91f16700Schasinglulu #include <drivers/st/stm32mp_reset.h> 16*91f16700Schasinglulu #include <dt-bindings/clock/stm32mp1-clks.h> 17*91f16700Schasinglulu #include <dt-bindings/reset/stm32mp1-resets.h> 18*91f16700Schasinglulu 19*91f16700Schasinglulu #define TIMEOUT_US_1MS 1000U 20*91f16700Schasinglulu 21*91f16700Schasinglulu #define SCMI_CLOCK_NAME_SIZE 16U 22*91f16700Schasinglulu #define SCMI_RSTD_NAME_SIZE 16U 23*91f16700Schasinglulu 24*91f16700Schasinglulu /* 25*91f16700Schasinglulu * struct stm32_scmi_clk - Data for the exposed clock 26*91f16700Schasinglulu * @clock_id: Clock identifier in RCC clock driver 27*91f16700Schasinglulu * @name: Clock string ID exposed to agent 28*91f16700Schasinglulu * @enabled: State of the SCMI clock 29*91f16700Schasinglulu */ 30*91f16700Schasinglulu struct stm32_scmi_clk { 31*91f16700Schasinglulu unsigned long clock_id; 32*91f16700Schasinglulu const char *name; 33*91f16700Schasinglulu bool enabled; 34*91f16700Schasinglulu }; 35*91f16700Schasinglulu 36*91f16700Schasinglulu /* 37*91f16700Schasinglulu * struct stm32_scmi_rstd - Data for the exposed reset controller 38*91f16700Schasinglulu * @reset_id: Reset identifier in RCC reset driver 39*91f16700Schasinglulu * @name: Reset string ID exposed to agent 40*91f16700Schasinglulu */ 41*91f16700Schasinglulu struct stm32_scmi_rstd { 42*91f16700Schasinglulu unsigned long reset_id; 43*91f16700Schasinglulu const char *name; 44*91f16700Schasinglulu }; 45*91f16700Schasinglulu 46*91f16700Schasinglulu /* Locate all non-secure SMT message buffers in last page of SYSRAM */ 47*91f16700Schasinglulu #define SMT_BUFFER_BASE STM32MP_SCMI_NS_SHM_BASE 48*91f16700Schasinglulu #define SMT_BUFFER0_BASE SMT_BUFFER_BASE 49*91f16700Schasinglulu #define SMT_BUFFER1_BASE (SMT_BUFFER_BASE + 0x200) 50*91f16700Schasinglulu 51*91f16700Schasinglulu CASSERT((STM32MP_SCMI_NS_SHM_BASE + STM32MP_SCMI_NS_SHM_SIZE) >= 52*91f16700Schasinglulu (SMT_BUFFER1_BASE + SMT_BUF_SLOT_SIZE), 53*91f16700Schasinglulu assert_scmi_non_secure_shm_fits_scmi_overall_buffer_size); 54*91f16700Schasinglulu 55*91f16700Schasinglulu static struct scmi_msg_channel scmi_channel[] = { 56*91f16700Schasinglulu [0] = { 57*91f16700Schasinglulu .shm_addr = SMT_BUFFER0_BASE, 58*91f16700Schasinglulu .shm_size = SMT_BUF_SLOT_SIZE, 59*91f16700Schasinglulu }, 60*91f16700Schasinglulu [1] = { 61*91f16700Schasinglulu .shm_addr = SMT_BUFFER1_BASE, 62*91f16700Schasinglulu .shm_size = SMT_BUF_SLOT_SIZE, 63*91f16700Schasinglulu }, 64*91f16700Schasinglulu }; 65*91f16700Schasinglulu 66*91f16700Schasinglulu struct scmi_msg_channel *plat_scmi_get_channel(unsigned int agent_id) 67*91f16700Schasinglulu { 68*91f16700Schasinglulu assert(agent_id < ARRAY_SIZE(scmi_channel)); 69*91f16700Schasinglulu 70*91f16700Schasinglulu return &scmi_channel[agent_id]; 71*91f16700Schasinglulu } 72*91f16700Schasinglulu 73*91f16700Schasinglulu #define CLOCK_CELL(_scmi_id, _id, _name, _init_enabled) \ 74*91f16700Schasinglulu [_scmi_id] = { \ 75*91f16700Schasinglulu .clock_id = _id, \ 76*91f16700Schasinglulu .name = _name, \ 77*91f16700Schasinglulu .enabled = _init_enabled, \ 78*91f16700Schasinglulu } 79*91f16700Schasinglulu 80*91f16700Schasinglulu static struct stm32_scmi_clk stm32_scmi0_clock[] = { 81*91f16700Schasinglulu CLOCK_CELL(CK_SCMI0_HSE, CK_HSE, "ck_hse", true), 82*91f16700Schasinglulu CLOCK_CELL(CK_SCMI0_HSI, CK_HSI, "ck_hsi", true), 83*91f16700Schasinglulu CLOCK_CELL(CK_SCMI0_CSI, CK_CSI, "ck_csi", true), 84*91f16700Schasinglulu CLOCK_CELL(CK_SCMI0_LSE, CK_LSE, "ck_lse", true), 85*91f16700Schasinglulu CLOCK_CELL(CK_SCMI0_LSI, CK_LSI, "ck_lsi", true), 86*91f16700Schasinglulu CLOCK_CELL(CK_SCMI0_PLL2_Q, PLL2_Q, "pll2_q", true), 87*91f16700Schasinglulu CLOCK_CELL(CK_SCMI0_PLL2_R, PLL2_R, "pll2_r", true), 88*91f16700Schasinglulu CLOCK_CELL(CK_SCMI0_MPU, CK_MPU, "ck_mpu", true), 89*91f16700Schasinglulu CLOCK_CELL(CK_SCMI0_AXI, CK_AXI, "ck_axi", true), 90*91f16700Schasinglulu CLOCK_CELL(CK_SCMI0_BSEC, BSEC, "bsec", true), 91*91f16700Schasinglulu CLOCK_CELL(CK_SCMI0_CRYP1, CRYP1, "cryp1", false), 92*91f16700Schasinglulu CLOCK_CELL(CK_SCMI0_GPIOZ, GPIOZ, "gpioz", false), 93*91f16700Schasinglulu CLOCK_CELL(CK_SCMI0_HASH1, HASH1, "hash1", false), 94*91f16700Schasinglulu CLOCK_CELL(CK_SCMI0_I2C4, I2C4_K, "i2c4_k", false), 95*91f16700Schasinglulu CLOCK_CELL(CK_SCMI0_I2C6, I2C6_K, "i2c6_k", false), 96*91f16700Schasinglulu CLOCK_CELL(CK_SCMI0_IWDG1, IWDG1, "iwdg1", false), 97*91f16700Schasinglulu CLOCK_CELL(CK_SCMI0_RNG1, RNG1_K, "rng1_k", true), 98*91f16700Schasinglulu CLOCK_CELL(CK_SCMI0_RTC, RTC, "ck_rtc", true), 99*91f16700Schasinglulu CLOCK_CELL(CK_SCMI0_RTCAPB, RTCAPB, "rtcapb", true), 100*91f16700Schasinglulu CLOCK_CELL(CK_SCMI0_SPI6, SPI6_K, "spi6_k", false), 101*91f16700Schasinglulu CLOCK_CELL(CK_SCMI0_USART1, USART1_K, "usart1_k", false), 102*91f16700Schasinglulu }; 103*91f16700Schasinglulu 104*91f16700Schasinglulu static struct stm32_scmi_clk stm32_scmi1_clock[] = { 105*91f16700Schasinglulu CLOCK_CELL(CK_SCMI1_PLL3_Q, PLL3_Q, "pll3_q", true), 106*91f16700Schasinglulu CLOCK_CELL(CK_SCMI1_PLL3_R, PLL3_R, "pll3_r", true), 107*91f16700Schasinglulu CLOCK_CELL(CK_SCMI1_MCU, CK_MCU, "ck_mcu", false), 108*91f16700Schasinglulu }; 109*91f16700Schasinglulu 110*91f16700Schasinglulu #define RESET_CELL(_scmi_id, _id, _name) \ 111*91f16700Schasinglulu [_scmi_id] = { \ 112*91f16700Schasinglulu .reset_id = _id, \ 113*91f16700Schasinglulu .name = _name, \ 114*91f16700Schasinglulu } 115*91f16700Schasinglulu 116*91f16700Schasinglulu static struct stm32_scmi_rstd stm32_scmi0_reset_domain[] = { 117*91f16700Schasinglulu RESET_CELL(RST_SCMI0_SPI6, SPI6_R, "spi6"), 118*91f16700Schasinglulu RESET_CELL(RST_SCMI0_I2C4, I2C4_R, "i2c4"), 119*91f16700Schasinglulu RESET_CELL(RST_SCMI0_I2C6, I2C6_R, "i2c6"), 120*91f16700Schasinglulu RESET_CELL(RST_SCMI0_USART1, USART1_R, "usart1"), 121*91f16700Schasinglulu RESET_CELL(RST_SCMI0_STGEN, STGEN_R, "stgen"), 122*91f16700Schasinglulu RESET_CELL(RST_SCMI0_GPIOZ, GPIOZ_R, "gpioz"), 123*91f16700Schasinglulu RESET_CELL(RST_SCMI0_CRYP1, CRYP1_R, "cryp1"), 124*91f16700Schasinglulu RESET_CELL(RST_SCMI0_HASH1, HASH1_R, "hash1"), 125*91f16700Schasinglulu RESET_CELL(RST_SCMI0_RNG1, RNG1_R, "rng1"), 126*91f16700Schasinglulu RESET_CELL(RST_SCMI0_MDMA, MDMA_R, "mdma"), 127*91f16700Schasinglulu RESET_CELL(RST_SCMI0_MCU, MCU_R, "mcu"), 128*91f16700Schasinglulu }; 129*91f16700Schasinglulu 130*91f16700Schasinglulu struct scmi_agent_resources { 131*91f16700Schasinglulu struct stm32_scmi_clk *clock; 132*91f16700Schasinglulu size_t clock_count; 133*91f16700Schasinglulu struct stm32_scmi_rstd *rstd; 134*91f16700Schasinglulu size_t rstd_count; 135*91f16700Schasinglulu }; 136*91f16700Schasinglulu 137*91f16700Schasinglulu static const struct scmi_agent_resources agent_resources[] = { 138*91f16700Schasinglulu [0] = { 139*91f16700Schasinglulu .clock = stm32_scmi0_clock, 140*91f16700Schasinglulu .clock_count = ARRAY_SIZE(stm32_scmi0_clock), 141*91f16700Schasinglulu .rstd = stm32_scmi0_reset_domain, 142*91f16700Schasinglulu .rstd_count = ARRAY_SIZE(stm32_scmi0_reset_domain), 143*91f16700Schasinglulu }, 144*91f16700Schasinglulu [1] = { 145*91f16700Schasinglulu .clock = stm32_scmi1_clock, 146*91f16700Schasinglulu .clock_count = ARRAY_SIZE(stm32_scmi1_clock), 147*91f16700Schasinglulu }, 148*91f16700Schasinglulu }; 149*91f16700Schasinglulu 150*91f16700Schasinglulu static const struct scmi_agent_resources *find_resource(unsigned int agent_id) 151*91f16700Schasinglulu { 152*91f16700Schasinglulu assert(agent_id < ARRAY_SIZE(agent_resources)); 153*91f16700Schasinglulu 154*91f16700Schasinglulu return &agent_resources[agent_id]; 155*91f16700Schasinglulu } 156*91f16700Schasinglulu 157*91f16700Schasinglulu #if ENABLE_ASSERTIONS 158*91f16700Schasinglulu static size_t plat_scmi_protocol_count_paranoid(void) 159*91f16700Schasinglulu { 160*91f16700Schasinglulu unsigned int n = 0U; 161*91f16700Schasinglulu unsigned int count = 0U; 162*91f16700Schasinglulu 163*91f16700Schasinglulu for (n = 0U; n < ARRAY_SIZE(agent_resources); n++) { 164*91f16700Schasinglulu if (agent_resources[n].clock_count) { 165*91f16700Schasinglulu count++; 166*91f16700Schasinglulu break; 167*91f16700Schasinglulu } 168*91f16700Schasinglulu } 169*91f16700Schasinglulu 170*91f16700Schasinglulu for (n = 0U; n < ARRAY_SIZE(agent_resources); n++) { 171*91f16700Schasinglulu if (agent_resources[n].rstd_count) { 172*91f16700Schasinglulu count++; 173*91f16700Schasinglulu break; 174*91f16700Schasinglulu } 175*91f16700Schasinglulu } 176*91f16700Schasinglulu 177*91f16700Schasinglulu return count; 178*91f16700Schasinglulu } 179*91f16700Schasinglulu #endif 180*91f16700Schasinglulu 181*91f16700Schasinglulu static const char vendor[] = "ST"; 182*91f16700Schasinglulu static const char sub_vendor[] = ""; 183*91f16700Schasinglulu 184*91f16700Schasinglulu const char *plat_scmi_vendor_name(void) 185*91f16700Schasinglulu { 186*91f16700Schasinglulu return vendor; 187*91f16700Schasinglulu } 188*91f16700Schasinglulu 189*91f16700Schasinglulu const char *plat_scmi_sub_vendor_name(void) 190*91f16700Schasinglulu { 191*91f16700Schasinglulu return sub_vendor; 192*91f16700Schasinglulu } 193*91f16700Schasinglulu 194*91f16700Schasinglulu /* Currently supporting Clocks and Reset Domains */ 195*91f16700Schasinglulu static const uint8_t plat_protocol_list[] = { 196*91f16700Schasinglulu SCMI_PROTOCOL_ID_CLOCK, 197*91f16700Schasinglulu SCMI_PROTOCOL_ID_RESET_DOMAIN, 198*91f16700Schasinglulu 0U /* Null termination */ 199*91f16700Schasinglulu }; 200*91f16700Schasinglulu 201*91f16700Schasinglulu size_t plat_scmi_protocol_count(void) 202*91f16700Schasinglulu { 203*91f16700Schasinglulu const size_t count = ARRAY_SIZE(plat_protocol_list) - 1U; 204*91f16700Schasinglulu 205*91f16700Schasinglulu assert(count == plat_scmi_protocol_count_paranoid()); 206*91f16700Schasinglulu 207*91f16700Schasinglulu return count; 208*91f16700Schasinglulu } 209*91f16700Schasinglulu 210*91f16700Schasinglulu const uint8_t *plat_scmi_protocol_list(unsigned int agent_id __unused) 211*91f16700Schasinglulu { 212*91f16700Schasinglulu assert(plat_scmi_protocol_count_paranoid() == 213*91f16700Schasinglulu (ARRAY_SIZE(plat_protocol_list) - 1U)); 214*91f16700Schasinglulu 215*91f16700Schasinglulu return plat_protocol_list; 216*91f16700Schasinglulu } 217*91f16700Schasinglulu 218*91f16700Schasinglulu /* 219*91f16700Schasinglulu * Platform SCMI clocks 220*91f16700Schasinglulu */ 221*91f16700Schasinglulu static struct stm32_scmi_clk *find_clock(unsigned int agent_id, 222*91f16700Schasinglulu unsigned int scmi_id) 223*91f16700Schasinglulu { 224*91f16700Schasinglulu const struct scmi_agent_resources *resource = find_resource(agent_id); 225*91f16700Schasinglulu size_t n = 0U; 226*91f16700Schasinglulu 227*91f16700Schasinglulu if (resource != NULL) { 228*91f16700Schasinglulu for (n = 0U; n < resource->clock_count; n++) { 229*91f16700Schasinglulu if (n == scmi_id) { 230*91f16700Schasinglulu return &resource->clock[n]; 231*91f16700Schasinglulu } 232*91f16700Schasinglulu } 233*91f16700Schasinglulu } 234*91f16700Schasinglulu 235*91f16700Schasinglulu return NULL; 236*91f16700Schasinglulu } 237*91f16700Schasinglulu 238*91f16700Schasinglulu size_t plat_scmi_clock_count(unsigned int agent_id) 239*91f16700Schasinglulu { 240*91f16700Schasinglulu const struct scmi_agent_resources *resource = find_resource(agent_id); 241*91f16700Schasinglulu 242*91f16700Schasinglulu if (resource == NULL) { 243*91f16700Schasinglulu return 0U; 244*91f16700Schasinglulu } 245*91f16700Schasinglulu 246*91f16700Schasinglulu return resource->clock_count; 247*91f16700Schasinglulu } 248*91f16700Schasinglulu 249*91f16700Schasinglulu const char *plat_scmi_clock_get_name(unsigned int agent_id, 250*91f16700Schasinglulu unsigned int scmi_id) 251*91f16700Schasinglulu { 252*91f16700Schasinglulu struct stm32_scmi_clk *clock = find_clock(agent_id, scmi_id); 253*91f16700Schasinglulu 254*91f16700Schasinglulu if ((clock == NULL) || 255*91f16700Schasinglulu !stm32mp_nsec_can_access_clock(clock->clock_id)) { 256*91f16700Schasinglulu return NULL; 257*91f16700Schasinglulu } 258*91f16700Schasinglulu 259*91f16700Schasinglulu return clock->name; 260*91f16700Schasinglulu } 261*91f16700Schasinglulu 262*91f16700Schasinglulu int32_t plat_scmi_clock_rates_array(unsigned int agent_id, unsigned int scmi_id, 263*91f16700Schasinglulu unsigned long *array, size_t *nb_elts, 264*91f16700Schasinglulu uint32_t start_idx) 265*91f16700Schasinglulu { 266*91f16700Schasinglulu struct stm32_scmi_clk *clock = find_clock(agent_id, scmi_id); 267*91f16700Schasinglulu 268*91f16700Schasinglulu if (clock == NULL) { 269*91f16700Schasinglulu return SCMI_NOT_FOUND; 270*91f16700Schasinglulu } 271*91f16700Schasinglulu 272*91f16700Schasinglulu if (!stm32mp_nsec_can_access_clock(clock->clock_id)) { 273*91f16700Schasinglulu return SCMI_DENIED; 274*91f16700Schasinglulu } 275*91f16700Schasinglulu 276*91f16700Schasinglulu if (start_idx > 0) { 277*91f16700Schasinglulu return SCMI_OUT_OF_RANGE; 278*91f16700Schasinglulu } 279*91f16700Schasinglulu 280*91f16700Schasinglulu if (array == NULL) { 281*91f16700Schasinglulu *nb_elts = 1U; 282*91f16700Schasinglulu } else if (*nb_elts == 1U) { 283*91f16700Schasinglulu *array = clk_get_rate(clock->clock_id); 284*91f16700Schasinglulu } else { 285*91f16700Schasinglulu return SCMI_GENERIC_ERROR; 286*91f16700Schasinglulu } 287*91f16700Schasinglulu 288*91f16700Schasinglulu return SCMI_SUCCESS; 289*91f16700Schasinglulu } 290*91f16700Schasinglulu 291*91f16700Schasinglulu unsigned long plat_scmi_clock_get_rate(unsigned int agent_id, 292*91f16700Schasinglulu unsigned int scmi_id) 293*91f16700Schasinglulu { 294*91f16700Schasinglulu struct stm32_scmi_clk *clock = find_clock(agent_id, scmi_id); 295*91f16700Schasinglulu 296*91f16700Schasinglulu if ((clock == NULL) || 297*91f16700Schasinglulu !stm32mp_nsec_can_access_clock(clock->clock_id)) { 298*91f16700Schasinglulu return 0U; 299*91f16700Schasinglulu } 300*91f16700Schasinglulu 301*91f16700Schasinglulu return clk_get_rate(clock->clock_id); 302*91f16700Schasinglulu } 303*91f16700Schasinglulu 304*91f16700Schasinglulu int32_t plat_scmi_clock_get_state(unsigned int agent_id, unsigned int scmi_id) 305*91f16700Schasinglulu { 306*91f16700Schasinglulu struct stm32_scmi_clk *clock = find_clock(agent_id, scmi_id); 307*91f16700Schasinglulu 308*91f16700Schasinglulu if ((clock == NULL) || 309*91f16700Schasinglulu !stm32mp_nsec_can_access_clock(clock->clock_id)) { 310*91f16700Schasinglulu return 0U; 311*91f16700Schasinglulu } 312*91f16700Schasinglulu 313*91f16700Schasinglulu return (int32_t)clock->enabled; 314*91f16700Schasinglulu } 315*91f16700Schasinglulu 316*91f16700Schasinglulu int32_t plat_scmi_clock_set_state(unsigned int agent_id, unsigned int scmi_id, 317*91f16700Schasinglulu bool enable_not_disable) 318*91f16700Schasinglulu { 319*91f16700Schasinglulu struct stm32_scmi_clk *clock = find_clock(agent_id, scmi_id); 320*91f16700Schasinglulu 321*91f16700Schasinglulu if (clock == NULL) { 322*91f16700Schasinglulu return SCMI_NOT_FOUND; 323*91f16700Schasinglulu } 324*91f16700Schasinglulu 325*91f16700Schasinglulu if (!stm32mp_nsec_can_access_clock(clock->clock_id)) { 326*91f16700Schasinglulu return SCMI_DENIED; 327*91f16700Schasinglulu } 328*91f16700Schasinglulu 329*91f16700Schasinglulu if (enable_not_disable) { 330*91f16700Schasinglulu if (!clock->enabled) { 331*91f16700Schasinglulu VERBOSE("SCMI clock %u enable\n", scmi_id); 332*91f16700Schasinglulu clk_enable(clock->clock_id); 333*91f16700Schasinglulu clock->enabled = true; 334*91f16700Schasinglulu } 335*91f16700Schasinglulu } else { 336*91f16700Schasinglulu if (clock->enabled) { 337*91f16700Schasinglulu VERBOSE("SCMI clock %u disable\n", scmi_id); 338*91f16700Schasinglulu clk_disable(clock->clock_id); 339*91f16700Schasinglulu clock->enabled = false; 340*91f16700Schasinglulu } 341*91f16700Schasinglulu } 342*91f16700Schasinglulu 343*91f16700Schasinglulu return SCMI_SUCCESS; 344*91f16700Schasinglulu } 345*91f16700Schasinglulu 346*91f16700Schasinglulu /* 347*91f16700Schasinglulu * Platform SCMI reset domains 348*91f16700Schasinglulu */ 349*91f16700Schasinglulu static struct stm32_scmi_rstd *find_rstd(unsigned int agent_id, 350*91f16700Schasinglulu unsigned int scmi_id) 351*91f16700Schasinglulu { 352*91f16700Schasinglulu const struct scmi_agent_resources *resource = find_resource(agent_id); 353*91f16700Schasinglulu size_t n; 354*91f16700Schasinglulu 355*91f16700Schasinglulu if (resource != NULL) { 356*91f16700Schasinglulu for (n = 0U; n < resource->rstd_count; n++) { 357*91f16700Schasinglulu if (n == scmi_id) { 358*91f16700Schasinglulu return &resource->rstd[n]; 359*91f16700Schasinglulu } 360*91f16700Schasinglulu } 361*91f16700Schasinglulu } 362*91f16700Schasinglulu 363*91f16700Schasinglulu return NULL; 364*91f16700Schasinglulu } 365*91f16700Schasinglulu 366*91f16700Schasinglulu const char *plat_scmi_rstd_get_name(unsigned int agent_id, unsigned int scmi_id) 367*91f16700Schasinglulu { 368*91f16700Schasinglulu const struct stm32_scmi_rstd *rstd = find_rstd(agent_id, scmi_id); 369*91f16700Schasinglulu 370*91f16700Schasinglulu if (rstd == NULL) { 371*91f16700Schasinglulu return NULL; 372*91f16700Schasinglulu } 373*91f16700Schasinglulu 374*91f16700Schasinglulu return rstd->name; 375*91f16700Schasinglulu } 376*91f16700Schasinglulu 377*91f16700Schasinglulu size_t plat_scmi_rstd_count(unsigned int agent_id) 378*91f16700Schasinglulu { 379*91f16700Schasinglulu const struct scmi_agent_resources *resource = find_resource(agent_id); 380*91f16700Schasinglulu 381*91f16700Schasinglulu if (resource == NULL) { 382*91f16700Schasinglulu return 0U; 383*91f16700Schasinglulu } 384*91f16700Schasinglulu 385*91f16700Schasinglulu return resource->rstd_count; 386*91f16700Schasinglulu } 387*91f16700Schasinglulu 388*91f16700Schasinglulu int32_t plat_scmi_rstd_autonomous(unsigned int agent_id, unsigned int scmi_id, 389*91f16700Schasinglulu uint32_t state) 390*91f16700Schasinglulu { 391*91f16700Schasinglulu const struct stm32_scmi_rstd *rstd = find_rstd(agent_id, scmi_id); 392*91f16700Schasinglulu 393*91f16700Schasinglulu if (rstd == NULL) { 394*91f16700Schasinglulu return SCMI_NOT_FOUND; 395*91f16700Schasinglulu } 396*91f16700Schasinglulu 397*91f16700Schasinglulu if (!stm32mp_nsec_can_access_reset(rstd->reset_id)) { 398*91f16700Schasinglulu return SCMI_DENIED; 399*91f16700Schasinglulu } 400*91f16700Schasinglulu 401*91f16700Schasinglulu /* Supports only reset with context loss */ 402*91f16700Schasinglulu if (state != 0U) { 403*91f16700Schasinglulu return SCMI_NOT_SUPPORTED; 404*91f16700Schasinglulu } 405*91f16700Schasinglulu 406*91f16700Schasinglulu VERBOSE("SCMI reset %lu cycle\n", rstd->reset_id); 407*91f16700Schasinglulu 408*91f16700Schasinglulu if (stm32mp_reset_assert(rstd->reset_id, TIMEOUT_US_1MS)) { 409*91f16700Schasinglulu return SCMI_HARDWARE_ERROR; 410*91f16700Schasinglulu } 411*91f16700Schasinglulu 412*91f16700Schasinglulu if (stm32mp_reset_deassert(rstd->reset_id, TIMEOUT_US_1MS)) { 413*91f16700Schasinglulu return SCMI_HARDWARE_ERROR; 414*91f16700Schasinglulu } 415*91f16700Schasinglulu 416*91f16700Schasinglulu return SCMI_SUCCESS; 417*91f16700Schasinglulu } 418*91f16700Schasinglulu 419*91f16700Schasinglulu int32_t plat_scmi_rstd_set_state(unsigned int agent_id, unsigned int scmi_id, 420*91f16700Schasinglulu bool assert_not_deassert) 421*91f16700Schasinglulu { 422*91f16700Schasinglulu const struct stm32_scmi_rstd *rstd = find_rstd(agent_id, scmi_id); 423*91f16700Schasinglulu 424*91f16700Schasinglulu if (rstd == NULL) { 425*91f16700Schasinglulu return SCMI_NOT_FOUND; 426*91f16700Schasinglulu } 427*91f16700Schasinglulu 428*91f16700Schasinglulu if (!stm32mp_nsec_can_access_reset(rstd->reset_id)) { 429*91f16700Schasinglulu return SCMI_DENIED; 430*91f16700Schasinglulu } 431*91f16700Schasinglulu 432*91f16700Schasinglulu if (assert_not_deassert) { 433*91f16700Schasinglulu VERBOSE("SCMI reset %lu set\n", rstd->reset_id); 434*91f16700Schasinglulu stm32mp_reset_set(rstd->reset_id); 435*91f16700Schasinglulu } else { 436*91f16700Schasinglulu VERBOSE("SCMI reset %lu release\n", rstd->reset_id); 437*91f16700Schasinglulu stm32mp_reset_release(rstd->reset_id); 438*91f16700Schasinglulu } 439*91f16700Schasinglulu 440*91f16700Schasinglulu return SCMI_SUCCESS; 441*91f16700Schasinglulu } 442*91f16700Schasinglulu 443*91f16700Schasinglulu /* 444*91f16700Schasinglulu * Initialize platform SCMI resources 445*91f16700Schasinglulu */ 446*91f16700Schasinglulu void stm32mp1_init_scmi_server(void) 447*91f16700Schasinglulu { 448*91f16700Schasinglulu size_t i; 449*91f16700Schasinglulu 450*91f16700Schasinglulu for (i = 0U; i < ARRAY_SIZE(scmi_channel); i++) { 451*91f16700Schasinglulu scmi_smt_init_agent_channel(&scmi_channel[i]); 452*91f16700Schasinglulu } 453*91f16700Schasinglulu 454*91f16700Schasinglulu for (i = 0U; i < ARRAY_SIZE(agent_resources); i++) { 455*91f16700Schasinglulu const struct scmi_agent_resources *res = &agent_resources[i]; 456*91f16700Schasinglulu size_t j; 457*91f16700Schasinglulu 458*91f16700Schasinglulu for (j = 0U; j < res->clock_count; j++) { 459*91f16700Schasinglulu struct stm32_scmi_clk *clk = &res->clock[j]; 460*91f16700Schasinglulu 461*91f16700Schasinglulu if ((clk->name == NULL) || 462*91f16700Schasinglulu (strlen(clk->name) >= SCMI_CLOCK_NAME_SIZE)) { 463*91f16700Schasinglulu ERROR("Invalid SCMI clock name\n"); 464*91f16700Schasinglulu panic(); 465*91f16700Schasinglulu } 466*91f16700Schasinglulu 467*91f16700Schasinglulu /* Sync SCMI clocks with their targeted initial state */ 468*91f16700Schasinglulu if (clk->enabled && 469*91f16700Schasinglulu stm32mp_nsec_can_access_clock(clk->clock_id)) { 470*91f16700Schasinglulu clk_enable(clk->clock_id); 471*91f16700Schasinglulu } 472*91f16700Schasinglulu } 473*91f16700Schasinglulu 474*91f16700Schasinglulu for (j = 0U; j < res->rstd_count; j++) { 475*91f16700Schasinglulu struct stm32_scmi_rstd *rstd = &res->rstd[j]; 476*91f16700Schasinglulu 477*91f16700Schasinglulu if ((rstd->name == NULL) || 478*91f16700Schasinglulu (strlen(rstd->name) >= SCMI_RSTD_NAME_SIZE)) { 479*91f16700Schasinglulu ERROR("Invalid SCMI reset domain name\n"); 480*91f16700Schasinglulu panic(); 481*91f16700Schasinglulu } 482*91f16700Schasinglulu } 483*91f16700Schasinglulu } 484*91f16700Schasinglulu } 485