1 /*
2  * Copyright (c) 2019, MediaTek Inc. All rights reserved.
3  *
4  * SPDX-License-Identifier: BSD-3-Clause
5  */
6 
7 #include <arch.h>
8 #include <lib/bakery_lock.h>
9 #include <drivers/console.h>
10 #include <common/debug.h>
11 #include <lib/mmio.h>
12 #include <plat_dcm.h>
13 #include <plat_private.h>
14 #include <plat_dcm.h>
15 #include <plat/common/platform.h>
16 #include <platform_def.h>
17 #include <mtk_plat_common.h>
18 
19 #define PWR_STATUS                     (SPM_BASE + 0x180)
20 
21 uint64_t plat_dcm_mcsi_a_addr;
22 uint32_t plat_dcm_mcsi_a_val;
23 static int plat_dcm_init_type;
24 static unsigned int dcm_big_core_cnt;
25 int plat_dcm_initiated;
26 
27 #define PWR_STA_BIG_MP_MASK	(0x1 << 15)
28 
29 DEFINE_BAKERY_LOCK(dcm_lock);
30 
dcm_lock_init(void)31 void dcm_lock_init(void)
32 {
33 	bakery_lock_init(&dcm_lock);
34 }
35 
dcm_lock_get(void)36 void dcm_lock_get(void)
37 {
38 	bakery_lock_get(&dcm_lock);
39 }
40 
dcm_lock_release(void)41 void dcm_lock_release(void)
42 {
43 	bakery_lock_release(&dcm_lock);
44 }
45 
plat_dcm_mcsi_a_backup(void)46 void plat_dcm_mcsi_a_backup(void)
47 {
48 }
49 
plat_dcm_mcsi_a_restore(void)50 void plat_dcm_mcsi_a_restore(void)
51 {
52 }
53 
plat_dcm_rgu_enable(void)54 void plat_dcm_rgu_enable(void)
55 {
56 }
57 
plat_dcm_big_core_sync(short on)58 void plat_dcm_big_core_sync(short on)
59 {
60 	/* Check if Big cluster power is existed */
61 	if (!(mmio_read_32(PWR_STATUS) & PWR_STA_BIG_MP_MASK))
62 		return;
63 
64 	if (on) {
65 		mmio_write_32(MP2_SYNC_DCM,
66 			      (mmio_read_32(MP2_SYNC_DCM) & ~MP2_SYNC_DCM_MASK)
67 			      | MP2_SYNC_DCM_ON);
68 		dcm_big_core_cnt++;
69 	} else
70 		mmio_write_32(MP2_SYNC_DCM,
71 			      (mmio_read_32(MP2_SYNC_DCM) & ~MP2_SYNC_DCM_MASK)
72 			      | MP2_SYNC_DCM_OFF);
73 }
74 
plat_dcm_restore_cluster_on(unsigned long mpidr)75 void plat_dcm_restore_cluster_on(unsigned long mpidr)
76 {
77 	unsigned long cluster_id =
78 		(mpidr & MPIDR_CLUSTER_MASK) >> MPIDR_AFFINITY_BITS;
79 
80 	switch (cluster_id) {
81 	case 0x1:
82 		dcm_lock_get();
83 		if (plat_dcm_init_type & BIG_CORE_DCM_TYPE)
84 			plat_dcm_big_core_sync(1);
85 		else
86 			plat_dcm_big_core_sync(0);
87 		dcm_lock_release();
88 		break;
89 	default:
90 		break;
91 	}
92 }
93 
plat_dcm_msg_handler(uint64_t x1)94 void plat_dcm_msg_handler(uint64_t x1)
95 {
96 	plat_dcm_init_type = x1 & ALL_DCM_TYPE;
97 }
98 
plat_dcm_get_enabled_cnt(uint64_t type)99 unsigned long plat_dcm_get_enabled_cnt(uint64_t type)
100 {
101 	switch (type) {
102 	case BIG_CORE_DCM_TYPE:
103 		return dcm_big_core_cnt;
104 	default:
105 		return 0;
106 	}
107 }
108 
plat_dcm_init(void)109 void plat_dcm_init(void)
110 {
111 	dcm_lock_init();
112 }
113