• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * linux-5.4/drivers/media/platform/sunxi-vin/vin-tdm/tdm_reg.c
3  *
4  * Copyright (c) 2007-2019 Allwinnertech Co., Ltd.
5  *
6  * Authors:  Zheng Zequn <zequnzheng@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 "tdm_reg.h"
21 
22 #include "../utility/vin_io.h"
23 #include "../platform/platform_cfg.h"
24 
25 volatile void __iomem *csic_tdm_base[VIN_MAX_TDM];
26 
27 #define TDM_ADDR_BIT_R_SHIFT 2
28 
csic_tdm_set_base_addr(unsigned int sel,unsigned long addr)29 int csic_tdm_set_base_addr(unsigned int sel, unsigned long addr)
30 {
31 	if (sel > VIN_MAX_TDM - 1)
32 		return -1;
33 	csic_tdm_base[sel] = (volatile void __iomem *)addr;
34 
35 	return 0;
36 }
37 
38 /*
39  * function about tdm top registers
40  */
csic_tdm_top_enable(unsigned int sel)41 void csic_tdm_top_enable(unsigned int sel)
42 {
43 	vin_reg_clr_set(csic_tdm_base[sel] + TDM_GOLBAL_CFG0_REG_OFF,
44 			TDM_TOP_EN_MASK, 1 << TDM_TOP_EN);
45 }
46 
csic_tdm_top_disable(unsigned int sel)47 void csic_tdm_top_disable(unsigned int sel)
48 {
49 	vin_reg_clr_set(csic_tdm_base[sel] + TDM_GOLBAL_CFG0_REG_OFF,
50 			TDM_TOP_EN_MASK, 0 << TDM_TOP_EN);
51 }
52 
csic_tdm_enable(unsigned int sel)53 void csic_tdm_enable(unsigned int sel)
54 {
55 	vin_reg_clr_set(csic_tdm_base[sel] + TDM_GOLBAL_CFG0_REG_OFF,
56 			TDM_EN_MASK, 1 << TDM_EN);
57 }
58 
csic_tdm_fifo_max_layer_en(unsigned int sel,unsigned int en)59 void csic_tdm_fifo_max_layer_en(unsigned int sel, unsigned int en)
60 {
61 	vin_reg_clr_set(csic_tdm_base[sel] + TDM_GOLBAL_CFG0_REG_OFF,
62 			TDM_RX_FIFO_MAX_LAYER_EN_MASK, 1 << TDM_RX_FIFO_MAX_LAYER_EN);
63 }
64 
csic_tdm_disable(unsigned int sel)65 void csic_tdm_disable(unsigned int sel)
66 {
67 	vin_reg_clr_set(csic_tdm_base[sel] + TDM_GOLBAL_CFG0_REG_OFF,
68 			TDM_EN_MASK, 0 << TDM_EN);
69 }
70 
csic_tdm_int_enable(unsigned int sel,enum tdm_int_sel interrupt)71 void csic_tdm_int_enable(unsigned int sel,	enum tdm_int_sel interrupt)
72 {
73 	vin_reg_set(csic_tdm_base[sel] + TDM_INT_BYPASS0_REG_OFF, interrupt);
74 }
75 
csic_tdm_int_disable(unsigned int sel,enum tdm_int_sel interrupt)76 void csic_tdm_int_disable(unsigned int sel, enum tdm_int_sel interrupt)
77 {
78 	vin_reg_clr(csic_tdm_base[sel] + TDM_INT_BYPASS0_REG_OFF, interrupt);
79 }
80 
csic_tdm_int_get_status(unsigned int sel,struct tdm_int_status * status)81 void csic_tdm_int_get_status(unsigned int sel, struct tdm_int_status *status)
82 {
83 	unsigned int reg_val = vin_reg_readl(csic_tdm_base[sel] + TDM_INT_STATUS0_REG_OFF);
84 
85 	status->rx_frm_lost = (reg_val & RX_FRM_LOST_PD_MASK) >> RX_FRM_LOST_PD;
86 	status->rx_frm_err = (reg_val & RX_FRM_ERR_PD_MASK) >> RX_FRM_ERR_PD;
87 	status->rx_btype_err = (reg_val & RX_BTYPE_ERR_PD_MASK) >> RX_BTYPE_ERR_PD;
88 	status->rx_buf_full = (reg_val & RX_BUF_FULL_PD_MASK) >> RX_BUF_FULL_PD;
89 	status->rx_comp_err = (reg_val & RX_COMP_ERR_PD_MASK) >> RX_COMP_ERR_PD;
90 	status->rx_hb_short = (reg_val & RX_HB_SHORT_PD_MASK) >> RX_HB_SHORT_PD;
91 	status->rx_fifo_full = (reg_val & RX_FIFO_FULL_PD_MASK) >> RX_FIFO_FULL_PD;
92 	status->rx0_frm_done = (reg_val & RX0_FRM_DONE_PD_MASK) >> RX0_FRM_DONE_PD;
93 	status->rx1_frm_done = (reg_val & RX1_FRM_DONE_PD_MASK) >> RX1_FRM_DONE_PD;
94 }
95 
csic_tdm_int_clear_status(unsigned int sel,enum tdm_int_sel interrupt)96 void csic_tdm_int_clear_status(unsigned int sel, enum tdm_int_sel interrupt)
97 {
98 	vin_reg_writel(csic_tdm_base[sel] + TDM_INT_STATUS0_REG_OFF, interrupt);
99 }
100 
csic_tdm_internal_get_status0(unsigned int sel,unsigned int status)101 unsigned int csic_tdm_internal_get_status0(unsigned int sel, unsigned int status)
102 {
103 	return (vin_reg_readl(csic_tdm_base[sel] + TDM_INTERNAL_STATUS0_REG_OFF)) & status;
104 }
105 
csic_tdm_internal_clear_status0(unsigned int sel,unsigned int status)106 void csic_tdm_internal_clear_status0(unsigned int sel, unsigned int status)
107 {
108 	vin_reg_writel(csic_tdm_base[sel] + TDM_INTERNAL_STATUS0_REG_OFF, status);
109 }
110 
csic_tdm_internal_get_status1(unsigned int sel,unsigned int status)111 unsigned int csic_tdm_internal_get_status1(unsigned int sel, unsigned int status)
112 {
113 	return (vin_reg_readl(csic_tdm_base[sel] + TDM_INTERNAL_STATUS1_REG_OFF)) & status;
114 }
115 
csic_tdm_internal_clear_status1(unsigned int sel,unsigned int status)116 void csic_tdm_internal_clear_status1(unsigned int sel, unsigned int status)
117 {
118 	vin_reg_writel(csic_tdm_base[sel] + TDM_INTERNAL_STATUS1_REG_OFF, status);
119 }
120 
121 /*
122  * function about tdm tx registers
123  */
csic_tdm_tx_cap_enable(unsigned int sel)124 void csic_tdm_tx_cap_enable(unsigned int sel)
125 {
126 	vin_reg_clr_set(csic_tdm_base[sel] + TMD_TX_OFFSET + TDM_TX_CFG0_REG_OFF,
127 				TDM_TX_CAP_EN_MASK, 1 << TDM_TX_CAP_EN);
128 }
129 
csic_tdm_tx_cap_disable(unsigned int sel)130 void csic_tdm_tx_cap_disable(unsigned int sel)
131 {
132 	vin_reg_clr_set(csic_tdm_base[sel] + TMD_TX_OFFSET + TDM_TX_CFG0_REG_OFF,
133 				TDM_TX_CAP_EN_MASK, 0 << TDM_TX_CAP_EN);
134 }
135 
csic_tdm_omode(unsigned int sel,unsigned int mode)136 void csic_tdm_omode(unsigned int sel, unsigned int mode)
137 {
138 	vin_reg_clr_set(csic_tdm_base[sel] + TMD_TX_OFFSET + TDM_TX_CFG0_REG_OFF,
139 				TDM_TX_OMODE_MASK, mode << TDM_TX_OMODE);
140 }
141 
csic_tdm_set_hblank(unsigned int sel,unsigned int hblank)142 void csic_tdm_set_hblank(unsigned int sel, unsigned int hblank)
143 {
144 	vin_reg_clr_set(csic_tdm_base[sel] + TMD_TX_OFFSET + TDM_TX_CFG1_REG_OFF,
145 				TDM_TX_H_BLANK_MASK, hblank << TDM_TX_H_BLANK);
146 }
147 
csic_tdm_set_bblank_fe(unsigned int sel,unsigned int bblank_fe)148 void csic_tdm_set_bblank_fe(unsigned int sel, unsigned int bblank_fe)
149 {
150 	vin_reg_clr_set(csic_tdm_base[sel] + TMD_TX_OFFSET + TDM_TX_CFG2_REG_OFF,
151 				TDM_TX_V_BLANK_FE_MASK, bblank_fe << TDM_TX_V_BLANK_FE);
152 }
153 
csic_tdm_set_bblank_be(unsigned int sel,unsigned int bblank_be)154 void csic_tdm_set_bblank_be(unsigned int sel, unsigned int bblank_be)
155 {
156 	vin_reg_clr_set(csic_tdm_base[sel] + TMD_TX_OFFSET + TDM_TX_CFG2_REG_OFF,
157 				TDM_TX_V_BLANK_BE_MASK, bblank_be << TDM_TX_V_BLANK_BE);
158 }
159 
160 /*
161  * function about tdm rx registers
162  */
csic_tdm_rx_enable(unsigned int sel,unsigned int ch)163 void csic_tdm_rx_enable(unsigned int sel, unsigned int ch)
164 {
165 	vin_reg_clr_set(csic_tdm_base[sel] + TMD_RX0_OFFSET + ch*AMONG_RX_OFFSET + TDM_RX_CFG0_REG_OFF,
166 					TDM_RX_EN_MASK, 1 << TDM_RX_EN);
167 }
168 
csic_tdm_rx_disable(unsigned int sel,unsigned int ch)169 void csic_tdm_rx_disable(unsigned int sel, unsigned int ch)
170 {
171 		vin_reg_clr_set(csic_tdm_base[sel] + TMD_RX0_OFFSET + ch*AMONG_RX_OFFSET + TDM_RX_CFG0_REG_OFF,
172 					TDM_RX_EN_MASK, 0 << TDM_RX_EN);
173 }
174 
csic_tdm_rx_cap_enable(unsigned int sel,unsigned int ch)175 void csic_tdm_rx_cap_enable(unsigned int sel, unsigned int ch)
176 {
177 	vin_reg_clr_set(csic_tdm_base[sel] + TMD_RX0_OFFSET + ch*AMONG_RX_OFFSET + TDM_RX_CFG0_REG_OFF,
178 					TDM_RX_CAP_EN_MASK, 1 << TDM_RX_CAP_EN);
179 }
180 
csic_tdm_rx_cap_disable(unsigned int sel,unsigned int ch)181 void csic_tdm_rx_cap_disable(unsigned int sel, unsigned int ch)
182 {
183 	vin_reg_clr_set(csic_tdm_base[sel] + TMD_RX0_OFFSET + ch*AMONG_RX_OFFSET + TDM_RX_CFG0_REG_OFF,
184 					TDM_RX_CAP_EN_MASK, 0 << TDM_RX_CAP_EN);
185 }
186 
csic_tdm_rx_set_buf_num(unsigned int sel,unsigned int ch,unsigned int num)187 void csic_tdm_rx_set_buf_num(unsigned int sel, unsigned int ch, unsigned int num)
188 {
189 	vin_reg_clr_set(csic_tdm_base[sel] + TMD_RX0_OFFSET + ch*AMONG_RX_OFFSET + TDM_RX_CFG0_REG_OFF,
190 					TDM_RX_BUF_NUM_MASK, num << TDM_RX_BUF_NUM);
191 }
192 
csic_tdm_rx_ch0_en(unsigned int sel,unsigned int ch,unsigned int en)193 void csic_tdm_rx_ch0_en(unsigned int sel, unsigned int ch, unsigned int en)
194 {
195 	vin_reg_clr_set(csic_tdm_base[sel] + TMD_RX0_OFFSET + ch*AMONG_RX_OFFSET + TDM_RX_CFG0_REG_OFF,
196 					TDM_RX_CH0_EN_MASK, en << TDM_RX_CH0_EN);
197 }
198 
csic_tdm_rx_set_min_ddr_size(unsigned int sel,unsigned int ch,enum min_ddr_size_sel ddr_size)199 void csic_tdm_rx_set_min_ddr_size(unsigned int sel, unsigned int ch, enum min_ddr_size_sel ddr_size)
200 {
201 	vin_reg_clr_set(csic_tdm_base[sel] + TMD_RX0_OFFSET + ch*AMONG_RX_OFFSET + TDM_RX_CFG0_REG_OFF,
202 					TDM_RX_MIN_DDR_SIZE_MASK, ddr_size << TDM_RX_MIN_DDR_SIZE);
203 }
204 
csic_tdm_rx_input_bit(unsigned int sel,unsigned int ch,enum input_image_type_sel input_tpye)205 void csic_tdm_rx_input_bit(unsigned int sel, unsigned int ch, enum input_image_type_sel input_tpye)
206 {
207 	vin_reg_clr_set(csic_tdm_base[sel] + TMD_RX0_OFFSET + ch*AMONG_RX_OFFSET + TDM_RX_CFG0_REG_OFF,
208 					TDM_INPUT_BIT_MASK, input_tpye << TDM_INPUT_BIT);
209 }
210 
csic_tdm_rx_input_size(unsigned int sel,unsigned int ch,unsigned int width,unsigned int height)211 void csic_tdm_rx_input_size(unsigned int sel, unsigned int ch, unsigned int width, unsigned int height)
212 {
213 	vin_reg_clr_set(csic_tdm_base[sel] + TMD_RX0_OFFSET + ch*AMONG_RX_OFFSET + TDM_RX_CFG1_REG_OFF,
214 					TDM_RX_WIDTH_MASK, width << TDM_RX_WIDTH);
215 	vin_reg_clr_set(csic_tdm_base[sel] + TMD_RX0_OFFSET + ch*AMONG_RX_OFFSET + TDM_RX_CFG1_REG_OFF,
216 					TDM_RX_HEIGHT_MASK, height << TDM_RX_HEIGHT);
217 }
218 
csic_tdm_rx_set_address(unsigned int sel,unsigned int ch,unsigned long address)219 void csic_tdm_rx_set_address(unsigned int sel, unsigned int ch, unsigned long address)
220 {
221 	vin_reg_writel(csic_tdm_base[sel] + TMD_RX0_OFFSET + ch*AMONG_RX_OFFSET + TDM_RX_CFG2_REG_OFF,
222 					address >> TDM_ADDR_BIT_R_SHIFT);
223 }
224 
csic_tdm_rx_get_size(unsigned int sel,unsigned int ch,unsigned int * width,unsigned int * heigth)225 void csic_tdm_rx_get_size(unsigned int sel, unsigned int ch, unsigned int *width, unsigned int *heigth)
226 {
227 	unsigned int regval;
228 
229 	regval = vin_reg_readl(csic_tdm_base[sel] + TMD_RX0_OFFSET + ch*AMONG_RX_OFFSET + TDM_RX_FRAME_ERR_REG_OFF);
230 	*width = regval & 0x3fff;
231 	*heigth = (regval >> 16) & 0x3fff;
232 }
233 
csic_tdm_rx_get_hblank(unsigned int sel,unsigned int ch,unsigned int * hb_min,unsigned int * hb_max)234 void csic_tdm_rx_get_hblank(unsigned int sel, unsigned int ch, unsigned int *hb_min, unsigned int *hb_max)
235 {
236 	unsigned int regval;
237 
238 	regval = vin_reg_readl(csic_tdm_base[sel] + TMD_RX0_OFFSET + ch*AMONG_RX_OFFSET + TDM_RX_HB_SHORT_REG_OFF);
239 	*hb_max = regval & 0xffff;
240 	*hb_min = (regval >> 16) & 0xffff;
241 }
242 
243