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