jpeg-hw-exynos4.c 8.3 KB

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