freescale R10 ipu lib 分析 - ipu_device.c

转载 2012年03月23日 20:57:28

转:http://blog.csdn.net/kickxxx/article/details/6561804

ipu_device.c

这个文件创建了一个mxc_ipu字符设备节点,目的是为了ipu lib服务的,主要函数就是mxc_ipu_ioctl,  app可以利用ipu lib实现如下功能:

  1. Resize
  2. Rotation
  3. Color space/format convert
  4. Overlay combination with the same size which supports color ker and alpha blending
  5. Output display to frame buffer directly after IPU process
  6. Two outputs processed form one input
  7. Windows crop
  8. Local alpha blending

 

474 int register_ipu_device()
475 {
476     int ret = 0;
477     struct device *temp;
478     mxc_ipu_major = register_chrdev(0, "mxc_ipu", &mxc_ipu_fops);
.................
510 }

 

478注册一个字符设备,应用通过/dev/mxc_ipu这个设备节点,操作IPU的channel,实现上述功能

 

 87 static int mxc_ipu_ioctl(struct inode *inode, struct file *file,
 88         unsigned int cmd, unsigned long arg)
 89 {
 90     int ret = 0;
 91 
 92     switch (cmd) {
 93     case IPU_INIT_CHANNEL:
 94         {
 95             ipu_channel_parm parm;
 96 
 97             if (copy_from_user
 98                     (&parm, (ipu_channel_parm *) arg,
 99                      sizeof(ipu_channel_parm)))
100                 return -EFAULT;
101 
102             if (!parm.flag) {
103                 ret =
104                     ipu_init_channel(parm.channel,
105                             &parm.params);
106             } else {
107                 ret = ipu_init_channel(parm.channel, NULL);
108             }
109         }
110         break;
111     case IPU_UNINIT_CHANNEL:
112         {
113         ipu_channel_t ch;
114         int __user *argp = (void __user *)arg;
115         if (get_user(ch, argp))
116                 return -EFAULT;
117             ipu_uninit_channel(ch);
118         }
119         break;
120     case IPU_INIT_CHANNEL_BUFFER:
121         {
122             ipu_channel_buf_parm parm;
123             if (copy_from_user
124                 (&parm, (ipu_channel_buf_parm *) arg,
125                 sizeof(ipu_channel_buf_parm)))
126                 return -EFAULT;
127 
128             ret =
129                 ipu_init_channel_buffer(
130                         parm.channel, parm.type,
131                         parm.pixel_fmt,
132                         parm.width, parm.height,
133                         parm.stride,
134                         parm.rot_mode,
135                         parm.phyaddr_0,
136                         parm.phyaddr_1,
137                         parm.u_offset,
138                         parm.v_offset);
139 
140         }
141         break;
142     case IPU_UPDATE_CHANNEL_BUFFER:
143         {
144             ipu_channel_buf_parm parm;
145             if (copy_from_user
146                 (&parm, (ipu_channel_buf_parm *) arg,
147                 sizeof(ipu_channel_buf_parm)))
148                 return -EFAULT;
149 
150             if ((parm.phyaddr_0 != (dma_addr_t) NULL)
151                 && (parm.phyaddr_1 == (dma_addr_t) NULL)) {
152                 ret =
153                     ipu_update_channel_buffer(
154                             parm.channel,
155                             parm.type,
156                             parm.bufNum,
157                             parm.phyaddr_0);
158             } else if ((parm.phyaddr_0 == (dma_addr_t) NULL)
159                 && (parm.phyaddr_1 != (dma_addr_t) NULL)) {
160                 ret =
161                     ipu_update_channel_buffer(
162                             parm.channel,
163                             parm.type,
164                             parm.bufNum,
165                             parm.phyaddr_1);
166             } else {
167                 ret = -1;
168             }
169 
170         }
171         break;
172     case IPU_SELECT_CHANNEL_BUFFER:
173         {
174             ipu_channel_buf_parm parm;
175             if (copy_from_user
176                 (&parm, (ipu_channel_buf_parm *) arg,
177                 sizeof(ipu_channel_buf_parm)))
178                 return -EFAULT;
179 
180             ret =
181                 ipu_select_buffer(parm.channel,
182                     parm.type, parm.bufNum);
183 
184         }
185         break;
186     case IPU_SELECT_MULTI_VDI_BUFFER:
187         {
188             uint32_t parm;
189             if (copy_from_user
190                 (&parm, (uint32_t *) arg,
191                 sizeof(uint32_t)))
192                 return -EFAULT;
193 
194             ret = ipu_select_multi_vdi_buffer(parm);
195         }
196         break;
197     case IPU_LINK_CHANNELS:
198         {
199             ipu_channel_link link;
200             if (copy_from_user
201                 (&link, (ipu_channel_link *) arg,
202                 sizeof(ipu_channel_link)))
203                 return -EFAULT;
204 
205             ret = ipu_link_channels(link.src_ch,
206                 link.dest_ch);
207 
208         }
209         break;
210     case IPU_UNLINK_CHANNELS:
211         {
212             ipu_channel_link link;
213             if (copy_from_user
214                 (&link, (ipu_channel_link *) arg,
215                 sizeof(ipu_channel_link)))
216                 return -EFAULT;
217 
218             ret = ipu_unlink_channels(link.src_ch,
219                 link.dest_ch);
220 
221         }
222         break;
223     case IPU_ENABLE_CHANNEL:
224         {
225             ipu_channel_t ch;
226             int __user *argp = (void __user *)arg;
227             if (get_user(ch, argp))
228                 return -EFAULT;
229             ipu_enable_channel(ch);
230         }
231         break;
232     case IPU_DISABLE_CHANNEL:
233         {
234             ipu_channel_info info;
235             if (copy_from_user
236                 (&info, (ipu_channel_info *) arg,
237                  sizeof(ipu_channel_info)))
238                 return -EFAULT;
239 
240             ret = ipu_disable_channel(info.channel,
241                 info.stop);
242         }
243         break;
244     case IPU_ENABLE_IRQ:
245         {
246             uint32_t irq;
247             int __user *argp = (void __user *)arg;
248             if (get_user(irq, argp))
249                 return -EFAULT;
250             ipu_enable_irq(irq);
251         }
252         break;
253     case IPU_DISABLE_IRQ:
254         {
255             uint32_t irq;
256             int __user *argp = (void __user *)arg;
257             if (get_user(irq, argp))
258                 return -EFAULT;
259             ipu_disable_irq(irq);
260         }
261         break;
262     case IPU_CLEAR_IRQ:
263         {
264             uint32_t irq;
265             int __user *argp = (void __user *)arg;
266             if (get_user(irq, argp))
267                 return -EFAULT;
268             ipu_clear_irq(irq);
269         }
270         break;
271     case IPU_FREE_IRQ:
272         {
273             ipu_irq_info info;
274 
275             if (copy_from_user
276                     (&info, (ipu_irq_info *) arg,
277                      sizeof(ipu_irq_info)))
278                 return -EFAULT;
279 
280             ipu_free_irq(info.irq, info.dev_id);
281             irq_info[info.irq].irq_pending = 0;
282         }
283         break;
284     case IPU_REQUEST_IRQ_STATUS:
285         {
286             uint32_t irq;
287             int __user *argp = (void __user *)arg;
288             if (get_user(irq, argp))
289                 return -EFAULT;
290             ret = ipu_get_irq_status(irq);
291         }
292         break;
293     case IPU_REGISTER_GENERIC_ISR:
294         {
295             ipu_event_info info;
296             if (copy_from_user
297                     (&info, (ipu_event_info *) arg,
298                      sizeof(ipu_event_info)))
299                 return -EFAULT;
300 
301             ret =
302                 ipu_request_irq(info.irq,
303                     mxc_ipu_generic_handler,
304                     0, "video_sink", info.dev);
305             if (ret == 0)
306                 init_waitqueue_head(&(irq_info[info.irq].waitq));
307         }
308         break;
309     case IPU_GET_EVENT:
310         /* User will have to allocate event_type
311         structure and pass the pointer in arg */
312         {
313             ipu_event_info info;
314             int r = -1;
315 
316             if (copy_from_user
317                     (&info, (ipu_event_info *) arg,
318                      sizeof(ipu_event_info)))
319                 return -EFAULT;
320 
321             r = get_events(&info);
322             if (r == -1) {
323                 if ((file->f_flags & O_NONBLOCK) &&
324                     (irq_info[info.irq].irq_pending == 0))
325                     return -EAGAIN;
326                 wait_event_interruptible_timeout(irq_info[info.irq].waitq,
327                         (irq_info[info.irq].irq_pending != 0), 2 * HZ);
328                 r = get_events(&info);
329             }
330             ret = -1;
331             if (r == 0) {
332                 if (!copy_to_user((ipu_event_info *) arg,
333                     &info, sizeof(ipu_event_info)))
334                     ret = 0;
335             }
336         }
337         break;
338     case IPU_ALOC_MEM:
339         {
340             ipu_mem_info info;
341             if (copy_from_user
342                     (&info, (ipu_mem_info *) arg,
343                      sizeof(ipu_mem_info)))
344                 return -EFAULT;
345 
346             info.vaddr = dma_alloc_coherent(0,
347                     PAGE_ALIGN(info.size),
348                     &info.paddr,
349                     GFP_DMA | GFP_KERNEL);
350             if (info.vaddr == 0) {
351                 printk(KERN_ERR "dma alloc failed!/n");
352                 return -ENOBUFS;
353             }
354             if (copy_to_user((ipu_mem_info *) arg, &info,
355                     sizeof(ipu_mem_info)) > 0)
356                 return -EFAULT;
357         }
358         break;
359     case IPU_FREE_MEM:
360         {
361             ipu_mem_info info;
362             if (copy_from_user
363                     (&info, (ipu_mem_info *) arg,
364                      sizeof(ipu_mem_info)))
365                 return -EFAULT;
366 
367             if (info.vaddr)
368                 dma_free_coherent(0, PAGE_ALIGN(info.size),
369                     info.vaddr, info.paddr);
370             else
371                 return -EFAULT;
372         }
373         break;
374     case IPU_IS_CHAN_BUSY:
375         {
376             ipu_channel_t chan;
377             if (copy_from_user
378                     (&chan, (ipu_channel_t *)arg,
379                      sizeof(ipu_channel_t)))
380                 return -EFAULT;
381 
382             if (ipu_is_channel_busy(chan))
383                 ret = 1;
384             else
385                 ret = 0;
386         }
387         break;
388     case IPU_CALC_STRIPES_SIZE:
389         {
390             ipu_stripe_parm stripe_parm;
391 
392             if (copy_from_user (&stripe_parm, (ipu_stripe_parm *)arg,
393                      sizeof(ipu_stripe_parm)))
394                 return -EFAULT;
395             ipu_calc_stripes_sizes(stripe_parm.input_width,
396                         stripe_parm.output_width,
397                         stripe_parm.maximal_stripe_width,
398                         stripe_parm.cirr,
399                         stripe_parm.equal_stripes,
400                         stripe_parm.input_pixelformat,
401                         stripe_parm.output_pixelformat,
402                         &stripe_parm.left,
403                         &stripe_parm.right);
404             if (copy_to_user((ipu_stripe_parm *) arg, &stripe_parm,
405                     sizeof(ipu_stripe_parm)) > 0)
406                 return -EFAULT;
407         }
408         break;
409     case IPU_UPDATE_BUF_OFFSET:
410         {
411             ipu_buf_offset_parm offset_parm;
412 
413             if (copy_from_user (&offset_parm, (ipu_buf_offset_parm *)arg,
414                      sizeof(ipu_buf_offset_parm)))
415                 return -EFAULT;
416             ret = ipu_update_channel_offset(offset_parm.channel,
417                             offset_parm.type,
418                             offset_parm.pixel_fmt,
419                             offset_parm.width,
420                             offset_parm.height,
421                             offset_parm.stride,
422                             offset_parm.u_offset,
423                             offset_parm.v_offset,
424                             offset_parm.vertical_offset,
425                             offset_parm.horizontal_offset);
426         }
427         break;
428     case IPU_CSC_UPDATE:
429         {
430             int param[5][3];
431             ipu_csc_update csc;
432             if (copy_from_user(&csc, (void *) arg,
433                        sizeof(ipu_csc_update)))
434                 return -EFAULT;
435             if (copy_from_user(&param[0][0], (void *) csc.param,
436                        sizeof(param)))
437                 return -EFAULT;
438             ipu_set_csc_coefficients(csc.channel, param);
439         }
440         break;
441     default:
442         break;
443     }
444     return ret;
445 }

 

这个函数很长,很简单,都是对ipu common函数的封装,先去分析ipu_common.c

freescale R10 ipu lib 分析 - ipu_common.c

ipu_common.c Common IPU API implementation,主要是为MXC V4L2和ipu device驱动提供IPU channel控制函数  110 static in...
  • kickxxx
  • kickxxx
  • 2011年06月24日 11:09
  • 5241

freescale R10 ipu lib 分析 - ipu_capture.c

ipu_capture.c 47 int32_t 48 ipu_csi_init_interface(uint16_t width, uint16_t height, uint32_t pixel_f...
  • kickxxx
  • kickxxx
  • 2011年06月22日 10:39
  • 3700

freescale R10 ipu lib 分析 - ipu_ic.c

 45 void _ipu_vdi_set_top_field_man(bool top_field_0) 46 { 47     uint32_t reg; 48  49     reg = __r...
  • kickxxx
  • kickxxx
  • 2011年06月27日 14:09
  • 2930

freescale R10 ipu lib 分析 - ipu_param_mem.h

ipu_param_mem.h  21 struct ipu_ch_param_word { 22     uint32_t data[5]; 23     uint32_t res[3]; 24 }...
  • kickxxx
  • kickxxx
  • 2011年06月24日 16:35
  • 3287

7.1 ipu_device.c分析(一)---流程分析

在ipu_common.c文件的ipu_probe函数中,最后调用到register_ipu_device函数,这个函数在ipu_device.c中,所以从这个文件开始分析。 这个文件中主要是两个内...

4.1 ipu_common.c分析---入口函数及probe函数分析

这个ipu_common.c函数提供ipu底层函数调用的一些关系和函数。 (一)分析这个文件从init函数入口,发现有这个subsys_initcall,说明ipu是作为一个子系统注册到内核中的: ...

4.2 ipu_init_channel函数的详细分析

在看这个函数之前,先对ipu内部的channel有所了解,先来看看ipu内部的flow的定义: 对于每个flow,代表数据从摄像头采集到显示(或者保存在内存中)的过程中的一个分步骤,...

dts文件分析---以ov5640为例,修改dts文件使ov5640使用第二个IPU

在ARMlinux中,每一个.dts文件都对应一个ARM的machine,这些文件都放在arch/arm/boot/dts文件夹中。同时,对于每一个SoC可能对应多个machine,这些dts文件中会...

IPU显示总结文档pdf

  • 2016年10月05日 11:08
  • 2.74MB
  • 下载

IPU总结报告v1.0

  • 2016年08月24日 20:01
  • 50.76MB
  • 下载
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:freescale R10 ipu lib 分析 - ipu_device.c
举报原因:
原因补充:

(最多只允许输入30个字)