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 <drivers/stm32mp1_pwr.h> 10 #include <dt-bindings/clock/stm32mp1-clks.h> 11 #include <dt-bindings/regulator/st,stm32mp15-regulator.h> 12 #include <dt-bindings/reset/stm32mp1-resets.h> 13 #include <initcall.h> 14 #include <mm/core_memprot.h> 15 #include <mm/core_mmu.h> 16 #include <platform_config.h> 17 #include <stdint.h> 18 #include <speculation_barrier.h> 19 #include <stm32_util.h> 20 #include <string.h> 21 #include <tee_api_defines.h> 22 #include <util.h> 23 24 #define TIMEOUT_US_1MS 1000 25 26 #define SCMI_CLOCK_NAME_SIZE 16 27 #define SCMI_RD_NAME_SIZE 16 28 #define SCMI_VOLTD_NAME_SIZE 16 29 30 /* 31 * struct stm32_scmi_clk - Data for the exposed clock 32 * @clock_id: Clock identifier in RCC clock driver 33 * @name: Clock string ID exposed to agent 34 * @enabled: State of the SCMI clock 35 */ 36 struct stm32_scmi_clk { 37 unsigned long clock_id; 38 const char *name; 39 bool enabled; 40 }; 41 42 /* 43 * struct stm32_scmi_rd - Data for the exposed reset controller 44 * @reset_id: Reset identifier in RCC reset driver 45 * @name: Reset string ID exposed to agent 46 */ 47 struct stm32_scmi_rd { 48 unsigned long reset_id; 49 const char *name; 50 }; 51 52 enum voltd_device { 53 VOLTD_PWR, 54 }; 55 56 /* 57 * struct stm32_scmi_voltd - Data for the exposed voltage domains 58 * @name: Power regulator string ID exposed to agent 59 * @priv_id: Internal string ID for the regulator 60 * @priv_dev: Internal ID for the device implementing the regulator 61 */ 62 struct stm32_scmi_voltd { 63 const char *name; 64 const char *priv_id; 65 enum voltd_device priv_dev; 66 67 }; 68 69 /* Locate all non-secure SMT message buffers in last page of SYSRAM */ 70 #define SMT_BUFFER_BASE CFG_STM32MP1_SCMI_SHM_BASE 71 #define SMT_BUFFER0_BASE SMT_BUFFER_BASE 72 #define SMT_BUFFER1_BASE (SMT_BUFFER_BASE + 0x200) 73 74 #if (SMT_BUFFER1_BASE + SMT_BUF_SLOT_SIZE > \ 75 CFG_STM32MP1_SCMI_SHM_BASE + CFG_STM32MP1_SCMI_SHM_SIZE) 76 #error "SCMI shared memory mismatch" 77 #endif 78 79 register_phys_mem(MEM_AREA_IO_NSEC, CFG_STM32MP1_SCMI_SHM_BASE, 80 CFG_STM32MP1_SCMI_SHM_SIZE); 81 82 static struct scmi_msg_channel scmi_channel[] = { 83 [0] = { 84 .agent_name = "stm32mp1-agent-0", 85 .shm_addr = { .pa = SMT_BUFFER0_BASE, }, 86 .shm_size = SMT_BUF_SLOT_SIZE, 87 }, 88 [1] = { 89 .agent_name = "stm32mp1-agent-1", 90 .shm_addr = { .pa = SMT_BUFFER1_BASE, }, 91 .shm_size = SMT_BUF_SLOT_SIZE, 92 }, 93 }; 94 95 struct scmi_msg_channel *plat_scmi_get_channel(unsigned int agent_id) 96 { 97 assert(agent_id < ARRAY_SIZE(scmi_channel)); 98 99 return &scmi_channel[agent_id]; 100 } 101 102 #define CLOCK_CELL(_scmi_id, _id, _name, _init_enabled) \ 103 [_scmi_id] = { \ 104 .clock_id = _id, \ 105 .name = _name, \ 106 .enabled = _init_enabled, \ 107 } 108 109 struct stm32_scmi_clk stm32_scmi0_clock[] = { 110 CLOCK_CELL(CK_SCMI0_HSE, CK_HSE, "ck_hse", true), 111 CLOCK_CELL(CK_SCMI0_HSI, CK_HSI, "ck_hsi", true), 112 CLOCK_CELL(CK_SCMI0_CSI, CK_CSI, "ck_csi", true), 113 CLOCK_CELL(CK_SCMI0_LSE, CK_LSE, "ck_lse", true), 114 CLOCK_CELL(CK_SCMI0_LSI, CK_LSI, "ck_lsi", true), 115 CLOCK_CELL(CK_SCMI0_PLL2_Q, PLL2_Q, "pll2_q", true), 116 CLOCK_CELL(CK_SCMI0_PLL2_R, PLL2_R, "pll2_r", true), 117 CLOCK_CELL(CK_SCMI0_MPU, CK_MPU, "ck_mpu", true), 118 CLOCK_CELL(CK_SCMI0_AXI, CK_AXI, "ck_axi", true), 119 CLOCK_CELL(CK_SCMI0_BSEC, BSEC, "bsec", true), 120 CLOCK_CELL(CK_SCMI0_CRYP1, CRYP1, "cryp1", false), 121 CLOCK_CELL(CK_SCMI0_GPIOZ, GPIOZ, "gpioz", false), 122 CLOCK_CELL(CK_SCMI0_HASH1, HASH1, "hash1", false), 123 CLOCK_CELL(CK_SCMI0_I2C4, I2C4_K, "i2c4_k", false), 124 CLOCK_CELL(CK_SCMI0_I2C6, I2C6_K, "i2c6_k", false), 125 CLOCK_CELL(CK_SCMI0_IWDG1, IWDG1, "iwdg1", false), 126 CLOCK_CELL(CK_SCMI0_RNG1, RNG1_K, "rng1_k", true), 127 CLOCK_CELL(CK_SCMI0_RTC, RTC, "ck_rtc", true), 128 CLOCK_CELL(CK_SCMI0_RTCAPB, RTCAPB, "rtcapb", true), 129 CLOCK_CELL(CK_SCMI0_SPI6, SPI6_K, "spi6_k", false), 130 CLOCK_CELL(CK_SCMI0_USART1, USART1_K, "usart1_k", false), 131 }; 132 133 struct stm32_scmi_clk stm32_scmi1_clock[] = { 134 CLOCK_CELL(CK_SCMI1_PLL3_Q, PLL3_Q, "pll3_q", true), 135 CLOCK_CELL(CK_SCMI1_PLL3_R, PLL3_R, "pll3_r", true), 136 CLOCK_CELL(CK_SCMI1_MCU, CK_MCU, "ck_mcu", false), 137 }; 138 139 #define RESET_CELL(_scmi_id, _id, _name) \ 140 [_scmi_id] = { \ 141 .reset_id = _id, \ 142 .name = _name, \ 143 } 144 145 struct stm32_scmi_rd stm32_scmi0_reset_domain[] = { 146 RESET_CELL(RST_SCMI0_SPI6, SPI6_R, "spi6"), 147 RESET_CELL(RST_SCMI0_I2C4, I2C4_R, "i2c4"), 148 RESET_CELL(RST_SCMI0_I2C6, I2C6_R, "i2c6"), 149 RESET_CELL(RST_SCMI0_USART1, USART1_R, "usart1"), 150 RESET_CELL(RST_SCMI0_STGEN, STGEN_R, "stgen"), 151 RESET_CELL(RST_SCMI0_GPIOZ, GPIOZ_R, "gpioz"), 152 RESET_CELL(RST_SCMI0_CRYP1, CRYP1_R, "cryp1"), 153 RESET_CELL(RST_SCMI0_HASH1, HASH1_R, "hash1"), 154 RESET_CELL(RST_SCMI0_RNG1, RNG1_R, "rng1"), 155 RESET_CELL(RST_SCMI0_MDMA, MDMA_R, "mdma"), 156 RESET_CELL(RST_SCMI0_MCU, MCU_R, "mcu"), 157 RESET_CELL(RST_SCMI0_MCU_HOLD_BOOT, MCU_HOLD_BOOT_R, "mcu_hold_boot"), 158 }; 159 160 #define VOLTD_CELL(_scmi_id, _dev_id, _priv_id, _name) \ 161 [_scmi_id] = { \ 162 .priv_id = (_priv_id), \ 163 .priv_dev = (_dev_id), \ 164 .name = (_name), \ 165 } 166 167 #define PWR_REG11_NAME_ID "0" 168 #define PWR_REG18_NAME_ID "1" 169 #define PWR_USB33_NAME_ID "2" 170 171 struct stm32_scmi_voltd scmi0_voltage_domain[] = { 172 VOLTD_CELL(VOLTD_SCMI0_REG11, VOLTD_PWR, PWR_REG11_NAME_ID, "reg11"), 173 VOLTD_CELL(VOLTD_SCMI0_REG18, VOLTD_PWR, PWR_REG18_NAME_ID, "reg18"), 174 VOLTD_CELL(VOLTD_SCMI0_USB33, VOLTD_PWR, PWR_USB33_NAME_ID, "usb33"), 175 }; 176 177 struct scmi_agent_resources { 178 struct stm32_scmi_clk *clock; 179 size_t clock_count; 180 struct stm32_scmi_rd *rd; 181 size_t rd_count; 182 struct stm32_scmi_pd *pd; 183 size_t pd_count; 184 struct stm32_scmi_perfs *perfs; 185 size_t perfs_count; 186 struct stm32_scmi_voltd *voltd; 187 size_t voltd_count; 188 }; 189 190 const struct scmi_agent_resources agent_resources[] = { 191 [0] = { 192 .clock = stm32_scmi0_clock, 193 .clock_count = ARRAY_SIZE(stm32_scmi0_clock), 194 .rd = stm32_scmi0_reset_domain, 195 .rd_count = ARRAY_SIZE(stm32_scmi0_reset_domain), 196 .voltd = scmi0_voltage_domain, 197 .voltd_count = ARRAY_SIZE(scmi0_voltage_domain), 198 }, 199 [1] = { 200 .clock = stm32_scmi1_clock, 201 .clock_count = ARRAY_SIZE(stm32_scmi1_clock), 202 }, 203 }; 204 205 static const struct scmi_agent_resources *find_resource(unsigned int agent_id) 206 { 207 assert(agent_id < ARRAY_SIZE(agent_resources)); 208 209 return &agent_resources[agent_id]; 210 } 211 212 static size_t __maybe_unused plat_scmi_protocol_count_paranoid(void) 213 { 214 unsigned int n = 0; 215 unsigned int count = 0; 216 const size_t agent_count = ARRAY_SIZE(agent_resources); 217 218 for (n = 0; n < agent_count; n++) 219 if (agent_resources[n].clock_count) 220 break; 221 if (n < agent_count) 222 count++; 223 224 for (n = 0; n < agent_count; n++) 225 if (agent_resources[n].rd_count) 226 break; 227 if (n < agent_count) 228 count++; 229 230 for (n = 0; n < agent_count; n++) 231 if (agent_resources[n].pd_count) 232 break; 233 if (n < agent_count) 234 count++; 235 236 for (n = 0; n < agent_count; n++) 237 if (agent_resources[n].perfs_count) 238 break; 239 if (n < agent_count) 240 count++; 241 242 for (n = 0; n < agent_count; n++) 243 if (agent_resources[n].voltd_count) 244 break; 245 if (n < agent_count) 246 count++; 247 248 return count; 249 } 250 251 static const char vendor[] = "ST"; 252 static const char sub_vendor[] = ""; 253 254 const char *plat_scmi_vendor_name(void) 255 { 256 return vendor; 257 } 258 259 const char *plat_scmi_sub_vendor_name(void) 260 { 261 return sub_vendor; 262 } 263 264 /* Currently supporting Clocks and Reset Domains */ 265 static const uint8_t plat_protocol_list[] = { 266 SCMI_PROTOCOL_ID_CLOCK, 267 SCMI_PROTOCOL_ID_RESET_DOMAIN, 268 SCMI_PROTOCOL_ID_VOLTAGE_DOMAIN, 269 0 /* Null termination */ 270 }; 271 272 size_t plat_scmi_protocol_count(void) 273 { 274 const size_t count = ARRAY_SIZE(plat_protocol_list) - 1; 275 276 assert(count == plat_scmi_protocol_count_paranoid()); 277 278 return count; 279 } 280 281 const uint8_t *plat_scmi_protocol_list(unsigned int agent_id __unused) 282 { 283 assert(plat_scmi_protocol_count_paranoid() == 284 (ARRAY_SIZE(plat_protocol_list) - 1)); 285 286 return plat_protocol_list; 287 } 288 289 /* 290 * Platform SCMI clocks 291 */ 292 static struct stm32_scmi_clk *find_clock(unsigned int agent_id, 293 unsigned int scmi_id) 294 { 295 const struct scmi_agent_resources *resource = find_resource(agent_id); 296 size_t n = 0; 297 298 if (resource) { 299 for (n = 0; n < resource->clock_count; n++) 300 if (n == scmi_id) 301 return &resource->clock[n]; 302 } 303 304 return NULL; 305 } 306 307 size_t plat_scmi_clock_count(unsigned int agent_id) 308 { 309 const struct scmi_agent_resources *resource = find_resource(agent_id); 310 311 if (!resource) 312 return 0; 313 314 return resource->clock_count; 315 } 316 317 const char *plat_scmi_clock_get_name(unsigned int agent_id, 318 unsigned int scmi_id) 319 { 320 struct stm32_scmi_clk *clock = find_clock(agent_id, scmi_id); 321 322 if (!clock || !stm32mp_nsec_can_access_clock(clock->clock_id)) 323 return NULL; 324 325 return clock->name; 326 } 327 328 int32_t plat_scmi_clock_rates_array(unsigned int agent_id, unsigned int scmi_id, 329 size_t start_index, unsigned long *array, 330 size_t *nb_elts) 331 { 332 struct stm32_scmi_clk *clock = find_clock(agent_id, scmi_id); 333 334 if (!clock) 335 return SCMI_NOT_FOUND; 336 337 if (!stm32mp_nsec_can_access_clock(clock->clock_id)) 338 return SCMI_DENIED; 339 340 /* Exposed clocks are currently fixed rate clocks */ 341 if (start_index) 342 return SCMI_INVALID_PARAMETERS; 343 344 if (!array) 345 *nb_elts = 1; 346 else if (*nb_elts == 1) 347 *array = stm32_clock_get_rate(clock->clock_id); 348 else 349 return SCMI_GENERIC_ERROR; 350 351 return SCMI_SUCCESS; 352 } 353 354 unsigned long plat_scmi_clock_get_rate(unsigned int agent_id, 355 unsigned int scmi_id) 356 { 357 struct stm32_scmi_clk *clock = find_clock(agent_id, scmi_id); 358 359 if (!clock || !stm32mp_nsec_can_access_clock(clock->clock_id)) 360 return 0; 361 362 return stm32_clock_get_rate(clock->clock_id); 363 } 364 365 int32_t plat_scmi_clock_get_state(unsigned int agent_id, unsigned int scmi_id) 366 { 367 struct stm32_scmi_clk *clock = find_clock(agent_id, scmi_id); 368 369 if (!clock || !stm32mp_nsec_can_access_clock(clock->clock_id)) 370 return 0; 371 372 return (int32_t)clock->enabled; 373 } 374 375 int32_t plat_scmi_clock_set_state(unsigned int agent_id, unsigned int scmi_id, 376 bool enable_not_disable) 377 { 378 struct stm32_scmi_clk *clock = find_clock(agent_id, scmi_id); 379 380 if (!clock) 381 return SCMI_NOT_FOUND; 382 383 if (!stm32mp_nsec_can_access_clock(clock->clock_id)) 384 return SCMI_DENIED; 385 386 if (enable_not_disable) { 387 if (!clock->enabled) { 388 DMSG("SCMI clock %u enable", scmi_id); 389 stm32_clock_enable(clock->clock_id); 390 clock->enabled = true; 391 } 392 } else { 393 if (clock->enabled) { 394 DMSG("SCMI clock %u disable", scmi_id); 395 stm32_clock_disable(clock->clock_id); 396 clock->enabled = false; 397 } 398 } 399 400 return SCMI_SUCCESS; 401 } 402 403 /* 404 * Platform SCMI reset domains 405 */ 406 static struct stm32_scmi_rd *find_rd(unsigned int agent_id, 407 unsigned int scmi_id) 408 { 409 const struct scmi_agent_resources *resource = find_resource(agent_id); 410 size_t n = 0; 411 412 if (resource) { 413 for (n = 0; n < resource->rd_count; n++) 414 if (n == scmi_id) 415 return &resource->rd[n]; 416 } 417 418 return NULL; 419 } 420 421 const char *plat_scmi_rd_get_name(unsigned int agent_id, unsigned int scmi_id) 422 { 423 const struct stm32_scmi_rd *rd = find_rd(agent_id, scmi_id); 424 425 if (!rd) 426 return NULL; 427 428 return rd->name; 429 } 430 431 size_t plat_scmi_rd_count(unsigned int agent_id) 432 { 433 const struct scmi_agent_resources *resource = find_resource(agent_id); 434 435 if (!resource) 436 return 0; 437 438 return resource->rd_count; 439 } 440 441 int32_t plat_scmi_rd_autonomous(unsigned int agent_id, unsigned int scmi_id, 442 uint32_t state) 443 { 444 const struct stm32_scmi_rd *rd = find_rd(agent_id, scmi_id); 445 446 if (!rd) 447 return SCMI_NOT_FOUND; 448 449 if (!stm32mp_nsec_can_access_reset(rd->reset_id)) 450 return SCMI_DENIED; 451 452 if (rd->reset_id == MCU_HOLD_BOOT_R) 453 return SCMI_NOT_SUPPORTED; 454 455 /* Supports only reset with context loss */ 456 if (state) 457 return SCMI_NOT_SUPPORTED; 458 459 DMSG("SCMI reset %u cycle", scmi_id); 460 461 if (stm32_reset_assert(rd->reset_id, TIMEOUT_US_1MS)) 462 return SCMI_HARDWARE_ERROR; 463 464 if (stm32_reset_deassert(rd->reset_id, TIMEOUT_US_1MS)) 465 return SCMI_HARDWARE_ERROR; 466 467 return SCMI_SUCCESS; 468 } 469 470 int32_t plat_scmi_rd_set_state(unsigned int agent_id, unsigned int scmi_id, 471 bool assert_not_deassert) 472 { 473 const struct stm32_scmi_rd *rd = find_rd(agent_id, scmi_id); 474 475 if (!rd) 476 return SCMI_NOT_FOUND; 477 478 if (!stm32mp_nsec_can_access_reset(rd->reset_id)) 479 return SCMI_DENIED; 480 481 if (rd->reset_id == MCU_HOLD_BOOT_R) { 482 DMSG("SCMI MCU hold boot %s", 483 assert_not_deassert ? "set" : "release"); 484 stm32_reset_assert_deassert_mcu(assert_not_deassert); 485 return SCMI_SUCCESS; 486 } 487 488 if (assert_not_deassert) { 489 DMSG("SCMI reset %u set", scmi_id); 490 stm32_reset_set(rd->reset_id); 491 } else { 492 DMSG("SCMI reset %u release", scmi_id); 493 stm32_reset_release(rd->reset_id); 494 } 495 496 return SCMI_SUCCESS; 497 } 498 499 /* 500 * Platform SCMI voltage domains 501 */ 502 static struct stm32_scmi_voltd *find_voltd(unsigned int agent_id, 503 unsigned int scmi_id) 504 { 505 const struct scmi_agent_resources *resource = find_resource(agent_id); 506 size_t n = 0; 507 508 if (resource) { 509 for (n = 0; n < resource->voltd_count; n++) 510 if (n == scmi_id) 511 return &resource->voltd[n]; 512 } 513 514 return NULL; 515 } 516 517 size_t plat_scmi_voltd_count(unsigned int agent_id) 518 { 519 const struct scmi_agent_resources *resource = find_resource(agent_id); 520 521 if (!resource) 522 return 0; 523 524 return resource->voltd_count; 525 } 526 527 const char *plat_scmi_voltd_get_name(unsigned int agent_id, 528 unsigned int scmi_id) 529 { 530 struct stm32_scmi_voltd *voltd = find_voltd(agent_id, scmi_id); 531 532 /* Currently non-secure is allowed to access all PWR regulators */ 533 if (!voltd) 534 return NULL; 535 536 return voltd->name; 537 } 538 539 static enum pwr_regulator pwr_scmi_to_regu_id(struct stm32_scmi_voltd *voltd) 540 { 541 if (!strcmp(voltd->priv_id, PWR_REG11_NAME_ID)) 542 return PWR_REG11; 543 if (!strcmp(voltd->priv_id, PWR_REG18_NAME_ID)) 544 return PWR_REG18; 545 if (!strcmp(voltd->priv_id, PWR_USB33_NAME_ID)) 546 return PWR_USB33; 547 548 panic(); 549 } 550 551 static long pwr_get_level(struct stm32_scmi_voltd *voltd) 552 { 553 enum pwr_regulator regu_id = pwr_scmi_to_regu_id(voltd); 554 555 return (long)stm32mp1_pwr_regulator_mv(regu_id) * 1000; 556 } 557 558 static int32_t pwr_set_level(struct stm32_scmi_voltd *voltd, long level_uv) 559 { 560 if (level_uv != pwr_get_level(voltd)) 561 return SCMI_INVALID_PARAMETERS; 562 563 return SCMI_SUCCESS; 564 } 565 566 static int32_t pwr_describe_levels(struct stm32_scmi_voltd *voltd, 567 size_t start_index, long *microvolt, 568 size_t *nb_elts) 569 { 570 if (start_index) 571 return SCMI_INVALID_PARAMETERS; 572 573 if (!microvolt) { 574 *nb_elts = 1; 575 return SCMI_SUCCESS; 576 } 577 578 if (*nb_elts < 1) 579 return SCMI_GENERIC_ERROR; 580 581 *nb_elts = 1; 582 *microvolt = pwr_get_level(voltd); 583 584 return SCMI_SUCCESS; 585 } 586 587 static uint32_t pwr_get_state(struct stm32_scmi_voltd *voltd) 588 { 589 enum pwr_regulator regu_id = pwr_scmi_to_regu_id(voltd); 590 591 if (stm32mp1_pwr_regulator_is_enabled(regu_id)) 592 return SCMI_VOLTAGE_DOMAIN_CONFIG_ARCH_ON; 593 594 return SCMI_VOLTAGE_DOMAIN_CONFIG_ARCH_OFF; 595 } 596 597 static void pwr_set_state(struct stm32_scmi_voltd *voltd, bool enable) 598 { 599 enum pwr_regulator regu_id = pwr_scmi_to_regu_id(voltd); 600 601 DMSG("%sable PWR %s (was %s)", enable ? "En" : "Dis", voltd->name, 602 stm32mp1_pwr_regulator_is_enabled(regu_id) ? "on" : "off"); 603 604 stm32mp1_pwr_regulator_set_state(regu_id, enable); 605 } 606 607 int32_t plat_scmi_voltd_levels_array(unsigned int agent_id, 608 unsigned int scmi_id, size_t start_index, 609 long *levels, size_t *nb_elts) 610 611 { 612 struct stm32_scmi_voltd *voltd = find_voltd(agent_id, scmi_id); 613 614 if (!voltd) 615 return SCMI_NOT_FOUND; 616 617 switch (voltd->priv_dev) { 618 case VOLTD_PWR: 619 return pwr_describe_levels(voltd, start_index, levels, nb_elts); 620 default: 621 return SCMI_GENERIC_ERROR; 622 } 623 } 624 625 long plat_scmi_voltd_get_level(unsigned int agent_id, unsigned int scmi_id) 626 { 627 struct stm32_scmi_voltd *voltd = find_voltd(agent_id, scmi_id); 628 629 if (!voltd) 630 return 0; 631 632 switch (voltd->priv_dev) { 633 case VOLTD_PWR: 634 return pwr_get_level(voltd); 635 default: 636 panic(); 637 } 638 } 639 640 int32_t plat_scmi_voltd_set_level(unsigned int agent_id, unsigned int scmi_id, 641 long level) 642 { 643 struct stm32_scmi_voltd *voltd = find_voltd(agent_id, scmi_id); 644 645 if (!voltd) 646 return SCMI_NOT_FOUND; 647 648 switch (voltd->priv_dev) { 649 case VOLTD_PWR: 650 return pwr_set_level(voltd, level); 651 default: 652 return SCMI_GENERIC_ERROR; 653 } 654 } 655 656 int32_t plat_scmi_voltd_get_config(unsigned int agent_id, unsigned int scmi_id, 657 uint32_t *config) 658 { 659 struct stm32_scmi_voltd *voltd = find_voltd(agent_id, scmi_id); 660 661 if (!voltd) 662 return SCMI_NOT_FOUND; 663 664 switch (voltd->priv_dev) { 665 case VOLTD_PWR: 666 *config = pwr_get_state(voltd); 667 break; 668 default: 669 return SCMI_GENERIC_ERROR; 670 } 671 672 return SCMI_SUCCESS; 673 } 674 675 int32_t plat_scmi_voltd_set_config(unsigned int agent_id, unsigned int scmi_id, 676 uint32_t config) 677 { 678 struct stm32_scmi_voltd *voltd = find_voltd(agent_id, scmi_id); 679 int32_t rc = SCMI_SUCCESS; 680 681 if (!voltd) 682 return SCMI_NOT_FOUND; 683 684 switch (voltd->priv_dev) { 685 case VOLTD_PWR: 686 pwr_set_state(voltd, config); 687 break; 688 default: 689 return SCMI_GENERIC_ERROR; 690 } 691 692 return rc; 693 } 694 695 /* 696 * Initialize platform SCMI resources 697 */ 698 static TEE_Result stm32mp1_init_scmi_server(void) 699 { 700 size_t i = 0; 701 size_t j = 0; 702 703 for (i = 0; i < ARRAY_SIZE(scmi_channel); i++) { 704 struct scmi_msg_channel *chan = &scmi_channel[i]; 705 706 /* Enforce non-secure shm mapped as device memory */ 707 chan->shm_addr.va = (vaddr_t)phys_to_virt(chan->shm_addr.pa, 708 MEM_AREA_IO_NSEC); 709 assert(chan->shm_addr.va); 710 711 scmi_smt_init_agent_channel(chan); 712 } 713 714 for (i = 0; i < ARRAY_SIZE(agent_resources); i++) { 715 const struct scmi_agent_resources *res = &agent_resources[i]; 716 717 for (j = 0; j < res->clock_count; j++) { 718 struct stm32_scmi_clk *clk = &res->clock[j]; 719 720 if (!clk->name || 721 strlen(clk->name) >= SCMI_CLOCK_NAME_SIZE) 722 panic("SCMI clock name invalid"); 723 724 /* Sync SCMI clocks with their targeted initial state */ 725 if (clk->enabled && 726 stm32mp_nsec_can_access_clock(clk->clock_id)) 727 stm32_clock_enable(clk->clock_id); 728 } 729 730 for (j = 0; j < res->rd_count; j++) { 731 struct stm32_scmi_rd *rd = &res->rd[j]; 732 733 if (!rd->name || 734 strlen(rd->name) >= SCMI_RD_NAME_SIZE) 735 panic("SCMI reset domain name invalid"); 736 } 737 738 for (j = 0; j < res->voltd_count; j++) { 739 struct stm32_scmi_voltd *voltd = &res->voltd[j]; 740 741 if (!voltd->name || 742 strlen(voltd->name) >= SCMI_VOLTD_NAME_SIZE) 743 panic("SCMI voltage domain name invalid"); 744 } 745 } 746 747 return TEE_SUCCESS; 748 } 749 750 driver_init_late(stm32mp1_init_scmi_server); 751