0001
0002
0003
0004
0005
0006
0007 #include "coresight-etm4x.h"
0008 #include "coresight-etm4x-cfg.h"
0009 #include "coresight-priv.h"
0010 #include "coresight-syscfg.h"
0011
0012
0013 #define CHECKREG(cval, elem) \
0014 { \
0015 if (offset == cval) { \
0016 reg_csdev->driver_regval = &drvcfg->elem; \
0017 err = 0; \
0018 break; \
0019 } \
0020 }
0021
0022 #define CHECKREGIDX(cval, elem, off_idx, mask) \
0023 { \
0024 if (mask == cval) { \
0025 reg_csdev->driver_regval = &drvcfg->elem[off_idx]; \
0026 err = 0; \
0027 break; \
0028 } \
0029 }
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040
0041
0042
0043
0044
0045
0046 static int etm4_cfg_map_reg_offset(struct etmv4_drvdata *drvdata,
0047 struct cscfg_regval_csdev *reg_csdev, u32 offset)
0048 {
0049 int err = -EINVAL, idx;
0050 struct etmv4_config *drvcfg = &drvdata->config;
0051 u32 off_mask;
0052
0053 if (((offset >= TRCEVENTCTL0R) && (offset <= TRCVIPCSSCTLR)) ||
0054 ((offset >= TRCSEQRSTEVR) && (offset <= TRCEXTINSELR)) ||
0055 ((offset >= TRCCIDCCTLR0) && (offset <= TRCVMIDCCTLR1))) {
0056 do {
0057 CHECKREG(TRCEVENTCTL0R, eventctrl0);
0058 CHECKREG(TRCEVENTCTL1R, eventctrl1);
0059 CHECKREG(TRCSTALLCTLR, stall_ctrl);
0060 CHECKREG(TRCTSCTLR, ts_ctrl);
0061 CHECKREG(TRCSYNCPR, syncfreq);
0062 CHECKREG(TRCCCCTLR, ccctlr);
0063 CHECKREG(TRCBBCTLR, bb_ctrl);
0064 CHECKREG(TRCVICTLR, vinst_ctrl);
0065 CHECKREG(TRCVIIECTLR, viiectlr);
0066 CHECKREG(TRCVISSCTLR, vissctlr);
0067 CHECKREG(TRCVIPCSSCTLR, vipcssctlr);
0068 CHECKREG(TRCSEQRSTEVR, seq_rst);
0069 CHECKREG(TRCSEQSTR, seq_state);
0070 CHECKREG(TRCEXTINSELR, ext_inp);
0071 CHECKREG(TRCCIDCCTLR0, ctxid_mask0);
0072 CHECKREG(TRCCIDCCTLR1, ctxid_mask1);
0073 CHECKREG(TRCVMIDCCTLR0, vmid_mask0);
0074 CHECKREG(TRCVMIDCCTLR1, vmid_mask1);
0075 } while (0);
0076 } else if ((offset & GENMASK(11, 4)) == TRCSEQEVRn(0)) {
0077
0078 idx = (offset & GENMASK(3, 0)) / 4;
0079 if (idx < ETM_MAX_SEQ_STATES) {
0080 reg_csdev->driver_regval = &drvcfg->seq_ctrl[idx];
0081 err = 0;
0082 }
0083 } else if ((offset >= TRCSSCCRn(0)) && (offset <= TRCSSPCICRn(7))) {
0084
0085 idx = (offset & GENMASK(4, 0)) / 4;
0086 off_mask = (offset & GENMASK(11, 5));
0087 do {
0088 CHECKREGIDX(TRCSSCCRn(0), ss_ctrl, idx, off_mask);
0089 CHECKREGIDX(TRCSSCSRn(0), ss_status, idx, off_mask);
0090 CHECKREGIDX(TRCSSPCICRn(0), ss_pe_cmp, idx, off_mask);
0091 } while (0);
0092 } else if ((offset >= TRCCIDCVRn(0)) && (offset <= TRCVMIDCVRn(7))) {
0093
0094 idx = (offset & GENMASK(5, 0)) / 8;
0095 off_mask = (offset & GENMASK(11, 6));
0096 do {
0097 CHECKREGIDX(TRCCIDCVRn(0), ctxid_pid, idx, off_mask);
0098 CHECKREGIDX(TRCVMIDCVRn(0), vmid_val, idx, off_mask);
0099 } while (0);
0100 } else if ((offset >= TRCRSCTLRn(2)) &&
0101 (offset <= TRCRSCTLRn((ETM_MAX_RES_SEL - 1)))) {
0102
0103 idx = (offset & GENMASK(6, 0)) / 4;
0104 if (idx < ETM_MAX_RES_SEL) {
0105 reg_csdev->driver_regval = &drvcfg->res_ctrl[idx];
0106 err = 0;
0107 }
0108 } else if ((offset >= TRCACVRn(0)) &&
0109 (offset <= TRCACATRn((ETM_MAX_SINGLE_ADDR_CMP - 1)))) {
0110
0111 idx = (offset & GENMASK(6, 0)) / 8;
0112 off_mask = offset & GENMASK(11, 7);
0113 do {
0114 CHECKREGIDX(TRCACVRn(0), addr_val, idx, off_mask);
0115 CHECKREGIDX(TRCACATRn(0), addr_acc, idx, off_mask);
0116 } while (0);
0117 } else if ((offset >= TRCCNTRLDVRn(0)) &&
0118 (offset <= TRCCNTVRn((ETMv4_MAX_CNTR - 1)))) {
0119
0120 idx = (offset & GENMASK(3, 0)) / 4;
0121 off_mask = offset & GENMASK(11, 4);
0122 do {
0123 CHECKREGIDX(TRCCNTRLDVRn(0), cntrldvr, idx, off_mask);
0124 CHECKREGIDX(TRCCNTCTLRn(0), cntr_ctrl, idx, off_mask);
0125 CHECKREGIDX(TRCCNTVRn(0), cntr_val, idx, off_mask);
0126 } while (0);
0127 }
0128 return err;
0129 }
0130
0131
0132
0133
0134
0135
0136
0137
0138
0139
0140
0141
0142
0143
0144
0145
0146
0147 static int etm4_cfg_load_feature(struct coresight_device *csdev,
0148 struct cscfg_feature_csdev *feat_csdev)
0149 {
0150 struct device *dev = csdev->dev.parent;
0151 struct etmv4_drvdata *drvdata = dev_get_drvdata(dev);
0152 const struct cscfg_feature_desc *feat_desc = feat_csdev->feat_desc;
0153 u32 offset;
0154 int i = 0, err = 0;
0155
0156
0157
0158
0159
0160
0161 feat_csdev->drv_spinlock = &drvdata->spinlock;
0162
0163
0164 for (i = 0; i < feat_csdev->nr_regs && !err; i++) {
0165 offset = feat_desc->regs_desc[i].offset;
0166 err = etm4_cfg_map_reg_offset(drvdata, &feat_csdev->regs_csdev[i], offset);
0167 }
0168 return err;
0169 }
0170
0171
0172 #define CS_CFG_ETM4_MATCH_FLAGS (CS_CFG_MATCH_CLASS_SRC_ALL | \
0173 CS_CFG_MATCH_CLASS_SRC_ETM4)
0174
0175 int etm4_cscfg_register(struct coresight_device *csdev)
0176 {
0177 struct cscfg_csdev_feat_ops ops;
0178
0179 ops.load_feat = &etm4_cfg_load_feature;
0180
0181 return cscfg_register_csdev(csdev, CS_CFG_ETM4_MATCH_FLAGS, &ops);
0182 }