in arm-ccn.c [943:989]
static void arm_ccn_pmu_xp_watchpoint_config(struct perf_event *event)
{
struct arm_ccn *ccn = pmu_to_arm_ccn(event->pmu);
struct hw_perf_event *hw = &event->hw;
struct arm_ccn_component *source =
ccn->dt.pmu_counters[hw->idx].source;
unsigned long wp = hw->config_base;
u32 val;
u64 cmp_l = event->attr.config1;
u64 cmp_h = event->attr.config2;
u64 mask_l = ccn->dt.cmp_mask[CCN_CONFIG_MASK(event->attr.config)].l;
u64 mask_h = ccn->dt.cmp_mask[CCN_CONFIG_MASK(event->attr.config)].h;
hw->event_base = CCN_XP_DT_CONFIG__DT_CFG__WATCHPOINT(wp);
/* Direction (RX/TX), device (port) & virtual channel */
val = readl(source->base + CCN_XP_DT_INTERFACE_SEL);
val &= ~(CCN_XP_DT_INTERFACE_SEL__DT_IO_SEL__MASK <<
CCN_XP_DT_INTERFACE_SEL__DT_IO_SEL__SHIFT(wp));
val |= CCN_CONFIG_DIR(event->attr.config) <<
CCN_XP_DT_INTERFACE_SEL__DT_IO_SEL__SHIFT(wp);
val &= ~(CCN_XP_DT_INTERFACE_SEL__DT_DEV_SEL__MASK <<
CCN_XP_DT_INTERFACE_SEL__DT_DEV_SEL__SHIFT(wp));
val |= CCN_CONFIG_PORT(event->attr.config) <<
CCN_XP_DT_INTERFACE_SEL__DT_DEV_SEL__SHIFT(wp);
val &= ~(CCN_XP_DT_INTERFACE_SEL__DT_VC_SEL__MASK <<
CCN_XP_DT_INTERFACE_SEL__DT_VC_SEL__SHIFT(wp));
val |= CCN_CONFIG_VC(event->attr.config) <<
CCN_XP_DT_INTERFACE_SEL__DT_VC_SEL__SHIFT(wp);
writel(val, source->base + CCN_XP_DT_INTERFACE_SEL);
/* Comparison values */
writel(cmp_l & 0xffffffff, source->base + CCN_XP_DT_CMP_VAL_L(wp));
writel((cmp_l >> 32) & 0x7fffffff,
source->base + CCN_XP_DT_CMP_VAL_L(wp) + 4);
writel(cmp_h & 0xffffffff, source->base + CCN_XP_DT_CMP_VAL_H(wp));
writel((cmp_h >> 32) & 0x0fffffff,
source->base + CCN_XP_DT_CMP_VAL_H(wp) + 4);
/* Mask */
writel(mask_l & 0xffffffff, source->base + CCN_XP_DT_CMP_MASK_L(wp));
writel((mask_l >> 32) & 0x7fffffff,
source->base + CCN_XP_DT_CMP_MASK_L(wp) + 4);
writel(mask_h & 0xffffffff, source->base + CCN_XP_DT_CMP_MASK_H(wp));
writel((mask_h >> 32) & 0x0fffffff,
source->base + CCN_XP_DT_CMP_MASK_H(wp) + 4);
}