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
ptp3_init(unsigned int core)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
pdp_proc_arm_write(unsigned int pdp_n)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
pdp_init(unsigned int pdp_cpu)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
ptp3_core_init(unsigned int core)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
ptp3_core_deinit(unsigned int core)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 */
ptp3_handle_pwr_on_event(const void * arg)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 */
ptp3_handle_pwr_off_event(const void * arg)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