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 22 uint32_t caam_desc_get_len(uint32_t *desc) 23 { 24 return GET_JD_DESCLEN(caam_read_val32((void *)desc)); 25 } 26 27 void caam_desc_init(uint32_t *desc) 28 { 29 *desc = 0; 30 } 31 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 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 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 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 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 */ 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 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 108 uint32_t caam_read_jobstatus(struct caam_outring_entry *out) 109 { 110 return caam_read_val32(&out->status); 111 } 112 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_IN_TYPE: 146 case CMD_SEQ_OUT_TYPE: 147 op_length = SEQ_LENGTH(data->sgtbuf.length); 148 op_ext_length = SEQ_EXT; 149 break; 150 151 default: 152 break; 153 } 154 155 if (op_length == data->sgtbuf.length) 156 operation |= op_length; 157 else 158 operation |= op_ext_length; 159 160 caam_desc_add_word(desc, operation); 161 caam_desc_add_ptr(desc, data->sgtbuf.paddr); 162 163 if (op_length != data->sgtbuf.length) 164 caam_desc_add_word(desc, data->sgtbuf.length); 165 } 166