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 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