1 /* 2 * Copyright (C) 2018 Marvell International Ltd. 3 * 4 * SPDX-License-Identifier: BSD-3-Clause 5 * https://spdx.org/licenses 6 */ 7 8 #include <platform_def.h> 9 10 #include <bl31/interrupt_mgmt.h> 11 #include <common/debug.h> 12 #include <drivers/arm/gicv2.h> 13 #include <lib/bakery_lock.h> 14 #include <lib/mmio.h> 15 #include <plat/common/platform.h> 16 17 #include <plat_marvell.h> 18 19 /* 20 * The following functions are defined as weak to allow a platform to override 21 * the way the GICv2 driver is initialised and used. 22 */ 23 #pragma weak plat_marvell_gic_driver_init 24 #pragma weak plat_marvell_gic_init 25 26 #define A7K8K_PIC_CAUSE_REG 0xf03f0100 27 #define A7K8K_PIC0_MASK_REG 0xf03f0108 28 29 #define A7K8K_PIC_PMUOF_IRQ_MASK (1 << 17) 30 31 #define A7K8K_PIC_MAX_IRQS 32 32 #define A7K8K_PIC_MAX_IRQ_MASK ((1UL << A7K8K_PIC_MAX_IRQS) - 1) 33 34 #define A7K8K_ODMIN_SET_REG 0xf0300040 35 #define A7K8K_ODMI_PMU_IRQ(idx) ((2 + idx) << 12) 36 37 #define A7K8K_ODMI_PMU_GIC_IRQ(idx) (130 + idx) 38 39 static DEFINE_BAKERY_LOCK(a7k8k_irq_lock); 40 41 /* 42 * On a GICv2 system, the Group 1 secure interrupts are treated as Group 0 43 * interrupts. 44 */ 45 static const interrupt_prop_t marvell_interrupt_props[] = { 46 PLAT_MARVELL_G1S_IRQ_PROPS(GICV2_INTR_GROUP0), 47 PLAT_MARVELL_G0_IRQ_PROPS(GICV2_INTR_GROUP0) 48 }; 49 50 static unsigned int target_mask_array[PLATFORM_CORE_COUNT]; 51 52 /* 53 * Ideally `marvell_gic_data` structure definition should be a `const` but it is 54 * kept as modifiable for overwriting with different GICD and GICC base when 55 * running on FVP with VE memory map. 56 */ 57 static gicv2_driver_data_t marvell_gic_data = { 58 .gicd_base = PLAT_MARVELL_GICD_BASE, 59 .gicc_base = PLAT_MARVELL_GICC_BASE, 60 .interrupt_props = marvell_interrupt_props, 61 .interrupt_props_num = ARRAY_SIZE(marvell_interrupt_props), 62 .target_masks = target_mask_array, 63 .target_masks_num = ARRAY_SIZE(target_mask_array), 64 }; 65 66 /* 67 * ARM common helper to initialize the GICv2 only driver. 68 */ 69 void plat_marvell_gic_driver_init(void) 70 { 71 gicv2_driver_init(&marvell_gic_data); 72 } 73 74 static uint64_t a7k8k_pmu_interrupt_handler(uint32_t id, 75 uint32_t flags, 76 void *handle, 77 void *cookie) 78 { 79 unsigned int idx = plat_my_core_pos(); 80 uint32_t irq; 81 82 bakery_lock_get(&a7k8k_irq_lock); 83 84 /* Acknowledge IRQ */ 85 irq = plat_ic_acknowledge_interrupt(); 86 87 plat_ic_end_of_interrupt(irq); 88 89 if (irq != MARVELL_IRQ_PIC0) { 90 bakery_lock_release(&a7k8k_irq_lock); 91 return 0; 92 } 93 94 /* Acknowledge PMU overflow IRQ in PIC0 */ 95 mmio_setbits_32(A7K8K_PIC_CAUSE_REG, A7K8K_PIC_PMUOF_IRQ_MASK); 96 97 /* Trigger ODMI Frame IRQ */ 98 mmio_write_32(A7K8K_ODMIN_SET_REG, A7K8K_ODMI_PMU_IRQ(idx)); 99 100 bakery_lock_release(&a7k8k_irq_lock); 101 102 return 0; 103 } 104 105 void mvebu_pmu_interrupt_enable(void) 106 { 107 unsigned int idx; 108 uint32_t flags; 109 int32_t rc; 110 111 /* Reset PIC */ 112 mmio_write_32(A7K8K_PIC_CAUSE_REG, A7K8K_PIC_MAX_IRQ_MASK); 113 /* Unmask PMU overflow IRQ in PIC0 */ 114 mmio_clrbits_32(A7K8K_PIC0_MASK_REG, A7K8K_PIC_PMUOF_IRQ_MASK); 115 116 /* Configure ODMI Frame IRQs as edge triggered */ 117 for (idx = 0; idx < PLATFORM_CORE_COUNT; idx++) 118 gicv2_interrupt_set_cfg(A7K8K_ODMI_PMU_GIC_IRQ(idx), 119 GIC_INTR_CFG_EDGE); 120 121 /* 122 * Register IRQ handler as INTR_TYPE_S_EL1 as its the only valid type 123 * for GICv2 in ARM-TF. 124 */ 125 flags = 0U; 126 set_interrupt_rm_flag((flags), (NON_SECURE)); 127 rc = register_interrupt_type_handler(INTR_TYPE_S_EL1, 128 a7k8k_pmu_interrupt_handler, 129 flags); 130 if (rc != 0) 131 panic(); 132 } 133 134 void mvebu_pmu_interrupt_disable(void) 135 { 136 /* Reset PIC */ 137 mmio_write_32(A7K8K_PIC_CAUSE_REG, A7K8K_PIC_MAX_IRQ_MASK); 138 /* Mask PMU overflow IRQ in PIC0 */ 139 mmio_setbits_32(A7K8K_PIC0_MASK_REG, A7K8K_PIC_PMUOF_IRQ_MASK); 140 } 141 142 void plat_marvell_gic_init(void) 143 { 144 gicv2_distif_init(); 145 gicv2_pcpu_distif_init(); 146 gicv2_set_pe_target_mask(plat_my_core_pos()); 147 gicv2_cpuif_enable(); 148 } 149