brintos

brintos / linux-shallow public Read only

0
0
Text · 17.9 KiB · 4a6ee21 Raw
662 lines · c
1// SPDX-License-Identifier: GPL-2.0-only2/*3 * Copyright (c) 2016 MediaTek Inc.4 * Author: Ming Hsiu Tsai <minghsiu.tsai@mediatek.com>5 *         Rick Chang <rick.chang@mediatek.com>6 */7 8#include <linux/clk.h>9#include <linux/interrupt.h>10#include <linux/irq.h>11#include <linux/io.h>12#include <linux/kernel.h>13#include <linux/module.h>14#include <linux/of.h>15#include <linux/platform_device.h>16#include <linux/pm_runtime.h>17#include <linux/slab.h>18#include <media/media-device.h>19#include <media/videobuf2-core.h>20#include <media/videobuf2-v4l2.h>21#include <media/v4l2-mem2mem.h>22#include <media/v4l2-dev.h>23#include <media/v4l2-device.h>24#include <media/v4l2-fh.h>25#include <media/v4l2-event.h>26 27#include "mtk_jpeg_core.h"28#include "mtk_jpeg_dec_hw.h"29 30#define MTK_JPEG_DUNUM_MASK(val)	(((val) - 1) & 0x3)31 32enum mtk_jpeg_color {33	MTK_JPEG_COLOR_420		= 0x00221111,34	MTK_JPEG_COLOR_422		= 0x00211111,35	MTK_JPEG_COLOR_444		= 0x00111111,36	MTK_JPEG_COLOR_422V		= 0x00121111,37	MTK_JPEG_COLOR_422X2		= 0x00412121,38	MTK_JPEG_COLOR_422VX2		= 0x00222121,39	MTK_JPEG_COLOR_400		= 0x0011000040};41 42static const struct of_device_id mtk_jpegdec_hw_ids[] = {43	{44		.compatible = "mediatek,mt8195-jpgdec-hw",45	},46	{},47};48MODULE_DEVICE_TABLE(of, mtk_jpegdec_hw_ids);49 50static inline int mtk_jpeg_verify_align(u32 val, int align, u32 reg)51{52	if (val & (align - 1)) {53		pr_err("mtk-jpeg: write reg %x without %d align\n", reg, align);54		return -1;55	}56 57	return 0;58}59 60static int mtk_jpeg_decide_format(struct mtk_jpeg_dec_param *param)61{62	param->src_color = (param->sampling_w[0] << 20) |63			   (param->sampling_h[0] << 16) |64			   (param->sampling_w[1] << 12) |65			   (param->sampling_h[1] << 8) |66			   (param->sampling_w[2] << 4) |67			   (param->sampling_h[2]);68 69	param->uv_brz_w = 0;70	switch (param->src_color) {71	case MTK_JPEG_COLOR_444:72		param->uv_brz_w = 1;73		param->dst_fourcc = V4L2_PIX_FMT_YUV422M;74		break;75	case MTK_JPEG_COLOR_422X2:76	case MTK_JPEG_COLOR_422:77		param->dst_fourcc = V4L2_PIX_FMT_YUV422M;78		break;79	case MTK_JPEG_COLOR_422V:80	case MTK_JPEG_COLOR_422VX2:81		param->uv_brz_w = 1;82		param->dst_fourcc = V4L2_PIX_FMT_YUV420M;83		break;84	case MTK_JPEG_COLOR_420:85		param->dst_fourcc = V4L2_PIX_FMT_YUV420M;86		break;87	case MTK_JPEG_COLOR_400:88		param->dst_fourcc = V4L2_PIX_FMT_GREY;89		break;90	default:91		param->dst_fourcc = 0;92		return -1;93	}94 95	return 0;96}97 98static void mtk_jpeg_calc_mcu(struct mtk_jpeg_dec_param *param)99{100	u32 factor_w, factor_h;101	u32 i, comp, blk;102 103	factor_w = 2 + param->sampling_w[0];104	factor_h = 2 + param->sampling_h[0];105	param->mcu_w = (param->pic_w + (1 << factor_w) - 1) >> factor_w;106	param->mcu_h = (param->pic_h + (1 << factor_h) - 1) >> factor_h;107	param->total_mcu = param->mcu_w * param->mcu_h;108	param->unit_num = ((param->pic_w + 7) >> 3) * ((param->pic_h + 7) >> 3);109	param->blk_num = 0;110	for (i = 0; i < MTK_JPEG_COMP_MAX; i++) {111		param->blk_comp[i] = 0;112		if (i >= param->comp_num)113			continue;114		param->blk_comp[i] = param->sampling_w[i] *115				     param->sampling_h[i];116		param->blk_num += param->blk_comp[i];117	}118 119	param->membership = 0;120	for (i = 0, blk = 0, comp = 0; i < MTK_JPEG_BLOCK_MAX; i++) {121		if (i < param->blk_num && comp < param->comp_num) {122			u32 tmp;123 124			tmp = (0x04 + (comp & 0x3));125			param->membership |= tmp << (i * 3);126			if (++blk == param->blk_comp[comp]) {127				comp++;128				blk = 0;129			}130		} else {131			param->membership |=  7 << (i * 3);132		}133	}134}135 136static void mtk_jpeg_calc_dma_group(struct mtk_jpeg_dec_param *param)137{138	u32 factor_mcu = 3;139 140	if (param->src_color == MTK_JPEG_COLOR_444 &&141	    param->dst_fourcc == V4L2_PIX_FMT_YUV422M)142		factor_mcu = 4;143	else if (param->src_color == MTK_JPEG_COLOR_422V &&144		 param->dst_fourcc == V4L2_PIX_FMT_YUV420M)145		factor_mcu = 4;146	else if (param->src_color == MTK_JPEG_COLOR_422X2 &&147		 param->dst_fourcc == V4L2_PIX_FMT_YUV422M)148		factor_mcu = 2;149	else if (param->src_color == MTK_JPEG_COLOR_400 ||150		 (param->src_color & 0x0FFFF) == 0)151		factor_mcu = 4;152 153	param->dma_mcu = 1 << factor_mcu;154	param->dma_group = param->mcu_w / param->dma_mcu;155	param->dma_last_mcu = param->mcu_w % param->dma_mcu;156	if (param->dma_last_mcu)157		param->dma_group++;158	else159		param->dma_last_mcu = param->dma_mcu;160}161 162static int mtk_jpeg_calc_dst_size(struct mtk_jpeg_dec_param *param)163{164	u32 i, padding_w;165	u32 ds_row_h[3];166	u32 brz_w[3];167 168	brz_w[0] = 0;169	brz_w[1] = param->uv_brz_w;170	brz_w[2] = brz_w[1];171 172	for (i = 0; i < param->comp_num; i++) {173		if (brz_w[i] > 3)174			return -1;175 176		padding_w = param->mcu_w * MTK_JPEG_DCTSIZE *177				param->sampling_w[i];178		/* output format is 420/422 */179		param->comp_w[i] = padding_w >> brz_w[i];180		param->comp_w[i] = round_up(param->comp_w[i],181					    MTK_JPEG_DCTSIZE);182		param->img_stride[i] = i ? round_up(param->comp_w[i], 16)183					: round_up(param->comp_w[i], 32);184		ds_row_h[i] = (MTK_JPEG_DCTSIZE * param->sampling_h[i]);185	}186	param->dec_w = param->img_stride[0];187	param->dec_h = ds_row_h[0] * param->mcu_h;188 189	for (i = 0; i < MTK_JPEG_COMP_MAX; i++) {190		/* They must be equal in frame mode. */191		param->mem_stride[i] = param->img_stride[i];192		param->comp_size[i] = param->mem_stride[i] * ds_row_h[i] *193				      param->mcu_h;194	}195 196	param->y_size = param->comp_size[0];197	param->uv_size = param->comp_size[1];198	param->dec_size = param->y_size + (param->uv_size << 1);199 200	return 0;201}202 203int mtk_jpeg_dec_fill_param(struct mtk_jpeg_dec_param *param)204{205	if (mtk_jpeg_decide_format(param))206		return -1;207 208	mtk_jpeg_calc_mcu(param);209	mtk_jpeg_calc_dma_group(param);210	if (mtk_jpeg_calc_dst_size(param))211		return -2;212 213	return 0;214}215EXPORT_SYMBOL_GPL(mtk_jpeg_dec_fill_param);216 217u32 mtk_jpeg_dec_get_int_status(void __iomem *base)218{219	u32 ret;220 221	ret = readl(base + JPGDEC_REG_INTERRUPT_STATUS) & BIT_INQST_MASK_ALLIRQ;222	if (ret)223		writel(ret, base + JPGDEC_REG_INTERRUPT_STATUS);224 225	return ret;226}227EXPORT_SYMBOL_GPL(mtk_jpeg_dec_get_int_status);228 229u32 mtk_jpeg_dec_enum_result(u32 irq_result)230{231	if (irq_result & BIT_INQST_MASK_EOF)232		return MTK_JPEG_DEC_RESULT_EOF_DONE;233	if (irq_result & BIT_INQST_MASK_PAUSE)234		return MTK_JPEG_DEC_RESULT_PAUSE;235	if (irq_result & BIT_INQST_MASK_UNDERFLOW)236		return MTK_JPEG_DEC_RESULT_UNDERFLOW;237	if (irq_result & BIT_INQST_MASK_OVERFLOW)238		return MTK_JPEG_DEC_RESULT_OVERFLOW;239	if (irq_result & BIT_INQST_MASK_ERROR_BS)240		return MTK_JPEG_DEC_RESULT_ERROR_BS;241 242	return MTK_JPEG_DEC_RESULT_ERROR_UNKNOWN;243}244EXPORT_SYMBOL_GPL(mtk_jpeg_dec_enum_result);245 246void mtk_jpeg_dec_start(void __iomem *base)247{248	writel(0, base + JPGDEC_REG_TRIG);249}250EXPORT_SYMBOL_GPL(mtk_jpeg_dec_start);251 252static void mtk_jpeg_dec_soft_reset(void __iomem *base)253{254	writel(0x0000FFFF, base + JPGDEC_REG_INTERRUPT_STATUS);255	writel(0x00, base + JPGDEC_REG_RESET);256	writel(0x01, base + JPGDEC_REG_RESET);257}258 259static void mtk_jpeg_dec_hard_reset(void __iomem *base)260{261	writel(0x00, base + JPGDEC_REG_RESET);262	writel(0x10, base + JPGDEC_REG_RESET);263}264 265void mtk_jpeg_dec_reset(void __iomem *base)266{267	mtk_jpeg_dec_soft_reset(base);268	mtk_jpeg_dec_hard_reset(base);269}270EXPORT_SYMBOL_GPL(mtk_jpeg_dec_reset);271 272static void mtk_jpeg_dec_set_brz_factor(void __iomem *base, u8 yscale_w,273					u8 yscale_h, u8 uvscale_w, u8 uvscale_h)274{275	u32 val;276 277	val = (uvscale_h << 12) | (uvscale_w << 8) |278	      (yscale_h << 4) | yscale_w;279	writel(val, base + JPGDEC_REG_BRZ_FACTOR);280}281 282static void mtk_jpeg_dec_set_dst_bank0(void __iomem *base, u32 addr_y,283				       u32 addr_u, u32 addr_v)284{285	mtk_jpeg_verify_align(addr_y, 16, JPGDEC_REG_DEST_ADDR0_Y);286	writel(addr_y, base + JPGDEC_REG_DEST_ADDR0_Y);287	mtk_jpeg_verify_align(addr_u, 16, JPGDEC_REG_DEST_ADDR0_U);288	writel(addr_u, base + JPGDEC_REG_DEST_ADDR0_U);289	mtk_jpeg_verify_align(addr_v, 16, JPGDEC_REG_DEST_ADDR0_V);290	writel(addr_v, base + JPGDEC_REG_DEST_ADDR0_V);291}292 293static void mtk_jpeg_dec_set_dst_bank1(void __iomem *base, u32 addr_y,294				       u32 addr_u, u32 addr_v)295{296	writel(addr_y, base + JPGDEC_REG_DEST_ADDR1_Y);297	writel(addr_u, base + JPGDEC_REG_DEST_ADDR1_U);298	writel(addr_v, base + JPGDEC_REG_DEST_ADDR1_V);299}300 301static void mtk_jpeg_dec_set_mem_stride(void __iomem *base, u32 stride_y,302					u32 stride_uv)303{304	writel((stride_y & 0xFFFF), base + JPGDEC_REG_STRIDE_Y);305	writel((stride_uv & 0xFFFF), base + JPGDEC_REG_STRIDE_UV);306}307 308static void mtk_jpeg_dec_set_img_stride(void __iomem *base, u32 stride_y,309					u32 stride_uv)310{311	writel((stride_y & 0xFFFF), base + JPGDEC_REG_IMG_STRIDE_Y);312	writel((stride_uv & 0xFFFF), base + JPGDEC_REG_IMG_STRIDE_UV);313}314 315static void mtk_jpeg_dec_set_pause_mcu_idx(void __iomem *base, u32 idx)316{317	writel(idx & 0x0003FFFFFF, base + JPGDEC_REG_PAUSE_MCU_NUM);318}319 320static void mtk_jpeg_dec_set_dec_mode(void __iomem *base, u32 mode)321{322	writel(mode & 0x03, base + JPGDEC_REG_OPERATION_MODE);323}324 325static void mtk_jpeg_dec_set_bs_write_ptr(void __iomem *base, u32 ptr)326{327	mtk_jpeg_verify_align(ptr, 16, JPGDEC_REG_FILE_BRP);328	writel(ptr, base + JPGDEC_REG_FILE_BRP);329}330 331static void mtk_jpeg_dec_set_bs_info(void __iomem *base, u32 addr, u32 size,332				     u32 bitstream_size)333{334	mtk_jpeg_verify_align(addr, 16, JPGDEC_REG_FILE_ADDR);335	mtk_jpeg_verify_align(size, 128, JPGDEC_REG_FILE_TOTAL_SIZE);336	writel(addr, base + JPGDEC_REG_FILE_ADDR);337	writel(size, base + JPGDEC_REG_FILE_TOTAL_SIZE);338	writel(bitstream_size, base + JPGDEC_REG_BIT_STREAM_SIZE);339}340 341static void mtk_jpeg_dec_set_comp_id(void __iomem *base, u32 id_y, u32 id_u,342				     u32 id_v)343{344	u32 val;345 346	val = ((id_y & 0x00FF) << 24) | ((id_u & 0x00FF) << 16) |347	      ((id_v & 0x00FF) << 8);348	writel(val, base + JPGDEC_REG_COMP_ID);349}350 351static void mtk_jpeg_dec_set_total_mcu(void __iomem *base, u32 num)352{353	writel(num - 1, base + JPGDEC_REG_TOTAL_MCU_NUM);354}355 356static void mtk_jpeg_dec_set_comp0_du(void __iomem *base, u32 num)357{358	writel(num - 1, base + JPGDEC_REG_COMP0_DATA_UNIT_NUM);359}360 361static void mtk_jpeg_dec_set_du_membership(void __iomem *base, u32 member,362					   u32 gmc, u32 isgray)363{364	if (isgray)365		member = 0x3FFFFFFC;366	member |= (isgray << 31) | (gmc << 30);367	writel(member, base + JPGDEC_REG_DU_CTRL);368}369 370static void mtk_jpeg_dec_set_q_table(void __iomem *base, u32 id0, u32 id1,371				     u32 id2)372{373	u32 val;374 375	val = ((id0 & 0x0f) << 8) | ((id1 & 0x0f) << 4) | ((id2 & 0x0f) << 0);376	writel(val, base + JPGDEC_REG_QT_ID);377}378 379static void mtk_jpeg_dec_set_dma_group(void __iomem *base, u32 mcu_group,380				       u32 group_num, u32 last_mcu)381{382	u32 val;383 384	val = (((mcu_group - 1) & 0x00FF) << 16) |385	      (((group_num - 1) & 0x007F) << 8) |386	      ((last_mcu - 1) & 0x00FF);387	writel(val, base + JPGDEC_REG_WDMA_CTRL);388}389 390static void mtk_jpeg_dec_set_sampling_factor(void __iomem *base, u32 comp_num,391					     u32 y_w, u32 y_h, u32 u_w,392					     u32 u_h, u32 v_w, u32 v_h)393{394	u32 val;395	u32 y_wh = (MTK_JPEG_DUNUM_MASK(y_w) << 2) | MTK_JPEG_DUNUM_MASK(y_h);396	u32 u_wh = (MTK_JPEG_DUNUM_MASK(u_w) << 2) | MTK_JPEG_DUNUM_MASK(u_h);397	u32 v_wh = (MTK_JPEG_DUNUM_MASK(v_w) << 2) | MTK_JPEG_DUNUM_MASK(v_h);398 399	if (comp_num == 1)400		val = 0;401	else402		val = (y_wh << 8) | (u_wh << 4) | v_wh;403	writel(val, base + JPGDEC_REG_DU_NUM);404}405 406void mtk_jpeg_dec_set_config(void __iomem *base,407			     struct mtk_jpeg_dec_param *cfg,408			     u32 bitstream_size,409			     struct mtk_jpeg_bs *bs,410			     struct mtk_jpeg_fb *fb)411{412	mtk_jpeg_dec_set_brz_factor(base, 0, 0, cfg->uv_brz_w, 0);413	mtk_jpeg_dec_set_dec_mode(base, 0);414	mtk_jpeg_dec_set_comp0_du(base, cfg->unit_num);415	mtk_jpeg_dec_set_total_mcu(base, cfg->total_mcu);416	mtk_jpeg_dec_set_bs_info(base, bs->str_addr, bs->size, bitstream_size);417	mtk_jpeg_dec_set_bs_write_ptr(base, bs->end_addr);418	mtk_jpeg_dec_set_du_membership(base, cfg->membership, 1,419				       (cfg->comp_num == 1) ? 1 : 0);420	mtk_jpeg_dec_set_comp_id(base, cfg->comp_id[0], cfg->comp_id[1],421				 cfg->comp_id[2]);422	mtk_jpeg_dec_set_q_table(base, cfg->qtbl_num[0],423				 cfg->qtbl_num[1], cfg->qtbl_num[2]);424	mtk_jpeg_dec_set_sampling_factor(base, cfg->comp_num,425					 cfg->sampling_w[0],426					 cfg->sampling_h[0],427					 cfg->sampling_w[1],428					 cfg->sampling_h[1],429					 cfg->sampling_w[2],430					 cfg->sampling_h[2]);431	mtk_jpeg_dec_set_mem_stride(base, cfg->mem_stride[0],432				    cfg->mem_stride[1]);433	mtk_jpeg_dec_set_img_stride(base, cfg->img_stride[0],434				    cfg->img_stride[1]);435	mtk_jpeg_dec_set_dst_bank0(base, fb->plane_addr[0],436				   fb->plane_addr[1], fb->plane_addr[2]);437	mtk_jpeg_dec_set_dst_bank1(base, 0, 0, 0);438	mtk_jpeg_dec_set_dma_group(base, cfg->dma_mcu, cfg->dma_group,439				   cfg->dma_last_mcu);440	mtk_jpeg_dec_set_pause_mcu_idx(base, cfg->total_mcu);441}442EXPORT_SYMBOL_GPL(mtk_jpeg_dec_set_config);443 444static void mtk_jpegdec_put_buf(struct mtk_jpegdec_comp_dev *jpeg)445{446	struct mtk_jpeg_src_buf *dst_done_buf, *tmp_dst_done_buf;447	struct vb2_v4l2_buffer *dst_buffer;448	struct list_head *temp_entry;449	struct list_head *pos = NULL;450	struct mtk_jpeg_ctx *ctx;451	unsigned long flags;452 453	ctx = jpeg->hw_param.curr_ctx;454	if (unlikely(!ctx)) {455		dev_err(jpeg->dev, "comp_jpeg ctx fail !!!\n");456		return;457	}458 459	dst_buffer = jpeg->hw_param.dst_buffer;460	if (!dst_buffer) {461		dev_err(jpeg->dev, "comp_jpeg dst_buffer fail !!!\n");462		return;463	}464 465	dst_done_buf = container_of(dst_buffer, struct mtk_jpeg_src_buf, b);466 467	spin_lock_irqsave(&ctx->done_queue_lock, flags);468	list_add_tail(&dst_done_buf->list, &ctx->dst_done_queue);469	while (!list_empty(&ctx->dst_done_queue) &&470	       (pos != &ctx->dst_done_queue)) {471		list_for_each_prev_safe(pos, temp_entry, &ctx->dst_done_queue) {472			tmp_dst_done_buf = list_entry(pos,473						      struct mtk_jpeg_src_buf,474						      list);475			if (tmp_dst_done_buf->frame_num ==476				ctx->last_done_frame_num) {477				list_del(&tmp_dst_done_buf->list);478				v4l2_m2m_buf_done(&tmp_dst_done_buf->b,479						  VB2_BUF_STATE_DONE);480				ctx->last_done_frame_num++;481			}482		}483	}484	spin_unlock_irqrestore(&ctx->done_queue_lock, flags);485}486 487static void mtk_jpegdec_timeout_work(struct work_struct *work)488{489	enum vb2_buffer_state buf_state = VB2_BUF_STATE_ERROR;490	struct mtk_jpegdec_comp_dev *cjpeg =491		container_of(work, struct mtk_jpegdec_comp_dev,492			     job_timeout_work.work);493	struct mtk_jpeg_dev *master_jpeg = cjpeg->master_dev;494	struct vb2_v4l2_buffer *src_buf, *dst_buf;495 496	src_buf = cjpeg->hw_param.src_buffer;497	dst_buf = cjpeg->hw_param.dst_buffer;498	v4l2_m2m_buf_copy_metadata(src_buf, dst_buf, true);499 500	mtk_jpeg_dec_reset(cjpeg->reg_base);501	clk_disable_unprepare(cjpeg->jdec_clk.clks->clk);502	pm_runtime_put(cjpeg->dev);503	cjpeg->hw_state = MTK_JPEG_HW_IDLE;504	atomic_inc(&master_jpeg->hw_rdy);505	wake_up(&master_jpeg->hw_wq);506	v4l2_m2m_buf_done(src_buf, buf_state);507	mtk_jpegdec_put_buf(cjpeg);508}509 510static irqreturn_t mtk_jpegdec_hw_irq_handler(int irq, void *priv)511{512	struct vb2_v4l2_buffer *src_buf, *dst_buf;513	struct mtk_jpeg_src_buf *jpeg_src_buf;514	enum vb2_buffer_state buf_state;515	struct mtk_jpeg_ctx *ctx;516	u32 dec_irq_ret;517	u32 irq_status;518	int i;519 520	struct mtk_jpegdec_comp_dev *jpeg = priv;521	struct mtk_jpeg_dev *master_jpeg = jpeg->master_dev;522 523	cancel_delayed_work(&jpeg->job_timeout_work);524 525	ctx = jpeg->hw_param.curr_ctx;526	src_buf = jpeg->hw_param.src_buffer;527	dst_buf = jpeg->hw_param.dst_buffer;528	v4l2_m2m_buf_copy_metadata(src_buf, dst_buf, true);529 530	irq_status = mtk_jpeg_dec_get_int_status(jpeg->reg_base);531	dec_irq_ret = mtk_jpeg_dec_enum_result(irq_status);532	if (dec_irq_ret >= MTK_JPEG_DEC_RESULT_UNDERFLOW)533		mtk_jpeg_dec_reset(jpeg->reg_base);534 535	if (dec_irq_ret != MTK_JPEG_DEC_RESULT_EOF_DONE)536		dev_warn(jpeg->dev, "Jpg Dec occurs unknown Err.");537 538	jpeg_src_buf =539		container_of(src_buf, struct mtk_jpeg_src_buf, b);540 541	for (i = 0; i < dst_buf->vb2_buf.num_planes; i++)542		vb2_set_plane_payload(&dst_buf->vb2_buf, i,543				      jpeg_src_buf->dec_param.comp_size[i]);544 545	buf_state = VB2_BUF_STATE_DONE;546	v4l2_m2m_buf_done(src_buf, buf_state);547	mtk_jpegdec_put_buf(jpeg);548	pm_runtime_put(ctx->jpeg->dev);549	clk_disable_unprepare(jpeg->jdec_clk.clks->clk);550 551	jpeg->hw_state = MTK_JPEG_HW_IDLE;552	wake_up(&master_jpeg->hw_wq);553	atomic_inc(&master_jpeg->hw_rdy);554 555	return IRQ_HANDLED;556}557 558static int mtk_jpegdec_hw_init_irq(struct mtk_jpegdec_comp_dev *dev)559{560	struct platform_device *pdev = dev->plat_dev;561	int ret;562 563	dev->jpegdec_irq = platform_get_irq(pdev, 0);564	if (dev->jpegdec_irq < 0)565		return dev->jpegdec_irq;566 567	ret = devm_request_irq(&pdev->dev,568			       dev->jpegdec_irq,569			       mtk_jpegdec_hw_irq_handler,570			       0,571			       pdev->name, dev);572	if (ret) {573		dev_err(&pdev->dev, "Failed to devm_request_irq %d (%d)",574			dev->jpegdec_irq, ret);575		return ret;576	}577 578	return 0;579}580 581static void mtk_jpegdec_destroy_workqueue(void *data)582{583	destroy_workqueue(data);584}585 586static int mtk_jpegdec_hw_probe(struct platform_device *pdev)587{588	struct mtk_jpegdec_clk *jpegdec_clk;589	struct mtk_jpeg_dev *master_dev;590	struct mtk_jpegdec_comp_dev *dev;591	int ret, i;592 593	struct device *decs = &pdev->dev;594 595	if (!decs->parent)596		return -EPROBE_DEFER;597 598	master_dev = dev_get_drvdata(decs->parent);599	if (!master_dev)600		return -EPROBE_DEFER;601 602	dev = devm_kzalloc(&pdev->dev, sizeof(*dev), GFP_KERNEL);603	if (!dev)604		return -ENOMEM;605 606	dev->plat_dev = pdev;607	dev->dev = &pdev->dev;608 609	ret = devm_add_action_or_reset(&pdev->dev,610				       mtk_jpegdec_destroy_workqueue,611				       master_dev->workqueue);612	if (ret)613		return ret;614 615	spin_lock_init(&dev->hw_lock);616	dev->hw_state = MTK_JPEG_HW_IDLE;617 618	INIT_DELAYED_WORK(&dev->job_timeout_work,619			  mtk_jpegdec_timeout_work);620 621	jpegdec_clk = &dev->jdec_clk;622 623	jpegdec_clk->clk_num = devm_clk_bulk_get_all(&pdev->dev,624						     &jpegdec_clk->clks);625	if (jpegdec_clk->clk_num < 0)626		return dev_err_probe(&pdev->dev,627				      jpegdec_clk->clk_num,628				      "Failed to get jpegdec clock count.\n");629 630	dev->reg_base = devm_platform_ioremap_resource(pdev, 0);631	if (IS_ERR(dev->reg_base))632		return PTR_ERR(dev->reg_base);633 634	ret = mtk_jpegdec_hw_init_irq(dev);635	if (ret)636		return dev_err_probe(&pdev->dev, ret,637				     "Failed to register JPEGDEC irq handler.\n");638 639	i = atomic_add_return(1, &master_dev->hw_index) - 1;640	master_dev->dec_hw_dev[i] = dev;641	master_dev->reg_decbase[i] = dev->reg_base;642	dev->master_dev = master_dev;643 644	platform_set_drvdata(pdev, dev);645	pm_runtime_enable(&pdev->dev);646 647	return 0;648}649 650static struct platform_driver mtk_jpegdec_hw_driver = {651	.probe = mtk_jpegdec_hw_probe,652	.driver = {653		.name = "mtk-jpegdec-hw",654		.of_match_table = mtk_jpegdec_hw_ids,655	},656};657 658module_platform_driver(mtk_jpegdec_hw_driver);659 660MODULE_DESCRIPTION("MediaTek JPEG decode HW driver");661MODULE_LICENSE("GPL");662