xref: /dpdk/drivers/compress/octeontx/otx_zip.c (revision a80ea5c082f252f6e6fd4aa0c549913a80ef6c67)
143e610bbSSunila Sahu /* SPDX-License-Identifier: BSD-3-Clause
243e610bbSSunila Sahu  * Copyright(c) 2018 Cavium, Inc
343e610bbSSunila Sahu  */
443e610bbSSunila Sahu 
543e610bbSSunila Sahu #include "otx_zip.h"
643e610bbSSunila Sahu 
743e610bbSSunila Sahu uint64_t
zip_reg_read64(uint8_t * hw_addr,uint64_t offset)843e610bbSSunila Sahu zip_reg_read64(uint8_t *hw_addr, uint64_t offset)
943e610bbSSunila Sahu {
1043e610bbSSunila Sahu 	uint8_t *base = hw_addr;
1143e610bbSSunila Sahu 	return *(volatile uint64_t *)(base + offset);
1243e610bbSSunila Sahu }
1343e610bbSSunila Sahu 
1443e610bbSSunila Sahu void
zip_reg_write64(uint8_t * hw_addr,uint64_t offset,uint64_t val)1543e610bbSSunila Sahu zip_reg_write64(uint8_t *hw_addr, uint64_t offset, uint64_t val)
1643e610bbSSunila Sahu {
1743e610bbSSunila Sahu 	uint8_t *base = hw_addr;
1843e610bbSSunila Sahu 	*(uint64_t *)(base + offset) = val;
1943e610bbSSunila Sahu }
2043e610bbSSunila Sahu 
21c378f084SAshish Gupta static void
zip_q_enable(struct zipvf_qp * qp)22c378f084SAshish Gupta zip_q_enable(struct zipvf_qp *qp)
23c378f084SAshish Gupta {
24c378f084SAshish Gupta 	zip_vqx_ena_t que_ena;
25c378f084SAshish Gupta 
26c378f084SAshish Gupta 	/*ZIP VFx command queue init*/
27c378f084SAshish Gupta 	que_ena.u = 0ull;
28c378f084SAshish Gupta 	que_ena.s.ena = 1;
29c378f084SAshish Gupta 
30c378f084SAshish Gupta 	zip_reg_write64(qp->vf->vbar0, ZIP_VQ_ENA, que_ena.u);
31c378f084SAshish Gupta 	rte_wmb();
32c378f084SAshish Gupta }
33c378f084SAshish Gupta 
34c378f084SAshish Gupta /* initialize given qp on zip device */
35c378f084SAshish Gupta int
zipvf_q_init(struct zipvf_qp * qp)36c378f084SAshish Gupta zipvf_q_init(struct zipvf_qp *qp)
37c378f084SAshish Gupta {
38c378f084SAshish Gupta 	zip_vqx_sbuf_addr_t que_sbuf_addr;
39c378f084SAshish Gupta 
40c378f084SAshish Gupta 	uint64_t size;
41c378f084SAshish Gupta 	void *cmdq_addr;
42c378f084SAshish Gupta 	uint64_t iova;
43c378f084SAshish Gupta 	struct zipvf_cmdq *cmdq = &qp->cmdq;
44c378f084SAshish Gupta 	struct zip_vf *vf = qp->vf;
45c378f084SAshish Gupta 
46c378f084SAshish Gupta 	/* allocate and setup instruction queue */
47c378f084SAshish Gupta 	size = ZIP_MAX_CMDQ_SIZE;
48c378f084SAshish Gupta 	size = ZIP_ALIGN_ROUNDUP(size, ZIP_CMDQ_ALIGN);
49c378f084SAshish Gupta 
50c378f084SAshish Gupta 	cmdq_addr = rte_zmalloc(qp->name, size, ZIP_CMDQ_ALIGN);
51c378f084SAshish Gupta 	if (cmdq_addr == NULL)
52c378f084SAshish Gupta 		return -1;
53c378f084SAshish Gupta 
54c378f084SAshish Gupta 	cmdq->sw_head = (uint64_t *)cmdq_addr;
55c378f084SAshish Gupta 	cmdq->va = (uint8_t *)cmdq_addr;
56c378f084SAshish Gupta 	iova = rte_mem_virt2iova(cmdq_addr);
57c378f084SAshish Gupta 
58c378f084SAshish Gupta 	cmdq->iova = iova;
59c378f084SAshish Gupta 
60c378f084SAshish Gupta 	que_sbuf_addr.u = 0ull;
61*a80ea5c0SMahipal Challa 	if (vf->pdev->id.device_id == PCI_DEVICE_ID_OCTEONTX2_ZIPVF)
62*a80ea5c0SMahipal Challa 		que_sbuf_addr.s9x.ptr = (cmdq->iova >> 7);
63*a80ea5c0SMahipal Challa 	else
64c378f084SAshish Gupta 		que_sbuf_addr.s.ptr = (cmdq->iova >> 7);
65*a80ea5c0SMahipal Challa 
66c378f084SAshish Gupta 	zip_reg_write64(vf->vbar0, ZIP_VQ_SBUF_ADDR, que_sbuf_addr.u);
67c378f084SAshish Gupta 
68c378f084SAshish Gupta 	zip_q_enable(qp);
69c378f084SAshish Gupta 
70c378f084SAshish Gupta 	memset(cmdq->va, 0, ZIP_MAX_CMDQ_SIZE);
71c378f084SAshish Gupta 	rte_spinlock_init(&cmdq->qlock);
72c378f084SAshish Gupta 
73c378f084SAshish Gupta 	return 0;
74c378f084SAshish Gupta }
75c378f084SAshish Gupta 
76c378f084SAshish Gupta int
zipvf_q_term(struct zipvf_qp * qp)77c378f084SAshish Gupta zipvf_q_term(struct zipvf_qp *qp)
78c378f084SAshish Gupta {
79c378f084SAshish Gupta 	struct zipvf_cmdq *cmdq = &qp->cmdq;
80c378f084SAshish Gupta 	zip_vqx_ena_t que_ena;
81c378f084SAshish Gupta 	struct zip_vf *vf = qp->vf;
82c378f084SAshish Gupta 
83c378f084SAshish Gupta 	if (cmdq->va != NULL) {
84c378f084SAshish Gupta 		memset(cmdq->va, 0, ZIP_MAX_CMDQ_SIZE);
85c378f084SAshish Gupta 		rte_free(cmdq->va);
86c378f084SAshish Gupta 	}
87c378f084SAshish Gupta 
88c378f084SAshish Gupta 	/*Disabling the ZIP queue*/
89c378f084SAshish Gupta 	que_ena.u = 0ull;
90c378f084SAshish Gupta 	zip_reg_write64(vf->vbar0, ZIP_VQ_ENA, que_ena.u);
91c378f084SAshish Gupta 
92c378f084SAshish Gupta 	return 0;
93c378f084SAshish Gupta }
94c378f084SAshish Gupta 
9552048f8fSAshish Gupta void
zipvf_push_command(struct zipvf_qp * qp,union zip_inst_s * cmd)9652048f8fSAshish Gupta zipvf_push_command(struct zipvf_qp *qp, union zip_inst_s *cmd)
9752048f8fSAshish Gupta {
9852048f8fSAshish Gupta 	zip_quex_doorbell_t dbell;
9952048f8fSAshish Gupta 	union zip_nptr_s ncp;
10052048f8fSAshish Gupta 	uint64_t *ncb_ptr;
10152048f8fSAshish Gupta 	struct zipvf_cmdq *cmdq = &qp->cmdq;
10252048f8fSAshish Gupta 	void *reg_base = qp->vf->vbar0;
10352048f8fSAshish Gupta 
10452048f8fSAshish Gupta 	/*Held queue lock*/
10552048f8fSAshish Gupta 	rte_spinlock_lock(&(cmdq->qlock));
10652048f8fSAshish Gupta 
10752048f8fSAshish Gupta 	/* Check space availability in zip cmd queue */
10852048f8fSAshish Gupta 	if ((((cmdq->sw_head - (uint64_t *)cmdq->va) * sizeof(uint64_t *)) +
10952048f8fSAshish Gupta 		ZIP_CMD_SIZE) == (ZIP_MAX_CMDQ_SIZE - ZIP_MAX_NCBP_SIZE)) {
11052048f8fSAshish Gupta 		/*Last buffer of the command queue*/
11152048f8fSAshish Gupta 		memcpy((uint8_t *)cmdq->sw_head,
11252048f8fSAshish Gupta 			(uint8_t *)cmd,
11352048f8fSAshish Gupta 			sizeof(union zip_inst_s));
11452048f8fSAshish Gupta 		/* move pointer to next loc in unit of 64-bit word */
11552048f8fSAshish Gupta 		cmdq->sw_head += ZIP_CMD_SIZE_WORDS;
11652048f8fSAshish Gupta 
11752048f8fSAshish Gupta 		/* now, point the "Next-Chunk Buffer Ptr" to sw_head */
11852048f8fSAshish Gupta 		ncb_ptr = cmdq->sw_head;
11952048f8fSAshish Gupta 		/* Pointing head again to cmdqueue base*/
12052048f8fSAshish Gupta 		cmdq->sw_head = (uint64_t *)cmdq->va;
12152048f8fSAshish Gupta 
12252048f8fSAshish Gupta 		ncp.u = 0ull;
12352048f8fSAshish Gupta 		ncp.s.addr = cmdq->iova;
12452048f8fSAshish Gupta 		*ncb_ptr = ncp.u;
12552048f8fSAshish Gupta 	} else {
12652048f8fSAshish Gupta 		/*Enough buffers available in the command queue*/
12752048f8fSAshish Gupta 		memcpy((uint8_t *)cmdq->sw_head,
12852048f8fSAshish Gupta 			(uint8_t *)cmd,
12952048f8fSAshish Gupta 			sizeof(union zip_inst_s));
13052048f8fSAshish Gupta 		cmdq->sw_head += ZIP_CMD_SIZE_WORDS;
13152048f8fSAshish Gupta 	}
13252048f8fSAshish Gupta 
13352048f8fSAshish Gupta 	rte_wmb();
13452048f8fSAshish Gupta 
13552048f8fSAshish Gupta 	/* Ringing ZIP VF doorbell */
13652048f8fSAshish Gupta 	dbell.u = 0ull;
13752048f8fSAshish Gupta 	dbell.s.dbell_cnt = 1;
13852048f8fSAshish Gupta 	zip_reg_write64(reg_base, ZIP_VQ_DOORBELL, dbell.u);
13952048f8fSAshish Gupta 
14052048f8fSAshish Gupta 	rte_spinlock_unlock(&(cmdq->qlock));
14152048f8fSAshish Gupta }
142c378f084SAshish Gupta 
14343e610bbSSunila Sahu int
zipvf_create(struct rte_compressdev * compressdev)14443e610bbSSunila Sahu zipvf_create(struct rte_compressdev *compressdev)
14543e610bbSSunila Sahu {
14643e610bbSSunila Sahu 	struct   rte_pci_device *pdev = RTE_DEV_TO_PCI(compressdev->device);
14743e610bbSSunila Sahu 	struct   zip_vf *zipvf = NULL;
14843e610bbSSunila Sahu 	char     *dev_name = compressdev->data->name;
14943e610bbSSunila Sahu 	void     *vbar0;
15043e610bbSSunila Sahu 	uint64_t reg;
15143e610bbSSunila Sahu 
15243e610bbSSunila Sahu 	if (pdev->mem_resource[0].phys_addr == 0ULL)
15343e610bbSSunila Sahu 		return -EIO;
15443e610bbSSunila Sahu 
15543e610bbSSunila Sahu 	vbar0 = pdev->mem_resource[0].addr;
15643e610bbSSunila Sahu 	if (!vbar0) {
15743e610bbSSunila Sahu 		ZIP_PMD_ERR("Failed to map BAR0 of %s", dev_name);
15843e610bbSSunila Sahu 		return -ENODEV;
15943e610bbSSunila Sahu 	}
16043e610bbSSunila Sahu 
16143e610bbSSunila Sahu 	zipvf = (struct zip_vf *)(compressdev->data->dev_private);
16243e610bbSSunila Sahu 
16343e610bbSSunila Sahu 	if (!zipvf)
16443e610bbSSunila Sahu 		return -ENOMEM;
16543e610bbSSunila Sahu 
16643e610bbSSunila Sahu 	zipvf->vbar0 = vbar0;
16743e610bbSSunila Sahu 	reg = zip_reg_read64(zipvf->vbar0, ZIP_VF_PF_MBOXX(0));
16843e610bbSSunila Sahu 	/* Storing domain in local to ZIP VF */
16943e610bbSSunila Sahu 	zipvf->dom_sdom = reg;
17043e610bbSSunila Sahu 	zipvf->pdev = pdev;
17143e610bbSSunila Sahu 	zipvf->max_nb_queue_pairs = ZIP_MAX_VF_QUEUE;
17243e610bbSSunila Sahu 	return 0;
17343e610bbSSunila Sahu }
17443e610bbSSunila Sahu 
17543e610bbSSunila Sahu int
zipvf_destroy(struct rte_compressdev * compressdev)17643e610bbSSunila Sahu zipvf_destroy(struct rte_compressdev *compressdev)
17743e610bbSSunila Sahu {
17843e610bbSSunila Sahu 	struct zip_vf *vf = (struct zip_vf *)(compressdev->data->dev_private);
17943e610bbSSunila Sahu 
18043e610bbSSunila Sahu 	/* Rewriting the domain_id in ZIP_VF_MBOX for app rerun */
18143e610bbSSunila Sahu 	zip_reg_write64(vf->vbar0, ZIP_VF_PF_MBOXX(0), vf->dom_sdom);
18243e610bbSSunila Sahu 
18343e610bbSSunila Sahu 	return 0;
18443e610bbSSunila Sahu }
185