1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * Allwinner Hantro G2 VPU codec driver 4 * 5 * Copyright (C) 2021 Jernej Skrabec <jernej.skrabec@gmail.com> 6 */ 7 8 #include <linux/clk.h> 9 10 #include "hantro.h" 11 12 static const struct hantro_fmt sunxi_vpu_postproc_fmts[] = { 13 { 14 .fourcc = V4L2_PIX_FMT_NV12, 15 .codec_mode = HANTRO_MODE_NONE, 16 .postprocessed = true, 17 .frmsize = { 18 .min_width = FMT_MIN_WIDTH, 19 .max_width = FMT_UHD_WIDTH, 20 .step_width = 32, 21 .min_height = FMT_MIN_HEIGHT, 22 .max_height = FMT_UHD_HEIGHT, 23 .step_height = 32, 24 }, 25 }, 26 { 27 .fourcc = V4L2_PIX_FMT_P010, 28 .codec_mode = HANTRO_MODE_NONE, 29 .postprocessed = true, 30 .frmsize = { 31 .min_width = FMT_MIN_WIDTH, 32 .max_width = FMT_UHD_WIDTH, 33 .step_width = 32, 34 .min_height = FMT_MIN_HEIGHT, 35 .max_height = FMT_UHD_HEIGHT, 36 .step_height = 32, 37 }, 38 }, 39 }; 40 41 static const struct hantro_fmt sunxi_vpu_dec_fmts[] = { 42 { 43 .fourcc = V4L2_PIX_FMT_NV12_4L4, 44 .codec_mode = HANTRO_MODE_NONE, 45 .match_depth = true, 46 .frmsize = { 47 .min_width = FMT_MIN_WIDTH, 48 .max_width = FMT_UHD_WIDTH, 49 .step_width = 32, 50 .min_height = FMT_MIN_HEIGHT, 51 .max_height = FMT_UHD_HEIGHT, 52 .step_height = 32, 53 }, 54 }, 55 { 56 .fourcc = V4L2_PIX_FMT_P010_4L4, 57 .codec_mode = HANTRO_MODE_NONE, 58 .match_depth = true, 59 .frmsize = { 60 .min_width = FMT_MIN_WIDTH, 61 .max_width = FMT_UHD_WIDTH, 62 .step_width = 32, 63 .min_height = FMT_MIN_HEIGHT, 64 .max_height = FMT_UHD_HEIGHT, 65 .step_height = 32, 66 }, 67 }, 68 { 69 .fourcc = V4L2_PIX_FMT_VP9_FRAME, 70 .codec_mode = HANTRO_MODE_VP9_DEC, 71 .max_depth = 2, 72 .frmsize = { 73 .min_width = FMT_MIN_WIDTH, 74 .max_width = FMT_UHD_WIDTH, 75 .step_width = 32, 76 .min_height = FMT_MIN_HEIGHT, 77 .max_height = FMT_UHD_HEIGHT, 78 .step_height = 32, 79 }, 80 }, 81 }; 82 83 static int sunxi_vpu_hw_init(struct hantro_dev *vpu) 84 { 85 clk_set_rate(vpu->clocks[0].clk, 300000000); 86 87 return 0; 88 } 89 90 static void sunxi_vpu_reset(struct hantro_ctx *ctx) 91 { 92 struct hantro_dev *vpu = ctx->dev; 93 94 reset_control_reset(vpu->resets); 95 } 96 97 static const struct hantro_codec_ops sunxi_vpu_codec_ops[] = { 98 [HANTRO_MODE_VP9_DEC] = { 99 .run = hantro_g2_vp9_dec_run, 100 .done = hantro_g2_vp9_dec_done, 101 .reset = sunxi_vpu_reset, 102 .init = hantro_vp9_dec_init, 103 .exit = hantro_vp9_dec_exit, 104 }, 105 }; 106 107 static const struct hantro_irq sunxi_irqs[] = { 108 { NULL, hantro_g2_irq }, 109 }; 110 111 static const char * const sunxi_clk_names[] = { "mod", "bus" }; 112 113 const struct hantro_variant sunxi_vpu_variant = { 114 .dec_fmts = sunxi_vpu_dec_fmts, 115 .num_dec_fmts = ARRAY_SIZE(sunxi_vpu_dec_fmts), 116 .postproc_fmts = sunxi_vpu_postproc_fmts, 117 .num_postproc_fmts = ARRAY_SIZE(sunxi_vpu_postproc_fmts), 118 .postproc_ops = &hantro_g2_postproc_ops, 119 .codec = HANTRO_VP9_DECODER, 120 .codec_ops = sunxi_vpu_codec_ops, 121 .init = sunxi_vpu_hw_init, 122 .irqs = sunxi_irqs, 123 .num_irqs = ARRAY_SIZE(sunxi_irqs), 124 .clk_names = sunxi_clk_names, 125 .num_clocks = ARRAY_SIZE(sunxi_clk_names), 126 .double_buffer = 1, 127 .legacy_regs = 1, 128 .late_postproc = 1, 129 }; 130