linux/drivers/media/platform/s5p-jpeg/jpeg-hw-s5p.c
<<
>>
Prefs
   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