• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2 *
3 * SPDX-License-Identifier: GPL-2.0
4 *
5 * Copyright (C) 2011-2018 ARM or its affiliates
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; version 2.
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
12 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
13 * for more details.
14 * You should have received a copy of the GNU General Public License along
15 * with this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17 *
18 */
19 
20 #include <linux/version.h>
21 #include <linux/irqreturn.h>
22 #include <linux/of_address.h>
23 #include <linux/of_irq.h>
24 #include <linux/ioport.h>
25 #include <linux/of_platform.h>
26 #include <linux/dma-mapping.h>
27 #include <linux/interrupt.h>
28 #include <linux/kernel.h>
29 #include <linux/device.h>
30 #if (LINUX_VERSION_CODE <= KERNEL_VERSION(4, 19, 0))
31 #include <linux/dma-contiguous.h>
32 #endif
33 #include <linux/of_reserved_mem.h>
34 #include <linux/platform_device.h>
35 #include <linux/device.h>
36 #include <linux/module.h>
37 #include <linux/of_fdt.h>
38 #include <linux/fs.h>
39 #include <linux/uaccess.h>
40 #include <linux/io.h>
41 #include <linux/kfifo.h>
42 #include <linux/completion.h>
43 #include <linux/jiffies.h>
44 #include <linux/version.h>
45 #include <linux/slab.h>
46 
47 #include "acamera_types.h"
48 #include "acamera_logger.h"
49 #include "system_am_md.h"
50 
51 #define AM_MD_IRQ         131
52 #define AM_MD_MEMORY      0x70000000
53 #define AM_MD_NAME        "amlogic, isp-md"
54 
55 static struct am_md *g_md;
56 
57 T_MD_PRM am_md_reg;
58 
59 /*****************************************************************/
write_reg(unsigned long addr,uint32_t val)60 static uint32_t write_reg(unsigned long addr, uint32_t val)
61 {
62     void __iomem *io_addr;
63 
64 #if (LINUX_VERSION_CODE <= KERNEL_VERSION(4, 19, 0))
65     io_addr = ioremap_nocache(addr, 8);
66 #else
67     io_addr = ioremap(addr, 8);
68 #endif
69     if (io_addr == NULL) {
70         LOG(LOG_ERR, "%s: Failed to ioremap addr\n", __func__);
71         return -1;
72     }
73     __raw_writel(val, io_addr);
74     iounmap(io_addr);
75 
76     return 0;
77 }
78 
md_write_reg(int addr,uint32_t val)79 static inline void md_write_reg(int addr, uint32_t val)
80 {
81 	void __iomem *base = g_md->base_addr;
82 
83 	if (base != NULL) {
84 		base = base + addr;
85 		writel(val, base);
86 	} else
87 		pr_err("isp-sc write register failed.\n");
88 
89     return;
90 }
91 
92 
93 /*************************************************************************
94     > File Name: isp_md_pkg.c
95   > Author: ma6174
96   > Mail: ma6174@163.com
97   > Created Time: Thu 09 May 2019 02:18:28 PM PDT
98  ************************************************************************/
99 //int param_md_init(T_MD_PRM *reg, int xsize, int ysize)
param_md_init(T_MD_PRM * reg)100 int param_md_init(T_MD_PRM *reg)
101 {
102     //int xsize = 1920;
103     //int ysize = 1080;
104 	int k;
105 #if 0
106 	int bld_coefs[4] = {32, 32, 32, 32};
107 	// (256)x   4xstep(1+1 + 2 + 4 + 8 + 16 +32 +64 +128 + 128 + 128 + 128 + 128 + 128 + 128) = 61 taps
108 	int eotf_u12[61] = {  0,   1,   2,   3,   4,    5,   6,   7,   8,  // xdelt = 1, 1
109 	                          10,  12,  14,  16,   20,  24,  28,  32,  // xdelt = 2, 4
110 	                          40,  48,  56,  64,   80,  96, 112, 128,  // xdelt = 8, 16
111 							 160, 192, 224, 256,  320, 384, 448, 512,  // xdelt = 32, 64
112 							 640, 768, 892,1024, 1152,1280,1408,1536,  // xdelt = 128
113 							1664,1792,1920,2048, 2176,2304,2432,2560,
114 							2688,2816,2944,3072, 3200,3328,3456,3584,
115 							3712,3840,3968,4095};                      // linear one
116 	int eotf_u12_sqrt[61] = {   0,  64,  91, 111, 128,   143, 157, 169, 181, // xdelt = 1, 1
117 		                           202, 222, 239, 256,   286, 314, 339, 362, // xdelt = 2, 4
118 								   405, 443, 479, 512,   572, 627, 677, 724, // xdelt = 8, 16
119 								   810, 887, 958,1024,  1145,1254,1355,1448, // xdelt = 32, 64
120 								  1619,1774,1911,2048,  2172,2290,2401,2508, // xdelt = 128
121 								  2611,2709,2804,2896,  2985,3072,3156,3238,
122 								  3318,3396,3473,3547,  3620,3692,3762,3831,
123 								  3899,3966,4031,4095};                // square root
124 	int inpc_winxxyy[4] = {0, xsize, 0, ysize};
125 	int win_xxyy[4]= {0, 1023, 0, 1023};
126 #endif
127     //MIN((eotf_u10+2)>>2,1023):
128     int eotf_u10[61] = {  0,   0,   1,   1,   1,    1,   2,   2,   2,  // xdelt = 1, 1
129 	                           3,   3,   4,   4,    5,   6,   7,   8,  // xdelt = 2, 4
130 	                          10,  12,  14,  16,   20,  24,  28,  32,  // xdelt = 8, 16
131 							  40,  48,  56,  64,   80,  96, 112, 128,  // xdelt = 32, 64
132 							 160, 192, 223, 256,  288, 320, 352, 384,  // xdelt = 128
133 							 416, 448, 480, 512,  544, 576, 608, 640,
134 							 672, 704, 736, 768,  800, 832, 864, 896,
135 							 928, 960, 992,1023};                      // linear one
136     //RTL CONTROL
137                                                   //REG_NAME: MD_TOP_GCLK
138     reg->reg_md_gclk           = 0;               // u32: clock gate control
139                                                     // end
140 
141                                                   //REG_NAME: MD_TOP_CTRL
142     reg->reg_md_top_ctrl           = 0x3c0204;       // u32: md top ntrol
143                                                   // end
144                                                //REG_NAME: MD_WR_CTRL0
145     reg->reg_wr_axi_wr_en         =1;            //u1:   axi wr enable
146     reg->reg_wr_axi_req_en        =1;            //u1:   axi request enable
147     reg->reg_wr_axi_bypass        =0;            //u1:   bypass axi wr
148     reg->reg_wr_total_size        =57600;    //u24:  pixels hsize * vsize
149                                                //end
150                                                //REG_NAME: MD_WR_CTRL1
151     reg->reg_wr_base_addr = 0x80000000;                       //u32:  wr axi base address
152                                                //end
153                                                //REG_NAME: MD_WR_CTRL2
154                                                //u9
155     reg->reg_wr_burst_lens= 2;                      //u3: burst_lens limiation, burst_size: 0: 1x128, 1: 2x128, 2��3: 4x128
156     reg->reg_wr_req_th = 4;                          //u4: fifo depth req_th * 8 *128 bits in fifo.  >=1
157     reg->reg_wr_urgent_ctrl = 0;                     //u16: urgent control, randome
158                                                //end
159                                                //REG_NAME: MD_WR_CTRL3
160     reg->reg_wr_awid = 0;                            //u8: wr id  ,random
161     reg->reg_wr_awprot = 0;                          //u3: awprot for security control,random
162                                                      //u21
163                                                      //end
164                                                    //REG_NAME:MD_RO_WR_ST0
165     reg->RO_wr_st0 = 0;	                           //u32
166                                                    //end
167                                                    //REG_NAME:MD_RO_WR_ST1
168     reg->RO_wr_st1 = 0;	                           //u32
169                                                    //end
170                                                    //REG_NAME:MD_RO_WR_ST2
171     reg->RO_wr_st2 = 0;                            //u32
172                                                    //end
173 
174                                               //REG_NAME: MD_RD_CTRL0
175     reg->reg_rd_axi_rd_en   =1;                //u1: axi rd enable
176     reg->reg_rd_axi_req_en  =1;                //u1: axi request enable
177                                               //u6
178     reg->reg_rd_total_size  = 57600;                //u24: total size hsize*vsize, <= 1024*1024
179                                               //end
180                                               //REG_NAME: MD_RD_CTRL1
181     reg->reg_rd_base_addr  =   0x80000000;                //u32
182                                               //end
183                                               //REG_NAME:MD_RD_CTRL2
184                                               //u9
185     reg->reg_rd_burst_lens  = 2 ;                //u3: burst_lens limiation, burst_size: 0: 1x128, 1: 2x128, 2��3: 4x128
186     reg->reg_rd_req_th      = 4 ;                //u4: fifo depth req_th * 8 *128 bits in fifo.
187     reg->reg_rd_urgent_ctrl = 0 ;                //u16: urgent control
188                                               //end
189                                               //REG_NAME:MD_RD_CTRL3
190     reg->reg_rd_arid          = 0 ;                //u8: wr id
191     reg->reg_rd_arprot         = 0;                //u3: awprot for security control
192                                                    //u21
193                                               //end
194                                               //REG_NAME:MD_RO_RD_ST0
195     reg->RO_rd_st0         =0  ;                //u32
196                                               //end
197                                               //REG_NAME:MD_RO_RD_ST1
198     reg->RO_rd_st1         =0  ;                //u32
199                                               //end
200 
201 
202     // cmodel control
203                                                   //REG_NAME: MD_INPUT_CTRL0
204 	reg->reg_md_enable         = 1;               //u1: lp motion detection enable, 0: disable;  1: enable
205 	reg->reg_md_raw_xphase_ofst= 0;               //u1: horizontal phase of the raw data, 0: start wz R-col (RGGB or GBRG); 1: start wz B-col (GRBG or BGGR)
206 	reg->reg_md_raw_yphase_ofst= 0;               //u1: vertical phase of the raw data,   0: start wz R-row (RGGB or GRBG); 1: start wz B-row (GRBG or BGGR)
207 	reg->reg_md_is_on_raw      = 1;               //u1: the md_sel is on raw data, set together with md_sel.    0: YUV/RGB;  1:RAW
208 
209     reg->reg_md_input_sel      = 1;               //u4: data selection for the lp motion detection. 0: raw sensor input; 1: raw WDR stitch; 2:raw fed_out(nr_in); 3:raw mirror_in; 4?? RGB after dms; 5: IRout; 6:RGB/YUV after gamma; 7: fe_o yuv bypass , default=1
210 
211 	reg->reg_md_input_ls       = 0;               //u4, E domain data left shift bit num to align with u20 Odomain data and will clip to u10 by droping 10lsb, e.g. yuv is u12, then ls = 8;
212                                                   //u20
213                                                   //end
214 
215                                                   //REG_NAME: MD_INPUT_SIZE
216                                                   //u3
217 	reg->reg_md_input_xsize    = 1920;           //u13, xsize of the input in pixels, set to image xsize
218                                                   //u3
219 	reg->reg_md_input_ysize    = 1080;           //u13, ysize of the input in pixels, set to image ysize
220                                                   //end
221 
222 	//step-I O domain reg_RGGB data do the black-level sub, gain, OETF
223 	//for (k=0;k<4;k++) {
224 	//	if (reg->reg_md_is_on_raw==1)
225 	//		reg->reg_md_inpc_winxxyy[k] = inpc_winxxyy[k]>>1;//u12x4, input combined window for processing.
226 	//	else
227     //		reg->reg_md_inpc_winxxyy[k] = inpc_winxxyy[k];   //u12x4, input combined window for processing.
228                                                //REG_NAME: MD_WINXY_0
229                                                //u4
230     reg->reg_md_inpc_winxxyy[0] = 0;           //u12, input combined window for processing. aligned to 2
231                                                //u4
232     reg->reg_md_inpc_winxxyy[1] = 960;         //u12, input combined window for processing.
233                                                //end
234                                                //REG_NAME: MD_WINXY_1
235                                                //u4
236     reg->reg_md_inpc_winxxyy[2] = 0;           //u12, input combined window for processing.
237                                                //u4
238     reg->reg_md_inpc_winxxyy[3] = 540;         //u12, input combined window for processing.
239                                                //end
240 
241                                                //REG_NAME: MD_RGGB_OFSET_0
242                                                //u12
243 		reg->reg_md_rggb_ofset[0]=    0;       //s20, ofset to the components, same as the ISP mission mode ofset
244                                                //end
245                                                //REG_NAME: MD_RGGB_OFSET_1
246                                                //u12
247 		reg->reg_md_rggb_ofset[1]=    0;       //s20, ofset to the components, same as the ISP mission mode ofset
248                                                //end
249                                                //REG_NAME: MD_RGGB_OFSET_2
250                                                //u12
251 		reg->reg_md_rggb_ofset[2]=    0;       //s20, ofset to the components, same as the ISP mission mode ofset
252                                                //end
253                                                //REG_NAME: MD_RGGB_OFSET_3
254                                                //u12
255 		reg->reg_md_rggb_ofset[3]=    0;       //s20, ofset to the components, same as the ISP mission mode ofset
256                                                //end
257 
258 
259 		//reg->reg_md_rggb_gain[k] = 1024;           //u12x4, gain to different channel, normalize to 1024 as "1.0"
260                                                    //REG_NAME: MD_RGGB_GAIN_0
261                                                    //u4
262 		reg->reg_md_rggb_gain[0] = 1024;           //u12, gain to different channel, normalize to 1024 as "1.0"
263                                                    //u4
264 		reg->reg_md_rggb_gain[1] = 1024;           //u12, gain to different channel, normalize to 1024 as "1.0"
265                                                    //end
266                                                    //REG_NAME: MD_RGGB_GAIN_1
267                                                    //u4
268 		reg->reg_md_rggb_gain[2] = 1024;           //u12, gain to different channel, normalize to 1024 as "1.0"
269                                                    //u4
270 		reg->reg_md_rggb_gain[3] = 1024;           //u12, gain to different channel, normalize to 1024 as "1.0"
271                                                    //end
272 		//reg->reg_md_bld_coefs[k] = bld_coefs[k];   //u8x4,  blender coef of the components to Y, normalize to 128 as "1"
273 
274                                                    //REG_NAME: MD_RGGB_COEF
275 		reg->reg_md_bld_coefs[0] = 32;             //u8,  blender coef of the components to Y, normalize to 128 as "1"
276 		reg->reg_md_bld_coefs[1] = 32;             //u8,  blender coef of the components to Y, normalize to 128 as "1"
277 		reg->reg_md_bld_coefs[2] = 32;             //u8,  blender coef of the components to Y, normalize to 128 as "1"
278 		reg->reg_md_bld_coefs[3] = 32;             //u8,  blender coef of the components to Y, normalize to 128 as "1"
279 	                                               //end
280 
281     //}
282     //for (k=0;k<61;k++)
283     //reg->reg_md_comb_eotf[k] = MIN((eotf_u12[k]+2)>>2, 1023);	        //u10x61,OETF, piece wise lut   TODO
284     for(k=0; k<20; k++) {
285                                                          //REG_NAME: MD_COMB_EOTF
286         reg->reg_md_comb_eotf[3*k]    = eotf_u10[3*k];   //u10, piec wise lut
287         reg->reg_md_comb_eotf[3*k+1]  = eotf_u10[3*k+1]; //u10, piec wise lut
288         reg->reg_md_comb_eotf[3*k+2]  = eotf_u10[3*k+2]; //u10, piec wise lut
289                                                          //u2
290                                                          //end
291     }
292     //for(k=20; k<21; k++) {
293                                                          //REG_NAME: MD_COMB_EOTF_20
294                                                          //u22
295         reg->reg_md_comb_eotf[60]    = eotf_u10[60];   //u10, piec wise lut
296                                                          //end
297     //}
298                                                    //REG_NAME: MD_EOTF
299                                                    //u30
300 	reg->reg_md_bld_use_max  = 0;                  //u1, use max of the components for the blender, 0: no max, 1:max (more sensitive)
301 	reg->reg_md_eotf_en      = 1;      	           //u1,OETF, piece wise lut enable
302                                                    //end
303 	//step-II the downscaled frame buffer size
304                                                    //REG_NAME: MD_DS_STEP
305                                                    //u12
306 	reg->reg_ds_hstep = 3;                         //u4: integer pixel ratio for horizontal scalar, o2i_ratio= 1/step, 1��15
307                                                    //u12
308     reg->reg_ds_vstep = 3;                         //u4: integer pixel ratio for vertical scalar,   o2i_ratio= 1/step??1��15
309                                                    //end
310 
311                                                    //REG_NAME: MD_DS_OSIZE
312                                                    //u4
313 	//reg->reg_ds_ocol  = (reg->reg_md_is_on_raw==1)? (xsize/2/reg->reg_ds_hstep+1):(xsize/reg->reg_ds_hstep+1);                      //u12: actual downscaled field buffer col number.
314     //<1024x1024
315 	reg->reg_ds_ocol  = 320;                       //u12: actual downscaled field buffer col number.
316                                                    //u4
317 	//reg->reg_ds_orow  = (reg->reg_md_is_on_raw==1)? (ysize/2/reg->reg_ds_vstep+1):(ysize/reg->reg_ds_vstep+1);                      //u12: actual downscaled field buffer row number.
318 	reg->reg_ds_orow  = 180;                      //u12: actual downscaled field buffer row number.
319 	                                              //end
320 
321                                                   //REG_NAME: MD_DS_CTRL
322                                                    //u21
323     reg->reg_ds_inp8b = 0;                         //u1, input to ds accum cell use 8bits instead of 10bits,only set to 1 when (v_step*h_step>64) 0: input 10bits, 1: input 8bits
324 	//reg->reg_ds_norm  = MIN(((reg->reg_ds_inp8b)? 4096:1024)/(reg->reg_ds_hstep*reg->reg_ds_vstep), 1023);                   //u10; normalization gain to the accum to get the 8bits data for ddr, norm = (inp8b? 4096:1024)/pixelnum(v_step*h_step)
325 	reg->reg_ds_norm  = 256;                      //u10; normalization gain to the accum to get the 8bits data for ddr, norm = (inp8b? 4096:1024)/pixelnum(v_step*h_step)
326                                                   //end
327 
328 
329     //step-III do the sad calculation and sum-up for RO
330                                                       //REG_NAME: MD_CORE_CTRL0
331                                                       //u4
332 	reg->reg_md_sad_mode   = 2;                       //u3,  window size for sad, 0: no sad, 1: 1x7,  2:3x3; 3:3x5, else 3x7
333 	reg->reg_md_edge_mode  = 0;                       //u1, mode for the pre and cur edge calculation, 0: min(edge_pre, edge_cur);  1: avg(edge_pre, edge_cur)
334 	reg->reg_md_coring     = 6;                       //u8, coring for sad for noise robustness. sad_core = max(sad-coring,0);
335                                                       //u2
336 	reg->reg_md_edge_ratio = 4;                       //u6, ratio to edge as dynamic coring part, final_coring or 1b_thrd = (edge*ratio + coring); norm to 16 as '1'
337                                                       //u8
338                                                       //end
339 	//for (k=0;k<4; k++)
340 	//reg->reg_md_win_xxyy[k] = win_xxyy[k];         //u8x4: window for motion sum statistics on down-scaled image. [x_st x_ed; y_st y_ed]*4
341 
342 	// set the win_xxyy, avoid the out of range
343     //if (reg->reg_md_is_on_raw==1)	{
344     //	reg->reg_md_win_xxyy[1] = xsize/2/(reg->reg_ds_hstep);
345     //    reg->reg_md_win_xxyy[3] = ysize/2/(reg->reg_ds_vstep);	}
346     //else{
347     //	reg->reg_md_win_xxyy[1] = xsize/(reg->reg_ds_hstep);
348     //    reg->reg_md_win_xxyy[3] = ysize/(reg->reg_ds_vstep);	}
349                                                      //REG_NAME: MD_WIN_XXYY0
350                                                      //u6
351     reg->reg_md_win_xxyy[0]  = 0;                    //u10 window for motion sum statistics on down-scaled image. [x_st x_ed; y_st y_ed]*4
352                                                      //u6
353     reg->reg_md_win_xxyy[1]  = 1023;                 //u10 window for motion sum statistics on down-scaled image. [x_st x_ed; y_st y_ed]*4
354                                                      //end
355                                                      //REG_NAME: MD_WIN_XXYY1
356                                                      //u6
357     reg->reg_md_win_xxyy[2]  = 0;                    //u10 window for motion sum statistics on down-scaled image. [x_st x_ed; y_st y_ed]*4
358                                                      //u6
359     reg->reg_md_win_xxyy[3]  = 1023;                 //u10 window for motion sum statistics on down-scaled image. [x_st x_ed; y_st y_ed]*4
360                                                      //end
361 
362 	// the output sum of motion, put to read-only registers
363                                                    //REG_NAME: RO_MD_SAD_SUM
364                                                    //u4
365 	reg->RO_md_sad_sum = 0;                        //u28, sum of the motion sad for all the pixels within the window;
366                                                    //end
367                                                    //REG_NAME: RO_MD_1BM_SUM
368                                                    //u12
369 	reg->RO_md_1bm_sum = 0;                        //u20, sum of the 1bit motion for all the pixels within the window;
370                                                    //end
371                                                    //REG_NAME: RO_MD_EDG_SUM
372                                                    //u4
373 	reg->RO_md_edg_sum = 0;                        //u28, sum of the edge info for all the pixels within the window;
374                                                    //end
375 
376 	// to HW decision on is_motion and send out interupt to CPU
377 	//valid_num = (reg->reg_md_win_xxyy[1]-reg->reg_md_win_xxyy[0]+ 1)*(reg->reg_md_win_xxyy[3]-reg->reg_md_win_xxyy[2] + 1)*16; //2^^24
378 	//reg->reg_ismot_sad_thrd = MIN(16*((valid_num*64)>>10),  (1<<24)-1);             //u24, threshold to sum_sad for current frame is motion
379                                                  //REG_NAME: MD_ISMOT_SAD_THRD
380                                                  //u8
381 	reg->reg_ismot_sad_thrd = 600;             //u24, threshold to sum_sad for current frame is motion
382                                                  //end
383                                                  //REG_NAME: MD_ISMOT_1BM_THRD
384                                                  //u16
385 	//reg->reg_ismot_1bm_thrd = MIN(((valid_num*64)>>10), (1<<16)-1)    ;             //u16, threshold to sum_1bm for current frame consider as motion
386 	reg->reg_ismot_1bm_thrd = 600;             //u16, threshold to sum_1bm for current frame consider as motion
387                                                  //end
388 
389     //added for new feature by Augustine
390                                                //REG_NAME: MD_WR_P_BADDR
391     reg->reg_wr_base_addr_p  = 0x80008000;     //u32,pre-pre base addr
392                                                //end
393 
394                                                //REG_NAME: MD_RD_P_BADDR
395     reg->reg_rd_base_addr_p  = 0x80008000;     //u32,pre-pre base addr
396                                                //end
397 
398     return 0;
399 }
400 
param_md_input(T_MD_PRM * reg,int hsize_i,int vsize_i,int in_sel)401 int param_md_input(T_MD_PRM *reg, int hsize_i, int vsize_i, int in_sel)
402 {
403     reg->reg_md_input_sel = in_sel;
404     reg->reg_md_input_xsize    = hsize_i;
405     reg->reg_md_input_ysize    = vsize_i;
406     if (reg->reg_md_input_sel>3) {
407         reg->reg_md_is_on_raw      = 0;
408         reg->reg_md_input_ls       = 8;
409         reg->reg_md_eotf_en        = 0; //do oe function
410     }
411 
412     return 0;
413 }
414 
param_md_scale(T_MD_PRM * reg,int hsize_i,int vsize_i,int hsize_o,int vsize_o,int32_t base_axi_addr)415 int param_md_scale(T_MD_PRM *reg, int hsize_i, int vsize_i, int hsize_o, int vsize_o, int32_t base_axi_addr)
416 {
417     reg->reg_ds_hstep =  (reg->reg_md_is_on_raw==1)?  hsize_i/2/hsize_o : hsize_i/hsize_o ;
418     reg->reg_ds_vstep =  (reg->reg_md_is_on_raw==1)?  vsize_i/2/vsize_o : vsize_i/vsize_o ;
419 
420     reg->reg_ds_ocol  = (reg->reg_md_is_on_raw==1)? (hsize_i/2/reg->reg_ds_hstep):(hsize_i/reg->reg_ds_hstep);
421     reg->reg_ds_orow  = (reg->reg_md_is_on_raw==1)? (vsize_i/2/reg->reg_ds_vstep):(vsize_i/reg->reg_ds_vstep);
422 
423     reg->reg_wr_base_addr  = base_axi_addr;     //u32,pre-pre base addr
424                                                //end
425 
426                                                //REG_NAME: MD_RD_P_BADDR
427     reg->reg_rd_base_addr  = base_axi_addr;     //u32,pre-pre base addr
428                                                //end
429     reg->reg_wr_total_size = reg->reg_ds_ocol * reg->reg_ds_orow;
430     reg->reg_rd_total_size = reg->reg_ds_ocol * reg->reg_ds_orow;
431 
432     return 0;
433 
434 }
435 
param_md_detect(T_MD_PRM * reg,int md_sad_thrd,int md_1bm_thrd)436 int param_md_detect(T_MD_PRM *reg, int md_sad_thrd, int md_1bm_thrd)
437 {
438     reg->reg_ismot_sad_thrd = md_sad_thrd;
439     reg->reg_ismot_1bm_thrd = md_1bm_thrd;
440     return 0;
441 }
442 
param_md_set(T_MD_PRM * reg)443 int param_md_set(T_MD_PRM *reg)
444 {
445     int k,sel;
446     sel = 0;
447     write_reg(MD_TOP_CTRL, reg->reg_md_top_ctrl);//          = 0x3c0204;
448     write_reg(MD_WR_CTRL0, (reg->reg_wr_axi_wr_en<<31)|
449                            (reg->reg_wr_axi_req_en<<30)|
450                            (reg->reg_wr_axi_bypass<<29)|
451                            (reg->reg_wr_total_size & 0xffffff));//        =57600;
452 
453     write_reg(MD_WR_CTRL1, reg->reg_wr_base_addr);// = 0x80000000;
454 
455     write_reg(MD_RD_CTRL0, (reg->reg_rd_axi_rd_en<<31)|
456                            (reg->reg_rd_axi_req_en<<30)|
457                            (reg->reg_rd_total_size & 0xffffff));//        =57600;
458 
459     write_reg(MD_RD_CTRL1, reg->reg_rd_base_addr);//  =   0x80000000;
460 
461     write_reg(MD_INPUT_SIZE,
462 	   ((reg->reg_md_input_xsize & 0x1fff) <<16) |
463 	    (reg->reg_md_input_ysize & 0x1fff));
464 
465     write_reg(MD_WINXY_0 ,
466       ((reg->reg_md_inpc_winxxyy[0] & 0x1fff)<<16) |
467       ((reg->reg_md_inpc_winxxyy[1] & 0x1fff)));
468 
469     write_reg(MD_WINXY_1,
470       ((reg->reg_md_inpc_winxxyy[2] & 0x1fff)<<16) |
471       ((reg->reg_md_inpc_winxxyy[3] & 0x1fff)));
472 
473     write_reg(MD_RGGB_OFSET_0 , reg->reg_md_rggb_ofset[0]);
474     write_reg(MD_RGGB_OFSET_1 , reg->reg_md_rggb_ofset[1]);
475     write_reg(MD_RGGB_OFSET_2 , reg->reg_md_rggb_ofset[2]);
476     write_reg(MD_RGGB_OFSET_3 , reg->reg_md_rggb_ofset[3]);
477 
478     write_reg(MD_RGGB_GAIN_0,
479 	  ((reg->reg_md_rggb_gain[0]  & 0xfff)<<16) |
480 	  ((reg->reg_md_rggb_gain[1]  & 0xfff)));
481 
482     write_reg(MD_RGGB_GAIN_1,
483 	  ((reg->reg_md_rggb_gain[2]  & 0xfff)<<16) |
484 	  ((reg->reg_md_rggb_gain[3]  & 0xfff)));
485 
486 
487     write_reg(MD_RGGB_COEF,
488       ((reg->reg_md_bld_coefs[0] & 0xff)<<24)|
489       ((reg->reg_md_bld_coefs[1] & 0xff)<<16)|
490       ((reg->reg_md_bld_coefs[2] & 0xff)<<18)|
491       ((reg->reg_md_bld_coefs[3] & 0xff)));
492 
493 
494     for(k=0; k<20; k++) {
495     write_reg(MD_COMB_EOTF_0 + k*4,
496        ((reg->reg_md_comb_eotf[3*k]    & 0x3ff) << 22)|
497        ((reg->reg_md_comb_eotf[3*k+1]  & 0x3ff) << 12)|
498        ((reg->reg_md_comb_eotf[3*k+2]  & 0x3ff) <<  2));
499 
500     }
501     write_reg(MD_COMB_EOTF_20, reg->reg_md_comb_eotf[60] & 0x3ff);
502 
503     write_reg(MD_EOTF,
504 	    (reg->reg_md_bld_use_max << 1) |
505 	     reg->reg_md_eotf_en);
506 
507     write_reg(MD_DS_STEP,
508 	    (reg->reg_ds_hstep << 16) |
509          reg->reg_ds_vstep);
510 
511     write_reg(MD_DS_OSIZE,
512 	    (reg->reg_ds_ocol << 16) |
513 	     reg->reg_ds_orow);
514 
515     write_reg(MD_DS_CTRL,
516         (reg->reg_ds_inp8b <<10)|
517 	     reg->reg_ds_norm);
518 
519     write_reg(MD_CORE_CTRL0,
520         ((reg->reg_md_sad_mode & 0x7)<<25) |
521 	    ((reg->reg_md_edge_mode & 0x1) << 24) |
522 	    ((reg->reg_md_coring & 0xff) <<16) |
523 	    ((reg->reg_md_edge_ratio & 0x3f) << 8));
524 
525     write_reg(MD_WIN_XXYY0 ,
526       ((reg->reg_md_win_xxyy[0] & 0x3ff)<<16) |
527       ((reg->reg_md_win_xxyy[1] & 0x3ff)));
528 
529     write_reg(MD_WIN_XXYY1,
530       ((reg->reg_md_win_xxyy[2] & 0x3ff)<<16) |
531       ((reg->reg_md_win_xxyy[3] & 0x3ff)));
532 
533 
534 	write_reg(MD_ISMOT_SAD_THRD, reg->reg_ismot_sad_thrd);// = 65536;d
535 	write_reg(MD_ISMOT_1BM_THRD, reg->reg_ismot_1bm_thrd);// = 4096;
536     write_reg(MD_WR_P_BADDR, reg->reg_wr_base_addr_p);// = 0x80008000;
537     write_reg(MD_RD_P_BADDR, reg->reg_rd_base_addr_p);// = 0x80008000;
538 
539 
540     write_reg(MD_INPUT_CTRL0,
541         ((reg->reg_md_enable           & 0x1) <<31)|
542         ((reg->reg_md_raw_xphase_ofst  & 0x1) <<30)|
543         ((reg->reg_md_raw_yphase_ofst  & 0x1) <<29)|
544         ((reg->reg_md_is_on_raw        & 0x1) <<28)|
545         ((reg->reg_md_input_sel        & 0xf) <<24)|
546         ((reg->reg_md_input_ls         & 0xf) <<20));
547 
548     return 0;
549 }
550 
motion_detection_isr(int irq,void * para)551 static irqreturn_t motion_detection_isr(int irq, void *para)
552 {
553     pr_err("Motion detection event\n");
554 
555 	return IRQ_HANDLED;
556 }
557 
am_md_parse_dt(struct device_node * node)558 int am_md_parse_dt(struct device_node *node)
559 {
560 	int rtn = -1;
561 	int irq = -1;
562 	struct resource rs;
563 	struct am_md *t_md = NULL;
564 
565 	if (node == NULL) {
566 		pr_err("%s: Error input param\n", __func__);
567 		return -1;
568 	}
569 
570 	rtn = of_device_is_compatible(node, AM_MD_NAME);
571 	if (rtn == 0) {
572 		pr_err("%s: Error match compatible\n", __func__);
573 		return -1;
574 	}
575 
576 	t_md = kzalloc(sizeof(*t_md), GFP_KERNEL);
577 	if (t_md == NULL) {
578 		pr_err("%s: Failed to alloc isp-md\n", __func__);
579 		return -1;
580 	}
581 
582 	t_md->of_node = node;
583 
584 	rtn = of_address_to_resource(node, 0, &rs);
585 	if (rtn != 0) {
586 		pr_err("%s:Error get isp-md reg resource\n", __func__);
587 		goto reg_error;
588 	}
589 
590 	pr_info("%s: rs idx info: name: %s\n", __func__, rs.name);
591 	if (strcmp(rs.name, "isp_md") == 0) {
592 		t_md->reg = rs;
593 #if (LINUX_VERSION_CODE <= KERNEL_VERSION(4, 19, 0))
594         t_md->base_addr = ioremap_nocache(t_md->reg.start, resource_size(&t_md->reg));
595 #else
596         t_md->base_addr = ioremap(t_md->reg.start, resource_size(&t_md->reg));
597 #endif
598 	}
599 
600 	irq = irq_of_parse_and_map(node, 0);
601 	if (irq <= 0) {
602 		pr_err("%s:Error get isp_md irq\n", __func__);
603 		goto irq_error;
604 	}
605 
606 	t_md->irq = irq;
607 	pr_info("%s:rs info: irq: %d\n", __func__, t_md->irq);
608 
609 	t_md->p_dev = of_find_device_by_node(node);
610 
611 	g_md = t_md;
612 
613 	return 0;
614 irq_error:
615 	iounmap(t_md->base_addr);
616 	t_md->base_addr = NULL;
617 
618 reg_error:
619 	if (t_md != NULL)
620 		kfree(t_md);
621 
622 	return -1;
623 }
624 
am_md_init(void)625 void am_md_init(void)
626 {
627 	int ret = 0;
628 
629     param_md_init(&am_md_reg);
630 	param_md_input(&am_md_reg, 1920, 1080, 1);
631 	param_md_scale(&am_md_reg, 1920, 1080, 480, 270, AM_MD_MEMORY);
632 	param_md_set(&am_md_reg);
633 
634 	ret = request_irq(g_md->irq, motion_detection_isr, IRQF_SHARED | IRQF_TRIGGER_RISING,
635 		"isp-md-irq", (void *)g_md);
636 
637 	return;
638 }
639 
am_md_deinit(void)640 void am_md_deinit(void)
641 {
642 	if (g_md == NULL) {
643 		pr_err("Error g_md is NULL\n");
644 		return;
645 	}
646 
647 	if (g_md->base_addr != NULL)
648 	{
649 		iounmap(g_md->base_addr);
650 		g_md->base_addr = NULL;
651 	}
652 
653     if(g_md->irq)
654 	    free_irq(g_md->irq, NULL);
655 
656 	if(g_md)
657 	{
658 	    kfree(g_md);
659 		g_md = NULL;
660 	}
661 }
662