1// SPDX-License-Identifier: GPL-2.0-only 2/* linux/drivers/media/platform/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 17void 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 30void s5p_jpeg_poweron(void __iomem *regs) 31{ 32 writel(S5P_POWER_ON, regs + S5P_JPGCLKCON); 33} 34 35void 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 51void 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 66void 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 81unsigned int s5p_jpeg_get_subsampling_mode(void __iomem *regs) 82{ 83 return readl(regs + S5P_JPGMOD) & S5P_SUBSAMPLING_MODE_MASK; 84} 85 86void 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 101void 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 111void 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 122void 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 133void 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 148void 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 163void 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 174void 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 185void 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 196int 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 202void 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 211void 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 222int 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 228void 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 237void 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 252void s5p_jpeg_jpgadr(void __iomem *regs, unsigned long addr) 253{ 254 writel(addr, regs + S5P_JPG_JPGADR); 255} 256 257void s5p_jpeg_imgadr(void __iomem *regs, unsigned long addr) 258{ 259 writel(addr, regs + S5P_JPG_IMGADR); 260} 261 262void 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 273void s5p_jpeg_start(void __iomem *regs) 274{ 275 writel(1, regs + S5P_JSTART); 276} 277 278int 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 284int 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 290void 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 297unsigned 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