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