viu_in.c 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706
  1. /*
  2. * Amlogic M3
  3. * frame buffer driver -------viu input
  4. * Copyright (C) 2010 Amlogic, Inc.
  5. *
  6. * This program is free software; you can redistribute it and/or modify
  7. * it under the terms of the GNU General Public License as published by
  8. * the Free Software Foundation; either version 2 of the named License,
  9. * or any later version.
  10. *
  11. * This program is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. * GNU General Public License for more details.
  15. *
  16. */
  17. #include <linux/kernel.h>
  18. #include <linux/types.h>
  19. #include <linux/errno.h>
  20. #include <linux/etherdevice.h>
  21. #include <linux/interrupt.h>
  22. #include <linux/timer.h>
  23. #include <linux/platform_device.h>
  24. #include <linux/workqueue.h>
  25. #include <linux/dma-mapping.h>
  26. #include <asm/delay.h>
  27. #include <asm/atomic.h>
  28. #include <linux/amports/amstream.h>
  29. #include <linux/amports/ptsserv.h>
  30. #include <linux/amports/canvas.h>
  31. #include <linux/amports/vframe.h>
  32. #include <linux/amports/vframe_provider.h>
  33. #include <media/amlogic/656in.h>
  34. #include <mach/am_regs.h>
  35. #include "tvin_global.h"
  36. #include "vdin_regs.h"
  37. #include "tvin_notifier.h"
  38. #include "vdin.h"
  39. #include "vdin_ctl.h"
  40. #include "tvin_format_table.h"
  41. #include <linux/vout/vout_notify.h>
  42. #define DEVICE_NAME "amvdec_viuin"
  43. #define MODULE_NAME "amvdec_viuin"
  44. #define viuin_IRQ_NAME "amvdec_viuin-irq"
  45. //#define viuin_COUNT 1
  46. //#define VIUIN_ANCI_DATA_SIZE 0x4000
  47. typedef struct {
  48. unsigned char rd_canvas_index;
  49. unsigned char wr_canvas_index;
  50. unsigned char buff_flag[VIUIN_VF_POOL_SIZE];
  51. unsigned char fmt_check_cnt;
  52. unsigned char watch_dog;
  53. unsigned pbufAddr;
  54. unsigned decbuf_size;
  55. unsigned active_pixel;
  56. unsigned active_line;
  57. unsigned dec_status : 1;
  58. unsigned wrap_flag : 1;
  59. unsigned canvas_total_count : 4;
  60. struct tvin_parm_s para ;
  61. }amviuin_t;
  62. static struct vdin_dev_s *vdin_devp_viu = NULL;
  63. amviuin_t amviuin_dec_info = {
  64. .pbufAddr = 0x81000000,
  65. .decbuf_size = 0x70000,
  66. .active_pixel = 720,
  67. .active_line = 288,
  68. .watch_dog = 0,
  69. .para = {
  70. .port = TVIN_PORT_NULL,
  71. .fmt_info.fmt = TVIN_SIG_FMT_NULL,
  72. .fmt_info.v_active=0,
  73. .fmt_info.h_active=0,
  74. .fmt_info.vsync_phase=0,
  75. .fmt_info.hsync_phase=0,
  76. .fmt_info.frame_rate=0,
  77. .status = TVIN_SIG_STATUS_NULL,
  78. .cap_addr = 0,
  79. .flag = 0, //TVIN_PARM_FLAG_CAP
  80. .cap_size = 0,
  81. .canvas_index = 0,
  82. },
  83. .rd_canvas_index = 0xff - (VIUIN_VF_POOL_SIZE + 2),
  84. .wr_canvas_index = 0,
  85. .buff_flag = {
  86. VIDTYPE_INTERLACE_BOTTOM,
  87. VIDTYPE_INTERLACE_TOP,
  88. VIDTYPE_INTERLACE_BOTTOM,
  89. VIDTYPE_INTERLACE_TOP,
  90. VIDTYPE_INTERLACE_BOTTOM,
  91. VIDTYPE_INTERLACE_TOP},
  92. .fmt_check_cnt = 0,
  93. .dec_status = 0,
  94. .wrap_flag = 0,
  95. .canvas_total_count = VIUIN_VF_POOL_SIZE,
  96. };
  97. #ifdef HANDLE_viuin_IRQ
  98. static const char viuin_dec_id[] = "viuin-dev";
  99. #endif
  100. static void reset_viuin_dec_parameter(void)
  101. {
  102. amviuin_dec_info.wrap_flag = 0;
  103. amviuin_dec_info.rd_canvas_index = 0xff - (amviuin_dec_info.canvas_total_count + 2);
  104. amviuin_dec_info.wr_canvas_index = 0;
  105. amviuin_dec_info.fmt_check_cnt = 0;
  106. amviuin_dec_info.watch_dog = 0;
  107. }
  108. static void init_viuin_dec_parameter(fmt_info_t fmt_info)
  109. {
  110. amviuin_dec_info.para.fmt_info.fmt= fmt_info.fmt;
  111. amviuin_dec_info.para.fmt_info.frame_rate=fmt_info.frame_rate;
  112. switch(fmt_info.fmt)
  113. {
  114. case TVIN_SIG_FMT_MAX+1:
  115. case 0xFFFF: //default camera
  116. amviuin_dec_info.active_pixel = fmt_info.h_active;
  117. amviuin_dec_info.active_line = fmt_info.v_active;
  118. amviuin_dec_info.para.fmt_info.h_active = fmt_info.h_active;
  119. amviuin_dec_info.para.fmt_info.v_active = fmt_info.v_active;
  120. amviuin_dec_info.para.fmt_info.hsync_phase = fmt_info.hsync_phase;
  121. amviuin_dec_info.para.fmt_info.vsync_phase = fmt_info.vsync_phase;
  122. pr_dbg("%dx%d input mode is selected for camera, \n",fmt_info.h_active,fmt_info.v_active);
  123. break;
  124. case TVIN_SIG_FMT_NULL:
  125. default:
  126. amviuin_dec_info.active_pixel = 0;
  127. amviuin_dec_info.active_line = 0;
  128. break;
  129. }
  130. return;
  131. }
  132. static int viu_in_canvas_init(unsigned int mem_start, unsigned int mem_size)
  133. {
  134. int i, canvas_start_index ;
  135. unsigned int canvas_width = 1600 << 1;
  136. unsigned int canvas_height = 1200;
  137. unsigned decbuf_start = mem_start + VIUIN_ANCI_DATA_SIZE;
  138. amviuin_dec_info.decbuf_size = 0x400000;
  139. i = (unsigned)((mem_size - VIUIN_ANCI_DATA_SIZE) / amviuin_dec_info.decbuf_size);
  140. amviuin_dec_info.canvas_total_count = (VIUIN_VF_POOL_SIZE > i)? i : VIUIN_VF_POOL_SIZE;
  141. amviuin_dec_info.pbufAddr = mem_start;
  142. if(vdin_devp_viu->index )
  143. canvas_start_index = tvin_canvas_tab[1][0];
  144. else
  145. canvas_start_index = tvin_canvas_tab[0][0];
  146. for ( i = 0; i < amviuin_dec_info.canvas_total_count; i++)
  147. {
  148. canvas_config(canvas_start_index + i, decbuf_start + i * amviuin_dec_info.decbuf_size,
  149. canvas_width, canvas_height, CANVAS_ADDR_NOWRAP, CANVAS_BLKMODE_LINEAR);
  150. }
  151. set_tvin_canvas_info(canvas_start_index ,amviuin_dec_info.canvas_total_count );
  152. return 0;
  153. }
  154. static void viu_release_canvas(void)
  155. {
  156. // int i = 0;
  157. // for(;i < amviuin_dec_info.canvas_total_count; i++)
  158. // {
  159. // canvas_release(VDIN_START_CANVAS + i);
  160. // }
  161. return;
  162. }
  163. static inline u32 viu_index2canvas(u32 index)
  164. {
  165. int tv_group_index ;
  166. if(vdin_devp_viu->index )
  167. tv_group_index = 1;
  168. else
  169. tv_group_index = 0;
  170. if(index < amviuin_dec_info.canvas_total_count)
  171. return tvin_canvas_tab[tv_group_index][index];
  172. else
  173. return 0xff;
  174. }
  175. static void start_amvdec_viu_in(unsigned int mem_start, unsigned int mem_size,
  176. tvin_port_t port, fmt_info_t fmt_info)
  177. {
  178. if(amviuin_dec_info.dec_status != 0)
  179. {
  180. pr_dbg("viu_in is processing, don't do starting operation \n");
  181. return;
  182. }
  183. pr_dbg("start ");
  184. if(port == TVIN_PORT_VIU_ENCT)
  185. {
  186. pr_dbg("viu in decode. \n");
  187. viu_in_canvas_init(mem_start, mem_size);
  188. init_viuin_dec_parameter(fmt_info);
  189. reset_viuin_dec_parameter();
  190. amviuin_dec_info.para.port = TVIN_PORT_VIU_ENCT;
  191. amviuin_dec_info.wr_canvas_index = 0xff;
  192. amviuin_dec_info.dec_status = 1;
  193. }
  194. return;
  195. }
  196. static void stop_amvdec_viu_in(void)
  197. {
  198. if(amviuin_dec_info.dec_status)
  199. {
  200. pr_dbg("stop viu_in decode. \n");
  201. viu_release_canvas();
  202. amviuin_dec_info.para.fmt_info.fmt= TVIN_SIG_FMT_NULL;
  203. amviuin_dec_info.dec_status = 0;
  204. }
  205. else
  206. {
  207. pr_dbg("viu_in is not started yet. \n");
  208. }
  209. return;
  210. }
  211. static void viu_send_buff_to_display_fifo(vframe_t * info)
  212. {
  213. if(amviuin_dec_info.para.fmt_info.fmt==TVIN_SIG_FMT_MAX+1)
  214. info->duration = 960000/amviuin_dec_info.para.fmt_info.frame_rate;
  215. else
  216. info->duration = tvin_fmt_tbl[amviuin_dec_info.para.fmt_info.fmt].duration;
  217. //info->duration = tvin_fmt_tbl[amviuin_dec_info.para.fmt].duration;
  218. info->type = VIDTYPE_VIU_SINGLE_PLANE | VIDTYPE_VIU_422 | VIDTYPE_VIU_FIELD | VIDTYPE_PROGRESSIVE ;
  219. info->width= amviuin_dec_info.active_pixel;
  220. info->height = amviuin_dec_info.active_line;
  221. if(amviuin_dec_info.para.fmt_info.fmt==TVIN_SIG_FMT_MAX+1)
  222. info->duration = 960000/amviuin_dec_info.para.fmt_info.frame_rate;
  223. else
  224. info->duration = tvin_fmt_tbl[amviuin_dec_info.para.fmt_info.fmt].duration;
  225. //info->duration = tvin_fmt_tbl[amviuin_dec_info.para.fmt].duration;
  226. info->canvas0Addr = info->canvas1Addr = viu_index2canvas(amviuin_dec_info.wr_canvas_index);
  227. }
  228. static void viuin_wr_vdin_canvas(void)
  229. {
  230. unsigned char canvas_id;
  231. amviuin_dec_info.wr_canvas_index += 1;
  232. if(amviuin_dec_info.wr_canvas_index > (amviuin_dec_info.canvas_total_count -1) )
  233. {
  234. amviuin_dec_info.wr_canvas_index = 0;
  235. amviuin_dec_info.wrap_flag = 1;
  236. }
  237. canvas_id = viu_index2canvas(amviuin_dec_info.wr_canvas_index);
  238. vdin_set_canvas_id(vdin_devp_viu->index, canvas_id);
  239. }
  240. static void viu_wr_vdin_canvas(int index)
  241. {
  242. vdin_set_canvas_id(vdin_devp_viu->index, viu_index2canvas(index));
  243. }
  244. static void viu_in_dec_run(vframe_t * info)
  245. {
  246. if (amviuin_dec_info.wr_canvas_index == 0xff) {
  247. viu_wr_vdin_canvas(0);
  248. amviuin_dec_info.wr_canvas_index = 0;
  249. return;
  250. }
  251. viu_send_buff_to_display_fifo(info);
  252. amviuin_dec_info.wr_canvas_index++;
  253. if (amviuin_dec_info.wr_canvas_index >= amviuin_dec_info.canvas_total_count)
  254. amviuin_dec_info.wr_canvas_index = 0;
  255. viu_wr_vdin_canvas(amviuin_dec_info.wr_canvas_index);
  256. return;
  257. }
  258. /*as use the spin_lock,
  259. *1--there is no sleep,
  260. *2--it is better to shorter the time,
  261. */
  262. int amvdec_viu_in_run(vframe_t *info)
  263. {
  264. unsigned ccir656_status;
  265. unsigned char canvas_id = 0;
  266. unsigned char last_receiver_buff_index = 0;
  267. if(amviuin_dec_info.dec_status == 0){
  268. // pr_error("viuin decoder is not started\n");
  269. return -1;
  270. }
  271. if(amviuin_dec_info.active_pixel == 0){
  272. return -1;
  273. }
  274. amviuin_dec_info.watch_dog = 0;
  275. if(vdin_devp_viu->para.flag & TVIN_PARM_FLAG_CAP)
  276. {
  277. if(amviuin_dec_info.wr_canvas_index == 0)
  278. last_receiver_buff_index = amviuin_dec_info.canvas_total_count - 1;
  279. else
  280. last_receiver_buff_index = amviuin_dec_info.wr_canvas_index - 1;
  281. if(last_receiver_buff_index != amviuin_dec_info.rd_canvas_index)
  282. canvas_id = last_receiver_buff_index;
  283. else
  284. {
  285. if(amviuin_dec_info.wr_canvas_index == amviuin_dec_info.canvas_total_count - 1)
  286. canvas_id = 0;
  287. else
  288. canvas_id = amviuin_dec_info.wr_canvas_index + 1;
  289. }
  290. vdin_devp_viu->para.cap_addr = amviuin_dec_info.pbufAddr +
  291. (amviuin_dec_info.decbuf_size * canvas_id) + VIUIN_ANCI_DATA_SIZE ;
  292. vdin_devp_viu->para.cap_size = amviuin_dec_info.decbuf_size;
  293. vdin_devp_viu->para.canvas_index =VDIN_START_CANVAS+ canvas_id;
  294. return 0;
  295. }
  296. if(amviuin_dec_info.para.port == TVIN_PORT_VIU_ENCT)
  297. {
  298. viu_in_dec_run(info);
  299. }
  300. return 0;
  301. }
  302. static int viuin_check_callback(struct notifier_block *block, unsigned long cmd , void *para)
  303. {
  304. int ret = 0;
  305. switch(cmd)
  306. {
  307. case TVIN_EVENT_INFO_CHECK:
  308. break;
  309. default:
  310. break;
  311. }
  312. return ret;
  313. }
  314. struct tvin_dec_ops_s viuin_op = {
  315. .dec_run = amvdec_viu_in_run,
  316. };
  317. static struct notifier_block viuin_check_notifier = {
  318. .notifier_call = viuin_check_callback,
  319. };
  320. static int viuin_notifier_callback(struct notifier_block *block, unsigned long cmd , void *para)
  321. {
  322. int ret = 0;
  323. vdin_dev_t *p = NULL;
  324. switch(cmd)
  325. {
  326. case TVIN_EVENT_DEC_START:
  327. if(para != NULL)
  328. {
  329. p = (vdin_dev_t*)para;
  330. if (p->para.port != TVIN_PORT_VIU_ENCT)
  331. {
  332. pr_info("viuin: ignore TVIN_EVENT_DEC_START (port=%d)\n", p->para.port);
  333. return ret;
  334. }
  335. pr_dbg("viuin_notifier_callback, para = %x ,mem_start = %x, port = %d, format = %d, ca-_flag = %d.\n" ,
  336. (unsigned int)para, p->mem_start, p->para.port, p->para.fmt_info.fmt, p->para.flag);
  337. vdin_devp_viu = p;
  338. start_amvdec_viu_in(p->mem_start,p->mem_size, p->para.port, p->para.fmt_info);
  339. amviuin_dec_info.para.status = TVIN_SIG_STATUS_STABLE;
  340. vdin_info_update(p, &amviuin_dec_info.para);
  341. tvin_dec_register(p, &viuin_op);
  342. tvin_check_notifier_register(&viuin_check_notifier);
  343. ret = NOTIFY_STOP_MASK;
  344. }
  345. break;
  346. case TVIN_EVENT_DEC_STOP:
  347. if(para != NULL)
  348. {
  349. p = (vdin_dev_t*)para;
  350. if(p->para.port != TVIN_PORT_VIU_ENCT)
  351. {
  352. pr_info("viuin: ignore TVIN_EVENT_DEC_STOP, port=%d \n", p->para.port);
  353. return ret;
  354. }
  355. stop_amvdec_viu_in();
  356. tvin_dec_unregister(vdin_devp_viu);
  357. tvin_check_notifier_unregister(&viuin_check_notifier);
  358. vdin_devp_viu = NULL;
  359. ret = NOTIFY_STOP_MASK;
  360. }
  361. break;
  362. default:
  363. break;
  364. }
  365. return ret;
  366. }
  367. static int notify_callback_v(struct notifier_block *block, unsigned long cmd , void *p)
  368. {
  369. return 0;
  370. }
  371. static struct notifier_block viuin_notifier = {
  372. .notifier_call = viuin_notifier_callback,
  373. };
  374. static struct notifier_block notifier_nb_v = {
  375. .notifier_call = notify_callback_v,
  376. };
  377. static int amvdec_viuin_probe(struct platform_device *pdev)
  378. {
  379. int r = 0;
  380. pr_dbg("amvdec_viuin probe start.\n");
  381. tvin_dec_notifier_register(&viuin_notifier);
  382. vout_register_client(&notifier_nb_v);
  383. pr_dbg("amvdec_viuin probe end.\n");
  384. return r;
  385. }
  386. static int amvdec_viuin_remove(struct platform_device *pdev)
  387. {
  388. /* Remove the cdev */
  389. tvin_dec_notifier_unregister(&viuin_notifier);
  390. vout_unregister_client(&notifier_nb_v);
  391. return 0;
  392. }
  393. static struct platform_driver amvdec_viuin_driver = {
  394. .probe = amvdec_viuin_probe,
  395. .remove = amvdec_viuin_remove,
  396. .driver = {
  397. .name = DEVICE_NAME,
  398. }
  399. };
  400. static struct platform_device* viuin_device = NULL;
  401. static int __init amvdec_viuin_init_module(void)
  402. {
  403. pr_dbg("amvdec_viuin module init\n");
  404. #if 1
  405. viuin_device = platform_device_alloc(DEVICE_NAME,0);
  406. if (!viuin_device) {
  407. pr_error("failed to alloc viuin_device\n");
  408. return -ENOMEM;
  409. }
  410. if(platform_device_add(viuin_device)){
  411. platform_device_put(viuin_device);
  412. pr_error("failed to add viuin_device\n");
  413. return -ENODEV;
  414. }
  415. if (platform_driver_register(&amvdec_viuin_driver)) {
  416. pr_error("failed to register amvdec_viuin driver\n");
  417. platform_device_del(viuin_device);
  418. platform_device_put(viuin_device);
  419. return -ENODEV;
  420. }
  421. #else
  422. if (platform_driver_register(&amvdec_viuin_driver)) {
  423. pr_error("failed to register amvdec_viuin driver\n");
  424. return -ENODEV;
  425. }
  426. #endif
  427. return 0;
  428. }
  429. static void __exit amvdec_viuin_exit_module(void)
  430. {
  431. pr_dbg("amvdec_viuin module remove.\n");
  432. platform_driver_unregister(&amvdec_viuin_driver);
  433. return ;
  434. }
  435. void vdin0_set_hscale(
  436. int src_w,
  437. int dst_w,
  438. int hsc_en,
  439. int prehsc_en,
  440. int hsc_bank_length,
  441. int hsc_rpt_p0_num,
  442. int hsc_ini_rcv_num,
  443. int hsc_ini_phase,
  444. int short_lineo_en
  445. )
  446. {
  447. const unsigned int filt_coef0[] = //bicubic
  448. {
  449. 0x00800000,
  450. 0x007f0100,
  451. 0xff7f0200,
  452. 0xfe7f0300,
  453. 0xfd7e0500,
  454. 0xfc7e0600,
  455. 0xfb7d0800,
  456. 0xfb7c0900,
  457. 0xfa7b0b00,
  458. 0xfa7a0dff,
  459. 0xf9790fff,
  460. 0xf97711ff,
  461. 0xf87613ff,
  462. 0xf87416fe,
  463. 0xf87218fe,
  464. 0xf8701afe,
  465. 0xf76f1dfd,
  466. 0xf76d1ffd,
  467. 0xf76b21fd,
  468. 0xf76824fd,
  469. 0xf76627fc,
  470. 0xf76429fc,
  471. 0xf7612cfc,
  472. 0xf75f2ffb,
  473. 0xf75d31fb,
  474. 0xf75a34fb,
  475. 0xf75837fa,
  476. 0xf7553afa,
  477. 0xf8523cfa,
  478. 0xf8503ff9,
  479. 0xf84d42f9,
  480. 0xf84a45f9,
  481. 0xf84848f8
  482. };
  483. const unsigned int filt_coef1[] = //2 point bilinear
  484. {
  485. 0x00800000,
  486. 0x007e0200,
  487. 0x007c0400,
  488. 0x007a0600,
  489. 0x00780800,
  490. 0x00760a00,
  491. 0x00740c00,
  492. 0x00720e00,
  493. 0x00701000,
  494. 0x006e1200,
  495. 0x006c1400,
  496. 0x006a1600,
  497. 0x00681800,
  498. 0x00661a00,
  499. 0x00641c00,
  500. 0x00621e00,
  501. 0x00602000,
  502. 0x005e2200,
  503. 0x005c2400,
  504. 0x005a2600,
  505. 0x00582800,
  506. 0x00562a00,
  507. 0x00542c00,
  508. 0x00522e00,
  509. 0x00503000,
  510. 0x004e3200,
  511. 0x004c3400,
  512. 0x004a3600,
  513. 0x00483800,
  514. 0x00463a00,
  515. 0x00443c00,
  516. 0x00423e00,
  517. 0x00404000
  518. };
  519. const unsigned int filt_coef2[] = //2 point bilinear, bank_length == 2
  520. {
  521. 0x80000000,
  522. 0x7e020000,
  523. 0x7c040000,
  524. 0x7a060000,
  525. 0x78080000,
  526. 0x760a0000,
  527. 0x740c0000,
  528. 0x720e0000,
  529. 0x70100000,
  530. 0x6e120000,
  531. 0x6c140000,
  532. 0x6a160000,
  533. 0x68180000,
  534. 0x661a0000,
  535. 0x641c0000,
  536. 0x621e0000,
  537. 0x60200000,
  538. 0x5e220000,
  539. 0x5c240000,
  540. 0x5a260000,
  541. 0x58280000,
  542. 0x562a0000,
  543. 0x542c0000,
  544. 0x522e0000,
  545. 0x50300000,
  546. 0x4e320000,
  547. 0x4c340000,
  548. 0x4a360000,
  549. 0x48380000,
  550. 0x463a0000,
  551. 0x443c0000,
  552. 0x423e0000,
  553. 0x40400000
  554. };
  555. int i;
  556. int horz_phase_step;
  557. int p_src_w;
  558. int ini_pixi_ptr;
  559. //write horz filter coefs
  560. WRITE_MPEG_REG (VDIN_SCALE_COEF_IDX, 0x0100);
  561. for (i = 0; i < 33; i++)
  562. {
  563. WRITE_MPEG_REG(VDIN_SCALE_COEF, filt_coef0[i]); //bicubic
  564. }
  565. p_src_w = (prehsc_en ? ((src_w+1) >>1) : src_w);
  566. horz_phase_step = (p_src_w << 20) / dst_w;
  567. horz_phase_step = (horz_phase_step << 4);
  568. WRITE_MPEG_REG(VDIN_WIDTHM1I_WIDTHM1O, ((src_w - 1) << 16) |
  569. (dst_w - 1)
  570. );
  571. WRITE_MPEG_REG(VDIN_HSC_PHASE_STEP, horz_phase_step);
  572. WRITE_MPEG_REG(VDIN_HSC_INI_CTRL, (hsc_rpt_p0_num << 29) |
  573. (hsc_ini_rcv_num << 24) |
  574. (hsc_ini_phase << 0)
  575. );
  576. ini_pixi_ptr = 0;
  577. WRITE_MPEG_REG(VDIN_SC_MISC_CTRL,
  578. (ini_pixi_ptr << 8) |
  579. (prehsc_en << 7) |
  580. (hsc_en << 6) |
  581. (short_lineo_en << 5) |
  582. (0 << 4) | //nearest_en
  583. (0 << 3) | //phase0_always_en
  584. (hsc_bank_length << 0)
  585. );
  586. }
  587. EXPORT_SYMBOL(vdin0_set_hscale);
  588. module_init(amvdec_viuin_init_module);
  589. module_exit(amvdec_viuin_exit_module);