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