diff options
Diffstat (limited to 'drivers/fpga/altera-cvp.c')
-rw-r--r-- | drivers/fpga/altera-cvp.c | 69 |
1 files changed, 43 insertions, 26 deletions
diff --git a/drivers/fpga/altera-cvp.c b/drivers/fpga/altera-cvp.c index 9df2073331cb..3b8386fd32e7 100644 --- a/drivers/fpga/altera-cvp.c +++ b/drivers/fpga/altera-cvp.c | |||
@@ -143,6 +143,42 @@ static int altera_cvp_wait_status(struct altera_cvp_conf *conf, u32 status_mask, | |||
143 | return -ETIMEDOUT; | 143 | return -ETIMEDOUT; |
144 | } | 144 | } |
145 | 145 | ||
146 | static int altera_cvp_chk_error(struct fpga_manager *mgr, size_t bytes) | ||
147 | { | ||
148 | struct altera_cvp_conf *conf = mgr->priv; | ||
149 | u32 val; | ||
150 | int ret; | ||
151 | |||
152 | /* STEP 10 (optional) - check CVP_CONFIG_ERROR flag */ | ||
153 | ret = altera_read_config_dword(conf, VSE_CVP_STATUS, &val); | ||
154 | if (ret || (val & VSE_CVP_STATUS_CFG_ERR)) { | ||
155 | dev_err(&mgr->dev, "CVP_CONFIG_ERROR after %zu bytes!\n", | ||
156 | bytes); | ||
157 | return -EPROTO; | ||
158 | } | ||
159 | return 0; | ||
160 | } | ||
161 | |||
162 | static int altera_cvp_send_block(struct altera_cvp_conf *conf, | ||
163 | const u32 *data, size_t len) | ||
164 | { | ||
165 | u32 mask, words = len / sizeof(u32); | ||
166 | int i, remainder; | ||
167 | |||
168 | for (i = 0; i < words; i++) | ||
169 | conf->write_data(conf, *data++); | ||
170 | |||
171 | /* write up to 3 trailing bytes, if any */ | ||
172 | remainder = len % sizeof(u32); | ||
173 | if (remainder) { | ||
174 | mask = BIT(remainder * 8) - 1; | ||
175 | if (mask) | ||
176 | conf->write_data(conf, *data & mask); | ||
177 | } | ||
178 | |||
179 | return 0; | ||
180 | } | ||
181 | |||
146 | static int altera_cvp_teardown(struct fpga_manager *mgr, | 182 | static int altera_cvp_teardown(struct fpga_manager *mgr, |
147 | struct fpga_image_info *info) | 183 | struct fpga_image_info *info) |
148 | { | 184 | { |
@@ -265,39 +301,25 @@ static int altera_cvp_write_init(struct fpga_manager *mgr, | |||
265 | return 0; | 301 | return 0; |
266 | } | 302 | } |
267 | 303 | ||
268 | static inline int altera_cvp_chk_error(struct fpga_manager *mgr, size_t bytes) | ||
269 | { | ||
270 | struct altera_cvp_conf *conf = mgr->priv; | ||
271 | u32 val; | ||
272 | |||
273 | /* STEP 10 (optional) - check CVP_CONFIG_ERROR flag */ | ||
274 | altera_read_config_dword(conf, VSE_CVP_STATUS, &val); | ||
275 | if (val & VSE_CVP_STATUS_CFG_ERR) { | ||
276 | dev_err(&mgr->dev, "CVP_CONFIG_ERROR after %zu bytes!\n", | ||
277 | bytes); | ||
278 | return -EPROTO; | ||
279 | } | ||
280 | return 0; | ||
281 | } | ||
282 | |||
283 | static int altera_cvp_write(struct fpga_manager *mgr, const char *buf, | 304 | static int altera_cvp_write(struct fpga_manager *mgr, const char *buf, |
284 | size_t count) | 305 | size_t count) |
285 | { | 306 | { |
286 | struct altera_cvp_conf *conf = mgr->priv; | 307 | struct altera_cvp_conf *conf = mgr->priv; |
308 | size_t done, remaining, len; | ||
287 | const u32 *data; | 309 | const u32 *data; |
288 | size_t done, remaining; | ||
289 | int status = 0; | 310 | int status = 0; |
290 | u32 mask; | ||
291 | 311 | ||
292 | /* STEP 9 - write 32-bit data from RBF file to CVP data register */ | 312 | /* STEP 9 - write 32-bit data from RBF file to CVP data register */ |
293 | data = (u32 *)buf; | 313 | data = (u32 *)buf; |
294 | remaining = count; | 314 | remaining = count; |
295 | done = 0; | 315 | done = 0; |
296 | 316 | ||
297 | while (remaining >= 4) { | 317 | while (remaining) { |
298 | conf->write_data(conf, *data++); | 318 | len = min(sizeof(u32), remaining); |
299 | done += 4; | 319 | altera_cvp_send_block(conf, data, len); |
300 | remaining -= 4; | 320 | data++; |
321 | done += len; | ||
322 | remaining -= len; | ||
301 | 323 | ||
302 | /* | 324 | /* |
303 | * STEP 10 (optional) and STEP 11 | 325 | * STEP 10 (optional) and STEP 11 |
@@ -315,11 +337,6 @@ static int altera_cvp_write(struct fpga_manager *mgr, const char *buf, | |||
315 | } | 337 | } |
316 | } | 338 | } |
317 | 339 | ||
318 | /* write up to 3 trailing bytes, if any */ | ||
319 | mask = BIT(remaining * 8) - 1; | ||
320 | if (mask) | ||
321 | conf->write_data(conf, *data & mask); | ||
322 | |||
323 | if (altera_cvp_chkcfg) | 340 | if (altera_cvp_chkcfg) |
324 | status = altera_cvp_chk_error(mgr, count); | 341 | status = altera_cvp_chk_error(mgr, count); |
325 | 342 | ||