xref: /freebsd/sys/dev/qat/qat_common/adf_gen4_pfvf.c (revision 71625ec9ad2a9bc8c09784fbd23b759830e0ee5f)
1*266b0663SKrzysztof Zdziarski /* SPDX-License-Identifier: BSD-3-Clause */
2*266b0663SKrzysztof Zdziarski /* Copyright(c) 2007-2022 Intel Corporation */
3*266b0663SKrzysztof Zdziarski #include <linux/iopoll.h>
4*266b0663SKrzysztof Zdziarski #include <linux/mutex.h>
5*266b0663SKrzysztof Zdziarski #include <linux/types.h>
6*266b0663SKrzysztof Zdziarski #include "adf_accel_devices.h"
7*266b0663SKrzysztof Zdziarski #include "adf_common_drv.h"
8*266b0663SKrzysztof Zdziarski #include "adf_gen4_pfvf.h"
9*266b0663SKrzysztof Zdziarski #include "adf_pfvf_utils.h"
10*266b0663SKrzysztof Zdziarski #include "adf_pfvf_vf_proto.h"
11*266b0663SKrzysztof Zdziarski 
12*266b0663SKrzysztof Zdziarski #define ADF_4XXX_PF2VM_OFFSET(i) (0x40B010 + ((i)*0x20))
13*266b0663SKrzysztof Zdziarski #define ADF_4XXX_VM2PF_OFFSET(i) (0x40B014 + ((i)*0x20))
14*266b0663SKrzysztof Zdziarski 
15*266b0663SKrzysztof Zdziarski /* VF2PF interrupt source registers */
16*266b0663SKrzysztof Zdziarski #define ADF_4XXX_VM2PF_SOU 0x41A180
17*266b0663SKrzysztof Zdziarski #define ADF_4XXX_VM2PF_MSK 0x41A1C0
18*266b0663SKrzysztof Zdziarski #define ADF_GEN4_VF_MSK 0xFFFF
19*266b0663SKrzysztof Zdziarski 
20*266b0663SKrzysztof Zdziarski #define ADF_PFVF_GEN4_MSGTYPE_SHIFT 2
21*266b0663SKrzysztof Zdziarski #define ADF_PFVF_GEN4_MSGTYPE_MASK 0x3F
22*266b0663SKrzysztof Zdziarski #define ADF_PFVF_GEN4_MSGDATA_SHIFT 8
23*266b0663SKrzysztof Zdziarski #define ADF_PFVF_GEN4_MSGDATA_MASK 0xFFFFFF
24*266b0663SKrzysztof Zdziarski 
25*266b0663SKrzysztof Zdziarski #define ADF_4XXXIOV_PF2VM_OFFSET 0x100C
26*266b0663SKrzysztof Zdziarski #define ADF_4XXXIOV_VM2PF_OFFSET 0x1008
27*266b0663SKrzysztof Zdziarski static const struct pfvf_csr_format csr_gen4_fmt = {
28*266b0663SKrzysztof Zdziarski 	{ ADF_PFVF_GEN4_MSGTYPE_SHIFT, ADF_PFVF_GEN4_MSGTYPE_MASK },
29*266b0663SKrzysztof Zdziarski 	{ ADF_PFVF_GEN4_MSGDATA_SHIFT, ADF_PFVF_GEN4_MSGDATA_MASK },
30*266b0663SKrzysztof Zdziarski };
31*266b0663SKrzysztof Zdziarski 
32*266b0663SKrzysztof Zdziarski static u32
adf_gen4_vf_get_pfvf_offset(u32 i)33*266b0663SKrzysztof Zdziarski adf_gen4_vf_get_pfvf_offset(u32 i)
34*266b0663SKrzysztof Zdziarski {
35*266b0663SKrzysztof Zdziarski 	return ADF_4XXXIOV_PF2VM_OFFSET;
36*266b0663SKrzysztof Zdziarski }
37*266b0663SKrzysztof Zdziarski 
38*266b0663SKrzysztof Zdziarski static u32
adf_gen4_vf_get_vfpf_offset(u32 i)39*266b0663SKrzysztof Zdziarski adf_gen4_vf_get_vfpf_offset(u32 i)
40*266b0663SKrzysztof Zdziarski {
41*266b0663SKrzysztof Zdziarski 	return ADF_4XXXIOV_VM2PF_OFFSET;
42*266b0663SKrzysztof Zdziarski }
43*266b0663SKrzysztof Zdziarski 
44*266b0663SKrzysztof Zdziarski static int
adf_gen4_pfvf_send(struct adf_accel_dev * accel_dev,struct pfvf_message msg,u32 pfvf_offset,struct mutex * csr_lock)45*266b0663SKrzysztof Zdziarski adf_gen4_pfvf_send(struct adf_accel_dev *accel_dev,
46*266b0663SKrzysztof Zdziarski 		   struct pfvf_message msg,
47*266b0663SKrzysztof Zdziarski 		   u32 pfvf_offset,
48*266b0663SKrzysztof Zdziarski 		   struct mutex *csr_lock)
49*266b0663SKrzysztof Zdziarski {
50*266b0663SKrzysztof Zdziarski 	struct resource *pmisc_addr = adf_get_pmisc_base(accel_dev);
51*266b0663SKrzysztof Zdziarski 	u32 csr_val;
52*266b0663SKrzysztof Zdziarski 	int ret;
53*266b0663SKrzysztof Zdziarski 	csr_val = adf_pfvf_csr_msg_of(accel_dev, msg, &csr_gen4_fmt);
54*266b0663SKrzysztof Zdziarski 	if (unlikely(!csr_val))
55*266b0663SKrzysztof Zdziarski 		return -EINVAL;
56*266b0663SKrzysztof Zdziarski 
57*266b0663SKrzysztof Zdziarski 	mutex_lock(csr_lock);
58*266b0663SKrzysztof Zdziarski 
59*266b0663SKrzysztof Zdziarski 	ADF_CSR_WR(pmisc_addr, pfvf_offset, csr_val | ADF_PFVF_INT);
60*266b0663SKrzysztof Zdziarski 
61*266b0663SKrzysztof Zdziarski 	/* Wait for confirmation from remote that it received the message */
62*266b0663SKrzysztof Zdziarski 	ret = read_poll_timeout(ADF_CSR_RD,
63*266b0663SKrzysztof Zdziarski 				csr_val,
64*266b0663SKrzysztof Zdziarski 				!(csr_val & ADF_PFVF_INT),
65*266b0663SKrzysztof Zdziarski 				ADF_PFVF_MSG_ACK_DELAY_US,
66*266b0663SKrzysztof Zdziarski 				ADF_PFVF_MSG_ACK_MAX_DELAY_US,
67*266b0663SKrzysztof Zdziarski 				true,
68*266b0663SKrzysztof Zdziarski 				pmisc_addr,
69*266b0663SKrzysztof Zdziarski 				pfvf_offset);
70*266b0663SKrzysztof Zdziarski 	if (ret < 0)
71*266b0663SKrzysztof Zdziarski 		device_printf(GET_DEV(accel_dev),
72*266b0663SKrzysztof Zdziarski 			      "ACK not received from remote\n");
73*266b0663SKrzysztof Zdziarski 
74*266b0663SKrzysztof Zdziarski 	mutex_unlock(csr_lock);
75*266b0663SKrzysztof Zdziarski 	return ret;
76*266b0663SKrzysztof Zdziarski }
77*266b0663SKrzysztof Zdziarski 
78*266b0663SKrzysztof Zdziarski static int
adf_gen4_vf2pf_send(struct adf_accel_dev * accel_dev,struct pfvf_message msg,u32 pfvf_offset,struct mutex * csr_lock)79*266b0663SKrzysztof Zdziarski adf_gen4_vf2pf_send(struct adf_accel_dev *accel_dev,
80*266b0663SKrzysztof Zdziarski 		    struct pfvf_message msg,
81*266b0663SKrzysztof Zdziarski 		    u32 pfvf_offset,
82*266b0663SKrzysztof Zdziarski 		    struct mutex *csr_lock)
83*266b0663SKrzysztof Zdziarski {
84*266b0663SKrzysztof Zdziarski 	return adf_gen4_pfvf_send(accel_dev, msg, pfvf_offset, csr_lock);
85*266b0663SKrzysztof Zdziarski }
86*266b0663SKrzysztof Zdziarski 
87*266b0663SKrzysztof Zdziarski static struct pfvf_message
adf_gen4_pfvf_recv(struct adf_accel_dev * accel_dev,u32 pfvf_offset,u8 compat_ver)88*266b0663SKrzysztof Zdziarski adf_gen4_pfvf_recv(struct adf_accel_dev *accel_dev,
89*266b0663SKrzysztof Zdziarski 		   u32 pfvf_offset,
90*266b0663SKrzysztof Zdziarski 		   u8 compat_ver)
91*266b0663SKrzysztof Zdziarski {
92*266b0663SKrzysztof Zdziarski 	struct resource *pmisc_addr = adf_get_pmisc_base(accel_dev);
93*266b0663SKrzysztof Zdziarski 	struct pfvf_message msg = { 0 };
94*266b0663SKrzysztof Zdziarski 	u32 csr_val;
95*266b0663SKrzysztof Zdziarski 
96*266b0663SKrzysztof Zdziarski 	/* Read message from the CSR */
97*266b0663SKrzysztof Zdziarski 	csr_val = ADF_CSR_RD(pmisc_addr, pfvf_offset);
98*266b0663SKrzysztof Zdziarski 	if (!(csr_val & ADF_PFVF_INT)) {
99*266b0663SKrzysztof Zdziarski 		device_printf(GET_DEV(accel_dev),
100*266b0663SKrzysztof Zdziarski 			      "Spurious PFVF interrupt, msg 0x%.8x. Ignored\n",
101*266b0663SKrzysztof Zdziarski 			      csr_val);
102*266b0663SKrzysztof Zdziarski 		return msg;
103*266b0663SKrzysztof Zdziarski 	}
104*266b0663SKrzysztof Zdziarski 
105*266b0663SKrzysztof Zdziarski 	/* We can now acknowledge the message reception by clearing the
106*266b0663SKrzysztof Zdziarski 	 * interrupt bit
107*266b0663SKrzysztof Zdziarski 	 */
108*266b0663SKrzysztof Zdziarski 	ADF_CSR_WR(pmisc_addr, pfvf_offset, csr_val & ~ADF_PFVF_INT);
109*266b0663SKrzysztof Zdziarski 
110*266b0663SKrzysztof Zdziarski 	/* Return the pfvf_message format */
111*266b0663SKrzysztof Zdziarski 	return adf_pfvf_message_of(accel_dev, csr_val, &csr_gen4_fmt);
112*266b0663SKrzysztof Zdziarski }
113*266b0663SKrzysztof Zdziarski 
114*266b0663SKrzysztof Zdziarski static struct pfvf_message
adf_gen4_pf2vf_recv(struct adf_accel_dev * accel_dev,u32 pfvf_offset,u8 compat_ver)115*266b0663SKrzysztof Zdziarski adf_gen4_pf2vf_recv(struct adf_accel_dev *accel_dev,
116*266b0663SKrzysztof Zdziarski 		    u32 pfvf_offset,
117*266b0663SKrzysztof Zdziarski 		    u8 compat_ver)
118*266b0663SKrzysztof Zdziarski {
119*266b0663SKrzysztof Zdziarski 	return adf_gen4_pfvf_recv(accel_dev, pfvf_offset, compat_ver);
120*266b0663SKrzysztof Zdziarski }
121*266b0663SKrzysztof Zdziarski 
122*266b0663SKrzysztof Zdziarski void
adf_gen4_init_vf_pfvf_ops(struct adf_pfvf_ops * pfvf_ops)123*266b0663SKrzysztof Zdziarski adf_gen4_init_vf_pfvf_ops(struct adf_pfvf_ops *pfvf_ops)
124*266b0663SKrzysztof Zdziarski {
125*266b0663SKrzysztof Zdziarski 	pfvf_ops->enable_comms = adf_enable_vf2pf_comms;
126*266b0663SKrzysztof Zdziarski 	pfvf_ops->get_pf2vf_offset = adf_gen4_vf_get_pfvf_offset;
127*266b0663SKrzysztof Zdziarski 	pfvf_ops->get_vf2pf_offset = adf_gen4_vf_get_vfpf_offset;
128*266b0663SKrzysztof Zdziarski 	pfvf_ops->send_msg = adf_gen4_vf2pf_send;
129*266b0663SKrzysztof Zdziarski 	pfvf_ops->recv_msg = adf_gen4_pf2vf_recv;
130*266b0663SKrzysztof Zdziarski }
131