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_proc_mode(void __iomem *regs, unsigned long mode) 55{ 56 unsigned long reg, m; 57 58 m = S5P_PROC_MODE_DECOMPR; 59 if (mode == S5P_JPEG_ENCODE) 60 m = S5P_PROC_MODE_COMPR; 61 else 62 m = S5P_PROC_MODE_DECOMPR; 63 reg = readl(regs + S5P_JPGMOD); 64 reg &= ~S5P_PROC_MODE_MASK; 65 reg |= m; 66 writel(reg, regs + S5P_JPGMOD); 67} 68 69void s5p_jpeg_subsampling_mode(void __iomem *regs, unsigned int mode) 70{ 71 unsigned long reg, m; 72 73 if (mode == V4L2_JPEG_CHROMA_SUBSAMPLING_420) 74 m = S5P_SUBSAMPLING_MODE_420; 75 else 76 m = S5P_SUBSAMPLING_MODE_422; 77 78 reg = readl(regs + S5P_JPGMOD); 79 reg &= ~S5P_SUBSAMPLING_MODE_MASK; 80 reg |= m; 81 writel(reg, regs + S5P_JPGMOD); 82} 83 84unsigned int s5p_jpeg_get_subsampling_mode(void __iomem *regs) 85{ 86 return readl(regs + S5P_JPGMOD) & S5P_SUBSAMPLING_MODE_MASK; 87} 88 89void s5p_jpeg_dri(void __iomem *regs, unsigned int dri) 90{ 91 unsigned long reg; 92 93 reg = readl(regs + S5P_JPGDRI_U); 94 reg &= ~0xff; 95 reg |= (dri >> 8) & 0xff; 96 writel(reg, regs + S5P_JPGDRI_U); 97 98 reg = readl(regs + S5P_JPGDRI_L); 99 reg &= ~0xff; 100 reg |= dri & 0xff; 101 writel(reg, regs + S5P_JPGDRI_L); 102} 103 104void s5p_jpeg_qtbl(void __iomem *regs, unsigned int t, unsigned int n) 105{ 106 unsigned long reg; 107 108 reg = readl(regs + S5P_JPG_QTBL); 109 reg &= ~S5P_QT_NUMt_MASK(t); 110 reg |= (n << S5P_QT_NUMt_SHIFT(t)) & S5P_QT_NUMt_MASK(t); 111 writel(reg, regs + S5P_JPG_QTBL); 112} 113 114void s5p_jpeg_htbl_ac(void __iomem *regs, unsigned int t) 115{ 116 unsigned long reg; 117 118 reg = readl(regs + S5P_JPG_HTBL); 119 reg &= ~S5P_HT_NUMt_AC_MASK(t); 120 /* this driver uses table 0 for all color components */ 121 reg |= (0 << S5P_HT_NUMt_AC_SHIFT(t)) & S5P_HT_NUMt_AC_MASK(t); 122 writel(reg, regs + S5P_JPG_HTBL); 123} 124 125void s5p_jpeg_htbl_dc(void __iomem *regs, unsigned int t) 126{ 127 unsigned long reg; 128 129 reg = readl(regs + S5P_JPG_HTBL); 130 reg &= ~S5P_HT_NUMt_DC_MASK(t); 131 /* this driver uses table 0 for all color components */ 132 reg |= (0 << S5P_HT_NUMt_DC_SHIFT(t)) & S5P_HT_NUMt_DC_MASK(t); 133 writel(reg, regs + S5P_JPG_HTBL); 134} 135 136void s5p_jpeg_y(void __iomem *regs, unsigned int y) 137{ 138 unsigned long reg; 139 140 reg = readl(regs + S5P_JPGY_U); 141 reg &= ~0xff; 142 reg |= (y >> 8) & 0xff; 143 writel(reg, regs + S5P_JPGY_U); 144 145 reg = readl(regs + S5P_JPGY_L); 146 reg &= ~0xff; 147 reg |= y & 0xff; 148 writel(reg, regs + S5P_JPGY_L); 149} 150 151void s5p_jpeg_x(void __iomem *regs, unsigned int x) 152{ 153 unsigned long reg; 154 155 reg = readl(regs + S5P_JPGX_U); 156 reg &= ~0xff; 157 reg |= (x >> 8) & 0xff; 158 writel(reg, regs + S5P_JPGX_U); 159 160 reg = readl(regs + S5P_JPGX_L); 161 reg &= ~0xff; 162 reg |= x & 0xff; 163 writel(reg, regs + S5P_JPGX_L); 164} 165 166void s5p_jpeg_rst_int_enable(void __iomem *regs, bool enable) 167{ 168 unsigned long reg; 169 170 reg = readl(regs + S5P_JPGINTSE); 171 reg &= ~S5P_RSTm_INT_EN_MASK; 172 if (enable) 173 reg |= S5P_RSTm_INT_EN; 174 writel(reg, regs + S5P_JPGINTSE); 175} 176 177void s5p_jpeg_data_num_int_enable(void __iomem *regs, bool enable) 178{ 179 unsigned long reg; 180 181 reg = readl(regs + S5P_JPGINTSE); 182 reg &= ~S5P_DATA_NUM_INT_EN_MASK; 183 if (enable) 184 reg |= S5P_DATA_NUM_INT_EN; 185 writel(reg, regs + S5P_JPGINTSE); 186} 187 188void s5p_jpeg_final_mcu_num_int_enable(void __iomem *regs, bool enbl) 189{ 190 unsigned long reg; 191 192 reg = readl(regs + S5P_JPGINTSE); 193 reg &= ~S5P_FINAL_MCU_NUM_INT_EN_MASK; 194 if (enbl) 195 reg |= S5P_FINAL_MCU_NUM_INT_EN; 196 writel(reg, regs + S5P_JPGINTSE); 197} 198 199int s5p_jpeg_timer_stat(void __iomem *regs) 200{ 201 return (int)((readl(regs + S5P_JPG_TIMER_ST) & S5P_TIMER_INT_STAT_MASK) 202 >> S5P_TIMER_INT_STAT_SHIFT); 203} 204 205void s5p_jpeg_clear_timer_stat(void __iomem *regs) 206{ 207 unsigned long reg; 208 209 reg = readl(regs + S5P_JPG_TIMER_SE); 210 reg &= ~S5P_TIMER_INT_STAT_MASK; 211 writel(reg, regs + S5P_JPG_TIMER_SE); 212} 213 214void s5p_jpeg_enc_stream_int(void __iomem *regs, unsigned long size) 215{ 216 unsigned long reg; 217 218 reg = readl(regs + S5P_JPG_ENC_STREAM_INTSE); 219 reg &= ~S5P_ENC_STREAM_BOUND_MASK; 220 reg |= S5P_ENC_STREAM_INT_EN; 221 reg |= size & S5P_ENC_STREAM_BOUND_MASK; 222 writel(reg, regs + S5P_JPG_ENC_STREAM_INTSE); 223} 224 225int s5p_jpeg_enc_stream_stat(void __iomem *regs) 226{ 227 return (int)(readl(regs + S5P_JPG_ENC_STREAM_INTST) & 228 S5P_ENC_STREAM_INT_STAT_MASK); 229} 230 231void s5p_jpeg_clear_enc_stream_stat(void __iomem *regs) 232{ 233 unsigned long reg; 234 235 reg = readl(regs + S5P_JPG_ENC_STREAM_INTSE); 236 reg &= ~S5P_ENC_STREAM_INT_MASK; 237 writel(reg, regs + S5P_JPG_ENC_STREAM_INTSE); 238} 239 240void s5p_jpeg_outform_raw(void __iomem *regs, unsigned long format) 241{ 242 unsigned long reg, f; 243 244 f = S5P_DEC_OUT_FORMAT_422; 245 if (format == S5P_JPEG_RAW_OUT_422) 246 f = S5P_DEC_OUT_FORMAT_422; 247 else if (format == S5P_JPEG_RAW_OUT_420) 248 f = S5P_DEC_OUT_FORMAT_420; 249 reg = readl(regs + S5P_JPG_OUTFORM); 250 reg &= ~S5P_DEC_OUT_FORMAT_MASK; 251 reg |= f; 252 writel(reg, regs + S5P_JPG_OUTFORM); 253} 254 255void s5p_jpeg_jpgadr(void __iomem *regs, unsigned long addr) 256{ 257 writel(addr, regs + S5P_JPG_JPGADR); 258} 259 260void s5p_jpeg_imgadr(void __iomem *regs, unsigned long addr) 261{ 262 writel(addr, regs + S5P_JPG_IMGADR); 263} 264 265void s5p_jpeg_coef(void __iomem *regs, unsigned int i, 266 unsigned int j, unsigned int coef) 267{ 268 unsigned long reg; 269 270 reg = readl(regs + S5P_JPG_COEF(i)); 271 reg &= ~S5P_COEFn_MASK(j); 272 reg |= (coef << S5P_COEFn_SHIFT(j)) & S5P_COEFn_MASK(j); 273 writel(reg, regs + S5P_JPG_COEF(i)); 274} 275 276void s5p_jpeg_start(void __iomem *regs) 277{ 278 writel(1, regs + S5P_JSTART); 279} 280 281int s5p_jpeg_result_stat_ok(void __iomem *regs) 282{ 283 return (int)((readl(regs + S5P_JPGINTST) & S5P_RESULT_STAT_MASK) 284 >> S5P_RESULT_STAT_SHIFT); 285} 286 287int s5p_jpeg_stream_stat_ok(void __iomem *regs) 288{ 289 return !(int)((readl(regs + S5P_JPGINTST) & S5P_STREAM_STAT_MASK) 290 >> S5P_STREAM_STAT_SHIFT); 291} 292 293void s5p_jpeg_clear_int(void __iomem *regs) 294{ 295 readl(regs + S5P_JPGINTST); 296 writel(S5P_INT_RELEASE, regs + S5P_JPGCOM); 297 readl(regs + S5P_JPGOPR); 298} 299 300unsigned int s5p_jpeg_compressed_size(void __iomem *regs) 301{ 302 unsigned long jpeg_size = 0; 303 304 jpeg_size |= (readl(regs + S5P_JPGCNT_U) & 0xff) << 16; 305 jpeg_size |= (readl(regs + S5P_JPGCNT_M) & 0xff) << 8; 306 jpeg_size |= (readl(regs + S5P_JPGCNT_L) & 0xff); 307 308 return (unsigned int)jpeg_size; 309} 310