mediatek: mt8183: support CPU hotplug
[project/bcm63xx/atf.git] / plat / mediatek / mt8183 / plat_dcm.c
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
31 void dcm_lock_init(void)
32 {
33 bakery_lock_init(&dcm_lock);
34 }
35
36 void dcm_lock_get(void)
37 {
38 bakery_lock_get(&dcm_lock);
39 }
40
41 void dcm_lock_release(void)
42 {
43 bakery_lock_release(&dcm_lock);
44 }
45
46 void plat_dcm_mcsi_a_backup(void)
47 {
48 }
49
50 void plat_dcm_mcsi_a_restore(void)
51 {
52 }
53
54 void plat_dcm_rgu_enable(void)
55 {
56 }
57
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
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
94 void plat_dcm_msg_handler(uint64_t x1)
95 {
96 plat_dcm_init_type = x1 & ALL_DCM_TYPE;
97 }
98
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
109 void plat_dcm_init(void)
110 {
111 dcm_lock_init();
112 }