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 "hmm.h" 16 17 #include "ia_css_pipeline.h" 18 #include "ia_css_isp_param.h" 19 20 /* Set functions for parameter memory descriptors */ 21 22 void 23 ia_css_isp_param_set_mem_init( 24 struct ia_css_isp_param_host_segments *mem_init, 25 enum ia_css_param_class pclass, 26 enum ia_css_isp_memories mem, 27 char *address, size_t size) 28 { 29 mem_init->params[pclass][mem].address = address; 30 mem_init->params[pclass][mem].size = (uint32_t)size; 31 } 32 33 void 34 ia_css_isp_param_set_css_mem_init( 35 struct ia_css_isp_param_css_segments *mem_init, 36 enum ia_css_param_class pclass, 37 enum ia_css_isp_memories mem, 38 ia_css_ptr address, size_t size) 39 { 40 mem_init->params[pclass][mem].address = address; 41 mem_init->params[pclass][mem].size = (uint32_t)size; 42 } 43 44 void 45 ia_css_isp_param_set_isp_mem_init( 46 struct ia_css_isp_param_isp_segments *mem_init, 47 enum ia_css_param_class pclass, 48 enum ia_css_isp_memories mem, 49 u32 address, size_t size) 50 { 51 mem_init->params[pclass][mem].address = address; 52 mem_init->params[pclass][mem].size = (uint32_t)size; 53 } 54 55 /* Get functions for parameter memory descriptors */ 56 const struct ia_css_host_data * 57 ia_css_isp_param_get_mem_init( 58 const struct ia_css_isp_param_host_segments *mem_init, 59 enum ia_css_param_class pclass, 60 enum ia_css_isp_memories mem) 61 { 62 return &mem_init->params[pclass][mem]; 63 } 64 65 const struct ia_css_data * 66 ia_css_isp_param_get_css_mem_init( 67 const struct ia_css_isp_param_css_segments *mem_init, 68 enum ia_css_param_class pclass, 69 enum ia_css_isp_memories mem) 70 { 71 return &mem_init->params[pclass][mem]; 72 } 73 74 const struct ia_css_isp_data * 75 ia_css_isp_param_get_isp_mem_init( 76 const struct ia_css_isp_param_isp_segments *mem_init, 77 enum ia_css_param_class pclass, 78 enum ia_css_isp_memories mem) 79 { 80 return &mem_init->params[pclass][mem]; 81 } 82 83 void 84 ia_css_init_memory_interface( 85 struct ia_css_isp_param_css_segments *isp_mem_if, 86 const struct ia_css_isp_param_host_segments *mem_params, 87 const struct ia_css_isp_param_css_segments *css_params) 88 { 89 unsigned int pclass, mem; 90 91 for (pclass = 0; pclass < IA_CSS_NUM_PARAM_CLASSES; pclass++) { 92 memset(isp_mem_if->params[pclass], 0, sizeof(isp_mem_if->params[pclass])); 93 for (mem = 0; mem < IA_CSS_NUM_MEMORIES; mem++) { 94 if (!mem_params->params[pclass][mem].address) 95 continue; 96 isp_mem_if->params[pclass][mem].size = mem_params->params[pclass][mem].size; 97 if (pclass != IA_CSS_PARAM_CLASS_PARAM) 98 isp_mem_if->params[pclass][mem].address = 99 css_params->params[pclass][mem].address; 100 } 101 } 102 } 103 104 int 105 ia_css_isp_param_allocate_isp_parameters( 106 struct ia_css_isp_param_host_segments *mem_params, 107 struct ia_css_isp_param_css_segments *css_params, 108 const struct ia_css_isp_param_isp_segments *mem_initializers) { 109 int err = 0; 110 unsigned int mem, pclass; 111 112 pclass = IA_CSS_PARAM_CLASS_PARAM; 113 for (mem = 0; mem < IA_CSS_NUM_MEMORIES; mem++) 114 { 115 for (pclass = 0; pclass < IA_CSS_NUM_PARAM_CLASSES; pclass++) { 116 u32 size = 0; 117 118 if (mem_initializers) 119 size = mem_initializers->params[pclass][mem].size; 120 mem_params->params[pclass][mem].size = size; 121 mem_params->params[pclass][mem].address = NULL; 122 css_params->params[pclass][mem].size = size; 123 css_params->params[pclass][mem].address = 0x0; 124 if (size) { 125 mem_params->params[pclass][mem].address = kvcalloc(1, 126 size, 127 GFP_KERNEL); 128 if (!mem_params->params[pclass][mem].address) { 129 err = -ENOMEM; 130 goto cleanup; 131 } 132 if (pclass != IA_CSS_PARAM_CLASS_PARAM) { 133 css_params->params[pclass][mem].address = hmm_alloc(size, HMM_BO_PRIVATE, 0, NULL, 0); 134 if (!css_params->params[pclass][mem].address) { 135 err = -ENOMEM; 136 goto cleanup; 137 } 138 } 139 } 140 } 141 } 142 return err; 143 cleanup: 144 ia_css_isp_param_destroy_isp_parameters(mem_params, css_params); 145 return err; 146 } 147 148 void 149 ia_css_isp_param_destroy_isp_parameters( 150 struct ia_css_isp_param_host_segments *mem_params, 151 struct ia_css_isp_param_css_segments *css_params) 152 { 153 unsigned int mem, pclass; 154 155 for (mem = 0; mem < IA_CSS_NUM_MEMORIES; mem++) { 156 for (pclass = 0; pclass < IA_CSS_NUM_PARAM_CLASSES; pclass++) { 157 if (mem_params->params[pclass][mem].address) 158 kvfree(mem_params->params[pclass][mem].address); 159 if (css_params->params[pclass][mem].address) 160 hmm_free(css_params->params[pclass][mem].address); 161 mem_params->params[pclass][mem].address = NULL; 162 css_params->params[pclass][mem].address = 0x0; 163 } 164 } 165 } 166 167 void 168 ia_css_isp_param_load_fw_params( 169 const char *fw, 170 union ia_css_all_memory_offsets *mem_offsets, 171 const struct ia_css_isp_param_memory_offsets *memory_offsets, 172 bool init) 173 { 174 unsigned int pclass; 175 176 for (pclass = 0; pclass < IA_CSS_NUM_PARAM_CLASSES; pclass++) { 177 mem_offsets->array[pclass].ptr = NULL; 178 if (init) 179 mem_offsets->array[pclass].ptr = (void *)(fw + memory_offsets->offsets[pclass]); 180 } 181 } 182 183 int 184 ia_css_isp_param_copy_isp_mem_if_to_ddr( 185 struct ia_css_isp_param_css_segments *ddr, 186 const struct ia_css_isp_param_host_segments *host, 187 enum ia_css_param_class pclass) { 188 unsigned int mem; 189 190 for (mem = 0; mem < N_IA_CSS_ISP_MEMORIES; mem++) 191 { 192 size_t size = host->params[pclass][mem].size; 193 ia_css_ptr ddr_mem_ptr = ddr->params[pclass][mem].address; 194 char *host_mem_ptr = host->params[pclass][mem].address; 195 196 if (size != ddr->params[pclass][mem].size) 197 return -EINVAL; 198 if (!size) 199 continue; 200 hmm_store(ddr_mem_ptr, host_mem_ptr, size); 201 } 202 return 0; 203 } 204 205 void 206 ia_css_isp_param_enable_pipeline( 207 const struct ia_css_isp_param_host_segments *mem_params) 208 { 209 /* By protocol b0 of the mandatory uint32_t first field of the 210 input parameter is a disable bit*/ 211 short dmem_offset = 0; 212 213 if (mem_params->params[IA_CSS_PARAM_CLASS_PARAM][IA_CSS_ISP_DMEM0].size == 0) 214 return; 215 216 *(uint32_t *) 217 &mem_params->params[IA_CSS_PARAM_CLASS_PARAM][IA_CSS_ISP_DMEM0].address[dmem_offset] 218 = 0x0; 219 } 220