1 /*
2 * linux-5.4/drivers/media/platform/sunxi-vin/vin-video/dma_reg.c
3 *
4 * Copyright (c) 2007-2017 Allwinnertech Co., Ltd.
5 *
6 * Authors: Zhao Wei <zhaowei@allwinnertech.com>
7 *
8 * This software is licensed under the terms of the GNU General Public
9 * License version 2, as published by the Free Software Foundation, and
10 * may be copied, distributed, and modified under those terms.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 */
18
19 #include <linux/kernel.h>
20 #include "dma_reg_i.h"
21 #include "dma_reg.h"
22
23 #include "../utility/vin_io.h"
24 #include "../platform/platform_cfg.h"
25
26 #define ADDR_BIT_R_SHIFT 2
27
28 volatile void __iomem *csic_dma_base[VIN_MAX_SCALER];
29
csic_dma_set_base_addr(unsigned int sel,unsigned long addr)30 int csic_dma_set_base_addr(unsigned int sel, unsigned long addr)
31 {
32 if (sel > VIN_MAX_SCALER - 1)
33 return -1;
34 csic_dma_base[sel] = (volatile void __iomem *)addr;
35
36 return 0;
37 }
38
39 /* open module */
40
csic_dma_get_frame_cnt(unsigned int sel)41 int csic_dma_get_frame_cnt(unsigned int sel)
42 {
43 unsigned int reg_val = vin_reg_readl(csic_dma_base[sel] + CSIC_DMA_FRM_CNT_REG_OFF);
44
45 return ((reg_val & CSIC_DMA_FRM_CNT_MASK) >> CSIC_DMA_FRM_CNT);
46 }
47
csic_dma_top_enable(unsigned int sel)48 void csic_dma_top_enable(unsigned int sel)
49 {
50 vin_reg_clr_set(csic_dma_base[sel] + CSIC_DMA_EN_REG_OFF,
51 CSIC_DMA_TOP_EN_MASK, 1 << CSIC_DMA_TOP_EN);
52 }
53
csic_dma_top_disable(unsigned int sel)54 void csic_dma_top_disable(unsigned int sel)
55 {
56 vin_reg_clr_set(csic_dma_base[sel] + CSIC_DMA_EN_REG_OFF,
57 CSIC_DMA_TOP_EN_MASK, 0 << CSIC_DMA_TOP_EN);
58 }
59
csic_dma_enable(unsigned int sel)60 void csic_dma_enable(unsigned int sel)
61 {
62 vin_reg_clr_set(csic_dma_base[sel] + CSIC_DMA_EN_REG_OFF,
63 CSIC_DMA_EN_MASK, 1 << CSIC_DMA_EN);
64 }
65
csic_dma_disable(unsigned int sel)66 void csic_dma_disable(unsigned int sel)
67 {
68 vin_reg_clr_set(csic_dma_base[sel] + CSIC_DMA_EN_REG_OFF,
69 CSIC_DMA_EN_MASK, 0 << CSIC_DMA_EN);
70 }
71
csic_fbc_enable(unsigned int sel)72 void csic_fbc_enable(unsigned int sel)
73 {
74 vin_reg_clr_set(csic_dma_base[sel] + CSIC_DMA_EN_REG_OFF,
75 CSIC_FBC_EN_MASK, 1 << CSIC_FBC_EN);
76 }
77
csic_fbc_disable(unsigned int sel)78 void csic_fbc_disable(unsigned int sel)
79 {
80 vin_reg_clr_set(csic_dma_base[sel] + CSIC_DMA_EN_REG_OFF,
81 CSIC_FBC_EN_MASK, 0 << CSIC_FBC_EN);
82 }
83
csic_lbc_enable(unsigned int sel)84 void csic_lbc_enable(unsigned int sel)
85 {
86 vin_reg_clr_set(csic_dma_base[sel] + CSIC_DMA_EN_REG_OFF,
87 CSIC_DMA_EN_MASK, 1 << CSIC_DMA_EN);
88 vin_reg_clr_set(csic_dma_base[sel] + CSIC_DMA_EN_REG_OFF,
89 CSIC_LBC_EN_MASK, 1 << CSIC_LBC_EN);
90 }
91
csic_lbc_disable(unsigned int sel)92 void csic_lbc_disable(unsigned int sel)
93 {
94 vin_reg_clr_set(csic_dma_base[sel] + CSIC_DMA_EN_REG_OFF,
95 CSIC_DMA_EN_MASK, 0 << CSIC_DMA_EN);
96 vin_reg_clr_set(csic_dma_base[sel] + CSIC_DMA_EN_REG_OFF,
97 CSIC_LBC_EN_MASK, 0 << CSIC_LBC_EN);
98 }
99
csic_frame_cnt_enable(unsigned int sel)100 void csic_frame_cnt_enable(unsigned int sel)
101 {
102 vin_reg_clr_set(csic_dma_base[sel] + CSIC_DMA_EN_REG_OFF,
103 CSIC_FRAME_CNT_EN_MASK, 1 << CSIC_FRAME_CNT_EN);
104 }
105
csic_frame_cnt_disable(unsigned int sel)106 void csic_frame_cnt_disable(unsigned int sel)
107 {
108 vin_reg_clr_set(csic_dma_base[sel] + CSIC_DMA_EN_REG_OFF,
109 CSIC_FRAME_CNT_EN_MASK, 0 << CSIC_FRAME_CNT_EN);
110 }
111
csic_buf_addr_fifo_en(unsigned int sel,unsigned int en)112 void csic_buf_addr_fifo_en(unsigned int sel, unsigned int en)
113 {
114 vin_reg_clr_set(csic_dma_base[sel] + CSIC_DMA_EN_REG_OFF,
115 CSIC_BUF_ADDR_MODE_MASK, en << CSIC_BUF_ADDR_MODE);
116 }
117
csic_dma_clk_cnt_en(unsigned int sel,unsigned int en)118 void csic_dma_clk_cnt_en(unsigned int sel, unsigned int en)
119 {
120 vin_reg_clr_set(csic_dma_base[sel] + CSIC_DMA_EN_REG_OFF,
121 CSIC_CLK_CNT_EN_MASK, 1 << CSIC_CLK_CNT_EN);
122
123 }
csic_dma_clk_cnt_sample(unsigned int sel,unsigned int en)124 void csic_dma_clk_cnt_sample(unsigned int sel, unsigned int en)
125 {
126 vin_reg_clr_set(csic_dma_base[sel] + CSIC_DMA_EN_REG_OFF,
127 CSIC_CLK_CNT_SPL_MASK, 1 << CSIC_CLK_CNT_SPL);
128
129 }
130
csic_dma_output_fmt_cfg(unsigned int sel,enum output_fmt fmt)131 void csic_dma_output_fmt_cfg(unsigned int sel, enum output_fmt fmt)
132 {
133 vin_reg_clr_set(csic_dma_base[sel] + CSIC_DMA_CFG_REG_OFF,
134 OUTPUT_FMT_MASK, fmt << OUTPUT_FMT);
135
136 }
137
csic_dma_buf_length_software_enable(unsigned int sel,unsigned int en)138 void csic_dma_buf_length_software_enable(unsigned int sel, unsigned int en)
139 {
140 vin_reg_clr_set(csic_dma_base[sel] + CSIC_DMA_EN_REG_OFF,
141 CSIC_BUF_LENGTH_CFG_MODE_MASK, en << CSIC_BUF_LENGTH_CFG_MODE);
142 }
143
csi_dam_flip_software_enable(unsigned int sel,unsigned int en)144 void csi_dam_flip_software_enable(unsigned int sel, unsigned int en)
145 {
146 vin_reg_clr_set(csic_dma_base[sel] + CSIC_DMA_EN_REG_OFF,
147 CSIC_FLIP_SIZE_CFG_MODE_MASK, en << CSIC_FLIP_SIZE_CFG_MODE);
148 vin_reg_clr_set(csic_dma_base[sel] + CSIC_DMA_EN_REG_OFF,
149 CSIC_VFLIP_BUF_ADDR_CFG_MODE_MASK, en << CSIC_VFLIP_BUF_ADDR_CFG_MODE);
150 }
151
csic_dma_flip_en(unsigned int sel,struct csic_dma_flip * flip)152 void csic_dma_flip_en(unsigned int sel, struct csic_dma_flip *flip)
153 {
154 vin_reg_clr_set(csic_dma_base[sel] + CSIC_DMA_CFG_REG_OFF,
155 HFLIP_EN_MASK, flip->hflip_en << HFLIP_EN);
156 vin_reg_clr_set(csic_dma_base[sel] + CSIC_DMA_CFG_REG_OFF,
157 VFLIP_EN_MASK, flip->vflip_en << VFLIP_EN);
158 }
csic_dma_config(unsigned int sel,struct csic_dma_cfg * cfg)159 void csic_dma_config(unsigned int sel, struct csic_dma_cfg *cfg)
160 {
161 vin_reg_clr_set(csic_dma_base[sel] + CSIC_DMA_CFG_REG_OFF,
162 MIN_SDR_WR_SIZE_MASK, cfg->block << MIN_SDR_WR_SIZE);
163 vin_reg_clr_set(csic_dma_base[sel] + CSIC_DMA_CFG_REG_OFF,
164 FPS_DS_MASK, cfg->ds << FPS_DS);
165 vin_reg_clr_set(csic_dma_base[sel] + CSIC_DMA_CFG_REG_OFF,
166 FIELD_SEL_MASK, cfg->field << FIELD_SEL);
167 vin_reg_clr_set(csic_dma_base[sel] + CSIC_DMA_CFG_REG_OFF,
168 HFLIP_EN_MASK, cfg->flip.hflip_en << HFLIP_EN);
169 vin_reg_clr_set(csic_dma_base[sel] + CSIC_DMA_CFG_REG_OFF,
170 VFLIP_EN_MASK, cfg->flip.vflip_en << VFLIP_EN);
171 vin_reg_clr_set(csic_dma_base[sel] + CSIC_DMA_CFG_REG_OFF,
172 OUTPUT_FMT_MASK, cfg->fmt << OUTPUT_FMT);
173 }
174
csic_dma_10bit_cut2_8bit_enable(unsigned int sel)175 void csic_dma_10bit_cut2_8bit_enable(unsigned int sel)
176 {
177 vin_reg_clr_set(csic_dma_base[sel] + CSIC_DMA_CFG_REG_OFF,
178 ENABLE_10BIT_CUT2_8BIT_MASK, 1 << ENABLE_10BIT_CUT2_8BIT);
179 }
180
csic_dma_10bit_cut2_8bit_disable(unsigned int sel)181 void csic_dma_10bit_cut2_8bit_disable(unsigned int sel)
182 {
183 vin_reg_clr_set(csic_dma_base[sel] + CSIC_DMA_CFG_REG_OFF,
184 ENABLE_10BIT_CUT2_8BIT_MASK, 0 << ENABLE_10BIT_CUT2_8BIT);
185 }
186
csic_set_threshold_for_bufa_mode(unsigned int sel,struct dma_bufa_threshold * threshold)187 void csic_set_threshold_for_bufa_mode(unsigned int sel, struct dma_bufa_threshold *threshold)
188 {
189 vin_reg_clr_set(csic_dma_base[sel] + CSIC_DMA_BUF_THRESHOLD_REG_OFF,
190 DMA_BUFA_FIFO_THRESHOLD_MASK, threshold->bufa_fifo_threshold << DMA_BUFA_FIFO_THRESHOLD);
191 vin_reg_clr_set(csic_dma_base[sel] + CSIC_DMA_BUF_THRESHOLD_REG_OFF,
192 DMA_STORED_FRM_THRESHOLD_MASK, threshold->stored_frm_threshold << DMA_STORED_FRM_THRESHOLD);
193 }
194
csic_dma_output_size_cfg(unsigned int sel,struct dma_output_size * size)195 void csic_dma_output_size_cfg(unsigned int sel, struct dma_output_size *size)
196 {
197 vin_reg_clr_set(csic_dma_base[sel] + CSIC_DMA_HSIZE_REG_OFF,
198 HOR_START_MASK, size->hor_start << HOR_START);
199 vin_reg_clr_set(csic_dma_base[sel] + CSIC_DMA_HSIZE_REG_OFF,
200 HOR_LEN_MASK, size->hor_len << HOR_LEN);
201 vin_reg_clr_set(csic_dma_base[sel] + CSIC_DMA_VSIZE_REG_OFF,
202 VER_START_MASK, size->ver_start << VER_START);
203 vin_reg_clr_set(csic_dma_base[sel] + CSIC_DMA_VSIZE_REG_OFF,
204 VER_LEN_MASK, size->ver_len << VER_LEN);
205 }
csic_dma_buffer_address(unsigned int sel,unsigned int buf,unsigned long addr)206 void csic_dma_buffer_address(unsigned int sel, unsigned int buf,
207 unsigned long addr)
208 {
209 #ifndef BUF_AUTO_UPDATE
210 vin_reg_clr_set(csic_dma_base[sel] + CSIC_DMA_F0_BUFA_REG_OFF + buf * 4,
211 F0_BUFA_MASK, addr >> ADDR_BIT_R_SHIFT);
212 #else
213 vin_reg_writel(csic_dma_base[sel] + CSIC_DMA_BUFA_F0_ENTRY_REG_OFF + buf * 2,
214 addr >> ADDR_BIT_R_SHIFT);
215 #endif
216 }
csic_dma_buffer_length(unsigned int sel,struct dma_buf_len * buf_len)217 void csic_dma_buffer_length(unsigned int sel, struct dma_buf_len *buf_len)
218 {
219 vin_reg_clr_set(csic_dma_base[sel] + CSIC_DMA_BUF_LEN_REG_OFF,
220 BUF_LEN_MASK, buf_len->buf_len_y << BUF_LEN);
221 vin_reg_clr_set(csic_dma_base[sel] + CSIC_DMA_BUF_LEN_REG_OFF,
222 BUF_LEN_C_MASK, buf_len->buf_len_c << BUF_LEN_C);
223
224 }
csic_dma_flip_size(unsigned int sel,struct dma_flip_size * flip_size)225 void csic_dma_flip_size(unsigned int sel, struct dma_flip_size *flip_size)
226 {
227 vin_reg_clr_set(csic_dma_base[sel] + CSIC_DMA_FLIP_SIZE_REG_OFF,
228 VALID_LEN_MASK, flip_size->hor_len << VALID_LEN);
229 vin_reg_clr_set(csic_dma_base[sel]+CSIC_DMA_FLIP_SIZE_REG_OFF,
230 VER_LEN_MASK, flip_size->ver_len << VER_LEN);
231 }
232
csic_dma_line_cnt(unsigned int sel,int line)233 void csic_dma_line_cnt(unsigned int sel, int line)
234 {
235 vin_reg_clr_set(csic_dma_base[sel] + CSIC_DMA_LINE_CNT_REG_OFF,
236 LINE_CNT_NUM_MASK, line);
237 }
csic_dma_frm_cnt(unsigned int sel,struct csi_sync_ctrl * sync)238 void csic_dma_frm_cnt(unsigned int sel, struct csi_sync_ctrl *sync)
239 {
240 vin_reg_clr_set(csic_dma_base[sel] + CSIC_DMA_FRM_CNT_REG_OFF,
241 CSIC_DMA_CLR_DIS_MASK, sync->dma_clr_dist<<CSIC_DMA_CLR_DIS);
242 }
csic_dma_cap_status(unsigned int sel,struct dma_capture_status * status)243 void csic_dma_cap_status(unsigned int sel, struct dma_capture_status *status)
244 {
245 unsigned int reg_val = vin_reg_readl(csic_dma_base[sel] + CSIC_DMA_CAP_STA_REG_OFF);
246
247 status->scap_sta = (reg_val & SCAP_STA_MASK) >> SCAP_STA;
248 status->vcap_sta = (reg_val & VCAP_STA_MASK) >> VCAP_STA;
249 status->field_sta = (reg_val & FIELD_STA_MASK) >> FIELD_STA;
250 }
251
csic_dma_int_enable(unsigned int sel,enum dma_int_sel interrupt)252 void csic_dma_int_enable(unsigned int sel, enum dma_int_sel interrupt)
253 {
254 vin_reg_set(csic_dma_base[sel] + CSIC_DMA_INT_EN_REG_OFF, interrupt);
255 }
csic_dma_int_disable(unsigned int sel,enum dma_int_sel interrupt)256 void csic_dma_int_disable(unsigned int sel, enum dma_int_sel interrupt)
257 {
258 vin_reg_clr(csic_dma_base[sel] + CSIC_DMA_INT_EN_REG_OFF, interrupt);
259 }
csic_dma_int_get_status(unsigned int sel,struct dma_int_status * status)260 void csic_dma_int_get_status(unsigned int sel, struct dma_int_status *status)
261 {
262 unsigned int reg_val = vin_reg_readl(csic_dma_base[sel] + CSIC_DMA_INT_STA_REG_OFF);
263
264 status->capture_done = (reg_val & CD_PD_MASK) >> CD_PD;
265 status->frame_done = (reg_val & FD_PD_MASK) >> FD_PD;
266 status->buf_0_overflow = (reg_val & FIFO0_OF_PD_MASK) >> FIFO0_OF_PD;
267 status->buf_1_overflow = (reg_val & FIFO1_OF_PD_MASK) >> FIFO1_OF_PD;
268 status->buf_2_overflow = (reg_val & FIFO2_OF_PD_MASK) >> FIFO2_OF_PD;
269 status->line_cnt_flag = (reg_val & LC_INT_EN_MASK) >> LC_INT_EN;
270 status->hblank_overflow = (reg_val & HB_OF_INT_EN_MASK) >> HB_OF_INT_EN;
271 status->vsync_trig = (reg_val & VS_INT_EN_MASK) >> VS_INT_EN;
272 status->fbc_ovhd_wrddr_full = (reg_val & FBC_OVHD_WRDDR_FULL_INT_EN_MASK) >> FBC_OVHD_WRDDR_FULL_INT_EN;
273 status->fbc_data_wrddr_full = (reg_val & FBC_DATA_WRDDR_FULL_INT_EN_MASK) >> FBC_DATA_WRDDR_FULL_INT_EN;
274 status->buf_addr_fifo = (reg_val & BUF_ADDR_FIFO_INT_PD_MASK) >> BUF_ADDR_FIFO_INT_PD;
275 status->stored_frm_cnt = (reg_val & STORED_FRM_CNT_INT_PD_MASK) >> STORED_FRM_CNT_INT_PD;
276 status->frm_lost = (reg_val & FRM_LOST_INT_PD_MASK) >> FRM_LOST_INT_PD;
277 status->lbc_hb = (reg_val & LBC_HB_INT_PD_MASK) >> LBC_HB_INT_PD;
278 }
csic_dma_int_clear_status(unsigned int sel,enum dma_int_sel interrupt)279 void csic_dma_int_clear_status(unsigned int sel, enum dma_int_sel interrupt)
280 {
281 vin_reg_writel(csic_dma_base[sel] + CSIC_DMA_INT_STA_REG_OFF, interrupt);
282 }
283
csic_lbc_cmp_ratio(unsigned int sel,struct dma_lbc_cmp * lbc_cmp)284 void csic_lbc_cmp_ratio(unsigned int sel, struct dma_lbc_cmp *lbc_cmp)
285 {
286 vin_reg_clr_set(csic_dma_base[sel] + CSIC_LBC_CONFIGURE_REG_OFF,
287 WHETHER_LOSSY_ENABLE_MASK, lbc_cmp->is_lossy << WHETHER_LOSSY_ENABLE);
288 vin_reg_clr_set(csic_dma_base[sel] + CSIC_LBC_CONFIGURE_REG_OFF,
289 GLB_ENABLE_MASK, lbc_cmp->glb_enable << GLB_ENABLE);
290 vin_reg_clr_set(csic_dma_base[sel] + CSIC_LBC_CONFIGURE_REG_OFF,
291 DTS_ENABLE_MASK, lbc_cmp->dts_enable << DTS_ENABLE);
292 vin_reg_clr_set(csic_dma_base[sel] + CSIC_LBC_CONFIGURE_REG_OFF,
293 OTS_ENABLE_MASK, lbc_cmp->ots_enable << OTS_ENABLE);
294 vin_reg_clr_set(csic_dma_base[sel] + CSIC_LBC_CONFIGURE_REG_OFF,
295 MSQ_ENABLE_MASK, lbc_cmp->msq_enable << MSQ_ENABLE);
296 vin_reg_clr_set(csic_dma_base[sel] + CSIC_LBC_CONFIGURE_REG_OFF,
297 UPDATE_ADVANTURE_ENABLE_MASK, lbc_cmp->updata_adv_en << UPDATE_ADVANTURE_ENABLE);
298 vin_reg_clr_set(csic_dma_base[sel] + CSIC_LBC_CONFIGURE_REG_OFF,
299 UPDATE_ADVANTURE_RATIO_MASK, lbc_cmp->updata_adv_ratio << UPDATE_ADVANTURE_RATIO);
300 vin_reg_clr_set(csic_dma_base[sel] + CSIC_LBC_CONFIGURE_REG_OFF,
301 LIMIT_QP_ENABLE_MASK, lbc_cmp->lmtqp_en << LIMIT_QP_ENABLE);
302 vin_reg_clr_set(csic_dma_base[sel] + CSIC_LBC_CONFIGURE_REG_OFF,
303 LIMIT_QP_MIM_MASK, lbc_cmp->lmtqp_min << LIMIT_QP_MIM);
304
305 vin_reg_writel(csic_dma_base[sel] + CSIC_LBC_LINE_TARGET_BIT0_REG_OFF, lbc_cmp->line_tar_bits[0]);
306 vin_reg_writel(csic_dma_base[sel] + CSIC_LBC_LINE_TARGET_BIT1_REG_OFF, lbc_cmp->line_tar_bits[1]);
307
308 vin_reg_clr_set(csic_dma_base[sel] + CSIC_LBC_RC_ADV_REG_OFF,
309 RATE_CONTROL_ADVANTURE_0_MASK, lbc_cmp->rc_adv[0] << RATE_CONTROL_ADVANTURE_0);
310 vin_reg_clr_set(csic_dma_base[sel] + CSIC_LBC_RC_ADV_REG_OFF,
311 RATE_CONTROL_ADVANTURE_1_MASK, lbc_cmp->rc_adv[1] << RATE_CONTROL_ADVANTURE_1);
312 vin_reg_clr_set(csic_dma_base[sel] + CSIC_LBC_RC_ADV_REG_OFF,
313 RATE_CONTROL_ADVANTURE_2_MASK, lbc_cmp->rc_adv[2] << RATE_CONTROL_ADVANTURE_2);
314 vin_reg_clr_set(csic_dma_base[sel] + CSIC_LBC_RC_ADV_REG_OFF,
315 RATE_CONTROL_ADVANTURE_3_MASK, lbc_cmp->rc_adv[3] << RATE_CONTROL_ADVANTURE_3);
316
317 vin_reg_clr_set(csic_dma_base[sel] + CSIC_LBC_MB_MIN_REG_OFF,
318 MACROBLOCK_MIN_BITS0_MASK, lbc_cmp->mb_mi_bits[0] << MACROBLOCK_MIN_BITS0);
319 vin_reg_clr_set(csic_dma_base[sel] + CSIC_LBC_MB_MIN_REG_OFF,
320 MACROBLOCK_MIN_BITS1_MASK, lbc_cmp->mb_mi_bits[1] << MACROBLOCK_MIN_BITS1);
321 }
322
323