1*4ddfb6f1SJacky Bai /* 2*4ddfb6f1SJacky Bai * Copyright 2023-2025 NXP 3*4ddfb6f1SJacky Bai * 4*4ddfb6f1SJacky Bai * SPDX-License-Identifier: BSD-3-Clause 5*4ddfb6f1SJacky Bai */ 6*4ddfb6f1SJacky Bai 7*4ddfb6f1SJacky Bai #include <assert.h> 8*4ddfb6f1SJacky Bai #include <stdint.h> 9*4ddfb6f1SJacky Bai 10*4ddfb6f1SJacky Bai #include <drivers/arm/css/scmi.h> 11*4ddfb6f1SJacky Bai #include <drivers/scmi.h> 12*4ddfb6f1SJacky Bai #include <lib/bakery_lock.h> 13*4ddfb6f1SJacky Bai #include <lib/mmio.h> 14*4ddfb6f1SJacky Bai 15*4ddfb6f1SJacky Bai #include <platform_def.h> 16*4ddfb6f1SJacky Bai 17*4ddfb6f1SJacky Bai #define SCMI_CORE_PROTO_ID 0x82 18*4ddfb6f1SJacky Bai 19*4ddfb6f1SJacky Bai void *imx9_scmi_handle; 20*4ddfb6f1SJacky Bai 21*4ddfb6f1SJacky Bai /* The SCMI channel global object */ 22*4ddfb6f1SJacky Bai static scmi_channel_t channel; 23*4ddfb6f1SJacky Bai 24*4ddfb6f1SJacky Bai spinlock_t imx95_scmi_lock; 25*4ddfb6f1SJacky Bai #define IMX95_SCMI_LOCK_GET_INSTANCE (&imx95_scmi_lock) 26*4ddfb6f1SJacky Bai mu_ring_doorbell(struct scmi_channel_plat_info * plat_info)27*4ddfb6f1SJacky Baistatic void mu_ring_doorbell(struct scmi_channel_plat_info *plat_info) 28*4ddfb6f1SJacky Bai { 29*4ddfb6f1SJacky Bai uint32_t db = mmio_read_32(plat_info->db_reg_addr) & 30*4ddfb6f1SJacky Bai (plat_info->db_preserve_mask); 31*4ddfb6f1SJacky Bai 32*4ddfb6f1SJacky Bai mmio_write_32(plat_info->db_reg_addr, db | plat_info->db_modify_mask); 33*4ddfb6f1SJacky Bai } 34*4ddfb6f1SJacky Bai 35*4ddfb6f1SJacky Bai static scmi_channel_plat_info_t sq_scmi_plat_info = { 36*4ddfb6f1SJacky Bai .scmi_mbx_mem = IMX9_SCMI_PAYLOAD_BASE, 37*4ddfb6f1SJacky Bai .db_reg_addr = IMX9_MU1_BASE + MU_GCR_OFF, 38*4ddfb6f1SJacky Bai .db_preserve_mask = 0xfffffffe, 39*4ddfb6f1SJacky Bai .db_modify_mask = 0x1, 40*4ddfb6f1SJacky Bai .ring_doorbell = &mu_ring_doorbell, 41*4ddfb6f1SJacky Bai }; 42*4ddfb6f1SJacky Bai scmi_ap_core_init(scmi_channel_t * ch)43*4ddfb6f1SJacky Baistatic int scmi_ap_core_init(scmi_channel_t *ch) 44*4ddfb6f1SJacky Bai { 45*4ddfb6f1SJacky Bai uint32_t version; 46*4ddfb6f1SJacky Bai int ret; 47*4ddfb6f1SJacky Bai 48*4ddfb6f1SJacky Bai ret = scmi_proto_version(ch, SCMI_CORE_PROTO_ID, &version); 49*4ddfb6f1SJacky Bai if (ret != SCMI_E_SUCCESS) { 50*4ddfb6f1SJacky Bai WARN("SCMI AP core protocol version message failed\n"); 51*4ddfb6f1SJacky Bai return -1; 52*4ddfb6f1SJacky Bai } 53*4ddfb6f1SJacky Bai 54*4ddfb6f1SJacky Bai INFO("SCMI AP core protocol version 0x%x detected\n", version); 55*4ddfb6f1SJacky Bai 56*4ddfb6f1SJacky Bai return 0; 57*4ddfb6f1SJacky Bai } 58*4ddfb6f1SJacky Bai plat_imx9_scmi_setup(void)59*4ddfb6f1SJacky Baivoid plat_imx9_scmi_setup(void) 60*4ddfb6f1SJacky Bai { 61*4ddfb6f1SJacky Bai channel.info = &sq_scmi_plat_info; 62*4ddfb6f1SJacky Bai channel.lock = IMX95_SCMI_LOCK_GET_INSTANCE; 63*4ddfb6f1SJacky Bai imx9_scmi_handle = scmi_init(&channel); 64*4ddfb6f1SJacky Bai if (imx9_scmi_handle == NULL) { 65*4ddfb6f1SJacky Bai ERROR("SCMI Initialization failed\n"); 66*4ddfb6f1SJacky Bai panic(); 67*4ddfb6f1SJacky Bai } 68*4ddfb6f1SJacky Bai if (scmi_ap_core_init(&channel) < 0) { 69*4ddfb6f1SJacky Bai ERROR("SCMI AP core protocol initialization failed\n"); 70*4ddfb6f1SJacky Bai panic(); 71*4ddfb6f1SJacky Bai } 72*4ddfb6f1SJacky Bai } 73