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