vm.c 37 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410
  1. /*******************************************************************
  2. *
  3. * Copyright C 2010 by Amlogic, Inc. All Rights Reserved.
  4. *
  5. * Description:
  6. *
  7. * Author: Amlogic Software
  8. * Created: 2010/4/1 19:46
  9. *
  10. *******************************************************************/
  11. #include <linux/kernel.h>
  12. #include <linux/types.h>
  13. #include <linux/errno.h>
  14. #include <linux/interrupt.h>
  15. #include <linux/timer.h>
  16. #include <linux/time.h>
  17. #include <linux/vout/vinfo.h>
  18. #include <linux/vout/vout_notify.h>
  19. #include <linux/platform_device.h>
  20. #include <linux/amports/ptsserv.h>
  21. #include <linux/amports/canvas.h>
  22. #include <linux/amports/vframe.h>
  23. #include <linux/amports/vframe_provider.h>
  24. #include <linux/amports/vframe_receiver.h>
  25. #include <mach/am_regs.h>
  26. #include <linux/amlog.h>
  27. #include <linux/ge2d/ge2d_main.h>
  28. #include <linux/ge2d/ge2d.h>
  29. #include <linux/kthread.h>
  30. #include <linux/delay.h>
  31. #include <linux/semaphore.h>
  32. #include <linux/sched.h>
  33. #include <linux/platform_device.h>
  34. #include <linux/ge2d/ge2d_main.h>
  35. #include <linux/ge2d/ge2d.h>
  36. #include "vm_log.h"
  37. #include "vm.h"
  38. #include <linux/amlog.h>
  39. #include <linux/ctype.h>
  40. #include <linux/io.h>
  41. #include <linux/videodev2.h>
  42. #include <media/videobuf-core.h>
  43. #include <media/videobuf-dma-contig.h>
  44. #include <media/videobuf-vmalloc.h>
  45. #include <media/videobuf-dma-sg.h>
  46. #include <media/amlogic/656in.h>
  47. #include <linux/ctype.h>
  48. /*class property info.*/
  49. #include "vmcls.h"
  50. static int task_running = 0;
  51. #ifdef CONFIG_ARCH_MESON6
  52. #define GE2D_NV
  53. #endif
  54. #if 0
  55. static unsigned amlvm_time_log_enable = 0;
  56. module_param(amlvm_time_log_enable, uint, 0644);
  57. MODULE_PARM_DESC(amlvm_time_log_enable, "enable vm time log when get frames");
  58. #endif
  59. #define MAGIC_SG_MEM 0x17890714
  60. #define MAGIC_DC_MEM 0x0733ac61
  61. #define MAGIC_VMAL_MEM 0x18221223
  62. #define VIDTYPE_3D_LR 0x10000
  63. #define VIDTYPE_3D_BT 0x20000
  64. #define MAX_VM_POOL_SIZE 8
  65. #define MAX_VF_POOL_SIZE 8
  66. /*same as tvin pool*/
  67. static int VM_POOL_SIZE = 6 ;
  68. static int VF_POOL_SIZE = 6;
  69. static int VM_CANVAS_INDEX = 24;
  70. /*same as tvin pool*/
  71. static int vm_skip_count = 0 ; //skip 5 frames from vdin
  72. static int test_zoom = 0;
  73. static inline void vm_vf_put_from_provider(vframe_t *vf);
  74. #define INCPTR(p) ptr_atomic_wrap_inc(&p)
  75. #define VM_DEPTH_16_CANVAS 0x50 //for single canvas use ,RGB16, YUV422,etc
  76. #define VM_DEPTH_24_CANVAS 0x52
  77. #define VM_DEPTH_8_CANVAS_Y 0x54 // for Y/CbCr 4:2:0
  78. #define VM_DEPTH_8_CANVAS_UV 0x55
  79. #define VM_DEPTH_8_CANVAS_U 0x57
  80. #define VM_DEPTH_8_CANVAS_V 0x58
  81. #define VM_DMA_CANVAS_INDEX 0x5e
  82. #define VM_CANVAS_MX 0x5f
  83. static int vmdecbuf_size[] ={
  84. 0xE79C00,//5M
  85. 0x900000,//3M
  86. 0x591000,//2M
  87. 0x384000,//1M3
  88. 0x240000,//1M
  89. 0xE1000,//VGA
  90. 0x3C000,//QVGA
  91. };
  92. static struct v4l2_frmsize_discrete canvas_config_wh[]={
  93. {2592,1952},
  94. {2048,1536},
  95. {1600,1216},
  96. {1280,960},
  97. {1024,768},
  98. {640,480},
  99. {320,256},
  100. };
  101. #define GE2D_ENDIAN_SHIFT 24
  102. #define GE2D_ENDIAN_MASK (0x1 << GE2D_ENDIAN_SHIFT)
  103. #define GE2D_BIG_ENDIAN (0 << GE2D_ENDIAN_SHIFT)
  104. #define GE2D_LITTLE_ENDIAN (1 << GE2D_ENDIAN_SHIFT)
  105. #define PROVIDER_NAME "vm"
  106. #define RECEIVER_NAME "vm"
  107. static DEFINE_SPINLOCK(lock);
  108. static inline void ptr_atomic_wrap_inc(u32 *ptr)
  109. {
  110. u32 i = *ptr;
  111. i++;
  112. if (i >= VM_POOL_SIZE)
  113. i = 0;
  114. *ptr = i;
  115. }
  116. int start_vm_task(void) ;
  117. int start_simulate_task(void);
  118. static struct vframe_s vfpool[MAX_VF_POOL_SIZE];
  119. /*static u32 vfpool_idx[MAX_VF_POOL_SIZE];*/
  120. static s32 vfbuf_use[MAX_VF_POOL_SIZE];
  121. static s32 fill_ptr, get_ptr, putting_ptr, put_ptr;
  122. struct semaphore vb_start_sema;
  123. struct semaphore vb_done_sema;
  124. static inline vframe_t *vm_vf_get_from_provider(void);
  125. static inline vframe_t *vm_vf_peek_from_provider(void);
  126. static inline void vm_vf_put_from_provider(vframe_t *vf);
  127. static vframe_receiver_op_t* vf_vm_unreg_provider(void);
  128. static vframe_receiver_op_t* vf_vm_reg_provider(void);
  129. static void stop_vm_task(void) ;
  130. static int prepare_vframe(vframe_t *vf);
  131. /************************************************
  132. *
  133. * buffer op for video sink.
  134. *
  135. *************************************************/
  136. static inline u32 index2canvas(u32 index)
  137. {
  138. int i;
  139. int start_canvas, count;
  140. u32 canvas_tab[6] ;
  141. get_tvin_canvas_info(&start_canvas,&count);
  142. VM_POOL_SIZE = count ;
  143. VF_POOL_SIZE = count ;
  144. VM_CANVAS_INDEX = start_canvas;
  145. for(i =0; i< count; i++)
  146. canvas_tab[i] = VM_CANVAS_INDEX +i;
  147. return canvas_tab[index];
  148. }
  149. static struct vframe_s* vm_vf_peek(void *op_arg)
  150. {
  151. vframe_t *vf = NULL;
  152. vf = vm_vf_peek_from_provider();
  153. if(vf){
  154. if(vm_skip_count > 0){
  155. vm_skip_count--;
  156. vm_vf_get_from_provider();
  157. vm_vf_put_from_provider(vf);
  158. vf = NULL;
  159. }
  160. }
  161. return vf;
  162. }
  163. static struct vframe_s* vm_vf_get(void *op_arg)
  164. {
  165. return vm_vf_get_from_provider();
  166. }
  167. static void vm_vf_put(vframe_t *vf, void* op_arg)
  168. {
  169. prepare_vframe(vf);
  170. }
  171. static int vm_vf_states(vframe_states_t *states, void* op_arg)
  172. {
  173. return 0;
  174. }
  175. static vframe_t *local_vf_peek(void)
  176. {
  177. if (get_ptr == fill_ptr)
  178. return NULL;
  179. return &vfpool[get_ptr];
  180. }
  181. static vframe_t *local_vf_get(void)
  182. {
  183. vframe_t *vf;
  184. if (get_ptr == fill_ptr)
  185. return NULL;
  186. vf = &vfpool[get_ptr];
  187. INCPTR(get_ptr);
  188. return vf;
  189. }
  190. static void local_vf_put(vframe_t *vf)
  191. {
  192. int i;
  193. int canvas_addr;
  194. if(!vf)
  195. return;
  196. INCPTR(putting_ptr);
  197. for (i = 0; i < VF_POOL_SIZE; i++) {
  198. canvas_addr = index2canvas(i);
  199. if(vf->canvas0Addr == canvas_addr ){
  200. vfbuf_use[i] = 0;
  201. vm_vf_put_from_provider(vf);
  202. }
  203. }
  204. }
  205. /*static int local_vf_states(vframe_states_t *states)
  206. {
  207. unsigned long flags;
  208. int i;
  209. spin_lock_irqsave(&lock, flags);
  210. states->vf_pool_size = VF_POOL_SIZE;
  211. i = put_ptr - fill_ptr;
  212. if (i < 0) i += VF_POOL_SIZE;
  213. states->buf_free_num = i;
  214. i = putting_ptr - put_ptr;
  215. if (i < 0) i += VF_POOL_SIZE;
  216. states->buf_recycle_num = i;
  217. i = fill_ptr - get_ptr;
  218. if (i < 0) i += VF_POOL_SIZE;
  219. states->buf_avail_num = i;
  220. spin_unlock_irqrestore(&lock, flags);
  221. return 0;
  222. }*/
  223. static int vm_receiver_event_fun(int type, void *data, void *private_data)
  224. {
  225. switch(type){
  226. case VFRAME_EVENT_PROVIDER_VFRAME_READY:
  227. //up(&vb_start_sema);
  228. //printk("vdin frame ready !!!!!\n");
  229. break;
  230. case VFRAME_EVENT_PROVIDER_START:
  231. //printk("vm register!!!!!\n");
  232. vf_vm_reg_provider();
  233. vm_skip_count = 0;
  234. test_zoom = 0;
  235. break;
  236. case VFRAME_EVENT_PROVIDER_UNREG:
  237. //printk("vm unregister!!!!!\n");
  238. vm_local_init();
  239. vf_vm_unreg_provider();
  240. //printk("vm unregister succeed!!!!!");
  241. break;
  242. default:
  243. break;
  244. }
  245. return 0;
  246. }
  247. static vframe_receiver_op_t vm_vf_receiver =
  248. {
  249. .event_cb = vm_receiver_event_fun
  250. };
  251. static const struct vframe_operations_s vm_vf_provider =
  252. {
  253. .peek = vm_vf_peek,
  254. .get = vm_vf_get,
  255. .put = vm_vf_put,
  256. .vf_states = vm_vf_states,
  257. };
  258. static struct vframe_provider_s vm_vf_prov;
  259. static struct vframe_receiver_s vm_vf_recv;
  260. int get_unused_vm_index(void)
  261. {
  262. int i;
  263. for (i = 0; i < VF_POOL_SIZE; i++){
  264. if(vfbuf_use[i] == 0)
  265. return i;
  266. }
  267. return -1;
  268. }
  269. static int prepare_vframe(vframe_t *vf)
  270. {
  271. vframe_t* new_vf;
  272. int index;
  273. index = get_unused_vm_index();
  274. if(index < 0)
  275. return -1;
  276. new_vf = &vfpool[fill_ptr];
  277. memcpy(new_vf, vf, sizeof(vframe_t));
  278. vfbuf_use[index]++;
  279. INCPTR(fill_ptr);
  280. return 0;
  281. }
  282. /*************************************************
  283. *
  284. * buffer op for decoder, camera, etc.
  285. *
  286. *************************************************/
  287. /* static const vframe_provider_t *vfp = NULL; */
  288. void vm_local_init(void)
  289. {
  290. int i;
  291. for(i=0;i<MAX_VF_POOL_SIZE;i++)
  292. {
  293. vfbuf_use[i] = 0;
  294. }
  295. fill_ptr=get_ptr=putting_ptr=put_ptr=0;
  296. }
  297. static vframe_receiver_op_t* vf_vm_unreg_provider(void)
  298. {
  299. // ulong flags;
  300. vf_unreg_provider(&vm_vf_prov);
  301. stop_vm_task();
  302. // spin_lock_irqsave(&lock, flags);
  303. // vfp = NULL;
  304. // spin_unlock_irqrestore(&lock, flags);
  305. return (vframe_receiver_op_t*)NULL;
  306. }
  307. EXPORT_SYMBOL(vf_vm_unreg_provider);
  308. static vframe_receiver_op_t* vf_vm_reg_provider( )
  309. {
  310. ulong flags;
  311. spin_lock_irqsave(&lock, flags);
  312. spin_unlock_irqrestore(&lock, flags);
  313. vm_buffer_init();
  314. vf_reg_provider(&vm_vf_prov);
  315. start_vm_task();
  316. #if 0
  317. start_simulate_task();
  318. #endif
  319. return &vm_vf_receiver;
  320. }
  321. EXPORT_SYMBOL(vf_vm_reg_provider);
  322. /*static const struct vframe_provider_s * vm_vf_get_vfp_from_provider(void)
  323. {
  324. return vfp;
  325. } */
  326. static inline vframe_t *vm_vf_peek_from_provider(void)
  327. {
  328. struct vframe_provider_s *vfp;
  329. vframe_t *vf;
  330. vfp = vf_get_provider(RECEIVER_NAME);
  331. if (!(vfp && vfp->ops && vfp->ops->peek))
  332. return NULL;
  333. vf = vfp->ops->peek(vfp->op_arg);
  334. return vf;
  335. }
  336. static inline vframe_t *vm_vf_get_from_provider(void)
  337. {
  338. struct vframe_provider_s *vfp;
  339. vfp = vf_get_provider(RECEIVER_NAME);
  340. if (!(vfp && vfp->ops && vfp->ops->peek))
  341. return NULL;
  342. return vfp->ops->get(vfp->op_arg);
  343. }
  344. static inline void vm_vf_put_from_provider(vframe_t *vf)
  345. {
  346. struct vframe_provider_s *vfp;
  347. vfp = vf_get_provider(RECEIVER_NAME);
  348. if (!(vfp && vfp->ops && vfp->ops->peek))
  349. return;
  350. vfp->ops->put(vf,vfp->op_arg);
  351. }
  352. /************************************************
  353. *
  354. * main task functions.
  355. *
  356. *************************************************/
  357. static int get_input_format(vframe_t* vf)
  358. {
  359. int format= GE2D_FORMAT_M24_YUV420;
  360. if(vf->type&VIDTYPE_VIU_422)
  361. format = GE2D_FORMAT_S16_YUV422;
  362. else
  363. format = GE2D_FORMAT_M24_YUV420;
  364. return format;
  365. }
  366. static int get_input_frame(display_frame_t* frame ,vframe_t* vf)
  367. {
  368. int ret = 0;
  369. int top, left, bottom ,right;
  370. if (!vf)
  371. return -1;
  372. frame->frame_top = 0;
  373. frame->frame_left = 0 ;
  374. frame->frame_width = vf->width;
  375. frame->frame_height = vf->height;
  376. ret = get_curren_frame_para(&top ,&left , &bottom, &right);
  377. if(ret >= 0 ){
  378. frame->content_top = top&(~1);
  379. frame->content_left = left&(~1);
  380. frame->content_width = vf->width - 2*frame->content_left ;
  381. frame->content_height = vf->height - 2*frame->content_top;
  382. }else{
  383. frame->content_top = 0;
  384. frame->content_left = 0 ;
  385. frame->content_width = vf->width;
  386. frame->content_height = vf->height;
  387. }
  388. return 0;
  389. }
  390. static int get_output_format(int v4l2_format)
  391. {
  392. int format = GE2D_FORMAT_S24_YUV444;
  393. switch(v4l2_format){
  394. case V4L2_PIX_FMT_RGB565X:
  395. format = GE2D_FORMAT_S16_RGB_565;
  396. break;
  397. case V4L2_PIX_FMT_YUV444:
  398. format = GE2D_FORMAT_S24_YUV444;
  399. break;
  400. case V4L2_PIX_FMT_VYUY:
  401. format = GE2D_FORMAT_S16_YUV422;
  402. break;
  403. case V4L2_PIX_FMT_BGR24:
  404. format = GE2D_FORMAT_S24_RGB ;
  405. break;
  406. case V4L2_PIX_FMT_RGB24:
  407. format = GE2D_FORMAT_S24_BGR;
  408. break;
  409. case V4L2_PIX_FMT_NV12:
  410. #ifdef GE2D_NV
  411. format = GE2D_FORMAT_M24_NV12;
  412. break;
  413. #endif
  414. case V4L2_PIX_FMT_NV21:
  415. #ifdef GE2D_NV
  416. format = GE2D_FORMAT_M24_NV21;
  417. break;
  418. #endif
  419. case V4L2_PIX_FMT_YUV420:
  420. format = GE2D_FORMAT_S8_Y;
  421. break;
  422. default:
  423. break;
  424. }
  425. return format;
  426. }
  427. typedef struct output_para{
  428. int width;
  429. int height;
  430. int bytesperline;
  431. int v4l2_format;
  432. int index;
  433. int v4l2_memory;
  434. unsigned vaddr;
  435. }output_para_t;
  436. static output_para_t output_para = {0,0,0,0,0};
  437. typedef struct vm_dma_contig_memory {
  438. u32 magic;
  439. void *vaddr;
  440. dma_addr_t dma_handle;
  441. unsigned long size;
  442. int is_userptr;
  443. }vm_contig_memory_t;
  444. int is_need_ge2d_pre_process(void)
  445. {
  446. int ret = 0;
  447. switch(output_para.v4l2_format) {
  448. case V4L2_PIX_FMT_RGB565X:
  449. case V4L2_PIX_FMT_YUV444:
  450. case V4L2_PIX_FMT_VYUY:
  451. case V4L2_PIX_FMT_BGR24:
  452. case V4L2_PIX_FMT_RGB24:
  453. case V4L2_PIX_FMT_YUV420:
  454. case V4L2_PIX_FMT_NV12:
  455. case V4L2_PIX_FMT_NV21:
  456. ret = 1;
  457. break;
  458. default:
  459. break;
  460. }
  461. return ret;
  462. }
  463. int is_need_sw_post_process(void)
  464. {
  465. int ret = 0;
  466. switch(output_para.v4l2_memory){
  467. case MAGIC_DC_MEM:
  468. goto exit;
  469. break;
  470. case MAGIC_SG_MEM:
  471. case MAGIC_VMAL_MEM:
  472. default:
  473. ret = 1;
  474. break;
  475. }
  476. exit:
  477. return ret;
  478. }
  479. int get_canvas_index(int v4l2_format, int *depth)
  480. {
  481. int canvas = VM_DEPTH_16_CANVAS;
  482. *depth = 16;
  483. switch(v4l2_format){
  484. case V4L2_PIX_FMT_RGB565X:
  485. case V4L2_PIX_FMT_VYUY:
  486. canvas = VM_DEPTH_16_CANVAS;
  487. *depth = 16 ;
  488. break;
  489. case V4L2_PIX_FMT_YUV444:
  490. case V4L2_PIX_FMT_BGR24:
  491. case V4L2_PIX_FMT_RGB24:
  492. canvas = VM_DEPTH_24_CANVAS;
  493. *depth = 24;
  494. break;
  495. case V4L2_PIX_FMT_NV12:
  496. case V4L2_PIX_FMT_NV21:
  497. #ifdef GE2D_NV
  498. canvas = VM_DEPTH_8_CANVAS_Y | (VM_DEPTH_8_CANVAS_UV<<8);
  499. #else
  500. canvas = VM_DEPTH_8_CANVAS_Y|(VM_DEPTH_8_CANVAS_U<<8)|(VM_DEPTH_8_CANVAS_V<<16);
  501. #endif
  502. *depth = 12;
  503. break;
  504. case V4L2_PIX_FMT_YUV420:
  505. canvas = VM_DEPTH_8_CANVAS_Y|(VM_DEPTH_8_CANVAS_U<<8)|(VM_DEPTH_8_CANVAS_V<<16);
  506. *depth = 12;
  507. break;
  508. default:
  509. break;
  510. }
  511. return canvas;
  512. }
  513. int vm_fill_buffer(struct videobuf_buffer* vb , int v4l2_format , int magic,void* vaddr)
  514. {
  515. vm_contig_memory_t *mem = NULL;
  516. char *buf_start,*vbuf_start;
  517. int buf_size;
  518. int depth=0;
  519. int ret = -1;
  520. int canvas_index = -1 ;
  521. struct videobuf_buffer buf={0};
  522. get_vm_buf_info((const char **)&buf_start,&buf_size,&vbuf_start);
  523. #if 0
  524. if(!vb)
  525. goto exit;
  526. #else
  527. if(!vb) {
  528. buf.width = 640;
  529. buf.height = 480;
  530. magic = MAGIC_VMAL_MEM ;
  531. v4l2_format = V4L2_PIX_FMT_YUV444 ;
  532. vb = &buf;
  533. }
  534. if(!task_running){
  535. return ret;
  536. }
  537. #endif
  538. switch(magic){
  539. case MAGIC_DC_MEM:
  540. mem = vb->priv;
  541. canvas_config(VM_DMA_CANVAS_INDEX,
  542. mem->dma_handle,
  543. vb->bytesperline, vb->height,
  544. CANVAS_ADDR_NOWRAP, CANVAS_BLKMODE_32X32);
  545. canvas_index = VM_DMA_CANVAS_INDEX ;
  546. depth = (vb->bytesperline <<3)/vb->width;
  547. break;
  548. case MAGIC_SG_MEM:
  549. case MAGIC_VMAL_MEM:
  550. if(buf_start && buf_size)
  551. canvas_index = get_canvas_index(v4l2_format,&depth);
  552. break;
  553. default:
  554. canvas_index = VM_DEPTH_16_CANVAS ;
  555. break;
  556. }
  557. output_para.width = vb->width;
  558. output_para.height = vb->height;
  559. output_para.bytesperline = (vb->width *depth)>>3;
  560. output_para.index = canvas_index ;
  561. output_para.v4l2_format = v4l2_format ;
  562. output_para.v4l2_memory = magic ;
  563. output_para.vaddr = (unsigned)vaddr;
  564. up(&vb_start_sema);
  565. ret = down_interruptible(&vb_done_sema);
  566. return ret;
  567. }
  568. /*for decoder input processing
  569. 1. output window should 1:1 as source frame size
  570. 2. keep the frame ratio
  571. 3. input format should be YUV420 , output format should be YUV444
  572. */
  573. int vm_ge2d_pre_process(vframe_t* vf, ge2d_context_t *context,config_para_ex_t* ge2d_config)
  574. {
  575. int ret;
  576. int src_top ,src_left ,src_width, src_height;
  577. canvas_t cs0,cs1,cs2,cd;
  578. int current_mirror = camera_mirror_flag;
  579. display_frame_t input_frame={0};
  580. ret = get_input_frame(&input_frame , vf);
  581. src_top = input_frame.content_top;
  582. src_left = input_frame.content_left;
  583. src_width = input_frame.content_width;
  584. src_height = input_frame.content_height;
  585. if(test_zoom){
  586. test_zoom = 0;
  587. printk("top is %d , left is %d , width is %d , height is %d\n",input_frame.content_top ,input_frame.content_left,input_frame.content_width,input_frame.content_height);
  588. }
  589. /* data operating. */
  590. ge2d_config->alu_const_color= 0;//0x000000ff;
  591. ge2d_config->bitmask_en = 0;
  592. ge2d_config->src1_gb_alpha = 0;//0xff;
  593. ge2d_config->dst_xy_swap = 0;
  594. canvas_read(vf->canvas0Addr&0xff,&cs0);
  595. canvas_read((vf->canvas0Addr>>8)&0xff,&cs1);
  596. canvas_read((vf->canvas0Addr>>16)&0xff,&cs2);
  597. ge2d_config->src_planes[0].addr = cs0.addr;
  598. ge2d_config->src_planes[0].w = cs0.width;
  599. ge2d_config->src_planes[0].h = cs0.height;
  600. ge2d_config->src_planes[1].addr = cs1.addr;
  601. ge2d_config->src_planes[1].w = cs1.width;
  602. ge2d_config->src_planes[1].h = cs1.height;
  603. ge2d_config->src_planes[2].addr = cs2.addr;
  604. ge2d_config->src_planes[2].w = cs2.width;
  605. ge2d_config->src_planes[2].h = cs2.height;
  606. canvas_read(output_para.index&0xff,&cd);
  607. ge2d_config->dst_planes[0].addr = cd.addr;
  608. ge2d_config->dst_planes[0].w = cd.width;
  609. ge2d_config->dst_planes[0].h = cd.height;
  610. ge2d_config->src_key.key_enable = 0;
  611. ge2d_config->src_key.key_mask = 0;
  612. ge2d_config->src_key.key_mode = 0;
  613. ge2d_config->src_para.canvas_index=vf->canvas0Addr;
  614. ge2d_config->src_para.mem_type = CANVAS_TYPE_INVALID;
  615. ge2d_config->src_para.format = get_input_format(vf);
  616. ge2d_config->src_para.fill_color_en = 0;
  617. ge2d_config->src_para.fill_mode = 0;
  618. ge2d_config->src_para.x_rev = 0;
  619. ge2d_config->src_para.y_rev = 0;
  620. ge2d_config->src_para.color = 0xffffffff;
  621. ge2d_config->src_para.top = 0;
  622. ge2d_config->src_para.left = 0;
  623. ge2d_config->src_para.width = vf->width;
  624. ge2d_config->src_para.height = vf->height;
  625. /* printk("vf_width is %d , vf_height is %d \n",vf->width ,vf->height); */
  626. ge2d_config->src2_para.mem_type = CANVAS_TYPE_INVALID;
  627. ge2d_config->dst_para.canvas_index = output_para.index&0xff;
  628. #ifdef GE2D_NV
  629. if(output_para.v4l2_format != V4L2_PIX_FMT_YUV420)
  630. ge2d_config->dst_para.canvas_index = output_para.index;
  631. #endif
  632. ge2d_config->dst_para.mem_type = CANVAS_TYPE_INVALID;
  633. ge2d_config->dst_para.format = get_output_format(output_para.v4l2_format)|GE2D_LITTLE_ENDIAN;
  634. ge2d_config->dst_para.fill_color_en = 0;
  635. ge2d_config->dst_para.fill_mode = 0;
  636. ge2d_config->dst_para.x_rev = 0;
  637. ge2d_config->dst_para.y_rev = 0;
  638. ge2d_config->dst_para.color = 0;
  639. ge2d_config->dst_para.top = 0;
  640. ge2d_config->dst_para.left = 0;
  641. ge2d_config->dst_para.width = output_para.width;
  642. ge2d_config->dst_para.height = output_para.height;
  643. if(current_mirror==1){
  644. ge2d_config->dst_para.x_rev = 1;
  645. ge2d_config->dst_para.y_rev = 0;
  646. }else if(current_mirror==2){
  647. ge2d_config->dst_para.x_rev = 0;
  648. ge2d_config->dst_para.y_rev = 1;
  649. }else{
  650. ge2d_config->dst_para.x_rev = 0;
  651. ge2d_config->dst_para.y_rev = 0;
  652. }
  653. if(ge2d_context_config_ex(context,ge2d_config)<0) {
  654. printk("++ge2d configing error.\n");
  655. return -1;
  656. }
  657. stretchblt_noalpha(context,src_left ,src_top ,src_width, src_height,0,0,output_para.width,output_para.height);
  658. /* for cr of yuv420p or yuv420sp. */
  659. if(output_para.v4l2_format==V4L2_PIX_FMT_YUV420) {
  660. /* for cb. */
  661. canvas_read((output_para.index>>8)&0xff,&cd);
  662. ge2d_config->dst_planes[0].addr = cd.addr;
  663. ge2d_config->dst_planes[0].w = cd.width;
  664. ge2d_config->dst_planes[0].h = cd.height;
  665. ge2d_config->dst_para.canvas_index=(output_para.index>>8)&0xff;
  666. ge2d_config->dst_para.format=GE2D_FORMAT_S8_CB|GE2D_LITTLE_ENDIAN;
  667. ge2d_config->dst_para.width = output_para.width/2;
  668. ge2d_config->dst_para.height = output_para.height/2;
  669. if(current_mirror==1){
  670. ge2d_config->dst_para.x_rev = 1;
  671. ge2d_config->dst_para.y_rev = 0;
  672. }else if(current_mirror==2){
  673. ge2d_config->dst_para.x_rev = 0;
  674. ge2d_config->dst_para.y_rev = 1;
  675. }else{
  676. ge2d_config->dst_para.x_rev = 0;
  677. ge2d_config->dst_para.y_rev = 0;
  678. }
  679. if(ge2d_context_config_ex(context,ge2d_config)<0) {
  680. printk("++ge2d configing error.\n");
  681. return -1;
  682. }
  683. stretchblt_noalpha(context, src_left, src_top, src_width, src_height,
  684. 0, 0, ge2d_config->dst_para.width,ge2d_config->dst_para.height);
  685. }
  686. #ifndef GE2D_NV
  687. else if (output_para.v4l2_format==V4L2_PIX_FMT_NV12||
  688. output_para.v4l2_format==V4L2_PIX_FMT_NV21) {
  689. canvas_read((output_para.index>>8)&0xff,&cd);
  690. ge2d_config->dst_planes[0].addr = cd.addr;
  691. ge2d_config->dst_planes[0].w = cd.width;
  692. ge2d_config->dst_planes[0].h = cd.height;
  693. ge2d_config->dst_para.canvas_index=(output_para.index>>8)&0xff;
  694. ge2d_config->dst_para.format=GE2D_FORMAT_S8_CB|GE2D_LITTLE_ENDIAN;
  695. ge2d_config->dst_para.width = output_para.width/2;
  696. ge2d_config->dst_para.height = output_para.height/2;
  697. if(current_mirror==1){
  698. ge2d_config->dst_para.x_rev = 1;
  699. ge2d_config->dst_para.y_rev = 0;
  700. }else if(current_mirror==2){
  701. ge2d_config->dst_para.x_rev = 0;
  702. ge2d_config->dst_para.y_rev = 1;
  703. }else{
  704. ge2d_config->dst_para.x_rev = 0;
  705. ge2d_config->dst_para.y_rev = 0;
  706. }
  707. if(ge2d_context_config_ex(context,ge2d_config)<0) {
  708. printk("++ge2d configing error.\n");
  709. return -1;
  710. }
  711. stretchblt_noalpha(context,src_left ,src_top ,src_width, src_height,0,0,ge2d_config->dst_para.width,ge2d_config->dst_para.height);
  712. }
  713. #endif
  714. /* for cb of yuv420p or yuv420sp. */
  715. if(output_para.v4l2_format==V4L2_PIX_FMT_YUV420
  716. #ifndef GE2D_NV
  717. ||output_para.v4l2_format==V4L2_PIX_FMT_NV12||
  718. output_para.v4l2_format==V4L2_PIX_FMT_NV21
  719. #endif
  720. ) {
  721. canvas_read((output_para.index>>16)&0xff,&cd);
  722. ge2d_config->dst_planes[0].addr = cd.addr;
  723. ge2d_config->dst_planes[0].w = cd.width;
  724. ge2d_config->dst_planes[0].h = cd.height;
  725. ge2d_config->dst_para.canvas_index=(output_para.index>>16)&0xff;
  726. ge2d_config->dst_para.format=GE2D_FORMAT_S8_CR|GE2D_LITTLE_ENDIAN;
  727. ge2d_config->dst_para.width = output_para.width/2;
  728. ge2d_config->dst_para.height = output_para.height/2;
  729. if(current_mirror==1){
  730. ge2d_config->dst_para.x_rev = 1;
  731. ge2d_config->dst_para.y_rev = 0;
  732. }else if(current_mirror==2){
  733. ge2d_config->dst_para.x_rev = 0;
  734. ge2d_config->dst_para.y_rev = 1;
  735. }else{
  736. ge2d_config->dst_para.x_rev = 0;
  737. ge2d_config->dst_para.y_rev = 0;
  738. }
  739. if(ge2d_context_config_ex(context,ge2d_config)<0) {
  740. printk("++ge2d configing error.\n");
  741. return -1;
  742. }
  743. stretchblt_noalpha(context, src_left, src_top, src_width, src_height,
  744. 0, 0, ge2d_config->dst_para.width, ge2d_config->dst_para.height);
  745. }
  746. return output_para.index;
  747. }
  748. int vm_sw_post_process(int canvas , int addr)
  749. {
  750. int poss=0,posd=0;
  751. int i=0;
  752. void __iomem * buffer_y_start;
  753. void __iomem * buffer_u_start;
  754. void __iomem * buffer_v_start = 0;
  755. canvas_t canvas_work_y;
  756. canvas_t canvas_work_u;
  757. canvas_t canvas_work_v;
  758. if(!addr)
  759. return -1;
  760. canvas_read(canvas&0xff,&canvas_work_y);
  761. buffer_y_start = ioremap_wc(canvas_work_y.addr,canvas_work_y.width*canvas_work_y.height);
  762. if(buffer_y_start == NULL) {
  763. printk(" vm.postprocess:mapping buffer error\n");
  764. return -1;
  765. }
  766. if (output_para.v4l2_format == V4L2_PIX_FMT_BGR24||
  767. output_para.v4l2_format == V4L2_PIX_FMT_RGB24||
  768. output_para.v4l2_format== V4L2_PIX_FMT_RGB565X) {
  769. for(i=0;i<output_para.height;i++) {
  770. memcpy((void *)(addr+poss),(void *)(buffer_y_start+posd),output_para.bytesperline);
  771. poss+=output_para.bytesperline;
  772. posd+= canvas_work_y.width;
  773. }
  774. } else if (output_para.v4l2_format== V4L2_PIX_FMT_NV12||
  775. output_para.v4l2_format== V4L2_PIX_FMT_NV21) {
  776. #ifdef GE2D_NV
  777. unsigned uv_width = output_para.width;
  778. unsigned uv_height = output_para.height>>1;
  779. posd = 0;
  780. for(i=output_para.height;i>0;i--) { /* copy y */
  781. memcpy((void *)(addr+poss),(void *)(buffer_y_start+posd),output_para.width);
  782. poss+=output_para.width;
  783. posd+= canvas_work_y.width;
  784. }
  785. posd=0;
  786. canvas_read((canvas>>8)&0xff,&canvas_work_u);
  787. buffer_u_start = ioremap_wc(canvas_work_u.addr,canvas_work_u.width*canvas_work_u.height);
  788. for(i=uv_height; i > 0; i--) { /* copy y */
  789. memcpy((void *)(addr+poss), (void *)(buffer_u_start+posd), uv_width);
  790. poss += uv_width;
  791. posd+= canvas_work_u.width;
  792. }
  793. iounmap(buffer_u_start);
  794. #else
  795. char* dst_buff=NULL;
  796. char* src_buff=NULL;
  797. char* src2_buff=NULL;
  798. canvas_read((canvas>>8)&0xff,&canvas_work_u);
  799. buffer_u_start = ioremap_wc(canvas_work_u.addr,canvas_work_u.width*canvas_work_u.height);
  800. poss = posd = 0 ;
  801. for(i=0;i<output_para.height;i+=2) { /* copy y */
  802. memcpy((void *)(addr+poss),(void *)(buffer_y_start+posd),output_para.width);
  803. poss+=output_para.width;
  804. posd+= canvas_work_y.width;
  805. memcpy((void *)(addr+poss),(void *)(buffer_y_start+posd),output_para.width);
  806. poss+=output_para.width;
  807. posd+= canvas_work_y.width;
  808. }
  809. posd=0;
  810. canvas_read((canvas>>16)&0xff,&canvas_work_v);
  811. buffer_v_start = ioremap_wc(canvas_work_v.addr,canvas_work_v.width*canvas_work_v.height);
  812. dst_buff= (char*)addr+output_para.width* output_para.height;
  813. src_buff = (char*)buffer_u_start;
  814. src2_buff= (char*)buffer_v_start;
  815. if(output_para.v4l2_format== V4L2_PIX_FMT_NV12) {
  816. for(i = 0 ;i < output_para.height/2; i++){
  817. interleave_uv(src_buff, src2_buff, dst_buff, output_para.width/2);
  818. src_buff += canvas_work_u.width;
  819. src2_buff += canvas_work_v.width;
  820. dst_buff += output_para.width;
  821. }
  822. } else {
  823. for(i = 0 ;i < output_para.height/2; i++){
  824. interleave_uv(src2_buff, src_buff, dst_buff, output_para.width/2);
  825. src_buff += canvas_work_u.width;
  826. src2_buff += canvas_work_v.width;
  827. dst_buff += output_para.width;
  828. }
  829. }
  830. iounmap(buffer_u_start);
  831. iounmap(buffer_v_start);
  832. #endif
  833. } else if (output_para.v4l2_format == V4L2_PIX_FMT_YUV420) {
  834. int uv_width = output_para.width>>1;
  835. int uv_height = output_para.height>>1;
  836. posd=0;
  837. for(i=output_para.height;i>0;i--) { /* copy y */
  838. memcpy((void *)(addr+poss),(void *)(buffer_y_start+posd),output_para.width);
  839. poss+=output_para.width;
  840. posd+= canvas_work_y.width;
  841. }
  842. posd=0;
  843. canvas_read((canvas>>8)&0xff,&canvas_work_u);
  844. buffer_u_start = ioremap_wc(canvas_work_u.addr,canvas_work_u.width*canvas_work_u.height);
  845. canvas_read((canvas>>16)&0xff,&canvas_work_v);
  846. buffer_v_start = ioremap_wc(canvas_work_v.addr,canvas_work_v.width*canvas_work_v.height);
  847. for(i=uv_height;i>0;i--) { /* copy y */
  848. memcpy((void *)(addr+poss),(void *)(buffer_u_start+posd),uv_width);
  849. poss+=uv_width;
  850. posd+= canvas_work_u.width;
  851. }
  852. posd=0;
  853. for(i=uv_height;i>0;i--) { /* copy y */
  854. memcpy((void *)(addr+poss),(void *)(buffer_v_start+posd),uv_width);
  855. poss+=uv_width;
  856. posd+= canvas_work_v.width;
  857. }
  858. iounmap(buffer_u_start);
  859. iounmap(buffer_v_start);
  860. }
  861. iounmap(buffer_y_start);
  862. return 0;
  863. }
  864. static struct task_struct *task=NULL;
  865. static struct task_struct *simulate_task_fd=NULL;
  866. /* static int reset_frame = 1; */
  867. static int vm_task(void *data) {
  868. int ret = 0;
  869. vframe_t *vf;
  870. int src_canvas;
  871. int timer_count = 0 ;
  872. struct sched_param param = {.sched_priority = MAX_RT_PRIO - 1 };
  873. ge2d_context_t *context=create_ge2d_work_queue();
  874. config_para_ex_t ge2d_config;
  875. #ifdef CONFIG_AMLCAP_LOG_TIME_USEFORFRAMES
  876. struct timeval start;
  877. struct timeval end;
  878. unsigned long time_use=0;
  879. #endif
  880. memset(&ge2d_config,0,sizeof(config_para_ex_t));
  881. amlog_level(LOG_LEVEL_HIGH,"vm task is running\n ");
  882. sched_setscheduler(current, SCHED_FIFO, &param);
  883. allow_signal(SIGTERM);
  884. while(1) {
  885. ret = down_interruptible(&vb_start_sema);
  886. timer_count = 0;
  887. if (kthread_should_stop()){
  888. up(&vb_done_sema);
  889. break;
  890. }
  891. /* wait for frame from 656 provider until 500ms runs out */
  892. vf = local_vf_peek();
  893. while((vf == NULL) && (timer_count < 200)) {
  894. if(!task_running){
  895. up(&vb_done_sema);
  896. goto vm_exit;
  897. break;
  898. }
  899. vf = local_vf_peek();
  900. timer_count++;
  901. msleep(5);
  902. }
  903. /* start to convert frame. */
  904. #ifdef CONFIG_AMLCAP_LOG_TIME_USEFORFRAMES
  905. do_gettimeofday(&start);
  906. #endif
  907. vf = local_vf_get();
  908. if (vf) {
  909. src_canvas = vf->canvas0Addr;
  910. /* step1 convert 422 format to other format.*/
  911. if (is_need_ge2d_pre_process())
  912. src_canvas = vm_ge2d_pre_process(vf,context,&ge2d_config);
  913. local_vf_put(vf);
  914. #ifdef CONFIG_AMLCAP_LOG_TIME_USEFORFRAMES
  915. do_gettimeofday(&end);
  916. time_use = (end.tv_sec - start.tv_sec)*1000 +
  917. (end.tv_usec - start.tv_usec) / 1000;
  918. printk("step 1, ge2d use: %ldms\n", time_use);
  919. do_gettimeofday(&start);
  920. #endif
  921. /* step2 copy to user memory. */
  922. if (is_need_sw_post_process())
  923. vm_sw_post_process(src_canvas ,output_para.vaddr);
  924. #ifdef CONFIG_AMLCAP_LOG_TIME_USEFORFRAMES
  925. do_gettimeofday(&end);
  926. time_use = (end.tv_sec - start.tv_sec) * 1000+
  927. (end.tv_usec - start.tv_usec) / 1000;
  928. printk("step 2, memcpy use: %ldms\n", time_use);
  929. #endif
  930. }
  931. if (kthread_should_stop()){
  932. up(&vb_done_sema);
  933. break;
  934. }
  935. up(&vb_done_sema);
  936. }
  937. vm_exit:
  938. destroy_ge2d_work_queue(context);
  939. while(!kthread_should_stop()){
  940. /* may not call stop, wait..
  941. it is killed by SIGTERM,eixt on down_interruptible
  942. if not call stop,this thread may on do_exit and
  943. kthread_stop may not work good;
  944. */
  945. msleep(10);
  946. }
  947. return ret;
  948. }
  949. /*simulate v4l2 device to request filling buffer,only for test use*/
  950. static int simulate_task(void *data)
  951. {
  952. while (1) {
  953. msleep(50);
  954. vm_fill_buffer(NULL,0,0,NULL);
  955. printk("simulate succeed\n");
  956. }
  957. return 0;
  958. }
  959. /************************************************
  960. *
  961. * init functions.
  962. *
  963. *************************************************/
  964. int vm_buffer_init(void)
  965. {
  966. int i;
  967. u32 canvas_width, canvas_height;
  968. u32 decbuf_size;
  969. char *buf_start,*vbuf_start;
  970. int buf_size;
  971. int buf_num = 0;
  972. int local_pool_size = 0;
  973. get_vm_buf_info((const char **)&buf_start,&buf_size,&vbuf_start);
  974. sema_init(&vb_start_sema,0);
  975. sema_init(&vb_done_sema,0);
  976. if(!buf_start || !buf_size)
  977. goto exit;
  978. for(i=0; i<ARRAY_SIZE(vmdecbuf_size);i++){
  979. if( buf_size >= vmdecbuf_size[i])
  980. break;
  981. }
  982. if(i==ARRAY_SIZE(vmdecbuf_size)){
  983. printk("vmbuf size=%d less than the smallest vmbuf size%d\n",
  984. buf_size, vmdecbuf_size[i-1]);
  985. return -1;
  986. }
  987. canvas_width = canvas_config_wh[i].width;//1920;
  988. canvas_height = canvas_config_wh[i].height;//1200;
  989. decbuf_size = vmdecbuf_size[i];//0x700000;
  990. buf_num = buf_size/decbuf_size;
  991. if(buf_num > 0)
  992. local_pool_size = 1;
  993. else {
  994. local_pool_size = 0;
  995. printk("need at least one buffer to handle 1920*1080 data.\n");
  996. }
  997. for (i = 0; i < local_pool_size; i++)
  998. {
  999. canvas_config((VM_DEPTH_16_CANVAS+i),
  1000. (unsigned long)(buf_start + i * decbuf_size),
  1001. canvas_width*2, canvas_height,
  1002. CANVAS_ADDR_NOWRAP, CANVAS_BLKMODE_LINEAR);
  1003. canvas_config((VM_DEPTH_24_CANVAS+i),
  1004. (unsigned long)(buf_start + i * decbuf_size),
  1005. canvas_width*3, canvas_height,
  1006. CANVAS_ADDR_NOWRAP, CANVAS_BLKMODE_LINEAR);
  1007. canvas_config((VM_DEPTH_8_CANVAS_Y+ i),
  1008. (unsigned long)(buf_start + i*decbuf_size/2),
  1009. canvas_width, canvas_height,
  1010. CANVAS_ADDR_NOWRAP, CANVAS_BLKMODE_LINEAR);
  1011. canvas_config(VM_DEPTH_8_CANVAS_UV + i,
  1012. (unsigned long)(buf_start + (i+1)*decbuf_size/2),
  1013. canvas_width, canvas_height/2,
  1014. CANVAS_ADDR_NOWRAP, CANVAS_BLKMODE_LINEAR);
  1015. canvas_config((VM_DEPTH_8_CANVAS_U + i),
  1016. (unsigned long)(buf_start + (i+1)*decbuf_size/2),
  1017. canvas_width/2, canvas_height/2,
  1018. CANVAS_ADDR_NOWRAP, CANVAS_BLKMODE_LINEAR);
  1019. canvas_config((VM_DEPTH_8_CANVAS_V + i),
  1020. (unsigned long)(buf_start + (i+3)*decbuf_size/4),
  1021. canvas_width/2, canvas_height/2,
  1022. CANVAS_ADDR_NOWRAP, CANVAS_BLKMODE_LINEAR);
  1023. vfbuf_use[i] = 0;
  1024. }
  1025. exit:
  1026. return 0;
  1027. }
  1028. int start_vm_task(void) {
  1029. /* init the device. */
  1030. vm_local_init();
  1031. if(!task) {
  1032. task=kthread_create(vm_task,0,"vm");
  1033. if(IS_ERR(task)) {
  1034. amlog_level(LOG_LEVEL_HIGH, "thread creating error.\n");
  1035. return -1;
  1036. }
  1037. wake_up_process(task);
  1038. }
  1039. task_running = 1;
  1040. return 0;
  1041. }
  1042. int start_simulate_task(void)
  1043. {
  1044. if(!simulate_task_fd) {
  1045. simulate_task_fd=kthread_create(simulate_task,0,"vm");
  1046. if(IS_ERR(simulate_task_fd)) {
  1047. amlog_level(LOG_LEVEL_HIGH, "thread creating error.\n");
  1048. return -1;
  1049. }
  1050. wake_up_process(simulate_task_fd);
  1051. }
  1052. return 0;
  1053. }
  1054. void stop_vm_task(void) {
  1055. if(task){
  1056. task_running = 0;
  1057. send_sig(SIGTERM, task, 1);
  1058. up(&vb_start_sema);
  1059. kthread_stop(task);
  1060. task = NULL;
  1061. }
  1062. vm_local_init();
  1063. }
  1064. /***********************************************************************
  1065. *
  1066. * global status.
  1067. *
  1068. ************************************************************************/
  1069. static int vm_enable_flag=0;
  1070. int get_vm_status() {
  1071. return vm_enable_flag;
  1072. }
  1073. void set_vm_status(int flag) {
  1074. if(flag >= 0)
  1075. vm_enable_flag=flag;
  1076. else
  1077. vm_enable_flag=0;
  1078. }
  1079. /***********************************************************************
  1080. *
  1081. * file op section.
  1082. *
  1083. ************************************************************************/
  1084. typedef struct {
  1085. char name[20];
  1086. unsigned int open_count;
  1087. int major;
  1088. unsigned int dbg_enable;
  1089. struct class *cla;
  1090. struct device *dev;
  1091. char *buffer_start;
  1092. unsigned int buffer_size;
  1093. void __iomem *buffer_v_start;
  1094. }vm_device_t;
  1095. static vm_device_t vm_device;
  1096. void set_vm_buf_info(char* start,unsigned int size) {
  1097. vm_device.buffer_start=start;
  1098. vm_device.buffer_size=size;
  1099. vm_device.buffer_v_start = ioremap_wc((unsigned long)start,size);
  1100. amlog_level(LOG_LEVEL_HIGH,"#############%x\n",vm_device.buffer_v_start);
  1101. }
  1102. void get_vm_buf_info(const char** start,unsigned int* size,char** vaddr) {
  1103. *start = vm_device.buffer_start;
  1104. *size = vm_device.buffer_size;
  1105. *vaddr = vm_device.buffer_v_start;
  1106. }
  1107. static int vm_open(struct inode *inode, struct file *file)
  1108. {
  1109. ge2d_context_t *context=NULL;
  1110. amlog_level(LOG_LEVEL_LOW,"open one vm device\n");
  1111. file->private_data=context;
  1112. vm_device.open_count++;
  1113. return 0;
  1114. }
  1115. static long vm_ioctl(struct file *filp, unsigned int cmd, unsigned long args)
  1116. {
  1117. int ret=0 ;
  1118. ge2d_context_t *context;
  1119. void __user* argp;
  1120. context=(ge2d_context_t *)filp->private_data;
  1121. argp =(void __user*)args;
  1122. switch (cmd)
  1123. {
  1124. case VM_IOC_2OSD0:
  1125. break;
  1126. case VM_IOC_ENABLE_PP:
  1127. break;
  1128. case VM_IOC_CONFIG_FRAME:
  1129. break;
  1130. default :
  1131. return -ENOIOCTLCMD;
  1132. }
  1133. return ret;
  1134. }
  1135. static int vm_release(struct inode *inode, struct file *file)
  1136. {
  1137. ge2d_context_t *context=(ge2d_context_t *)file->private_data;
  1138. if(context && (0==destroy_ge2d_work_queue(context)))
  1139. {
  1140. vm_device.open_count--;
  1141. return 0;
  1142. }
  1143. amlog_level(LOG_LEVEL_LOW,"release one vm device\n");
  1144. return -1;
  1145. }
  1146. /***********************************************************************
  1147. *
  1148. * file op init section.
  1149. *
  1150. ************************************************************************/
  1151. static const struct file_operations vm_fops = {
  1152. .owner = THIS_MODULE,
  1153. .open = vm_open,
  1154. .unlocked_ioctl = vm_ioctl,
  1155. .release = vm_release,
  1156. };
  1157. int init_vm_device(void)
  1158. {
  1159. int ret=0;
  1160. strcpy(vm_device.name,"vm");
  1161. ret=register_chrdev(0,vm_device.name,&vm_fops);
  1162. if(ret <=0)
  1163. {
  1164. amlog_level(LOG_LEVEL_HIGH,"register vm device error\r\n");
  1165. return ret ;
  1166. }
  1167. vm_device.major=ret;
  1168. vm_device.dbg_enable=0;
  1169. amlog_level(LOG_LEVEL_LOW,"vm_dev major:%d\r\n",ret);
  1170. vm_device.cla = init_vm_cls();
  1171. if(vm_device.cla == NULL)
  1172. return -1;
  1173. vm_device.dev=device_create(vm_device.cla,NULL,MKDEV(vm_device.major,0)
  1174. ,NULL,vm_device.name);
  1175. if (IS_ERR(vm_device.dev)) {
  1176. amlog_level(LOG_LEVEL_HIGH,"create vm device error\n");
  1177. goto unregister_dev;
  1178. }
  1179. if(vm_buffer_init()<0) goto unregister_dev;
  1180. vf_provider_init(&vm_vf_prov, PROVIDER_NAME ,&vm_vf_provider, NULL);
  1181. //vf_reg_provider(&vm_vf_prov);
  1182. vf_receiver_init(&vm_vf_recv, RECEIVER_NAME, &vm_vf_receiver, NULL);
  1183. vf_reg_receiver(&vm_vf_recv);
  1184. return 0;
  1185. unregister_dev:
  1186. class_unregister(vm_device.cla);
  1187. return -1;
  1188. }
  1189. int uninit_vm_device(void)
  1190. {
  1191. stop_vm_task();
  1192. if(vm_device.cla)
  1193. {
  1194. if(vm_device.dev)
  1195. device_destroy(vm_device.cla, MKDEV(vm_device.major, 0));
  1196. class_unregister(vm_device.cla);
  1197. }
  1198. unregister_chrdev(vm_device.major, vm_device.name);
  1199. return 0;
  1200. }
  1201. /*******************************************************************
  1202. *
  1203. * interface for Linux driver
  1204. *
  1205. * ******************************************************************/
  1206. MODULE_AMLOG(AMLOG_DEFAULT_LEVEL, 0xff, LOG_LEVEL_DESC, LOG_MASK_DESC);
  1207. /* for driver. */
  1208. static int vm_driver_probe(struct platform_device *pdev)
  1209. {
  1210. char* buf_start;
  1211. unsigned int buf_size;
  1212. struct resource *mem;
  1213. if (!(mem = platform_get_resource(pdev, IORESOURCE_MEM, 0)))
  1214. {
  1215. buf_start = 0;
  1216. buf_size = 0;
  1217. } else {
  1218. buf_start = (char *)mem->start;
  1219. buf_size = mem->end - mem->start + 1;
  1220. }
  1221. set_vm_buf_info((char *)mem->start,buf_size);
  1222. init_vm_device();
  1223. return 0;
  1224. }
  1225. static int vm_drv_remove(struct platform_device *plat_dev)
  1226. {
  1227. uninit_vm_device();
  1228. iounmap(vm_device.buffer_v_start);
  1229. return 0;
  1230. }
  1231. /* general interface for a linux driver .*/
  1232. static struct platform_driver vm_drv = {
  1233. .probe = vm_driver_probe,
  1234. .remove = vm_drv_remove,
  1235. .driver = {
  1236. .name = "vm",
  1237. .owner = THIS_MODULE,
  1238. }
  1239. };
  1240. static int __init
  1241. vm_init_module(void)
  1242. {
  1243. int err;
  1244. amlog_level(LOG_LEVEL_HIGH,"vm_init\n");
  1245. if ((err = platform_driver_register(&vm_drv))) {
  1246. printk(KERN_ERR "Failed to register vm driver (error=%d\n", err);
  1247. return err;
  1248. }
  1249. return err;
  1250. }
  1251. static void __exit
  1252. vm_remove_module(void)
  1253. {
  1254. platform_driver_unregister(&vm_drv);
  1255. amlog_level(LOG_LEVEL_HIGH,"vm module removed.\n");
  1256. }
  1257. module_init(vm_init_module);
  1258. module_exit(vm_remove_module);
  1259. MODULE_DESCRIPTION("Amlogic Video Input Manager");
  1260. MODULE_LICENSE("GPL");
  1261. MODULE_AUTHOR("Simon Zheng <simon.zheng@amlogic.com>");