brintos

brintos / linux-shallow public Read only

0
0
Text · 9.8 KiB · f850d8b Raw
403 lines · c
1// SPDX-License-Identifier: GPL-2.02/*3 * Hantro VPU codec driver4 *5 * Copyright (C) 2019 Pengutronix, Philipp Zabel <kernel@pengutronix.de>6 */7 8#include <linux/clk.h>9#include <linux/delay.h>10 11#include "hantro.h"12#include "hantro_jpeg.h"13#include "hantro_g1_regs.h"14#include "hantro_g2_regs.h"15 16#define CTRL_SOFT_RESET		0x0017#define RESET_G1		BIT(1)18#define RESET_G2		BIT(0)19 20#define CTRL_CLOCK_ENABLE	0x0421#define CLOCK_G1		BIT(1)22#define CLOCK_G2		BIT(0)23 24#define CTRL_G1_DEC_FUSE	0x0825#define CTRL_G1_PP_FUSE		0x0c26#define CTRL_G2_DEC_FUSE	0x1027 28static void imx8m_soft_reset(struct hantro_dev *vpu, u32 reset_bits)29{30	u32 val;31 32	/* Assert */33	val = readl(vpu->ctrl_base + CTRL_SOFT_RESET);34	val &= ~reset_bits;35	writel(val, vpu->ctrl_base + CTRL_SOFT_RESET);36 37	udelay(2);38 39	/* Release */40	val = readl(vpu->ctrl_base + CTRL_SOFT_RESET);41	val |= reset_bits;42	writel(val, vpu->ctrl_base + CTRL_SOFT_RESET);43}44 45static void imx8m_clk_enable(struct hantro_dev *vpu, u32 clock_bits)46{47	u32 val;48 49	val = readl(vpu->ctrl_base + CTRL_CLOCK_ENABLE);50	val |= clock_bits;51	writel(val, vpu->ctrl_base + CTRL_CLOCK_ENABLE);52}53 54static int imx8mq_runtime_resume(struct hantro_dev *vpu)55{56	int ret;57 58	ret = clk_bulk_prepare_enable(vpu->variant->num_clocks, vpu->clocks);59	if (ret) {60		dev_err(vpu->dev, "Failed to enable clocks\n");61		return ret;62	}63 64	imx8m_soft_reset(vpu, RESET_G1 | RESET_G2);65	imx8m_clk_enable(vpu, CLOCK_G1 | CLOCK_G2);66 67	/* Set values of the fuse registers */68	writel(0xffffffff, vpu->ctrl_base + CTRL_G1_DEC_FUSE);69	writel(0xffffffff, vpu->ctrl_base + CTRL_G1_PP_FUSE);70	writel(0xffffffff, vpu->ctrl_base + CTRL_G2_DEC_FUSE);71 72	clk_bulk_disable_unprepare(vpu->variant->num_clocks, vpu->clocks);73 74	return 0;75}76 77/*78 * Supported formats.79 */80 81static const struct hantro_fmt imx8m_vpu_postproc_fmts[] = {82	{83		.fourcc = V4L2_PIX_FMT_YUYV,84		.codec_mode = HANTRO_MODE_NONE,85		.postprocessed = true,86		.frmsize = {87			.min_width = FMT_MIN_WIDTH,88			.max_width = FMT_UHD_WIDTH,89			.step_width = MB_DIM,90			.min_height = FMT_MIN_HEIGHT,91			.max_height = FMT_UHD_HEIGHT,92			.step_height = MB_DIM,93		},94	},95};96 97static const struct hantro_fmt imx8m_vpu_dec_fmts[] = {98	{99		.fourcc = V4L2_PIX_FMT_NV12,100		.codec_mode = HANTRO_MODE_NONE,101		.frmsize = {102			.min_width = FMT_MIN_WIDTH,103			.max_width = FMT_UHD_WIDTH,104			.step_width = MB_DIM,105			.min_height = FMT_MIN_HEIGHT,106			.max_height = FMT_UHD_HEIGHT,107			.step_height = MB_DIM,108		},109	},110	{111		.fourcc = V4L2_PIX_FMT_MPEG2_SLICE,112		.codec_mode = HANTRO_MODE_MPEG2_DEC,113		.max_depth = 2,114		.frmsize = {115			.min_width = FMT_MIN_WIDTH,116			.max_width = FMT_FHD_WIDTH,117			.step_width = MB_DIM,118			.min_height = FMT_MIN_HEIGHT,119			.max_height = FMT_FHD_HEIGHT,120			.step_height = MB_DIM,121		},122	},123	{124		.fourcc = V4L2_PIX_FMT_VP8_FRAME,125		.codec_mode = HANTRO_MODE_VP8_DEC,126		.max_depth = 2,127		.frmsize = {128			.min_width = FMT_MIN_WIDTH,129			.max_width = FMT_UHD_WIDTH,130			.step_width = MB_DIM,131			.min_height = FMT_MIN_HEIGHT,132			.max_height = FMT_UHD_HEIGHT,133			.step_height = MB_DIM,134		},135	},136	{137		.fourcc = V4L2_PIX_FMT_H264_SLICE,138		.codec_mode = HANTRO_MODE_H264_DEC,139		.max_depth = 2,140		.frmsize = {141			.min_width = FMT_MIN_WIDTH,142			.max_width = FMT_UHD_WIDTH,143			.step_width = MB_DIM,144			.min_height = FMT_MIN_HEIGHT,145			.max_height = FMT_UHD_HEIGHT,146			.step_height = MB_DIM,147		},148	},149};150 151static const struct hantro_fmt imx8m_vpu_g2_postproc_fmts[] = {152	{153		.fourcc = V4L2_PIX_FMT_NV12,154		.codec_mode = HANTRO_MODE_NONE,155		.match_depth = true,156		.postprocessed = true,157		.frmsize = {158			.min_width = FMT_MIN_WIDTH,159			.max_width = FMT_UHD_WIDTH,160			.step_width = MB_DIM,161			.min_height = FMT_MIN_HEIGHT,162			.max_height = FMT_UHD_HEIGHT,163			.step_height = MB_DIM,164		},165	},166	{167		.fourcc = V4L2_PIX_FMT_P010,168		.codec_mode = HANTRO_MODE_NONE,169		.match_depth = true,170		.postprocessed = true,171		.frmsize = {172			.min_width = FMT_MIN_WIDTH,173			.max_width = FMT_UHD_WIDTH,174			.step_width = MB_DIM,175			.min_height = FMT_MIN_HEIGHT,176			.max_height = FMT_UHD_HEIGHT,177			.step_height = MB_DIM,178		},179	},180};181 182static const struct hantro_fmt imx8m_vpu_g2_dec_fmts[] = {183	{184		.fourcc = V4L2_PIX_FMT_NV12_4L4,185		.codec_mode = HANTRO_MODE_NONE,186		.match_depth = true,187		.frmsize = {188			.min_width = FMT_MIN_WIDTH,189			.max_width = FMT_UHD_WIDTH,190			.step_width = TILE_MB_DIM,191			.min_height = FMT_MIN_HEIGHT,192			.max_height = FMT_UHD_HEIGHT,193			.step_height = TILE_MB_DIM,194		},195	},196	{197		.fourcc = V4L2_PIX_FMT_P010_4L4,198		.codec_mode = HANTRO_MODE_NONE,199		.match_depth = true,200		.frmsize = {201			.min_width = FMT_MIN_WIDTH,202			.max_width = FMT_UHD_WIDTH,203			.step_width = TILE_MB_DIM,204			.min_height = FMT_MIN_HEIGHT,205			.max_height = FMT_UHD_HEIGHT,206			.step_height = TILE_MB_DIM,207		},208	},209	{210		.fourcc = V4L2_PIX_FMT_HEVC_SLICE,211		.codec_mode = HANTRO_MODE_HEVC_DEC,212		.max_depth = 2,213		.frmsize = {214			.min_width = FMT_MIN_WIDTH,215			.max_width = FMT_UHD_WIDTH,216			.step_width = TILE_MB_DIM,217			.min_height = FMT_MIN_HEIGHT,218			.max_height = FMT_UHD_HEIGHT,219			.step_height = TILE_MB_DIM,220		},221	},222	{223		.fourcc = V4L2_PIX_FMT_VP9_FRAME,224		.codec_mode = HANTRO_MODE_VP9_DEC,225		.max_depth = 2,226		.frmsize = {227			.min_width = FMT_MIN_WIDTH,228			.max_width = FMT_UHD_WIDTH,229			.step_width = TILE_MB_DIM,230			.min_height = FMT_MIN_HEIGHT,231			.max_height = FMT_UHD_HEIGHT,232			.step_height = TILE_MB_DIM,233		},234	},235};236 237static irqreturn_t imx8m_vpu_g1_irq(int irq, void *dev_id)238{239	struct hantro_dev *vpu = dev_id;240	enum vb2_buffer_state state;241	u32 status;242 243	status = vdpu_read(vpu, G1_REG_INTERRUPT);244	state = (status & G1_REG_INTERRUPT_DEC_RDY_INT) ?245		 VB2_BUF_STATE_DONE : VB2_BUF_STATE_ERROR;246 247	vdpu_write(vpu, 0, G1_REG_INTERRUPT);248	vdpu_write(vpu, G1_REG_CONFIG_DEC_CLK_GATE_E, G1_REG_CONFIG);249 250	hantro_irq_done(vpu, state);251 252	return IRQ_HANDLED;253}254 255static int imx8mq_vpu_hw_init(struct hantro_dev *vpu)256{257	vpu->ctrl_base = vpu->reg_bases[vpu->variant->num_regs - 1];258 259	return 0;260}261 262static void imx8m_vpu_g1_reset(struct hantro_ctx *ctx)263{264	struct hantro_dev *vpu = ctx->dev;265 266	imx8m_soft_reset(vpu, RESET_G1);267}268 269/*270 * Supported codec ops.271 */272 273static const struct hantro_codec_ops imx8mq_vpu_codec_ops[] = {274	[HANTRO_MODE_MPEG2_DEC] = {275		.run = hantro_g1_mpeg2_dec_run,276		.reset = imx8m_vpu_g1_reset,277		.init = hantro_mpeg2_dec_init,278		.exit = hantro_mpeg2_dec_exit,279	},280	[HANTRO_MODE_VP8_DEC] = {281		.run = hantro_g1_vp8_dec_run,282		.reset = imx8m_vpu_g1_reset,283		.init = hantro_vp8_dec_init,284		.exit = hantro_vp8_dec_exit,285	},286	[HANTRO_MODE_H264_DEC] = {287		.run = hantro_g1_h264_dec_run,288		.reset = imx8m_vpu_g1_reset,289		.init = hantro_h264_dec_init,290		.exit = hantro_h264_dec_exit,291	},292};293 294static const struct hantro_codec_ops imx8mq_vpu_g1_codec_ops[] = {295	[HANTRO_MODE_MPEG2_DEC] = {296		.run = hantro_g1_mpeg2_dec_run,297		.init = hantro_mpeg2_dec_init,298		.exit = hantro_mpeg2_dec_exit,299	},300	[HANTRO_MODE_VP8_DEC] = {301		.run = hantro_g1_vp8_dec_run,302		.init = hantro_vp8_dec_init,303		.exit = hantro_vp8_dec_exit,304	},305	[HANTRO_MODE_H264_DEC] = {306		.run = hantro_g1_h264_dec_run,307		.init = hantro_h264_dec_init,308		.exit = hantro_h264_dec_exit,309	},310};311 312static const struct hantro_codec_ops imx8mq_vpu_g2_codec_ops[] = {313	[HANTRO_MODE_HEVC_DEC] = {314		.run = hantro_g2_hevc_dec_run,315		.init = hantro_hevc_dec_init,316		.exit = hantro_hevc_dec_exit,317	},318	[HANTRO_MODE_VP9_DEC] = {319		.run = hantro_g2_vp9_dec_run,320		.done = hantro_g2_vp9_dec_done,321		.init = hantro_vp9_dec_init,322		.exit = hantro_vp9_dec_exit,323	},324};325 326/*327 * VPU variants.328 */329 330static const struct hantro_irq imx8mq_irqs[] = {331	{ "g1", imx8m_vpu_g1_irq },332};333 334static const struct hantro_irq imx8mq_g2_irqs[] = {335	{ "g2", hantro_g2_irq },336};337 338static const char * const imx8mq_clk_names[] = { "g1", "g2", "bus" };339static const char * const imx8mq_reg_names[] = { "g1", "g2", "ctrl" };340static const char * const imx8mq_g1_clk_names[] = { "g1" };341static const char * const imx8mq_g2_clk_names[] = { "g2" };342 343const struct hantro_variant imx8mq_vpu_variant = {344	.dec_fmts = imx8m_vpu_dec_fmts,345	.num_dec_fmts = ARRAY_SIZE(imx8m_vpu_dec_fmts),346	.postproc_fmts = imx8m_vpu_postproc_fmts,347	.num_postproc_fmts = ARRAY_SIZE(imx8m_vpu_postproc_fmts),348	.postproc_ops = &hantro_g1_postproc_ops,349	.codec = HANTRO_MPEG2_DECODER | HANTRO_VP8_DECODER |350		 HANTRO_H264_DECODER,351	.codec_ops = imx8mq_vpu_codec_ops,352	.init = imx8mq_vpu_hw_init,353	.runtime_resume = imx8mq_runtime_resume,354	.irqs = imx8mq_irqs,355	.num_irqs = ARRAY_SIZE(imx8mq_irqs),356	.clk_names = imx8mq_clk_names,357	.num_clocks = ARRAY_SIZE(imx8mq_clk_names),358	.reg_names = imx8mq_reg_names,359	.num_regs = ARRAY_SIZE(imx8mq_reg_names)360};361 362const struct hantro_variant imx8mq_vpu_g1_variant = {363	.dec_fmts = imx8m_vpu_dec_fmts,364	.num_dec_fmts = ARRAY_SIZE(imx8m_vpu_dec_fmts),365	.postproc_fmts = imx8m_vpu_postproc_fmts,366	.num_postproc_fmts = ARRAY_SIZE(imx8m_vpu_postproc_fmts),367	.postproc_ops = &hantro_g1_postproc_ops,368	.codec = HANTRO_MPEG2_DECODER | HANTRO_VP8_DECODER |369		 HANTRO_H264_DECODER,370	.codec_ops = imx8mq_vpu_g1_codec_ops,371	.irqs = imx8mq_irqs,372	.num_irqs = ARRAY_SIZE(imx8mq_irqs),373	.clk_names = imx8mq_g1_clk_names,374	.num_clocks = ARRAY_SIZE(imx8mq_g1_clk_names),375};376 377const struct hantro_variant imx8mq_vpu_g2_variant = {378	.dec_offset = 0x0,379	.dec_fmts = imx8m_vpu_g2_dec_fmts,380	.num_dec_fmts = ARRAY_SIZE(imx8m_vpu_g2_dec_fmts),381	.postproc_fmts = imx8m_vpu_g2_postproc_fmts,382	.num_postproc_fmts = ARRAY_SIZE(imx8m_vpu_g2_postproc_fmts),383	.postproc_ops = &hantro_g2_postproc_ops,384	.codec = HANTRO_HEVC_DECODER | HANTRO_VP9_DECODER,385	.codec_ops = imx8mq_vpu_g2_codec_ops,386	.irqs = imx8mq_g2_irqs,387	.num_irqs = ARRAY_SIZE(imx8mq_g2_irqs),388	.clk_names = imx8mq_g2_clk_names,389	.num_clocks = ARRAY_SIZE(imx8mq_g2_clk_names),390};391 392const struct hantro_variant imx8mm_vpu_g1_variant = {393	.dec_fmts = imx8m_vpu_dec_fmts,394	.num_dec_fmts = ARRAY_SIZE(imx8m_vpu_dec_fmts),395	.codec = HANTRO_MPEG2_DECODER | HANTRO_VP8_DECODER |396		 HANTRO_H264_DECODER,397	.codec_ops = imx8mq_vpu_g1_codec_ops,398	.irqs = imx8mq_irqs,399	.num_irqs = ARRAY_SIZE(imx8mq_irqs),400	.clk_names = imx8mq_g1_clk_names,401	.num_clocks = ARRAY_SIZE(imx8mq_g1_clk_names),402};403