xref: /rk3399_ARM-atf/plat/imx/imx9/common/scmi/scmi_client.c (revision 480e8dd9df291cc0e31695983fa6ff235e1671cd)
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 Bai static 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 Bai static 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 Bai void 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