Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

media: imx-jpeg: Support to assign slot for encoder/decoder

imx jpeg encoder and decoder support 4 slots each,
aim to support some virtualization scenarios.

driver should only enable one slot one time.

but due to some hardware issue,
only slot 0 can be enabled in imx8q platform,
and they may be fixed in imx9 platform.

Signed-off-by: Ming Qian <ming.qian@nxp.com>
Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
Signed-off-by: Mauro Carvalho Chehab <mchehab@kernel.org>

authored by

Ming Qian and committed by
Mauro Carvalho Chehab
53ebeea5 dcff0b56

+68 -73
-1
drivers/media/platform/nxp/imx-jpeg/mxc-jpeg-hw.h
··· 58 58 #define CAST_OFBSIZE_LO CAST_STATUS18 59 59 #define CAST_OFBSIZE_HI CAST_STATUS19 60 60 61 - #define MXC_MAX_SLOTS 1 /* TODO use all 4 slots*/ 62 61 /* JPEG-Decoder Wrapper Slot Registers 0..3 */ 63 62 #define SLOT_BASE 0x10000 64 63 #define SLOT_STATUS 0x0
+65 -70
drivers/media/platform/nxp/imx-jpeg/mxc-jpeg.c
··· 745 745 v4l2_event_queue_fh(&ctx->fh, &ev); 746 746 } 747 747 748 - static int mxc_get_free_slot(struct mxc_jpeg_slot_data slot_data[], int n) 748 + static int mxc_get_free_slot(struct mxc_jpeg_slot_data *slot_data) 749 749 { 750 - int free_slot = 0; 751 - 752 - while (slot_data[free_slot].used && free_slot < n) 753 - free_slot++; 754 - 755 - return free_slot; /* >=n when there are no more free slots */ 750 + if (!slot_data->used) 751 + return slot_data->slot; 752 + return -1; 756 753 } 757 754 758 - static bool mxc_jpeg_alloc_slot_data(struct mxc_jpeg_dev *jpeg, 759 - unsigned int slot) 755 + static bool mxc_jpeg_alloc_slot_data(struct mxc_jpeg_dev *jpeg) 760 756 { 761 757 struct mxc_jpeg_desc *desc; 762 758 struct mxc_jpeg_desc *cfg_desc; 763 759 void *cfg_stm; 764 760 765 - if (jpeg->slot_data[slot].desc) 761 + if (jpeg->slot_data.desc) 766 762 goto skip_alloc; /* already allocated, reuse it */ 767 763 768 764 /* allocate descriptor for decoding/encoding phase */ 769 765 desc = dma_alloc_coherent(jpeg->dev, 770 766 sizeof(struct mxc_jpeg_desc), 771 - &jpeg->slot_data[slot].desc_handle, 767 + &jpeg->slot_data.desc_handle, 772 768 GFP_ATOMIC); 773 769 if (!desc) 774 770 goto err; 775 - jpeg->slot_data[slot].desc = desc; 771 + jpeg->slot_data.desc = desc; 776 772 777 773 /* allocate descriptor for configuration phase (encoder only) */ 778 774 cfg_desc = dma_alloc_coherent(jpeg->dev, 779 775 sizeof(struct mxc_jpeg_desc), 780 - &jpeg->slot_data[slot].cfg_desc_handle, 776 + &jpeg->slot_data.cfg_desc_handle, 781 777 GFP_ATOMIC); 782 778 if (!cfg_desc) 783 779 goto err; 784 - jpeg->slot_data[slot].cfg_desc = cfg_desc; 780 + jpeg->slot_data.cfg_desc = cfg_desc; 785 781 786 782 /* allocate configuration stream */ 787 783 cfg_stm = dma_alloc_coherent(jpeg->dev, 788 784 MXC_JPEG_MAX_CFG_STREAM, 789 - &jpeg->slot_data[slot].cfg_stream_handle, 785 + &jpeg->slot_data.cfg_stream_handle, 790 786 GFP_ATOMIC); 791 787 if (!cfg_stm) 792 788 goto err; 793 - jpeg->slot_data[slot].cfg_stream_vaddr = cfg_stm; 789 + jpeg->slot_data.cfg_stream_vaddr = cfg_stm; 794 790 795 791 skip_alloc: 796 - jpeg->slot_data[slot].used = true; 792 + jpeg->slot_data.used = true; 797 793 798 794 return true; 799 795 err: 800 - dev_err(jpeg->dev, "Could not allocate descriptors for slot %d", slot); 796 + dev_err(jpeg->dev, "Could not allocate descriptors for slot %d", jpeg->slot_data.slot); 801 797 802 798 return false; 803 799 } 804 800 805 - static void mxc_jpeg_free_slot_data(struct mxc_jpeg_dev *jpeg, 806 - unsigned int slot) 801 + static void mxc_jpeg_free_slot_data(struct mxc_jpeg_dev *jpeg) 807 802 { 808 - if (slot >= MXC_MAX_SLOTS) { 809 - dev_err(jpeg->dev, "Invalid slot %d, nothing to free.", slot); 810 - return; 811 - } 812 - 813 803 /* free descriptor for decoding/encoding phase */ 814 804 dma_free_coherent(jpeg->dev, sizeof(struct mxc_jpeg_desc), 815 - jpeg->slot_data[slot].desc, 816 - jpeg->slot_data[slot].desc_handle); 805 + jpeg->slot_data.desc, 806 + jpeg->slot_data.desc_handle); 817 807 818 808 /* free descriptor for encoder configuration phase / decoder DHT */ 819 809 dma_free_coherent(jpeg->dev, sizeof(struct mxc_jpeg_desc), 820 - jpeg->slot_data[slot].cfg_desc, 821 - jpeg->slot_data[slot].cfg_desc_handle); 810 + jpeg->slot_data.cfg_desc, 811 + jpeg->slot_data.cfg_desc_handle); 822 812 823 813 /* free configuration stream */ 824 814 dma_free_coherent(jpeg->dev, MXC_JPEG_MAX_CFG_STREAM, 825 - jpeg->slot_data[slot].cfg_stream_vaddr, 826 - jpeg->slot_data[slot].cfg_stream_handle); 815 + jpeg->slot_data.cfg_stream_vaddr, 816 + jpeg->slot_data.cfg_stream_handle); 827 817 828 - jpeg->slot_data[slot].used = false; 818 + jpeg->slot_data.used = false; 829 819 } 830 820 831 821 static void mxc_jpeg_check_and_set_last_buffer(struct mxc_jpeg_ctx *ctx, ··· 845 855 v4l2_m2m_buf_done(dst_buf, state); 846 856 847 857 mxc_jpeg_disable_irq(reg, ctx->slot); 848 - ctx->mxc_jpeg->slot_data[ctx->slot].used = false; 858 + jpeg->slot_data.used = false; 849 859 if (reset) 850 860 mxc_jpeg_sw_reset(reg); 851 861 } ··· 909 919 goto job_unlock; 910 920 } 911 921 912 - if (!jpeg->slot_data[slot].used) 922 + if (!jpeg->slot_data.used) 913 923 goto job_unlock; 914 924 915 925 dec_ret = readl(reg + MXC_SLOT_OFFSET(slot, SLOT_STATUS)); ··· 1169 1179 struct mxc_jpeg_dev *jpeg = ctx->mxc_jpeg; 1170 1180 void __iomem *reg = jpeg->base_reg; 1171 1181 unsigned int slot = ctx->slot; 1172 - struct mxc_jpeg_desc *desc = jpeg->slot_data[slot].desc; 1173 - struct mxc_jpeg_desc *cfg_desc = jpeg->slot_data[slot].cfg_desc; 1174 - dma_addr_t desc_handle = jpeg->slot_data[slot].desc_handle; 1175 - dma_addr_t cfg_desc_handle = jpeg->slot_data[slot].cfg_desc_handle; 1176 - dma_addr_t cfg_stream_handle = jpeg->slot_data[slot].cfg_stream_handle; 1177 - unsigned int *cfg_size = &jpeg->slot_data[slot].cfg_stream_size; 1178 - void *cfg_stream_vaddr = jpeg->slot_data[slot].cfg_stream_vaddr; 1182 + struct mxc_jpeg_desc *desc = jpeg->slot_data.desc; 1183 + struct mxc_jpeg_desc *cfg_desc = jpeg->slot_data.cfg_desc; 1184 + dma_addr_t desc_handle = jpeg->slot_data.desc_handle; 1185 + dma_addr_t cfg_desc_handle = jpeg->slot_data.cfg_desc_handle; 1186 + dma_addr_t cfg_stream_handle = jpeg->slot_data.cfg_stream_handle; 1187 + unsigned int *cfg_size = &jpeg->slot_data.cfg_stream_size; 1188 + void *cfg_stream_vaddr = jpeg->slot_data.cfg_stream_vaddr; 1179 1189 struct mxc_jpeg_src_buf *jpeg_src_buf; 1180 1190 1181 1191 jpeg_src_buf = vb2_to_mxc_buf(src_buf); ··· 1235 1245 struct mxc_jpeg_dev *jpeg = ctx->mxc_jpeg; 1236 1246 void __iomem *reg = jpeg->base_reg; 1237 1247 unsigned int slot = ctx->slot; 1238 - struct mxc_jpeg_desc *desc = jpeg->slot_data[slot].desc; 1239 - struct mxc_jpeg_desc *cfg_desc = jpeg->slot_data[slot].cfg_desc; 1240 - dma_addr_t desc_handle = jpeg->slot_data[slot].desc_handle; 1241 - dma_addr_t cfg_desc_handle = jpeg->slot_data[slot].cfg_desc_handle; 1242 - void *cfg_stream_vaddr = jpeg->slot_data[slot].cfg_stream_vaddr; 1248 + struct mxc_jpeg_desc *desc = jpeg->slot_data.desc; 1249 + struct mxc_jpeg_desc *cfg_desc = jpeg->slot_data.cfg_desc; 1250 + dma_addr_t desc_handle = jpeg->slot_data.desc_handle; 1251 + dma_addr_t cfg_desc_handle = jpeg->slot_data.cfg_desc_handle; 1252 + void *cfg_stream_vaddr = jpeg->slot_data.cfg_stream_vaddr; 1243 1253 struct mxc_jpeg_q_data *q_data; 1244 1254 enum mxc_jpeg_image_format img_fmt; 1245 1255 int w, h; 1246 1256 1247 1257 q_data = mxc_jpeg_get_q_data(ctx, src_buf->vb2_queue->type); 1248 1258 1249 - jpeg->slot_data[slot].cfg_stream_size = 1259 + jpeg->slot_data.cfg_stream_size = 1250 1260 mxc_jpeg_setup_cfg_stream(cfg_stream_vaddr, 1251 1261 q_data->fmt->fourcc, 1252 1262 q_data->crop.width, ··· 1255 1265 /* chain the config descriptor with the encoding descriptor */ 1256 1266 cfg_desc->next_descpt_ptr = desc_handle | MXC_NXT_DESCPT_EN; 1257 1267 1258 - cfg_desc->buf_base0 = jpeg->slot_data[slot].cfg_stream_handle; 1268 + cfg_desc->buf_base0 = jpeg->slot_data.cfg_stream_handle; 1259 1269 cfg_desc->buf_base1 = 0; 1260 1270 cfg_desc->line_pitch = 0; 1261 1271 cfg_desc->stm_bufbase = 0; /* no output expected */ ··· 1398 1408 unsigned long flags; 1399 1409 1400 1410 spin_lock_irqsave(&ctx->mxc_jpeg->hw_lock, flags); 1401 - if (ctx->slot < MXC_MAX_SLOTS && ctx->mxc_jpeg->slot_data[ctx->slot].used) { 1411 + if (ctx->mxc_jpeg->slot_data.used) { 1402 1412 dev_warn(jpeg->dev, "%s timeout, cancel it\n", 1403 1413 ctx->mxc_jpeg->mode == MXC_JPEG_DECODE ? "decode" : "encode"); 1404 1414 mxc_jpeg_job_finish(ctx, VB2_BUF_STATE_ERROR, true); ··· 1466 1476 mxc_jpeg_enable(reg); 1467 1477 mxc_jpeg_set_l_endian(reg, 1); 1468 1478 1469 - ctx->slot = mxc_get_free_slot(jpeg->slot_data, MXC_MAX_SLOTS); 1470 - if (ctx->slot >= MXC_MAX_SLOTS) { 1479 + ctx->slot = mxc_get_free_slot(&jpeg->slot_data); 1480 + if (ctx->slot < 0) { 1471 1481 dev_err(dev, "No more free slots\n"); 1472 1482 goto end; 1473 1483 } 1474 - if (!mxc_jpeg_alloc_slot_data(jpeg, ctx->slot)) { 1484 + if (!mxc_jpeg_alloc_slot_data(jpeg)) { 1475 1485 dev_err(dev, "Cannot allocate slot data\n"); 1476 1486 goto end; 1477 1487 } ··· 2091 2101 } 2092 2102 ctx->fh.ctrl_handler = &ctx->ctrl_handler; 2093 2103 mxc_jpeg_set_default_params(ctx); 2094 - ctx->slot = MXC_MAX_SLOTS; /* slot not allocated yet */ 2104 + ctx->slot = -1; /* slot not allocated yet */ 2095 2105 INIT_DELAYED_WORK(&ctx->task_timer, mxc_jpeg_device_run_timeout); 2096 2106 2097 2107 if (mxc_jpeg->mode == MXC_JPEG_DECODE) ··· 2667 2677 dev_err(dev, "No power domains defined for jpeg node\n"); 2668 2678 return jpeg->num_domains; 2669 2679 } 2680 + if (jpeg->num_domains == 1) { 2681 + /* genpd_dev_pm_attach() attach automatically if power domains count is 1 */ 2682 + jpeg->num_domains = 0; 2683 + return 0; 2684 + } 2670 2685 2671 2686 jpeg->pd_dev = devm_kmalloc_array(dev, jpeg->num_domains, 2672 2687 sizeof(*jpeg->pd_dev), GFP_KERNEL); ··· 2713 2718 int ret; 2714 2719 int mode; 2715 2720 const struct of_device_id *of_id; 2716 - unsigned int slot; 2717 2721 2718 2722 of_id = of_match_node(mxc_jpeg_match, dev->of_node); 2719 2723 if (!of_id) ··· 2736 2742 if (IS_ERR(jpeg->base_reg)) 2737 2743 return PTR_ERR(jpeg->base_reg); 2738 2744 2739 - for (slot = 0; slot < MXC_MAX_SLOTS; slot++) { 2740 - dec_irq = platform_get_irq(pdev, slot); 2741 - if (dec_irq < 0) { 2742 - ret = dec_irq; 2743 - goto err_irq; 2744 - } 2745 - ret = devm_request_irq(&pdev->dev, dec_irq, mxc_jpeg_dec_irq, 2746 - 0, pdev->name, jpeg); 2747 - if (ret) { 2748 - dev_err(&pdev->dev, "Failed to request irq %d (%d)\n", 2749 - dec_irq, ret); 2750 - goto err_irq; 2751 - } 2745 + ret = of_property_read_u32_index(pdev->dev.of_node, "slot", 0, &jpeg->slot_data.slot); 2746 + if (ret) 2747 + jpeg->slot_data.slot = 0; 2748 + dev_info(&pdev->dev, "choose slot %d\n", jpeg->slot_data.slot); 2749 + dec_irq = platform_get_irq(pdev, 0); 2750 + if (dec_irq < 0) { 2751 + dev_err(&pdev->dev, "Failed to get irq %d\n", dec_irq); 2752 + ret = dec_irq; 2753 + goto err_irq; 2754 + } 2755 + ret = devm_request_irq(&pdev->dev, dec_irq, mxc_jpeg_dec_irq, 2756 + 0, pdev->name, jpeg); 2757 + if (ret) { 2758 + dev_err(&pdev->dev, "Failed to request irq %d (%d)\n", 2759 + dec_irq, ret); 2760 + goto err_irq; 2752 2761 } 2753 2762 2754 2763 jpeg->pdev = pdev; ··· 2911 2914 2912 2915 static void mxc_jpeg_remove(struct platform_device *pdev) 2913 2916 { 2914 - unsigned int slot; 2915 2917 struct mxc_jpeg_dev *jpeg = platform_get_drvdata(pdev); 2916 2918 2917 - for (slot = 0; slot < MXC_MAX_SLOTS; slot++) 2918 - mxc_jpeg_free_slot_data(jpeg, slot); 2919 + mxc_jpeg_free_slot_data(jpeg); 2919 2920 2920 2921 pm_runtime_disable(&pdev->dev); 2921 2922 video_unregister_device(jpeg->dec_vdev);
+3 -2
drivers/media/platform/nxp/imx-jpeg/mxc-jpeg.h
··· 97 97 struct mxc_jpeg_q_data cap_q; 98 98 struct v4l2_fh fh; 99 99 enum mxc_jpeg_enc_state enc_state; 100 - unsigned int slot; 100 + int slot; 101 101 unsigned int source_change; 102 102 bool header_parsed; 103 103 struct v4l2_ctrl_handler ctrl_handler; ··· 106 106 }; 107 107 108 108 struct mxc_jpeg_slot_data { 109 + int slot; 109 110 bool used; 110 111 struct mxc_jpeg_desc *desc; // enc/dec descriptor 111 112 struct mxc_jpeg_desc *cfg_desc; // configuration descriptor ··· 129 128 struct v4l2_device v4l2_dev; 130 129 struct v4l2_m2m_dev *m2m_dev; 131 130 struct video_device *dec_vdev; 132 - struct mxc_jpeg_slot_data slot_data[MXC_MAX_SLOTS]; 131 + struct mxc_jpeg_slot_data slot_data; 133 132 int num_domains; 134 133 struct device **pd_dev; 135 134 struct device_link **pd_link;