vreal.c 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895
  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: Chen Zhang <chen.zhang@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/fs.h>
  27. #include <linux/platform_device.h>
  28. #include <linux/dma-mapping.h>
  29. #include <linux/amports/amstream.h>
  30. #include <linux/amports/ptsserv.h>
  31. #include <linux/amports/canvas.h>
  32. #include <linux/amports/vframe.h>
  33. #include <linux/amports/vframe_provider.h>
  34. #include <linux/amports/vframe_receiver.h>
  35. #include <mach/am_regs.h>
  36. #include <asm/uaccess.h>
  37. #include <plat/io.h>
  38. #include "vdec_reg.h"
  39. #include "vreal.h"
  40. #include "amvdec.h"
  41. #include "vreal_mc.h"
  42. #include "streambuf.h"
  43. #include "streambuf_reg.h"
  44. #include "rmparser.h"
  45. #include "vreal.h"
  46. #define DRIVER_NAME "amvdec_real"
  47. #define MODULE_NAME "amvdec_real"
  48. #define HANDLE_REAL_IRQ
  49. #ifdef CONFIG_ARCH_MESON6
  50. #define NV21
  51. #endif
  52. #define RM_DEF_BUFFER_ADDR 0x81000000
  53. /* protocol registers */
  54. #define STATUS_AMRISC AV_SCRATCH_4
  55. #define PARSER_ERROR_WRONG_PACKAGE_SIZE 0x80
  56. #define PARSER_ERROR_WRONG_HEAD_VER 0x40
  57. #define DECODER_ERROR_VLC_DECODE_TBL 0x20
  58. #define RV_PIC_INFO AV_SCRATCH_5
  59. #define VPTS_TR AV_SCRATCH_6
  60. #define VDTS AV_SCRATCH_7
  61. #define FROM_AMRISC AV_SCRATCH_8
  62. #define TO_AMRISC AV_SCRATCH_9
  63. #define SKIP_B_AMRISC AV_SCRATCH_A
  64. #ifdef CONFIG_ARCH_MESON6
  65. #define MDEC_WIDTH AV_SCRATCH_I
  66. #define MDEC_HEIGHT AV_SCRATCH_J
  67. #else
  68. #define MDEC_WIDTH HARM_ASB_MB2
  69. #define MDEC_HEIGHT HASB_ARM_MB0
  70. #endif
  71. #define PARC_FORBIDDEN 0
  72. #define PARC_SQUARE 1
  73. #define PARC_CIF 2
  74. #define PARC_10_11 3
  75. #define PARC_16_11 4
  76. #define PARC_40_33 5
  77. #define PARC_RESERVED 6
  78. /* values between 6 and 14 are reserved */
  79. #define PARC_EXTENDED 15
  80. #define VF_POOL_SIZE 12
  81. #define VF_BUF_NUM 4
  82. #define PUT_INTERVAL HZ/100
  83. #define INCPTR(p) ptr_atomic_wrap_inc(&p)
  84. #define STAT_TIMER_INIT 0x01
  85. #define STAT_MC_LOAD 0x02
  86. #define STAT_ISR_REG 0x04
  87. #define STAT_VF_HOOK 0x08
  88. #define STAT_TIMER_ARM 0x10
  89. #define STAT_VDEC_RUN 0x20
  90. #define REAL_RECYCLE_Q_BITS 3
  91. #define REAL_RECYCLE_Q_SIZE (1<<(REAL_RECYCLE_Q_BITS))
  92. #define REAL_RECYCLE_Q_MASK ((REAL_RECYCLE_Q_SIZE)-1)
  93. static vframe_t *vreal_vf_peek(void*);
  94. static vframe_t *vreal_vf_get(void*);
  95. static void vreal_vf_put(vframe_t *, void*);
  96. static int vreal_vf_states(vframe_states_t *states, void*);
  97. static int vreal_event_cb(int type, void *data, void *private_data);
  98. static void vreal_prot_init(void);
  99. static void vreal_local_init(void);
  100. static const char vreal_dec_id[] = "vreal-dev";
  101. #define PROVIDER_NAME "decoder.real"
  102. static const struct vframe_operations_s vreal_vf_provider = {
  103. .peek = vreal_vf_peek,
  104. .get = vreal_vf_get,
  105. .put = vreal_vf_put,
  106. .event_cb = vreal_event_cb,
  107. .vf_states = vreal_vf_states,
  108. };
  109. static struct vframe_provider_s vreal_vf_prov;
  110. static struct vframe_s vfpool[VF_POOL_SIZE];
  111. static u32 vfpool_idx[VF_POOL_SIZE];
  112. static s32 vfbuf_use[4];
  113. static s32 fill_ptr, get_ptr, putting_ptr, put_ptr;
  114. static u32 frame_width, frame_height, frame_dur, frame_prog;
  115. static struct timer_list recycle_timer;
  116. static u32 stat;
  117. static u32 buf_start, buf_size, buf_offset;
  118. static u32 vreal_ratio;
  119. u32 vreal_format;
  120. static u32 wait_key_frame;
  121. static u32 last_tr;
  122. static u32 frame_count;
  123. static u32 current_vdts;
  124. static u32 hold;
  125. static u32 decoder_state;
  126. static u32 real_err_count;
  127. static u32 real_recycle_q[REAL_RECYCLE_Q_SIZE];
  128. static u32 real_recycle_rd;
  129. static u32 real_recycle_wr;
  130. static DEFINE_SPINLOCK(lock);
  131. static unsigned short pic_sz_tbl[12] __attribute__((aligned(32)));
  132. static dma_addr_t pic_sz_tbl_map;
  133. static const unsigned char RPR_size[9] = {0, 1, 1, 2, 2, 3, 3, 3, 3};
  134. static struct dec_sysinfo vreal_amstream_dec_info;
  135. static unsigned char aspect_ratio_table[16] = {
  136. PARC_FORBIDDEN,
  137. PARC_SQUARE,
  138. PARC_CIF,
  139. PARC_10_11,
  140. PARC_16_11,
  141. PARC_40_33,
  142. PARC_RESERVED, PARC_RESERVED, PARC_RESERVED, PARC_RESERVED,
  143. PARC_RESERVED, PARC_RESERVED, PARC_RESERVED, PARC_RESERVED,
  144. PARC_RESERVED, PARC_EXTENDED
  145. };
  146. static inline u32 index2canvas(u32 index)
  147. {
  148. const u32 canvas_tab[4] = {
  149. #ifdef NV21
  150. 0x010100, 0x030302, 0x050504, 0x070706
  151. #else
  152. 0x020100, 0x050403, 0x080706, 0x0b0a09
  153. #endif
  154. };
  155. return canvas_tab[index];
  156. }
  157. static inline void ptr_atomic_wrap_inc(u32 *ptr)
  158. {
  159. u32 i = *ptr;
  160. i++;
  161. if (i >= VF_POOL_SIZE) {
  162. i = 0;
  163. }
  164. *ptr = i;
  165. }
  166. static void set_aspect_ratio(vframe_t *vf, unsigned pixel_ratio)
  167. {
  168. int ar = 0;
  169. if (vreal_ratio == 0) {
  170. vf->ratio_control |= (0x90 << DISP_RATIO_ASPECT_RATIO_BIT); // always stretch to 16:9
  171. } else {
  172. switch (aspect_ratio_table[pixel_ratio]) {
  173. case 0:
  174. ar = vreal_amstream_dec_info.height * vreal_ratio / vreal_amstream_dec_info.width;
  175. break;
  176. case 1:
  177. case 0xff:
  178. ar = vreal_ratio * vf->height / vf->width;
  179. break;
  180. case 2:
  181. ar = (vreal_ratio * vf->height * 12) / (vf->width * 11);
  182. break;
  183. case 3:
  184. ar = (vreal_ratio * vf->height * 11) / (vf->width * 10);
  185. break;
  186. case 4:
  187. ar = (vreal_ratio * vf->height * 11) / (vf->width * 16);
  188. break;
  189. case 5:
  190. ar = (vreal_ratio * vf->height * 33) / (vf->width * 40);
  191. break;
  192. default:
  193. ar = vreal_ratio * vf->height / vf->width;
  194. break;
  195. }
  196. }
  197. ar = min(ar, DISP_RATIO_ASPECT_RATIO_MAX);
  198. vf->ratio_control |= (ar << DISP_RATIO_ASPECT_RATIO_BIT);
  199. }
  200. #ifdef HANDLE_REAL_IRQ
  201. static irqreturn_t vreal_isr(int irq, void *dev_id)
  202. #else
  203. static void vreal_isr(void)
  204. #endif
  205. {
  206. u32 from;
  207. vframe_t *vf;
  208. u32 buffer_index;
  209. unsigned int status;
  210. unsigned int vdts;
  211. unsigned int info;
  212. unsigned int tr;
  213. unsigned int pictype;
  214. if (decoder_state == 0) {
  215. #ifdef HANDLE_REAL_IRQ
  216. return IRQ_HANDLED;
  217. #else
  218. return;
  219. #endif
  220. }
  221. status = READ_VREG(STATUS_AMRISC);
  222. if (status & (PARSER_ERROR_WRONG_PACKAGE_SIZE | PARSER_ERROR_WRONG_HEAD_VER | DECODER_ERROR_VLC_DECODE_TBL)) {
  223. // decoder or parser error
  224. real_err_count++;
  225. //printk("real decoder or parser error, status 0x%x\n", status);
  226. }
  227. from = READ_VREG(FROM_AMRISC);
  228. if ((hold == 0) && from) {
  229. tr = READ_VREG(VPTS_TR);
  230. pictype = (tr >> 13) & 3;
  231. tr = (tr & 0x1fff) * 96;
  232. vf = &vfpool[fill_ptr];
  233. vdts = READ_VREG(VDTS);
  234. if (last_tr == -1) { // ignore tr for first time
  235. vf->duration = frame_dur;
  236. } else {
  237. if (tr > last_tr) {
  238. vf->duration = tr - last_tr;
  239. } else {
  240. vf->duration = (96 << 13) + tr - last_tr;
  241. }
  242. if (vf->duration > 10 * frame_dur) {
  243. // not a reasonable duration, should not happen
  244. vf->duration = frame_dur;
  245. }
  246. #if 0
  247. else {
  248. if (check_frame_duration == 0) {
  249. frame_dur = vf->duration;
  250. check_frame_duration = 1;
  251. }
  252. }
  253. #endif
  254. }
  255. last_tr = tr;
  256. buffer_index = from & 0x03;
  257. if (0 == pictype) { // I
  258. current_vdts = vdts * 90 + 1;
  259. vf->pts = current_vdts;
  260. if (wait_key_frame) {
  261. wait_key_frame = 0;
  262. }
  263. } else {
  264. if (wait_key_frame) {
  265. while (READ_VREG(TO_AMRISC)) {}
  266. WRITE_VREG(TO_AMRISC, ~(1 << buffer_index));
  267. //INCPTR(put_ptr);
  268. WRITE_VREG(FROM_AMRISC, 0);
  269. #ifdef HANDLE_REAL_IRQ
  270. return IRQ_HANDLED;
  271. #else
  272. return;
  273. #endif
  274. } else {
  275. current_vdts += vf->duration - (vf->duration >> 4);
  276. vf->pts = current_vdts;
  277. }
  278. }
  279. //printk("pts %d, picture type %d\n", vf->pts, pictype);
  280. info = READ_VREG(RV_PIC_INFO);
  281. vf->width = info >> 16;
  282. vf->height = (info >> 4) & 0xfff;
  283. vf->bufWidth = 1920;
  284. vf->ratio_control = 0;
  285. set_aspect_ratio(vf, info & 0x0f);
  286. vf->duration_pulldown = 0;
  287. #ifdef NV21
  288. vf->type = VIDTYPE_PROGRESSIVE | VIDTYPE_VIU_FIELD | VIDTYPE_VIU_NV21;
  289. #else
  290. vf->type = VIDTYPE_PROGRESSIVE | VIDTYPE_VIU_FIELD;
  291. #endif
  292. vf->canvas0Addr = vf->canvas1Addr = index2canvas(buffer_index);
  293. vfpool_idx[fill_ptr] = buffer_index;
  294. vfbuf_use[buffer_index]++;
  295. INCPTR(fill_ptr);
  296. frame_count++;
  297. vf_notify_receiver(PROVIDER_NAME,VFRAME_EVENT_PROVIDER_VFRAME_READY,NULL);
  298. WRITE_VREG(FROM_AMRISC, 0);
  299. }
  300. WRITE_VREG(ASSIST_MBOX1_CLR_REG, 1);
  301. #ifdef HANDLE_REAL_IRQ
  302. return IRQ_HANDLED;
  303. #else
  304. return;
  305. #endif
  306. }
  307. static vframe_t *vreal_vf_peek(void* op_arg)
  308. {
  309. if (get_ptr == fill_ptr) {
  310. return NULL;
  311. }
  312. return &vfpool[get_ptr];
  313. }
  314. static vframe_t *vreal_vf_get(void* op_arg)
  315. {
  316. vframe_t *vf;
  317. if (get_ptr == fill_ptr) {
  318. return NULL;
  319. }
  320. vf = &vfpool[get_ptr];
  321. INCPTR(get_ptr);
  322. return vf;
  323. }
  324. static void vreal_vf_put(vframe_t *vf, void* op_arg)
  325. {
  326. INCPTR(putting_ptr);
  327. }
  328. static int vreal_event_cb(int type, void *data, void *private_data)
  329. {
  330. if(type & VFRAME_EVENT_RECEIVER_RESET){
  331. unsigned long flags;
  332. amvdec_stop();
  333. #ifndef CONFIG_POST_PROCESS_MANAGER
  334. vf_light_unreg_provider(&vreal_vf_prov);
  335. #endif
  336. spin_lock_irqsave(&lock, flags);
  337. vreal_local_init();
  338. vreal_prot_init();
  339. spin_unlock_irqrestore(&lock, flags);
  340. #ifndef CONFIG_POST_PROCESS_MANAGER
  341. vf_reg_provider(&vreal_vf_prov);
  342. #endif
  343. amvdec_start();
  344. }
  345. return 0;
  346. }
  347. static int vreal_vf_states(vframe_states_t *states, void* op_arg)
  348. {
  349. unsigned long flags;
  350. int i;
  351. spin_lock_irqsave(&lock, flags);
  352. states->vf_pool_size = VF_POOL_SIZE;
  353. i = put_ptr - fill_ptr;
  354. if (i < 0) i += VF_POOL_SIZE;
  355. states->buf_free_num = i;
  356. i = putting_ptr - put_ptr;
  357. if (i < 0) i += VF_POOL_SIZE;
  358. states->buf_recycle_num = i;
  359. i = fill_ptr - get_ptr;
  360. if (i < 0) i += VF_POOL_SIZE;
  361. states->buf_avail_num = i;
  362. spin_unlock_irqrestore(&lock, flags);
  363. return 0;
  364. }
  365. static void vreal_put_timer_func(unsigned long arg)
  366. {
  367. struct timer_list *timer = (struct timer_list *)arg;
  368. //unsigned int status;
  369. #ifndef HANDLE_REAL_IRQ
  370. vreal_isr();
  371. #endif
  372. if (putting_ptr != put_ptr) {
  373. u32 index = vfpool_idx[put_ptr];
  374. if (--vfbuf_use[index] == 0) {
  375. #if 0
  376. //WRITE_MPEG_REG(VIDEO_PTS, realdec.buffer_timestamp[disbuf->buffer_index]);
  377. /* this frame is not used, need return this buffer back to decoder side */
  378. /* todo: fix this polling, something on amrisc side */
  379. while (READ_VREG(TO_AMRISC)) {
  380. status = READ_VREG(STATUS_AMRISC);
  381. if (status & (PARSER_ERROR_WRONG_PACKAGE_SIZE | PARSER_ERROR_WRONG_HEAD_VER | DECODER_ERROR_VLC_DECODE_TBL)) {
  382. break;
  383. }
  384. }
  385. WRITE_VREG(TO_AMRISC, ~(1 << index));
  386. #endif
  387. real_recycle_q[real_recycle_wr++] = ~(1 << index);
  388. real_recycle_wr &= REAL_RECYCLE_Q_MASK;
  389. }
  390. INCPTR(put_ptr);
  391. }
  392. if ((real_recycle_rd != real_recycle_wr) && !READ_VREG(TO_AMRISC)) {
  393. WRITE_VREG(TO_AMRISC, real_recycle_q[real_recycle_rd++]);
  394. real_recycle_rd &= REAL_RECYCLE_Q_MASK;
  395. }
  396. timer->expires = jiffies + PUT_INTERVAL;
  397. add_timer(timer);
  398. }
  399. int vreal_dec_status(struct vdec_status *vstatus)
  400. {
  401. vstatus->width = vreal_amstream_dec_info.width;
  402. vstatus->height = vreal_amstream_dec_info.height;
  403. if (0 != vreal_amstream_dec_info.rate) {
  404. vstatus->fps = 96000 / vreal_amstream_dec_info.rate;
  405. } else {
  406. vstatus->fps = 96000;
  407. }
  408. vstatus->error_count = real_err_count;
  409. vstatus->status = (READ_VREG(STATUS_AMRISC) << 16) | stat;
  410. return 0;
  411. }
  412. /****************************************/
  413. static void vreal_canvas_init(void)
  414. {
  415. int i;
  416. u32 canvas_width, canvas_height;
  417. u32 decbuf_size, decbuf_y_size, decbuf_uv_size;
  418. u32 disp_addr = 0xffffffff;
  419. if (buf_size <= 0x00400000) {
  420. /* SD only */
  421. canvas_width = 768;
  422. canvas_height = 576;
  423. decbuf_y_size = 0x80000;
  424. decbuf_uv_size = 0x20000;
  425. decbuf_size = 0x100000;
  426. } else {
  427. /* HD & SD */
  428. canvas_width = 1920;
  429. canvas_height = 1088;
  430. decbuf_y_size = 0x200000;
  431. decbuf_uv_size = 0x80000;
  432. decbuf_size = 0x300000;
  433. }
  434. if (READ_MPEG_REG(VPP_MISC) & VPP_VD1_POSTBLEND) {
  435. canvas_t cur_canvas;
  436. canvas_read((READ_MPEG_REG(VD1_IF0_CANVAS0) & 0xff), &cur_canvas);
  437. disp_addr = (cur_canvas.addr + 7) >> 3;
  438. }
  439. for (i = 0; i < 4; i++) {
  440. if (((buf_start + i * decbuf_size + 7) >> 3) == disp_addr) {
  441. #ifdef NV21
  442. canvas_config(2 * i + 0,
  443. buf_start + 4 * decbuf_size,
  444. canvas_width, canvas_height,
  445. CANVAS_ADDR_NOWRAP, CANVAS_BLKMODE_32X32);
  446. canvas_config(2 * i + 1,
  447. buf_start + 4 * decbuf_size + decbuf_y_size,
  448. canvas_width, canvas_height / 2,
  449. CANVAS_ADDR_NOWRAP, CANVAS_BLKMODE_32X32);
  450. #else
  451. canvas_config(3 * i + 0,
  452. buf_start + 4 * decbuf_size,
  453. canvas_width, canvas_height,
  454. CANVAS_ADDR_NOWRAP, CANVAS_BLKMODE_32X32);
  455. canvas_config(3 * i + 1,
  456. buf_start + 4 * decbuf_size + decbuf_y_size,
  457. canvas_width / 2, canvas_height / 2,
  458. CANVAS_ADDR_NOWRAP, CANVAS_BLKMODE_32X32);
  459. canvas_config(3 * i + 2,
  460. buf_start + 4 * decbuf_size + decbuf_y_size + decbuf_uv_size,
  461. canvas_width / 2, canvas_height / 2,
  462. CANVAS_ADDR_NOWRAP, CANVAS_BLKMODE_32X32);
  463. #endif
  464. } else {
  465. #ifdef NV21
  466. canvas_config(2 * i + 0,
  467. buf_start + i * decbuf_size,
  468. canvas_width, canvas_height,
  469. CANVAS_ADDR_NOWRAP, CANVAS_BLKMODE_32X32);
  470. canvas_config(2 * i + 1,
  471. buf_start + i * decbuf_size + decbuf_y_size,
  472. canvas_width, canvas_height / 2,
  473. CANVAS_ADDR_NOWRAP, CANVAS_BLKMODE_32X32);
  474. #else
  475. canvas_config(3 * i + 0,
  476. buf_start + i * decbuf_size,
  477. canvas_width, canvas_height,
  478. CANVAS_ADDR_NOWRAP, CANVAS_BLKMODE_32X32);
  479. canvas_config(3 * i + 1,
  480. buf_start + i * decbuf_size + decbuf_y_size,
  481. canvas_width / 2, canvas_height / 2,
  482. CANVAS_ADDR_NOWRAP, CANVAS_BLKMODE_32X32);
  483. canvas_config(3 * i + 2,
  484. buf_start + i * decbuf_size + decbuf_y_size + decbuf_uv_size,
  485. canvas_width / 2, canvas_height / 2,
  486. CANVAS_ADDR_NOWRAP, CANVAS_BLKMODE_32X32);
  487. #endif
  488. }
  489. }
  490. }
  491. static void vreal_prot_init(void)
  492. {
  493. #ifdef CONFIG_ARCH_MESON6
  494. WRITE_VREG(DOS_SW_RESET0, (1<<7) | (1<<6));
  495. WRITE_VREG(DOS_SW_RESET0, 0);
  496. #else
  497. WRITE_MPEG_REG(RESET0_REGISTER, RESET_IQIDCT | RESET_MC);
  498. #endif
  499. vreal_canvas_init();
  500. /* index v << 16 | u << 8 | y */
  501. #ifdef NV21
  502. WRITE_VREG(AV_SCRATCH_0, 0x010100);
  503. WRITE_VREG(AV_SCRATCH_1, 0x030302);
  504. WRITE_VREG(AV_SCRATCH_2, 0x050504);
  505. WRITE_VREG(AV_SCRATCH_3, 0x070706);
  506. #else
  507. WRITE_VREG(AV_SCRATCH_0, 0x020100);
  508. WRITE_VREG(AV_SCRATCH_1, 0x050403);
  509. WRITE_VREG(AV_SCRATCH_2, 0x080706);
  510. WRITE_VREG(AV_SCRATCH_3, 0x0b0a09);
  511. #endif
  512. /* notify ucode the buffer offset */
  513. WRITE_VREG(AV_SCRATCH_F, buf_offset >> 12);
  514. #ifdef CONFIG_ARCH_MESON6
  515. WRITE_VREG(DOS_SW_RESET0, (1<<9) | (1<<8));
  516. WRITE_VREG(DOS_SW_RESET0, 0);
  517. #else
  518. WRITE_MPEG_REG(RESET2_REGISTER, RESET_PIC_DC | RESET_DBLK);
  519. #endif
  520. /* disable PSCALE for hardware sharing */
  521. WRITE_VREG(PSCALE_CTRL, 0);
  522. WRITE_VREG(FROM_AMRISC, 0);
  523. WRITE_VREG(TO_AMRISC, 0);
  524. WRITE_VREG(STATUS_AMRISC, 0);
  525. WRITE_VREG(RV_PIC_INFO, 0);
  526. WRITE_VREG(VPTS_TR, 0);
  527. WRITE_VREG(VDTS, 0);
  528. WRITE_VREG(SKIP_B_AMRISC, 0);
  529. WRITE_VREG(MDEC_WIDTH, (frame_width + 15) & 0xfff0);
  530. WRITE_VREG(MDEC_HEIGHT, (frame_height + 15) & 0xfff0);
  531. /* clear mailbox interrupt */
  532. WRITE_VREG(ASSIST_MBOX1_CLR_REG, 1);
  533. /* enable mailbox interrupt */
  534. WRITE_VREG(ASSIST_MBOX1_MASK, 1);
  535. #ifdef NV21
  536. SET_VREG_MASK(MDEC_PIC_DC_CTRL, 1<<17);
  537. #endif
  538. }
  539. static void vreal_local_init(void)
  540. {
  541. int i;
  542. //vreal_ratio = vreal_amstream_dec_info.ratio;
  543. vreal_ratio = 0x100;
  544. fill_ptr = get_ptr = put_ptr = putting_ptr = 0;
  545. frame_prog = 0;
  546. frame_width = vreal_amstream_dec_info.width;
  547. frame_height = vreal_amstream_dec_info.height;
  548. frame_dur = vreal_amstream_dec_info.rate;
  549. for (i = 0; i < 4; i++) {
  550. vfbuf_use[i] = 0;
  551. }
  552. decoder_state = 1;
  553. hold = 0;
  554. last_tr = -1;
  555. wait_key_frame = 1;
  556. frame_count = 0;
  557. current_vdts = 0;
  558. real_err_count = 0;
  559. real_recycle_rd = 0;
  560. real_recycle_wr = 0;
  561. pic_sz_tbl_map = 0;
  562. }
  563. static void load_block_data(unsigned int dest, unsigned int count)
  564. {
  565. unsigned short *pdest = (unsigned short *)dest;
  566. unsigned short src_tbl[12];
  567. unsigned int i;
  568. src_tbl[0] = RPR_size[vreal_amstream_dec_info.extra + 1];
  569. memcpy((void *)&src_tbl[1], vreal_amstream_dec_info.param, 2 << src_tbl[0]);
  570. #if 0
  571. for (i = 0; i < 12; i++) {
  572. printk("src_tbl[%d]: 0x%x\n", i, src_tbl[i]);
  573. }
  574. #endif
  575. for (i = 0; i < count / 4; i++) {
  576. pdest[i * 4] = src_tbl[i * 4 + 3];
  577. pdest[i * 4 + 1] = src_tbl[i * 4 + 2];
  578. pdest[i * 4 + 2] = src_tbl[i * 4 + 1];
  579. pdest[i * 4 + 3] = src_tbl[i * 4];
  580. }
  581. pic_sz_tbl_map = dma_map_single(NULL, &pic_sz_tbl,
  582. sizeof(pic_sz_tbl), DMA_TO_DEVICE);
  583. return;
  584. }
  585. s32 vreal_init(void)
  586. {
  587. int r;
  588. printk("vreal_init\n");
  589. init_timer(&recycle_timer);
  590. stat |= STAT_TIMER_INIT;
  591. amvdec_enable();
  592. vreal_local_init();
  593. r = rmparser_init();
  594. if (r) {
  595. amvdec_disable();
  596. printk("rm parser init failed\n");
  597. return r;
  598. }
  599. if (vreal_amstream_dec_info.format == VIDEO_DEC_FORMAT_REAL_8) {
  600. load_block_data((unsigned int)pic_sz_tbl, 12);
  601. // TODO: need to load the table into lmem
  602. WRITE_VREG(LMEM_DMA_ADR, (unsigned)pic_sz_tbl_map);
  603. WRITE_VREG(LMEM_DMA_COUNT, 10);
  604. WRITE_VREG(LMEM_DMA_CTRL, 0xc178 | (3 << 11));
  605. while (READ_VREG(LMEM_DMA_CTRL) & 0x8000) {};
  606. printk("load VIDEO_DEC_FORMAT_REAL_8\n");
  607. if (amvdec_loadmc(vreal_mc_8) < 0) {
  608. amvdec_disable();
  609. printk("failed\n");
  610. return -EBUSY;
  611. }
  612. } else if (vreal_amstream_dec_info.format == VIDEO_DEC_FORMAT_REAL_9) {
  613. printk("load VIDEO_DEC_FORMAT_REAL_9\n");
  614. if (amvdec_loadmc(vreal_mc_9) < 0) {
  615. amvdec_disable();
  616. printk("failed\n");
  617. return -EBUSY;
  618. }
  619. } else {
  620. printk("unsurpported real format\n");
  621. }
  622. stat |= STAT_MC_LOAD;
  623. /* enable AMRISC side protocol */
  624. vreal_prot_init();
  625. #ifdef HANDLE_REAL_IRQ
  626. if (request_irq(INT_MAILBOX_1A, vreal_isr,
  627. IRQF_SHARED, "vreal-irq", (void *)vreal_dec_id)) {
  628. amvdec_disable();
  629. printk("vreal irq register error.\n");
  630. return -ENOENT;
  631. }
  632. #endif
  633. stat |= STAT_ISR_REG;
  634. #ifdef CONFIG_POST_PROCESS_MANAGER
  635. vf_provider_init(&vreal_vf_prov, PROVIDER_NAME, &vreal_vf_provider, NULL);
  636. vf_reg_provider(&vreal_vf_prov);
  637. vf_notify_receiver(PROVIDER_NAME,VFRAME_EVENT_PROVIDER_START,NULL);
  638. #else
  639. vf_provider_init(&vreal_vf_prov, PROVIDER_NAME, &vreal_vf_provider, NULL);
  640. vf_reg_provider(&vreal_vf_prov);
  641. #endif
  642. stat |= STAT_VF_HOOK;
  643. recycle_timer.data = (ulong) & recycle_timer;
  644. recycle_timer.function = vreal_put_timer_func;
  645. recycle_timer.expires = jiffies + PUT_INTERVAL;
  646. add_timer(&recycle_timer);
  647. stat |= STAT_TIMER_ARM;
  648. amvdec_start();
  649. stat |= STAT_VDEC_RUN;
  650. set_vdec_func(&vreal_dec_status);
  651. printk("vreal init finished\n");
  652. return 0;
  653. }
  654. static int amvdec_real_probe(struct platform_device *pdev)
  655. {
  656. struct resource *mem;
  657. if (!(mem = platform_get_resource(pdev, IORESOURCE_MEM, 0))) {
  658. printk("amvdec_real memory resource undefined.\n");
  659. return -EFAULT;
  660. }
  661. buf_start = mem->start;
  662. buf_size = mem->end - mem->start + 1;
  663. buf_offset = buf_start - RM_DEF_BUFFER_ADDR;
  664. memcpy(&vreal_amstream_dec_info, (void *)mem[1].start, sizeof(vreal_amstream_dec_info));
  665. if (vreal_init() < 0) {
  666. printk("amvdec_real init failed.\n");
  667. return -ENODEV;
  668. }
  669. return 0;
  670. }
  671. static int amvdec_real_remove(struct platform_device *pdev)
  672. {
  673. if (stat & STAT_VDEC_RUN) {
  674. amvdec_stop();
  675. stat &= ~STAT_VDEC_RUN;
  676. }
  677. if (stat & STAT_ISR_REG) {
  678. free_irq(INT_MAILBOX_1A, (void *)vreal_dec_id);
  679. stat &= ~STAT_ISR_REG;
  680. }
  681. if (stat & STAT_TIMER_ARM) {
  682. del_timer_sync(&recycle_timer);
  683. stat &= ~STAT_TIMER_ARM;
  684. }
  685. if (stat & STAT_VF_HOOK) {
  686. ulong flags;
  687. spin_lock_irqsave(&lock, flags);
  688. fill_ptr = get_ptr = put_ptr = putting_ptr = 0;
  689. spin_unlock_irqrestore(&lock, flags);
  690. vf_unreg_provider(&vreal_vf_prov);
  691. stat &= ~STAT_VF_HOOK;
  692. }
  693. if (pic_sz_tbl_map != 0) {
  694. dma_unmap_single(NULL, pic_sz_tbl_map, sizeof(pic_sz_tbl), DMA_TO_DEVICE);
  695. }
  696. amvdec_disable();
  697. printk("frame duration %d, frames %d\n", frame_dur, frame_count);
  698. return 0;
  699. }
  700. /****************************************/
  701. static struct platform_driver amvdec_real_driver = {
  702. .probe = amvdec_real_probe,
  703. .remove = amvdec_real_remove,
  704. #ifdef CONFIG_PM
  705. .suspend = amvdec_suspend,
  706. .resume = amvdec_resume,
  707. #endif
  708. .driver = {
  709. .name = DRIVER_NAME,
  710. }
  711. };
  712. static struct codec_profile_t amvdec_real_profile = {
  713. .name = "real",
  714. .profile = "rmvb,"
  715. };
  716. static int __init amvdec_real_driver_init_module(void)
  717. {
  718. printk("amvdec_real module init\n");
  719. if (platform_driver_register(&amvdec_real_driver)) {
  720. printk("failed to register amvdec_real driver\n");
  721. return -ENODEV;
  722. }
  723. vcodec_profile_register(&amvdec_real_profile);
  724. return 0;
  725. }
  726. static void __exit amvdec_real_driver_remove_module(void)
  727. {
  728. printk("amvdec_real module remove.\n");
  729. platform_driver_unregister(&amvdec_real_driver);
  730. }
  731. /****************************************/
  732. module_param(stat, uint, 0664);
  733. MODULE_PARM_DESC(stat, "\n amvdec_real stat \n");
  734. module_init(amvdec_real_driver_init_module);
  735. module_exit(amvdec_real_driver_remove_module);
  736. MODULE_DESCRIPTION("AMLOGIC REAL Video Decoder Driver");
  737. MODULE_LICENSE("GPL");