cx25821-video-upstream.c 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673
  1. /*
  2. * Driver for the Conexant CX25821 PCIe bridge
  3. *
  4. * Copyright (C) 2009 Conexant Systems Inc.
  5. * Authors <hiep.huynh@conexant.com>, <shu.lin@conexant.com>
  6. *
  7. * This program is free software; you can redistribute it and/or modify
  8. * it under the terms of the GNU General Public License as published by
  9. * the Free Software Foundation; either version 2 of the License, or
  10. * (at your option) any later version.
  11. *
  12. * This program is distributed in the hope that it will be useful,
  13. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  15. *
  16. * GNU General Public License for more details.
  17. */
  18. #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
  19. #include "cx25821-video.h"
  20. #include "cx25821-video-upstream.h"
  21. #include <linux/errno.h>
  22. #include <linux/kernel.h>
  23. #include <linux/init.h>
  24. #include <linux/module.h>
  25. #include <linux/slab.h>
  26. MODULE_DESCRIPTION("v4l2 driver module for cx25821 based TV cards");
  27. MODULE_AUTHOR("Hiep Huynh <hiep.huynh@conexant.com>");
  28. MODULE_LICENSE("GPL");
  29. static int _intr_msk = FLD_VID_SRC_RISC1 | FLD_VID_SRC_UF | FLD_VID_SRC_SYNC |
  30. FLD_VID_SRC_OPC_ERR;
  31. int cx25821_sram_channel_setup_upstream(struct cx25821_dev *dev,
  32. const struct sram_channel *ch,
  33. unsigned int bpl, u32 risc)
  34. {
  35. unsigned int i, lines;
  36. u32 cdt;
  37. if (ch->cmds_start == 0) {
  38. cx_write(ch->ptr1_reg, 0);
  39. cx_write(ch->ptr2_reg, 0);
  40. cx_write(ch->cnt2_reg, 0);
  41. cx_write(ch->cnt1_reg, 0);
  42. return 0;
  43. }
  44. bpl = (bpl + 7) & ~7; /* alignment */
  45. cdt = ch->cdt;
  46. lines = ch->fifo_size / bpl;
  47. if (lines > 4)
  48. lines = 4;
  49. BUG_ON(lines < 2);
  50. /* write CDT */
  51. for (i = 0; i < lines; i++) {
  52. cx_write(cdt + 16 * i, ch->fifo_start + bpl * i);
  53. cx_write(cdt + 16 * i + 4, 0);
  54. cx_write(cdt + 16 * i + 8, 0);
  55. cx_write(cdt + 16 * i + 12, 0);
  56. }
  57. /* write CMDS */
  58. cx_write(ch->cmds_start + 0, risc);
  59. cx_write(ch->cmds_start + 4, 0);
  60. cx_write(ch->cmds_start + 8, cdt);
  61. cx_write(ch->cmds_start + 12, (lines * 16) >> 3);
  62. cx_write(ch->cmds_start + 16, ch->ctrl_start);
  63. cx_write(ch->cmds_start + 20, VID_IQ_SIZE_DW);
  64. for (i = 24; i < 80; i += 4)
  65. cx_write(ch->cmds_start + i, 0);
  66. /* fill registers */
  67. cx_write(ch->ptr1_reg, ch->fifo_start);
  68. cx_write(ch->ptr2_reg, cdt);
  69. cx_write(ch->cnt2_reg, (lines * 16) >> 3);
  70. cx_write(ch->cnt1_reg, (bpl >> 3) - 1);
  71. return 0;
  72. }
  73. static __le32 *cx25821_update_riscprogram(struct cx25821_channel *chan,
  74. __le32 *rp, unsigned int offset,
  75. unsigned int bpl, u32 sync_line,
  76. unsigned int lines, int fifo_enable,
  77. int field_type)
  78. {
  79. struct cx25821_video_out_data *out = chan->out;
  80. unsigned int line, i;
  81. int dist_betwn_starts = bpl * 2;
  82. *(rp++) = cpu_to_le32(RISC_RESYNC | sync_line);
  83. if (USE_RISC_NOOP_VIDEO) {
  84. for (i = 0; i < NUM_NO_OPS; i++)
  85. *(rp++) = cpu_to_le32(RISC_NOOP);
  86. }
  87. /* scan lines */
  88. for (line = 0; line < lines; line++) {
  89. *(rp++) = cpu_to_le32(RISC_READ | RISC_SOL | RISC_EOL | bpl);
  90. *(rp++) = cpu_to_le32(out->_data_buf_phys_addr + offset);
  91. *(rp++) = cpu_to_le32(0); /* bits 63-32 */
  92. if ((lines <= NTSC_FIELD_HEIGHT)
  93. || (line < (NTSC_FIELD_HEIGHT - 1)) || !(out->is_60hz)) {
  94. offset += dist_betwn_starts;
  95. }
  96. }
  97. return rp;
  98. }
  99. static __le32 *cx25821_risc_field_upstream(struct cx25821_channel *chan, __le32 *rp,
  100. dma_addr_t databuf_phys_addr,
  101. unsigned int offset, u32 sync_line,
  102. unsigned int bpl, unsigned int lines,
  103. int fifo_enable, int field_type)
  104. {
  105. struct cx25821_video_out_data *out = chan->out;
  106. unsigned int line, i;
  107. const struct sram_channel *sram_ch = chan->sram_channels;
  108. int dist_betwn_starts = bpl * 2;
  109. /* sync instruction */
  110. if (sync_line != NO_SYNC_LINE)
  111. *(rp++) = cpu_to_le32(RISC_RESYNC | sync_line);
  112. if (USE_RISC_NOOP_VIDEO) {
  113. for (i = 0; i < NUM_NO_OPS; i++)
  114. *(rp++) = cpu_to_le32(RISC_NOOP);
  115. }
  116. /* scan lines */
  117. for (line = 0; line < lines; line++) {
  118. *(rp++) = cpu_to_le32(RISC_READ | RISC_SOL | RISC_EOL | bpl);
  119. *(rp++) = cpu_to_le32(databuf_phys_addr + offset);
  120. *(rp++) = cpu_to_le32(0); /* bits 63-32 */
  121. if ((lines <= NTSC_FIELD_HEIGHT)
  122. || (line < (NTSC_FIELD_HEIGHT - 1)) || !(out->is_60hz))
  123. /* to skip the other field line */
  124. offset += dist_betwn_starts;
  125. /* check if we need to enable the FIFO after the first 4 lines
  126. * For the upstream video channel, the risc engine will enable
  127. * the FIFO. */
  128. if (fifo_enable && line == 3) {
  129. *(rp++) = cpu_to_le32(RISC_WRITECR);
  130. *(rp++) = cpu_to_le32(sram_ch->dma_ctl);
  131. *(rp++) = cpu_to_le32(FLD_VID_FIFO_EN);
  132. *(rp++) = cpu_to_le32(0x00000001);
  133. }
  134. }
  135. return rp;
  136. }
  137. static int cx25821_risc_buffer_upstream(struct cx25821_channel *chan,
  138. struct pci_dev *pci,
  139. unsigned int top_offset,
  140. unsigned int bpl, unsigned int lines)
  141. {
  142. struct cx25821_video_out_data *out = chan->out;
  143. __le32 *rp;
  144. int fifo_enable = 0;
  145. /* get line count for single field */
  146. int singlefield_lines = lines >> 1;
  147. int odd_num_lines = singlefield_lines;
  148. int frame = 0;
  149. int frame_size = 0;
  150. int databuf_offset = 0;
  151. int risc_program_size = 0;
  152. int risc_flag = RISC_CNT_RESET;
  153. unsigned int bottom_offset = bpl;
  154. dma_addr_t risc_phys_jump_addr;
  155. if (out->is_60hz) {
  156. odd_num_lines = singlefield_lines + 1;
  157. risc_program_size = FRAME1_VID_PROG_SIZE;
  158. frame_size = (bpl == Y411_LINE_SZ) ?
  159. FRAME_SIZE_NTSC_Y411 : FRAME_SIZE_NTSC_Y422;
  160. } else {
  161. risc_program_size = PAL_VID_PROG_SIZE;
  162. frame_size = (bpl == Y411_LINE_SZ) ?
  163. FRAME_SIZE_PAL_Y411 : FRAME_SIZE_PAL_Y422;
  164. }
  165. /* Virtual address of Risc buffer program */
  166. rp = out->_dma_virt_addr;
  167. for (frame = 0; frame < NUM_FRAMES; frame++) {
  168. databuf_offset = frame_size * frame;
  169. if (UNSET != top_offset) {
  170. fifo_enable = (frame == 0) ? FIFO_ENABLE : FIFO_DISABLE;
  171. rp = cx25821_risc_field_upstream(chan, rp,
  172. out->_data_buf_phys_addr +
  173. databuf_offset, top_offset, 0, bpl,
  174. odd_num_lines, fifo_enable, ODD_FIELD);
  175. }
  176. fifo_enable = FIFO_DISABLE;
  177. /* Even Field */
  178. rp = cx25821_risc_field_upstream(chan, rp,
  179. out->_data_buf_phys_addr +
  180. databuf_offset, bottom_offset,
  181. 0x200, bpl, singlefield_lines,
  182. fifo_enable, EVEN_FIELD);
  183. if (frame == 0) {
  184. risc_flag = RISC_CNT_RESET;
  185. risc_phys_jump_addr = out->_dma_phys_start_addr +
  186. risc_program_size;
  187. } else {
  188. risc_phys_jump_addr = out->_dma_phys_start_addr;
  189. risc_flag = RISC_CNT_INC;
  190. }
  191. /* Loop to 2ndFrameRISC or to Start of Risc
  192. * program & generate IRQ
  193. */
  194. *(rp++) = cpu_to_le32(RISC_JUMP | RISC_IRQ1 | risc_flag);
  195. *(rp++) = cpu_to_le32(risc_phys_jump_addr);
  196. *(rp++) = cpu_to_le32(0);
  197. }
  198. return 0;
  199. }
  200. void cx25821_stop_upstream_video(struct cx25821_channel *chan)
  201. {
  202. struct cx25821_video_out_data *out = chan->out;
  203. struct cx25821_dev *dev = chan->dev;
  204. const struct sram_channel *sram_ch = chan->sram_channels;
  205. u32 tmp = 0;
  206. if (!out->_is_running) {
  207. pr_info("No video file is currently running so return!\n");
  208. return;
  209. }
  210. /* Set the interrupt mask register, disable irq. */
  211. cx_set(PCI_INT_MSK, cx_read(PCI_INT_MSK) & ~(1 << sram_ch->irq_bit));
  212. /* Disable RISC interrupts */
  213. tmp = cx_read(sram_ch->int_msk);
  214. cx_write(sram_ch->int_msk, tmp & ~_intr_msk);
  215. /* Turn OFF risc and fifo enable */
  216. tmp = cx_read(sram_ch->dma_ctl);
  217. cx_write(sram_ch->dma_ctl, tmp & ~(FLD_VID_FIFO_EN | FLD_VID_RISC_EN));
  218. free_irq(dev->pci->irq, chan);
  219. /* Clear data buffer memory */
  220. if (out->_data_buf_virt_addr)
  221. memset(out->_data_buf_virt_addr, 0, out->_data_buf_size);
  222. out->_is_running = 0;
  223. out->_is_first_frame = 0;
  224. out->_frame_count = 0;
  225. out->_file_status = END_OF_FILE;
  226. tmp = cx_read(VID_CH_MODE_SEL);
  227. cx_write(VID_CH_MODE_SEL, tmp & 0xFFFFFE00);
  228. }
  229. void cx25821_free_mem_upstream(struct cx25821_channel *chan)
  230. {
  231. struct cx25821_video_out_data *out = chan->out;
  232. struct cx25821_dev *dev = chan->dev;
  233. if (out->_is_running)
  234. cx25821_stop_upstream_video(chan);
  235. if (out->_dma_virt_addr) {
  236. pci_free_consistent(dev->pci, out->_risc_size,
  237. out->_dma_virt_addr, out->_dma_phys_addr);
  238. out->_dma_virt_addr = NULL;
  239. }
  240. if (out->_data_buf_virt_addr) {
  241. pci_free_consistent(dev->pci, out->_data_buf_size,
  242. out->_data_buf_virt_addr,
  243. out->_data_buf_phys_addr);
  244. out->_data_buf_virt_addr = NULL;
  245. }
  246. }
  247. int cx25821_write_frame(struct cx25821_channel *chan,
  248. const char __user *data, size_t count)
  249. {
  250. struct cx25821_video_out_data *out = chan->out;
  251. int line_size = (out->_pixel_format == PIXEL_FRMT_411) ?
  252. Y411_LINE_SZ : Y422_LINE_SZ;
  253. int frame_size = 0;
  254. int frame_offset = 0;
  255. int curpos = out->curpos;
  256. if (out->is_60hz)
  257. frame_size = (line_size == Y411_LINE_SZ) ?
  258. FRAME_SIZE_NTSC_Y411 : FRAME_SIZE_NTSC_Y422;
  259. else
  260. frame_size = (line_size == Y411_LINE_SZ) ?
  261. FRAME_SIZE_PAL_Y411 : FRAME_SIZE_PAL_Y422;
  262. if (curpos == 0) {
  263. out->cur_frame_index = out->_frame_index;
  264. if (wait_event_interruptible(out->waitq, out->cur_frame_index != out->_frame_index))
  265. return -EINTR;
  266. out->cur_frame_index = out->_frame_index;
  267. }
  268. frame_offset = out->cur_frame_index ? frame_size : 0;
  269. if (frame_size - curpos < count)
  270. count = frame_size - curpos;
  271. if (copy_from_user((__force char *)out->_data_buf_virt_addr + frame_offset + curpos,
  272. data, count))
  273. return -EFAULT;
  274. curpos += count;
  275. if (curpos == frame_size) {
  276. out->_frame_count++;
  277. curpos = 0;
  278. }
  279. out->curpos = curpos;
  280. return count;
  281. }
  282. static int cx25821_upstream_buffer_prepare(struct cx25821_channel *chan,
  283. const struct sram_channel *sram_ch,
  284. int bpl)
  285. {
  286. struct cx25821_video_out_data *out = chan->out;
  287. struct cx25821_dev *dev = chan->dev;
  288. int ret = 0;
  289. dma_addr_t dma_addr;
  290. dma_addr_t data_dma_addr;
  291. if (out->_dma_virt_addr != NULL)
  292. pci_free_consistent(dev->pci, out->upstream_riscbuf_size,
  293. out->_dma_virt_addr, out->_dma_phys_addr);
  294. out->_dma_virt_addr = pci_alloc_consistent(dev->pci,
  295. out->upstream_riscbuf_size, &dma_addr);
  296. out->_dma_virt_start_addr = out->_dma_virt_addr;
  297. out->_dma_phys_start_addr = dma_addr;
  298. out->_dma_phys_addr = dma_addr;
  299. out->_risc_size = out->upstream_riscbuf_size;
  300. if (!out->_dma_virt_addr) {
  301. pr_err("FAILED to allocate memory for Risc buffer! Returning\n");
  302. return -ENOMEM;
  303. }
  304. /* Clear memory at address */
  305. memset(out->_dma_virt_addr, 0, out->_risc_size);
  306. if (out->_data_buf_virt_addr != NULL)
  307. pci_free_consistent(dev->pci, out->upstream_databuf_size,
  308. out->_data_buf_virt_addr,
  309. out->_data_buf_phys_addr);
  310. /* For Video Data buffer allocation */
  311. out->_data_buf_virt_addr = pci_alloc_consistent(dev->pci,
  312. out->upstream_databuf_size, &data_dma_addr);
  313. out->_data_buf_phys_addr = data_dma_addr;
  314. out->_data_buf_size = out->upstream_databuf_size;
  315. if (!out->_data_buf_virt_addr) {
  316. pr_err("FAILED to allocate memory for data buffer! Returning\n");
  317. return -ENOMEM;
  318. }
  319. /* Clear memory at address */
  320. memset(out->_data_buf_virt_addr, 0, out->_data_buf_size);
  321. /* Create RISC programs */
  322. ret = cx25821_risc_buffer_upstream(chan, dev->pci, 0, bpl,
  323. out->_lines_count);
  324. if (ret < 0) {
  325. pr_info("Failed creating Video Upstream Risc programs!\n");
  326. goto error;
  327. }
  328. return 0;
  329. error:
  330. return ret;
  331. }
  332. static int cx25821_video_upstream_irq(struct cx25821_channel *chan, u32 status)
  333. {
  334. struct cx25821_video_out_data *out = chan->out;
  335. struct cx25821_dev *dev = chan->dev;
  336. u32 int_msk_tmp;
  337. const struct sram_channel *channel = chan->sram_channels;
  338. int singlefield_lines = NTSC_FIELD_HEIGHT;
  339. int line_size_in_bytes = Y422_LINE_SZ;
  340. int odd_risc_prog_size = 0;
  341. dma_addr_t risc_phys_jump_addr;
  342. __le32 *rp;
  343. if (status & FLD_VID_SRC_RISC1) {
  344. /* We should only process one program per call */
  345. u32 prog_cnt = cx_read(channel->gpcnt);
  346. /* Since we've identified our IRQ, clear our bits from the
  347. * interrupt mask and interrupt status registers */
  348. int_msk_tmp = cx_read(channel->int_msk);
  349. cx_write(channel->int_msk, int_msk_tmp & ~_intr_msk);
  350. cx_write(channel->int_stat, _intr_msk);
  351. wake_up(&out->waitq);
  352. spin_lock(&dev->slock);
  353. out->_frame_index = prog_cnt;
  354. if (out->_is_first_frame) {
  355. out->_is_first_frame = 0;
  356. if (out->is_60hz) {
  357. singlefield_lines += 1;
  358. odd_risc_prog_size = ODD_FLD_NTSC_PROG_SIZE;
  359. } else {
  360. singlefield_lines = PAL_FIELD_HEIGHT;
  361. odd_risc_prog_size = ODD_FLD_PAL_PROG_SIZE;
  362. }
  363. if (out->_dma_virt_start_addr != NULL) {
  364. line_size_in_bytes =
  365. (out->_pixel_format ==
  366. PIXEL_FRMT_411) ? Y411_LINE_SZ :
  367. Y422_LINE_SZ;
  368. risc_phys_jump_addr =
  369. out->_dma_phys_start_addr +
  370. odd_risc_prog_size;
  371. rp = cx25821_update_riscprogram(chan,
  372. out->_dma_virt_start_addr, TOP_OFFSET,
  373. line_size_in_bytes, 0x0,
  374. singlefield_lines, FIFO_DISABLE,
  375. ODD_FIELD);
  376. /* Jump to Even Risc program of 1st Frame */
  377. *(rp++) = cpu_to_le32(RISC_JUMP);
  378. *(rp++) = cpu_to_le32(risc_phys_jump_addr);
  379. *(rp++) = cpu_to_le32(0);
  380. }
  381. }
  382. spin_unlock(&dev->slock);
  383. } else {
  384. if (status & FLD_VID_SRC_UF)
  385. pr_err("%s(): Video Received Underflow Error Interrupt!\n",
  386. __func__);
  387. if (status & FLD_VID_SRC_SYNC)
  388. pr_err("%s(): Video Received Sync Error Interrupt!\n",
  389. __func__);
  390. if (status & FLD_VID_SRC_OPC_ERR)
  391. pr_err("%s(): Video Received OpCode Error Interrupt!\n",
  392. __func__);
  393. }
  394. if (out->_file_status == END_OF_FILE) {
  395. pr_err("EOF Channel 1 Framecount = %d\n", out->_frame_count);
  396. return -1;
  397. }
  398. /* ElSE, set the interrupt mask register, re-enable irq. */
  399. int_msk_tmp = cx_read(channel->int_msk);
  400. cx_write(channel->int_msk, int_msk_tmp |= _intr_msk);
  401. return 0;
  402. }
  403. static irqreturn_t cx25821_upstream_irq(int irq, void *dev_id)
  404. {
  405. struct cx25821_channel *chan = dev_id;
  406. struct cx25821_dev *dev = chan->dev;
  407. u32 vid_status;
  408. int handled = 0;
  409. const struct sram_channel *sram_ch;
  410. if (!dev)
  411. return -1;
  412. sram_ch = chan->sram_channels;
  413. vid_status = cx_read(sram_ch->int_stat);
  414. /* Only deal with our interrupt */
  415. if (vid_status)
  416. handled = cx25821_video_upstream_irq(chan, vid_status);
  417. return IRQ_RETVAL(handled);
  418. }
  419. static void cx25821_set_pixelengine(struct cx25821_channel *chan,
  420. const struct sram_channel *ch,
  421. int pix_format)
  422. {
  423. struct cx25821_video_out_data *out = chan->out;
  424. struct cx25821_dev *dev = chan->dev;
  425. int width = WIDTH_D1;
  426. int height = out->_lines_count;
  427. int num_lines, odd_num_lines;
  428. u32 value;
  429. int vip_mode = OUTPUT_FRMT_656;
  430. value = ((pix_format & 0x3) << 12) | (vip_mode & 0x7);
  431. value &= 0xFFFFFFEF;
  432. value |= out->is_60hz ? 0 : 0x10;
  433. cx_write(ch->vid_fmt_ctl, value);
  434. /* set number of active pixels in each line.
  435. * Default is 720 pixels in both NTSC and PAL format */
  436. cx_write(ch->vid_active_ctl1, width);
  437. num_lines = (height / 2) & 0x3FF;
  438. odd_num_lines = num_lines;
  439. if (out->is_60hz)
  440. odd_num_lines += 1;
  441. value = (num_lines << 16) | odd_num_lines;
  442. /* set number of active lines in field 0 (top) and field 1 (bottom) */
  443. cx_write(ch->vid_active_ctl2, value);
  444. cx_write(ch->vid_cdt_size, VID_CDT_SIZE >> 3);
  445. }
  446. static int cx25821_start_video_dma_upstream(struct cx25821_channel *chan,
  447. const struct sram_channel *sram_ch)
  448. {
  449. struct cx25821_video_out_data *out = chan->out;
  450. struct cx25821_dev *dev = chan->dev;
  451. u32 tmp = 0;
  452. int err = 0;
  453. /* 656/VIP SRC Upstream Channel I & J and 7 - Host Bus Interface for
  454. * channel A-C
  455. */
  456. tmp = cx_read(VID_CH_MODE_SEL);
  457. cx_write(VID_CH_MODE_SEL, tmp | 0x1B0001FF);
  458. /* Set the physical start address of the RISC program in the initial
  459. * program counter(IPC) member of the cmds.
  460. */
  461. cx_write(sram_ch->cmds_start + 0, out->_dma_phys_addr);
  462. /* Risc IPC High 64 bits 63-32 */
  463. cx_write(sram_ch->cmds_start + 4, 0);
  464. /* reset counter */
  465. cx_write(sram_ch->gpcnt_ctl, 3);
  466. /* Clear our bits from the interrupt status register. */
  467. cx_write(sram_ch->int_stat, _intr_msk);
  468. /* Set the interrupt mask register, enable irq. */
  469. cx_set(PCI_INT_MSK, cx_read(PCI_INT_MSK) | (1 << sram_ch->irq_bit));
  470. tmp = cx_read(sram_ch->int_msk);
  471. cx_write(sram_ch->int_msk, tmp |= _intr_msk);
  472. err = request_irq(dev->pci->irq, cx25821_upstream_irq,
  473. IRQF_SHARED, dev->name, chan);
  474. if (err < 0) {
  475. pr_err("%s: can't get upstream IRQ %d\n",
  476. dev->name, dev->pci->irq);
  477. goto fail_irq;
  478. }
  479. /* Start the DMA engine */
  480. tmp = cx_read(sram_ch->dma_ctl);
  481. cx_set(sram_ch->dma_ctl, tmp | FLD_VID_RISC_EN);
  482. out->_is_running = 1;
  483. out->_is_first_frame = 1;
  484. return 0;
  485. fail_irq:
  486. cx25821_dev_unregister(dev);
  487. return err;
  488. }
  489. int cx25821_vidupstream_init(struct cx25821_channel *chan,
  490. int pixel_format)
  491. {
  492. struct cx25821_video_out_data *out = chan->out;
  493. struct cx25821_dev *dev = chan->dev;
  494. const struct sram_channel *sram_ch;
  495. u32 tmp;
  496. int err = 0;
  497. int data_frame_size = 0;
  498. int risc_buffer_size = 0;
  499. if (out->_is_running) {
  500. pr_info("Video Channel is still running so return!\n");
  501. return 0;
  502. }
  503. sram_ch = chan->sram_channels;
  504. out->is_60hz = dev->tvnorm & V4L2_STD_525_60;
  505. /* 656/VIP SRC Upstream Channel I & J and 7 - Host Bus Interface for
  506. * channel A-C
  507. */
  508. tmp = cx_read(VID_CH_MODE_SEL);
  509. cx_write(VID_CH_MODE_SEL, tmp | 0x1B0001FF);
  510. out->_is_running = 0;
  511. out->_frame_count = 0;
  512. out->_file_status = RESET_STATUS;
  513. out->_lines_count = out->is_60hz ? 480 : 576;
  514. out->_pixel_format = pixel_format;
  515. out->_line_size = (out->_pixel_format == PIXEL_FRMT_422) ?
  516. (WIDTH_D1 * 2) : (WIDTH_D1 * 3) / 2;
  517. data_frame_size = out->is_60hz ? NTSC_DATA_BUF_SZ : PAL_DATA_BUF_SZ;
  518. risc_buffer_size = out->is_60hz ?
  519. NTSC_RISC_BUF_SIZE : PAL_RISC_BUF_SIZE;
  520. out->_is_running = 0;
  521. out->_frame_count = 0;
  522. out->_file_status = RESET_STATUS;
  523. out->_lines_count = out->is_60hz ? 480 : 576;
  524. out->_pixel_format = pixel_format;
  525. out->_line_size = (out->_pixel_format == PIXEL_FRMT_422) ?
  526. (WIDTH_D1 * 2) : (WIDTH_D1 * 3) / 2;
  527. out->curpos = 0;
  528. init_waitqueue_head(&out->waitq);
  529. err = cx25821_sram_channel_setup_upstream(dev, sram_ch,
  530. out->_line_size, 0);
  531. /* setup fifo + format */
  532. cx25821_set_pixelengine(chan, sram_ch, out->_pixel_format);
  533. out->upstream_riscbuf_size = risc_buffer_size * 2;
  534. out->upstream_databuf_size = data_frame_size * 2;
  535. /* Allocating buffers and prepare RISC program */
  536. err = cx25821_upstream_buffer_prepare(chan, sram_ch, out->_line_size);
  537. if (err < 0) {
  538. pr_err("%s: Failed to set up Video upstream buffers!\n",
  539. dev->name);
  540. goto error;
  541. }
  542. cx25821_start_video_dma_upstream(chan, sram_ch);
  543. return 0;
  544. error:
  545. cx25821_dev_unregister(dev);
  546. return err;
  547. }