Merge branch 'perf/core' of git://git.kernel.org/pub/scm/linux/kernel/git/acme/linux...
[pandora-kernel.git] / arch / arm / kernel / perf_event_v7.c
index e20ca9c..4c85183 100644 (file)
  */
 
 #ifdef CONFIG_CPU_V7
-/* Common ARMv7 event types */
+/*
+ * Common ARMv7 event types
+ *
+ * Note: An implementation may not be able to count all of these events
+ * but the encodings are considered to be `reserved' in the case that
+ * they are not available.
+ */
 enum armv7_perf_types {
        ARMV7_PERFCTR_PMNC_SW_INCR              = 0x00,
        ARMV7_PERFCTR_IFETCH_MISS               = 0x01,
        ARMV7_PERFCTR_ITLB_MISS                 = 0x02,
-       ARMV7_PERFCTR_DCACHE_REFILL             = 0x03,
-       ARMV7_PERFCTR_DCACHE_ACCESS             = 0x04,
+       ARMV7_PERFCTR_DCACHE_REFILL             = 0x03, /* L1 */
+       ARMV7_PERFCTR_DCACHE_ACCESS             = 0x04, /* L1 */
        ARMV7_PERFCTR_DTLB_REFILL               = 0x05,
        ARMV7_PERFCTR_DREAD                     = 0x06,
        ARMV7_PERFCTR_DWRITE                    = 0x07,
-
+       ARMV7_PERFCTR_INSTR_EXECUTED            = 0x08,
        ARMV7_PERFCTR_EXC_TAKEN                 = 0x09,
        ARMV7_PERFCTR_EXC_EXECUTED              = 0x0A,
        ARMV7_PERFCTR_CID_WRITE                 = 0x0B,
@@ -39,21 +45,30 @@ enum armv7_perf_types {
         */
        ARMV7_PERFCTR_PC_WRITE                  = 0x0C,
        ARMV7_PERFCTR_PC_IMM_BRANCH             = 0x0D,
+       ARMV7_PERFCTR_PC_PROC_RETURN            = 0x0E,
        ARMV7_PERFCTR_UNALIGNED_ACCESS          = 0x0F,
+
+       /* These events are defined by the PMUv2 supplement (ARM DDI 0457A). */
        ARMV7_PERFCTR_PC_BRANCH_MIS_PRED        = 0x10,
        ARMV7_PERFCTR_CLOCK_CYCLES              = 0x11,
-
-       ARMV7_PERFCTR_PC_BRANCH_MIS_USED        = 0x12,
+       ARMV7_PERFCTR_PC_BRANCH_PRED            = 0x12,
+       ARMV7_PERFCTR_MEM_ACCESS                = 0x13,
+       ARMV7_PERFCTR_L1_ICACHE_ACCESS          = 0x14,
+       ARMV7_PERFCTR_L1_DCACHE_WB              = 0x15,
+       ARMV7_PERFCTR_L2_DCACHE_ACCESS          = 0x16,
+       ARMV7_PERFCTR_L2_DCACHE_REFILL          = 0x17,
+       ARMV7_PERFCTR_L2_DCACHE_WB              = 0x18,
+       ARMV7_PERFCTR_BUS_ACCESS                = 0x19,
+       ARMV7_PERFCTR_MEMORY_ERROR              = 0x1A,
+       ARMV7_PERFCTR_INSTR_SPEC                = 0x1B,
+       ARMV7_PERFCTR_TTBR_WRITE                = 0x1C,
+       ARMV7_PERFCTR_BUS_CYCLES                = 0x1D,
 
        ARMV7_PERFCTR_CPU_CYCLES                = 0xFF
 };
 
 /* ARMv7 Cortex-A8 specific event types */
 enum armv7_a8_perf_types {
-       ARMV7_PERFCTR_INSTR_EXECUTED            = 0x08,
-
-       ARMV7_PERFCTR_PC_PROC_RETURN            = 0x0E,
-
        ARMV7_PERFCTR_WRITE_BUFFER_FULL         = 0x40,
        ARMV7_PERFCTR_L2_STORE_MERGED           = 0x41,
        ARMV7_PERFCTR_L2_STORE_BUFF             = 0x42,
@@ -138,6 +153,39 @@ enum armv7_a9_perf_types {
        ARMV7_PERFCTR_PLE_RQST_PROG             = 0xA5
 };
 
+/* ARMv7 Cortex-A5 specific event types */
+enum armv7_a5_perf_types {
+       ARMV7_PERFCTR_IRQ_TAKEN                 = 0x86,
+       ARMV7_PERFCTR_FIQ_TAKEN                 = 0x87,
+
+       ARMV7_PERFCTR_EXT_MEM_RQST              = 0xc0,
+       ARMV7_PERFCTR_NC_EXT_MEM_RQST           = 0xc1,
+       ARMV7_PERFCTR_PREFETCH_LINEFILL         = 0xc2,
+       ARMV7_PERFCTR_PREFETCH_LINEFILL_DROP    = 0xc3,
+       ARMV7_PERFCTR_ENTER_READ_ALLOC          = 0xc4,
+       ARMV7_PERFCTR_READ_ALLOC                = 0xc5,
+
+       ARMV7_PERFCTR_STALL_SB_FULL             = 0xc9,
+};
+
+/* ARMv7 Cortex-A15 specific event types */
+enum armv7_a15_perf_types {
+       ARMV7_PERFCTR_L1_DCACHE_READ_ACCESS     = 0x40,
+       ARMV7_PERFCTR_L1_DCACHE_WRITE_ACCESS    = 0x41,
+       ARMV7_PERFCTR_L1_DCACHE_READ_REFILL     = 0x42,
+       ARMV7_PERFCTR_L1_DCACHE_WRITE_REFILL    = 0x43,
+
+       ARMV7_PERFCTR_L1_DTLB_READ_REFILL       = 0x4C,
+       ARMV7_PERFCTR_L1_DTLB_WRITE_REFILL      = 0x4D,
+
+       ARMV7_PERFCTR_L2_DCACHE_READ_ACCESS     = 0x50,
+       ARMV7_PERFCTR_L2_DCACHE_WRITE_ACCESS    = 0x51,
+       ARMV7_PERFCTR_L2_DCACHE_READ_REFILL     = 0x52,
+       ARMV7_PERFCTR_L2_DCACHE_WRITE_REFILL    = 0x53,
+
+       ARMV7_PERFCTR_SPEC_PC_WRITE             = 0x76,
+};
+
 /*
  * Cortex-A8 HW events mapping
  *
@@ -207,11 +255,6 @@ static const unsigned armv7_a8_perf_cache_map[PERF_COUNT_HW_CACHE_MAX]
                },
        },
        [C(DTLB)] = {
-               /*
-                * Only ITLB misses and DTLB refills are supported.
-                * If users want the DTLB refills misses a raw counter
-                * must be used.
-                */
                [C(OP_READ)] = {
                        [C(RESULT_ACCESS)]      = CACHE_OP_UNSUPPORTED,
                        [C(RESULT_MISS)]        = ARMV7_PERFCTR_DTLB_REFILL,
@@ -337,11 +380,6 @@ static const unsigned armv7_a9_perf_cache_map[PERF_COUNT_HW_CACHE_MAX]
                },
        },
        [C(DTLB)] = {
-               /*
-                * Only ITLB misses and DTLB refills are supported.
-                * If users want the DTLB refills misses a raw counter
-                * must be used.
-                */
                [C(OP_READ)] = {
                        [C(RESULT_ACCESS)]      = CACHE_OP_UNSUPPORTED,
                        [C(RESULT_MISS)]        = ARMV7_PERFCTR_DTLB_REFILL,
@@ -401,6 +439,242 @@ static const unsigned armv7_a9_perf_cache_map[PERF_COUNT_HW_CACHE_MAX]
        },
 };
 
+/*
+ * Cortex-A5 HW events mapping
+ */
+static const unsigned armv7_a5_perf_map[PERF_COUNT_HW_MAX] = {
+       [PERF_COUNT_HW_CPU_CYCLES]          = ARMV7_PERFCTR_CPU_CYCLES,
+       [PERF_COUNT_HW_INSTRUCTIONS]        = ARMV7_PERFCTR_INSTR_EXECUTED,
+       [PERF_COUNT_HW_CACHE_REFERENCES]    = HW_OP_UNSUPPORTED,
+       [PERF_COUNT_HW_CACHE_MISSES]        = HW_OP_UNSUPPORTED,
+       [PERF_COUNT_HW_BRANCH_INSTRUCTIONS] = ARMV7_PERFCTR_PC_WRITE,
+       [PERF_COUNT_HW_BRANCH_MISSES]       = ARMV7_PERFCTR_PC_BRANCH_MIS_PRED,
+       [PERF_COUNT_HW_BUS_CYCLES]          = HW_OP_UNSUPPORTED,
+};
+
+static const unsigned armv7_a5_perf_cache_map[PERF_COUNT_HW_CACHE_MAX]
+                                       [PERF_COUNT_HW_CACHE_OP_MAX]
+                                       [PERF_COUNT_HW_CACHE_RESULT_MAX] = {
+       [C(L1D)] = {
+               [C(OP_READ)] = {
+                       [C(RESULT_ACCESS)]
+                                       = ARMV7_PERFCTR_DCACHE_ACCESS,
+                       [C(RESULT_MISS)]
+                                       = ARMV7_PERFCTR_DCACHE_REFILL,
+               },
+               [C(OP_WRITE)] = {
+                       [C(RESULT_ACCESS)]
+                                       = ARMV7_PERFCTR_DCACHE_ACCESS,
+                       [C(RESULT_MISS)]
+                                       = ARMV7_PERFCTR_DCACHE_REFILL,
+               },
+               [C(OP_PREFETCH)] = {
+                       [C(RESULT_ACCESS)]
+                                       = ARMV7_PERFCTR_PREFETCH_LINEFILL,
+                       [C(RESULT_MISS)]
+                                       = ARMV7_PERFCTR_PREFETCH_LINEFILL_DROP,
+               },
+       },
+       [C(L1I)] = {
+               [C(OP_READ)] = {
+                       [C(RESULT_ACCESS)]      = ARMV7_PERFCTR_L1_ICACHE_ACCESS,
+                       [C(RESULT_MISS)]        = ARMV7_PERFCTR_IFETCH_MISS,
+               },
+               [C(OP_WRITE)] = {
+                       [C(RESULT_ACCESS)]      = ARMV7_PERFCTR_L1_ICACHE_ACCESS,
+                       [C(RESULT_MISS)]        = ARMV7_PERFCTR_IFETCH_MISS,
+               },
+               /*
+                * The prefetch counters don't differentiate between the I
+                * side and the D side.
+                */
+               [C(OP_PREFETCH)] = {
+                       [C(RESULT_ACCESS)]
+                                       = ARMV7_PERFCTR_PREFETCH_LINEFILL,
+                       [C(RESULT_MISS)]
+                                       = ARMV7_PERFCTR_PREFETCH_LINEFILL_DROP,
+               },
+       },
+       [C(LL)] = {
+               [C(OP_READ)] = {
+                       [C(RESULT_ACCESS)]      = CACHE_OP_UNSUPPORTED,
+                       [C(RESULT_MISS)]        = CACHE_OP_UNSUPPORTED,
+               },
+               [C(OP_WRITE)] = {
+                       [C(RESULT_ACCESS)]      = CACHE_OP_UNSUPPORTED,
+                       [C(RESULT_MISS)]        = CACHE_OP_UNSUPPORTED,
+               },
+               [C(OP_PREFETCH)] = {
+                       [C(RESULT_ACCESS)]      = CACHE_OP_UNSUPPORTED,
+                       [C(RESULT_MISS)]        = CACHE_OP_UNSUPPORTED,
+               },
+       },
+       [C(DTLB)] = {
+               [C(OP_READ)] = {
+                       [C(RESULT_ACCESS)]      = CACHE_OP_UNSUPPORTED,
+                       [C(RESULT_MISS)]        = ARMV7_PERFCTR_DTLB_REFILL,
+               },
+               [C(OP_WRITE)] = {
+                       [C(RESULT_ACCESS)]      = CACHE_OP_UNSUPPORTED,
+                       [C(RESULT_MISS)]        = ARMV7_PERFCTR_DTLB_REFILL,
+               },
+               [C(OP_PREFETCH)] = {
+                       [C(RESULT_ACCESS)]      = CACHE_OP_UNSUPPORTED,
+                       [C(RESULT_MISS)]        = CACHE_OP_UNSUPPORTED,
+               },
+       },
+       [C(ITLB)] = {
+               [C(OP_READ)] = {
+                       [C(RESULT_ACCESS)]      = CACHE_OP_UNSUPPORTED,
+                       [C(RESULT_MISS)]        = ARMV7_PERFCTR_ITLB_MISS,
+               },
+               [C(OP_WRITE)] = {
+                       [C(RESULT_ACCESS)]      = CACHE_OP_UNSUPPORTED,
+                       [C(RESULT_MISS)]        = ARMV7_PERFCTR_ITLB_MISS,
+               },
+               [C(OP_PREFETCH)] = {
+                       [C(RESULT_ACCESS)]      = CACHE_OP_UNSUPPORTED,
+                       [C(RESULT_MISS)]        = CACHE_OP_UNSUPPORTED,
+               },
+       },
+       [C(BPU)] = {
+               [C(OP_READ)] = {
+                       [C(RESULT_ACCESS)]      = ARMV7_PERFCTR_PC_BRANCH_PRED,
+                       [C(RESULT_MISS)]
+                                       = ARMV7_PERFCTR_PC_BRANCH_MIS_PRED,
+               },
+               [C(OP_WRITE)] = {
+                       [C(RESULT_ACCESS)]      = ARMV7_PERFCTR_PC_BRANCH_PRED,
+                       [C(RESULT_MISS)]
+                                       = ARMV7_PERFCTR_PC_BRANCH_MIS_PRED,
+               },
+               [C(OP_PREFETCH)] = {
+                       [C(RESULT_ACCESS)]      = CACHE_OP_UNSUPPORTED,
+                       [C(RESULT_MISS)]        = CACHE_OP_UNSUPPORTED,
+               },
+       },
+};
+
+/*
+ * Cortex-A15 HW events mapping
+ */
+static const unsigned armv7_a15_perf_map[PERF_COUNT_HW_MAX] = {
+       [PERF_COUNT_HW_CPU_CYCLES]          = ARMV7_PERFCTR_CPU_CYCLES,
+       [PERF_COUNT_HW_INSTRUCTIONS]        = ARMV7_PERFCTR_INSTR_EXECUTED,
+       [PERF_COUNT_HW_CACHE_REFERENCES]    = HW_OP_UNSUPPORTED,
+       [PERF_COUNT_HW_CACHE_MISSES]        = HW_OP_UNSUPPORTED,
+       [PERF_COUNT_HW_BRANCH_INSTRUCTIONS] = ARMV7_PERFCTR_SPEC_PC_WRITE,
+       [PERF_COUNT_HW_BRANCH_MISSES]       = ARMV7_PERFCTR_PC_BRANCH_MIS_PRED,
+       [PERF_COUNT_HW_BUS_CYCLES]          = ARMV7_PERFCTR_BUS_CYCLES,
+};
+
+static const unsigned armv7_a15_perf_cache_map[PERF_COUNT_HW_CACHE_MAX]
+                                       [PERF_COUNT_HW_CACHE_OP_MAX]
+                                       [PERF_COUNT_HW_CACHE_RESULT_MAX] = {
+       [C(L1D)] = {
+               [C(OP_READ)] = {
+                       [C(RESULT_ACCESS)]
+                                       = ARMV7_PERFCTR_L1_DCACHE_READ_ACCESS,
+                       [C(RESULT_MISS)]
+                                       = ARMV7_PERFCTR_L1_DCACHE_READ_REFILL,
+               },
+               [C(OP_WRITE)] = {
+                       [C(RESULT_ACCESS)]
+                                       = ARMV7_PERFCTR_L1_DCACHE_WRITE_ACCESS,
+                       [C(RESULT_MISS)]
+                                       = ARMV7_PERFCTR_L1_DCACHE_WRITE_REFILL,
+               },
+               [C(OP_PREFETCH)] = {
+                       [C(RESULT_ACCESS)]      = CACHE_OP_UNSUPPORTED,
+                       [C(RESULT_MISS)]        = CACHE_OP_UNSUPPORTED,
+               },
+       },
+       [C(L1I)] = {
+               /*
+                * Not all performance counters differentiate between read
+                * and write accesses/misses so we're not always strictly
+                * correct, but it's the best we can do. Writes and reads get
+                * combined in these cases.
+                */
+               [C(OP_READ)] = {
+                       [C(RESULT_ACCESS)]      = ARMV7_PERFCTR_L1_ICACHE_ACCESS,
+                       [C(RESULT_MISS)]        = ARMV7_PERFCTR_IFETCH_MISS,
+               },
+               [C(OP_WRITE)] = {
+                       [C(RESULT_ACCESS)]      = ARMV7_PERFCTR_L1_ICACHE_ACCESS,
+                       [C(RESULT_MISS)]        = ARMV7_PERFCTR_IFETCH_MISS,
+               },
+               [C(OP_PREFETCH)] = {
+                       [C(RESULT_ACCESS)]      = CACHE_OP_UNSUPPORTED,
+                       [C(RESULT_MISS)]        = CACHE_OP_UNSUPPORTED,
+               },
+       },
+       [C(LL)] = {
+               [C(OP_READ)] = {
+                       [C(RESULT_ACCESS)]
+                                       = ARMV7_PERFCTR_L2_DCACHE_READ_ACCESS,
+                       [C(RESULT_MISS)]
+                                       = ARMV7_PERFCTR_L2_DCACHE_READ_REFILL,
+               },
+               [C(OP_WRITE)] = {
+                       [C(RESULT_ACCESS)]
+                                       = ARMV7_PERFCTR_L2_DCACHE_WRITE_ACCESS,
+                       [C(RESULT_MISS)]
+                                       = ARMV7_PERFCTR_L2_DCACHE_WRITE_REFILL,
+               },
+               [C(OP_PREFETCH)] = {
+                       [C(RESULT_ACCESS)]      = CACHE_OP_UNSUPPORTED,
+                       [C(RESULT_MISS)]        = CACHE_OP_UNSUPPORTED,
+               },
+       },
+       [C(DTLB)] = {
+               [C(OP_READ)] = {
+                       [C(RESULT_ACCESS)]      = CACHE_OP_UNSUPPORTED,
+                       [C(RESULT_MISS)]
+                                       = ARMV7_PERFCTR_L1_DTLB_READ_REFILL,
+               },
+               [C(OP_WRITE)] = {
+                       [C(RESULT_ACCESS)]      = CACHE_OP_UNSUPPORTED,
+                       [C(RESULT_MISS)]
+                                       = ARMV7_PERFCTR_L1_DTLB_WRITE_REFILL,
+               },
+               [C(OP_PREFETCH)] = {
+                       [C(RESULT_ACCESS)]      = CACHE_OP_UNSUPPORTED,
+                       [C(RESULT_MISS)]        = CACHE_OP_UNSUPPORTED,
+               },
+       },
+       [C(ITLB)] = {
+               [C(OP_READ)] = {
+                       [C(RESULT_ACCESS)]      = CACHE_OP_UNSUPPORTED,
+                       [C(RESULT_MISS)]        = ARMV7_PERFCTR_ITLB_MISS,
+               },
+               [C(OP_WRITE)] = {
+                       [C(RESULT_ACCESS)]      = CACHE_OP_UNSUPPORTED,
+                       [C(RESULT_MISS)]        = ARMV7_PERFCTR_ITLB_MISS,
+               },
+               [C(OP_PREFETCH)] = {
+                       [C(RESULT_ACCESS)]      = CACHE_OP_UNSUPPORTED,
+                       [C(RESULT_MISS)]        = CACHE_OP_UNSUPPORTED,
+               },
+       },
+       [C(BPU)] = {
+               [C(OP_READ)] = {
+                       [C(RESULT_ACCESS)]      = ARMV7_PERFCTR_PC_BRANCH_PRED,
+                       [C(RESULT_MISS)]
+                                       = ARMV7_PERFCTR_PC_BRANCH_MIS_PRED,
+               },
+               [C(OP_WRITE)] = {
+                       [C(RESULT_ACCESS)]      = ARMV7_PERFCTR_PC_BRANCH_PRED,
+                       [C(RESULT_MISS)]
+                                       = ARMV7_PERFCTR_PC_BRANCH_MIS_PRED,
+               },
+               [C(OP_PREFETCH)] = {
+                       [C(RESULT_ACCESS)]      = CACHE_OP_UNSUPPORTED,
+                       [C(RESULT_MISS)]        = CACHE_OP_UNSUPPORTED,
+               },
+       },
+};
+
 /*
  * Perf Events counters
  */
@@ -933,6 +1207,26 @@ static const struct arm_pmu *__init armv7_a9_pmu_init(void)
        armv7pmu.num_events     = armv7_read_num_pmnc_events();
        return &armv7pmu;
 }
+
+static const struct arm_pmu *__init armv7_a5_pmu_init(void)
+{
+       armv7pmu.id             = ARM_PERF_PMU_ID_CA5;
+       armv7pmu.name           = "ARMv7 Cortex-A5";
+       armv7pmu.cache_map      = &armv7_a5_perf_cache_map;
+       armv7pmu.event_map      = &armv7_a5_perf_map;
+       armv7pmu.num_events     = armv7_read_num_pmnc_events();
+       return &armv7pmu;
+}
+
+static const struct arm_pmu *__init armv7_a15_pmu_init(void)
+{
+       armv7pmu.id             = ARM_PERF_PMU_ID_CA15;
+       armv7pmu.name           = "ARMv7 Cortex-A15";
+       armv7pmu.cache_map      = &armv7_a15_perf_cache_map;
+       armv7pmu.event_map      = &armv7_a15_perf_map;
+       armv7pmu.num_events     = armv7_read_num_pmnc_events();
+       return &armv7pmu;
+}
 #else
 static const struct arm_pmu *__init armv7_a8_pmu_init(void)
 {
@@ -943,4 +1237,14 @@ static const struct arm_pmu *__init armv7_a9_pmu_init(void)
 {
        return NULL;
 }
+
+static const struct arm_pmu *__init armv7_a5_pmu_init(void)
+{
+       return NULL;
+}
+
+static const struct arm_pmu *__init armv7_a15_pmu_init(void)
+{
+       return NULL;
+}
 #endif /* CONFIG_CPU_V7 */