2 * Rockchip RK3288 VPU codec driver
4 * Copyright (C) 2014 Google, Inc.
5 * Tomasz Figa <tfiga@chromium.org>
7 * This software is licensed under the terms of the GNU General Public
8 * License version 2, as published by the Free Software Foundation, and
9 * may be copied, distributed, and modified under those terms.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
17 #include "rk3288_vpu_common.h"
19 #include <linux/clk.h>
20 #include <linux/delay.h>
21 #include <linux/interrupt.h>
23 #include <linux/pm_runtime.h>
24 #include <linux/module.h>
25 #include <linux/platform_device.h>
26 #include <linux/sched.h>
27 #include <linux/slab.h>
29 #include <linux/of_platform.h>
31 #include <asm/dma-iommu.h>
33 #include "rk3288_vpu_regs.h"
36 * struct rk3288_vpu_variant - information about VPU hardware variant
38 * @hw_id: Top 16 bits (product ID) of hardware ID register.
39 * @enc_offset: Offset from VPU base to encoder registers.
40 * @enc_reg_num: Number of registers of encoder block.
41 * @dec_offset: Offset from VPU base to decoder registers.
42 * @dec_reg_num: Number of registers of decoder block.
44 struct rk3288_vpu_variant {
52 /* Supported VPU variants. */
53 static const struct rk3288_vpu_variant rk3288_vpu_variants[] = {
59 .dec_reg_num = 60 + 41,
64 * struct rk3288_vpu_codec_ops - codec mode specific operations
66 * @init: Prepare for streaming. Called from VB2 .start_streaming()
67 * when streaming from both queues is being enabled.
68 * @exit: Clean-up after streaming. Called from VB2 .stop_streaming()
69 * when streaming from first of both enabled queues is being
71 * @run: Start single {en,de)coding run. Called from non-atomic context
72 * to indicate that a pair of buffers is ready and the hardware
73 * should be programmed and started.
74 * @done: Read back processing results and additional data from hardware.
75 * @reset: Reset the hardware in case of a timeout.
77 struct rk3288_vpu_codec_ops {
78 int (*init)(struct rk3288_vpu_ctx *);
79 void (*exit)(struct rk3288_vpu_ctx *);
81 void (*run)(struct rk3288_vpu_ctx *);
82 void (*done)(struct rk3288_vpu_ctx *, enum vb2_buffer_state);
83 void (*reset)(struct rk3288_vpu_ctx *);
87 * Hardware control routines.
90 static int rk3288_vpu_identify(struct rk3288_vpu_dev *vpu)
95 hw_id = readl(vpu->base) >> 16;
97 dev_info(vpu->dev, "Read hardware ID: %x\n", hw_id);
99 for (i = 0; i < ARRAY_SIZE(rk3288_vpu_variants); ++i) {
100 if (hw_id == rk3288_vpu_variants[i].hw_id) {
101 vpu->variant = &rk3288_vpu_variants[i];
109 void rk3288_vpu_power_on(struct rk3288_vpu_dev *vpu)
113 /* TODO: Clock gating. */
115 pm_runtime_get_sync(vpu->dev);
120 static void rk3288_vpu_power_off(struct rk3288_vpu_dev *vpu)
124 pm_runtime_mark_last_busy(vpu->dev);
125 pm_runtime_put_autosuspend(vpu->dev);
127 /* TODO: Clock gating. */
133 * Interrupt handlers.
136 static irqreturn_t vepu_irq(int irq, void *dev_id)
138 struct rk3288_vpu_dev *vpu = dev_id;
139 u32 status = vepu_read(vpu, VEPU_REG_INTERRUPT);
141 vepu_write(vpu, 0, VEPU_REG_INTERRUPT);
143 if (status & VEPU_REG_INTERRUPT_BIT) {
144 struct rk3288_vpu_ctx *ctx = vpu->current_ctx;
146 vepu_write(vpu, 0, VEPU_REG_AXI_CTRL);
147 rk3288_vpu_power_off(vpu);
148 cancel_delayed_work(&vpu->watchdog_work);
150 ctx->hw.codec_ops->done(ctx, VB2_BUF_STATE_DONE);
156 static irqreturn_t vdpu_irq(int irq, void *dev_id)
158 struct rk3288_vpu_dev *vpu = dev_id;
159 u32 status = vdpu_read(vpu, VDPU_REG_INTERRUPT);
161 vdpu_write(vpu, 0, VDPU_REG_INTERRUPT);
163 vpu_debug(3, "vdpu_irq status: %08x\n", status);
165 if (status & VDPU_REG_INTERRUPT_DEC_IRQ) {
166 struct rk3288_vpu_ctx *ctx = vpu->current_ctx;
168 vdpu_write(vpu, 0, VDPU_REG_CONFIG);
169 rk3288_vpu_power_off(vpu);
170 cancel_delayed_work(&vpu->watchdog_work);
172 ctx->hw.codec_ops->done(ctx, VB2_BUF_STATE_DONE);
178 static void rk3288_vpu_watchdog(struct work_struct *work)
180 struct rk3288_vpu_dev *vpu = container_of(to_delayed_work(work),
181 struct rk3288_vpu_dev, watchdog_work);
182 struct rk3288_vpu_ctx *ctx = vpu->current_ctx;
185 spin_lock_irqsave(&vpu->irqlock, flags);
187 ctx->hw.codec_ops->reset(ctx);
189 spin_unlock_irqrestore(&vpu->irqlock, flags);
191 vpu_err("frame processing timed out!\n");
193 rk3288_vpu_power_off(vpu);
194 ctx->hw.codec_ops->done(ctx, VB2_BUF_STATE_ERROR);
198 * Initialization/clean-up.
201 #if defined(CONFIG_ROCKCHIP_IOMMU)
202 static int rk3288_vpu_iommu_init(struct rk3288_vpu_dev *vpu)
206 vpu->mapping = arm_iommu_create_mapping(&platform_bus_type,
208 if (IS_ERR(vpu->mapping)) {
209 ret = PTR_ERR(vpu->mapping);
213 vpu->dev->dma_parms = devm_kzalloc(vpu->dev,
214 sizeof(*vpu->dev->dma_parms), GFP_KERNEL);
215 if (!vpu->dev->dma_parms)
216 goto err_release_mapping;
218 dma_set_max_seg_size(vpu->dev, 0xffffffffu);
220 ret = arm_iommu_attach_device(vpu->dev, vpu->mapping);
222 goto err_release_mapping;
227 arm_iommu_release_mapping(vpu->mapping);
232 static void rk3288_vpu_iommu_cleanup(struct rk3288_vpu_dev *vpu)
234 arm_iommu_detach_device(vpu->dev);
235 arm_iommu_release_mapping(vpu->mapping);
238 static inline int rk3288_vpu_iommu_init(struct rk3288_vpu_dev *vpu)
243 static inline void rk3288_vpu_iommu_cleanup(struct rk3288_vpu_dev *vpu) { }
246 int rk3288_vpu_hw_probe(struct rk3288_vpu_dev *vpu)
248 struct resource *res;
249 int irq_enc, irq_dec;
252 pr_info("probe device %s\n", dev_name(vpu->dev));
254 INIT_DELAYED_WORK(&vpu->watchdog_work, rk3288_vpu_watchdog);
256 vpu->aclk_vcodec = devm_clk_get(vpu->dev, "aclk_vcodec");
257 if (IS_ERR(vpu->aclk_vcodec)) {
258 dev_err(vpu->dev, "failed to get aclk_vcodec\n");
259 return PTR_ERR(vpu->aclk_vcodec);
262 vpu->hclk_vcodec = devm_clk_get(vpu->dev, "hclk_vcodec");
263 if (IS_ERR(vpu->hclk_vcodec)) {
264 dev_err(vpu->dev, "failed to get hclk_vcodec\n");
265 return PTR_ERR(vpu->hclk_vcodec);
269 * Bump ACLK to max. possible freq. (400 MHz) to improve performance.
271 * VP8 encoding 1280x720@1.2Mbps 200 MHz: 39 fps, 400: MHz 77 fps
273 clk_set_rate(vpu->aclk_vcodec, 400*1000*1000);
275 res = platform_get_resource(vpu->pdev, IORESOURCE_MEM, 0);
276 vpu->base = devm_ioremap_resource(vpu->dev, res);
277 if (IS_ERR(vpu->base))
278 return PTR_ERR(vpu->base);
280 clk_prepare_enable(vpu->aclk_vcodec);
281 clk_prepare_enable(vpu->hclk_vcodec);
283 ret = rk3288_vpu_identify(vpu);
285 dev_err(vpu->dev, "failed to identify hardware variant\n");
289 vpu->enc_base = vpu->base + vpu->variant->enc_offset;
290 vpu->dec_base = vpu->base + vpu->variant->dec_offset;
292 ret = dma_set_coherent_mask(vpu->dev, DMA_BIT_MASK(32));
294 dev_err(vpu->dev, "could not set DMA coherent mask\n");
298 ret = rk3288_vpu_iommu_init(vpu);
302 irq_enc = platform_get_irq_byname(vpu->pdev, "vepu");
304 dev_err(vpu->dev, "could not get vepu IRQ\n");
309 ret = devm_request_threaded_irq(vpu->dev, irq_enc, NULL, vepu_irq,
310 IRQF_ONESHOT, dev_name(vpu->dev), vpu);
312 dev_err(vpu->dev, "could not request vepu IRQ\n");
316 irq_dec = platform_get_irq_byname(vpu->pdev, "vdpu");
318 dev_err(vpu->dev, "could not get vdpu IRQ\n");
323 ret = devm_request_threaded_irq(vpu->dev, irq_dec, NULL, vdpu_irq,
324 IRQF_ONESHOT, dev_name(vpu->dev), vpu);
326 dev_err(vpu->dev, "could not request vdpu IRQ\n");
330 pm_runtime_set_autosuspend_delay(vpu->dev, 100);
331 pm_runtime_use_autosuspend(vpu->dev);
332 pm_runtime_enable(vpu->dev);
337 rk3288_vpu_iommu_cleanup(vpu);
339 clk_disable_unprepare(vpu->hclk_vcodec);
340 clk_disable_unprepare(vpu->aclk_vcodec);
345 void rk3288_vpu_hw_remove(struct rk3288_vpu_dev *vpu)
347 rk3288_vpu_iommu_cleanup(vpu);
349 pm_runtime_disable(vpu->dev);
351 clk_disable_unprepare(vpu->hclk_vcodec);
352 clk_disable_unprepare(vpu->aclk_vcodec);
355 static void rk3288_vpu_enc_reset(struct rk3288_vpu_ctx *ctx)
357 struct rk3288_vpu_dev *vpu = ctx->dev;
359 vepu_write(vpu, VEPU_REG_INTERRUPT_DIS_BIT, VEPU_REG_INTERRUPT);
360 vepu_write(vpu, 0, VEPU_REG_ENC_CTRL);
361 vepu_write(vpu, 0, VEPU_REG_AXI_CTRL);
364 static void rk3288_vpu_dec_reset(struct rk3288_vpu_ctx *ctx)
366 struct rk3288_vpu_dev *vpu = ctx->dev;
368 vdpu_write(vpu, VDPU_REG_INTERRUPT_DEC_IRQ_DIS, VDPU_REG_INTERRUPT);
369 vdpu_write(vpu, 0, VDPU_REG_CONFIG);
372 static const struct rk3288_vpu_codec_ops mode_ops[] = {
373 [RK_VPU_CODEC_VP8E] = {
374 .init = rk3288_vpu_vp8e_init,
375 .exit = rk3288_vpu_vp8e_exit,
376 .run = rk3288_vpu_vp8e_run,
377 .done = rk3288_vpu_vp8e_done,
378 .reset = rk3288_vpu_enc_reset,
380 [RK_VPU_CODEC_VP8D] = {
381 .init = rk3288_vpu_vp8d_init,
382 .exit = rk3288_vpu_vp8d_exit,
383 .run = rk3288_vpu_vp8d_run,
384 .done = rk3288_vpu_run_done,
385 .reset = rk3288_vpu_dec_reset,
387 [RK_VPU_CODEC_H264D] = {
388 .init = rk3288_vpu_h264d_init,
389 .exit = rk3288_vpu_h264d_exit,
390 .run = rk3288_vpu_h264d_run,
391 .done = rk3288_vpu_run_done,
392 .reset = rk3288_vpu_dec_reset,
396 void rk3288_vpu_run(struct rk3288_vpu_ctx *ctx)
398 ctx->hw.codec_ops->run(ctx);
401 int rk3288_vpu_init(struct rk3288_vpu_ctx *ctx)
403 enum rk3288_vpu_codec_mode codec_mode;
405 if (ctx->vpu_dst_fmt->codec_mode != RK_VPU_CODEC_NONE)
406 codec_mode = ctx->vpu_dst_fmt->codec_mode; /* Encoder */
408 codec_mode = ctx->vpu_src_fmt->codec_mode; /* Decoder */
410 ctx->hw.codec_ops = &mode_ops[codec_mode];
412 return ctx->hw.codec_ops->init(ctx);
415 void rk3288_vpu_deinit(struct rk3288_vpu_ctx *ctx)
417 ctx->hw.codec_ops->exit(ctx);