Message ID | 20220716093408.29734-4-irui.wang@mediatek.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | Support multi-hardware jpeg decoder for MT8195 | expand |
Il 16/07/22 11:34, Irui Wang ha scritto: > From: kyrie wu <kyrie.wu@mediatek.com> > > manage each hardware information, including irq/clk/power. > the hardware includes HW0/HW1/HW2. > > Signed-off-by: kyrie wu <kyrie.wu@mediatek.com> > Signed-off-by: irui wang <irui.wang@mediatek.com> > > --- > drivers/media/platform/mediatek/jpeg/Makefile | 5 +- > .../platform/mediatek/jpeg/mtk_jpeg_core.c | 23 +++ > .../platform/mediatek/jpeg/mtk_jpeg_core.h | 37 ++++ > .../platform/mediatek/jpeg/mtk_jpeg_dec_hw.c | 172 ++++++++++++++++++ > 4 files changed, 235 insertions(+), 2 deletions(-) > > diff --git a/drivers/media/platform/mediatek/jpeg/Makefile b/drivers/media/platform/mediatek/jpeg/Makefile > index 69703db4b0a5..26e84852523e 100644 > --- a/drivers/media/platform/mediatek/jpeg/Makefile > +++ b/drivers/media/platform/mediatek/jpeg/Makefile > @@ -1,9 +1,10 @@ > # SPDX-License-Identifier: GPL-2.0-only > obj-$(CONFIG_VIDEO_MEDIATEK_JPEG) += mtk_jpeg.o \ > - mtk-jpeg-enc-hw.o > + mtk-jpeg-enc-hw.o \ > + mtk-jpeg-dec-hw.o > > mtk_jpeg-y := mtk_jpeg_core.o \ > - mtk_jpeg_dec_hw.o \ > mtk_jpeg_dec_parse.o > > mtk-jpeg-enc-hw-y := mtk_jpeg_enc_hw.o > +mtk-jpeg-dec-hw-y := mtk_jpeg_dec_hw.o > diff --git a/drivers/media/platform/mediatek/jpeg/mtk_jpeg_core.c b/drivers/media/platform/mediatek/jpeg/mtk_jpeg_core.c > index 386d48cc4f59..a9e8be976bb0 100644 > --- a/drivers/media/platform/mediatek/jpeg/mtk_jpeg_core.c > +++ b/drivers/media/platform/mediatek/jpeg/mtk_jpeg_core.c > @@ -1100,6 +1100,10 @@ static void mtk_jpeg_multicore_enc_device_run(void *priv) > queue_work(jpeg->workqueue, &ctx->jpeg_work); > } > > +static void mtk_jpeg_multicore_dec_device_run(void *priv) > +{ .... why is this function empty?! > +} > + > static void mtk_jpeg_dec_device_run(void *priv) > { > struct mtk_jpeg_ctx *ctx = priv; > @@ -1166,6 +1170,10 @@ static const struct v4l2_m2m_ops mtk_jpeg_multicore_enc_m2m_ops = { > .device_run = mtk_jpeg_multicore_enc_device_run, > }; > > +static const struct v4l2_m2m_ops mtk_jpeg_multicore_dec_m2m_ops = { > + .device_run = mtk_jpeg_multicore_dec_device_run, > +}; > + > static const struct v4l2_m2m_ops mtk_jpeg_dec_m2m_ops = { > .device_run = mtk_jpeg_dec_device_run, > .job_ready = mtk_jpeg_dec_job_ready, > @@ -1680,6 +1688,17 @@ static struct mtk_jpeg_variant mtk8195_jpegenc_drvdata = { > .cap_q_default_fourcc = V4L2_PIX_FMT_JPEG, > }; > > +static const struct mtk_jpeg_variant mtk8195_jpegdec_drvdata = { > + .formats = mtk_jpeg_dec_formats, > + .num_formats = MTK_JPEG_DEC_NUM_FORMATS, > + .qops = &mtk_jpeg_dec_qops, > + .m2m_ops = &mtk_jpeg_multicore_dec_m2m_ops, > + .dev_name = "mtk-jpeg-dec", > + .ioctl_ops = &mtk_jpeg_dec_ioctl_ops, > + .out_q_default_fourcc = V4L2_PIX_FMT_JPEG, > + .cap_q_default_fourcc = V4L2_PIX_FMT_YUV420M, > +}; > + > #if defined(CONFIG_OF) > static const struct of_device_id mtk_jpeg_match[] = { > { > @@ -1698,6 +1717,10 @@ static const struct of_device_id mtk_jpeg_match[] = { > .compatible = "mediatek,mt8195-jpgenc", > .data = &mtk8195_jpegenc_drvdata, > }, > + { > + .compatible = "mediatek,mt8195-jpgdec", > + .data = &mtk8195_jpegdec_drvdata, > + }, > {}, > }; > ..snip.. > diff --git a/drivers/media/platform/mediatek/jpeg/mtk_jpeg_dec_hw.c b/drivers/media/platform/mediatek/jpeg/mtk_jpeg_dec_hw.c > index d2f25f43e852..232e81165dd3 100644 > --- a/drivers/media/platform/mediatek/jpeg/mtk_jpeg_dec_hw.c > +++ b/drivers/media/platform/mediatek/jpeg/mtk_jpeg_dec_hw.c ..snip.. > + > +static int mtk_jpegdec_hw_probe(struct platform_device *pdev) > +{ > + struct mtk_jpegdec_clk *jpegdec_clk; > + struct mtk_jpeg_dev *master_dev; > + struct mtk_jpegdec_comp_dev *dev; > + int ret, i; > + > + struct device *decs = &pdev->dev; > + > + if (!decs->parent) > + return -EPROBE_DEFER; > + > + master_dev = dev_get_drvdata(decs->parent); > + if (!master_dev) > + return -EPROBE_DEFER; > + > + dev = devm_kzalloc(&pdev->dev, sizeof(*dev), GFP_KERNEL); > + if (!dev) > + return -ENOMEM; > + > + dev->plat_dev = pdev; > + dev->dev = &pdev->dev; > + > + if (!master_dev->is_jpgdec_multihw) { > + master_dev->is_jpgdec_multihw = true; > + for (i = 0; i < MTK_JPEGDEC_HW_MAX; i++) > + master_dev->dec_hw_dev[i] = NULL; > + } > + > + jpegdec_clk = &dev->jdec_clk; > + > + jpegdec_clk->clk_num = devm_clk_bulk_get_all(&pdev->dev, > + &jpegdec_clk->clks); > + if (jpegdec_clk->clk_num < 0) > + return dev_err_probe(&pdev->dev, > + jpegdec_clk->clk_num, > + "Failed to get jpegdec clock count.\n"); > + > + dev->reg_base = devm_platform_ioremap_resource(pdev, 0); > + if (IS_ERR(dev->reg_base)) > + return PTR_ERR(dev->reg_base); > + > + ret = mtk_jpegdec_hw_init_irq(dev); > + if (ret) > + return dev_err_probe(&pdev->dev, > + ret, > + "Failed to register JPEGDEC irq handler.\n"); Fix: return dev_err_probe(&pdev->dev, ret, "Failed to register JPEGDEC irq handler.\n"); Regards, Angelo
On Mon, 2022-07-18 at 12:22 +0200, AngeloGioacchino Del Regno wrote: > Il 16/07/22 11:34, Irui Wang ha scritto: > > From: kyrie wu <kyrie.wu@mediatek.com> > > > > manage each hardware information, including irq/clk/power. > > the hardware includes HW0/HW1/HW2. > > > > Signed-off-by: kyrie wu <kyrie.wu@mediatek.com> > > Signed-off-by: irui wang <irui.wang@mediatek.com> > > > > --- > > drivers/media/platform/mediatek/jpeg/Makefile | 5 +- > > .../platform/mediatek/jpeg/mtk_jpeg_core.c | 23 +++ > > .../platform/mediatek/jpeg/mtk_jpeg_core.h | 37 ++++ > > .../platform/mediatek/jpeg/mtk_jpeg_dec_hw.c | 172 > > ++++++++++++++++++ > > 4 files changed, 235 insertions(+), 2 deletions(-) > > > > diff --git a/drivers/media/platform/mediatek/jpeg/Makefile > > b/drivers/media/platform/mediatek/jpeg/Makefile > > index 69703db4b0a5..26e84852523e 100644 > > --- a/drivers/media/platform/mediatek/jpeg/Makefile > > +++ b/drivers/media/platform/mediatek/jpeg/Makefile > > @@ -1,9 +1,10 @@ > > # SPDX-License-Identifier: GPL-2.0-only > > obj-$(CONFIG_VIDEO_MEDIATEK_JPEG) += mtk_jpeg.o \ > > - mtk-jpeg-enc-hw.o > > + mtk-jpeg-enc-hw.o \ > > + mtk-jpeg-dec-hw.o > > > > mtk_jpeg-y := mtk_jpeg_core.o \ > > - mtk_jpeg_dec_hw.o \ > > mtk_jpeg_dec_parse.o > > > > mtk-jpeg-enc-hw-y := mtk_jpeg_enc_hw.o > > +mtk-jpeg-dec-hw-y := mtk_jpeg_dec_hw.o > > diff --git a/drivers/media/platform/mediatek/jpeg/mtk_jpeg_core.c > > b/drivers/media/platform/mediatek/jpeg/mtk_jpeg_core.c > > index 386d48cc4f59..a9e8be976bb0 100644 > > --- a/drivers/media/platform/mediatek/jpeg/mtk_jpeg_core.c > > +++ b/drivers/media/platform/mediatek/jpeg/mtk_jpeg_core.c > > @@ -1100,6 +1100,10 @@ static void > > mtk_jpeg_multicore_enc_device_run(void *priv) > > queue_work(jpeg->workqueue, &ctx->jpeg_work); > > } > > > > +static void mtk_jpeg_multicore_dec_device_run(void *priv) > > +{ > > .... why is this function empty?! > > > +} > > + > > static void mtk_jpeg_dec_device_run(void *priv) > > { > > struct mtk_jpeg_ctx *ctx = priv; > > @@ -1166,6 +1170,10 @@ static const struct v4l2_m2m_ops > > mtk_jpeg_multicore_enc_m2m_ops = { > > .device_run = mtk_jpeg_multicore_enc_device_run, > > }; > > > > +static const struct v4l2_m2m_ops mtk_jpeg_multicore_dec_m2m_ops = > > { > > + .device_run = mtk_jpeg_multicore_dec_device_run, > > +}; > > + > > static const struct v4l2_m2m_ops mtk_jpeg_dec_m2m_ops = { > > .device_run = mtk_jpeg_dec_device_run, > > .job_ready = mtk_jpeg_dec_job_ready, > > @@ -1680,6 +1688,17 @@ static struct mtk_jpeg_variant > > mtk8195_jpegenc_drvdata = { > > .cap_q_default_fourcc = V4L2_PIX_FMT_JPEG, > > }; > > > > +static const struct mtk_jpeg_variant mtk8195_jpegdec_drvdata = { > > + .formats = mtk_jpeg_dec_formats, > > + .num_formats = MTK_JPEG_DEC_NUM_FORMATS, > > + .qops = &mtk_jpeg_dec_qops, > > + .m2m_ops = &mtk_jpeg_multicore_dec_m2m_ops, > > + .dev_name = "mtk-jpeg-dec", > > + .ioctl_ops = &mtk_jpeg_dec_ioctl_ops, > > + .out_q_default_fourcc = V4L2_PIX_FMT_JPEG, > > + .cap_q_default_fourcc = V4L2_PIX_FMT_YUV420M, > > +}; > > + > > #if defined(CONFIG_OF) > > static const struct of_device_id mtk_jpeg_match[] = { > > { > > @@ -1698,6 +1717,10 @@ static const struct of_device_id > > mtk_jpeg_match[] = { > > .compatible = "mediatek,mt8195-jpgenc", > > .data = &mtk8195_jpegenc_drvdata, > > }, > > + { > > + .compatible = "mediatek,mt8195-jpgdec", > > + .data = &mtk8195_jpegdec_drvdata, > > + }, > > {}, > > }; > > > > ..snip.. > > > diff --git a/drivers/media/platform/mediatek/jpeg/mtk_jpeg_dec_hw.c > > b/drivers/media/platform/mediatek/jpeg/mtk_jpeg_dec_hw.c > > index d2f25f43e852..232e81165dd3 100644 > > --- a/drivers/media/platform/mediatek/jpeg/mtk_jpeg_dec_hw.c > > +++ b/drivers/media/platform/mediatek/jpeg/mtk_jpeg_dec_hw.c > > ..snip.. > > > + > > +static int mtk_jpegdec_hw_probe(struct platform_device *pdev) > > +{ > > + struct mtk_jpegdec_clk *jpegdec_clk; > > + struct mtk_jpeg_dev *master_dev; > > + struct mtk_jpegdec_comp_dev *dev; > > + int ret, i; > > + > > + struct device *decs = &pdev->dev; > > + > > + if (!decs->parent) > > + return -EPROBE_DEFER; > > + > > + master_dev = dev_get_drvdata(decs->parent); > > + if (!master_dev) > > + return -EPROBE_DEFER; > > + > > + dev = devm_kzalloc(&pdev->dev, sizeof(*dev), GFP_KERNEL); > > + if (!dev) > > + return -ENOMEM; > > + > > + dev->plat_dev = pdev; > > + dev->dev = &pdev->dev; > > + > > + if (!master_dev->is_jpgdec_multihw) { > > + master_dev->is_jpgdec_multihw = true; > > + for (i = 0; i < MTK_JPEGDEC_HW_MAX; i++) > > + master_dev->dec_hw_dev[i] = NULL; > > + } > > + > > + jpegdec_clk = &dev->jdec_clk; > > + > > + jpegdec_clk->clk_num = devm_clk_bulk_get_all(&pdev->dev, > > + &jpegdec_clk- > > >clks); > > + if (jpegdec_clk->clk_num < 0) > > + return dev_err_probe(&pdev->dev, > > + jpegdec_clk->clk_num, > > + "Failed to get jpegdec clock > > count.\n"); > > + > > + dev->reg_base = devm_platform_ioremap_resource(pdev, 0); > > + if (IS_ERR(dev->reg_base)) > > + return PTR_ERR(dev->reg_base); > > + > > + ret = mtk_jpegdec_hw_init_irq(dev); > > + if (ret) > > + return dev_err_probe(&pdev->dev, > > + ret, > > + "Failed to register JPEGDEC irq > > handler.\n"); > > Fix: > return dev_err_probe(&pdev->dev, ret, > > "Failed to register JPEGDEC irq > handler.\n"); > > > Regards, > Angelo Hi Angelo, Thanks for your checking. Regards, Kyrie.
diff --git a/drivers/media/platform/mediatek/jpeg/Makefile b/drivers/media/platform/mediatek/jpeg/Makefile index 69703db4b0a5..26e84852523e 100644 --- a/drivers/media/platform/mediatek/jpeg/Makefile +++ b/drivers/media/platform/mediatek/jpeg/Makefile @@ -1,9 +1,10 @@ # SPDX-License-Identifier: GPL-2.0-only obj-$(CONFIG_VIDEO_MEDIATEK_JPEG) += mtk_jpeg.o \ - mtk-jpeg-enc-hw.o + mtk-jpeg-enc-hw.o \ + mtk-jpeg-dec-hw.o mtk_jpeg-y := mtk_jpeg_core.o \ - mtk_jpeg_dec_hw.o \ mtk_jpeg_dec_parse.o mtk-jpeg-enc-hw-y := mtk_jpeg_enc_hw.o +mtk-jpeg-dec-hw-y := mtk_jpeg_dec_hw.o diff --git a/drivers/media/platform/mediatek/jpeg/mtk_jpeg_core.c b/drivers/media/platform/mediatek/jpeg/mtk_jpeg_core.c index 386d48cc4f59..a9e8be976bb0 100644 --- a/drivers/media/platform/mediatek/jpeg/mtk_jpeg_core.c +++ b/drivers/media/platform/mediatek/jpeg/mtk_jpeg_core.c @@ -1100,6 +1100,10 @@ static void mtk_jpeg_multicore_enc_device_run(void *priv) queue_work(jpeg->workqueue, &ctx->jpeg_work); } +static void mtk_jpeg_multicore_dec_device_run(void *priv) +{ +} + static void mtk_jpeg_dec_device_run(void *priv) { struct mtk_jpeg_ctx *ctx = priv; @@ -1166,6 +1170,10 @@ static const struct v4l2_m2m_ops mtk_jpeg_multicore_enc_m2m_ops = { .device_run = mtk_jpeg_multicore_enc_device_run, }; +static const struct v4l2_m2m_ops mtk_jpeg_multicore_dec_m2m_ops = { + .device_run = mtk_jpeg_multicore_dec_device_run, +}; + static const struct v4l2_m2m_ops mtk_jpeg_dec_m2m_ops = { .device_run = mtk_jpeg_dec_device_run, .job_ready = mtk_jpeg_dec_job_ready, @@ -1680,6 +1688,17 @@ static struct mtk_jpeg_variant mtk8195_jpegenc_drvdata = { .cap_q_default_fourcc = V4L2_PIX_FMT_JPEG, }; +static const struct mtk_jpeg_variant mtk8195_jpegdec_drvdata = { + .formats = mtk_jpeg_dec_formats, + .num_formats = MTK_JPEG_DEC_NUM_FORMATS, + .qops = &mtk_jpeg_dec_qops, + .m2m_ops = &mtk_jpeg_multicore_dec_m2m_ops, + .dev_name = "mtk-jpeg-dec", + .ioctl_ops = &mtk_jpeg_dec_ioctl_ops, + .out_q_default_fourcc = V4L2_PIX_FMT_JPEG, + .cap_q_default_fourcc = V4L2_PIX_FMT_YUV420M, +}; + #if defined(CONFIG_OF) static const struct of_device_id mtk_jpeg_match[] = { { @@ -1698,6 +1717,10 @@ static const struct of_device_id mtk_jpeg_match[] = { .compatible = "mediatek,mt8195-jpgenc", .data = &mtk8195_jpegenc_drvdata, }, + { + .compatible = "mediatek,mt8195-jpgdec", + .data = &mtk8195_jpegdec_drvdata, + }, {}, }; diff --git a/drivers/media/platform/mediatek/jpeg/mtk_jpeg_core.h b/drivers/media/platform/mediatek/jpeg/mtk_jpeg_core.h index 9321d1597e21..e2e670e58b82 100644 --- a/drivers/media/platform/mediatek/jpeg/mtk_jpeg_core.h +++ b/drivers/media/platform/mediatek/jpeg/mtk_jpeg_core.h @@ -102,6 +102,13 @@ enum mtk_jpegenc_hw_id { MTK_JPEGENC_HW_MAX, }; +enum mtk_jpegdec_hw_id { + MTK_JPEGDEC_HW0, + MTK_JPEGDEC_HW1, + MTK_JPEGDEC_HW2, + MTK_JPEGDEC_HW_MAX, +}; + /** * struct mtk_jpegenc_clk - Structure used to store vcodec clock information */ @@ -110,6 +117,14 @@ struct mtk_jpegenc_clk { int clk_num; }; +/** + * struct mtk_jpegdec_clk - Structure used to store vcodec clock information + */ +struct mtk_jpegdec_clk { + struct clk_bulk_data *clks; + int clk_num; +}; + /** * struct mtk_jpegenc_comp_dev - JPEG COREX abstraction * @dev: JPEG device @@ -138,6 +153,24 @@ struct mtk_jpegenc_comp_dev { spinlock_t hw_lock; }; +/** + * struct mtk_jpegdec_comp_dev - JPEG COREX abstraction + * @dev: JPEG device + * @plat_dev: platform device data + * @reg_base: JPEG registers mapping + * @master_dev: mtk_jpeg_dev device + * @jdec_clk: mtk_jpegdec_clk + * @jpegdec_irq: jpeg decode irq num + */ +struct mtk_jpegdec_comp_dev { + struct device *dev; + struct platform_device *plat_dev; + void __iomem *reg_base; + struct mtk_jpeg_dev *master_dev; + struct mtk_jpegdec_clk jdec_clk; + int jpegdec_irq; +}; + /** * struct mtk_jpeg_dev - JPEG IP abstraction * @lock: the mutex protecting this structure @@ -170,6 +203,10 @@ struct mtk_jpeg_dev { bool is_jpgenc_multihw; wait_queue_head_t enc_hw_wq; atomic_t enchw_rdy; + + void __iomem *reg_decbase[MTK_JPEGDEC_HW_MAX]; + struct mtk_jpegdec_comp_dev *dec_hw_dev[MTK_JPEGDEC_HW_MAX]; + bool is_jpgdec_multihw; }; /** diff --git a/drivers/media/platform/mediatek/jpeg/mtk_jpeg_dec_hw.c b/drivers/media/platform/mediatek/jpeg/mtk_jpeg_dec_hw.c index d2f25f43e852..232e81165dd3 100644 --- a/drivers/media/platform/mediatek/jpeg/mtk_jpeg_dec_hw.c +++ b/drivers/media/platform/mediatek/jpeg/mtk_jpeg_dec_hw.c @@ -5,9 +5,24 @@ * Rick Chang <rick.chang@mediatek.com> */ +#include <linux/clk.h> +#include <linux/interrupt.h> +#include <linux/irq.h> #include <linux/io.h> #include <linux/kernel.h> +#include <linux/module.h> +#include <linux/of.h> +#include <linux/of_device.h> +#include <linux/pm_runtime.h> +#include <linux/slab.h> +#include <media/media-device.h> #include <media/videobuf2-core.h> +#include <media/videobuf2-v4l2.h> +#include <media/v4l2-mem2mem.h> +#include <media/v4l2-dev.h> +#include <media/v4l2-device.h> +#include <media/v4l2-fh.h> +#include <media/v4l2-event.h> #include "mtk_jpeg_core.h" #include "mtk_jpeg_dec_hw.h" @@ -24,6 +39,16 @@ enum mtk_jpeg_color { MTK_JPEG_COLOR_400 = 0x00110000 }; +#if defined(CONFIG_OF) +static const struct of_device_id mtk_jpegdec_hw_ids[] = { + { + .compatible = "mediatek,mt8195-jpgdec-hw", + }, + {}, +}; +MODULE_DEVICE_TABLE(of, mtk_jpegdec_hw_ids); +#endif + static inline int mtk_jpeg_verify_align(u32 val, int align, u32 reg) { if (val & (align - 1)) { @@ -414,3 +439,150 @@ void mtk_jpeg_dec_set_config(void __iomem *base, mtk_jpeg_dec_set_pause_mcu_idx(base, config->total_mcu); } EXPORT_SYMBOL_GPL(mtk_jpeg_dec_set_config); + +static irqreturn_t mtk_jpegdec_hw_irq_handler(int irq, void *priv) +{ + struct vb2_v4l2_buffer *src_buf, *dst_buf; + struct mtk_jpeg_src_buf *jpeg_src_buf; + enum vb2_buffer_state buf_state; + struct mtk_jpeg_ctx *ctx; + u32 dec_irq_ret; + u32 irq_status; + int i; + + struct mtk_jpegdec_comp_dev *jpeg = priv; + struct mtk_jpeg_dev *master_jpeg = jpeg->master_dev; + + irq_status = mtk_jpeg_dec_get_int_status(jpeg->reg_base); + dec_irq_ret = mtk_jpeg_dec_enum_result(irq_status); + if (dec_irq_ret >= MTK_JPEG_DEC_RESULT_UNDERFLOW) + mtk_jpeg_dec_reset(jpeg->reg_base); + if (dec_irq_ret != MTK_JPEG_DEC_RESULT_EOF_DONE) + return IRQ_NONE; + + ctx = v4l2_m2m_get_curr_priv(master_jpeg->m2m_dev); + if (!ctx) { + dev_err(jpeg->dev, "Context is NULL\n"); + return IRQ_HANDLED; + } + + src_buf = v4l2_m2m_src_buf_remove(ctx->fh.m2m_ctx); + dst_buf = v4l2_m2m_dst_buf_remove(ctx->fh.m2m_ctx); + v4l2_m2m_buf_copy_metadata(src_buf, dst_buf, true); + jpeg_src_buf = + container_of(src_buf, struct mtk_jpeg_src_buf, b); + + for (i = 0; i < dst_buf->vb2_buf.num_planes; i++) + vb2_set_plane_payload(&dst_buf->vb2_buf, i, + jpeg_src_buf->dec_param.comp_size[i]); + + buf_state = VB2_BUF_STATE_DONE; + + v4l2_m2m_buf_done(src_buf, buf_state); + v4l2_m2m_buf_done(dst_buf, buf_state); + v4l2_m2m_job_finish(master_jpeg->m2m_dev, ctx->fh.m2m_ctx); + pm_runtime_put(ctx->jpeg->dev); + + return IRQ_HANDLED; +} + +static int mtk_jpegdec_hw_init_irq(struct mtk_jpegdec_comp_dev *dev) +{ + struct platform_device *pdev = dev->plat_dev; + int ret; + + dev->jpegdec_irq = platform_get_irq(pdev, 0); + if (dev->jpegdec_irq < 0) { + dev_err(&pdev->dev, "Failed to get irq resource"); + return dev->jpegdec_irq; + } + + ret = devm_request_irq(&pdev->dev, + dev->jpegdec_irq, + mtk_jpegdec_hw_irq_handler, + 0, + pdev->name, dev); + if (ret) { + dev_err(&pdev->dev, "Failed to devm_request_irq %d (%d)", + dev->jpegdec_irq, ret); + return -ENOENT; + } + + return 0; +} + +static int mtk_jpegdec_hw_probe(struct platform_device *pdev) +{ + struct mtk_jpegdec_clk *jpegdec_clk; + struct mtk_jpeg_dev *master_dev; + struct mtk_jpegdec_comp_dev *dev; + int ret, i; + + struct device *decs = &pdev->dev; + + if (!decs->parent) + return -EPROBE_DEFER; + + master_dev = dev_get_drvdata(decs->parent); + if (!master_dev) + return -EPROBE_DEFER; + + dev = devm_kzalloc(&pdev->dev, sizeof(*dev), GFP_KERNEL); + if (!dev) + return -ENOMEM; + + dev->plat_dev = pdev; + dev->dev = &pdev->dev; + + if (!master_dev->is_jpgdec_multihw) { + master_dev->is_jpgdec_multihw = true; + for (i = 0; i < MTK_JPEGDEC_HW_MAX; i++) + master_dev->dec_hw_dev[i] = NULL; + } + + jpegdec_clk = &dev->jdec_clk; + + jpegdec_clk->clk_num = devm_clk_bulk_get_all(&pdev->dev, + &jpegdec_clk->clks); + if (jpegdec_clk->clk_num < 0) + return dev_err_probe(&pdev->dev, + jpegdec_clk->clk_num, + "Failed to get jpegdec clock count.\n"); + + dev->reg_base = devm_platform_ioremap_resource(pdev, 0); + if (IS_ERR(dev->reg_base)) + return PTR_ERR(dev->reg_base); + + ret = mtk_jpegdec_hw_init_irq(dev); + if (ret) + return dev_err_probe(&pdev->dev, + ret, + "Failed to register JPEGDEC irq handler.\n"); + + for (i = 0; i < MTK_JPEGDEC_HW_MAX; i++) { + if (master_dev->dec_hw_dev[i]) + continue; + + master_dev->dec_hw_dev[i] = dev; + master_dev->reg_decbase[i] = dev->reg_base; + dev->master_dev = master_dev; + } + + platform_set_drvdata(pdev, dev); + pm_runtime_enable(&pdev->dev); + + return 0; +} + +struct platform_driver mtk_jpegdec_hw_driver = { + .probe = mtk_jpegdec_hw_probe, + .driver = { + .name = "mtk-jpegdec-hw", + .of_match_table = of_match_ptr(mtk_jpegdec_hw_ids), + }, +}; + +module_platform_driver(mtk_jpegdec_hw_driver); + +MODULE_DESCRIPTION("MediaTek JPEG decode HW driver"); +MODULE_LICENSE("GPL");