root/drivers/staging/media/hantro/rk3288_vpu_hw.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. rk3288_vepu_irq
  2. rk3288_vdpu_irq
  3. rk3288_vpu_hw_init
  4. rk3288_vpu_enc_reset
  5. rk3288_vpu_dec_reset

   1 // SPDX-License-Identifier: GPL-2.0
   2 /*
   3  * Hantro VPU codec driver
   4  *
   5  * Copyright (C) 2018 Rockchip Electronics Co., Ltd.
   6  *      Jeffy Chen <jeffy.chen@rock-chips.com>
   7  */
   8 
   9 #include <linux/clk.h>
  10 
  11 #include "hantro.h"
  12 #include "hantro_jpeg.h"
  13 #include "hantro_g1_regs.h"
  14 #include "hantro_h1_regs.h"
  15 
  16 #define RK3288_ACLK_MAX_FREQ (400 * 1000 * 1000)
  17 
  18 /*
  19  * Supported formats.
  20  */
  21 
  22 static const struct hantro_fmt rk3288_vpu_enc_fmts[] = {
  23         {
  24                 .fourcc = V4L2_PIX_FMT_YUV420M,
  25                 .codec_mode = HANTRO_MODE_NONE,
  26                 .enc_fmt = RK3288_VPU_ENC_FMT_YUV420P,
  27         },
  28         {
  29                 .fourcc = V4L2_PIX_FMT_NV12M,
  30                 .codec_mode = HANTRO_MODE_NONE,
  31                 .enc_fmt = RK3288_VPU_ENC_FMT_YUV420SP,
  32         },
  33         {
  34                 .fourcc = V4L2_PIX_FMT_YUYV,
  35                 .codec_mode = HANTRO_MODE_NONE,
  36                 .enc_fmt = RK3288_VPU_ENC_FMT_YUYV422,
  37         },
  38         {
  39                 .fourcc = V4L2_PIX_FMT_UYVY,
  40                 .codec_mode = HANTRO_MODE_NONE,
  41                 .enc_fmt = RK3288_VPU_ENC_FMT_UYVY422,
  42         },
  43         {
  44                 .fourcc = V4L2_PIX_FMT_JPEG,
  45                 .codec_mode = HANTRO_MODE_JPEG_ENC,
  46                 .max_depth = 2,
  47                 .header_size = JPEG_HEADER_SIZE,
  48                 .frmsize = {
  49                         .min_width = 96,
  50                         .max_width = 8192,
  51                         .step_width = JPEG_MB_DIM,
  52                         .min_height = 32,
  53                         .max_height = 8192,
  54                         .step_height = JPEG_MB_DIM,
  55                 },
  56         },
  57 };
  58 
  59 static const struct hantro_fmt rk3288_vpu_dec_fmts[] = {
  60         {
  61                 .fourcc = V4L2_PIX_FMT_NV12,
  62                 .codec_mode = HANTRO_MODE_NONE,
  63         },
  64         {
  65                 .fourcc = V4L2_PIX_FMT_H264_SLICE,
  66                 .codec_mode = HANTRO_MODE_H264_DEC,
  67                 .max_depth = 2,
  68                 .frmsize = {
  69                         .min_width = 48,
  70                         .max_width = 3840,
  71                         .step_width = H264_MB_DIM,
  72                         .min_height = 48,
  73                         .max_height = 2160,
  74                         .step_height = H264_MB_DIM,
  75                 },
  76         },
  77         {
  78                 .fourcc = V4L2_PIX_FMT_MPEG2_SLICE,
  79                 .codec_mode = HANTRO_MODE_MPEG2_DEC,
  80                 .max_depth = 2,
  81                 .frmsize = {
  82                         .min_width = 48,
  83                         .max_width = 1920,
  84                         .step_width = MPEG2_MB_DIM,
  85                         .min_height = 48,
  86                         .max_height = 1088,
  87                         .step_height = MPEG2_MB_DIM,
  88                 },
  89         },
  90         {
  91                 .fourcc = V4L2_PIX_FMT_VP8_FRAME,
  92                 .codec_mode = HANTRO_MODE_VP8_DEC,
  93                 .max_depth = 2,
  94                 .frmsize = {
  95                         .min_width = 48,
  96                         .max_width = 3840,
  97                         .step_width = VP8_MB_DIM,
  98                         .min_height = 48,
  99                         .max_height = 2160,
 100                         .step_height = VP8_MB_DIM,
 101                 },
 102         },
 103 };
 104 
 105 static irqreturn_t rk3288_vepu_irq(int irq, void *dev_id)
 106 {
 107         struct hantro_dev *vpu = dev_id;
 108         enum vb2_buffer_state state;
 109         u32 status, bytesused;
 110 
 111         status = vepu_read(vpu, H1_REG_INTERRUPT);
 112         bytesused = vepu_read(vpu, H1_REG_STR_BUF_LIMIT) / 8;
 113         state = (status & H1_REG_INTERRUPT_FRAME_RDY) ?
 114                 VB2_BUF_STATE_DONE : VB2_BUF_STATE_ERROR;
 115 
 116         vepu_write(vpu, 0, H1_REG_INTERRUPT);
 117         vepu_write(vpu, 0, H1_REG_AXI_CTRL);
 118 
 119         hantro_irq_done(vpu, bytesused, state);
 120 
 121         return IRQ_HANDLED;
 122 }
 123 
 124 static irqreturn_t rk3288_vdpu_irq(int irq, void *dev_id)
 125 {
 126         struct hantro_dev *vpu = dev_id;
 127         enum vb2_buffer_state state;
 128         u32 status;
 129 
 130         status = vdpu_read(vpu, G1_REG_INTERRUPT);
 131         state = (status & G1_REG_INTERRUPT_DEC_RDY_INT) ?
 132                 VB2_BUF_STATE_DONE : VB2_BUF_STATE_ERROR;
 133 
 134         vdpu_write(vpu, 0, G1_REG_INTERRUPT);
 135         vdpu_write(vpu, G1_REG_CONFIG_DEC_CLK_GATE_E, G1_REG_CONFIG);
 136 
 137         hantro_irq_done(vpu, 0, state);
 138 
 139         return IRQ_HANDLED;
 140 }
 141 
 142 static int rk3288_vpu_hw_init(struct hantro_dev *vpu)
 143 {
 144         /* Bump ACLK to max. possible freq. to improve performance. */
 145         clk_set_rate(vpu->clocks[0].clk, RK3288_ACLK_MAX_FREQ);
 146         return 0;
 147 }
 148 
 149 static void rk3288_vpu_enc_reset(struct hantro_ctx *ctx)
 150 {
 151         struct hantro_dev *vpu = ctx->dev;
 152 
 153         vepu_write(vpu, H1_REG_INTERRUPT_DIS_BIT, H1_REG_INTERRUPT);
 154         vepu_write(vpu, 0, H1_REG_ENC_CTRL);
 155         vepu_write(vpu, 0, H1_REG_AXI_CTRL);
 156 }
 157 
 158 static void rk3288_vpu_dec_reset(struct hantro_ctx *ctx)
 159 {
 160         struct hantro_dev *vpu = ctx->dev;
 161 
 162         vdpu_write(vpu, G1_REG_INTERRUPT_DEC_IRQ_DIS, G1_REG_INTERRUPT);
 163         vdpu_write(vpu, G1_REG_CONFIG_DEC_CLK_GATE_E, G1_REG_CONFIG);
 164         vdpu_write(vpu, 1, G1_REG_SOFT_RESET);
 165 }
 166 
 167 /*
 168  * Supported codec ops.
 169  */
 170 
 171 static const struct hantro_codec_ops rk3288_vpu_codec_ops[] = {
 172         [HANTRO_MODE_JPEG_ENC] = {
 173                 .run = hantro_h1_jpeg_enc_run,
 174                 .reset = rk3288_vpu_enc_reset,
 175                 .init = hantro_jpeg_enc_init,
 176                 .exit = hantro_jpeg_enc_exit,
 177         },
 178         [HANTRO_MODE_H264_DEC] = {
 179                 .run = hantro_g1_h264_dec_run,
 180                 .reset = rk3288_vpu_dec_reset,
 181                 .init = hantro_h264_dec_init,
 182                 .exit = hantro_h264_dec_exit,
 183         },
 184         [HANTRO_MODE_MPEG2_DEC] = {
 185                 .run = hantro_g1_mpeg2_dec_run,
 186                 .reset = rk3288_vpu_dec_reset,
 187                 .init = hantro_mpeg2_dec_init,
 188                 .exit = hantro_mpeg2_dec_exit,
 189         },
 190         [HANTRO_MODE_VP8_DEC] = {
 191                 .run = hantro_g1_vp8_dec_run,
 192                 .reset = rk3288_vpu_dec_reset,
 193                 .init = hantro_vp8_dec_init,
 194                 .exit = hantro_vp8_dec_exit,
 195         },
 196 };
 197 
 198 /*
 199  * VPU variant.
 200  */
 201 
 202 static const struct hantro_irq rk3288_irqs[] = {
 203         { "vepu", rk3288_vepu_irq },
 204         { "vdpu", rk3288_vdpu_irq },
 205 };
 206 
 207 static const char * const rk3288_clk_names[] = {
 208         "aclk", "hclk"
 209 };
 210 
 211 const struct hantro_variant rk3288_vpu_variant = {
 212         .enc_offset = 0x0,
 213         .enc_fmts = rk3288_vpu_enc_fmts,
 214         .num_enc_fmts = ARRAY_SIZE(rk3288_vpu_enc_fmts),
 215         .dec_offset = 0x400,
 216         .dec_fmts = rk3288_vpu_dec_fmts,
 217         .num_dec_fmts = ARRAY_SIZE(rk3288_vpu_dec_fmts),
 218         .codec = HANTRO_JPEG_ENCODER | HANTRO_MPEG2_DECODER |
 219                  HANTRO_VP8_DECODER | HANTRO_H264_DECODER,
 220         .codec_ops = rk3288_vpu_codec_ops,
 221         .irqs = rk3288_irqs,
 222         .num_irqs = ARRAY_SIZE(rk3288_irqs),
 223         .init = rk3288_vpu_hw_init,
 224         .clk_names = rk3288_clk_names,
 225         .num_clocks = ARRAY_SIZE(rk3288_clk_names)
 226 };

/* [<][>][^][v][top][bottom][index][help] */