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