1f5fbb83fSMauro Carvalho Chehab // SPDX-License-Identifier: GPL-2.0
29d4fa1a1SMauro Carvalho Chehab /*
39d4fa1a1SMauro Carvalho Chehab  * Support for Intel Camera Imaging ISP subsystem.
49d4fa1a1SMauro Carvalho Chehab  * Copyright (c) 2010 - 2016, Intel Corporation.
59d4fa1a1SMauro Carvalho Chehab  *
69d4fa1a1SMauro Carvalho Chehab  * This program is free software; you can redistribute it and/or modify it
79d4fa1a1SMauro Carvalho Chehab  * under the terms and conditions of the GNU General Public License,
89d4fa1a1SMauro Carvalho Chehab  * version 2, as published by the Free Software Foundation.
99d4fa1a1SMauro Carvalho Chehab  *
109d4fa1a1SMauro Carvalho Chehab  * This program is distributed in the hope it will be useful, but WITHOUT
119d4fa1a1SMauro Carvalho Chehab  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
129d4fa1a1SMauro Carvalho Chehab  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
139d4fa1a1SMauro Carvalho Chehab  * more details.
149d4fa1a1SMauro Carvalho Chehab  */
159d4fa1a1SMauro Carvalho Chehab 
169d4fa1a1SMauro Carvalho Chehab #include "isp.h"
179d4fa1a1SMauro Carvalho Chehab #include "vmem.h"
189d4fa1a1SMauro Carvalho Chehab #include "vmem_local.h"
199d4fa1a1SMauro Carvalho Chehab 
209d4fa1a1SMauro Carvalho Chehab #if !defined(HRT_MEMORY_ACCESS)
219d4fa1a1SMauro Carvalho Chehab #include "ia_css_device_access.h"
229d4fa1a1SMauro Carvalho Chehab #endif
239d4fa1a1SMauro Carvalho Chehab #include "assert_support.h"
249d4fa1a1SMauro Carvalho Chehab 
259d4fa1a1SMauro Carvalho Chehab typedef unsigned long long hive_uedge;
269d4fa1a1SMauro Carvalho Chehab typedef hive_uedge *hive_wide;
279d4fa1a1SMauro Carvalho Chehab 
289d4fa1a1SMauro Carvalho Chehab /* Copied from SDK: sim_semantics.c */
299d4fa1a1SMauro Carvalho Chehab 
309d4fa1a1SMauro Carvalho Chehab /* subword bits move like this:         MSB[____xxxx____]LSB -> MSB[00000000xxxx]LSB */
31*197ec0f4SBrent Pappas static inline hive_uedge
subword(hive_uedge w,unsigned int start,unsigned int end)32*197ec0f4SBrent Pappas subword(hive_uedge w, unsigned int start, unsigned int end)
33*197ec0f4SBrent Pappas {
34*197ec0f4SBrent Pappas 	return (w & (((1ULL << (end - 1)) - 1) << 1 | 1)) >> start;
35*197ec0f4SBrent Pappas }
369d4fa1a1SMauro Carvalho Chehab 
379d4fa1a1SMauro Carvalho Chehab /* inverse subword bits move like this: MSB[xxxx____xxxx]LSB -> MSB[xxxx0000xxxx]LSB */
38*197ec0f4SBrent Pappas static inline hive_uedge
inv_subword(hive_uedge w,unsigned int start,unsigned int end)39*197ec0f4SBrent Pappas inv_subword(hive_uedge w, unsigned int start, unsigned int end)
40*197ec0f4SBrent Pappas {
41*197ec0f4SBrent Pappas 	return w & (~(((1ULL << (end - 1)) - 1) << 1 | 1) | ((1ULL << start) - 1));
42*197ec0f4SBrent Pappas }
439d4fa1a1SMauro Carvalho Chehab 
449d4fa1a1SMauro Carvalho Chehab #define uedge_bits (8 * sizeof(hive_uedge))
459d4fa1a1SMauro Carvalho Chehab #define move_lower_bits(target, target_bit, src, src_bit) move_subword(target, target_bit, src, 0, src_bit)
469d4fa1a1SMauro Carvalho Chehab #define move_upper_bits(target, target_bit, src, src_bit) move_subword(target, target_bit, src, src_bit, uedge_bits)
479d4fa1a1SMauro Carvalho Chehab #define move_word(target, target_bit, src) move_subword(target, target_bit, src, 0, uedge_bits)
489d4fa1a1SMauro Carvalho Chehab 
499d4fa1a1SMauro Carvalho Chehab static void
move_subword(hive_uedge * target,unsigned int target_bit,hive_uedge src,unsigned int src_start,unsigned int src_end)509d4fa1a1SMauro Carvalho Chehab move_subword(
519d4fa1a1SMauro Carvalho Chehab     hive_uedge *target,
529d4fa1a1SMauro Carvalho Chehab     unsigned int target_bit,
539d4fa1a1SMauro Carvalho Chehab     hive_uedge src,
549d4fa1a1SMauro Carvalho Chehab     unsigned int src_start,
559d4fa1a1SMauro Carvalho Chehab     unsigned int src_end)
569d4fa1a1SMauro Carvalho Chehab {
579d4fa1a1SMauro Carvalho Chehab 	unsigned int start_elem = target_bit / uedge_bits;
589d4fa1a1SMauro Carvalho Chehab 	unsigned int start_bit  = target_bit % uedge_bits;
599d4fa1a1SMauro Carvalho Chehab 	unsigned int subword_width = src_end - src_start;
609d4fa1a1SMauro Carvalho Chehab 
61*197ec0f4SBrent Pappas 	hive_uedge src_subword = subword(src, src_start, src_end);
629d4fa1a1SMauro Carvalho Chehab 
639d4fa1a1SMauro Carvalho Chehab 	if (subword_width + start_bit > uedge_bits) { /* overlap */
649d4fa1a1SMauro Carvalho Chehab 		hive_uedge old_val1;
65*197ec0f4SBrent Pappas 		hive_uedge old_val0 = inv_subword(target[start_elem], start_bit, uedge_bits);
669d4fa1a1SMauro Carvalho Chehab 
679d4fa1a1SMauro Carvalho Chehab 		target[start_elem] = old_val0 | (src_subword << start_bit);
68*197ec0f4SBrent Pappas 		old_val1 = inv_subword(target[start_elem + 1], 0,
699d4fa1a1SMauro Carvalho Chehab 				       subword_width + start_bit - uedge_bits);
709d4fa1a1SMauro Carvalho Chehab 		target[start_elem + 1] = old_val1 | (src_subword >> (uedge_bits - start_bit));
719d4fa1a1SMauro Carvalho Chehab 	} else {
72*197ec0f4SBrent Pappas 		hive_uedge old_val = inv_subword(target[start_elem], start_bit,
739d4fa1a1SMauro Carvalho Chehab 						 start_bit + subword_width);
749d4fa1a1SMauro Carvalho Chehab 
759d4fa1a1SMauro Carvalho Chehab 		target[start_elem] = old_val | (src_subword << start_bit);
769d4fa1a1SMauro Carvalho Chehab 	}
779d4fa1a1SMauro Carvalho Chehab }
789d4fa1a1SMauro Carvalho Chehab 
799d4fa1a1SMauro Carvalho Chehab static void
hive_sim_wide_unpack(hive_wide vector,hive_wide elem,hive_uint elem_bits,hive_uint index)809d4fa1a1SMauro Carvalho Chehab hive_sim_wide_unpack(
819d4fa1a1SMauro Carvalho Chehab     hive_wide vector,
829d4fa1a1SMauro Carvalho Chehab     hive_wide elem,
839d4fa1a1SMauro Carvalho Chehab     hive_uint elem_bits,
849d4fa1a1SMauro Carvalho Chehab     hive_uint index)
859d4fa1a1SMauro Carvalho Chehab {
869d4fa1a1SMauro Carvalho Chehab 	/* pointers into wide_type: */
879d4fa1a1SMauro Carvalho Chehab 	unsigned int start_elem = (elem_bits * index) / uedge_bits;
889d4fa1a1SMauro Carvalho Chehab 	unsigned int start_bit  = (elem_bits * index) % uedge_bits;
899d4fa1a1SMauro Carvalho Chehab 	unsigned int end_elem   = (elem_bits * (index + 1) - 1) / uedge_bits;
909d4fa1a1SMauro Carvalho Chehab 	unsigned int end_bit    = ((elem_bits * (index + 1) - 1) % uedge_bits) + 1;
919d4fa1a1SMauro Carvalho Chehab 
929d4fa1a1SMauro Carvalho Chehab 	if (elem_bits == uedge_bits) {
939d4fa1a1SMauro Carvalho Chehab 		/* easy case for speedup: */
949d4fa1a1SMauro Carvalho Chehab 		elem[0] = vector[index];
959d4fa1a1SMauro Carvalho Chehab 	} else if (start_elem == end_elem) {
969d4fa1a1SMauro Carvalho Chehab 		/* only one (<=64 bits) element needs to be (partly) copied: */
979d4fa1a1SMauro Carvalho Chehab 		move_subword(elem, 0, vector[start_elem], start_bit, end_bit);
989d4fa1a1SMauro Carvalho Chehab 	} else {
999d4fa1a1SMauro Carvalho Chehab 		/* general case: handles edge spanning cases (includes >64bit elements) */
1009d4fa1a1SMauro Carvalho Chehab 		unsigned int bits_written = 0;
1019d4fa1a1SMauro Carvalho Chehab 		unsigned int i;
1029d4fa1a1SMauro Carvalho Chehab 
1039d4fa1a1SMauro Carvalho Chehab 		move_upper_bits(elem, bits_written, vector[start_elem], start_bit);
1049d4fa1a1SMauro Carvalho Chehab 		bits_written += (64 - start_bit);
1059d4fa1a1SMauro Carvalho Chehab 		for (i = start_elem + 1; i < end_elem; i++) {
1069d4fa1a1SMauro Carvalho Chehab 			move_word(elem, bits_written, vector[i]);
1079d4fa1a1SMauro Carvalho Chehab 			bits_written += uedge_bits;
1089d4fa1a1SMauro Carvalho Chehab 		}
1099d4fa1a1SMauro Carvalho Chehab 		move_lower_bits(elem, bits_written, vector[end_elem], end_bit);
1109d4fa1a1SMauro Carvalho Chehab 	}
1119d4fa1a1SMauro Carvalho Chehab }
1129d4fa1a1SMauro Carvalho Chehab 
1139d4fa1a1SMauro Carvalho Chehab static void
hive_sim_wide_pack(hive_wide vector,hive_wide elem,hive_uint elem_bits,hive_uint index)1149d4fa1a1SMauro Carvalho Chehab hive_sim_wide_pack(
1159d4fa1a1SMauro Carvalho Chehab     hive_wide vector,
1169d4fa1a1SMauro Carvalho Chehab     hive_wide elem,
1179d4fa1a1SMauro Carvalho Chehab     hive_uint elem_bits,
1189d4fa1a1SMauro Carvalho Chehab     hive_uint index)
1199d4fa1a1SMauro Carvalho Chehab {
1209d4fa1a1SMauro Carvalho Chehab 	/* pointers into wide_type: */
1219d4fa1a1SMauro Carvalho Chehab 	unsigned int start_elem = (elem_bits * index) / uedge_bits;
1229d4fa1a1SMauro Carvalho Chehab 
1239d4fa1a1SMauro Carvalho Chehab 	/* easy case for speedup: */
1249d4fa1a1SMauro Carvalho Chehab 	if (elem_bits == uedge_bits) {
1259d4fa1a1SMauro Carvalho Chehab 		vector[start_elem] = elem[0];
1269d4fa1a1SMauro Carvalho Chehab 	} else if (elem_bits > uedge_bits) {
1279d4fa1a1SMauro Carvalho Chehab 		unsigned int bits_to_write = elem_bits;
1289d4fa1a1SMauro Carvalho Chehab 		unsigned int start_bit = elem_bits * index;
1299d4fa1a1SMauro Carvalho Chehab 		unsigned int i = 0;
1309d4fa1a1SMauro Carvalho Chehab 
1319d4fa1a1SMauro Carvalho Chehab 		for (; bits_to_write > uedge_bits;
1329d4fa1a1SMauro Carvalho Chehab 		     bits_to_write -= uedge_bits, i++, start_bit += uedge_bits) {
1339d4fa1a1SMauro Carvalho Chehab 			move_word(vector, start_bit, elem[i]);
1349d4fa1a1SMauro Carvalho Chehab 		}
1359d4fa1a1SMauro Carvalho Chehab 		move_lower_bits(vector, start_bit, elem[i], bits_to_write);
1369d4fa1a1SMauro Carvalho Chehab 	} else {
1379d4fa1a1SMauro Carvalho Chehab 		/* only one element needs to be (partly) copied: */
1389d4fa1a1SMauro Carvalho Chehab 		move_lower_bits(vector, elem_bits * index, elem[0], elem_bits);
1399d4fa1a1SMauro Carvalho Chehab 	}
1409d4fa1a1SMauro Carvalho Chehab }
1419d4fa1a1SMauro Carvalho Chehab 
load_vector(const isp_ID_t ID,t_vmem_elem * to,const t_vmem_elem * from)1429d4fa1a1SMauro Carvalho Chehab static void load_vector(
1439d4fa1a1SMauro Carvalho Chehab     const isp_ID_t		ID,
1449d4fa1a1SMauro Carvalho Chehab     t_vmem_elem		*to,
1459d4fa1a1SMauro Carvalho Chehab     const t_vmem_elem	*from)
1469d4fa1a1SMauro Carvalho Chehab {
1479d4fa1a1SMauro Carvalho Chehab 	unsigned int i;
1489d4fa1a1SMauro Carvalho Chehab 	hive_uedge *data;
1499d4fa1a1SMauro Carvalho Chehab 	unsigned int size = sizeof(short) * ISP_NWAY;
1509d4fa1a1SMauro Carvalho Chehab 
1519d4fa1a1SMauro Carvalho Chehab 	VMEM_ARRAY(v, 2 * ISP_NWAY); /* Need 2 vectors to work around vmem hss bug */
1529d4fa1a1SMauro Carvalho Chehab 	assert(ISP_BAMEM_BASE[ID] != (hrt_address) - 1);
1539d4fa1a1SMauro Carvalho Chehab #if !defined(HRT_MEMORY_ACCESS)
1549d4fa1a1SMauro Carvalho Chehab 	ia_css_device_load(ISP_BAMEM_BASE[ID] + (unsigned long)from, &v[0][0], size);
1559d4fa1a1SMauro Carvalho Chehab #else
1569d4fa1a1SMauro Carvalho Chehab 	hrt_master_port_load(ISP_BAMEM_BASE[ID] + (unsigned long)from, &v[0][0], size);
1579d4fa1a1SMauro Carvalho Chehab #endif
1589d4fa1a1SMauro Carvalho Chehab 	data = (hive_uedge *)v;
1599d4fa1a1SMauro Carvalho Chehab 	for (i = 0; i < ISP_NWAY; i++) {
1609d4fa1a1SMauro Carvalho Chehab 		hive_uedge elem = 0;
1619d4fa1a1SMauro Carvalho Chehab 
1629d4fa1a1SMauro Carvalho Chehab 		hive_sim_wide_unpack(data, &elem, ISP_VEC_ELEMBITS, i);
1639d4fa1a1SMauro Carvalho Chehab 		to[i] = elem;
1649d4fa1a1SMauro Carvalho Chehab 	}
16569a03e36SMauro Carvalho Chehab 	udelay(1); /* Spend at least 1 cycles per vector */
1669d4fa1a1SMauro Carvalho Chehab }
1679d4fa1a1SMauro Carvalho Chehab 
store_vector(const isp_ID_t ID,t_vmem_elem * to,const t_vmem_elem * from)1689d4fa1a1SMauro Carvalho Chehab static void store_vector(
1699d4fa1a1SMauro Carvalho Chehab     const isp_ID_t		ID,
1709d4fa1a1SMauro Carvalho Chehab     t_vmem_elem		*to,
1719d4fa1a1SMauro Carvalho Chehab     const t_vmem_elem	*from)
1729d4fa1a1SMauro Carvalho Chehab {
1739d4fa1a1SMauro Carvalho Chehab 	unsigned int i;
1749d4fa1a1SMauro Carvalho Chehab 	unsigned int size = sizeof(short) * ISP_NWAY;
1759d4fa1a1SMauro Carvalho Chehab 
1769d4fa1a1SMauro Carvalho Chehab 	VMEM_ARRAY(v, 2 * ISP_NWAY); /* Need 2 vectors to work around vmem hss bug */
1779d4fa1a1SMauro Carvalho Chehab 	//load_vector (&v[1][0], &to[ISP_NWAY]); /* Fetch the next vector, since it will be overwritten. */
1789d4fa1a1SMauro Carvalho Chehab 	hive_uedge *data = (hive_uedge *)v;
1799d4fa1a1SMauro Carvalho Chehab 
1809d4fa1a1SMauro Carvalho Chehab 	for (i = 0; i < ISP_NWAY; i++) {
1819d4fa1a1SMauro Carvalho Chehab 		hive_sim_wide_pack(data, (hive_wide)&from[i], ISP_VEC_ELEMBITS, i);
1829d4fa1a1SMauro Carvalho Chehab 	}
1839d4fa1a1SMauro Carvalho Chehab 	assert(ISP_BAMEM_BASE[ID] != (hrt_address) - 1);
1849d4fa1a1SMauro Carvalho Chehab #if !defined(HRT_MEMORY_ACCESS)
1859d4fa1a1SMauro Carvalho Chehab 	ia_css_device_store(ISP_BAMEM_BASE[ID] + (unsigned long)to, &v, size);
1869d4fa1a1SMauro Carvalho Chehab #else
1879d4fa1a1SMauro Carvalho Chehab 	//hrt_mem_store (ISP, VMEM, (unsigned)to, &v, siz); /* This will overwrite the next vector as well */
1889d4fa1a1SMauro Carvalho Chehab 	hrt_master_port_store(ISP_BAMEM_BASE[ID] + (unsigned long)to, &v, size);
1899d4fa1a1SMauro Carvalho Chehab #endif
19069a03e36SMauro Carvalho Chehab 	udelay(1); /* Spend at least 1 cycles per vector */
1919d4fa1a1SMauro Carvalho Chehab }
1929d4fa1a1SMauro Carvalho Chehab 
isp_vmem_load(const isp_ID_t ID,const t_vmem_elem * from,t_vmem_elem * to,unsigned int elems)1939d4fa1a1SMauro Carvalho Chehab void isp_vmem_load(
1949d4fa1a1SMauro Carvalho Chehab     const isp_ID_t		ID,
1959d4fa1a1SMauro Carvalho Chehab     const t_vmem_elem	*from,
1969d4fa1a1SMauro Carvalho Chehab     t_vmem_elem		*to,
1979d4fa1a1SMauro Carvalho Chehab     unsigned int elems) /* In t_vmem_elem */
1989d4fa1a1SMauro Carvalho Chehab {
1999d4fa1a1SMauro Carvalho Chehab 	unsigned int c;
2009d4fa1a1SMauro Carvalho Chehab 	const t_vmem_elem *vp = from;
2019d4fa1a1SMauro Carvalho Chehab 
2029d4fa1a1SMauro Carvalho Chehab 	assert(ID < N_ISP_ID);
2039d4fa1a1SMauro Carvalho Chehab 	assert((unsigned long)from % ISP_VEC_ALIGN == 0);
2049d4fa1a1SMauro Carvalho Chehab 	assert(elems % ISP_NWAY == 0);
2059d4fa1a1SMauro Carvalho Chehab 	for (c = 0; c < elems; c += ISP_NWAY) {
2069d4fa1a1SMauro Carvalho Chehab 		load_vector(ID, &to[c], vp);
2079d4fa1a1SMauro Carvalho Chehab 		vp = (t_vmem_elem *)((char *)vp + ISP_VEC_ALIGN);
2089d4fa1a1SMauro Carvalho Chehab 	}
2099d4fa1a1SMauro Carvalho Chehab }
2109d4fa1a1SMauro Carvalho Chehab 
isp_vmem_store(const isp_ID_t ID,t_vmem_elem * to,const t_vmem_elem * from,unsigned int elems)2119d4fa1a1SMauro Carvalho Chehab void isp_vmem_store(
2129d4fa1a1SMauro Carvalho Chehab     const isp_ID_t		ID,
2139d4fa1a1SMauro Carvalho Chehab     t_vmem_elem		*to,
2149d4fa1a1SMauro Carvalho Chehab     const t_vmem_elem	*from,
2159d4fa1a1SMauro Carvalho Chehab     unsigned int elems) /* In t_vmem_elem */
2169d4fa1a1SMauro Carvalho Chehab {
2179d4fa1a1SMauro Carvalho Chehab 	unsigned int c;
2189d4fa1a1SMauro Carvalho Chehab 	t_vmem_elem *vp = to;
2199d4fa1a1SMauro Carvalho Chehab 
2209d4fa1a1SMauro Carvalho Chehab 	assert(ID < N_ISP_ID);
2219d4fa1a1SMauro Carvalho Chehab 	assert((unsigned long)to % ISP_VEC_ALIGN == 0);
2229d4fa1a1SMauro Carvalho Chehab 	assert(elems % ISP_NWAY == 0);
2239d4fa1a1SMauro Carvalho Chehab 	for (c = 0; c < elems; c += ISP_NWAY) {
2249d4fa1a1SMauro Carvalho Chehab 		store_vector(ID, vp, &from[c]);
2259d4fa1a1SMauro Carvalho Chehab 		vp = (t_vmem_elem *)((char *)vp + ISP_VEC_ALIGN);
2269d4fa1a1SMauro Carvalho Chehab 	}
2279d4fa1a1SMauro Carvalho Chehab }
2289d4fa1a1SMauro Carvalho Chehab 
isp_vmem_2d_load(const isp_ID_t ID,const t_vmem_elem * from,t_vmem_elem * to,unsigned int height,unsigned int width,unsigned int stride_to,unsigned stride_from)2299d4fa1a1SMauro Carvalho Chehab void isp_vmem_2d_load(
2309d4fa1a1SMauro Carvalho Chehab     const isp_ID_t		ID,
2319d4fa1a1SMauro Carvalho Chehab     const t_vmem_elem	*from,
2329d4fa1a1SMauro Carvalho Chehab     t_vmem_elem		*to,
2339d4fa1a1SMauro Carvalho Chehab     unsigned int height,
2349d4fa1a1SMauro Carvalho Chehab     unsigned int width,
2359d4fa1a1SMauro Carvalho Chehab     unsigned int stride_to,  /* In t_vmem_elem */
2369d4fa1a1SMauro Carvalho Chehab 
2379d4fa1a1SMauro Carvalho Chehab     unsigned stride_from /* In t_vmem_elem */)
2389d4fa1a1SMauro Carvalho Chehab {
2399d4fa1a1SMauro Carvalho Chehab 	unsigned int h;
2409d4fa1a1SMauro Carvalho Chehab 
2419d4fa1a1SMauro Carvalho Chehab 	assert(ID < N_ISP_ID);
2429d4fa1a1SMauro Carvalho Chehab 	assert((unsigned long)from % ISP_VEC_ALIGN == 0);
2439d4fa1a1SMauro Carvalho Chehab 	assert(width % ISP_NWAY == 0);
2449d4fa1a1SMauro Carvalho Chehab 	assert(stride_from % ISP_NWAY == 0);
2459d4fa1a1SMauro Carvalho Chehab 	for (h = 0; h < height; h++) {
2469d4fa1a1SMauro Carvalho Chehab 		unsigned int c;
2479d4fa1a1SMauro Carvalho Chehab 		const t_vmem_elem *vp = from;
2489d4fa1a1SMauro Carvalho Chehab 
2499d4fa1a1SMauro Carvalho Chehab 		for (c = 0; c < width; c += ISP_NWAY) {
2509d4fa1a1SMauro Carvalho Chehab 			load_vector(ID, &to[stride_to * h + c], vp);
2519d4fa1a1SMauro Carvalho Chehab 			vp = (t_vmem_elem *)((char *)vp + ISP_VEC_ALIGN);
2529d4fa1a1SMauro Carvalho Chehab 		}
2539d4fa1a1SMauro Carvalho Chehab 		from = (const t_vmem_elem *)((const char *)from + stride_from / ISP_NWAY *
2549d4fa1a1SMauro Carvalho Chehab 					     ISP_VEC_ALIGN);
2559d4fa1a1SMauro Carvalho Chehab 	}
2569d4fa1a1SMauro Carvalho Chehab }
2579d4fa1a1SMauro Carvalho Chehab 
isp_vmem_2d_store(const isp_ID_t ID,t_vmem_elem * to,const t_vmem_elem * from,unsigned int height,unsigned int width,unsigned int stride_to,unsigned stride_from)2589d4fa1a1SMauro Carvalho Chehab void isp_vmem_2d_store(
2599d4fa1a1SMauro Carvalho Chehab     const isp_ID_t		ID,
2609d4fa1a1SMauro Carvalho Chehab     t_vmem_elem		*to,
2619d4fa1a1SMauro Carvalho Chehab     const t_vmem_elem	*from,
2629d4fa1a1SMauro Carvalho Chehab     unsigned int height,
2639d4fa1a1SMauro Carvalho Chehab     unsigned int width,
2649d4fa1a1SMauro Carvalho Chehab     unsigned int stride_to,  /* In t_vmem_elem */
2659d4fa1a1SMauro Carvalho Chehab 
2669d4fa1a1SMauro Carvalho Chehab     unsigned stride_from /* In t_vmem_elem */)
2679d4fa1a1SMauro Carvalho Chehab {
2689d4fa1a1SMauro Carvalho Chehab 	unsigned int h;
2699d4fa1a1SMauro Carvalho Chehab 
2709d4fa1a1SMauro Carvalho Chehab 	assert(ID < N_ISP_ID);
2719d4fa1a1SMauro Carvalho Chehab 	assert((unsigned long)to % ISP_VEC_ALIGN == 0);
2729d4fa1a1SMauro Carvalho Chehab 	assert(width % ISP_NWAY == 0);
2739d4fa1a1SMauro Carvalho Chehab 	assert(stride_to % ISP_NWAY == 0);
2749d4fa1a1SMauro Carvalho Chehab 	for (h = 0; h < height; h++) {
2759d4fa1a1SMauro Carvalho Chehab 		unsigned int c;
2769d4fa1a1SMauro Carvalho Chehab 		t_vmem_elem *vp = to;
2779d4fa1a1SMauro Carvalho Chehab 
2789d4fa1a1SMauro Carvalho Chehab 		for (c = 0; c < width; c += ISP_NWAY) {
2799d4fa1a1SMauro Carvalho Chehab 			store_vector(ID, vp, &from[stride_from * h + c]);
2809d4fa1a1SMauro Carvalho Chehab 			vp = (t_vmem_elem *)((char *)vp + ISP_VEC_ALIGN);
2819d4fa1a1SMauro Carvalho Chehab 		}
2829d4fa1a1SMauro Carvalho Chehab 		to = (t_vmem_elem *)((char *)to + stride_to / ISP_NWAY * ISP_VEC_ALIGN);
2839d4fa1a1SMauro Carvalho Chehab 	}
2849d4fa1a1SMauro Carvalho Chehab }
285