1// 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} 154