jpeg-hw-exynos4.c 8.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317
  1. /* Copyright (c) 2013 Samsung Electronics Co., Ltd.
  2. * http://www.samsung.com/
  3. *
  4. * Author: Jacek Anaszewski <j.anaszewski@samsung.com>
  5. *
  6. * Register interface file for JPEG driver on Exynos4x12.
  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/delay.h>
  14. #include "jpeg-core.h"
  15. #include "jpeg-hw-exynos4.h"
  16. #include "jpeg-regs.h"
  17. void exynos4_jpeg_sw_reset(void __iomem *base)
  18. {
  19. unsigned int reg;
  20. reg = readl(base + EXYNOS4_JPEG_CNTL_REG);
  21. writel(reg & ~EXYNOS4_SOFT_RESET_HI, base + EXYNOS4_JPEG_CNTL_REG);
  22. udelay(100);
  23. writel(reg | EXYNOS4_SOFT_RESET_HI, base + EXYNOS4_JPEG_CNTL_REG);
  24. }
  25. void exynos4_jpeg_set_enc_dec_mode(void __iomem *base, unsigned int mode)
  26. {
  27. unsigned int reg;
  28. reg = readl(base + EXYNOS4_JPEG_CNTL_REG);
  29. /* set exynos4_jpeg mod register */
  30. if (mode == S5P_JPEG_DECODE) {
  31. writel((reg & EXYNOS4_ENC_DEC_MODE_MASK) |
  32. EXYNOS4_DEC_MODE,
  33. base + EXYNOS4_JPEG_CNTL_REG);
  34. } else {/* encode */
  35. writel((reg & EXYNOS4_ENC_DEC_MODE_MASK) |
  36. EXYNOS4_ENC_MODE,
  37. base + EXYNOS4_JPEG_CNTL_REG);
  38. }
  39. }
  40. void __exynos4_jpeg_set_img_fmt(void __iomem *base, unsigned int img_fmt,
  41. unsigned int version)
  42. {
  43. unsigned int reg;
  44. unsigned int exynos4_swap_chroma_cbcr;
  45. unsigned int exynos4_swap_chroma_crcb;
  46. if (version == SJPEG_EXYNOS4) {
  47. exynos4_swap_chroma_cbcr = EXYNOS4_SWAP_CHROMA_CBCR;
  48. exynos4_swap_chroma_crcb = EXYNOS4_SWAP_CHROMA_CRCB;
  49. } else {
  50. exynos4_swap_chroma_cbcr = EXYNOS5433_SWAP_CHROMA_CBCR;
  51. exynos4_swap_chroma_crcb = EXYNOS5433_SWAP_CHROMA_CRCB;
  52. }
  53. reg = readl(base + EXYNOS4_IMG_FMT_REG) &
  54. EXYNOS4_ENC_IN_FMT_MASK; /* clear except enc format */
  55. switch (img_fmt) {
  56. case V4L2_PIX_FMT_GREY:
  57. reg = reg | EXYNOS4_ENC_GRAY_IMG | EXYNOS4_GRAY_IMG_IP;
  58. break;
  59. case V4L2_PIX_FMT_RGB32:
  60. reg = reg | EXYNOS4_ENC_RGB_IMG |
  61. EXYNOS4_RGB_IP_RGB_32BIT_IMG;
  62. break;
  63. case V4L2_PIX_FMT_RGB565:
  64. reg = reg | EXYNOS4_ENC_RGB_IMG |
  65. EXYNOS4_RGB_IP_RGB_16BIT_IMG;
  66. break;
  67. case V4L2_PIX_FMT_NV24:
  68. reg = reg | EXYNOS4_ENC_YUV_444_IMG |
  69. EXYNOS4_YUV_444_IP_YUV_444_2P_IMG |
  70. exynos4_swap_chroma_cbcr;
  71. break;
  72. case V4L2_PIX_FMT_NV42:
  73. reg = reg | EXYNOS4_ENC_YUV_444_IMG |
  74. EXYNOS4_YUV_444_IP_YUV_444_2P_IMG |
  75. exynos4_swap_chroma_crcb;
  76. break;
  77. case V4L2_PIX_FMT_YUYV:
  78. reg = reg | EXYNOS4_DEC_YUV_422_IMG |
  79. EXYNOS4_YUV_422_IP_YUV_422_1P_IMG |
  80. exynos4_swap_chroma_cbcr;
  81. break;
  82. case V4L2_PIX_FMT_YVYU:
  83. reg = reg | EXYNOS4_DEC_YUV_422_IMG |
  84. EXYNOS4_YUV_422_IP_YUV_422_1P_IMG |
  85. exynos4_swap_chroma_crcb;
  86. break;
  87. case V4L2_PIX_FMT_NV16:
  88. reg = reg | EXYNOS4_DEC_YUV_422_IMG |
  89. EXYNOS4_YUV_422_IP_YUV_422_2P_IMG |
  90. exynos4_swap_chroma_cbcr;
  91. break;
  92. case V4L2_PIX_FMT_NV61:
  93. reg = reg | EXYNOS4_DEC_YUV_422_IMG |
  94. EXYNOS4_YUV_422_IP_YUV_422_2P_IMG |
  95. exynos4_swap_chroma_crcb;
  96. break;
  97. case V4L2_PIX_FMT_NV12:
  98. reg = reg | EXYNOS4_DEC_YUV_420_IMG |
  99. EXYNOS4_YUV_420_IP_YUV_420_2P_IMG |
  100. exynos4_swap_chroma_cbcr;
  101. break;
  102. case V4L2_PIX_FMT_NV21:
  103. reg = reg | EXYNOS4_DEC_YUV_420_IMG |
  104. EXYNOS4_YUV_420_IP_YUV_420_2P_IMG |
  105. exynos4_swap_chroma_crcb;
  106. break;
  107. case V4L2_PIX_FMT_YUV420:
  108. reg = reg | EXYNOS4_DEC_YUV_420_IMG |
  109. EXYNOS4_YUV_420_IP_YUV_420_3P_IMG |
  110. exynos4_swap_chroma_cbcr;
  111. break;
  112. default:
  113. break;
  114. }
  115. writel(reg, base + EXYNOS4_IMG_FMT_REG);
  116. }
  117. void __exynos4_jpeg_set_enc_out_fmt(void __iomem *base, unsigned int out_fmt,
  118. unsigned int version)
  119. {
  120. unsigned int reg;
  121. reg = readl(base + EXYNOS4_IMG_FMT_REG) &
  122. ~(version == SJPEG_EXYNOS4 ? EXYNOS4_ENC_FMT_MASK :
  123. EXYNOS5433_ENC_FMT_MASK); /* clear enc format */
  124. switch (out_fmt) {
  125. case V4L2_JPEG_CHROMA_SUBSAMPLING_GRAY:
  126. reg = reg | EXYNOS4_ENC_FMT_GRAY;
  127. break;
  128. case V4L2_JPEG_CHROMA_SUBSAMPLING_444:
  129. reg = reg | EXYNOS4_ENC_FMT_YUV_444;
  130. break;
  131. case V4L2_JPEG_CHROMA_SUBSAMPLING_422:
  132. reg = reg | EXYNOS4_ENC_FMT_YUV_422;
  133. break;
  134. case V4L2_JPEG_CHROMA_SUBSAMPLING_420:
  135. reg = reg | EXYNOS4_ENC_FMT_YUV_420;
  136. break;
  137. default:
  138. break;
  139. }
  140. writel(reg, base + EXYNOS4_IMG_FMT_REG);
  141. }
  142. void exynos4_jpeg_set_interrupt(void __iomem *base, unsigned int version)
  143. {
  144. unsigned int reg;
  145. if (version == SJPEG_EXYNOS4) {
  146. reg = readl(base + EXYNOS4_INT_EN_REG) & ~EXYNOS4_INT_EN_MASK;
  147. writel(reg | EXYNOS4_INT_EN_ALL, base + EXYNOS4_INT_EN_REG);
  148. } else {
  149. reg = readl(base + EXYNOS4_INT_EN_REG) &
  150. ~EXYNOS5433_INT_EN_MASK;
  151. writel(reg | EXYNOS5433_INT_EN_ALL, base + EXYNOS4_INT_EN_REG);
  152. }
  153. }
  154. unsigned int exynos4_jpeg_get_int_status(void __iomem *base)
  155. {
  156. return readl(base + EXYNOS4_INT_STATUS_REG);
  157. }
  158. unsigned int exynos4_jpeg_get_fifo_status(void __iomem *base)
  159. {
  160. return readl(base + EXYNOS4_FIFO_STATUS_REG);
  161. }
  162. void exynos4_jpeg_set_huf_table_enable(void __iomem *base, int value)
  163. {
  164. unsigned int reg;
  165. reg = readl(base + EXYNOS4_JPEG_CNTL_REG) & ~EXYNOS4_HUF_TBL_EN;
  166. if (value == 1)
  167. writel(reg | EXYNOS4_HUF_TBL_EN,
  168. base + EXYNOS4_JPEG_CNTL_REG);
  169. else
  170. writel(reg & ~EXYNOS4_HUF_TBL_EN,
  171. base + EXYNOS4_JPEG_CNTL_REG);
  172. }
  173. void exynos4_jpeg_set_sys_int_enable(void __iomem *base, int value)
  174. {
  175. unsigned int reg;
  176. reg = readl(base + EXYNOS4_JPEG_CNTL_REG) & ~(EXYNOS4_SYS_INT_EN);
  177. if (value == 1)
  178. writel(reg | EXYNOS4_SYS_INT_EN, base + EXYNOS4_JPEG_CNTL_REG);
  179. else
  180. writel(reg & ~EXYNOS4_SYS_INT_EN, base + EXYNOS4_JPEG_CNTL_REG);
  181. }
  182. void exynos4_jpeg_set_stream_buf_address(void __iomem *base,
  183. unsigned int address)
  184. {
  185. writel(address, base + EXYNOS4_OUT_MEM_BASE_REG);
  186. }
  187. void exynos4_jpeg_set_stream_size(void __iomem *base,
  188. unsigned int x_value, unsigned int y_value)
  189. {
  190. writel(0x0, base + EXYNOS4_JPEG_IMG_SIZE_REG); /* clear */
  191. writel(EXYNOS4_X_SIZE(x_value) | EXYNOS4_Y_SIZE(y_value),
  192. base + EXYNOS4_JPEG_IMG_SIZE_REG);
  193. }
  194. void exynos4_jpeg_set_frame_buf_address(void __iomem *base,
  195. struct s5p_jpeg_addr *exynos4_jpeg_addr)
  196. {
  197. writel(exynos4_jpeg_addr->y, base + EXYNOS4_IMG_BA_PLANE_1_REG);
  198. writel(exynos4_jpeg_addr->cb, base + EXYNOS4_IMG_BA_PLANE_2_REG);
  199. writel(exynos4_jpeg_addr->cr, base + EXYNOS4_IMG_BA_PLANE_3_REG);
  200. }
  201. void exynos4_jpeg_set_encode_tbl_select(void __iomem *base,
  202. enum exynos4_jpeg_img_quality_level level)
  203. {
  204. unsigned int reg;
  205. reg = EXYNOS4_Q_TBL_COMP1_0 | EXYNOS4_Q_TBL_COMP2_1 |
  206. EXYNOS4_Q_TBL_COMP3_1 |
  207. EXYNOS4_HUFF_TBL_COMP1_AC_0_DC_1 |
  208. EXYNOS4_HUFF_TBL_COMP2_AC_0_DC_0 |
  209. EXYNOS4_HUFF_TBL_COMP3_AC_1_DC_1;
  210. writel(reg, base + EXYNOS4_TBL_SEL_REG);
  211. }
  212. void exynos4_jpeg_set_dec_components(void __iomem *base, int n)
  213. {
  214. unsigned int reg;
  215. reg = readl(base + EXYNOS4_TBL_SEL_REG);
  216. reg |= EXYNOS4_NF(n);
  217. writel(reg, base + EXYNOS4_TBL_SEL_REG);
  218. }
  219. void exynos4_jpeg_select_dec_q_tbl(void __iomem *base, char c, char x)
  220. {
  221. unsigned int reg;
  222. reg = readl(base + EXYNOS4_TBL_SEL_REG);
  223. reg |= EXYNOS4_Q_TBL_COMP(c, x);
  224. writel(reg, base + EXYNOS4_TBL_SEL_REG);
  225. }
  226. void exynos4_jpeg_select_dec_h_tbl(void __iomem *base, char c, char x)
  227. {
  228. unsigned int reg;
  229. reg = readl(base + EXYNOS4_TBL_SEL_REG);
  230. reg |= EXYNOS4_HUFF_TBL_COMP(c, x);
  231. writel(reg, base + EXYNOS4_TBL_SEL_REG);
  232. }
  233. void exynos4_jpeg_set_encode_hoff_cnt(void __iomem *base, unsigned int fmt)
  234. {
  235. if (fmt == V4L2_PIX_FMT_GREY)
  236. writel(0xd2, base + EXYNOS4_HUFF_CNT_REG);
  237. else
  238. writel(0x1a2, base + EXYNOS4_HUFF_CNT_REG);
  239. }
  240. unsigned int exynos4_jpeg_get_stream_size(void __iomem *base)
  241. {
  242. return readl(base + EXYNOS4_BITSTREAM_SIZE_REG);
  243. }
  244. void exynos4_jpeg_set_dec_bitstream_size(void __iomem *base, unsigned int size)
  245. {
  246. writel(size, base + EXYNOS4_BITSTREAM_SIZE_REG);
  247. }
  248. void exynos4_jpeg_get_frame_size(void __iomem *base,
  249. unsigned int *width, unsigned int *height)
  250. {
  251. *width = (readl(base + EXYNOS4_DECODE_XY_SIZE_REG) &
  252. EXYNOS4_DECODED_SIZE_MASK);
  253. *height = (readl(base + EXYNOS4_DECODE_XY_SIZE_REG) >> 16) &
  254. EXYNOS4_DECODED_SIZE_MASK;
  255. }
  256. unsigned int exynos4_jpeg_get_frame_fmt(void __iomem *base)
  257. {
  258. return readl(base + EXYNOS4_DECODE_IMG_FMT_REG) &
  259. EXYNOS4_JPEG_DECODED_IMG_FMT_MASK;
  260. }
  261. void exynos4_jpeg_set_timer_count(void __iomem *base, unsigned int size)
  262. {
  263. writel(size, base + EXYNOS4_INT_TIMER_COUNT_REG);
  264. }