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