1 // SPDX-License-Identifier: BSD-2-Clause
2 /*
3  * Copyright 2019, 2021 NXP
4  *
5  * Brief   Descriptor construction functions.
6  */
7 #include <caam_desc_helper.h>
8 #include <caam_io.h>
9 #include <trace.h>
10 #include <types_ext.h>
11 
12 struct ptr_addr {
13 #ifdef CFG_CAAM_BIG_ENDIAN
14 	uint32_t high;
15 	uint32_t low;
16 #else
17 	uint32_t low;
18 	uint32_t high;
19 #endif /* CFG_CAAM_BIG_ENDIAN */
20 };
21 
caam_desc_get_len(uint32_t * desc)22 uint32_t caam_desc_get_len(uint32_t *desc)
23 {
24 	return GET_JD_DESCLEN(caam_read_val32((void *)desc));
25 }
26 
caam_desc_init(uint32_t * desc)27 void caam_desc_init(uint32_t *desc)
28 {
29 	*desc = 0;
30 }
31 
caam_desc_update_hdr(uint32_t * desc,uint32_t word)32 void caam_desc_update_hdr(uint32_t *desc, uint32_t word)
33 {
34 	/* Update first word of desc */
35 	caam_write_val32((void *)desc, word);
36 }
37 
caam_desc_add_word(uint32_t * desc,uint32_t word)38 void caam_desc_add_word(uint32_t *desc, uint32_t word)
39 {
40 	uint32_t len = caam_desc_get_len(desc);
41 	uint32_t *last = desc + len;
42 
43 	/* Add Word at Last */
44 	caam_write_val32((void *)last, word);
45 
46 	/* Increase the length */
47 	caam_write_val32((void *)desc, caam_read_val32((void *)desc) + 1);
48 }
49 
caam_desc_add_ptr(uint32_t * desc,paddr_t ptr)50 void caam_desc_add_ptr(uint32_t *desc, paddr_t ptr)
51 {
52 	uint32_t len = caam_desc_get_len(desc);
53 	uint32_t *last = desc + len;
54 	uint32_t inc = 1;
55 
56 	/* Add Word at Last */
57 #ifdef CFG_CAAM_64BIT
58 	struct ptr_addr *ptr_addr = (struct ptr_addr *)(uintptr_t)last;
59 
60 #ifdef CFG_ARM64_core
61 	caam_write_val32(&ptr_addr->high, ptr >> 32);
62 #else
63 	caam_write_val32(&ptr_addr->high, 0);
64 #endif /* CFG_ARM64_core */
65 	caam_write_val32(&ptr_addr->low, ptr);
66 	inc++;
67 #else
68 	caam_write_val32((void *)last, ptr);
69 #endif /* CFG_CAAM_64BIT */
70 
71 	/* Increase the length */
72 	caam_write_val32((void *)desc, caam_read_val32((void *)desc) + inc);
73 }
74 
75 #ifdef CFG_CAAM_64BIT
caam_desc_push(struct caam_inring_entry * in_entry,paddr_t paddr)76 void caam_desc_push(struct caam_inring_entry *in_entry, paddr_t paddr)
77 {
78 #ifdef CFG_CAAM_BIG_ENDIAN
79 	put_be64(&in_entry->desc, paddr);
80 #else
81 	put_le64(&in_entry->desc, paddr);
82 #endif /* CFG_CAAM_BIG_ENDIAN */
83 }
84 
caam_desc_pop(struct caam_outring_entry * out_entry)85 paddr_t caam_desc_pop(struct caam_outring_entry *out_entry)
86 {
87 	const uintptr_t v_desc = (uintptr_t)&out_entry->desc;
88 	const uint32_t *a32 = (const uint32_t *)v_desc;
89 
90 #ifdef CFG_CAAM_BIG_ENDIAN
91 	return SHIFT_U64(get_be32(&a32[0]), 32) | get_be32(&a32[1]);
92 #else
93 	return SHIFT_U64(a32[1], 32) | a32[0];
94 #endif /* CFG_CAAM_BIG_ENDIAN */
95 }
96 #else /* CFG_CAAM_64BIT */
caam_desc_push(struct caam_inring_entry * in_entry,paddr_t paddr)97 void caam_desc_push(struct caam_inring_entry *in_entry, paddr_t paddr)
98 {
99 	caam_write_val32(&in_entry->desc, paddr);
100 }
101 
caam_desc_pop(struct caam_outring_entry * out_entry)102 paddr_t caam_desc_pop(struct caam_outring_entry *out_entry)
103 {
104 	return caam_read_val32(&out_entry->desc);
105 }
106 #endif /* CFG_CAAM_64BIT */
107 
caam_read_jobstatus(struct caam_outring_entry * out)108 uint32_t caam_read_jobstatus(struct caam_outring_entry *out)
109 {
110 	return caam_read_val32(&out->status);
111 }
112 
caam_desc_add_dmaobj(uint32_t * desc,struct caamdmaobj * data,unsigned int pre_op)113 void caam_desc_add_dmaobj(uint32_t *desc, struct caamdmaobj *data,
114 			  unsigned int pre_op)
115 {
116 	uint32_t operation = pre_op;
117 	size_t op_length = 0;
118 	uint32_t op_ext_length = 0;
119 
120 	if (data->sgtbuf.sgt_type)
121 		operation |= CMD_SGT;
122 
123 	/* Check the operation length to set extension length or not */
124 	switch (GET_CMD_TYPE(pre_op)) {
125 	case CMD_FIFO_LOAD_TYPE:
126 		op_length = FIFO_LOAD_LENGTH(data->sgtbuf.length);
127 		op_ext_length = FIFO_LOAD_EXT;
128 		break;
129 
130 	case CMD_STORE_TYPE:
131 		/* Note: there is extension length for the STORE command */
132 		op_length = STORE_LENGTH(data->sgtbuf.length);
133 		break;
134 
135 	case CMD_FIFO_STORE_TYPE:
136 		op_length = FIFO_STORE_LENGTH(data->sgtbuf.length);
137 		op_ext_length = FIFO_STORE_EXT;
138 		break;
139 
140 	case CMD_KEY_TYPE:
141 		/* Note: there is extension length for the KEY command */
142 		op_length = KEY_LENGTH(data->sgtbuf.length);
143 		break;
144 
145 	case CMD_SEQ_OUT_TYPE:
146 		op_length = SEQ_LENGTH(data->sgtbuf.length);
147 		op_ext_length = SEQ_EXT;
148 		break;
149 
150 	default:
151 		break;
152 	}
153 
154 	if (op_length == data->sgtbuf.length)
155 		operation |= op_length;
156 	else
157 		operation |= op_ext_length;
158 
159 	caam_desc_add_word(desc, operation);
160 	caam_desc_add_ptr(desc, data->sgtbuf.paddr);
161 
162 	if (op_length != data->sgtbuf.length)
163 		caam_desc_add_word(desc, data->sgtbuf.length);
164 }
165