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