aboutsummaryrefslogtreecommitdiff
path: root/plat/mediatek/mt8195/drivers/ptp3/mtk_ptp3_main.c
blob: 540cb33cb935080c7532c38ae2862952c81231a1 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
/*
 * Copyright (c) 2021, MediaTek Inc. All rights reserved. \
 *
 * SPDX-License-Identifier: BSD-3-Clause
 */

#include <arch_helpers.h>
#include <mtk_ptp3_common.h>

#define PTP3_CORE_OFT(core)	(0x800 * (core))

/************************************************
 * Central control
 ************************************************/
static unsigned int ptp3_cfg1[NR_PTP3_CFG1_DATA][NR_PTP3_CFG] = {
	{0x0C53A2A0, 0x1000},
	{0x0C53A2A4, 0x1000}
};

static unsigned int ptp3_cfg2[NR_PTP3_CFG2_DATA][NR_PTP3_CFG] = {
	{0x0C530404, 0x3A1000},
	{0x0C530428, 0x13E0408},
	{0x0C530434, 0xB22800},
	{0x0C53043C, 0x750},
	{0x0C530440, 0x0222c4cc}
};

static unsigned int ptp3_cfg3[NR_PTP3_CFG] = {0x0C530400, 0x2D80};
static unsigned int ptp3_cfg3_ext[NR_PTP3_CFG] = {0x0C530400, 0xC00};

static void ptp3_init(unsigned int core)
{
	unsigned int i, addr, value;

	if (core < PTP3_CFG_CPU_START_ID_B) {
		ptp3_clrsetbits(ptp3_cfg1[0][PTP3_CFG_ADDR], PTP3_CFG1_MASK,
				ptp3_cfg1[0][PTP3_CFG_VALUE]);
	} else {
		ptp3_clrsetbits(ptp3_cfg1[1][PTP3_CFG_ADDR], PTP3_CFG1_MASK,
				ptp3_cfg1[1][PTP3_CFG_VALUE]);
	}

	if (core < PTP3_CFG_CPU_START_ID_B) {
		for (i = 0; i < NR_PTP3_CFG2_DATA; i++) {
			addr = ptp3_cfg2[i][PTP3_CFG_ADDR] +
			       PTP3_CORE_OFT(core);
			value = ptp3_cfg2[i][PTP3_CFG_VALUE];

			ptp3_write(addr, value);
		}
	} else {
		for (i = 0; i < NR_PTP3_CFG2_DATA; i++) {
			addr = ptp3_cfg2[i][PTP3_CFG_ADDR] +
			       PTP3_CORE_OFT(core);

			if (i == 2) {
				value = ptp3_cfg2[i][PTP3_CFG_VALUE] + 0x5E0;
			} else {
				value = ptp3_cfg2[i][PTP3_CFG_VALUE];
			}
			ptp3_write(addr, value);
		}
	}

	if (core < PTP3_CFG_CPU_START_ID_B) {
		addr = ptp3_cfg3[PTP3_CFG_ADDR] + PTP3_CORE_OFT(core);
		value = ptp3_cfg3[PTP3_CFG_VALUE];

		ptp3_write(addr, value & PTP3_CFG3_MASK1);
		ptp3_write(addr, value & PTP3_CFG3_MASK2);
		ptp3_write(addr, value & PTP3_CFG3_MASK3);
	} else {
		addr = ptp3_cfg3_ext[PTP3_CFG_ADDR] + PTP3_CORE_OFT(core);
		value = ptp3_cfg3_ext[PTP3_CFG_VALUE];

		ptp3_write(addr, value & PTP3_CFG3_MASK1);
		ptp3_write(addr, value & PTP3_CFG3_MASK2);
		ptp3_write(addr, value & PTP3_CFG3_MASK3);
	}
}

void pdp_proc_ARM_write(unsigned int pdp_n)
{
	unsigned long v = 0;

	dsb();
	__asm__ volatile ("mrs %0, S3_6_C15_C2_0" : "=r" (v));
	v |= (UL(0x0) << 52);
	v |= (UL(0x1) << 53);
	v |= (UL(0x0) << 54);
	v |= (UL(0x0) << 48);
	v |= (UL(0x1) << 49);
	__asm__ volatile ("msr S3_6_C15_C2_0, %0" : : "r" (v));
	dsb();
}

void pdp_init(unsigned int pdp_cpu, unsigned int en)
{
	if ((pdp_cpu >= PTP3_CFG_CPU_START_ID_B) &&
	    (pdp_cpu < NR_PTP3_CFG_CPU)) {
		pdp_proc_ARM_write(pdp_cpu);
	}
}

static void dt_proc_ARM_write(unsigned int dt_n)
{
	unsigned long v = 0;

	dsb();
	__asm__ volatile ("mrs %0, S3_6_C15_C2_0" : "=r" (v));
	v |= (UL(0x0) << 33);
	v |= (UL(0x0) << 32);
	__asm__ volatile ("msr S3_6_C15_C2_0, %0" : : "r" (v));
	dsb();
}

void dt_init(unsigned int dt_cpu, unsigned int en)
{
	if ((dt_cpu >= PTP3_CFG_CPU_START_ID_B) &&
	    (dt_cpu < NR_PTP3_CFG_CPU)) {
		dt_proc_ARM_write(dt_cpu);
	}
}
void ptp3_core_init(unsigned int core)
{
	/* init for ptp3 */
	ptp3_init(core);
	/* init for pdp */
	pdp_init(core, 1);
	/* init for dt */
	dt_init(core, 1);
}

void ptp3_core_unInit(unsigned int core)
{
	/* TBD */
}