vmpeg12.c 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758
  1. /*
  2. * AMLOGIC Audio/Video streaming port driver.
  3. *
  4. * This program is free software; you can redistribute it and/or modify
  5. * it under the terms of the GNU General Public License as published by
  6. * the Free Software Foundation; either version 2 of the named License,
  7. * or any later version.
  8. *
  9. * This program is distributed in the hope that it will be useful,
  10. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. * GNU General Public License for more details.
  13. *
  14. * You should have received a copy of the GNU General Public License
  15. * along with this program; if not, write to the Free Software
  16. * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA
  17. *
  18. * Author: Tim Yao <timyao@amlogic.com>
  19. *
  20. */
  21. #include <linux/kernel.h>
  22. #include <linux/types.h>
  23. #include <linux/errno.h>
  24. #include <linux/interrupt.h>
  25. #include <linux/timer.h>
  26. #include <linux/platform_device.h>
  27. #include <linux/amports/ptsserv.h>
  28. #include <linux/amports/amstream.h>
  29. #include <linux/amports/canvas.h>
  30. #include <linux/amports/vframe.h>
  31. #include <linux/amports/vfp.h>
  32. #include <linux/amports/vframe_provider.h>
  33. #include <linux/amports/vframe_receiver.h>
  34. #include <mach/am_regs.h>
  35. #include <plat/io.h>
  36. #include "vdec_reg.h"
  37. #include "vmpeg12.h"
  38. #ifdef CONFIG_AM_VDEC_MPEG12_LOG
  39. #define AMLOG
  40. #define LOG_LEVEL_VAR amlog_level_vmpeg
  41. #define LOG_MASK_VAR amlog_mask_vmpeg
  42. #define LOG_LEVEL_ERROR 0
  43. #define LOG_LEVEL_INFO 1
  44. #define LOG_LEVEL_DESC "0:ERROR, 1:INFO"
  45. #endif
  46. #include <linux/amlog.h>
  47. MODULE_AMLOG(LOG_LEVEL_ERROR, 0, LOG_LEVEL_DESC, LOG_DEFAULT_MASK_DESC);
  48. #include "amvdec.h"
  49. #include "vmpeg12_mc.h"
  50. #define DRIVER_NAME "amvdec_mpeg12"
  51. #define MODULE_NAME "amvdec_mpeg12"
  52. /* protocol registers */
  53. #define MREG_SEQ_INFO AV_SCRATCH_4
  54. #define MREG_PIC_INFO AV_SCRATCH_5
  55. #define MREG_PIC_WIDTH AV_SCRATCH_6
  56. #define MREG_PIC_HEIGHT AV_SCRATCH_7
  57. #define MREG_BUFFERIN AV_SCRATCH_8
  58. #define MREG_BUFFEROUT AV_SCRATCH_9
  59. #define MREG_CMD AV_SCRATCH_A
  60. #define MREG_CO_MV_START AV_SCRATCH_B
  61. #define MREG_ERROR_COUNT AV_SCRATCH_C
  62. #define MREG_FRAME_OFFSET AV_SCRATCH_D
  63. #define PICINFO_ERROR 0x80000000
  64. #define PICINFO_TYPE_MASK 0x00030000
  65. #define PICINFO_TYPE_I 0x00000000
  66. #define PICINFO_TYPE_P 0x00010000
  67. #define PICINFO_TYPE_B 0x00020000
  68. #define PICINFO_PROG 0x8000
  69. #define PICINFO_RPT_FIRST 0x4000
  70. #define PICINFO_TOP_FIRST 0x2000
  71. #define SEQINFO_EXT_AVAILABLE 0x80000000
  72. #define SEQINFO_PROG 0x00010000
  73. #define VF_POOL_SIZE 12
  74. #define PUT_INTERVAL HZ/100
  75. #define INCPTR(p) ptr_atomic_wrap_inc(&p)
  76. #define STAT_TIMER_INIT 0x01
  77. #define STAT_MC_LOAD 0x02
  78. #define STAT_ISR_REG 0x04
  79. #define STAT_VF_HOOK 0x08
  80. #define STAT_TIMER_ARM 0x10
  81. #define STAT_VDEC_RUN 0x20
  82. #ifdef CONFIG_ARCH_MESON6
  83. #define NV21
  84. #endif
  85. static vframe_t *vmpeg_vf_peek(void*);
  86. static vframe_t *vmpeg_vf_get(void*);
  87. static void vmpeg_vf_put(vframe_t *, void*);
  88. static int vmpeg_vf_states(vframe_states_t *states, void*);
  89. static int vmpeg_event_cb(int type, void *data, void *private_data);
  90. static void vmpeg12_prot_init(void);
  91. static void vmpeg12_local_init(void);
  92. static const char vmpeg12_dec_id[] = "vmpeg12-dev";
  93. #define PROVIDER_NAME "decoder.mpeg12"
  94. static const struct vframe_operations_s vmpeg_vf_provider =
  95. {
  96. .peek = vmpeg_vf_peek,
  97. .get = vmpeg_vf_get,
  98. .put = vmpeg_vf_put,
  99. .event_cb = vmpeg_event_cb,
  100. .vf_states = vmpeg_vf_states,
  101. };
  102. static struct vframe_provider_s vmpeg_vf_prov;
  103. static const u32 frame_rate_tab[16] = {
  104. 96000 / 30, 96000 / 24, 96000 / 24, 96000 / 25,
  105. 96000 / 30, 96000 / 30, 96000 / 50, 96000 / 60,
  106. 96000 / 60,
  107. /* > 8 reserved, use 24 */
  108. 96000 / 24, 96000 / 24, 96000 / 24, 96000 / 24,
  109. 96000 / 24, 96000 / 24, 96000 / 24
  110. };
  111. static struct vframe_s vfqool[VF_POOL_SIZE];
  112. static s32 vfbuf_use[VF_POOL_SIZE];
  113. static struct vframe_s *vfp_pool_newframe[VF_POOL_SIZE+1];
  114. static struct vframe_s *vfp_pool_display[VF_POOL_SIZE+1];
  115. static struct vframe_s *vfp_pool_recycle[VF_POOL_SIZE+1];
  116. static vfq_t newframe_q, display_q, recycle_q;
  117. static u32 frame_width, frame_height, frame_dur, frame_prog;
  118. static struct timer_list recycle_timer;
  119. static u32 stat;
  120. static u32 buf_start, buf_size;
  121. static DEFINE_SPINLOCK(lock);
  122. /* for error handling */
  123. static s32 frame_force_skip_flag = 0;
  124. static s32 error_frame_skip_level = 0;
  125. static inline u32 index2canvas(u32 index)
  126. {
  127. const u32 canvas_tab[4] = {
  128. #ifdef NV21
  129. 0x010100, 0x030302, 0x050504, 0x070706
  130. #else
  131. 0x020100, 0x050403, 0x080706, 0x0b0a09
  132. #endif
  133. };
  134. return canvas_tab[index];
  135. }
  136. static void set_frame_info(vframe_t *vf)
  137. {
  138. unsigned ar_bits;
  139. #ifdef CONFIG_AM_VDEC_MPEG12_LOG
  140. bool first = (frame_width == 0) && (frame_height == 0);
  141. #endif
  142. vf->width = frame_width = READ_VREG(MREG_PIC_WIDTH);
  143. vf->height = frame_height = READ_VREG(MREG_PIC_HEIGHT);
  144. if (frame_dur > 0) {
  145. vf->duration = frame_dur;
  146. } else {
  147. vf->duration = frame_dur =
  148. frame_rate_tab[(READ_VREG(MREG_SEQ_INFO) >> 4) & 0xf];
  149. }
  150. ar_bits = READ_VREG(MREG_SEQ_INFO) & 0xf;
  151. if (ar_bits == 0x2) {
  152. vf->ratio_control = 0xc0 << DISP_RATIO_ASPECT_RATIO_BIT;
  153. } else if (ar_bits == 0x3) {
  154. vf->ratio_control = 0x90 << DISP_RATIO_ASPECT_RATIO_BIT;
  155. } else if (ar_bits == 0x4) {
  156. vf->ratio_control = 0x74 << DISP_RATIO_ASPECT_RATIO_BIT;
  157. } else {
  158. vf->ratio_control = 0;
  159. }
  160. amlog_level_if(first, LOG_LEVEL_INFO, "mpeg2dec: w(%d), h(%d), dur(%d), dur-ES(%d)\n",
  161. frame_width,
  162. frame_height,
  163. frame_dur,
  164. frame_rate_tab[(READ_VREG(MREG_SEQ_INFO) >> 4) & 0xf]);
  165. }
  166. static bool error_skip(u32 info, vframe_t *vf)
  167. {
  168. if (error_frame_skip_level) {
  169. /* skip error frame */
  170. if ((info & PICINFO_ERROR) || (frame_force_skip_flag)) {
  171. if ((info & PICINFO_ERROR) == 0) {
  172. if ((info & PICINFO_TYPE_MASK) == PICINFO_TYPE_I) {
  173. frame_force_skip_flag = 0;
  174. }
  175. } else {
  176. if (error_frame_skip_level >= 2) {
  177. frame_force_skip_flag = 1;
  178. }
  179. }
  180. if ((info & PICINFO_ERROR) || (frame_force_skip_flag)) {
  181. return true;
  182. }
  183. }
  184. }
  185. return false;
  186. }
  187. static irqreturn_t vmpeg12_isr(int irq, void *dev_id)
  188. {
  189. u32 reg, info, seqinfo, offset, pts, pts_valid = 0;
  190. vframe_t *vf;
  191. ulong flags;
  192. WRITE_VREG(ASSIST_MBOX1_CLR_REG, 1);
  193. reg = READ_VREG(MREG_BUFFEROUT);
  194. if (reg) {
  195. info = READ_VREG(MREG_PIC_INFO);
  196. offset = READ_VREG(MREG_FRAME_OFFSET);
  197. if (((info & PICINFO_TYPE_MASK) == PICINFO_TYPE_I) &&
  198. (pts_lookup_offset(PTS_TYPE_VIDEO, offset, &pts, 0) == 0)) {
  199. pts_valid = 1;
  200. }
  201. /*if (frame_prog == 0)*/ {
  202. frame_prog = info & PICINFO_PROG;
  203. }
  204. if (frame_prog & PICINFO_PROG) {
  205. u32 index = ((reg & 7) - 1) & 3;
  206. seqinfo = READ_VREG(MREG_SEQ_INFO);
  207. vf = vfq_pop(&newframe_q);
  208. set_frame_info(vf);
  209. vf->index = index;
  210. #ifdef NV21
  211. vf->type = VIDTYPE_PROGRESSIVE | VIDTYPE_VIU_FIELD | VIDTYPE_VIU_NV21;
  212. #else
  213. vf->type = VIDTYPE_PROGRESSIVE | VIDTYPE_VIU_FIELD;
  214. #endif
  215. if ((seqinfo & SEQINFO_EXT_AVAILABLE) && (seqinfo & SEQINFO_PROG)) {
  216. if (info & PICINFO_RPT_FIRST) {
  217. if (info & PICINFO_TOP_FIRST) {
  218. vf->duration = vf->duration * 3; // repeat three times
  219. } else {
  220. vf->duration = vf->duration * 2; // repeat two times
  221. }
  222. }
  223. vf->duration_pulldown = 0; // no pull down
  224. } else {
  225. vf->duration_pulldown = (info & PICINFO_RPT_FIRST) ?
  226. vf->duration >> 1 : 0;
  227. }
  228. vf->duration += vf->duration_pulldown;
  229. vf->canvas0Addr = vf->canvas1Addr = index2canvas(index);
  230. vf->pts = (pts_valid) ? pts : 0;
  231. vfbuf_use[index]++;
  232. if (error_skip(info, vf)) {
  233. spin_lock_irqsave(&lock, flags);
  234. vfq_push(&recycle_q, vf);
  235. spin_unlock_irqrestore(&lock, flags);
  236. } else {
  237. vfq_push(&display_q, vf);
  238. }
  239. vf_notify_receiver(PROVIDER_NAME,VFRAME_EVENT_PROVIDER_VFRAME_READY,NULL);
  240. } else {
  241. u32 index = ((reg & 7) - 1) & 3;
  242. vf = vfq_pop(&newframe_q);
  243. vfbuf_use[index] += 2;
  244. set_frame_info(vf);
  245. vf->index = index;
  246. vf->type = (info & PICINFO_TOP_FIRST) ?
  247. VIDTYPE_INTERLACE_TOP : VIDTYPE_INTERLACE_BOTTOM;
  248. #ifdef NV21
  249. vf->type |= VIDTYPE_VIU_NV21;
  250. #endif
  251. vf->duration >>= 1;
  252. vf->duration_pulldown = (info & PICINFO_RPT_FIRST) ?
  253. vf->duration >> 1 : 0;
  254. vf->duration += vf->duration_pulldown;
  255. vf->canvas0Addr = vf->canvas1Addr = index2canvas(index);
  256. vf->pts = (pts_valid) ? pts : 0;
  257. if (error_skip(info, vf)) {
  258. vfq_push(&recycle_q, vf);
  259. } else {
  260. vfq_push(&display_q, vf);
  261. vf_notify_receiver(PROVIDER_NAME,VFRAME_EVENT_PROVIDER_VFRAME_READY,NULL);
  262. }
  263. vf = vfq_pop(&newframe_q);
  264. set_frame_info(vf);
  265. vf->index = index;
  266. vf->type = (info & PICINFO_TOP_FIRST) ?
  267. VIDTYPE_INTERLACE_BOTTOM : VIDTYPE_INTERLACE_TOP;
  268. #ifdef NV21
  269. vf->type |= VIDTYPE_VIU_NV21;
  270. #endif
  271. vf->duration >>= 1;
  272. vf->duration_pulldown = (info & PICINFO_RPT_FIRST) ?
  273. vf->duration >> 1 : 0;
  274. vf->duration += vf->duration_pulldown;
  275. vf->canvas0Addr = vf->canvas1Addr = index2canvas(index);
  276. vf->pts = 0;
  277. if (error_skip(info, vf)) {
  278. vfq_push(&recycle_q, vf);
  279. } else {
  280. vfq_push(&display_q, vf);
  281. vf_notify_receiver(PROVIDER_NAME,VFRAME_EVENT_PROVIDER_VFRAME_READY,NULL);
  282. }
  283. }
  284. WRITE_VREG(MREG_BUFFEROUT, 0);
  285. }
  286. return IRQ_HANDLED;
  287. }
  288. static vframe_t *vmpeg_vf_peek(void* op_arg)
  289. {
  290. return vfq_peek(&display_q);
  291. }
  292. static vframe_t *vmpeg_vf_get(void* op_arg)
  293. {
  294. return vfq_pop(&display_q);
  295. }
  296. static void vmpeg_vf_put(vframe_t *vf, void* op_arg)
  297. {
  298. vfq_push(&recycle_q, vf);
  299. }
  300. static int vmpeg_event_cb(int type, void *data, void *private_data)
  301. {
  302. if(type & VFRAME_EVENT_RECEIVER_RESET){
  303. unsigned long flags;
  304. amvdec_stop();
  305. #ifndef CONFIG_POST_PROCESS_MANAGER
  306. vf_light_unreg_provider(&vmpeg_vf_prov);
  307. #endif
  308. spin_lock_irqsave(&lock, flags);
  309. vmpeg12_local_init();
  310. vmpeg12_prot_init();
  311. spin_unlock_irqrestore(&lock, flags);
  312. #ifndef CONFIG_POST_PROCESS_MANAGER
  313. vf_reg_provider(&vmpeg_vf_prov);
  314. #endif
  315. amvdec_start();
  316. }
  317. return 0;
  318. }
  319. static int vmpeg_vf_states(vframe_states_t *states, void* op_arg)
  320. {
  321. unsigned long flags;
  322. spin_lock_irqsave(&lock, flags);
  323. states->vf_pool_size = VF_POOL_SIZE;
  324. states->buf_recycle_num = vfq_level(&recycle_q);
  325. states->buf_free_num = vfq_level(&newframe_q);
  326. states->buf_avail_num = vfq_level(&display_q);
  327. spin_unlock_irqrestore(&lock, flags);
  328. return 0;
  329. }
  330. static void vmpeg_put_timer_func(unsigned long arg)
  331. {
  332. struct timer_list *timer = (struct timer_list *)arg;
  333. while (!vfq_empty(&recycle_q) && (READ_VREG(MREG_BUFFERIN) == 0)) {
  334. vframe_t *vf = vfq_pop(&recycle_q);
  335. if (--vfbuf_use[vf->index] == 0) {
  336. WRITE_VREG(MREG_BUFFERIN, vf->index + 1);
  337. }
  338. vfq_push(&newframe_q, vf);
  339. }
  340. timer->expires = jiffies + PUT_INTERVAL;
  341. add_timer(timer);
  342. }
  343. int vmpeg12_dec_status(struct vdec_status *vstatus)
  344. {
  345. vstatus->width = frame_width;
  346. vstatus->height = frame_height;
  347. if (frame_dur != 0) {
  348. vstatus->fps = 96000 / frame_dur;
  349. } else {
  350. vstatus->fps = 96000;
  351. }
  352. vstatus->error_count = READ_VREG(AV_SCRATCH_C);
  353. vstatus->status = stat;
  354. return 0;
  355. }
  356. /****************************************/
  357. static void vmpeg12_canvas_init(void)
  358. {
  359. int i;
  360. u32 canvas_width, canvas_height;
  361. u32 decbuf_size, decbuf_y_size, decbuf_uv_size;
  362. u32 disp_addr = 0xffffffff;
  363. if (buf_size <= 0x00400000) {
  364. /* SD only */
  365. canvas_width = 768;
  366. canvas_height = 576;
  367. decbuf_y_size = 0x80000;
  368. decbuf_uv_size = 0x20000;
  369. decbuf_size = 0x100000;
  370. } else {
  371. /* HD & SD */
  372. canvas_width = 1920;
  373. canvas_height = 1088;
  374. decbuf_y_size = 0x200000;
  375. decbuf_uv_size = 0x80000;
  376. decbuf_size = 0x300000;
  377. }
  378. if (READ_MPEG_REG(VPP_MISC) & VPP_VD1_POSTBLEND) {
  379. canvas_t cur_canvas;
  380. canvas_read((READ_MPEG_REG(VD1_IF0_CANVAS0) & 0xff), &cur_canvas);
  381. disp_addr = (cur_canvas.addr + 7) >> 3;
  382. }
  383. for (i = 0; i < 4; i++) {
  384. if (((buf_start + i * decbuf_size + 7) >> 3) == disp_addr) {
  385. #ifdef NV21
  386. canvas_config(2 * i + 0,
  387. buf_start + 4 * decbuf_size,
  388. canvas_width, canvas_height,
  389. CANVAS_ADDR_NOWRAP, CANVAS_BLKMODE_32X32);
  390. canvas_config(2 * i + 1,
  391. buf_start + 4 * decbuf_size + decbuf_y_size,
  392. canvas_width, canvas_height / 2,
  393. CANVAS_ADDR_NOWRAP, CANVAS_BLKMODE_32X32);
  394. #else
  395. canvas_config(3 * i + 0,
  396. buf_start + 4 * decbuf_size,
  397. canvas_width, canvas_height,
  398. CANVAS_ADDR_NOWRAP, CANVAS_BLKMODE_32X32);
  399. canvas_config(3 * i + 1,
  400. buf_start + 4 * decbuf_size + decbuf_y_size,
  401. canvas_width / 2, canvas_height / 2,
  402. CANVAS_ADDR_NOWRAP, CANVAS_BLKMODE_32X32);
  403. canvas_config(3 * i + 2,
  404. buf_start + 4 * decbuf_size + decbuf_y_size + decbuf_uv_size,
  405. canvas_width / 2, canvas_height / 2,
  406. CANVAS_ADDR_NOWRAP, CANVAS_BLKMODE_32X32);
  407. #endif
  408. } else {
  409. #ifdef NV21
  410. canvas_config(2 * i + 0,
  411. buf_start + i * decbuf_size,
  412. canvas_width, canvas_height,
  413. CANVAS_ADDR_NOWRAP, CANVAS_BLKMODE_32X32);
  414. canvas_config(2 * i + 1,
  415. buf_start + i * decbuf_size + decbuf_y_size,
  416. canvas_width, canvas_height / 2,
  417. CANVAS_ADDR_NOWRAP, CANVAS_BLKMODE_32X32);
  418. #else
  419. canvas_config(3 * i + 0,
  420. buf_start + i * decbuf_size,
  421. canvas_width, canvas_height,
  422. CANVAS_ADDR_NOWRAP, CANVAS_BLKMODE_32X32);
  423. canvas_config(3 * i + 1,
  424. buf_start + i * decbuf_size + decbuf_y_size,
  425. canvas_width / 2, canvas_height / 2,
  426. CANVAS_ADDR_NOWRAP, CANVAS_BLKMODE_32X32);
  427. canvas_config(3 * i + 2,
  428. buf_start + i * decbuf_size + decbuf_y_size + decbuf_uv_size,
  429. canvas_width / 2, canvas_height / 2,
  430. CANVAS_ADDR_NOWRAP, CANVAS_BLKMODE_32X32);
  431. #endif
  432. }
  433. }
  434. WRITE_VREG(MREG_CO_MV_START, buf_start + 4 * decbuf_size);
  435. }
  436. static void vmpeg12_prot_init(void)
  437. {
  438. #ifdef CONFIG_ARCH_MESON6
  439. WRITE_VREG(DOS_SW_RESET0, (1<<7) | (1<<6));
  440. WRITE_VREG(DOS_SW_RESET0, 0);
  441. #else
  442. WRITE_MPEG_REG(RESET0_REGISTER, RESET_IQIDCT | RESET_MC);
  443. #endif
  444. vmpeg12_canvas_init();
  445. #ifdef NV21
  446. WRITE_VREG(AV_SCRATCH_0, 0x010100);
  447. WRITE_VREG(AV_SCRATCH_1, 0x030302);
  448. WRITE_VREG(AV_SCRATCH_2, 0x050504);
  449. WRITE_VREG(AV_SCRATCH_3, 0x070706);
  450. #else
  451. WRITE_VREG(AV_SCRATCH_0, 0x020100);
  452. WRITE_VREG(AV_SCRATCH_1, 0x050403);
  453. WRITE_VREG(AV_SCRATCH_2, 0x080706);
  454. WRITE_VREG(AV_SCRATCH_3, 0x0b0a09);
  455. #endif
  456. /* set to mpeg1 default */
  457. WRITE_VREG(MPEG1_2_REG, 0);
  458. /* disable PSCALE for hardware sharing */
  459. WRITE_VREG(PSCALE_CTRL, 0);
  460. /* for Mpeg1 default value */
  461. WRITE_VREG(PIC_HEAD_INFO, 0x380);
  462. /* disable mpeg4 */
  463. WRITE_VREG(M4_CONTROL_REG, 0);
  464. /* clear mailbox interrupt */
  465. WRITE_VREG(ASSIST_MBOX1_CLR_REG, 1);
  466. /* clear buffer IN/OUT registers */
  467. WRITE_VREG(MREG_BUFFERIN, 0);
  468. WRITE_VREG(MREG_BUFFEROUT, 0);
  469. /* set reference width and height */
  470. if ((frame_width != 0) && (frame_height != 0)) {
  471. WRITE_VREG(MREG_CMD, (frame_width << 16) | frame_height);
  472. } else {
  473. WRITE_VREG(MREG_CMD, 0);
  474. }
  475. /* clear error count */
  476. WRITE_VREG(MREG_ERROR_COUNT, 0);
  477. #ifdef NV21
  478. SET_VREG_MASK(MDEC_PIC_DC_CTRL, 1<<17);
  479. #endif
  480. }
  481. static void vmpeg12_local_init(void)
  482. {
  483. int i;
  484. vfq_init(&display_q, VF_POOL_SIZE+1, &vfp_pool_display[0]);
  485. vfq_init(&recycle_q, VF_POOL_SIZE+1, &vfp_pool_recycle[0]);
  486. vfq_init(&newframe_q, VF_POOL_SIZE+1, &vfp_pool_newframe[0]);
  487. for (i = 0; i < VF_POOL_SIZE; i++) {
  488. vfq_push(&newframe_q, &vfqool[i]);
  489. }
  490. frame_width = frame_height = frame_dur = frame_prog = 0;
  491. for (i = 0; i < 4; i++) {
  492. vfbuf_use[i] = 0;
  493. }
  494. frame_force_skip_flag = 0;
  495. }
  496. static s32 vmpeg12_init(void)
  497. {
  498. int r;
  499. init_timer(&recycle_timer);
  500. stat |= STAT_TIMER_INIT;
  501. vmpeg12_local_init();
  502. amvdec_enable();
  503. if (amvdec_loadmc(vmpeg12_mc) < 0) {
  504. amvdec_disable();
  505. return -EBUSY;
  506. }
  507. stat |= STAT_MC_LOAD;
  508. /* enable AMRISC side protocol */
  509. vmpeg12_prot_init();
  510. r = request_irq(INT_MAILBOX_1A, vmpeg12_isr,
  511. IRQF_SHARED, "vmpeg12-irq", (void *)vmpeg12_dec_id);
  512. if (r) {
  513. amvdec_disable();
  514. amlog_level(LOG_LEVEL_ERROR, "vmpeg12 irq register error.\n");
  515. return -ENOENT;
  516. }
  517. stat |= STAT_ISR_REG;
  518. #ifdef CONFIG_POST_PROCESS_MANAGER
  519. vf_provider_init(&vmpeg_vf_prov, PROVIDER_NAME, &vmpeg_vf_provider, NULL);
  520. vf_reg_provider(&vmpeg_vf_prov);
  521. vf_notify_receiver(PROVIDER_NAME,VFRAME_EVENT_PROVIDER_START,NULL);
  522. #else
  523. vf_provider_init(&vmpeg_vf_prov, PROVIDER_NAME, &vmpeg_vf_provider, NULL);
  524. vf_reg_provider(&vmpeg_vf_prov);
  525. #endif
  526. stat |= STAT_VF_HOOK;
  527. recycle_timer.data = (ulong)&recycle_timer;
  528. recycle_timer.function = vmpeg_put_timer_func;
  529. recycle_timer.expires = jiffies + PUT_INTERVAL;
  530. add_timer(&recycle_timer);
  531. stat |= STAT_TIMER_ARM;
  532. amvdec_start();
  533. stat |= STAT_VDEC_RUN;
  534. set_vdec_func(&vmpeg12_dec_status);
  535. return 0;
  536. }
  537. static int amvdec_mpeg12_probe(struct platform_device *pdev)
  538. {
  539. struct resource *mem;
  540. amlog_level(LOG_LEVEL_INFO, "amvdec_mpeg12 probe start.\n");
  541. if (!(mem = platform_get_resource(pdev, IORESOURCE_MEM, 0))) {
  542. amlog_level(LOG_LEVEL_ERROR, "amvdec_mpeg12 memory resource undefined.\n");
  543. return -EFAULT;
  544. }
  545. buf_start = mem->start;
  546. buf_size = mem->end - mem->start + 1;
  547. if (vmpeg12_init() < 0) {
  548. amlog_level(LOG_LEVEL_ERROR, "amvdec_mpeg12 init failed.\n");
  549. return -ENODEV;
  550. }
  551. amlog_level(LOG_LEVEL_INFO, "amvdec_mpeg12 probe end.\n");
  552. return 0;
  553. }
  554. static int amvdec_mpeg12_remove(struct platform_device *pdev)
  555. {
  556. if (stat & STAT_VDEC_RUN) {
  557. amvdec_stop();
  558. stat &= ~STAT_VDEC_RUN;
  559. }
  560. if (stat & STAT_ISR_REG) {
  561. free_irq(INT_MAILBOX_1A, (void *)vmpeg12_dec_id);
  562. stat &= ~STAT_ISR_REG;
  563. }
  564. if (stat & STAT_TIMER_ARM) {
  565. del_timer_sync(&recycle_timer);
  566. stat &= ~STAT_TIMER_ARM;
  567. }
  568. if (stat & STAT_VF_HOOK) {
  569. ulong flags;
  570. spin_lock_irqsave(&lock, flags);
  571. vfq_init(&display_q, VF_POOL_SIZE+1, &vfp_pool_display[0]);
  572. vfq_init(&recycle_q, VF_POOL_SIZE+1, &vfp_pool_recycle[0]);
  573. vfq_init(&newframe_q, VF_POOL_SIZE+1, &vfp_pool_newframe[0]);
  574. spin_unlock_irqrestore(&lock, flags);
  575. vf_unreg_provider(&vmpeg_vf_prov);
  576. stat &= ~STAT_VF_HOOK;
  577. }
  578. amvdec_disable();
  579. amlog_level(LOG_LEVEL_INFO, "amvdec_mpeg12 remove.\n");
  580. return 0;
  581. }
  582. /****************************************/
  583. static struct platform_driver amvdec_mpeg12_driver = {
  584. .probe = amvdec_mpeg12_probe,
  585. .remove = amvdec_mpeg12_remove,
  586. #ifdef CONFIG_PM
  587. .suspend = amvdec_suspend,
  588. .resume = amvdec_resume,
  589. #endif
  590. .driver = {
  591. .name = DRIVER_NAME,
  592. }
  593. };
  594. static struct codec_profile_t amvdec_mpeg12_profile = {
  595. .name = "mpeg12",
  596. .profile = ""
  597. };
  598. static int __init amvdec_mpeg12_driver_init_module(void)
  599. {
  600. amlog_level(LOG_LEVEL_INFO, "amvdec_mpeg12 module init\n");
  601. if (platform_driver_register(&amvdec_mpeg12_driver)) {
  602. amlog_level(LOG_LEVEL_ERROR, "failed to register amvdec_mpeg12 driver\n");
  603. return -ENODEV;
  604. }
  605. vcodec_profile_register(&amvdec_mpeg12_profile);
  606. return 0;
  607. }
  608. static void __exit amvdec_mpeg12_driver_remove_module(void)
  609. {
  610. amlog_level(LOG_LEVEL_INFO, "amvdec_mpeg12 module remove.\n");
  611. platform_driver_unregister(&amvdec_mpeg12_driver);
  612. }
  613. /****************************************/
  614. module_param(stat, uint, 0664);
  615. MODULE_PARM_DESC(stat, "\n amvdec_mpeg12 stat \n");
  616. module_init(amvdec_mpeg12_driver_init_module);
  617. module_exit(amvdec_mpeg12_driver_remove_module);
  618. MODULE_DESCRIPTION("AMLOGIC MPEG1/2 Video Decoder Driver");
  619. MODULE_LICENSE("GPL");
  620. MODULE_AUTHOR("Tim Yao <timyao@amlogic.com>");