jpeg-hw-exynos3250.c 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489
  1. /* linux/drivers/media/platform/exynos3250-jpeg/jpeg-hw.h
  2. *
  3. * Copyright (c) 2014 Samsung Electronics Co., Ltd.
  4. * http://www.samsung.com
  5. *
  6. * Author: Jacek Anaszewski <j.anaszewski@samsung.com>
  7. *
  8. * This program is free software; you can redistribute it and/or modify
  9. * it under the terms of the GNU General Public License version 2 as
  10. * published by the Free Software Foundation.
  11. */
  12. #include <linux/io.h>
  13. #include <linux/videodev2.h>
  14. #include <linux/delay.h>
  15. #include "jpeg-core.h"
  16. #include "jpeg-regs.h"
  17. #include "jpeg-hw-exynos3250.h"
  18. void exynos3250_jpeg_reset(void __iomem *regs)
  19. {
  20. u32 reg = 1;
  21. int count = 1000;
  22. writel(1, regs + EXYNOS3250_SW_RESET);
  23. /* no other way but polling for when JPEG IP becomes operational */
  24. while (reg != 0 && --count > 0) {
  25. udelay(1);
  26. cpu_relax();
  27. reg = readl(regs + EXYNOS3250_SW_RESET);
  28. }
  29. reg = 0;
  30. count = 1000;
  31. while (reg != 1 && --count > 0) {
  32. writel(1, regs + EXYNOS3250_JPGDRI);
  33. udelay(1);
  34. cpu_relax();
  35. reg = readl(regs + EXYNOS3250_JPGDRI);
  36. }
  37. writel(0, regs + EXYNOS3250_JPGDRI);
  38. }
  39. void exynos3250_jpeg_poweron(void __iomem *regs)
  40. {
  41. writel(EXYNOS3250_POWER_ON, regs + EXYNOS3250_JPGCLKCON);
  42. }
  43. void exynos3250_jpeg_set_dma_num(void __iomem *regs)
  44. {
  45. writel(((EXYNOS3250_DMA_MO_COUNT << EXYNOS3250_WDMA_ISSUE_NUM_SHIFT) &
  46. EXYNOS3250_WDMA_ISSUE_NUM_MASK) |
  47. ((EXYNOS3250_DMA_MO_COUNT << EXYNOS3250_RDMA_ISSUE_NUM_SHIFT) &
  48. EXYNOS3250_RDMA_ISSUE_NUM_MASK) |
  49. ((EXYNOS3250_DMA_MO_COUNT << EXYNOS3250_ISSUE_GATHER_NUM_SHIFT) &
  50. EXYNOS3250_ISSUE_GATHER_NUM_MASK),
  51. regs + EXYNOS3250_DMA_ISSUE_NUM);
  52. }
  53. void exynos3250_jpeg_clk_set(void __iomem *base)
  54. {
  55. u32 reg;
  56. reg = readl(base + EXYNOS3250_JPGCMOD) & ~EXYNOS3250_HALF_EN_MASK;
  57. writel(reg | EXYNOS3250_HALF_EN, base + EXYNOS3250_JPGCMOD);
  58. }
  59. void exynos3250_jpeg_input_raw_fmt(void __iomem *regs, unsigned int fmt)
  60. {
  61. u32 reg;
  62. reg = readl(regs + EXYNOS3250_JPGCMOD) &
  63. EXYNOS3250_MODE_Y16_MASK;
  64. switch (fmt) {
  65. case V4L2_PIX_FMT_RGB32:
  66. reg |= EXYNOS3250_MODE_SEL_ARGB8888;
  67. break;
  68. case V4L2_PIX_FMT_BGR32:
  69. reg |= EXYNOS3250_MODE_SEL_ARGB8888 | EXYNOS3250_SRC_SWAP_RGB;
  70. break;
  71. case V4L2_PIX_FMT_RGB565:
  72. reg |= EXYNOS3250_MODE_SEL_RGB565;
  73. break;
  74. case V4L2_PIX_FMT_RGB565X:
  75. reg |= EXYNOS3250_MODE_SEL_RGB565 | EXYNOS3250_SRC_SWAP_RGB;
  76. break;
  77. case V4L2_PIX_FMT_YUYV:
  78. reg |= EXYNOS3250_MODE_SEL_422_1P_LUM_CHR;
  79. break;
  80. case V4L2_PIX_FMT_YVYU:
  81. reg |= EXYNOS3250_MODE_SEL_422_1P_LUM_CHR |
  82. EXYNOS3250_SRC_SWAP_UV;
  83. break;
  84. case V4L2_PIX_FMT_UYVY:
  85. reg |= EXYNOS3250_MODE_SEL_422_1P_CHR_LUM;
  86. break;
  87. case V4L2_PIX_FMT_VYUY:
  88. reg |= EXYNOS3250_MODE_SEL_422_1P_CHR_LUM |
  89. EXYNOS3250_SRC_SWAP_UV;
  90. break;
  91. case V4L2_PIX_FMT_NV12:
  92. reg |= EXYNOS3250_MODE_SEL_420_2P | EXYNOS3250_SRC_NV12;
  93. break;
  94. case V4L2_PIX_FMT_NV21:
  95. reg |= EXYNOS3250_MODE_SEL_420_2P | EXYNOS3250_SRC_NV21;
  96. break;
  97. case V4L2_PIX_FMT_YUV420:
  98. reg |= EXYNOS3250_MODE_SEL_420_3P;
  99. break;
  100. default:
  101. break;
  102. }
  103. writel(reg, regs + EXYNOS3250_JPGCMOD);
  104. }
  105. void exynos3250_jpeg_set_y16(void __iomem *regs, bool y16)
  106. {
  107. u32 reg;
  108. reg = readl(regs + EXYNOS3250_JPGCMOD);
  109. if (y16)
  110. reg |= EXYNOS3250_MODE_Y16;
  111. else
  112. reg &= ~EXYNOS3250_MODE_Y16_MASK;
  113. writel(reg, regs + EXYNOS3250_JPGCMOD);
  114. }
  115. void exynos3250_jpeg_proc_mode(void __iomem *regs, unsigned int mode)
  116. {
  117. u32 reg, m;
  118. if (mode == S5P_JPEG_ENCODE)
  119. m = EXYNOS3250_PROC_MODE_COMPR;
  120. else
  121. m = EXYNOS3250_PROC_MODE_DECOMPR;
  122. reg = readl(regs + EXYNOS3250_JPGMOD);
  123. reg &= ~EXYNOS3250_PROC_MODE_MASK;
  124. reg |= m;
  125. writel(reg, regs + EXYNOS3250_JPGMOD);
  126. }
  127. void exynos3250_jpeg_subsampling_mode(void __iomem *regs, unsigned int mode)
  128. {
  129. u32 reg, m = 0;
  130. switch (mode) {
  131. case V4L2_JPEG_CHROMA_SUBSAMPLING_444:
  132. m = EXYNOS3250_SUBSAMPLING_MODE_444;
  133. break;
  134. case V4L2_JPEG_CHROMA_SUBSAMPLING_422:
  135. m = EXYNOS3250_SUBSAMPLING_MODE_422;
  136. break;
  137. case V4L2_JPEG_CHROMA_SUBSAMPLING_420:
  138. m = EXYNOS3250_SUBSAMPLING_MODE_420;
  139. break;
  140. }
  141. reg = readl(regs + EXYNOS3250_JPGMOD);
  142. reg &= ~EXYNOS3250_SUBSAMPLING_MODE_MASK;
  143. reg |= m;
  144. writel(reg, regs + EXYNOS3250_JPGMOD);
  145. }
  146. unsigned int exynos3250_jpeg_get_subsampling_mode(void __iomem *regs)
  147. {
  148. return readl(regs + EXYNOS3250_JPGMOD) &
  149. EXYNOS3250_SUBSAMPLING_MODE_MASK;
  150. }
  151. void exynos3250_jpeg_dri(void __iomem *regs, unsigned int dri)
  152. {
  153. u32 reg;
  154. reg = dri & EXYNOS3250_JPGDRI_MASK;
  155. writel(reg, regs + EXYNOS3250_JPGDRI);
  156. }
  157. void exynos3250_jpeg_qtbl(void __iomem *regs, unsigned int t, unsigned int n)
  158. {
  159. unsigned long reg;
  160. reg = readl(regs + EXYNOS3250_QHTBL);
  161. reg &= ~EXYNOS3250_QT_NUM_MASK(t);
  162. reg |= (n << EXYNOS3250_QT_NUM_SHIFT(t)) &
  163. EXYNOS3250_QT_NUM_MASK(t);
  164. writel(reg, regs + EXYNOS3250_QHTBL);
  165. }
  166. void exynos3250_jpeg_htbl_ac(void __iomem *regs, unsigned int t)
  167. {
  168. unsigned long reg;
  169. reg = readl(regs + EXYNOS3250_QHTBL);
  170. reg &= ~EXYNOS3250_HT_NUM_AC_MASK(t);
  171. /* this driver uses table 0 for all color components */
  172. reg |= (0 << EXYNOS3250_HT_NUM_AC_SHIFT(t)) &
  173. EXYNOS3250_HT_NUM_AC_MASK(t);
  174. writel(reg, regs + EXYNOS3250_QHTBL);
  175. }
  176. void exynos3250_jpeg_htbl_dc(void __iomem *regs, unsigned int t)
  177. {
  178. unsigned long reg;
  179. reg = readl(regs + EXYNOS3250_QHTBL);
  180. reg &= ~EXYNOS3250_HT_NUM_DC_MASK(t);
  181. /* this driver uses table 0 for all color components */
  182. reg |= (0 << EXYNOS3250_HT_NUM_DC_SHIFT(t)) &
  183. EXYNOS3250_HT_NUM_DC_MASK(t);
  184. writel(reg, regs + EXYNOS3250_QHTBL);
  185. }
  186. void exynos3250_jpeg_set_y(void __iomem *regs, unsigned int y)
  187. {
  188. u32 reg;
  189. reg = y & EXYNOS3250_JPGY_MASK;
  190. writel(reg, regs + EXYNOS3250_JPGY);
  191. }
  192. void exynos3250_jpeg_set_x(void __iomem *regs, unsigned int x)
  193. {
  194. u32 reg;
  195. reg = x & EXYNOS3250_JPGX_MASK;
  196. writel(reg, regs + EXYNOS3250_JPGX);
  197. }
  198. #if 0 /* Currently unused */
  199. unsigned int exynos3250_jpeg_get_y(void __iomem *regs)
  200. {
  201. return readl(regs + EXYNOS3250_JPGY);
  202. }
  203. unsigned int exynos3250_jpeg_get_x(void __iomem *regs)
  204. {
  205. return readl(regs + EXYNOS3250_JPGX);
  206. }
  207. #endif
  208. void exynos3250_jpeg_interrupts_enable(void __iomem *regs)
  209. {
  210. u32 reg;
  211. reg = readl(regs + EXYNOS3250_JPGINTSE);
  212. reg |= (EXYNOS3250_JPEG_DONE_EN |
  213. EXYNOS3250_WDMA_DONE_EN |
  214. EXYNOS3250_RDMA_DONE_EN |
  215. EXYNOS3250_ENC_STREAM_INT_EN |
  216. EXYNOS3250_CORE_DONE_EN |
  217. EXYNOS3250_ERR_INT_EN |
  218. EXYNOS3250_HEAD_INT_EN);
  219. writel(reg, regs + EXYNOS3250_JPGINTSE);
  220. }
  221. void exynos3250_jpeg_enc_stream_bound(void __iomem *regs, unsigned int size)
  222. {
  223. u32 reg;
  224. reg = size & EXYNOS3250_ENC_STREAM_BOUND_MASK;
  225. writel(reg, regs + EXYNOS3250_ENC_STREAM_BOUND);
  226. }
  227. void exynos3250_jpeg_output_raw_fmt(void __iomem *regs, unsigned int fmt)
  228. {
  229. u32 reg;
  230. switch (fmt) {
  231. case V4L2_PIX_FMT_RGB32:
  232. reg = EXYNOS3250_OUT_FMT_ARGB8888;
  233. break;
  234. case V4L2_PIX_FMT_BGR32:
  235. reg = EXYNOS3250_OUT_FMT_ARGB8888 | EXYNOS3250_OUT_SWAP_RGB;
  236. break;
  237. case V4L2_PIX_FMT_RGB565:
  238. reg = EXYNOS3250_OUT_FMT_RGB565;
  239. break;
  240. case V4L2_PIX_FMT_RGB565X:
  241. reg = EXYNOS3250_OUT_FMT_RGB565 | EXYNOS3250_OUT_SWAP_RGB;
  242. break;
  243. case V4L2_PIX_FMT_YUYV:
  244. reg = EXYNOS3250_OUT_FMT_422_1P_LUM_CHR;
  245. break;
  246. case V4L2_PIX_FMT_YVYU:
  247. reg = EXYNOS3250_OUT_FMT_422_1P_LUM_CHR |
  248. EXYNOS3250_OUT_SWAP_UV;
  249. break;
  250. case V4L2_PIX_FMT_UYVY:
  251. reg = EXYNOS3250_OUT_FMT_422_1P_CHR_LUM;
  252. break;
  253. case V4L2_PIX_FMT_VYUY:
  254. reg = EXYNOS3250_OUT_FMT_422_1P_CHR_LUM |
  255. EXYNOS3250_OUT_SWAP_UV;
  256. break;
  257. case V4L2_PIX_FMT_NV12:
  258. reg = EXYNOS3250_OUT_FMT_420_2P | EXYNOS3250_OUT_NV12;
  259. break;
  260. case V4L2_PIX_FMT_NV21:
  261. reg = EXYNOS3250_OUT_FMT_420_2P | EXYNOS3250_OUT_NV21;
  262. break;
  263. case V4L2_PIX_FMT_YUV420:
  264. reg = EXYNOS3250_OUT_FMT_420_3P;
  265. break;
  266. default:
  267. reg = 0;
  268. break;
  269. }
  270. writel(reg, regs + EXYNOS3250_OUTFORM);
  271. }
  272. void exynos3250_jpeg_jpgadr(void __iomem *regs, unsigned int addr)
  273. {
  274. writel(addr, regs + EXYNOS3250_JPG_JPGADR);
  275. }
  276. void exynos3250_jpeg_imgadr(void __iomem *regs, struct s5p_jpeg_addr *img_addr)
  277. {
  278. writel(img_addr->y, regs + EXYNOS3250_LUMA_BASE);
  279. writel(img_addr->cb, regs + EXYNOS3250_CHROMA_BASE);
  280. writel(img_addr->cr, regs + EXYNOS3250_CHROMA_CR_BASE);
  281. }
  282. void exynos3250_jpeg_stride(void __iomem *regs, unsigned int img_fmt,
  283. unsigned int width)
  284. {
  285. u32 reg_luma = 0, reg_cr = 0, reg_cb = 0;
  286. switch (img_fmt) {
  287. case V4L2_PIX_FMT_RGB32:
  288. reg_luma = 4 * width;
  289. break;
  290. case V4L2_PIX_FMT_RGB565:
  291. case V4L2_PIX_FMT_RGB565X:
  292. case V4L2_PIX_FMT_YUYV:
  293. case V4L2_PIX_FMT_YVYU:
  294. case V4L2_PIX_FMT_UYVY:
  295. case V4L2_PIX_FMT_VYUY:
  296. reg_luma = 2 * width;
  297. break;
  298. case V4L2_PIX_FMT_NV12:
  299. case V4L2_PIX_FMT_NV21:
  300. reg_luma = width;
  301. reg_cb = reg_luma;
  302. break;
  303. case V4L2_PIX_FMT_YUV420:
  304. reg_luma = width;
  305. reg_cb = reg_cr = reg_luma / 2;
  306. break;
  307. default:
  308. break;
  309. }
  310. writel(reg_luma, regs + EXYNOS3250_LUMA_STRIDE);
  311. writel(reg_cb, regs + EXYNOS3250_CHROMA_STRIDE);
  312. writel(reg_cr, regs + EXYNOS3250_CHROMA_CR_STRIDE);
  313. }
  314. void exynos3250_jpeg_offset(void __iomem *regs, unsigned int x_offset,
  315. unsigned int y_offset)
  316. {
  317. u32 reg;
  318. reg = (y_offset << EXYNOS3250_LUMA_YY_OFFSET_SHIFT) &
  319. EXYNOS3250_LUMA_YY_OFFSET_MASK;
  320. reg |= (x_offset << EXYNOS3250_LUMA_YX_OFFSET_SHIFT) &
  321. EXYNOS3250_LUMA_YX_OFFSET_MASK;
  322. writel(reg, regs + EXYNOS3250_LUMA_XY_OFFSET);
  323. reg = (y_offset << EXYNOS3250_CHROMA_YY_OFFSET_SHIFT) &
  324. EXYNOS3250_CHROMA_YY_OFFSET_MASK;
  325. reg |= (x_offset << EXYNOS3250_CHROMA_YX_OFFSET_SHIFT) &
  326. EXYNOS3250_CHROMA_YX_OFFSET_MASK;
  327. writel(reg, regs + EXYNOS3250_CHROMA_XY_OFFSET);
  328. reg = (y_offset << EXYNOS3250_CHROMA_CR_YY_OFFSET_SHIFT) &
  329. EXYNOS3250_CHROMA_CR_YY_OFFSET_MASK;
  330. reg |= (x_offset << EXYNOS3250_CHROMA_CR_YX_OFFSET_SHIFT) &
  331. EXYNOS3250_CHROMA_CR_YX_OFFSET_MASK;
  332. writel(reg, regs + EXYNOS3250_CHROMA_CR_XY_OFFSET);
  333. }
  334. void exynos3250_jpeg_coef(void __iomem *base, unsigned int mode)
  335. {
  336. if (mode == S5P_JPEG_ENCODE) {
  337. writel(EXYNOS3250_JPEG_ENC_COEF1,
  338. base + EXYNOS3250_JPG_COEF(1));
  339. writel(EXYNOS3250_JPEG_ENC_COEF2,
  340. base + EXYNOS3250_JPG_COEF(2));
  341. writel(EXYNOS3250_JPEG_ENC_COEF3,
  342. base + EXYNOS3250_JPG_COEF(3));
  343. } else {
  344. writel(EXYNOS3250_JPEG_DEC_COEF1,
  345. base + EXYNOS3250_JPG_COEF(1));
  346. writel(EXYNOS3250_JPEG_DEC_COEF2,
  347. base + EXYNOS3250_JPG_COEF(2));
  348. writel(EXYNOS3250_JPEG_DEC_COEF3,
  349. base + EXYNOS3250_JPG_COEF(3));
  350. }
  351. }
  352. void exynos3250_jpeg_start(void __iomem *regs)
  353. {
  354. writel(1, regs + EXYNOS3250_JSTART);
  355. }
  356. void exynos3250_jpeg_rstart(void __iomem *regs)
  357. {
  358. writel(1, regs + EXYNOS3250_JRSTART);
  359. }
  360. unsigned int exynos3250_jpeg_get_int_status(void __iomem *regs)
  361. {
  362. return readl(regs + EXYNOS3250_JPGINTST);
  363. }
  364. void exynos3250_jpeg_clear_int_status(void __iomem *regs,
  365. unsigned int value)
  366. {
  367. return writel(value, regs + EXYNOS3250_JPGINTST);
  368. }
  369. unsigned int exynos3250_jpeg_operating(void __iomem *regs)
  370. {
  371. return readl(regs + S5P_JPGOPR) & EXYNOS3250_JPGOPR_MASK;
  372. }
  373. unsigned int exynos3250_jpeg_compressed_size(void __iomem *regs)
  374. {
  375. return readl(regs + EXYNOS3250_JPGCNT) & EXYNOS3250_JPGCNT_MASK;
  376. }
  377. void exynos3250_jpeg_dec_stream_size(void __iomem *regs,
  378. unsigned int size)
  379. {
  380. writel(size & EXYNOS3250_DEC_STREAM_MASK,
  381. regs + EXYNOS3250_DEC_STREAM_SIZE);
  382. }
  383. void exynos3250_jpeg_dec_scaling_ratio(void __iomem *regs,
  384. unsigned int sratio)
  385. {
  386. switch (sratio) {
  387. case 1:
  388. default:
  389. sratio = EXYNOS3250_DEC_SCALE_FACTOR_8_8;
  390. break;
  391. case 2:
  392. sratio = EXYNOS3250_DEC_SCALE_FACTOR_4_8;
  393. break;
  394. case 4:
  395. sratio = EXYNOS3250_DEC_SCALE_FACTOR_2_8;
  396. break;
  397. case 8:
  398. sratio = EXYNOS3250_DEC_SCALE_FACTOR_1_8;
  399. break;
  400. }
  401. writel(sratio & EXYNOS3250_DEC_SCALE_FACTOR_MASK,
  402. regs + EXYNOS3250_DEC_SCALING_RATIO);
  403. }
  404. void exynos3250_jpeg_set_timer(void __iomem *regs, unsigned int time_value)
  405. {
  406. time_value &= EXYNOS3250_TIMER_INIT_MASK;
  407. writel(EXYNOS3250_TIMER_INT_STAT | time_value,
  408. regs + EXYNOS3250_TIMER_SE);
  409. }
  410. unsigned int exynos3250_jpeg_get_timer_status(void __iomem *regs)
  411. {
  412. return readl(regs + EXYNOS3250_TIMER_ST);
  413. }
  414. void exynos3250_jpeg_clear_timer_status(void __iomem *regs)
  415. {
  416. writel(EXYNOS3250_TIMER_INT_STAT, regs + EXYNOS3250_TIMER_ST);
  417. }