1*44a10511SRiven Chen /* 2*44a10511SRiven Chen * Copyright (c) 2022, MediaTek Inc. All rights reserved. 3*44a10511SRiven Chen * 4*44a10511SRiven Chen * SPDX-License-Identifier: BSD-3-Clause 5*44a10511SRiven Chen */ 6*44a10511SRiven Chen 7*44a10511SRiven Chen #include <arch_helpers.h> 8*44a10511SRiven Chen #if MTK_PUBEVENT_ENABLE 9*44a10511SRiven Chen #include <lib/pm/mtk_pm.h> 10*44a10511SRiven Chen #endif 11*44a10511SRiven Chen #include <ptp3_plat.h> 12*44a10511SRiven Chen 13*44a10511SRiven Chen #define PTP3_CORE_OFT(core) (0x800 * (core)) 14*44a10511SRiven Chen 15*44a10511SRiven Chen static void ptp3_init(unsigned int core) 16*44a10511SRiven Chen { 17*44a10511SRiven Chen unsigned int i, addr, value; 18*44a10511SRiven Chen 19*44a10511SRiven Chen if (core < PTP3_CFG_CPU_START_ID_B) { 20*44a10511SRiven Chen mmio_clrsetbits_32(ptp3_cfg1[0][PTP3_CFG_ADDR], PTP3_CFG1_MASK, 21*44a10511SRiven Chen ptp3_cfg1[0][PTP3_CFG_VALUE]); 22*44a10511SRiven Chen } else { 23*44a10511SRiven Chen mmio_clrsetbits_32(ptp3_cfg1[1][PTP3_CFG_ADDR], PTP3_CFG1_MASK, 24*44a10511SRiven Chen ptp3_cfg1[1][PTP3_CFG_VALUE]); 25*44a10511SRiven Chen } 26*44a10511SRiven Chen 27*44a10511SRiven Chen if (core < PTP3_CFG_CPU_START_ID_B) { 28*44a10511SRiven Chen for (i = 0; i < NR_PTP3_CFG2_DATA; i++) { 29*44a10511SRiven Chen addr = ptp3_cfg2[i][PTP3_CFG_ADDR] + PTP3_CORE_OFT(core); 30*44a10511SRiven Chen value = ptp3_cfg2[i][PTP3_CFG_VALUE]; 31*44a10511SRiven Chen 32*44a10511SRiven Chen mmio_write_32(addr, value); 33*44a10511SRiven Chen } 34*44a10511SRiven Chen } else { 35*44a10511SRiven Chen for (i = 0; i < NR_PTP3_CFG2_DATA; i++) { 36*44a10511SRiven Chen addr = ptp3_cfg2[i][PTP3_CFG_ADDR] + PTP3_CORE_OFT(core); 37*44a10511SRiven Chen 38*44a10511SRiven Chen if (i == 2) { 39*44a10511SRiven Chen value = ptp3_cfg2[i][PTP3_CFG_VALUE] + 0x5E0; 40*44a10511SRiven Chen } else { 41*44a10511SRiven Chen value = ptp3_cfg2[i][PTP3_CFG_VALUE]; 42*44a10511SRiven Chen } 43*44a10511SRiven Chen mmio_write_32(addr, value); 44*44a10511SRiven Chen } 45*44a10511SRiven Chen } 46*44a10511SRiven Chen 47*44a10511SRiven Chen if (core < PTP3_CFG_CPU_START_ID_B) { 48*44a10511SRiven Chen addr = ptp3_cfg3[PTP3_CFG_ADDR] + PTP3_CORE_OFT(core); 49*44a10511SRiven Chen value = ptp3_cfg3[PTP3_CFG_VALUE]; 50*44a10511SRiven Chen } else { 51*44a10511SRiven Chen addr = ptp3_cfg3_ext[PTP3_CFG_ADDR] + PTP3_CORE_OFT(core); 52*44a10511SRiven Chen value = ptp3_cfg3_ext[PTP3_CFG_VALUE]; 53*44a10511SRiven Chen } 54*44a10511SRiven Chen mmio_write_32(addr, value & PTP3_CFG3_MASK1); 55*44a10511SRiven Chen mmio_write_32(addr, value & PTP3_CFG3_MASK2); 56*44a10511SRiven Chen mmio_write_32(addr, value & PTP3_CFG3_MASK3); 57*44a10511SRiven Chen } 58*44a10511SRiven Chen 59*44a10511SRiven Chen static void pdp_proc_arm_write(unsigned int pdp_n) 60*44a10511SRiven Chen { 61*44a10511SRiven Chen unsigned long v = 0; 62*44a10511SRiven Chen 63*44a10511SRiven Chen dsb(); 64*44a10511SRiven Chen __asm__ volatile ("mrs %0, S3_6_C15_C2_0" : "=r" (v)); 65*44a10511SRiven Chen v |= (UL(0x0) << 52); 66*44a10511SRiven Chen v |= (UL(0x1) << 53); 67*44a10511SRiven Chen v |= (UL(0x0) << 54); 68*44a10511SRiven Chen v |= (UL(0x0) << 48); 69*44a10511SRiven Chen v |= (UL(0x1) << 49); 70*44a10511SRiven Chen __asm__ volatile ("msr S3_6_C15_C2_0, %0" : : "r" (v)); 71*44a10511SRiven Chen dsb(); 72*44a10511SRiven Chen } 73*44a10511SRiven Chen 74*44a10511SRiven Chen static void pdp_init(unsigned int pdp_cpu) 75*44a10511SRiven Chen { 76*44a10511SRiven Chen if ((pdp_cpu >= PTP3_CFG_CPU_START_ID_B) && (pdp_cpu < NR_PTP3_CFG_CPU)) { 77*44a10511SRiven Chen pdp_proc_arm_write(pdp_cpu); 78*44a10511SRiven Chen } 79*44a10511SRiven Chen } 80*44a10511SRiven Chen 81*44a10511SRiven Chen void ptp3_core_init(unsigned int core) 82*44a10511SRiven Chen { 83*44a10511SRiven Chen ptp3_init(core); 84*44a10511SRiven Chen pdp_init(core); 85*44a10511SRiven Chen } 86*44a10511SRiven Chen 87*44a10511SRiven Chen void ptp3_core_deinit(unsigned int core) 88*44a10511SRiven Chen { 89*44a10511SRiven Chen /* TBD */ 90*44a10511SRiven Chen } 91*44a10511SRiven Chen 92*44a10511SRiven Chen #if MTK_PUBEVENT_ENABLE 93*44a10511SRiven Chen /* Handle for power on domain */ 94*44a10511SRiven Chen void *ptp3_handle_pwr_on_event(const void *arg) 95*44a10511SRiven Chen { 96*44a10511SRiven Chen if (arg != NULL) { 97*44a10511SRiven Chen struct mt_cpupm_event_data *data = (struct mt_cpupm_event_data *)arg; 98*44a10511SRiven Chen 99*44a10511SRiven Chen if ((data->pwr_domain & MT_CPUPM_PWR_DOMAIN_CORE) > 0) { 100*44a10511SRiven Chen ptp3_core_init(data->cpuid); 101*44a10511SRiven Chen } 102*44a10511SRiven Chen } 103*44a10511SRiven Chen return (void *)arg; 104*44a10511SRiven Chen } 105*44a10511SRiven Chen MT_CPUPM_SUBCRIBE_EVENT_PWR_ON(ptp3_handle_pwr_on_event); 106*44a10511SRiven Chen 107*44a10511SRiven Chen /* Handle for power off domain */ 108*44a10511SRiven Chen void *ptp3_handle_pwr_off_event(const void *arg) 109*44a10511SRiven Chen { 110*44a10511SRiven Chen if (arg != NULL) { 111*44a10511SRiven Chen struct mt_cpupm_event_data *data = (struct mt_cpupm_event_data *)arg; 112*44a10511SRiven Chen 113*44a10511SRiven Chen if ((data->pwr_domain & MT_CPUPM_PWR_DOMAIN_CORE) > 0) { 114*44a10511SRiven Chen ptp3_core_deinit(data->cpuid); 115*44a10511SRiven Chen } 116*44a10511SRiven Chen } 117*44a10511SRiven Chen return (void *)arg; 118*44a10511SRiven Chen } 119*44a10511SRiven Chen MT_CPUPM_SUBCRIBE_EVENT_PWR_OFF(ptp3_handle_pwr_off_event); 120*44a10511SRiven Chen #else 121*44a10511SRiven Chen #pragma message "PSCI hint not enable" 122*44a10511SRiven Chen #endif 123