1 /* 2 * Support for Intel Camera Imaging ISP subsystem. 3 * Copyright (c) 2010 - 2015, Intel Corporation. 4 * 5 * This program is free software; you can redistribute it and/or modify it 6 * under the terms and conditions of the GNU General Public License, 7 * version 2, as published by the Free Software Foundation. 8 * 9 * This program is distributed in the hope it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 12 * more details. 13 */ 14 15 #include "type_support.h" 16 #include "queue_access.h" 17 #include "ia_css_circbuf.h" 18 #include "sp.h" 19 #include "memory_access.h" 20 #include "assert_support.h" 21 22 int ia_css_queue_load( 23 struct ia_css_queue *rdesc, 24 ia_css_circbuf_desc_t *cb_desc, 25 uint32_t ignore_desc_flags) 26 { 27 if (!rdesc || !cb_desc) 28 return EINVAL; 29 30 if (rdesc->location == IA_CSS_QUEUE_LOC_SP) { 31 assert(ignore_desc_flags <= QUEUE_IGNORE_DESC_FLAGS_MAX); 32 33 if (0 == (ignore_desc_flags & QUEUE_IGNORE_SIZE_FLAG)) { 34 cb_desc->size = sp_dmem_load_uint8(rdesc->proc_id, 35 rdesc->desc.remote.cb_desc_addr 36 + offsetof(ia_css_circbuf_desc_t, size)); 37 38 if (cb_desc->size == 0) { 39 /* Adding back the workaround which was removed 40 while refactoring queues. When reading size 41 through sp_dmem_load_*, sometimes we get back 42 the value as zero. This causes division by 0 43 exception as the size is used in a modular 44 division operation. */ 45 return EDOM; 46 } 47 } 48 49 if (0 == (ignore_desc_flags & QUEUE_IGNORE_START_FLAG)) 50 cb_desc->start = sp_dmem_load_uint8(rdesc->proc_id, 51 rdesc->desc.remote.cb_desc_addr 52 + offsetof(ia_css_circbuf_desc_t, start)); 53 54 if (0 == (ignore_desc_flags & QUEUE_IGNORE_END_FLAG)) 55 cb_desc->end = sp_dmem_load_uint8(rdesc->proc_id, 56 rdesc->desc.remote.cb_desc_addr 57 + offsetof(ia_css_circbuf_desc_t, end)); 58 59 if (0 == (ignore_desc_flags & QUEUE_IGNORE_STEP_FLAG)) 60 cb_desc->step = sp_dmem_load_uint8(rdesc->proc_id, 61 rdesc->desc.remote.cb_desc_addr 62 + offsetof(ia_css_circbuf_desc_t, step)); 63 64 } else if (rdesc->location == IA_CSS_QUEUE_LOC_HOST) { 65 /* doing DMA transfer of entire structure */ 66 mmgr_load(rdesc->desc.remote.cb_desc_addr, 67 (void *)cb_desc, 68 sizeof(ia_css_circbuf_desc_t)); 69 } else if (rdesc->location == IA_CSS_QUEUE_LOC_ISP) { 70 /* Not supported yet */ 71 return ENOTSUP; 72 } 73 74 return 0; 75 } 76 77 int ia_css_queue_store( 78 struct ia_css_queue *rdesc, 79 ia_css_circbuf_desc_t *cb_desc, 80 uint32_t ignore_desc_flags) 81 { 82 if (!rdesc || !cb_desc) 83 return EINVAL; 84 85 if (rdesc->location == IA_CSS_QUEUE_LOC_SP) { 86 assert(ignore_desc_flags <= QUEUE_IGNORE_DESC_FLAGS_MAX); 87 88 if (0 == (ignore_desc_flags & QUEUE_IGNORE_SIZE_FLAG)) 89 sp_dmem_store_uint8(rdesc->proc_id, 90 rdesc->desc.remote.cb_desc_addr 91 + offsetof(ia_css_circbuf_desc_t, size), 92 cb_desc->size); 93 94 if (0 == (ignore_desc_flags & QUEUE_IGNORE_START_FLAG)) 95 sp_dmem_store_uint8(rdesc->proc_id, 96 rdesc->desc.remote.cb_desc_addr 97 + offsetof(ia_css_circbuf_desc_t, start), 98 cb_desc->start); 99 100 if (0 == (ignore_desc_flags & QUEUE_IGNORE_END_FLAG)) 101 sp_dmem_store_uint8(rdesc->proc_id, 102 rdesc->desc.remote.cb_desc_addr 103 + offsetof(ia_css_circbuf_desc_t, end), 104 cb_desc->end); 105 106 if (0 == (ignore_desc_flags & QUEUE_IGNORE_STEP_FLAG)) 107 sp_dmem_store_uint8(rdesc->proc_id, 108 rdesc->desc.remote.cb_desc_addr 109 + offsetof(ia_css_circbuf_desc_t, step), 110 cb_desc->step); 111 } else if (rdesc->location == IA_CSS_QUEUE_LOC_HOST) { 112 /* doing DMA transfer of entire structure */ 113 mmgr_store(rdesc->desc.remote.cb_desc_addr, 114 (void *)cb_desc, 115 sizeof(ia_css_circbuf_desc_t)); 116 } else if (rdesc->location == IA_CSS_QUEUE_LOC_ISP) { 117 /* Not supported yet */ 118 return ENOTSUP; 119 } 120 121 return 0; 122 } 123 124 int ia_css_queue_item_load( 125 struct ia_css_queue *rdesc, 126 u8 position, 127 ia_css_circbuf_elem_t *item) 128 { 129 if (!rdesc || !item) 130 return EINVAL; 131 132 if (rdesc->location == IA_CSS_QUEUE_LOC_SP) { 133 sp_dmem_load(rdesc->proc_id, 134 rdesc->desc.remote.cb_elems_addr 135 + position * sizeof(ia_css_circbuf_elem_t), 136 item, 137 sizeof(ia_css_circbuf_elem_t)); 138 } else if (rdesc->location == IA_CSS_QUEUE_LOC_HOST) { 139 mmgr_load(rdesc->desc.remote.cb_elems_addr 140 + position * sizeof(ia_css_circbuf_elem_t), 141 (void *)item, 142 sizeof(ia_css_circbuf_elem_t)); 143 } else if (rdesc->location == IA_CSS_QUEUE_LOC_ISP) { 144 /* Not supported yet */ 145 return ENOTSUP; 146 } 147 148 return 0; 149 } 150 151 int ia_css_queue_item_store( 152 struct ia_css_queue *rdesc, 153 u8 position, 154 ia_css_circbuf_elem_t *item) 155 { 156 if (!rdesc || !item) 157 return EINVAL; 158 159 if (rdesc->location == IA_CSS_QUEUE_LOC_SP) { 160 sp_dmem_store(rdesc->proc_id, 161 rdesc->desc.remote.cb_elems_addr 162 + position * sizeof(ia_css_circbuf_elem_t), 163 item, 164 sizeof(ia_css_circbuf_elem_t)); 165 } else if (rdesc->location == IA_CSS_QUEUE_LOC_HOST) { 166 mmgr_store(rdesc->desc.remote.cb_elems_addr 167 + position * sizeof(ia_css_circbuf_elem_t), 168 (void *)item, 169 sizeof(ia_css_circbuf_elem_t)); 170 } else if (rdesc->location == IA_CSS_QUEUE_LOC_ISP) { 171 /* Not supported yet */ 172 return ENOTSUP; 173 } 174 175 return 0; 176 } 177