306 lines · c
1// SPDX-License-Identifier: GPL-2.0-only2/* linux/drivers/media/platform/samsung/s5p-jpeg/jpeg-hw.h3 *4 * Copyright (c) 2011 Samsung Electronics Co., Ltd.5 * http://www.samsung.com6 *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 else58 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 else72 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}306