1 /* SPDX-License-Identifier: GPL-2.0 */
2 /*
3  * Support for Intel Camera Imaging ISP subsystem.
4  * Copyright (c) 2015, Intel Corporation.
5  */
6 
7 #ifndef __DMA_GLOBAL_H_INCLUDED__
8 #define __DMA_GLOBAL_H_INCLUDED__
9 
10 #include <type_support.h>
11 
12 #define IS_DMA_VERSION_2
13 
14 #define HIVE_ISP_NUM_DMA_CONNS		3
15 #define HIVE_ISP_NUM_DMA_CHANNELS	32
16 
17 #define N_DMA_CHANNEL_ID	HIVE_ISP_NUM_DMA_CHANNELS
18 
19 #include "dma_v2_defs.h"
20 
21 /*
22  * Command token bit mappings
23  *
24  * transfer / config
25  *    param id[4] channel id[5] cmd id[6]
26  *	| b14 .. b11 | b10 ... b6 | b5 ... b0 |
27  *
28  * fast transfer:
29  *    height[5]     width[8]      width[8]  channel id[5] cmd id[6]
30  *	| b31 .. b26 | b25 .. b18 | b17 .. b11 | b10 ... b6 | b5 ... b0 |
31  *
32  */
33 
34 #define _DMA_PACKING_SETUP_PARAM	_DMA_V2_PACKING_SETUP_PARAM
35 #define _DMA_HEIGHT_PARAM			_DMA_V2_HEIGHT_PARAM
36 #define _DMA_STRIDE_A_PARAM			_DMA_V2_STRIDE_A_PARAM
37 #define _DMA_ELEM_CROPPING_A_PARAM	_DMA_V2_ELEM_CROPPING_A_PARAM
38 #define _DMA_WIDTH_A_PARAM			_DMA_V2_WIDTH_A_PARAM
39 #define _DMA_STRIDE_B_PARAM			_DMA_V2_STRIDE_B_PARAM
40 #define _DMA_ELEM_CROPPING_B_PARAM	_DMA_V2_ELEM_CROPPING_B_PARAM
41 #define _DMA_WIDTH_B_PARAM			_DMA_V2_WIDTH_B_PARAM
42 
43 #define _DMA_ZERO_EXTEND     _DMA_V2_ZERO_EXTEND
44 #define _DMA_SIGN_EXTEND     _DMA_V2_SIGN_EXTEND
45 
46 typedef unsigned int dma_channel;
47 
48 typedef enum {
49 	dma_isp_to_bus_connection = HIVE_DMA_ISP_BUS_CONN,
50 	dma_isp_to_ddr_connection = HIVE_DMA_ISP_DDR_CONN,
51 	dma_bus_to_ddr_connection = HIVE_DMA_BUS_DDR_CONN,
52 } dma_connection;
53 
54 typedef enum {
55 	dma_zero_extension = _DMA_ZERO_EXTEND,
56 	dma_sign_extension = _DMA_SIGN_EXTEND
57 } dma_extension;
58 
59 #define DMA_PROP_SHIFT(val, param)       ((val) << _DMA_V2_ ## param ## _IDX)
60 #define DMA_PROP_MASK(param)             ((1U << _DMA_V2_ ## param ## _BITS) - 1)
61 #define DMA_PACK(val, param)             DMA_PROP_SHIFT((val) & DMA_PROP_MASK(param), param)
62 
63 #define DMA_PACK_COMMAND(cmd)            DMA_PACK(cmd, CMD)
64 #define DMA_PACK_CHANNEL(ch)             DMA_PACK(ch,  CHANNEL)
65 #define DMA_PACK_PARAM(par)              DMA_PACK(par, PARAM)
66 #define DMA_PACK_EXTENSION(ext)          DMA_PACK(ext, EXTENSION)
67 #define DMA_PACK_LEFT_CROPPING(lc)       DMA_PACK(lc,  LEFT_CROPPING)
68 #define DMA_PACK_WIDTH_A(w)              DMA_PACK(w,   SPEC_DEV_A_XB)
69 #define DMA_PACK_WIDTH_B(w)              DMA_PACK(w,   SPEC_DEV_B_XB)
70 #define DMA_PACK_HEIGHT(h)               DMA_PACK(h,   SPEC_YB)
71 
72 #define DMA_PACK_CMD_CHANNEL(cmd, ch)	 (DMA_PACK_COMMAND(cmd) | DMA_PACK_CHANNEL(ch))
73 #define DMA_PACK_SETUP(conn, ext)        ((conn) | DMA_PACK_EXTENSION(ext))
74 #define DMA_PACK_CROP_ELEMS(elems, crop) ((elems) | DMA_PACK_LEFT_CROPPING(crop))
75 
76 #define hive_dma_snd(dma_id, token) OP_std_snd(dma_id, (unsigned int)(token))
77 
78 #define DMA_PACK_BLOCK_CMD(cmd, ch, width_a, width_b, height) \
79   (DMA_PACK_COMMAND(cmd)     | \
80    DMA_PACK_CHANNEL(ch)      | \
81    DMA_PACK_WIDTH_A(width_a) | \
82    DMA_PACK_WIDTH_B(width_b) | \
83    DMA_PACK_HEIGHT(height))
84 
85 #define hive_dma_move_data(dma_id, read, channel, addr_a, addr_b, to_is_var, from_is_var) \
86 { \
87   hive_dma_snd(dma_id, DMA_PACK(_DMA_V2_SET_CRUN_COMMAND, CMD)); \
88   hive_dma_snd(dma_id, DMA_PACK_CMD_CHANNEL(read ? _DMA_V2_MOVE_B2A_COMMAND : _DMA_V2_MOVE_A2B_COMMAND, channel)); \
89   hive_dma_snd(dma_id, read ? (unsigned int)(addr_b) : (unsigned int)(addr_a)); \
90   hive_dma_snd(dma_id, read ? (unsigned int)(addr_a) : (unsigned int)(addr_b)); \
91   hive_dma_snd(dma_id, to_is_var); \
92   hive_dma_snd(dma_id, from_is_var); \
93 }
94 
95 #define hive_dma_move_data_no_ack(dma_id, read, channel, addr_a, addr_b, to_is_var, from_is_var) \
96 { \
97   hive_dma_snd(dma_id, DMA_PACK(_DMA_V2_SET_CRUN_COMMAND, CMD)); \
98   hive_dma_snd(dma_id, DMA_PACK_CMD_CHANNEL(read ? _DMA_V2_NO_ACK_MOVE_B2A_NO_SYNC_CHK_COMMAND : _DMA_V2_NO_ACK_MOVE_A2B_NO_SYNC_CHK_COMMAND, channel)); \
99   hive_dma_snd(dma_id, read ? (unsigned int)(addr_b) : (unsigned int)(addr_a)); \
100   hive_dma_snd(dma_id, read ? (unsigned int)(addr_a) : (unsigned int)(addr_b)); \
101   hive_dma_snd(dma_id, to_is_var); \
102   hive_dma_snd(dma_id, from_is_var); \
103 }
104 
105 #define hive_dma_move_b2a_data(dma_id, channel, to_addr, from_addr, to_is_var, from_is_var) \
106 { \
107   hive_dma_move_data(dma_id, true, channel, to_addr, from_addr, to_is_var, from_is_var) \
108 }
109 
110 #define hive_dma_move_a2b_data(dma_id, channel, from_addr, to_addr, from_is_var, to_is_var) \
111 { \
112   hive_dma_move_data(dma_id, false, channel, from_addr, to_addr, from_is_var, to_is_var) \
113 }
114 
115 #define hive_dma_set_data(dma_id, channel, address, value, is_var) \
116 { \
117   hive_dma_snd(dma_id, DMA_PACK(_DMA_V2_SET_CRUN_COMMAND, CMD)); \
118   hive_dma_snd(dma_id, DMA_PACK_CMD_CHANNEL(_DMA_V2_INIT_A_COMMAND, channel)); \
119   hive_dma_snd(dma_id, value); \
120   hive_dma_snd(dma_id, address); \
121   hive_dma_snd(dma_id, is_var); \
122 }
123 
124 #define hive_dma_clear_data(dma_id, channel, address, is_var) hive_dma_set_data(dma_id, channel, address, 0, is_var)
125 
126 #define hive_dma_configure(dma_id, channel, connection, extension, height, \
127 	stride_A, elems_A, cropping_A, width_A, \
128 	stride_B, elems_B, cropping_B, width_B) \
129 { \
130   hive_dma_snd(dma_id, DMA_PACK_CMD_CHANNEL(_DMA_V2_CONFIG_CHANNEL_COMMAND, channel)); \
131   hive_dma_snd(dma_id, DMA_PACK_SETUP(connection, extension)); \
132   hive_dma_snd(dma_id, stride_A); \
133   hive_dma_snd(dma_id, DMA_PACK_CROP_ELEMS(elems_A, cropping_A)); \
134   hive_dma_snd(dma_id, width_A); \
135   hive_dma_snd(dma_id, stride_B); \
136   hive_dma_snd(dma_id, DMA_PACK_CROP_ELEMS(elems_B, cropping_B)); \
137   hive_dma_snd(dma_id, width_B); \
138   hive_dma_snd(dma_id, height); \
139 }
140 
141 #define hive_dma_execute(dma_id, channel, cmd, to_addr, from_addr_value, to_is_var, from_is_var) \
142 { \
143   hive_dma_snd(dma_id, DMA_PACK(_DMA_V2_SET_CRUN_COMMAND, CMD)); \
144   hive_dma_snd(dma_id, DMA_PACK_CMD_CHANNEL(cmd, channel)); \
145   hive_dma_snd(dma_id, to_addr); \
146   hive_dma_snd(dma_id, from_addr_value); \
147   hive_dma_snd(dma_id, to_is_var); \
148   if ((cmd & DMA_CLEAR_CMDBIT) == 0) { \
149 	hive_dma_snd(dma_id, from_is_var); \
150   } \
151 }
152 
153 #define hive_dma_configure_fast(dma_id, channel, connection, extension, elems_A, elems_B) \
154 { \
155   hive_dma_snd(dma_id, DMA_PACK_CMD_CHANNEL(_DMA_V2_CONFIG_CHANNEL_COMMAND, channel)); \
156   hive_dma_snd(dma_id, DMA_PACK_SETUP(connection, extension)); \
157   hive_dma_snd(dma_id, 0); \
158   hive_dma_snd(dma_id, DMA_PACK_CROP_ELEMS(elems_A, 0)); \
159   hive_dma_snd(dma_id, 0); \
160   hive_dma_snd(dma_id, 0); \
161   hive_dma_snd(dma_id, DMA_PACK_CROP_ELEMS(elems_B, 0)); \
162   hive_dma_snd(dma_id, 0); \
163   hive_dma_snd(dma_id, 1); \
164 }
165 
166 #define hive_dma_set_parameter(dma_id, channel, param, value) \
167 { \
168   hive_dma_snd(dma_id, _DMA_V2_SET_CHANNEL_PARAM_COMMAND | DMA_PACK_CHANNEL(channel) | DMA_PACK_PARAM(param)); \
169   hive_dma_snd(dma_id, value); \
170 }
171 
172 #define	DMA_SPECIFIC_CMDBIT	0x01
173 #define	DMA_CHECK_CMDBIT	0x02
174 #define	DMA_RW_CMDBIT		0x04
175 #define	DMA_CLEAR_CMDBIT	0x08
176 #define	DMA_ACK_CMDBIT		0x10
177 #define	DMA_CFG_CMDBIT		0x20
178 #define	DMA_PARAM_CMDBIT	0x01
179 
180 /* Write complete check not necessary if there's no ack */
181 #define	DMA_NOACK_CMD		(DMA_ACK_CMDBIT | DMA_CHECK_CMDBIT)
182 #define	DMA_CFG_CMD			(DMA_CFG_CMDBIT)
183 #define	DMA_CFGPARAM_CMD	(DMA_CFG_CMDBIT | DMA_PARAM_CMDBIT)
184 
185 #define DMA_CMD_NEEDS_ACK(cmd) ((cmd & DMA_NOACK_CMD) == 0)
186 #define DMA_CMD_IS_TRANSFER(cmd) ((cmd & DMA_CFG_CMDBIT) == 0)
187 #define DMA_CMD_IS_WR(cmd) ((cmd & DMA_RW_CMDBIT) != 0)
188 #define DMA_CMD_IS_RD(cmd) ((cmd & DMA_RW_CMDBIT) == 0)
189 #define DMA_CMD_IS_CLR(cmd) ((cmd & DMA_CLEAR_CMDBIT) != 0)
190 #define DMA_CMD_IS_CFG(cmd) ((cmd & DMA_CFG_CMDBIT) != 0)
191 #define DMA_CMD_IS_PARAMCFG(cmd) ((cmd & DMA_CFGPARAM_CMD) == DMA_CFGPARAM_CMD)
192 
193 /* As a matter of convention */
194 #define DMA_TRANSFER_READ		DMA_TRANSFER_B2A
195 #define DMA_TRANSFER_WRITE		DMA_TRANSFER_A2B
196 /* store/load from the PoV of the system(memory) */
197 #define DMA_TRANSFER_STORE		DMA_TRANSFER_B2A
198 #define DMA_TRANSFER_LOAD		DMA_TRANSFER_A2B
199 #define DMA_TRANSFER_CLEAR		DMA_TRANSFER_CLEAR_A
200 
201 typedef enum {
202 	DMA_TRANSFER_CLEAR_A = DMA_CLEAR_CMDBIT,                                       /* 8 */
203 	DMA_TRANSFER_CLEAR_B = DMA_CLEAR_CMDBIT | DMA_RW_CMDBIT,                       /* 12 */
204 	DMA_TRANSFER_A2B = DMA_RW_CMDBIT,                                              /* 4 */
205 	DMA_TRANSFER_B2A = 0,                                                          /* 0 */
206 	DMA_TRANSFER_CLEAR_A_NOACK = DMA_CLEAR_CMDBIT | DMA_NOACK_CMD,                 /* 26 */
207 	DMA_TRANSFER_CLEAR_B_NOACK = DMA_CLEAR_CMDBIT | DMA_RW_CMDBIT | DMA_NOACK_CMD, /* 30 */
208 	DMA_TRANSFER_A2B_NOACK = DMA_RW_CMDBIT | DMA_NOACK_CMD,                        /* 22 */
209 	DMA_TRANSFER_B2A_NOACK = DMA_NOACK_CMD,                                        /* 18 */
210 	DMA_FASTTRANSFER_CLEAR_A = DMA_CLEAR_CMDBIT | DMA_SPECIFIC_CMDBIT,
211 	DMA_FASTTRANSFER_CLEAR_B = DMA_CLEAR_CMDBIT | DMA_RW_CMDBIT | DMA_SPECIFIC_CMDBIT,
212 	DMA_FASTTRANSFER_A2B = DMA_RW_CMDBIT | DMA_SPECIFIC_CMDBIT,
213 	DMA_FASTTRANSFER_B2A = DMA_SPECIFIC_CMDBIT,
214 	DMA_FASTTRANSFER_CLEAR_A_NOACK = DMA_CLEAR_CMDBIT | DMA_NOACK_CMD | DMA_SPECIFIC_CMDBIT,
215 	DMA_FASTTRANSFER_CLEAR_B_NOACK = DMA_CLEAR_CMDBIT | DMA_RW_CMDBIT | DMA_NOACK_CMD | DMA_SPECIFIC_CMDBIT,
216 	DMA_FASTTRANSFER_A2B_NOACK = DMA_RW_CMDBIT | DMA_NOACK_CMD | DMA_SPECIFIC_CMDBIT,
217 	DMA_FASTTRANSFER_B2A_NOACK = DMA_NOACK_CMD | DMA_SPECIFIC_CMDBIT,
218 } dma_transfer_type_t;
219 
220 typedef enum {
221 	DMA_CONFIG_SETUP = _DMA_V2_PACKING_SETUP_PARAM,
222 	DMA_CONFIG_HEIGHT = _DMA_V2_HEIGHT_PARAM,
223 	DMA_CONFIG_STRIDE_A_ = _DMA_V2_STRIDE_A_PARAM,
224 	DMA_CONFIG_CROP_ELEM_A = _DMA_V2_ELEM_CROPPING_A_PARAM,
225 	DMA_CONFIG_WIDTH_A = _DMA_V2_WIDTH_A_PARAM,
226 	DMA_CONFIG_STRIDE_B_ = _DMA_V2_STRIDE_B_PARAM,
227 	DMA_CONFIG_CROP_ELEM_B = _DMA_V2_ELEM_CROPPING_B_PARAM,
228 	DMA_CONFIG_WIDTH_B = _DMA_V2_WIDTH_B_PARAM,
229 } dma_config_type_t;
230 
231 struct dma_port_config {
232 	u8  crop, elems;
233 	u16 width;
234 	u32 stride;
235 };
236 
237 /* Descriptor for dma configuration */
238 struct dma_channel_config {
239 	u8  connection;
240 	u8  extension;
241 	u8  height;
242 	struct dma_port_config a, b;
243 };
244 
245 #endif /* __DMA_GLOBAL_H_INCLUDED__ */
246