blob: 779e646c1263913aaf5d5617b241a606b91d71d2 [file] [log] [blame]
developer2fddd722022-05-20 11:22:21 +08001// SPDX-License-Identifier: GPL-2.0
2/*
3 * Copyright (C) 2022 MediaTek Inc. All rights reserved.
4 *
5 * Author: Weijie Gao <weijie.gao@mediatek.com>
6 */
7
8#include <asm/io.h>
9#include <asm/addrspace.h>
10#include <asm/mipsregs.h>
11#include <asm/cm.h>
12#include <linux/bitfield.h>
13#include "../mt7621.h"
14
15/* GIC Shared Register Bases */
16#define GIC_SH_POL_BASE 0x100
17#define GIC_SH_TRIG_BASE 0x180
18#define GIC_SH_RMASK_BASE 0x300
19#define GIC_SH_SMASK_BASE 0x380
20#define GIC_SH_MASK_BASE 0x400
21#define GIC_SH_PEND_BASE 0x480
22#define GIC_SH_MAP_PIN_BASE 0x500
23#define GIC_SH_MAP_VPE_BASE 0x2000
24
25/* GIC Registers */
26#define GIC_SH_POL31_0 (GIC_SH_POL_BASE + 0x00)
27#define GIC_SH_POL63_32 (GIC_SH_POL_BASE + 0x04)
28
29#define GIC_SH_TRIG31_0 (GIC_SH_TRIG_BASE + 0x00)
30#define GIC_SH_TRIG63_32 (GIC_SH_TRIG_BASE + 0x04)
31
32#define GIC_SH_RMASK31_0 (GIC_SH_RMASK_BASE + 0x00)
33#define GIC_SH_RMASK63_32 (GIC_SH_RMASK_BASE + 0x04)
34
35#define GIC_SH_SMASK31_0 (GIC_SH_SMASK_BASE + 0x00)
36#define GIC_SH_SMASK63_32 (GIC_SH_SMASK_BASE + 0x04)
37
38#define GIC_SH_MAP_PIN(n) (GIC_SH_MAP_PIN_BASE + (n) * 4)
39
40#define GIC_SH_MAP_VPE(n, v) (GIC_SH_MAP_VPE_BASE + (n) * 0x20 + ((v) / 32) * 4)
41#define GIC_SH_MAP_VPE31_0(n) GIC_SH_MAP_VPE(n, 0)
42
43/* GIC_SH_MAP_PIN fields */
44#define GIC_MAP_TO_PIN BIT(31)
45#define GIC_MAP_TO_NMI BIT(30)
46#define GIC_MAP GENMASK(5, 0)
47#define GIC_MAP_SHIFT 0
48
49static void cm_init(void __iomem *cm_base)
50{
51 u32 gcrcfg, num_cores;
52
53 gcrcfg = readl(cm_base + GCR_CONFIG);
54 num_cores = FIELD_GET(GCR_CONFIG_PCORES, gcrcfg) + 1;
55
56 writel((1 << num_cores) - 1, cm_base + GCR_ACCESS);
57
58 writel(GCR_REG0_BASE_VALUE, cm_base + GCR_REG0_BASE);
59 writel(GCR_REG1_BASE_VALUE, cm_base + GCR_REG1_BASE);
60 writel(GCR_REG2_BASE_VALUE, cm_base + GCR_REG2_BASE);
61 writel(GCR_REG3_BASE_VALUE, cm_base + GCR_REG3_BASE);
62
63 clrsetbits_32(cm_base + GCR_REG0_MASK,
64 GCR_REGn_MASK_ADDRMASK | GCR_REGn_MASK_CMTGT,
65 FIELD_PREP(GCR_REGn_MASK_ADDRMASK, GCR_REG0_MASK_VALUE) |
66 GCR_REGn_MASK_CMTGT_IOCU0);
67
68 clrsetbits_32(cm_base + GCR_REG1_MASK,
69 GCR_REGn_MASK_ADDRMASK | GCR_REGn_MASK_CMTGT,
70 FIELD_PREP(GCR_REGn_MASK_ADDRMASK, GCR_REG1_MASK_VALUE) |
71 GCR_REGn_MASK_CMTGT_IOCU0);
72
73 clrsetbits_32(cm_base + GCR_REG2_MASK,
74 GCR_REGn_MASK_ADDRMASK | GCR_REGn_MASK_CMTGT,
75 FIELD_PREP(GCR_REGn_MASK_ADDRMASK, GCR_REG2_MASK_VALUE) |
76 GCR_REGn_MASK_CMTGT_IOCU0);
77
78 clrsetbits_32(cm_base + GCR_REG3_MASK,
79 GCR_REGn_MASK_ADDRMASK | GCR_REGn_MASK_CMTGT,
80 FIELD_PREP(GCR_REGn_MASK_ADDRMASK, GCR_REG3_MASK_VALUE) |
81 GCR_REGn_MASK_CMTGT_IOCU0);
82
83 clrbits_32(cm_base + GCR_BASE, CM_DEFAULT_TARGET_MASK);
84 setbits_32(cm_base + GCR_CONTROL, GCR_CONTROL_SYNCCTL);
85}
86
87static void gic_init(void)
88{
89 void __iomem *gic_base = (void *)KSEG1ADDR(MIPS_GIC_BASE);
90 int i;
91
92 /* Interrupt 0..5: Level Trigger, Active High */
93 writel(0, gic_base + GIC_SH_TRIG31_0);
94 writel(0x3f, gic_base + GIC_SH_RMASK31_0);
95 writel(0x3f, gic_base + GIC_SH_POL31_0);
96 writel(0x3f, gic_base + GIC_SH_SMASK31_0);
97
98 /* Interrupt 56..63: Edge Trigger, Rising Edge */
99 /* Hardcoded to set up the last 8 external interrupts for IPI. */
100 writel(0xff000000, gic_base + GIC_SH_TRIG63_32);
101 writel(0xff000000, gic_base + GIC_SH_RMASK63_32);
102 writel(0xff000000, gic_base + GIC_SH_POL63_32);
103 writel(0xff000000, gic_base + GIC_SH_SMASK63_32);
104
105 /* Map interrupt source to particular hardware interrupt pin */
106 /* source {0,1,2,3,4,5} -> pin {0,0,4,3,0,5} */
107 writel(GIC_MAP_TO_PIN | 0, gic_base + GIC_SH_MAP_PIN(0));
108 writel(GIC_MAP_TO_PIN | 0, gic_base + GIC_SH_MAP_PIN(1));
109 writel(GIC_MAP_TO_PIN | 4, gic_base + GIC_SH_MAP_PIN(2));
110 writel(GIC_MAP_TO_PIN | 3, gic_base + GIC_SH_MAP_PIN(3));
111 writel(GIC_MAP_TO_PIN | 0, gic_base + GIC_SH_MAP_PIN(4));
112 writel(GIC_MAP_TO_PIN | 5, gic_base + GIC_SH_MAP_PIN(5));
113
114 /* source 56~59 -> pin 1, 60~63 -> pin 2 */
115 writel(GIC_MAP_TO_PIN | 1, gic_base + GIC_SH_MAP_PIN(56));
116 writel(GIC_MAP_TO_PIN | 1, gic_base + GIC_SH_MAP_PIN(57));
117 writel(GIC_MAP_TO_PIN | 1, gic_base + GIC_SH_MAP_PIN(58));
118 writel(GIC_MAP_TO_PIN | 1, gic_base + GIC_SH_MAP_PIN(59));
119 writel(GIC_MAP_TO_PIN | 2, gic_base + GIC_SH_MAP_PIN(60));
120 writel(GIC_MAP_TO_PIN | 2, gic_base + GIC_SH_MAP_PIN(61));
121 writel(GIC_MAP_TO_PIN | 2, gic_base + GIC_SH_MAP_PIN(62));
122 writel(GIC_MAP_TO_PIN | 2, gic_base + GIC_SH_MAP_PIN(63));
123
124 /* Interrupt map to VPE (bit mask) */
125 for (i = 0; i < 32; i++)
126 writel(BIT(0), gic_base + GIC_SH_MAP_VPE31_0(i));
127
128 /*
129 * Direct GIC_int 56..63 to vpe 0..3
130 * MIPS Linux convention that last 16 interrupts implemented be set
131 * aside for IPI signaling.
132 * The actual interrupts are tied low and software sends interrupts
133 * via GIC_SH_WEDGE writes.
134 */
135 for (i = 0; i < 4; i++) {
136 writel(BIT(i), gic_base + GIC_SH_MAP_VPE31_0(i + 56));
137 writel(BIT(i), gic_base + GIC_SH_MAP_VPE31_0(i + 60));
138 }
139}
140
141void mt7621_cps_init(void)
142{
143 void __iomem *cm_base = (void *)KSEG1ADDR(CONFIG_MIPS_CM_BASE);
144
145 /* Enable GIC */
146 writel(MIPS_GIC_BASE | GCR_GIC_EN, cm_base + GCR_GIC_BASE);
147
148 /* Enable CPC */
149 writel(MIPS_CPC_BASE | GCR_CPC_EN, cm_base + GCR_CPC_BASE);
150
151 gic_init();
152 cm_init(cm_base);
153}