@@ -273,6 +273,11 @@ static inline bool afu_has_cap(struct afu *afu, u64 cap)
return afu_cap & cap;
}
+static inline bool afu_is_ocxl_lisn(struct afu *afu)
+{
+ return afu_has_cap(afu, SISL_INTVER_CAP_OCXL_LISN);
+}
+
static inline bool afu_is_afu_debug(struct afu *afu)
{
return afu_has_cap(afu, SISL_INTVER_CAP_AFU_DEBUG);
@@ -310,6 +310,10 @@ struct sisl_ctrl_map {
#define SISL_CTX_CAP_WRITE_CMD 0x0000000000000002ULL /* afu_rc 0x21 */
#define SISL_CTX_CAP_READ_CMD 0x0000000000000001ULL /* afu_rc 0x21 */
__be64 mbox_r;
+ __be64 lisn_pasid[2];
+ /* pasid _a arg must be ULL */
+#define SISL_LISN_PASID(_a, _b) (((_a) << 32) | (_b))
+ __be64 lisn_ea[3];
};
/* single copy global regs */
@@ -416,6 +420,7 @@ struct sisl_global_regs {
#define SISL_INTVER_CAP_RESERVED_CMD_MODE_B 0x100000000000ULL
#define SISL_INTVER_CAP_LUN_PROVISION 0x080000000000ULL
#define SISL_INTVER_CAP_AFU_DEBUG 0x040000000000ULL
+#define SISL_INTVER_CAP_OCXL_LISN 0x020000000000ULL
};
#define CXLFLASH_NUM_FC_PORTS_PER_BANK 2 /* fixed # of ports per bank */
@@ -269,6 +269,7 @@ static int afu_attach(struct cxlflash_cfg *cfg, struct ctx_info *ctxi)
int rc = 0;
struct hwq *hwq = get_hwq(afu, PRIMARY_HWQ);
u64 val;
+ int i;
/* Unlock cap and restrict user to read/write cmds in translated mode */
readq_be(&ctrl_map->mbox_r);
@@ -282,6 +283,19 @@ static int afu_attach(struct cxlflash_cfg *cfg, struct ctx_info *ctxi)
goto out;
}
+ if (afu_is_ocxl_lisn(afu)) {
+ /* Set up the LISN effective address for each interrupt */
+ for (i = 0; i < ctxi->irqs; i++) {
+ val = cfg->ops->get_irq_objhndl(ctxi->ctx, i);
+ writeq_be(val, &ctrl_map->lisn_ea[i]);
+ }
+
+ /* Use primary HWQ PASID as identifier for all interrupts */
+ val = hwq->ctx_hndl;
+ writeq_be(SISL_LISN_PASID(val, val), &ctrl_map->lisn_pasid[0]);
+ writeq_be(SISL_LISN_PASID(0UL, val), &ctrl_map->lisn_pasid[1]);
+ }
+
/* Set up MMIO registers pointing to the RHT */
writeq_be((u64)ctxi->rht_start, &ctrl_map->rht_start);
val = SISL_RHT_CNT_ID((u64)MAX_RHT_PER_CONTEXT, (u64)(hwq->ctx_hndl));