1/* linux/drivers/media/platform/s5p-jpeg/jpeg-hw.h 2 * 3 * Copyright (c) 2011 Samsung Electronics Co., Ltd. 4 * http://www.samsung.com 5 * 6 * Author: Andrzej Pietrasiewicz <andrzej.p@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 13#include <linux/io.h> 14#include <linux/videodev2.h> 15 16#include "jpeg-core.h" 17#include "jpeg-regs.h" 18#include "jpeg-hw-s5p.h" 19 20void s5p_jpeg_reset(void __iomem *regs) 21{ 22 unsigned long reg; 23 24 writel(1, regs + S5P_JPG_SW_RESET); 25 reg = readl(regs + S5P_JPG_SW_RESET); 26 /* no other way but polling for when JPEG IP becomes operational */ 27 while (reg != 0) { 28 cpu_relax(); 29 reg = readl(regs + S5P_JPG_SW_RESET); 30 } 31} 32 33void s5p_jpeg_poweron(void __iomem *regs) 34{ 35 writel(S5P_POWER_ON, regs + S5P_JPGCLKCON); 36} 37 38void s5p_jpeg_input_raw_mode(void __iomem *regs, unsigned long mode) 39{ 40 unsigned long reg, m; 41 42 m = S5P_MOD_SEL_565; 43 if (mode == S5P_JPEG_RAW_IN_565) 44 m = S5P_MOD_SEL_565; 45 else if (mode == S5P_JPEG_RAW_IN_422) 46 m = S5P_MOD_SEL_422; 47 48 reg = readl(regs + S5P_JPGCMOD); 49 reg &= ~S5P_MOD_SEL_MASK; 50 reg |= m; 51 writel(reg, regs + S5P_JPGCMOD); 52} 53 54void s5p_jpeg_input_raw_y16(void __iomem *regs, bool y16) 55{ 56 unsigned long reg; 57 58 reg = readl(regs + S5P_JPGCMOD); 59 if (y16) 60 reg |= S5P_MODE_Y16; 61 else 62 reg &= ~S5P_MODE_Y16_MASK; 63 writel(reg, regs + S5P_JPGCMOD); 64} 65 66void s5p_jpeg_proc_mode(void __iomem *regs, unsigned long mode) 67{ 68 unsigned long reg, m; 69 70 m = S5P_PROC_MODE_DECOMPR; 71 if (mode == S5P_JPEG_ENCODE) 72 m = S5P_PROC_MODE_COMPR; 73 else 74 m = S5P_PROC_MODE_DECOMPR; 75 reg = readl(regs + S5P_JPGMOD); 76 reg &= ~S5P_PROC_MODE_MASK; 77 reg |= m; 78 writel(reg, regs + S5P_JPGMOD); 79} 80 81void s5p_jpeg_subsampling_mode(void __iomem *regs, unsigned int mode) 82{ 83 unsigned long reg, m; 84 85 if (mode == V4L2_JPEG_CHROMA_SUBSAMPLING_420) 86 m = S5P_SUBSAMPLING_MODE_420; 87 else 88 m = S5P_SUBSAMPLING_MODE_422; 89 90 reg = readl(regs + S5P_JPGMOD); 91 reg &= ~S5P_SUBSAMPLING_MODE_MASK; 92 reg |= m; 93 writel(reg, regs + S5P_JPGMOD); 94} 95 96unsigned int s5p_jpeg_get_subsampling_mode(void __iomem *regs) 97{ 98 return readl(regs + S5P_JPGMOD) & S5P_SUBSAMPLING_MODE_MASK; 99} 100 101void s5p_jpeg_dri(void __iomem *regs, unsigned int dri) 102{ 103 unsigned long reg; 104 105 reg = readl(regs + S5P_JPGDRI_U); 106 reg &= ~0xff; 107 reg |= (dri >> 8) & 0xff; 108 writel(reg, regs + S5P_JPGDRI_U); 109 110 reg = readl(regs + S5P_JPGDRI_L); 111 reg &= ~0xff; 112 reg |= dri & 0xff; 113 writel(reg, regs + S5P_JPGDRI_L); 114} 115 116void s5p_jpeg_qtbl(void __iomem *regs, unsigned int t, unsigned int n) 117{ 118 unsigned long reg; 119 120 reg = readl(regs + S5P_JPG_QTBL); 121 reg &= ~S5P_QT_NUMt_MASK(t); 122 reg |= (n << S5P_QT_NUMt_SHIFT(t)) & S5P_QT_NUMt_MASK(t); 123 writel(reg, regs + S5P_JPG_QTBL); 124} 125 126void s5p_jpeg_htbl_ac(void __iomem *regs, unsigned int t) 127{ 128 unsigned long reg; 129 130 reg = readl(regs + S5P_JPG_HTBL); 131 reg &= ~S5P_HT_NUMt_AC_MASK(t); 132 /* this driver uses table 0 for all color components */ 133 reg |= (0 << S5P_HT_NUMt_AC_SHIFT(t)) & S5P_HT_NUMt_AC_MASK(t); 134 writel(reg, regs + S5P_JPG_HTBL); 135} 136 137void s5p_jpeg_htbl_dc(void __iomem *regs, unsigned int t) 138{ 139 unsigned long reg; 140 141 reg = readl(regs + S5P_JPG_HTBL); 142 reg &= ~S5P_HT_NUMt_DC_MASK(t); 143 /* this driver uses table 0 for all color components */ 144 reg |= (0 << S5P_HT_NUMt_DC_SHIFT(t)) & S5P_HT_NUMt_DC_MASK(t); 145 writel(reg, regs + S5P_JPG_HTBL); 146} 147 148void s5p_jpeg_y(void __iomem *regs, unsigned int y) 149{ 150 unsigned long reg; 151 152 reg = readl(regs + S5P_JPGY_U); 153 reg &= ~0xff; 154 reg |= (y >> 8) & 0xff; 155 writel(reg, regs + S5P_JPGY_U); 156 157 reg = readl(regs + S5P_JPGY_L); 158 reg &= ~0xff; 159 reg |= y & 0xff; 160 writel(reg, regs + S5P_JPGY_L); 161} 162 163void s5p_jpeg_x(void __iomem *regs, unsigned int x) 164{ 165 unsigned long reg; 166 167 reg = readl(regs + S5P_JPGX_U); 168 reg &= ~0xff; 169 reg |= (x >> 8) & 0xff; 170 writel(reg, regs + S5P_JPGX_U); 171 172 reg = readl(regs + S5P_JPGX_L); 173 reg &= ~0xff; 174 reg |= x & 0xff; 175 writel(reg, regs + S5P_JPGX_L); 176} 177 178void s5p_jpeg_rst_int_enable(void __iomem *regs, bool enable) 179{ 180 unsigned long reg; 181 182 reg = readl(regs + S5P_JPGINTSE); 183 reg &= ~S5P_RSTm_INT_EN_MASK; 184 if (enable) 185 reg |= S5P_RSTm_INT_EN; 186 writel(reg, regs + S5P_JPGINTSE); 187} 188 189void s5p_jpeg_data_num_int_enable(void __iomem *regs, bool enable) 190{ 191 unsigned long reg; 192 193 reg = readl(regs + S5P_JPGINTSE); 194 reg &= ~S5P_DATA_NUM_INT_EN_MASK; 195 if (enable) 196 reg |= S5P_DATA_NUM_INT_EN; 197 writel(reg, regs + S5P_JPGINTSE); 198} 199 200void s5p_jpeg_final_mcu_num_int_enable(void __iomem *regs, bool enbl) 201{ 202 unsigned long reg; 203 204 reg = readl(regs + S5P_JPGINTSE); 205 reg &= ~S5P_FINAL_MCU_NUM_INT_EN_MASK; 206 if (enbl) 207 reg |= S5P_FINAL_MCU_NUM_INT_EN; 208 writel(reg, regs + S5P_JPGINTSE); 209} 210 211void s5p_jpeg_timer_enable(void __iomem *regs, unsigned long val) 212{ 213 unsigned long reg; 214 215 reg = readl(regs + S5P_JPG_TIMER_SE); 216 reg |= S5P_TIMER_INT_EN; 217 reg &= ~S5P_TIMER_INIT_MASK; 218 reg |= val & S5P_TIMER_INIT_MASK; 219 writel(reg, regs + S5P_JPG_TIMER_SE); 220} 221 222void s5p_jpeg_timer_disable(void __iomem *regs) 223{ 224 unsigned long reg; 225 226 reg = readl(regs + S5P_JPG_TIMER_SE); 227 reg &= ~S5P_TIMER_INT_EN_MASK; 228 writel(reg, regs + S5P_JPG_TIMER_SE); 229} 230 231int s5p_jpeg_timer_stat(void __iomem *regs) 232{ 233 return (int)((readl(regs + S5P_JPG_TIMER_ST) & S5P_TIMER_INT_STAT_MASK) 234 >> S5P_TIMER_INT_STAT_SHIFT); 235} 236 237void s5p_jpeg_clear_timer_stat(void __iomem *regs) 238{ 239 unsigned long reg; 240 241 reg = readl(regs + S5P_JPG_TIMER_SE); 242 reg &= ~S5P_TIMER_INT_STAT_MASK; 243 writel(reg, regs + S5P_JPG_TIMER_SE); 244} 245 246void s5p_jpeg_enc_stream_int(void __iomem *regs, unsigned long size) 247{ 248 unsigned long reg; 249 250 reg = readl(regs + S5P_JPG_ENC_STREAM_INTSE); 251 reg &= ~S5P_ENC_STREAM_BOUND_MASK; 252 reg |= S5P_ENC_STREAM_INT_EN; 253 reg |= size & S5P_ENC_STREAM_BOUND_MASK; 254 writel(reg, regs + S5P_JPG_ENC_STREAM_INTSE); 255} 256 257int s5p_jpeg_enc_stream_stat(void __iomem *regs) 258{ 259 return (int)(readl(regs + S5P_JPG_ENC_STREAM_INTST) & 260 S5P_ENC_STREAM_INT_STAT_MASK); 261} 262 263void s5p_jpeg_clear_enc_stream_stat(void __iomem *regs) 264{ 265 unsigned long reg; 266 267 reg = readl(regs + S5P_JPG_ENC_STREAM_INTSE); 268 reg &= ~S5P_ENC_STREAM_INT_MASK; 269 writel(reg, regs + S5P_JPG_ENC_STREAM_INTSE); 270} 271 272void s5p_jpeg_outform_raw(void __iomem *regs, unsigned long format) 273{ 274 unsigned long reg, f; 275 276 f = S5P_DEC_OUT_FORMAT_422; 277 if (format == S5P_JPEG_RAW_OUT_422) 278 f = S5P_DEC_OUT_FORMAT_422; 279 else if (format == S5P_JPEG_RAW_OUT_420) 280 f = S5P_DEC_OUT_FORMAT_420; 281 reg = readl(regs + S5P_JPG_OUTFORM); 282 reg &= ~S5P_DEC_OUT_FORMAT_MASK; 283 reg |= f; 284 writel(reg, regs + S5P_JPG_OUTFORM); 285} 286 287void s5p_jpeg_jpgadr(void __iomem *regs, unsigned long addr) 288{ 289 writel(addr, regs + S5P_JPG_JPGADR); 290} 291 292void s5p_jpeg_imgadr(void __iomem *regs, unsigned long addr) 293{ 294 writel(addr, regs + S5P_JPG_IMGADR); 295} 296 297void s5p_jpeg_coef(void __iomem *regs, unsigned int i, 298 unsigned int j, unsigned int coef) 299{ 300 unsigned long reg; 301 302 reg = readl(regs + S5P_JPG_COEF(i)); 303 reg &= ~S5P_COEFn_MASK(j); 304 reg |= (coef << S5P_COEFn_SHIFT(j)) & S5P_COEFn_MASK(j); 305 writel(reg, regs + S5P_JPG_COEF(i)); 306} 307 308void s5p_jpeg_start(void __iomem *regs) 309{ 310 writel(1, regs + S5P_JSTART); 311} 312 313int s5p_jpeg_result_stat_ok(void __iomem *regs) 314{ 315 return (int)((readl(regs + S5P_JPGINTST) & S5P_RESULT_STAT_MASK) 316 >> S5P_RESULT_STAT_SHIFT); 317} 318 319int s5p_jpeg_stream_stat_ok(void __iomem *regs) 320{ 321 return !(int)((readl(regs + S5P_JPGINTST) & S5P_STREAM_STAT_MASK) 322 >> S5P_STREAM_STAT_SHIFT); 323} 324 325void s5p_jpeg_clear_int(void __iomem *regs) 326{ 327 readl(regs + S5P_JPGINTST); 328 writel(S5P_INT_RELEASE, regs + S5P_JPGCOM); 329 readl(regs + S5P_JPGOPR); 330} 331 332unsigned int s5p_jpeg_compressed_size(void __iomem *regs) 333{ 334 unsigned long jpeg_size = 0; 335 336 jpeg_size |= (readl(regs + S5P_JPGCNT_U) & 0xff) << 16; 337 jpeg_size |= (readl(regs + S5P_JPGCNT_M) & 0xff) << 8; 338 jpeg_size |= (readl(regs + S5P_JPGCNT_L) & 0xff); 339 340 return (unsigned int)jpeg_size; 341} 342