1 // SPDX-License-Identifier: BSD-2-Clause 2 /* 3 * Copyright (c) 2019, STMicroelectronics 4 * Copyright (c) 2021, Microchip 5 */ 6 7 #include <at91_clk.h> 8 #include <confine_array_index.h> 9 #include <drivers/scmi-msg.h> 10 #include <drivers/scmi.h> 11 #include <dt-bindings/clock/at91.h> 12 #include <initcall.h> 13 #include <tee_api_defines.h> 14 15 static_assert(SMT_BUF_SLOT_SIZE <= CFG_SCMI_SHMEM_SIZE); 16 17 register_phys_mem(MEM_AREA_IO_NSEC, CFG_SCMI_SHMEM_START, CFG_SCMI_SHMEM_SIZE); 18 19 struct channel_resources { 20 struct scmi_msg_channel *channel; 21 }; 22 23 static const struct channel_resources scmi_channel[] = { 24 [0] = { 25 .channel = &(struct scmi_msg_channel){ 26 .shm_addr = { .pa = CFG_SCMI_SHMEM_START }, 27 .shm_size = SMT_BUF_SLOT_SIZE, 28 }, 29 }, 30 }; 31 32 static const struct channel_resources *find_resource(unsigned int channel_id) 33 { 34 assert(channel_id < ARRAY_SIZE(scmi_channel)); 35 36 return scmi_channel + channel_id; 37 } 38 39 struct scmi_msg_channel *plat_scmi_get_channel(unsigned int channel_id) 40 { 41 const size_t max_id = ARRAY_SIZE(scmi_channel); 42 unsigned int confined_id = confine_array_index(channel_id, max_id); 43 44 if (channel_id >= max_id) 45 return NULL; 46 47 return find_resource(confined_id)->channel; 48 } 49 50 static const char vendor[] = "Microchip"; 51 static const char sub_vendor[] = ""; 52 53 const char *plat_scmi_vendor_name(void) 54 { 55 return vendor; 56 } 57 58 const char *plat_scmi_sub_vendor_name(void) 59 { 60 return sub_vendor; 61 } 62 63 /* Currently supporting only SCMI Base protocol */ 64 static const uint8_t plat_protocol_list[] = { 65 SCMI_PROTOCOL_ID_CLOCK, 66 0 /* Null termination */ 67 }; 68 69 size_t plat_scmi_protocol_count(void) 70 { 71 return ARRAY_SIZE(plat_protocol_list) - 1; 72 } 73 74 const uint8_t *plat_scmi_protocol_list(unsigned int channel_id __unused) 75 { 76 return plat_protocol_list; 77 } 78 79 struct sama5d2_pmc_clk { 80 unsigned int scmi_id; 81 unsigned int pmc_type; 82 unsigned int pmc_id; 83 }; 84 85 static const struct sama5d2_pmc_clk pmc_clks[] = { 86 { 87 .scmi_id = AT91_SCMI_CLK_CORE_MCK, 88 .pmc_type = PMC_TYPE_CORE, 89 .pmc_id = PMC_MCK 90 }, 91 { 92 .scmi_id = AT91_SCMI_CLK_CORE_UTMI, 93 .pmc_type = PMC_TYPE_CORE, 94 .pmc_id = PMC_UTMI 95 }, 96 { 97 .scmi_id = AT91_SCMI_CLK_CORE_MAIN, 98 .pmc_type = PMC_TYPE_CORE, 99 .pmc_id = PMC_MAIN 100 }, 101 { 102 .scmi_id = AT91_SCMI_CLK_CORE_MCK2, 103 .pmc_type = PMC_TYPE_CORE, 104 .pmc_id = PMC_MCK2 105 }, 106 { 107 .scmi_id = AT91_SCMI_CLK_CORE_I2S0_MUX, 108 .pmc_type = PMC_TYPE_CORE, 109 .pmc_id = PMC_I2S0_MUX 110 }, 111 { 112 .scmi_id = AT91_SCMI_CLK_CORE_I2S1_MUX, 113 .pmc_type = PMC_TYPE_CORE, 114 .pmc_id = PMC_I2S1_MUX 115 }, 116 { 117 .scmi_id = AT91_SCMI_CLK_CORE_PLLACK, 118 .pmc_type = PMC_TYPE_CORE, 119 .pmc_id = PMC_PLLACK 120 }, 121 { 122 .scmi_id = AT91_SCMI_CLK_CORE_AUDIOPLLCK, 123 .pmc_type = PMC_TYPE_CORE, 124 .pmc_id = PMC_AUDIOPLLCK 125 }, 126 { 127 .scmi_id = AT91_SCMI_CLK_CORE_MCK_PRES, 128 .pmc_type = PMC_TYPE_CORE, 129 .pmc_id = PMC_MCK_PRES 130 }, 131 { 132 .scmi_id = AT91_SCMI_CLK_SYSTEM_DDRCK, 133 .pmc_type = PMC_TYPE_SYSTEM, 134 .pmc_id = 2 135 }, 136 { 137 .scmi_id = AT91_SCMI_CLK_SYSTEM_LCDCK, 138 .pmc_type = PMC_TYPE_SYSTEM, 139 .pmc_id = 3 140 }, 141 { 142 .scmi_id = AT91_SCMI_CLK_SYSTEM_UHPCK, 143 .pmc_type = PMC_TYPE_SYSTEM, 144 .pmc_id = 6 145 }, 146 { 147 .scmi_id = AT91_SCMI_CLK_SYSTEM_UDPCK, 148 .pmc_type = PMC_TYPE_SYSTEM, 149 .pmc_id = 7 150 }, 151 { 152 .scmi_id = AT91_SCMI_CLK_SYSTEM_PCK0, 153 .pmc_type = PMC_TYPE_SYSTEM, 154 .pmc_id = 8 155 }, 156 { 157 .scmi_id = AT91_SCMI_CLK_SYSTEM_PCK1, 158 .pmc_type = PMC_TYPE_SYSTEM, 159 .pmc_id = 9 160 }, 161 { 162 .scmi_id = AT91_SCMI_CLK_SYSTEM_PCK2, 163 .pmc_type = PMC_TYPE_SYSTEM, 164 .pmc_id = 10 165 }, 166 { 167 .scmi_id = AT91_SCMI_CLK_SYSTEM_ISCCK, 168 .pmc_type = PMC_TYPE_SYSTEM, 169 .pmc_id = 18 170 }, 171 { 172 .scmi_id = AT91_SCMI_CLK_PERIPH_MACB0_CLK, 173 .pmc_type = PMC_TYPE_PERIPHERAL, 174 .pmc_id = 5 175 }, 176 { 177 .scmi_id = AT91_SCMI_CLK_PERIPH_TDES_CLK, 178 .pmc_type = PMC_TYPE_PERIPHERAL, 179 .pmc_id = 11 180 }, 181 { 182 .scmi_id = AT91_SCMI_CLK_PERIPH_MATRIX1_CLK, 183 .pmc_type = PMC_TYPE_PERIPHERAL, 184 .pmc_id = 14 185 }, 186 { 187 .scmi_id = AT91_SCMI_CLK_PERIPH_HSMC_CLK, 188 .pmc_type = PMC_TYPE_PERIPHERAL, 189 .pmc_id = 17 190 }, 191 { 192 .scmi_id = AT91_SCMI_CLK_PERIPH_PIOA_CLK, 193 .pmc_type = PMC_TYPE_PERIPHERAL, 194 .pmc_id = 18 195 }, 196 { 197 .scmi_id = AT91_SCMI_CLK_PERIPH_FLX0_CLK, 198 .pmc_type = PMC_TYPE_PERIPHERAL, 199 .pmc_id = 19 200 }, 201 { 202 .scmi_id = AT91_SCMI_CLK_PERIPH_FLX1_CLK, 203 .pmc_type = PMC_TYPE_PERIPHERAL, 204 .pmc_id = 20 205 }, 206 { 207 .scmi_id = AT91_SCMI_CLK_PERIPH_FLX2_CLK, 208 .pmc_type = PMC_TYPE_PERIPHERAL, 209 .pmc_id = 21 210 }, 211 { 212 .scmi_id = AT91_SCMI_CLK_PERIPH_FLX3_CLK, 213 .pmc_type = PMC_TYPE_PERIPHERAL, 214 .pmc_id = 22 215 }, 216 { 217 .scmi_id = AT91_SCMI_CLK_PERIPH_FLX4_CLK, 218 .pmc_type = PMC_TYPE_PERIPHERAL, 219 .pmc_id = 23 220 }, 221 { 222 .scmi_id = AT91_SCMI_CLK_PERIPH_UART0_CLK, 223 .pmc_type = PMC_TYPE_PERIPHERAL, 224 .pmc_id = 24 225 }, 226 { 227 .scmi_id = AT91_SCMI_CLK_PERIPH_UART1_CLK, 228 .pmc_type = PMC_TYPE_PERIPHERAL, 229 .pmc_id = 25 230 }, 231 { 232 .scmi_id = AT91_SCMI_CLK_PERIPH_UART2_CLK, 233 .pmc_type = PMC_TYPE_PERIPHERAL, 234 .pmc_id = 26 235 }, 236 { 237 .scmi_id = AT91_SCMI_CLK_PERIPH_UART3_CLK, 238 .pmc_type = PMC_TYPE_PERIPHERAL, 239 .pmc_id = 27 240 }, 241 { 242 .scmi_id = AT91_SCMI_CLK_PERIPH_UART4_CLK, 243 .pmc_type = PMC_TYPE_PERIPHERAL, 244 .pmc_id = 28 245 }, 246 { 247 .scmi_id = AT91_SCMI_CLK_PERIPH_TWI0_CLK, 248 .pmc_type = PMC_TYPE_PERIPHERAL, 249 .pmc_id = 29 250 }, 251 { 252 .scmi_id = AT91_SCMI_CLK_PERIPH_TWI1_CLK, 253 .pmc_type = PMC_TYPE_PERIPHERAL, 254 .pmc_id = 30 255 }, 256 { 257 .scmi_id = AT91_SCMI_CLK_PERIPH_SPI0_CLK, 258 .pmc_type = PMC_TYPE_PERIPHERAL, 259 .pmc_id = 33 260 }, 261 { 262 .scmi_id = AT91_SCMI_CLK_PERIPH_SPI1_CLK, 263 .pmc_type = PMC_TYPE_PERIPHERAL, 264 .pmc_id = 34 265 }, 266 { 267 .scmi_id = AT91_SCMI_CLK_PERIPH_TCB0_CLK, 268 .pmc_type = PMC_TYPE_PERIPHERAL, 269 .pmc_id = 35 270 }, 271 { 272 .scmi_id = AT91_SCMI_CLK_PERIPH_TCB1_CLK, 273 .pmc_type = PMC_TYPE_PERIPHERAL, 274 .pmc_id = 36 275 }, 276 { 277 .scmi_id = AT91_SCMI_CLK_PERIPH_PWM_CLK, 278 .pmc_type = PMC_TYPE_PERIPHERAL, 279 .pmc_id = 38 280 }, 281 { 282 .scmi_id = AT91_SCMI_CLK_PERIPH_ADC_CLK, 283 .pmc_type = PMC_TYPE_PERIPHERAL, 284 .pmc_id = 40 285 }, 286 { 287 .scmi_id = AT91_SCMI_CLK_PERIPH_UHPHS_CLK, 288 .pmc_type = PMC_TYPE_PERIPHERAL, 289 .pmc_id = 41 290 }, 291 { 292 .scmi_id = AT91_SCMI_CLK_PERIPH_UDPHS_CLK, 293 .pmc_type = PMC_TYPE_PERIPHERAL, 294 .pmc_id = 42 295 }, 296 { 297 .scmi_id = AT91_SCMI_CLK_PERIPH_SSC0_CLK, 298 .pmc_type = PMC_TYPE_PERIPHERAL, 299 .pmc_id = 43 300 }, 301 { 302 .scmi_id = AT91_SCMI_CLK_PERIPH_SSC1_CLK, 303 .pmc_type = PMC_TYPE_PERIPHERAL, 304 .pmc_id = 44 305 }, 306 { 307 .scmi_id = AT91_SCMI_CLK_PERIPH_TRNG_CLK, 308 .pmc_type = PMC_TYPE_PERIPHERAL, 309 .pmc_id = 47 310 }, 311 { 312 .scmi_id = AT91_SCMI_CLK_PERIPH_PDMIC_CLK, 313 .pmc_type = PMC_TYPE_PERIPHERAL, 314 .pmc_id = 48 315 }, 316 { 317 .scmi_id = AT91_SCMI_CLK_PERIPH_SECURAM_CLK, 318 .pmc_type = PMC_TYPE_PERIPHERAL, 319 .pmc_id = 51 320 }, 321 { 322 .scmi_id = AT91_SCMI_CLK_PERIPH_I2S0_CLK, 323 .pmc_type = PMC_TYPE_PERIPHERAL, 324 .pmc_id = 54 325 }, 326 { 327 .scmi_id = AT91_SCMI_CLK_PERIPH_I2S1_CLK, 328 .pmc_type = PMC_TYPE_PERIPHERAL, 329 .pmc_id = 55 330 }, 331 { 332 .scmi_id = AT91_SCMI_CLK_PERIPH_CAN0_CLK, 333 .pmc_type = PMC_TYPE_PERIPHERAL, 334 .pmc_id = 56 335 }, 336 { 337 .scmi_id = AT91_SCMI_CLK_PERIPH_CAN1_CLK, 338 .pmc_type = PMC_TYPE_PERIPHERAL, 339 .pmc_id = 57 340 }, 341 { 342 .scmi_id = AT91_SCMI_CLK_PERIPH_PTC_CLK, 343 .pmc_type = PMC_TYPE_PERIPHERAL, 344 .pmc_id = 58 345 }, 346 { 347 .scmi_id = AT91_SCMI_CLK_PERIPH_CLASSD_CLK, 348 .pmc_type = PMC_TYPE_PERIPHERAL, 349 .pmc_id = 59 350 }, 351 { 352 .scmi_id = AT91_SCMI_CLK_PERIPH_DMA0_CLK, 353 .pmc_type = PMC_TYPE_PERIPHERAL, 354 .pmc_id = 6 355 }, 356 { 357 .scmi_id = AT91_SCMI_CLK_PERIPH_DMA1_CLK, 358 .pmc_type = PMC_TYPE_PERIPHERAL, 359 .pmc_id = 7 360 }, 361 { 362 .scmi_id = AT91_SCMI_CLK_PERIPH_AES_CLK, 363 .pmc_type = PMC_TYPE_PERIPHERAL, 364 .pmc_id = 9 365 }, 366 { 367 .scmi_id = AT91_SCMI_CLK_PERIPH_AESB_CLK, 368 .pmc_type = PMC_TYPE_PERIPHERAL, 369 .pmc_id = 10 370 }, 371 { 372 .scmi_id = AT91_SCMI_CLK_PERIPH_SHA_CLK, 373 .pmc_type = PMC_TYPE_PERIPHERAL, 374 .pmc_id = 12 375 }, 376 { 377 .scmi_id = AT91_SCMI_CLK_PERIPH_MPDDR_CLK, 378 .pmc_type = PMC_TYPE_PERIPHERAL, 379 .pmc_id = 13 380 }, 381 { 382 .scmi_id = AT91_SCMI_CLK_PERIPH_MATRIX0_CLK, 383 .pmc_type = PMC_TYPE_PERIPHERAL, 384 .pmc_id = 15 385 }, 386 { 387 .scmi_id = AT91_SCMI_CLK_PERIPH_SDMMC0_HCLK, 388 .pmc_type = PMC_TYPE_PERIPHERAL, 389 .pmc_id = 31 390 }, 391 { 392 .scmi_id = AT91_SCMI_CLK_PERIPH_SDMMC1_HCLK, 393 .pmc_type = PMC_TYPE_PERIPHERAL, 394 .pmc_id = 32 395 }, 396 { 397 .scmi_id = AT91_SCMI_CLK_PERIPH_LCDC_CLK, 398 .pmc_type = PMC_TYPE_PERIPHERAL, 399 .pmc_id = 45 400 }, 401 { 402 .scmi_id = AT91_SCMI_CLK_PERIPH_ISC_CLK, 403 .pmc_type = PMC_TYPE_PERIPHERAL, 404 .pmc_id = 46 405 }, 406 { 407 .scmi_id = AT91_SCMI_CLK_PERIPH_QSPI0_CLK, 408 .pmc_type = PMC_TYPE_PERIPHERAL, 409 .pmc_id = 52 410 }, 411 { 412 .scmi_id = AT91_SCMI_CLK_PERIPH_QSPI1_CLK, 413 .pmc_type = PMC_TYPE_PERIPHERAL, 414 .pmc_id = 53 415 }, 416 { 417 .scmi_id = AT91_SCMI_CLK_GCK_SDMMC0_GCLK, 418 .pmc_type = PMC_TYPE_GCK, 419 .pmc_id = 31 420 }, 421 { 422 .scmi_id = AT91_SCMI_CLK_GCK_SDMMC1_GCLK, 423 .pmc_type = PMC_TYPE_GCK, 424 .pmc_id = 32 425 }, 426 { 427 .scmi_id = AT91_SCMI_CLK_GCK_TCB0_GCLK, 428 .pmc_type = PMC_TYPE_GCK, 429 .pmc_id = 35 430 }, 431 { 432 .scmi_id = AT91_SCMI_CLK_GCK_TCB1_GCLK, 433 .pmc_type = PMC_TYPE_GCK, 434 .pmc_id = 36 435 }, 436 { 437 .scmi_id = AT91_SCMI_CLK_GCK_PWM_GCLK, 438 .pmc_type = PMC_TYPE_GCK, 439 .pmc_id = 38 440 }, 441 { 442 .scmi_id = AT91_SCMI_CLK_GCK_ISC_GCLK, 443 .pmc_type = PMC_TYPE_GCK, 444 .pmc_id = 46 445 }, 446 { 447 .scmi_id = AT91_SCMI_CLK_GCK_PDMIC_GCLK, 448 .pmc_type = PMC_TYPE_GCK, 449 .pmc_id = 48 450 }, 451 { 452 .scmi_id = AT91_SCMI_CLK_GCK_I2S0_GCLK, 453 .pmc_type = PMC_TYPE_GCK, 454 .pmc_id = 54 455 }, 456 { 457 .scmi_id = AT91_SCMI_CLK_GCK_I2S1_GCLK, 458 .pmc_type = PMC_TYPE_GCK, 459 .pmc_id = 55 460 }, 461 { 462 .scmi_id = AT91_SCMI_CLK_GCK_CAN0_GCLK, 463 .pmc_type = PMC_TYPE_GCK, 464 .pmc_id = 56 465 }, 466 { 467 .scmi_id = AT91_SCMI_CLK_GCK_CAN1_GCLK, 468 .pmc_type = PMC_TYPE_GCK, 469 .pmc_id = 57 470 }, 471 { 472 .scmi_id = AT91_SCMI_CLK_GCK_CLASSD_GCLK, 473 .pmc_type = PMC_TYPE_GCK, 474 .pmc_id = 59 475 }, 476 { 477 .scmi_id = AT91_SCMI_CLK_PROG_PROG0, 478 .pmc_type = PMC_TYPE_PROGRAMMABLE, 479 .pmc_id = 0 480 }, 481 { 482 .scmi_id = AT91_SCMI_CLK_PROG_PROG1, 483 .pmc_type = PMC_TYPE_PROGRAMMABLE, 484 .pmc_id = 1 485 }, 486 { 487 .scmi_id = AT91_SCMI_CLK_PROG_PROG2, 488 .pmc_type = PMC_TYPE_PROGRAMMABLE, 489 .pmc_id = 2 490 }, 491 }; 492 493 static TEE_Result sam_init_scmi_clk(void) 494 { 495 unsigned int i = 0; 496 struct clk *clk = NULL; 497 TEE_Result res = TEE_ERROR_GENERIC; 498 const struct sama5d2_pmc_clk *pmc_clk = NULL; 499 500 for (i = 0; i < ARRAY_SIZE(pmc_clks); i++) { 501 pmc_clk = &pmc_clks[i]; 502 res = at91_pmc_clk_get(pmc_clk->pmc_type, pmc_clk->pmc_id, 503 &clk); 504 if (res) { 505 EMSG("Failed to get PMC clock type %u, id %u", 506 pmc_clk->pmc_type, pmc_clk->pmc_id); 507 return res; 508 } 509 res = scmi_clk_add(clk, 0, pmc_clk->scmi_id); 510 if (res) { 511 EMSG("Failed to add PMC SCMI clock id %u", 512 pmc_clk->scmi_id); 513 return res; 514 } 515 } 516 517 clk = at91_sckc_clk_get(); 518 if (!clk) 519 return TEE_ERROR_GENERIC; 520 521 res = scmi_clk_add(clk, 0, AT91_SCMI_CLK_SCKC_SLOWCK_32K); 522 if (res) { 523 EMSG("Failed to add slow clock to SCMI clocks"); 524 return res; 525 } 526 527 return TEE_SUCCESS; 528 } 529 530 /* 531 * Initialize platform SCMI resources 532 */ 533 static TEE_Result sam_init_scmi_server(void) 534 { 535 size_t i = 0; 536 537 for (i = 0; i < ARRAY_SIZE(scmi_channel); i++) { 538 const struct channel_resources *res = scmi_channel + i; 539 struct scmi_msg_channel *chan = res->channel; 540 541 /* Enforce non-secure shm mapped as device memory */ 542 chan->shm_addr.va = (vaddr_t)phys_to_virt(chan->shm_addr.pa, 543 MEM_AREA_IO_NSEC, 1); 544 assert(chan->shm_addr.va); 545 546 scmi_smt_init_agent_channel(chan); 547 } 548 549 return sam_init_scmi_clk(); 550 } 551 552 driver_init_late(sam_init_scmi_server); 553