diff options
| author | Stephen Rothwell <sfr@canb.auug.org.au> | 2022-06-28 10:44:22 +1000 |
|---|---|---|
| committer | Stephen Rothwell <sfr@canb.auug.org.au> | 2022-06-28 10:44:22 +1000 |
| commit | 7ad74b5af8743f204774287b6dc61ca3d7b32602 (patch) | |
| tree | 389cf37bfbc3e331c6f4643f8f4376c2ca603904 | |
| parent | 8d6308e68cd854eb7bfdbd0133c62f3e84f4826c (diff) | |
| parent | 945a9a8e448b65bec055d37eba58f711b39f66f0 (diff) | |
| download | linux-next-7ad74b5af8743f204774287b6dc61ca3d7b32602.tar.gz | |
Merge branch 'master' of git://linuxtv.org/media_tree.git
100 files changed, 1475 insertions, 688 deletions
diff --git a/Documentation/admin-guide/media/vivid.rst b/Documentation/admin-guide/media/vivid.rst index 6d7175f96f74c..4f680dc9661cb 100644 --- a/Documentation/admin-guide/media/vivid.rst +++ b/Documentation/admin-guide/media/vivid.rst @@ -714,6 +714,20 @@ The Test Pattern Controls are all specific to video capture. does the same for the EAV (End of Active Video) code. +- Insert Video Guard Band + + adds 4 columns of pixels with the HDMI Video Guard Band code at the + left hand side of the image. This only works with 3 or 4 byte RGB pixel + formats. The RGB pixel value 0xab/0x55/0xab turns out to be equivalent + to the HDMI Video Guard Band code that precedes each active video line + (see section 5.2.2.1 in the HDMI 1.3 Specification). To test if a video + receiver has correct HDMI Video Guard Band processing, enable this + control and then move the image to the left hand side of the screen. + That will result in video lines that start with multiple pixels that + have the same value as the Video Guard Band that precedes them. + Receivers that will just keep skipping Video Guard Band values will + now fail and either loose sync or these video lines will shift. + Capture Feature Selection Controls ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/Documentation/devicetree/bindings/media/mediatek,vcodec-subdev-decoder.yaml b/Documentation/devicetree/bindings/media/mediatek,vcodec-subdev-decoder.yaml index 440646e44c0d4..d4e2051beeb6d 100644 --- a/Documentation/devicetree/bindings/media/mediatek,vcodec-subdev-decoder.yaml +++ b/Documentation/devicetree/bindings/media/mediatek,vcodec-subdev-decoder.yaml @@ -17,20 +17,20 @@ description: | About the Decoder Hardware Block Diagram, please check below: - +---------------------------------+------------------------------------+ - | | | - | input -> lat HW -> lat buffer --|--> lat buffer -> core HW -> output | - | || | || | - +------------||-------------------+---------------------||-------------+ - lat workqueue | core workqueue <parent> - -------------||-----------------------------------------||------------------ - || || <child> - \/ <----------------HW index-------------->\/ - +------------------------------------------------------+ - | enable/disable | - | clk power irq iommu | - | (lat/lat soc/core0/core1) | - +------------------------------------------------------+ + +------------------------------------------------+-------------------------------------+ + | | | + | input -> lat soc HW -> lat HW -> lat buffer --|--> lat buffer -> core HW -> output | + | || || | || | + +------------||-------------||-------------------+---------------------||--------------+ + || lat || | core workqueue <parent> + -------------||-------------||-------------------|---------------------||--------------- + ||<------------||----------------HW index---------------->|| <child> + \/ \/ \/ + +-------------------------------------------------------------+ + | enable/disable | + | clk power irq iommu | + | (lat/lat soc/core0/core1) | + +-------------------------------------------------------------+ As above, there are parent and child devices, child mean each hardware. The child device controls the information of each hardware independent which include clk/power/irq. @@ -45,11 +45,19 @@ description: | For the smi common may not the same for each hardware, can't combine all hardware in one node, or leading to iommu fault when access dram data. + Lat soc is a hardware which is related with some larb(local arbiter) ports. For mt8195 + platform, there are some ports like RDMA, UFO in lat soc larb, need to enable its power and + clock when lat start to work, don't have interrupt. + + mt8195: lat soc HW + lat HW + core HW + mt8192: lat HW + core HW + properties: compatible: enum: - mediatek,mt8192-vcodec-dec - mediatek,mt8186-vcodec-dec + - mediatek,mt8195-vcodec-dec reg: maxItems: 1 @@ -87,7 +95,9 @@ patternProperties: properties: compatible: - const: mediatek,mtk-vcodec-lat + enum: + - mediatek,mtk-vcodec-lat + - mediatek,mtk-vcodec-lat-soc reg: maxItems: 1 @@ -125,7 +135,6 @@ patternProperties: required: - compatible - reg - - interrupts - iommus - clocks - clock-names @@ -196,6 +205,17 @@ required: - dma-ranges - ranges +if: + properties: + compatible: + contains: + enum: + - mediatek,mtk-vcodec-lat + +then: + required: + - interrupts + additionalProperties: false examples: diff --git a/Documentation/devicetree/bindings/media/mediatek-jpeg-encoder.yaml b/Documentation/devicetree/bindings/media/mediatek-jpeg-encoder.yaml index 8bfdfdfaba594..4fd390c042a99 100644 --- a/Documentation/devicetree/bindings/media/mediatek-jpeg-encoder.yaml +++ b/Documentation/devicetree/bindings/media/mediatek-jpeg-encoder.yaml @@ -18,6 +18,7 @@ properties: - enum: - mediatek,mt2701-jpgenc - mediatek,mt8183-jpgenc + - mediatek,mt8186-jpgenc - const: mediatek,mtk-jpgenc reg: maxItems: 1 @@ -42,6 +43,11 @@ properties: Documentation/devicetree/bindings/iommu/mediatek,iommu.yaml for details. Ports are according to the HW. + dma-ranges: + maxItems: 1 + description: | + Describes the physical address space of IOMMU maps to memory. + required: - compatible - reg diff --git a/Documentation/devicetree/bindings/media/qcom,sdm660-camss.yaml b/Documentation/devicetree/bindings/media/qcom,sdm660-camss.yaml index 338ab28d5f3b2..b28c8e17f1581 100644 --- a/Documentation/devicetree/bindings/media/qcom,sdm660-camss.yaml +++ b/Documentation/devicetree/bindings/media/qcom,sdm660-camss.yaml @@ -84,6 +84,13 @@ properties: - const: vfe0 - const: vfe1 + interconnects: + maxItems: 1 + + interconnect-names: + items: + - const: vfe-mem + iommus: maxItems: 4 diff --git a/Documentation/userspace-api/media/v4l/pixfmt-yuv-planar.rst b/Documentation/userspace-api/media/v4l/pixfmt-yuv-planar.rst index 8dff5906639b9..a900ff66911ad 100644 --- a/Documentation/userspace-api/media/v4l/pixfmt-yuv-planar.rst +++ b/Documentation/userspace-api/media/v4l/pixfmt-yuv-planar.rst @@ -109,6 +109,13 @@ All components are stored with the same number of bits per component. - Cb, Cr - No - 16x16 tiles + * - V4L2_PIX_FMT_P010 + - 'P010' + - 10 + - 4:2:0 + - Cb, Cr + - Yes + - Linear * - V4L2_PIX_FMT_NV16 - 'NV16' - 8 @@ -171,6 +178,7 @@ horizontally. .. _V4L2-PIX-FMT-NV21: .. _V4L2-PIX-FMT-NV12M: .. _V4L2-PIX-FMT-NV21M: +.. _V4L2-PIX-FMT-P010: NV12, NV21, NV12M and NV21M --------------------------- @@ -519,6 +527,52 @@ number of lines as the luma plane. - Cb\ :sub:`33` - Cr\ :sub:`33` +.. _V4L2_PIX_FMT_P010: + +P010 +---- + +Like NV12 with 10 bits per component, expanded to 16 bits. +Data in the 10 high bits, zeros in the 6 low bits, arranged in little endian order. + +.. flat-table:: Sample 4x4 P010 Image + :header-rows: 0 + :stub-columns: 0 + + * - start + 0: + - Y'\ :sub:`00` + - Y'\ :sub:`01` + - Y'\ :sub:`02` + - Y'\ :sub:`03` + * - start + 8: + - Y'\ :sub:`10` + - Y'\ :sub:`11` + - Y'\ :sub:`12` + - Y'\ :sub:`13` + * - start + 16: + - Y'\ :sub:`20` + - Y'\ :sub:`21` + - Y'\ :sub:`22` + - Y'\ :sub:`23` + * - start + 24: + - Y'\ :sub:`30` + - Y'\ :sub:`31` + - Y'\ :sub:`32` + - Y'\ :sub:`33` + * - start + 32: + - Cb\ :sub:`00` + - Cr\ :sub:`00` + - Cb\ :sub:`01` + - Cr\ :sub:`01` + * - start + 40: + - Cb\ :sub:`10` + - Cr\ :sub:`10` + - Cb\ :sub:`11` + - Cr\ :sub:`11` + +.. raw:: latex + + \endgroup Fully Planar YUV Formats ======================== diff --git a/drivers/media/cec/core/cec-adap.c b/drivers/media/cec/core/cec-adap.c index 8bf91b5a7d0e6..41a79293ee02d 100644 --- a/drivers/media/cec/core/cec-adap.c +++ b/drivers/media/cec/core/cec-adap.c @@ -1309,8 +1309,11 @@ static int cec_config_log_addr(struct cec_adapter *adap, * we assume that something is really weird and that it is not a * good idea to try and claim this logical address. */ - if (i == max_retries) + if (i == max_retries) { + dprintk(0, "polling for LA %u failed with tx_status=0x%04x\n", + log_addr, msg.tx_status); return 0; + } /* * Message not acknowledged, so this logical diff --git a/drivers/media/cec/platform/cros-ec/cros-ec-cec.c b/drivers/media/cec/platform/cros-ec/cros-ec-cec.c index 8c8d8fc5e63e6..25dc7309beab5 100644 --- a/drivers/media/cec/platform/cros-ec/cros-ec-cec.c +++ b/drivers/media/cec/platform/cros-ec/cros-ec-cec.c @@ -217,6 +217,8 @@ static const struct cec_dmi_match cec_dmi_match_table[] = { { "Google", "Fizz", "0000:00:02.0", "Port B" }, /* Google Brask */ { "Google", "Brask", "0000:00:02.0", "Port B" }, + /* Google Moli */ + { "Google", "Moli", "0000:00:02.0", "Port B" }, }; static struct device *cros_ec_cec_find_hdmi_dev(struct device *dev, diff --git a/drivers/media/common/v4l2-tpg/v4l2-tpg-core.c b/drivers/media/common/v4l2-tpg/v4l2-tpg-core.c index 7607b516a7c43..cb985de8ff72b 100644 --- a/drivers/media/common/v4l2-tpg/v4l2-tpg-core.c +++ b/drivers/media/common/v4l2-tpg/v4l2-tpg-core.c @@ -2402,6 +2402,44 @@ static void tpg_fill_plane_extras(const struct tpg_data *tpg, ((params->sav_eav_f ^ vact) << 1) | (hact ^ vact ^ params->sav_eav_f); } + if (tpg->insert_hdmi_video_guard_band) { + unsigned int i; + + switch (tpg->fourcc) { + case V4L2_PIX_FMT_BGR24: + case V4L2_PIX_FMT_RGB24: + for (i = 0; i < 3 * 4; i += 3) { + vbuf[i] = 0xab; + vbuf[i + 1] = 0x55; + vbuf[i + 2] = 0xab; + } + break; + case V4L2_PIX_FMT_RGB32: + case V4L2_PIX_FMT_ARGB32: + case V4L2_PIX_FMT_XRGB32: + case V4L2_PIX_FMT_BGRX32: + case V4L2_PIX_FMT_BGRA32: + for (i = 0; i < 4 * 4; i += 4) { + vbuf[i] = 0x00; + vbuf[i + 1] = 0xab; + vbuf[i + 2] = 0x55; + vbuf[i + 3] = 0xab; + } + break; + case V4L2_PIX_FMT_BGR32: + case V4L2_PIX_FMT_XBGR32: + case V4L2_PIX_FMT_ABGR32: + case V4L2_PIX_FMT_RGBX32: + case V4L2_PIX_FMT_RGBA32: + for (i = 0; i < 4 * 4; i += 4) { + vbuf[i] = 0xab; + vbuf[i + 1] = 0x55; + vbuf[i + 2] = 0xab; + vbuf[i + 3] = 0x00; + } + break; + } + } } static void tpg_fill_plane_pattern(const struct tpg_data *tpg, diff --git a/drivers/media/i2c/adv7180.c b/drivers/media/i2c/adv7180.c index e3a57c178c6b6..5fde5243722d7 100644 --- a/drivers/media/i2c/adv7180.c +++ b/drivers/media/i2c/adv7180.c @@ -43,6 +43,7 @@ #define ADV7180_INPUT_CONTROL_INSEL_MASK 0x0f #define ADV7182_REG_INPUT_VIDSEL 0x0002 +#define ADV7182_REG_INPUT_RESERVED BIT(2) #define ADV7180_REG_OUTPUT_CONTROL 0x0003 #define ADV7180_REG_EXTENDED_OUTPUT_CONTROL 0x0004 @@ -1060,7 +1061,9 @@ static int adv7182_init(struct adv7180_state *state) static int adv7182_set_std(struct adv7180_state *state, unsigned int std) { - return adv7180_write(state, ADV7182_REG_INPUT_VIDSEL, std << 4); + /* Failing to set the reserved bit can result in increased video noise */ + return adv7180_write(state, ADV7182_REG_INPUT_VIDSEL, + (std << 4) | ADV7182_REG_INPUT_RESERVED); } enum adv7182_input_type { diff --git a/drivers/media/i2c/adv7604.c b/drivers/media/i2c/adv7604.c index bb0c8fc6d3832..497419a5cfddd 100644 --- a/drivers/media/i2c/adv7604.c +++ b/drivers/media/i2c/adv7604.c @@ -2505,9 +2505,8 @@ static void adv76xx_log_infoframes(struct v4l2_subdev *sd) union hdmi_infoframe frame; struct i2c_client *client = v4l2_get_subdevdata(sd); - if (adv76xx_read_infoframe(sd, i, &frame)) - return; - hdmi_infoframe_log(KERN_INFO, &client->dev, &frame); + if (!adv76xx_read_infoframe(sd, i, &frame)) + hdmi_infoframe_log(KERN_INFO, &client->dev, &frame); } } diff --git a/drivers/media/i2c/tda1997x.c b/drivers/media/i2c/tda1997x.c index 8fafce26d62fa..0de7acdf58a73 100644 --- a/drivers/media/i2c/tda1997x.c +++ b/drivers/media/i2c/tda1997x.c @@ -2798,6 +2798,7 @@ err_free_mutex: cancel_delayed_work(&state->delayed_work_enable_hpd); mutex_destroy(&state->page_lock); mutex_destroy(&state->lock); + tda1997x_set_power(state, 0); err_free_state: kfree(state); dev_err(&client->dev, "%s failed: %d\n", __func__, ret); diff --git a/drivers/media/pci/cx88/cx88-core.c b/drivers/media/pci/cx88/cx88-core.c index 89d4d5a3ba34c..52be42f9a7fac 100644 --- a/drivers/media/pci/cx88/cx88-core.c +++ b/drivers/media/pci/cx88/cx88-core.c @@ -618,12 +618,24 @@ EXPORT_SYMBOL(cx88_reset); static inline unsigned int norm_swidth(v4l2_std_id norm) { - return (norm & (V4L2_STD_MN & ~V4L2_STD_PAL_Nc)) ? 754 : 922; + if (norm & (V4L2_STD_NTSC | V4L2_STD_PAL_M)) + return 754; + + if (norm & V4L2_STD_PAL_Nc) + return 745; + + return 922; } static inline unsigned int norm_hdelay(v4l2_std_id norm) { - return (norm & (V4L2_STD_MN & ~V4L2_STD_PAL_Nc)) ? 135 : 186; + if (norm & (V4L2_STD_NTSC | V4L2_STD_PAL_M)) + return 135; + + if (norm & V4L2_STD_PAL_Nc) + return 149; + + return 186; } static inline unsigned int norm_vdelay(v4l2_std_id norm) @@ -636,7 +648,7 @@ static inline unsigned int norm_fsc8(v4l2_std_id norm) if (norm & V4L2_STD_PAL_M) return 28604892; // 3.575611 MHz - if (norm & (V4L2_STD_PAL_Nc)) + if (norm & V4L2_STD_PAL_Nc) return 28656448; // 3.582056 MHz if (norm & V4L2_STD_NTSC) // All NTSC/M and variants @@ -841,8 +853,8 @@ static int set_tvaudio(struct cx88_core *core) } else if (V4L2_STD_SECAM_DK & norm) { core->tvaudio = WW_DK; - } else if ((V4L2_STD_NTSC_M & norm) || - (V4L2_STD_PAL_M & norm)) { + } else if ((V4L2_STD_NTSC_M | V4L2_STD_PAL_M | V4L2_STD_PAL_Nc) & + norm) { core->tvaudio = WW_BTSC; } else if (V4L2_STD_NTSC_M_JP & norm) { diff --git a/drivers/media/pci/tw5864/tw5864-core.c b/drivers/media/pci/tw5864/tw5864-core.c index 5cae73e6fb9c7..560ff1ddcc838 100644 --- a/drivers/media/pci/tw5864/tw5864-core.c +++ b/drivers/media/pci/tw5864/tw5864-core.c @@ -254,9 +254,9 @@ static int tw5864_initdev(struct pci_dev *pci_dev, /* pci init */ dev->pci = pci_dev; - err = pci_enable_device(pci_dev); + err = pcim_enable_device(pci_dev); if (err) { - dev_err(&dev->pci->dev, "pci_enable_device() failed\n"); + dev_err(&dev->pci->dev, "pcim_enable_device() failed\n"); goto unreg_v4l2; } @@ -265,21 +265,16 @@ static int tw5864_initdev(struct pci_dev *pci_dev, err = dma_set_mask(&pci_dev->dev, DMA_BIT_MASK(32)); if (err) { dev_err(&dev->pci->dev, "32 bit PCI DMA is not supported\n"); - goto disable_pci; + goto unreg_v4l2; } /* get mmio */ - err = pci_request_regions(pci_dev, dev->name); + err = pcim_iomap_regions(pci_dev, BIT(0), dev->name); if (err) { dev_err(&dev->pci->dev, "Cannot request regions for MMIO\n"); - goto disable_pci; - } - dev->mmio = pci_ioremap_bar(pci_dev, 0); - if (!dev->mmio) { - err = -EIO; - dev_err(&dev->pci->dev, "can't ioremap() MMIO memory\n"); - goto release_mmio; + goto unreg_v4l2; } + dev->mmio = pcim_iomap_table(pci_dev)[0]; spin_lock_init(&dev->slock); @@ -291,7 +286,7 @@ static int tw5864_initdev(struct pci_dev *pci_dev, err = tw5864_video_init(dev, video_nr); if (err) - goto unmap_mmio; + goto unreg_v4l2; /* get irq */ err = devm_request_irq(&pci_dev->dev, pci_dev->irq, tw5864_isr, @@ -308,12 +303,6 @@ static int tw5864_initdev(struct pci_dev *pci_dev, fini_video: tw5864_video_fini(dev); -unmap_mmio: - iounmap(dev->mmio); -release_mmio: - pci_release_regions(pci_dev); -disable_pci: - pci_disable_device(pci_dev); unreg_v4l2: v4l2_device_unregister(&dev->v4l2_dev); return err; @@ -331,11 +320,6 @@ static void tw5864_finidev(struct pci_dev *pci_dev) /* unregister */ tw5864_video_fini(dev); - /* release resources */ - iounmap(dev->mmio); - pci_release_regions(pci_dev); - pci_disable_device(pci_dev); - v4l2_device_unregister(&dev->v4l2_dev); } diff --git a/drivers/media/pci/tw686x/tw686x-core.c b/drivers/media/pci/tw686x/tw686x-core.c index 6676e069b515d..384d38754a4b1 100644 --- a/drivers/media/pci/tw686x/tw686x-core.c +++ b/drivers/media/pci/tw686x/tw686x-core.c @@ -315,13 +315,6 @@ static int tw686x_probe(struct pci_dev *pci_dev, spin_lock_init(&dev->lock); - err = request_irq(pci_dev->irq, tw686x_irq, IRQF_SHARED, - dev->name, dev); - if (err < 0) { - dev_err(&pci_dev->dev, "unable to request interrupt\n"); - goto iounmap; - } - timer_setup(&dev->dma_delay_timer, tw686x_dma_delay, 0); /* @@ -333,18 +326,23 @@ static int tw686x_probe(struct pci_dev *pci_dev, err = tw686x_video_init(dev); if (err) { dev_err(&pci_dev->dev, "can't register video\n"); - goto free_irq; + goto iounmap; } err = tw686x_audio_init(dev); if (err) dev_warn(&pci_dev->dev, "can't register audio\n"); + err = request_irq(pci_dev->irq, tw686x_irq, IRQF_SHARED, + dev->name, dev); + if (err < 0) { + dev_err(&pci_dev->dev, "unable to request interrupt\n"); + goto iounmap; + } + pci_set_drvdata(pci_dev, dev); return 0; -free_irq: - free_irq(pci_dev->irq, dev); iounmap: pci_iounmap(pci_dev, dev->mmio); free_region: diff --git a/drivers/media/platform/amphion/vdec.c b/drivers/media/platform/amphion/vdec.c index 3c02aa2a54aa6..09d4f27970ec0 100644 --- a/drivers/media/platform/amphion/vdec.c +++ b/drivers/media/platform/amphion/vdec.c @@ -1369,8 +1369,7 @@ static void vdec_cleanup(struct vpu_inst *inst) return; vdec = inst->priv; - if (vdec) - vfree(vdec); + vfree(vdec); inst->priv = NULL; vfree(inst); } diff --git a/drivers/media/platform/amphion/venc.c b/drivers/media/platform/amphion/venc.c index 43d61d82f58c2..461524dd1e441 100644 --- a/drivers/media/platform/amphion/venc.c +++ b/drivers/media/platform/amphion/venc.c @@ -919,8 +919,7 @@ static void venc_cleanup(struct vpu_inst *inst) return; venc = inst->priv; - if (venc) - vfree(venc); + vfree(venc); inst->priv = NULL; vfree(inst); } diff --git a/drivers/media/platform/amphion/vpu_cmds.c b/drivers/media/platform/amphion/vpu_cmds.c index 9b39d77a178d7..f4d7ca78a6212 100644 --- a/drivers/media/platform/amphion/vpu_cmds.c +++ b/drivers/media/platform/amphion/vpu_cmds.c @@ -117,8 +117,7 @@ static void vpu_free_cmd(struct vpu_cmd_t *cmd) { if (!cmd) return; - if (cmd->pkt) - vfree(cmd->pkt); + vfree(cmd->pkt); vfree(cmd); } diff --git a/drivers/media/platform/amphion/vpu_core.c b/drivers/media/platform/amphion/vpu_core.c index 68ad183925fdb..3cca7ae2355d0 100644 --- a/drivers/media/platform/amphion/vpu_core.c +++ b/drivers/media/platform/amphion/vpu_core.c @@ -257,14 +257,8 @@ static int vpu_core_register(struct device *dev, struct vpu_core *core) } list_add_tail(&core->list, &vpu->cores); - vpu_core_get_vpu(core); - if (vpu_iface_get_power_state(core)) - ret = vpu_core_restore(core); - if (ret) - goto error; - return 0; error: if (core->msg_buffer) { @@ -362,7 +356,10 @@ struct vpu_core *vpu_request_core(struct vpu_dev *vpu, enum vpu_core_type type) pm_runtime_resume_and_get(core->dev); if (core->state == VPU_CORE_DEINIT) { - ret = vpu_core_boot(core, true); + if (vpu_iface_get_power_state(core)) + ret = vpu_core_restore(core); + else + ret = vpu_core_boot(core, true); if (ret) { pm_runtime_put_sync(core->dev); mutex_unlock(&core->lock); diff --git a/drivers/media/platform/amphion/vpu_dbg.c b/drivers/media/platform/amphion/vpu_dbg.c index da62bd718fb84..f72c8a506b220 100644 --- a/drivers/media/platform/amphion/vpu_dbg.c +++ b/drivers/media/platform/amphion/vpu_dbg.c @@ -27,7 +27,7 @@ struct print_buf_desc { u32 bytes; u32 read; u32 write; - char buffer[0]; + char buffer[]; }; static char *vb2_stat_name[] = { diff --git a/drivers/media/platform/amphion/vpu_malone.c b/drivers/media/platform/amphion/vpu_malone.c index f29c223eefced..c62b49e850604 100644 --- a/drivers/media/platform/amphion/vpu_malone.c +++ b/drivers/media/platform/amphion/vpu_malone.c @@ -309,6 +309,7 @@ struct malone_padding_scode { struct malone_fmt_mapping { u32 pixelformat; enum vpu_malone_format malone_format; + u32 is_disabled; }; struct malone_scode_t { @@ -568,6 +569,8 @@ static enum vpu_malone_format vpu_malone_format_remap(u32 pixelformat) u32 i; for (i = 0; i < ARRAY_SIZE(fmt_mappings); i++) { + if (fmt_mappings[i].is_disabled) + continue; if (pixelformat == fmt_mappings[i].pixelformat) return fmt_mappings[i].malone_format; } @@ -575,6 +578,19 @@ static enum vpu_malone_format vpu_malone_format_remap(u32 pixelformat) return MALONE_FMT_NULL; } +bool vpu_malone_check_fmt(enum vpu_core_type type, u32 pixelfmt) +{ + if (!vpu_imx8q_check_fmt(type, pixelfmt)) + return false; + + if (pixelfmt == V4L2_PIX_FMT_NV12M_8L128 || pixelfmt == V4L2_PIX_FMT_NV12M_10BE_8L128) + return true; + if (vpu_malone_format_remap(pixelfmt) == MALONE_FMT_NULL) + return false; + + return true; +} + static void vpu_malone_set_stream_cfg(struct vpu_shared_addr *shared, u32 instance, enum vpu_malone_format malone_format) @@ -610,6 +626,8 @@ static int vpu_malone_set_params(struct vpu_shared_addr *shared, enum vpu_malone_format malone_format; malone_format = vpu_malone_format_remap(params->codec_format); + if (WARN_ON(malone_format == MALONE_FMT_NULL)) + return -EINVAL; iface->udata_buffer[instance].base = params->udata.base; iface->udata_buffer[instance].slot_size = params->udata.size; diff --git a/drivers/media/platform/amphion/vpu_malone.h b/drivers/media/platform/amphion/vpu_malone.h index e5a5cbe9843e4..02a9d9530970f 100644 --- a/drivers/media/platform/amphion/vpu_malone.h +++ b/drivers/media/platform/amphion/vpu_malone.h @@ -40,5 +40,6 @@ int vpu_malone_pre_cmd(struct vpu_shared_addr *shared, u32 instance); int vpu_malone_post_cmd(struct vpu_shared_addr *shared, u32 instance); int vpu_malone_init_instance(struct vpu_shared_addr *shared, u32 instance); u32 vpu_malone_get_max_instance_count(struct vpu_shared_addr *shared); +bool vpu_malone_check_fmt(enum vpu_core_type type, u32 pixelfmt); #endif diff --git a/drivers/media/platform/amphion/vpu_rpc.c b/drivers/media/platform/amphion/vpu_rpc.c index 18a164766409d..676f7da041bda 100644 --- a/drivers/media/platform/amphion/vpu_rpc.c +++ b/drivers/media/platform/amphion/vpu_rpc.c @@ -195,7 +195,7 @@ static struct vpu_iface_ops imx8q_rpc_ops[] = { }, [VPU_CORE_TYPE_DEC] = { .check_codec = vpu_imx8q_check_codec, - .check_fmt = vpu_imx8q_check_fmt, + .check_fmt = vpu_malone_check_fmt, .boot_core = vpu_imx8q_boot_core, .get_power_state = vpu_imx8q_get_power_state, .on_firmware_loaded = vpu_imx8q_on_firmware_loaded, diff --git a/drivers/media/platform/amphion/vpu_v4l2.c b/drivers/media/platform/amphion/vpu_v4l2.c index 446f07d09d0bb..da455e5ab3376 100644 --- a/drivers/media/platform/amphion/vpu_v4l2.c +++ b/drivers/media/platform/amphion/vpu_v4l2.c @@ -500,10 +500,12 @@ static int vpu_vb2_start_streaming(struct vb2_queue *q, unsigned int count) fmt->sizeimage[1], fmt->bytesperline[1], fmt->sizeimage[2], fmt->bytesperline[2], q->num_buffers); - call_void_vop(inst, start, q->type); + ret = call_vop(inst, start, q->type); vb2_clear_last_buffer_dequeued(q); + if (ret) + vpu_vb2_buffers_return(inst, q->type, VB2_BUF_STATE_QUEUED); - return 0; + return ret; } static void vpu_vb2_stop_streaming(struct vb2_queue *q) diff --git a/drivers/media/platform/atmel/atmel-isc-base.c b/drivers/media/platform/atmel/atmel-isc-base.c index 2f07a50035c89..0d7d28004efb6 100644 --- a/drivers/media/platform/atmel/atmel-isc-base.c +++ b/drivers/media/platform/atmel/atmel-isc-base.c @@ -132,12 +132,9 @@ static int isc_buffer_prepare(struct vb2_buffer *vb) return 0; } -static void isc_start_dma(struct isc_device *isc) +static void isc_crop_pfe(struct isc_device *isc) { struct regmap *regmap = isc->regmap; - u32 sizeimage = isc->fmt.fmt.pix.sizeimage; - u32 dctrl_dview; - dma_addr_t addr0; u32 h, w; h = isc->fmt.fmt.pix.height; @@ -172,6 +169,14 @@ static void isc_start_dma(struct isc_device *isc) regmap_update_bits(regmap, ISC_PFE_CFG0, ISC_PFE_CFG0_COLEN | ISC_PFE_CFG0_ROWEN, ISC_PFE_CFG0_COLEN | ISC_PFE_CFG0_ROWEN); +} + +static void isc_start_dma(struct isc_device *isc) +{ + struct regmap *regmap = isc->regmap; + u32 sizeimage = isc->fmt.fmt.pix.sizeimage; + u32 dctrl_dview; + dma_addr_t addr0; addr0 = vb2_dma_contig_plane_dma_addr(&isc->cur_frm->vb.vb2_buf, 0); regmap_write(regmap, ISC_DAD0 + isc->offsets.dma, addr0); @@ -369,6 +374,7 @@ static int isc_start_streaming(struct vb2_queue *vq, unsigned int count) struct isc_buffer, list); list_del(&isc->cur_frm->list); + isc_crop_pfe(isc); isc_start_dma(isc); spin_unlock_irqrestore(&isc->dma_queue_lock, flags); @@ -1466,7 +1472,7 @@ static void isc_awb_work(struct work_struct *w) if (isc->stop) { mutex_unlock(&isc->awb_mutex); return; - }; + } isc_update_profile(isc); diff --git a/drivers/media/platform/atmel/atmel-sama7g5-isc.c b/drivers/media/platform/atmel/atmel-sama7g5-isc.c index 83b175070c067..8b11aa8340d7e 100644 --- a/drivers/media/platform/atmel/atmel-sama7g5-isc.c +++ b/drivers/media/platform/atmel/atmel-sama7g5-isc.c @@ -591,11 +591,13 @@ static const struct dev_pm_ops microchip_xisc_dev_pm_ops = { SET_RUNTIME_PM_OPS(xisc_runtime_suspend, xisc_runtime_resume, NULL) }; +#if IS_ENABLED(CONFIG_OF) static const struct of_device_id microchip_xisc_of_match[] = { { .compatible = "microchip,sama7g5-isc" }, { } }; MODULE_DEVICE_TABLE(of, microchip_xisc_of_match); +#endif static struct platform_driver microchip_xisc_driver = { .probe = microchip_xisc_probe, diff --git a/drivers/media/platform/mediatek/jpeg/mtk_jpeg_core.c b/drivers/media/platform/mediatek/jpeg/mtk_jpeg_core.c index bc5b0a0168ec0..87685a62a5c23 100644 --- a/drivers/media/platform/mediatek/jpeg/mtk_jpeg_core.c +++ b/drivers/media/platform/mediatek/jpeg/mtk_jpeg_core.c @@ -1369,6 +1369,9 @@ static int mtk_jpeg_probe(struct platform_device *pdev) jpeg->vdev->device_caps = V4L2_CAP_STREAMING | V4L2_CAP_VIDEO_M2M_MPLANE; + if (of_get_property(pdev->dev.of_node, "dma-ranges", NULL)) + dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(34)); + ret = video_register_device(jpeg->vdev, VFL_TYPE_VIDEO, -1); if (ret) { v4l2_err(&jpeg->v4l2_dev, "Failed to register video device\n"); diff --git a/drivers/media/platform/mediatek/vcodec/mtk_vcodec_dec.c b/drivers/media/platform/mediatek/vcodec/mtk_vcodec_dec.c index 52e5d36aa912c..61412d0eeb339 100644 --- a/drivers/media/platform/mediatek/vcodec/mtk_vcodec_dec.c +++ b/drivers/media/platform/mediatek/vcodec/mtk_vcodec_dec.c @@ -35,6 +35,44 @@ mtk_vdec_find_format(struct v4l2_format *f, return NULL; } +static bool mtk_vdec_get_cap_fmt(struct mtk_vcodec_ctx *ctx, int format_index) +{ + const struct mtk_vcodec_dec_pdata *dec_pdata = ctx->dev->vdec_pdata; + const struct mtk_video_fmt *fmt; + struct mtk_q_data *q_data; + int num_frame_count = 0, i; + bool ret = true; + + for (i = 0; i < *dec_pdata->num_formats; i++) { + if (dec_pdata->vdec_formats[i].type != MTK_FMT_FRAME) + continue; + + num_frame_count++; + } + + if (num_frame_count == 1) + return true; + + fmt = &dec_pdata->vdec_formats[format_index]; + q_data = &ctx->q_data[MTK_Q_DATA_SRC]; + switch (q_data->fmt->fourcc) { + case V4L2_PIX_FMT_VP8_FRAME: + if (fmt->fourcc == V4L2_PIX_FMT_MM21) + ret = true; + break; + case V4L2_PIX_FMT_H264_SLICE: + case V4L2_PIX_FMT_VP9_FRAME: + if (fmt->fourcc == V4L2_PIX_FMT_MM21) + ret = false; + break; + default: + ret = true; + break; + }; + + return ret; +} + static struct mtk_q_data *mtk_vdec_get_q_data(struct mtk_vcodec_ctx *ctx, enum v4l2_buf_type type) { @@ -566,6 +604,9 @@ static int vidioc_enum_fmt(struct v4l2_fmtdesc *f, void *priv, dec_pdata->vdec_formats[i].type != MTK_FMT_FRAME) continue; + if (!output_queue && !mtk_vdec_get_cap_fmt(ctx, i)) + continue; + if (j == f->index) break; ++j; @@ -938,6 +979,7 @@ int mtk_vcodec_dec_queue_init(void *priv, struct vb2_queue *src_vq, src_vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY; src_vq->lock = &ctx->dev->dev_mutex; src_vq->dev = &ctx->dev->plat_dev->dev; + src_vq->allow_cache_hints = 1; ret = vb2_queue_init(src_vq); if (ret) { @@ -953,6 +995,7 @@ int mtk_vcodec_dec_queue_init(void *priv, struct vb2_queue *src_vq, dst_vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY; dst_vq->lock = &ctx->dev->dev_mutex; dst_vq->dev = &ctx->dev->plat_dev->dev; + dst_vq->allow_cache_hints = 1; ret = vb2_queue_init(dst_vq); if (ret) diff --git a/drivers/media/platform/mediatek/vcodec/mtk_vcodec_dec_drv.c b/drivers/media/platform/mediatek/vcodec/mtk_vcodec_dec_drv.c index 995e6e2fb1ab2..3f63abbf289e0 100644 --- a/drivers/media/platform/mediatek/vcodec/mtk_vcodec_dec_drv.c +++ b/drivers/media/platform/mediatek/vcodec/mtk_vcodec_dec_drv.c @@ -388,6 +388,10 @@ static int mtk_vcodec_probe(struct platform_device *pdev) } } + atomic_set(&dev->dec_active_cnt, 0); + memset(dev->vdec_racing_info, 0, sizeof(dev->vdec_racing_info)); + mutex_init(&dev->dec_racing_info_mutex); + ret = video_register_device(vfd_dec, VFL_TYPE_VIDEO, -1); if (ret) { mtk_v4l2_err("Failed to register video device"); @@ -465,6 +469,10 @@ static const struct of_device_id mtk_vcodec_match[] = { .compatible = "mediatek,mt8186-vcodec-dec", .data = &mtk_vdec_single_core_pdata, }, + { + .compatible = "mediatek,mt8195-vcodec-dec", + .data = &mtk_lat_sig_core_pdata, + }, {}, }; diff --git a/drivers/media/platform/mediatek/vcodec/mtk_vcodec_dec_hw.c b/drivers/media/platform/mediatek/vcodec/mtk_vcodec_dec_hw.c index 14bed2bd4283d..376db0e433d75 100644 --- a/drivers/media/platform/mediatek/vcodec/mtk_vcodec_dec_hw.c +++ b/drivers/media/platform/mediatek/vcodec/mtk_vcodec_dec_hw.c @@ -28,6 +28,10 @@ static const struct of_device_id mtk_vdec_hw_match[] = { .compatible = "mediatek,mtk-vcodec-core", .data = (void *)MTK_VDEC_CORE, }, + { + .compatible = "mediatek,mtk-vcodec-lat-soc", + .data = (void *)MTK_VDEC_LAT_SOC, + }, {}, }; MODULE_DEVICE_TABLE(of, mtk_vdec_hw_match); @@ -166,9 +170,11 @@ static int mtk_vdec_hw_probe(struct platform_device *pdev) subdev_dev->reg_base[VDEC_HW_SYS] = main_dev->reg_base[VDEC_HW_SYS]; set_bit(subdev_dev->hw_idx, main_dev->subdev_bitmap); - ret = mtk_vdec_hw_init_irq(subdev_dev); - if (ret) - goto err; + if (IS_SUPPORT_VDEC_HW_IRQ(hw_idx)) { + ret = mtk_vdec_hw_init_irq(subdev_dev); + if (ret) + goto err; + } subdev_dev->reg_base[VDEC_HW_MISC] = devm_platform_ioremap_resource(pdev, 0); diff --git a/drivers/media/platform/mediatek/vcodec/mtk_vcodec_dec_hw.h b/drivers/media/platform/mediatek/vcodec/mtk_vcodec_dec_hw.h index a63e4b1b81c3e..36faa8d9d681b 100644 --- a/drivers/media/platform/mediatek/vcodec/mtk_vcodec_dec_hw.h +++ b/drivers/media/platform/mediatek/vcodec/mtk_vcodec_dec_hw.h @@ -17,6 +17,8 @@ #define VDEC_IRQ_CLR 0x10 #define VDEC_IRQ_CFG_REG 0xa4 +#define IS_SUPPORT_VDEC_HW_IRQ(hw_idx) ((hw_idx) != MTK_VDEC_LAT_SOC) + /** * enum mtk_vdec_hw_reg_idx - subdev hardware register base index * @VDEC_HW_SYS : vdec soc register index diff --git a/drivers/media/platform/mediatek/vcodec/mtk_vcodec_dec_pm.c b/drivers/media/platform/mediatek/vcodec/mtk_vcodec_dec_pm.c index 0fb7e5ba635b4..4305e4eb9900d 100644 --- a/drivers/media/platform/mediatek/vcodec/mtk_vcodec_dec_pm.c +++ b/drivers/media/platform/mediatek/vcodec/mtk_vcodec_dec_pm.c @@ -144,6 +144,34 @@ static void mtk_vcodec_dec_disable_irq(struct mtk_vcodec_dev *vdec_dev, int hw_i } } +static void mtk_vcodec_load_racing_info(struct mtk_vcodec_ctx *ctx) +{ + void __iomem *vdec_racing_addr; + int j; + + mutex_lock(&ctx->dev->dec_racing_info_mutex); + if (atomic_inc_return(&ctx->dev->dec_active_cnt) == 1) { + vdec_racing_addr = ctx->dev->reg_base[VDEC_MISC] + 0x100; + for (j = 0; j < 132; j++) + writel(ctx->dev->vdec_racing_info[j], vdec_racing_addr + j * 4); + } + mutex_unlock(&ctx->dev->dec_racing_info_mutex); +} + +static void mtk_vcodec_record_racing_info(struct mtk_vcodec_ctx *ctx) +{ + void __iomem *vdec_racing_addr; + int j; + + mutex_lock(&ctx->dev->dec_racing_info_mutex); + if (atomic_dec_and_test(&ctx->dev->dec_active_cnt)) { + vdec_racing_addr = ctx->dev->reg_base[VDEC_MISC] + 0x100; + for (j = 0; j < 132; j++) + ctx->dev->vdec_racing_info[j] = readl(vdec_racing_addr + j * 4); + } + mutex_unlock(&ctx->dev->dec_racing_info_mutex); +} + static struct mtk_vcodec_pm *mtk_vcodec_dec_get_pm(struct mtk_vcodec_dev *vdec_dev, int hw_idx) { @@ -174,6 +202,14 @@ static void mtk_vcodec_dec_child_dev_on(struct mtk_vcodec_dev *vdec_dev, mtk_vcodec_dec_pw_on(pm); mtk_vcodec_dec_clock_on(pm); } + + if (hw_idx == MTK_VDEC_LAT0) { + pm = mtk_vcodec_dec_get_pm(vdec_dev, MTK_VDEC_LAT_SOC); + if (pm) { + mtk_vcodec_dec_pw_on(pm); + mtk_vcodec_dec_clock_on(pm); + } + } } static void mtk_vcodec_dec_child_dev_off(struct mtk_vcodec_dev *vdec_dev, @@ -186,6 +222,14 @@ static void mtk_vcodec_dec_child_dev_off(struct mtk_vcodec_dev *vdec_dev, mtk_vcodec_dec_clock_off(pm); mtk_vcodec_dec_pw_off(pm); } + + if (hw_idx == MTK_VDEC_LAT0) { + pm = mtk_vcodec_dec_get_pm(vdec_dev, MTK_VDEC_LAT_SOC); + if (pm) { + mtk_vcodec_dec_clock_off(pm); + mtk_vcodec_dec_pw_off(pm); + } + } } void mtk_vcodec_dec_enable_hardware(struct mtk_vcodec_ctx *ctx, int hw_idx) @@ -198,11 +242,17 @@ void mtk_vcodec_dec_enable_hardware(struct mtk_vcodec_ctx *ctx, int hw_idx) mtk_vcodec_dec_child_dev_on(ctx->dev, hw_idx); mtk_vcodec_dec_enable_irq(ctx->dev, hw_idx); + + if (IS_VDEC_INNER_RACING(ctx->dev->dec_capability)) + mtk_vcodec_load_racing_info(ctx); } EXPORT_SYMBOL_GPL(mtk_vcodec_dec_enable_hardware); void mtk_vcodec_dec_disable_hardware(struct mtk_vcodec_ctx *ctx, int hw_idx) { + if (IS_VDEC_INNER_RACING(ctx->dev->dec_capability)) + mtk_vcodec_record_racing_info(ctx); + mtk_vcodec_dec_disable_irq(ctx->dev, hw_idx); mtk_vcodec_dec_child_dev_off(ctx->dev, hw_idx); diff --git a/drivers/media/platform/mediatek/vcodec/mtk_vcodec_drv.h b/drivers/media/platform/mediatek/vcodec/mtk_vcodec_drv.h index a29041a0b7e00..dc6aada882d9b 100644 --- a/drivers/media/platform/mediatek/vcodec/mtk_vcodec_drv.h +++ b/drivers/media/platform/mediatek/vcodec/mtk_vcodec_drv.h @@ -28,6 +28,7 @@ #define MTK_V4L2_BENCHMARK 0 #define WAIT_INTR_TIMEOUT_MS 1000 #define IS_VDEC_LAT_ARCH(hw_arch) ((hw_arch) >= MTK_VDEC_LAT_SINGLE_CORE) +#define IS_VDEC_INNER_RACING(capability) ((capability) & MTK_VCODEC_INNER_RACING) /* * enum mtk_hw_reg_idx - MTK hw register base index @@ -104,6 +105,7 @@ enum mtk_vdec_hw_id { MTK_VDEC_CORE, MTK_VDEC_LAT0, MTK_VDEC_LAT1, + MTK_VDEC_LAT_SOC, MTK_VDEC_HW_MAX, }; @@ -255,7 +257,7 @@ struct vdec_pic_info { * @param_change: indicate encode parameter type * @enc_params: encoding parameters * @dec_if: hooked decoder driver interface - * @enc_if: hoooked encoder driver interface + * @enc_if: hooked encoder driver interface * @drv_handle: driver handle for specific decode/encode instance * * @picinfo: store picture info after header parsing @@ -356,6 +358,7 @@ enum mtk_vdec_format_types { MTK_VDEC_FORMAT_H264_SLICE = 0x100, MTK_VDEC_FORMAT_VP8_FRAME = 0x200, MTK_VDEC_FORMAT_VP9_FRAME = 0x400, + MTK_VCODEC_INNER_RACING = 0x20000, }; /** @@ -477,6 +480,10 @@ struct mtk_vcodec_enc_pdata { * @subdev_dev: subdev hardware device * @subdev_prob_done: check whether all used hw device is prob done * @subdev_bitmap: used to record hardware is ready or not + * + * @dec_active_cnt: used to mark whether need to record register value + * @vdec_racing_info: record register value + * @dec_racing_info_mutex: mutex lock used for inner racing mode */ struct mtk_vcodec_dev { struct v4l2_device v4l2_dev; @@ -522,6 +529,11 @@ struct mtk_vcodec_dev { void *subdev_dev[MTK_VDEC_HW_MAX]; int (*subdev_prob_done)(struct mtk_vcodec_dev *vdec_dev); DECLARE_BITMAP(subdev_bitmap, MTK_VDEC_HW_MAX); + + atomic_t dec_active_cnt; + u32 vdec_racing_info[132]; + /* Protects access to vdec_racing_info data */ + struct mutex dec_racing_info_mutex; }; static inline struct mtk_vcodec_ctx *fh_to_ctx(struct v4l2_fh *fh) diff --git a/drivers/media/platform/mediatek/vcodec/vdec/vdec_h264_req_multi_if.c b/drivers/media/platform/mediatek/vcodec/vdec/vdec_h264_req_multi_if.c index 784d01f8bd50f..4cc92700692b3 100644 --- a/drivers/media/platform/mediatek/vcodec/vdec/vdec_h264_req_multi_if.c +++ b/drivers/media/platform/mediatek/vcodec/vdec/vdec_h264_req_multi_if.c @@ -633,6 +633,17 @@ static int vdec_h264_slice_lat_decode(void *h_vdec, struct mtk_vcodec_mem *bs, goto err_scp_decode; } + share_info->trans_end = inst->ctx->msg_queue.wdma_addr.dma_addr + + inst->vsi->wdma_end_addr_offset; + share_info->trans_start = inst->ctx->msg_queue.wdma_wptr_addr; + share_info->nal_info = inst->vsi->dec.nal_info; + + if (IS_VDEC_INNER_RACING(inst->ctx->dev->dec_capability)) { + memcpy(&share_info->h264_slice_params, &inst->vsi->h264_slice_params, + sizeof(share_info->h264_slice_params)); + vdec_msg_queue_qbuf(&inst->ctx->dev->msg_queue_core_ctx, lat_buf); + } + /* wait decoder done interrupt */ timeout = mtk_vcodec_wait_for_done_ctx(inst->ctx, MTK_INST_IRQ_RECEIVED, WAIT_INTR_TIMEOUT_MS, MTK_VDEC_LAT0); @@ -646,18 +657,22 @@ static int vdec_h264_slice_lat_decode(void *h_vdec, struct mtk_vcodec_mem *bs, share_info->trans_end = inst->ctx->msg_queue.wdma_addr.dma_addr + inst->vsi->wdma_end_addr_offset; - share_info->trans_start = inst->ctx->msg_queue.wdma_wptr_addr; - share_info->nal_info = inst->vsi->dec.nal_info; vdec_msg_queue_update_ube_wptr(&lat_buf->ctx->msg_queue, share_info->trans_end); - memcpy(&share_info->h264_slice_params, &inst->vsi->h264_slice_params, - sizeof(share_info->h264_slice_params)); - vdec_msg_queue_qbuf(&inst->ctx->dev->msg_queue_core_ctx, lat_buf); + if (!IS_VDEC_INNER_RACING(inst->ctx->dev->dec_capability)) { + memcpy(&share_info->h264_slice_params, &inst->vsi->h264_slice_params, + sizeof(share_info->h264_slice_params)); + vdec_msg_queue_qbuf(&inst->ctx->dev->msg_queue_core_ctx, lat_buf); + } + mtk_vcodec_debug(inst, "dec num: %d lat crc: 0x%x 0x%x 0x%x", inst->slice_dec_num, + inst->vsi->dec.crc[0], inst->vsi->dec.crc[1], inst->vsi->dec.crc[2]); inst->slice_dec_num++; return 0; err_scp_decode: + if (!IS_VDEC_INNER_RACING(inst->ctx->dev->dec_capability)) + vdec_msg_queue_qbuf(&inst->ctx->msg_queue.lat_ctx, lat_buf); err_free_fb_out: vdec_msg_queue_qbuf(&inst->ctx->msg_queue.lat_ctx, lat_buf); mtk_vcodec_err(inst, "slice dec number: %d err: %d", inst->slice_dec_num, err); diff --git a/drivers/media/platform/mediatek/vcodec/vdec/vdec_vp9_req_lat_if.c b/drivers/media/platform/mediatek/vcodec/vdec/vdec_vp9_req_lat_if.c index 023aba4ec2c43..f464af190d8ca 100644 --- a/drivers/media/platform/mediatek/vcodec/vdec/vdec_vp9_req_lat_if.c +++ b/drivers/media/platform/mediatek/vcodec/vdec/vdec_vp9_req_lat_if.c @@ -439,6 +439,8 @@ struct vdec_vp9_slice_ref { * @init_vsi: vsi used for initialized VP9 instance * @vsi: vsi used for decoding/flush ... * @core_vsi: vsi used for Core stage + * + * @sc_pfc: per frame context single core * @counts_map: used map to counts_helper * @counts_helper: counts table according to newest kernel spec */ @@ -487,6 +489,7 @@ struct vdec_vp9_slice_instance { }; struct vdec_vp9_slice_vsi *core_vsi; + struct vdec_vp9_slice_pfc sc_pfc; struct vdec_vp9_slice_counts_map counts_map; struct v4l2_vp9_frame_symbol_counts counts_helper; }; @@ -523,13 +526,12 @@ static int vdec_vp9_slice_init_default_frame_ctx(struct vdec_vp9_slice_instance if (vdec_vp9_slice_default_frame_ctx) goto out; - frame_ctx = kmalloc(sizeof(*frame_ctx), GFP_KERNEL); + frame_ctx = kmemdup(remote_frame_ctx, sizeof(*frame_ctx), GFP_KERNEL); if (!frame_ctx) { ret = -ENOMEM; goto out; } - memcpy(frame_ctx, remote_frame_ctx, sizeof(*frame_ctx)); vdec_vp9_slice_default_frame_ctx = frame_ctx; out: @@ -692,6 +694,25 @@ static int vdec_vp9_slice_tile_offset(int idx, int mi_num, int tile_log2) return offset < mi_num ? offset : mi_num; } +static +int vdec_vp9_slice_setup_single_from_src_to_dst(struct vdec_vp9_slice_instance *instance) +{ + struct vb2_v4l2_buffer *src; + struct vb2_v4l2_buffer *dst; + + src = v4l2_m2m_next_src_buf(instance->ctx->m2m_ctx); + if (!src) + return -EINVAL; + + dst = v4l2_m2m_next_dst_buf(instance->ctx->m2m_ctx); + if (!dst) + return -EINVAL; + + v4l2_m2m_buf_copy_metadata(src, dst, true); + + return 0; +} + static int vdec_vp9_slice_setup_lat_from_src_buf(struct vdec_vp9_slice_instance *instance, struct vdec_lat_buf *lat_buf) { @@ -1567,6 +1588,33 @@ static int vdec_vp9_slice_update_prob(struct vdec_vp9_slice_instance *instance, return 0; } +static int vdec_vp9_slice_update_single(struct vdec_vp9_slice_instance *instance, + struct vdec_vp9_slice_pfc *pfc) +{ + struct vdec_vp9_slice_vsi *vsi; + + vsi = &pfc->vsi; + memcpy(&pfc->state[0], &vsi->state, sizeof(vsi->state)); + + mtk_vcodec_debug(instance, "Frame %u Y_CRC %08x %08x %08x %08x\n", + pfc->seq, + vsi->state.crc[0], vsi->state.crc[1], + vsi->state.crc[2], vsi->state.crc[3]); + mtk_vcodec_debug(instance, "Frame %u C_CRC %08x %08x %08x %08x\n", + pfc->seq, + vsi->state.crc[4], vsi->state.crc[5], + vsi->state.crc[6], vsi->state.crc[7]); + + vdec_vp9_slice_update_prob(instance, vsi); + + instance->width = vsi->frame.uh.frame_width; + instance->height = vsi->frame.uh.frame_height; + instance->frame_type = vsi->frame.uh.frame_type; + instance->show_frame = vsi->frame.uh.show_frame; + + return 0; +} + static int vdec_vp9_slice_update_lat(struct vdec_vp9_slice_instance *instance, struct vdec_lat_buf *lat_buf, struct vdec_vp9_slice_pfc *pfc) @@ -1690,6 +1738,40 @@ static int vdec_vp9_slice_setup_core_buffer(struct vdec_vp9_slice_instance *inst return 0; } +static void vdec_vp9_slice_setup_single_buffer(struct vdec_vp9_slice_instance *instance, + struct vdec_vp9_slice_pfc *pfc, + struct vdec_vp9_slice_vsi *vsi, + struct mtk_vcodec_mem *bs, + struct vdec_fb *fb) +{ + int i; + + vsi->bs.buf.dma_addr = bs->dma_addr; + vsi->bs.buf.size = bs->size; + vsi->bs.frame.dma_addr = bs->dma_addr; + vsi->bs.frame.size = bs->size; + + for (i = 0; i < 2; i++) { + vsi->mv[i].dma_addr = instance->mv[i].dma_addr; + vsi->mv[i].size = instance->mv[i].size; + } + for (i = 0; i < 2; i++) { + vsi->seg[i].dma_addr = instance->seg[i].dma_addr; + vsi->seg[i].size = instance->seg[i].size; + } + vsi->tile.dma_addr = instance->tile.dma_addr; + vsi->tile.size = instance->tile.size; + vsi->prob.dma_addr = instance->prob.dma_addr; + vsi->prob.size = instance->prob.size; + vsi->counts.dma_addr = instance->counts.dma_addr; + vsi->counts.size = instance->counts.size; + + vsi->row_info.buf = 0; + vsi->row_info.size = 0; + + vdec_vp9_slice_setup_core_buffer(instance, pfc, vsi, fb, NULL); +} + static int vdec_vp9_slice_setup_core(struct vdec_vp9_slice_instance *instance, struct vdec_fb *fb, struct vdec_lat_buf *lat_buf, @@ -1716,6 +1798,43 @@ err: return ret; } +static int vdec_vp9_slice_setup_single(struct vdec_vp9_slice_instance *instance, + struct mtk_vcodec_mem *bs, + struct vdec_fb *fb, + struct vdec_vp9_slice_pfc *pfc) +{ + struct vdec_vp9_slice_vsi *vsi = &pfc->vsi; + int ret; + + ret = vdec_vp9_slice_setup_single_from_src_to_dst(instance); + if (ret) + goto err; + + ret = vdec_vp9_slice_setup_pfc(instance, pfc); + if (ret) + goto err; + + ret = vdec_vp9_slice_alloc_working_buffer(instance, vsi); + if (ret) + goto err; + + vdec_vp9_slice_setup_single_buffer(instance, pfc, vsi, bs, fb); + vdec_vp9_slice_setup_seg_buffer(instance, vsi, &instance->seg[0]); + + ret = vdec_vp9_slice_setup_prob_buffer(instance, vsi); + if (ret) + goto err; + + ret = vdec_vp9_slice_setup_tile_buffer(instance, vsi, bs); + if (ret) + goto err; + + return 0; + +err: + return ret; +} + static int vdec_vp9_slice_update_core(struct vdec_vp9_slice_instance *instance, struct vdec_lat_buf *lat_buf, struct vdec_vp9_slice_pfc *pfc) @@ -1813,8 +1932,8 @@ static int vdec_vp9_slice_flush(void *h_vdec, struct mtk_vcodec_mem *bs, struct vdec_vp9_slice_instance *instance = h_vdec; mtk_vcodec_debug(instance, "flush ...\n"); - - vdec_msg_queue_wait_lat_buf_full(&instance->ctx->msg_queue); + if (instance->ctx->dev->vdec_pdata->hw_arch != MTK_VDEC_PURE_SINGLE_CORE) + vdec_msg_queue_wait_lat_buf_full(&instance->ctx->msg_queue); return vpu_dec_reset(&instance->vpu); } @@ -1867,6 +1986,63 @@ static int vdec_vp9_slice_get_param(void *h_vdec, enum vdec_get_param_type type, return 0; } +static int vdec_vp9_slice_single_decode(void *h_vdec, struct mtk_vcodec_mem *bs, + struct vdec_fb *fb, bool *res_chg) +{ + struct vdec_vp9_slice_instance *instance = h_vdec; + struct vdec_vp9_slice_pfc *pfc = &instance->sc_pfc; + struct vdec_vp9_slice_vsi *vsi; + struct mtk_vcodec_ctx *ctx; + int ret; + + if (!instance || !instance->ctx) + return -EINVAL; + ctx = instance->ctx; + + /* bs NULL means flush decoder */ + if (!bs) + return vdec_vp9_slice_flush(h_vdec, bs, fb, res_chg); + + fb = ctx->dev->vdec_pdata->get_cap_buffer(ctx); + if (!fb) + return -EBUSY; + + vsi = &pfc->vsi; + + ret = vdec_vp9_slice_setup_single(instance, bs, fb, pfc); + if (ret) { + mtk_vcodec_err(instance, "Failed to setup VP9 single ret %d\n", ret); + return ret; + } + vdec_vp9_slice_vsi_to_remote(vsi, instance->vsi); + + ret = vpu_dec_start(&instance->vpu, NULL, 0); + if (ret) { + mtk_vcodec_err(instance, "Failed to dec VP9 ret %d\n", ret); + return ret; + } + + ret = mtk_vcodec_wait_for_done_ctx(ctx, MTK_INST_IRQ_RECEIVED, + WAIT_INTR_TIMEOUT_MS, MTK_VDEC_CORE); + /* update remote vsi if decode timeout */ + if (ret) { + mtk_vcodec_err(instance, "VP9 decode timeout %d\n", ret); + WRITE_ONCE(instance->vsi->state.timeout, 1); + } + + vpu_dec_end(&instance->vpu); + + vdec_vp9_slice_vsi_from_remote(vsi, instance->vsi, 0); + ret = vdec_vp9_slice_update_single(instance, pfc); + if (ret) { + mtk_vcodec_err(instance, "VP9 decode error: %d\n", ret); + return ret; + } + + instance->ctx->decoded_frame_cnt++; + return 0; +} + static int vdec_vp9_slice_lat_decode(void *h_vdec, struct mtk_vcodec_mem *bs, struct vdec_fb *fb, bool *res_chg) { @@ -1946,6 +2122,20 @@ static int vdec_vp9_slice_lat_decode(void *h_vdec, struct mtk_vcodec_mem *bs, return 0; } +static int vdec_vp9_slice_decode(void *h_vdec, struct mtk_vcodec_mem *bs, + struct vdec_fb *fb, bool *res_chg) +{ + struct vdec_vp9_slice_instance *instance = h_vdec; + int ret; + + if (instance->ctx->dev->vdec_pdata->hw_arch == MTK_VDEC_PURE_SINGLE_CORE) + ret = vdec_vp9_slice_single_decode(h_vdec, bs, fb, res_chg); + else + ret = vdec_vp9_slice_lat_decode(h_vdec, bs, fb, res_chg); + + return ret; +} + static int vdec_vp9_slice_core_decode(struct vdec_lat_buf *lat_buf) { struct vdec_vp9_slice_instance *instance; @@ -2024,7 +2214,7 @@ err: const struct vdec_common_if vdec_vp9_slice_lat_if = { .init = vdec_vp9_slice_init, - .decode = vdec_vp9_slice_lat_decode, + .decode = vdec_vp9_slice_decode, .get_param = vdec_vp9_slice_get_param, .deinit = vdec_vp9_slice_deinit, }; diff --git a/drivers/media/platform/mediatek/vcodec/vdec_drv_if.c b/drivers/media/platform/mediatek/vcodec/vdec_drv_if.c index 27b4b35039cfa..f3807f03d8806 100644 --- a/drivers/media/platform/mediatek/vcodec/vdec_drv_if.c +++ b/drivers/media/platform/mediatek/vcodec/vdec_drv_if.c @@ -47,7 +47,7 @@ int vdec_if_init(struct mtk_vcodec_ctx *ctx, unsigned int fourcc) break; case V4L2_PIX_FMT_VP9_FRAME: ctx->dec_if = &vdec_vp9_slice_lat_if; - ctx->hw_id = MTK_VDEC_LAT0; + ctx->hw_id = IS_VDEC_LAT_ARCH(hw_arch) ? MTK_VDEC_LAT0 : MTK_VDEC_CORE; break; default: return -EINVAL; diff --git a/drivers/media/platform/mediatek/vcodec/vdec_vpu_if.c b/drivers/media/platform/mediatek/vcodec/vdec_vpu_if.c index 35f4d55830849..df309e8e93798 100644 --- a/drivers/media/platform/mediatek/vcodec/vdec_vpu_if.c +++ b/drivers/media/platform/mediatek/vcodec/vdec_vpu_if.c @@ -91,6 +91,11 @@ static void vpu_dec_ipi_handler(void *data, unsigned int len, void *priv) struct vdec_vpu_inst *vpu = (struct vdec_vpu_inst *) (unsigned long)msg->ap_inst_addr; + if (!vpu) { + mtk_v4l2_err("ap_inst_addr is NULL, did the SCP hang or crash?"); + return; + } + mtk_vcodec_debug(vpu, "+ id=%X", msg->msg_id); vpu->failure = msg->status; diff --git a/drivers/media/platform/nxp/imx-jpeg/mxc-jpeg-hw.c b/drivers/media/platform/nxp/imx-jpeg/mxc-jpeg-hw.c index 29c604b1b1790..c482228262a33 100644 --- a/drivers/media/platform/nxp/imx-jpeg/mxc-jpeg-hw.c +++ b/drivers/media/platform/nxp/imx-jpeg/mxc-jpeg-hw.c @@ -100,9 +100,6 @@ void mxc_jpeg_enc_mode_conf(struct device *dev, void __iomem *reg) /* all markers and segments */ writel(0x3ff, reg + CAST_CFG_MODE); - - /* quality factor */ - writel(0x4b, reg + CAST_QUALITY); } void mxc_jpeg_enc_mode_go(struct device *dev, void __iomem *reg) @@ -114,6 +111,14 @@ void mxc_jpeg_enc_mode_go(struct device *dev, void __iomem *reg) writel(0x140, reg + CAST_MODE); } +void mxc_jpeg_enc_set_quality(struct device *dev, void __iomem *reg, u8 quality) +{ + dev_dbg(dev, "CAST Encoder Quality %d...\n", quality); + + /* quality factor */ + writel(quality, reg + CAST_QUALITY); +} + void mxc_jpeg_dec_mode_go(struct device *dev, void __iomem *reg) { dev_dbg(dev, "CAST Decoder GO...\n"); diff --git a/drivers/media/platform/nxp/imx-jpeg/mxc-jpeg-hw.h b/drivers/media/platform/nxp/imx-jpeg/mxc-jpeg-hw.h index d838e875616c3..07655502f4bd0 100644 --- a/drivers/media/platform/nxp/imx-jpeg/mxc-jpeg-hw.h +++ b/drivers/media/platform/nxp/imx-jpeg/mxc-jpeg-hw.h @@ -53,10 +53,10 @@ #define CAST_REC_REGS_SEL CAST_STATUS4 #define CAST_LUMTH CAST_STATUS5 #define CAST_CHRTH CAST_STATUS6 -#define CAST_NOMFRSIZE_LO CAST_STATUS7 -#define CAST_NOMFRSIZE_HI CAST_STATUS8 -#define CAST_OFBSIZE_LO CAST_STATUS9 -#define CAST_OFBSIZE_HI CAST_STATUS10 +#define CAST_NOMFRSIZE_LO CAST_STATUS16 +#define CAST_NOMFRSIZE_HI CAST_STATUS17 +#define CAST_OFBSIZE_LO CAST_STATUS18 +#define CAST_OFBSIZE_HI CAST_STATUS19 #define MXC_MAX_SLOTS 1 /* TODO use all 4 slots*/ /* JPEG-Decoder Wrapper Slot Registers 0..3 */ @@ -119,6 +119,7 @@ int mxc_jpeg_enable(void __iomem *reg); void wait_frmdone(struct device *dev, void __iomem *reg); void mxc_jpeg_enc_mode_conf(struct device *dev, void __iomem *reg); void mxc_jpeg_enc_mode_go(struct device *dev, void __iomem *reg); +void mxc_jpeg_enc_set_quality(struct device *dev, void __iomem *reg, u8 quality); void mxc_jpeg_dec_mode_go(struct device *dev, void __iomem *reg); int mxc_jpeg_get_slot(void __iomem *reg); u32 mxc_jpeg_get_offset(void __iomem *reg, int slot); diff --git a/drivers/media/platform/nxp/imx-jpeg/mxc-jpeg.c b/drivers/media/platform/nxp/imx-jpeg/mxc-jpeg.c index f36b512bae51f..965021d3c7ef9 100644 --- a/drivers/media/platform/nxp/imx-jpeg/mxc-jpeg.c +++ b/drivers/media/platform/nxp/imx-jpeg/mxc-jpeg.c @@ -389,7 +389,6 @@ static int enum_fmt(const struct mxc_jpeg_fmt *mxc_formats, int n, if (i >= n) return -EINVAL; - strscpy(f->description, mxc_formats[i].name, sizeof(f->description)); f->pixelformat = mxc_formats[i].fourcc; return 0; @@ -520,6 +519,7 @@ static bool mxc_jpeg_alloc_slot_data(struct mxc_jpeg_dev *jpeg, GFP_ATOMIC); if (!cfg_stm) goto err; + memset(cfg_stm, 0, MXC_JPEG_MAX_CFG_STREAM); jpeg->slot_data[slot].cfg_stream_vaddr = cfg_stm; skip_alloc: @@ -558,6 +558,18 @@ static void mxc_jpeg_free_slot_data(struct mxc_jpeg_dev *jpeg, jpeg->slot_data[slot].used = false; } +static void mxc_jpeg_check_and_set_last_buffer(struct mxc_jpeg_ctx *ctx, + struct vb2_v4l2_buffer *src_buf, + struct vb2_v4l2_buffer *dst_buf) +{ + if (v4l2_m2m_is_last_draining_src_buf(ctx->fh.m2m_ctx, src_buf)) { + dst_buf->flags |= V4L2_BUF_FLAG_LAST; + v4l2_m2m_mark_stopped(ctx->fh.m2m_ctx); + notify_eos(ctx); + ctx->header_parsed = false; + } +} + static irqreturn_t mxc_jpeg_dec_irq(int irq, void *priv) { struct mxc_jpeg_dev *jpeg = priv; @@ -624,6 +636,7 @@ static irqreturn_t mxc_jpeg_dec_irq(int irq, void *priv) ctx->enc_state == MXC_JPEG_ENC_CONF) { ctx->enc_state = MXC_JPEG_ENCODING; dev_dbg(dev, "Encoder config finished. Start encoding...\n"); + mxc_jpeg_enc_set_quality(dev, reg, ctx->jpeg_quality); mxc_jpeg_enc_mode_go(dev, reg); goto job_unlock; } @@ -632,6 +645,7 @@ static irqreturn_t mxc_jpeg_dec_irq(int irq, void *priv) dev_dbg(dev, "Decoder DHT cfg finished. Start decoding...\n"); goto job_unlock; } + if (jpeg->mode == MXC_JPEG_ENCODE) { payload = readl(reg + MXC_SLOT_OFFSET(slot, SLOT_BUF_PTR)); vb2_set_plane_payload(&dst_buf->vb2_buf, 0, payload); @@ -660,6 +674,7 @@ static irqreturn_t mxc_jpeg_dec_irq(int irq, void *priv) buffers_done: jpeg->slot_data[slot].used = false; /* unused, but don't free */ + mxc_jpeg_check_and_set_last_buffer(ctx, src_buf, dst_buf); v4l2_m2m_src_buf_remove(ctx->fh.m2m_ctx); v4l2_m2m_dst_buf_remove(ctx->fh.m2m_ctx); v4l2_m2m_buf_done(src_buf, buf_state); @@ -755,7 +770,13 @@ static unsigned int mxc_jpeg_setup_cfg_stream(void *cfg_stream_vaddr, u32 fourcc, u16 w, u16 h) { - unsigned int offset = 0; + /* + * There is a hardware issue that first 128 bytes of configuration data + * can't be loaded correctly. + * To avoid this issue, we need to write the configuration from + * an offset which should be no less than 0x80 (128 bytes). + */ + unsigned int offset = 0x80; u8 *cfg = (u8 *)cfg_stream_vaddr; struct mxc_jpeg_sof *sof; struct mxc_jpeg_sos *sos; @@ -887,8 +908,8 @@ static void mxc_jpeg_config_enc_desc(struct vb2_buffer *out_buf, jpeg->slot_data[slot].cfg_stream_size = mxc_jpeg_setup_cfg_stream(cfg_stream_vaddr, q_data->fmt->fourcc, - q_data->w_adjusted, - q_data->h_adjusted); + q_data->w, + q_data->h); /* chain the config descriptor with the encoding descriptor */ cfg_desc->next_descpt_ptr = desc_handle | MXC_NXT_DESCPT_EN; @@ -970,7 +991,7 @@ static bool mxc_jpeg_source_change(struct mxc_jpeg_ctx *ctx, &q_data_cap->h_adjusted, q_data_cap->h_adjusted, /* adjust up */ MXC_JPEG_MAX_HEIGHT, - q_data_cap->fmt->v_align, + 0, 0); /* setup bytesperline/sizeimage for capture queue */ @@ -1027,6 +1048,7 @@ static void mxc_jpeg_device_run(void *priv) jpeg_src_buf->jpeg_parse_error = true; } if (jpeg_src_buf->jpeg_parse_error) { + mxc_jpeg_check_and_set_last_buffer(ctx, src_buf, dst_buf); v4l2_m2m_src_buf_remove(ctx->fh.m2m_ctx); v4l2_m2m_dst_buf_remove(ctx->fh.m2m_ctx); v4l2_m2m_buf_done(src_buf, VB2_BUF_STATE_ERROR); @@ -1077,45 +1099,33 @@ end: spin_unlock_irqrestore(&ctx->mxc_jpeg->hw_lock, flags); } -static void mxc_jpeg_set_last_buffer_dequeued(struct mxc_jpeg_ctx *ctx) -{ - struct vb2_queue *q; - - ctx->stopped = 1; - q = v4l2_m2m_get_dst_vq(ctx->fh.m2m_ctx); - if (!list_empty(&q->done_list)) - return; - - q->last_buffer_dequeued = true; - wake_up(&q->done_wq); - ctx->stopped = 0; - ctx->header_parsed = false; -} - static int mxc_jpeg_decoder_cmd(struct file *file, void *priv, struct v4l2_decoder_cmd *cmd) { struct v4l2_fh *fh = file->private_data; struct mxc_jpeg_ctx *ctx = mxc_jpeg_fh_to_ctx(fh); - struct device *dev = ctx->mxc_jpeg->dev; int ret; ret = v4l2_m2m_ioctl_try_decoder_cmd(file, fh, cmd); if (ret < 0) return ret; - if (cmd->cmd == V4L2_DEC_CMD_STOP) { - dev_dbg(dev, "Received V4L2_DEC_CMD_STOP"); - if (v4l2_m2m_num_src_bufs_ready(fh->m2m_ctx) == 0) { - /* No more src bufs, notify app EOS */ - notify_eos(ctx); - mxc_jpeg_set_last_buffer_dequeued(ctx); - } else { - /* will send EOS later*/ - ctx->stopping = 1; - } + if (!vb2_is_streaming(v4l2_m2m_get_src_vq(fh->m2m_ctx))) + return 0; + + ret = v4l2_m2m_ioctl_decoder_cmd(file, priv, cmd); + if (ret < 0) + return ret; + + if (cmd->cmd == V4L2_DEC_CMD_STOP && + v4l2_m2m_has_stopped(fh->m2m_ctx)) { + notify_eos(ctx); + ctx->header_parsed = false; } + if (cmd->cmd == V4L2_DEC_CMD_START && + v4l2_m2m_has_stopped(fh->m2m_ctx)) + vb2_clear_last_buffer_dequeued(&fh->m2m_ctx->cap_q_ctx.q); return 0; } @@ -1124,24 +1134,27 @@ static int mxc_jpeg_encoder_cmd(struct file *file, void *priv, { struct v4l2_fh *fh = file->private_data; struct mxc_jpeg_ctx *ctx = mxc_jpeg_fh_to_ctx(fh); - struct device *dev = ctx->mxc_jpeg->dev; int ret; ret = v4l2_m2m_ioctl_try_encoder_cmd(file, fh, cmd); if (ret < 0) return ret; - if (cmd->cmd == V4L2_ENC_CMD_STOP) { - dev_dbg(dev, "Received V4L2_ENC_CMD_STOP"); - if (v4l2_m2m_num_src_bufs_ready(fh->m2m_ctx) == 0) { - /* No more src bufs, notify app EOS */ - notify_eos(ctx); - mxc_jpeg_set_last_buffer_dequeued(ctx); - } else { - /* will send EOS later*/ - ctx->stopping = 1; - } - } + if (!vb2_is_streaming(v4l2_m2m_get_src_vq(fh->m2m_ctx)) || + !vb2_is_streaming(v4l2_m2m_get_dst_vq(fh->m2m_ctx))) + return 0; + + ret = v4l2_m2m_ioctl_encoder_cmd(file, fh, cmd); + if (ret < 0) + return 0; + + if (cmd->cmd == V4L2_ENC_CMD_STOP && + v4l2_m2m_has_stopped(fh->m2m_ctx)) + notify_eos(ctx); + + if (cmd->cmd == V4L2_ENC_CMD_START && + v4l2_m2m_has_stopped(fh->m2m_ctx)) + vb2_clear_last_buffer_dequeued(&fh->m2m_ctx->cap_q_ctx.q); return 0; } @@ -1154,18 +1167,30 @@ static int mxc_jpeg_queue_setup(struct vb2_queue *q, { struct mxc_jpeg_ctx *ctx = vb2_get_drv_priv(q); struct mxc_jpeg_q_data *q_data = NULL; + struct mxc_jpeg_q_data tmp_q; int i; q_data = mxc_jpeg_get_q_data(ctx, q->type); if (!q_data) return -EINVAL; + tmp_q.fmt = q_data->fmt; + tmp_q.w = q_data->w_adjusted; + tmp_q.h = q_data->h_adjusted; + for (i = 0; i < MXC_JPEG_MAX_PLANES; i++) { + tmp_q.bytesperline[i] = q_data->bytesperline[i]; + tmp_q.sizeimage[i] = q_data->sizeimage[i]; + } + mxc_jpeg_sizeimage(&tmp_q); + for (i = 0; i < MXC_JPEG_MAX_PLANES; i++) + tmp_q.sizeimage[i] = max(tmp_q.sizeimage[i], q_data->sizeimage[i]); + /* Handle CREATE_BUFS situation - *nplanes != 0 */ if (*nplanes) { if (*nplanes != q_data->fmt->colplanes) return -EINVAL; for (i = 0; i < *nplanes; i++) { - if (sizes[i] < q_data->sizeimage[i]) + if (sizes[i] < tmp_q.sizeimage[i]) return -EINVAL; } return 0; @@ -1174,7 +1199,7 @@ static int mxc_jpeg_queue_setup(struct vb2_queue *q, /* Handle REQBUFS situation */ *nplanes = q_data->fmt->colplanes; for (i = 0; i < *nplanes; i++) - sizes[i] = q_data->sizeimage[i]; + sizes[i] = tmp_q.sizeimage[i]; return 0; } @@ -1185,6 +1210,8 @@ static int mxc_jpeg_start_streaming(struct vb2_queue *q, unsigned int count) struct mxc_jpeg_q_data *q_data = mxc_jpeg_get_q_data(ctx, q->type); int ret; + v4l2_m2m_update_start_streaming_state(ctx->fh.m2m_ctx, q); + if (ctx->mxc_jpeg->mode == MXC_JPEG_DECODE && V4L2_TYPE_IS_CAPTURE(q->type)) ctx->source_change = 0; dev_dbg(ctx->mxc_jpeg->dev, "Start streaming ctx=%p", ctx); @@ -1216,11 +1243,15 @@ static void mxc_jpeg_stop_streaming(struct vb2_queue *q) break; v4l2_m2m_buf_done(vbuf, VB2_BUF_STATE_ERROR); } - pm_runtime_put_sync(&ctx->mxc_jpeg->pdev->dev); - if (V4L2_TYPE_IS_OUTPUT(q->type)) { - ctx->stopping = 0; - ctx->stopped = 0; + + v4l2_m2m_update_stop_streaming_state(ctx->fh.m2m_ctx, q); + if (V4L2_TYPE_IS_OUTPUT(q->type) && + v4l2_m2m_has_stopped(ctx->fh.m2m_ctx)) { + notify_eos(ctx); + ctx->header_parsed = false; } + + pm_runtime_put_sync(&ctx->mxc_jpeg->pdev->dev); } static int mxc_jpeg_valid_comp_id(struct device *dev, @@ -1374,11 +1405,6 @@ static int mxc_jpeg_parse(struct mxc_jpeg_ctx *ctx, struct vb2_buffer *vb) } q_data_out->w = header.frame.width; q_data_out->h = header.frame.height; - if (header.frame.width % 8 != 0 || header.frame.height % 8 != 0) { - dev_err(dev, "JPEG width or height not multiple of 8: %dx%d\n", - header.frame.width, header.frame.height); - return -EINVAL; - } if (header.frame.width > MXC_JPEG_MAX_WIDTH || header.frame.height > MXC_JPEG_MAX_HEIGHT) { dev_err(dev, "JPEG width or height should be <= 8192: %dx%d\n", @@ -1424,6 +1450,20 @@ static void mxc_jpeg_buf_queue(struct vb2_buffer *vb) struct mxc_jpeg_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue); struct mxc_jpeg_src_buf *jpeg_src_buf; + if (V4L2_TYPE_IS_CAPTURE(vb->vb2_queue->type) && + vb2_is_streaming(vb->vb2_queue) && + v4l2_m2m_dst_buf_is_last(ctx->fh.m2m_ctx)) { + struct mxc_jpeg_q_data *q_data; + + q_data = mxc_jpeg_get_q_data(ctx, vb->vb2_queue->type); + vbuf->field = V4L2_FIELD_NONE; + vbuf->sequence = q_data->sequence++; + v4l2_m2m_last_buffer_done(ctx->fh.m2m_ctx, vbuf); + notify_eos(ctx); + ctx->header_parsed = false; + return; + } + if (vb->vb2_queue->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) goto end; @@ -1472,24 +1512,11 @@ static int mxc_jpeg_buf_prepare(struct vb2_buffer *vb) return -EINVAL; } } - return 0; -} - -static void mxc_jpeg_buf_finish(struct vb2_buffer *vb) -{ - struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb); - struct mxc_jpeg_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue); - struct vb2_queue *q = vb->vb2_queue; - - if (V4L2_TYPE_IS_OUTPUT(vb->type)) - return; - if (!ctx->stopped) - return; - if (list_empty(&q->done_list)) { - vbuf->flags |= V4L2_BUF_FLAG_LAST; - ctx->stopped = 0; - ctx->header_parsed = false; + if (V4L2_TYPE_IS_CAPTURE(vb->vb2_queue->type)) { + vb2_set_plane_payload(vb, 0, 0); + vb2_set_plane_payload(vb, 1, 0); } + return 0; } static const struct vb2_ops mxc_jpeg_qops = { @@ -1498,7 +1525,6 @@ static const struct vb2_ops mxc_jpeg_qops = { .wait_finish = vb2_ops_wait_finish, .buf_out_validate = mxc_jpeg_buf_out_validate, .buf_prepare = mxc_jpeg_buf_prepare, - .buf_finish = mxc_jpeg_buf_finish, .start_streaming = mxc_jpeg_start_streaming, .stop_streaming = mxc_jpeg_stop_streaming, .buf_queue = mxc_jpeg_buf_queue, @@ -1563,6 +1589,56 @@ static void mxc_jpeg_set_default_params(struct mxc_jpeg_ctx *ctx) } } +static int mxc_jpeg_s_ctrl(struct v4l2_ctrl *ctrl) +{ + struct mxc_jpeg_ctx *ctx = + container_of(ctrl->handler, struct mxc_jpeg_ctx, ctrl_handler); + + switch (ctrl->id) { + case V4L2_CID_JPEG_COMPRESSION_QUALITY: + ctx->jpeg_quality = ctrl->val; + break; + default: + dev_err(ctx->mxc_jpeg->dev, "Invalid control, id = %d, val = %d\n", + ctrl->id, ctrl->val); + return -EINVAL; + } + + return 0; +} + +static const struct v4l2_ctrl_ops mxc_jpeg_ctrl_ops = { + .s_ctrl = mxc_jpeg_s_ctrl, +}; + +static void mxc_jpeg_encode_ctrls(struct mxc_jpeg_ctx *ctx) +{ + v4l2_ctrl_new_std(&ctx->ctrl_handler, &mxc_jpeg_ctrl_ops, + V4L2_CID_JPEG_COMPRESSION_QUALITY, 1, 100, 1, 75); +} + +static int mxc_jpeg_ctrls_setup(struct mxc_jpeg_ctx *ctx) +{ + int err; + + v4l2_ctrl_handler_init(&ctx->ctrl_handler, 2); + + if (ctx->mxc_jpeg->mode == MXC_JPEG_ENCODE) + mxc_jpeg_encode_ctrls(ctx); + + if (ctx->ctrl_handler.error) { + err = ctx->ctrl_handler.error; + + v4l2_ctrl_handler_free(&ctx->ctrl_handler); + return err; + } + + err = v4l2_ctrl_handler_setup(&ctx->ctrl_handler); + if (err) + v4l2_ctrl_handler_free(&ctx->ctrl_handler); + return err; +} + static int mxc_jpeg_open(struct file *file) { struct mxc_jpeg_dev *mxc_jpeg = video_drvdata(file); @@ -1594,6 +1670,12 @@ static int mxc_jpeg_open(struct file *file) goto error; } + ret = mxc_jpeg_ctrls_setup(ctx); + if (ret) { + dev_err(ctx->mxc_jpeg->dev, "failed to setup mxc jpeg controls\n"); + goto err_ctrls_setup; + } + ctx->fh.ctrl_handler = &ctx->ctrl_handler; mxc_jpeg_set_default_params(ctx); ctx->slot = MXC_MAX_SLOTS; /* slot not allocated yet */ @@ -1605,6 +1687,8 @@ static int mxc_jpeg_open(struct file *file) return 0; +err_ctrls_setup: + v4l2_m2m_ctx_release(ctx->fh.m2m_ctx); error: v4l2_fh_del(&ctx->fh); v4l2_fh_exit(&ctx->fh); @@ -1646,7 +1730,6 @@ static int mxc_jpeg_enum_fmt_vid_cap(struct file *file, void *priv, if (f->index) return -EINVAL; f->pixelformat = q_data->fmt->fourcc; - strscpy(f->description, q_data->fmt->name, sizeof(f->description)); return 0; } } @@ -1684,22 +1767,17 @@ static int mxc_jpeg_try_fmt(struct v4l2_format *f, const struct mxc_jpeg_fmt *fm pix_mp->num_planes = fmt->colplanes; pix_mp->pixelformat = fmt->fourcc; - /* - * use MXC_JPEG_H_ALIGN instead of fmt->v_align, for vertical - * alignment, to loosen up the alignment to multiple of 8, - * otherwise NV12-1080p fails as 1080 is not a multiple of 16 - */ + pix_mp->width = w; + pix_mp->height = h; v4l_bound_align_image(&w, - MXC_JPEG_MIN_WIDTH, - w, /* adjust downwards*/ + w, /* adjust upwards*/ + MXC_JPEG_MAX_WIDTH, fmt->h_align, &h, - MXC_JPEG_MIN_HEIGHT, - h, /* adjust downwards*/ - MXC_JPEG_H_ALIGN, + h, /* adjust upwards*/ + MXC_JPEG_MAX_HEIGHT, + 0, 0); - pix_mp->width = w; /* negotiate the width */ - pix_mp->height = h; /* negotiate the height */ /* get user input into the tmp_q */ tmp_q.w = w; @@ -1825,35 +1903,19 @@ static int mxc_jpeg_s_fmt(struct mxc_jpeg_ctx *ctx, q_data->w_adjusted = q_data->w; q_data->h_adjusted = q_data->h; - if (jpeg->mode == MXC_JPEG_DECODE) { - /* - * align up the resolution for CAST IP, - * but leave the buffer resolution unchanged - */ - v4l_bound_align_image(&q_data->w_adjusted, - q_data->w_adjusted, /* adjust upwards */ - MXC_JPEG_MAX_WIDTH, - q_data->fmt->h_align, - &q_data->h_adjusted, - q_data->h_adjusted, /* adjust upwards */ - MXC_JPEG_MAX_HEIGHT, - q_data->fmt->v_align, - 0); - } else { - /* - * align down the resolution for CAST IP, - * but leave the buffer resolution unchanged - */ - v4l_bound_align_image(&q_data->w_adjusted, - MXC_JPEG_MIN_WIDTH, - q_data->w_adjusted, /* adjust downwards*/ - q_data->fmt->h_align, - &q_data->h_adjusted, - MXC_JPEG_MIN_HEIGHT, - q_data->h_adjusted, /* adjust downwards*/ - q_data->fmt->v_align, - 0); - } + /* + * align up the resolution for CAST IP, + * but leave the buffer resolution unchanged + */ + v4l_bound_align_image(&q_data->w_adjusted, + q_data->w_adjusted, /* adjust upwards */ + MXC_JPEG_MAX_WIDTH, + q_data->fmt->h_align, + &q_data->h_adjusted, + q_data->h_adjusted, /* adjust upwards */ + MXC_JPEG_MAX_HEIGHT, + q_data->fmt->v_align, + 0); for (i = 0; i < pix_mp->num_planes; i++) { q_data->bytesperline[i] = pix_mp->plane_fmt[i].bytesperline; @@ -1958,32 +2020,13 @@ static int mxc_jpeg_subscribe_event(struct v4l2_fh *fh, return v4l2_event_subscribe(fh, sub, 0, NULL); case V4L2_EVENT_SOURCE_CHANGE: return v4l2_src_change_event_subscribe(fh, sub); + case V4L2_EVENT_CTRL: + return v4l2_ctrl_subscribe_event(fh, sub); default: return -EINVAL; } } -static int mxc_jpeg_dqbuf(struct file *file, void *priv, - struct v4l2_buffer *buf) -{ - struct v4l2_fh *fh = file->private_data; - struct mxc_jpeg_ctx *ctx = mxc_jpeg_fh_to_ctx(priv); - struct device *dev = ctx->mxc_jpeg->dev; - int num_src_ready = v4l2_m2m_num_src_bufs_ready(fh->m2m_ctx); - int ret; - - dev_dbg(dev, "DQBUF type=%d, index=%d", buf->type, buf->index); - if (ctx->stopping == 1 && num_src_ready == 0) { - /* No more src bufs, notify app EOS */ - notify_eos(ctx); - ctx->stopping = 0; - mxc_jpeg_set_last_buffer_dequeued(ctx); - } - - ret = v4l2_m2m_dqbuf(file, fh->m2m_ctx, buf); - return ret; -} - static const struct v4l2_ioctl_ops mxc_jpeg_ioctl_ops = { .vidioc_querycap = mxc_jpeg_querycap, .vidioc_enum_fmt_vid_cap = mxc_jpeg_enum_fmt_vid_cap, @@ -2007,7 +2050,7 @@ static const struct v4l2_ioctl_ops mxc_jpeg_ioctl_ops = { .vidioc_encoder_cmd = mxc_jpeg_encoder_cmd, .vidioc_qbuf = v4l2_m2m_ioctl_qbuf, - .vidioc_dqbuf = mxc_jpeg_dqbuf, + .vidioc_dqbuf = v4l2_m2m_ioctl_dqbuf, .vidioc_create_bufs = v4l2_m2m_ioctl_create_bufs, .vidioc_prepare_buf = v4l2_m2m_ioctl_prepare_buf, @@ -2031,6 +2074,7 @@ static int mxc_jpeg_release(struct file *file) else dev_dbg(dev, "Release JPEG encoder instance on slot %d.", ctx->slot); + v4l2_ctrl_handler_free(&ctx->ctrl_handler); v4l2_m2m_ctx_release(ctx->fh.m2m_ctx); v4l2_fh_del(&ctx->fh); v4l2_fh_exit(&ctx->fh); diff --git a/drivers/media/platform/nxp/imx-jpeg/mxc-jpeg.h b/drivers/media/platform/nxp/imx-jpeg/mxc-jpeg.h index 760eaf5387a1c..c508d41a906f4 100644 --- a/drivers/media/platform/nxp/imx-jpeg/mxc-jpeg.h +++ b/drivers/media/platform/nxp/imx-jpeg/mxc-jpeg.h @@ -92,11 +92,11 @@ struct mxc_jpeg_ctx { struct mxc_jpeg_q_data cap_q; struct v4l2_fh fh; enum mxc_jpeg_enc_state enc_state; - unsigned int stopping; - unsigned int stopped; unsigned int slot; unsigned int source_change; bool header_parsed; + struct v4l2_ctrl_handler ctrl_handler; + u8 jpeg_quality; }; struct mxc_jpeg_slot_data { diff --git a/drivers/media/platform/qcom/camss/camss-csid.c b/drivers/media/platform/qcom/camss/camss-csid.c index f993f349b66bf..80628801cf09f 100644 --- a/drivers/media/platform/qcom/camss/camss-csid.c +++ b/drivers/media/platform/qcom/camss/camss-csid.c @@ -666,7 +666,7 @@ int msm_csid_subdev_init(struct camss *camss, struct csid_device *csid, if (csid->num_supplies) { csid->supplies = devm_kmalloc_array(camss->dev, csid->num_supplies, - sizeof(csid->supplies), + sizeof(*csid->supplies), GFP_KERNEL); if (!csid->supplies) return -ENOMEM; diff --git a/drivers/media/platform/qcom/camss/camss-ispif.c b/drivers/media/platform/qcom/camss/camss-ispif.c index 4ee11bb979cde..91e6a2b9ac504 100644 --- a/drivers/media/platform/qcom/camss/camss-ispif.c +++ b/drivers/media/platform/qcom/camss/camss-ispif.c @@ -1253,6 +1253,41 @@ static enum ispif_intf ispif_get_intf(enum vfe_line_id line_id) } /* + * ispif_get_vfe_id - Get VFE HW module id + * @entity: Pointer to VFE media entity structure + * @id: Return CSID HW module id here + */ +static void ispif_get_vfe_id(struct media_entity *entity, u8 *id) +{ + struct v4l2_subdev *sd; + struct vfe_line *line; + struct vfe_device *vfe; + + sd = media_entity_to_v4l2_subdev(entity); + line = v4l2_get_subdevdata(sd); + vfe = to_vfe(line); + + *id = vfe->id; +} + +/* + * ispif_get_vfe_line_id - Get VFE line id by media entity + * @entity: Pointer to VFE media entity structure + * @id: Return VFE line id here + */ +static void ispif_get_vfe_line_id(struct media_entity *entity, + enum vfe_line_id *id) +{ + struct v4l2_subdev *sd; + struct vfe_line *line; + + sd = media_entity_to_v4l2_subdev(entity); + line = v4l2_get_subdevdata(sd); + + *id = line->id; +} + +/* * ispif_link_setup - Setup ISPIF connections * @entity: Pointer to media entity structure * @local: Pointer to local pad @@ -1285,8 +1320,8 @@ static int ispif_link_setup(struct media_entity *entity, sd = media_entity_to_v4l2_subdev(entity); line = v4l2_get_subdevdata(sd); - msm_vfe_get_vfe_id(remote->entity, &line->vfe_id); - msm_vfe_get_vfe_line_id(remote->entity, &id); + ispif_get_vfe_id(remote->entity, &line->vfe_id); + ispif_get_vfe_line_id(remote->entity, &id); line->interface = ispif_get_intf(id); } } diff --git a/drivers/media/platform/qcom/camss/camss-vfe.c b/drivers/media/platform/qcom/camss/camss-vfe.c index 5b148e9f8134d..76e28b8325685 100644 --- a/drivers/media/platform/qcom/camss/camss-vfe.c +++ b/drivers/media/platform/qcom/camss/camss-vfe.c @@ -1423,40 +1423,6 @@ int msm_vfe_subdev_init(struct camss *camss, struct vfe_device *vfe, } /* - * msm_vfe_get_vfe_id - Get VFE HW module id - * @entity: Pointer to VFE media entity structure - * @id: Return CSID HW module id here - */ -void msm_vfe_get_vfe_id(struct media_entity *entity, u8 *id) -{ - struct v4l2_subdev *sd; - struct vfe_line *line; - struct vfe_device *vfe; - - sd = media_entity_to_v4l2_subdev(entity); - line = v4l2_get_subdevdata(sd); - vfe = to_vfe(line); - - *id = vfe->id; -} - -/* - * msm_vfe_get_vfe_line_id - Get VFE line id by media entity - * @entity: Pointer to VFE media entity structure - * @id: Return VFE line id here - */ -void msm_vfe_get_vfe_line_id(struct media_entity *entity, enum vfe_line_id *id) -{ - struct v4l2_subdev *sd; - struct vfe_line *line; - - sd = media_entity_to_v4l2_subdev(entity); - line = v4l2_get_subdevdata(sd); - - *id = line->id; -} - -/* * vfe_link_setup - Setup VFE connections * @entity: Pointer to media entity structure * @local: Pointer to local pad diff --git a/drivers/media/platform/qcom/camss/camss-vfe.h b/drivers/media/platform/qcom/camss/camss-vfe.h index 0eba04eb9b77c..cbc314c4e244b 100644 --- a/drivers/media/platform/qcom/camss/camss-vfe.h +++ b/drivers/media/platform/qcom/camss/camss-vfe.h @@ -163,9 +163,6 @@ int msm_vfe_register_entities(struct vfe_device *vfe, void msm_vfe_unregister_entities(struct vfe_device *vfe); -void msm_vfe_get_vfe_id(struct media_entity *entity, u8 *id); -void msm_vfe_get_vfe_line_id(struct media_entity *entity, enum vfe_line_id *id); - /* * vfe_buf_add_pending - Add output buffer to list of pending * @output: VFE output diff --git a/drivers/media/platform/qcom/camss/camss.c b/drivers/media/platform/qcom/camss/camss.c index 79ad82e233cb1..932968e5f1e52 100644 --- a/drivers/media/platform/qcom/camss/camss.c +++ b/drivers/media/platform/qcom/camss/camss.c @@ -1452,19 +1452,31 @@ static const struct media_device_ops camss_media_ops = { static int camss_configure_pd(struct camss *camss) { - int nbr_pm_domains = 0; + struct device *dev = camss->dev; int last_pm_domain = 0; int i; int ret; - if (camss->version == CAMSS_8x96 || - camss->version == CAMSS_660) - nbr_pm_domains = PM_DOMAIN_GEN1_COUNT; - else if (camss->version == CAMSS_845 || - camss->version == CAMSS_8250) - nbr_pm_domains = PM_DOMAIN_GEN2_COUNT; + camss->genpd_num = of_count_phandle_with_args(dev->of_node, + "power-domains", + "#power-domain-cells"); + if (camss->genpd_num < 0) { + dev_err(dev, "Power domains are not defined for camss\n"); + return camss->genpd_num; + } + + camss->genpd = devm_kmalloc_array(dev, camss->genpd_num, + sizeof(*camss->genpd), GFP_KERNEL); + if (!camss->genpd) + return -ENOMEM; + + camss->genpd_link = devm_kmalloc_array(dev, camss->genpd_num, + sizeof(*camss->genpd_link), + GFP_KERNEL); + if (!camss->genpd_link) + return -ENOMEM; - for (i = 0; i < nbr_pm_domains; i++) { + for (i = 0; i < camss->genpd_num; i++) { camss->genpd[i] = dev_pm_domain_attach_by_id(camss->dev, i); if (IS_ERR(camss->genpd[i])) { ret = PTR_ERR(camss->genpd[i]); @@ -1529,7 +1541,7 @@ static int camss_probe(struct platform_device *pdev) struct camss *camss; int num_subdevs, ret; - camss = kzalloc(sizeof(*camss), GFP_KERNEL); + camss = devm_kzalloc(dev, sizeof(*camss), GFP_KERNEL); if (!camss) return -ENOMEM; @@ -1567,39 +1579,30 @@ static int camss_probe(struct platform_device *pdev) camss->csid_num = 4; camss->vfe_num = 4; } else { - ret = -EINVAL; - goto err_free; + return -EINVAL; } camss->csiphy = devm_kcalloc(dev, camss->csiphy_num, sizeof(*camss->csiphy), GFP_KERNEL); - if (!camss->csiphy) { - ret = -ENOMEM; - goto err_free; - } + if (!camss->csiphy) + return -ENOMEM; camss->csid = devm_kcalloc(dev, camss->csid_num, sizeof(*camss->csid), GFP_KERNEL); - if (!camss->csid) { - ret = -ENOMEM; - goto err_free; - } + if (!camss->csid) + return -ENOMEM; if (camss->version == CAMSS_8x16 || camss->version == CAMSS_8x96) { camss->ispif = devm_kcalloc(dev, 1, sizeof(*camss->ispif), GFP_KERNEL); - if (!camss->ispif) { - ret = -ENOMEM; - goto err_free; - } + if (!camss->ispif) + return -ENOMEM; } camss->vfe = devm_kcalloc(dev, camss->vfe_num, sizeof(*camss->vfe), GFP_KERNEL); - if (!camss->vfe) { - ret = -ENOMEM; - goto err_free; - } + if (!camss->vfe) + return -ENOMEM; v4l2_async_nf_init(&camss->notifier); @@ -1681,15 +1684,12 @@ err_register_entities: v4l2_device_unregister(&camss->v4l2_dev); err_cleanup: v4l2_async_nf_cleanup(&camss->notifier); -err_free: - kfree(camss); return ret; } void camss_delete(struct camss *camss) { - int nbr_pm_domains = 0; int i; v4l2_device_unregister(&camss->v4l2_dev); @@ -1698,19 +1698,10 @@ void camss_delete(struct camss *camss) pm_runtime_disable(camss->dev); - if (camss->version == CAMSS_8x96 || - camss->version == CAMSS_660) - nbr_pm_domains = PM_DOMAIN_GEN1_COUNT; - else if (camss->version == CAMSS_845 || - camss->version == CAMSS_8250) - nbr_pm_domains = PM_DOMAIN_GEN2_COUNT; - - for (i = 0; i < nbr_pm_domains; i++) { + for (i = 0; i < camss->genpd_num; i++) { device_link_del(camss->genpd_link[i]); dev_pm_domain_detach(camss->genpd[i], true); } - - kfree(camss); } /* diff --git a/drivers/media/platform/qcom/camss/camss.h b/drivers/media/platform/qcom/camss/camss.h index c9b3e0df5be8f..0db80cadbbaa0 100644 --- a/drivers/media/platform/qcom/camss/camss.h +++ b/drivers/media/platform/qcom/camss/camss.h @@ -69,9 +69,7 @@ struct resources_icc { enum pm_domain { PM_DOMAIN_VFE0 = 0, PM_DOMAIN_VFE1 = 1, - PM_DOMAIN_GEN1_COUNT = 2, /* CAMSS series of ISPs */ PM_DOMAIN_VFELITE = 2, /* VFELITE / TOP GDSC */ - PM_DOMAIN_GEN2_COUNT = 3, /* Titan series of ISPs */ }; enum camss_version { @@ -101,8 +99,9 @@ struct camss { int vfe_num; struct vfe_device *vfe; atomic_t ref_count; - struct device *genpd[PM_DOMAIN_GEN2_COUNT]; - struct device_link *genpd_link[PM_DOMAIN_GEN2_COUNT]; + int genpd_num; + struct device **genpd; + struct device_link **genpd_link; struct icc_path *icc_path[ICC_SM8250_COUNT]; struct icc_bw_tbl icc_bw_tbl[ICC_SM8250_COUNT]; }; diff --git a/drivers/media/platform/renesas/rcar-vin/rcar-core.c b/drivers/media/platform/renesas/rcar-vin/rcar-core.c index 49bdcfba010b2..4b7a9743554af 100644 --- a/drivers/media/platform/renesas/rcar-vin/rcar-core.c +++ b/drivers/media/platform/renesas/rcar-vin/rcar-core.c @@ -1261,7 +1261,7 @@ static const struct rvin_info rcar_info_r8a77980 = { }; static const struct rvin_group_route rcar_info_r8a77990_routes[] = { - { .master = 0, .csi = RVIN_CSI40, .chsel = 0x03 }, + { .master = 4, .csi = RVIN_CSI40, .chsel = 0x03 }, { /* Sentinel */ } }; diff --git a/drivers/media/platform/samsung/exynos-gsc/gsc-core.c b/drivers/media/platform/samsung/exynos-gsc/gsc-core.c index e3559b0470921..b147c645ae0bb 100644 --- a/drivers/media/platform/samsung/exynos-gsc/gsc-core.c +++ b/drivers/media/platform/samsung/exynos-gsc/gsc-core.c @@ -339,8 +339,7 @@ static int get_plane_info(struct gsc_frame *frm, u32 addr, u32 *index, u32 *ret_ void gsc_set_prefbuf(struct gsc_dev *gsc, struct gsc_frame *frm) { - u32 f_chk_addr, f_chk_len, s_chk_addr, s_chk_len; - f_chk_addr = f_chk_len = s_chk_addr = s_chk_len = 0; + u32 f_chk_addr, f_chk_len, s_chk_addr = 0, s_chk_len = 0; f_chk_addr = frm->addr.y; f_chk_len = frm->payload[0]; diff --git a/drivers/media/platform/samsung/exynos-gsc/gsc-core.h b/drivers/media/platform/samsung/exynos-gsc/gsc-core.h index e894e85e84a4e..1ea5fa1bf3c84 100644 --- a/drivers/media/platform/samsung/exynos-gsc/gsc-core.h +++ b/drivers/media/platform/samsung/exynos-gsc/gsc-core.h @@ -222,7 +222,7 @@ struct gsc_m2m_device { * @org_scaler_input_w: max pixel width when the scaler is enabled * @org_scaler_input_h: max pixel height when the scaler is enabled * @real_rot_dis_w: max pixel src cropped height with the rotator is off - * @real_rot_dis_h: max pixel src croppped width with the rotator is off + * @real_rot_dis_h: max pixel src cropped width with the rotator is off * @real_rot_en_w: max pixel src cropped width with the rotator is on * @real_rot_en_h: max pixel src cropped height with the rotator is on * @target_rot_dis_w: max pixel dst scaled width with the rotator is off diff --git a/drivers/media/platform/samsung/exynos4-is/fimc-is-errno.h b/drivers/media/platform/samsung/exynos4-is/fimc-is-errno.h index da36b48b8f9fd..9dcbb9853ac0b 100644 --- a/drivers/media/platform/samsung/exynos4-is/fimc-is-errno.h +++ b/drivers/media/platform/samsung/exynos4-is/fimc-is-errno.h @@ -116,7 +116,7 @@ enum fimc_is_error { ERROR_COMMON_PARAMETER = 2, /* Invalid parameter */ /* setfile is not loaded before adjusting */ ERROR_COMMON_SETFILE_LOAD = 3, - /* setfile is not Adjusted before runnng. */ + /* setfile is not Adjusted before running. */ ERROR_COMMON_SETFILE_ADJUST = 4, /* Index of setfile is not valid (0~MAX_SETFILE_NUM-1) */ ERROR_COMMON_SETFILE_INDEX = 5, diff --git a/drivers/media/platform/samsung/exynos4-is/mipi-csis.c b/drivers/media/platform/samsung/exynos4-is/mipi-csis.c index 27a214936cb08..6a0d35f33e8c6 100644 --- a/drivers/media/platform/samsung/exynos4-is/mipi-csis.c +++ b/drivers/media/platform/samsung/exynos4-is/mipi-csis.c @@ -124,7 +124,7 @@ static char *csi_clock_name[] = { #define DEFAULT_SCLK_CSIS_FREQ 166000000UL static const char * const csis_supply_name[] = { - "vddcore", /* CSIS Core (1.0V, 1.1V or 1.2V) suppply */ + "vddcore", /* CSIS Core (1.0V, 1.1V or 1.2V) supply */ "vddio", /* CSIS I/O and PLL (1.8V) supply */ }; #define CSIS_NUM_SUPPLIES ARRAY_SIZE(csis_supply_name) diff --git a/drivers/media/platform/samsung/s5p-jpeg/jpeg-core.c b/drivers/media/platform/samsung/s5p-jpeg/jpeg-core.c index 456287186ad8e..55814041b8d8f 100644 --- a/drivers/media/platform/samsung/s5p-jpeg/jpeg-core.c +++ b/drivers/media/platform/samsung/s5p-jpeg/jpeg-core.c @@ -1709,7 +1709,7 @@ static int exynos3250_jpeg_try_downscale(struct s5p_jpeg_ctx *ctx, w_ratio = ctx->out_q.w / r->width; h_ratio = ctx->out_q.h / r->height; - scale_factor = w_ratio > h_ratio ? w_ratio : h_ratio; + scale_factor = max(w_ratio, h_ratio); scale_factor = clamp_val(scale_factor, 1, 8); /* Align scale ratio to the nearest power of 2 */ diff --git a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_pm.c b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_pm.c index 72a901e994503..187849841a28b 100644 --- a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_pm.c +++ b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc_pm.c @@ -88,7 +88,6 @@ int s5p_mfc_power_on(void) if (ret < 0) { mfc_err("clock prepare failed for clock: %s\n", pm->clk_names[i]); - i++; goto err; } } @@ -98,7 +97,7 @@ int s5p_mfc_power_on(void) return 0; err: - while (--i > 0) + while (--i >= 0) clk_disable_unprepare(pm->clocks[i]); pm_runtime_put(pm->device); return ret; diff --git a/drivers/media/platform/st/sti/delta/delta-v4l2.c b/drivers/media/platform/st/sti/delta/delta-v4l2.c index 420ad4d8df5d5..03eaee6d15da0 100644 --- a/drivers/media/platform/st/sti/delta/delta-v4l2.c +++ b/drivers/media/platform/st/sti/delta/delta-v4l2.c @@ -1669,14 +1669,12 @@ static int delta_open(struct file *file) set_default_params(ctx); /* enable ST231 clocks */ - if (delta->clk_st231) - if (clk_prepare_enable(delta->clk_st231)) - dev_warn(delta->dev, "failed to enable st231 clk\n"); + if (clk_prepare_enable(delta->clk_st231)) + dev_warn(delta->dev, "failed to enable st231 clk\n"); /* enable FLASH_PROMIP clock */ - if (delta->clk_flash_promip) - if (clk_prepare_enable(delta->clk_flash_promip)) - dev_warn(delta->dev, "failed to enable delta promip clk\n"); + if (clk_prepare_enable(delta->clk_flash_promip)) + dev_warn(delta->dev, "failed to enable delta promip clk\n"); mutex_unlock(&delta->lock); @@ -1717,12 +1715,10 @@ static int delta_release(struct file *file) v4l2_fh_exit(&ctx->fh); /* disable ST231 clocks */ - if (delta->clk_st231) - clk_disable_unprepare(delta->clk_st231); + clk_disable_unprepare(delta->clk_st231); /* disable FLASH_PROMIP clock */ - if (delta->clk_flash_promip) - clk_disable_unprepare(delta->clk_flash_promip); + clk_disable_unprepare(delta->clk_flash_promip); dev_dbg(delta->dev, "%s decoder instance released\n", ctx->name); @@ -1926,8 +1922,7 @@ static int delta_runtime_suspend(struct device *dev) { struct delta_dev *delta = dev_get_drvdata(dev); - if (delta->clk_delta) - clk_disable_unprepare(delta->clk_delta); + clk_disable_unprepare(delta->clk_delta); return 0; } @@ -1936,9 +1931,8 @@ static int delta_runtime_resume(struct device *dev) { struct delta_dev *delta = dev_get_drvdata(dev); - if (delta->clk_delta) - if (clk_prepare_enable(delta->clk_delta)) - dev_warn(dev, "failed to prepare/enable delta clk\n"); + if (clk_prepare_enable(delta->clk_delta)) + dev_warn(dev, "failed to prepare/enable delta clk\n"); return 0; } diff --git a/drivers/media/platform/ti/davinci/vpif.c b/drivers/media/platform/ti/davinci/vpif.c index 97ef770266af6..da27da4c165a0 100644 --- a/drivers/media/platform/ti/davinci/vpif.c +++ b/drivers/media/platform/ti/davinci/vpif.c @@ -469,6 +469,7 @@ static int vpif_probe(struct platform_device *pdev) endpoint); if (!endpoint) return 0; + of_node_put(endpoint); /* * For DT platforms, manually create platform_devices for diff --git a/drivers/media/platform/ti/omap/omap_voutlib.c b/drivers/media/platform/ti/omap/omap_voutlib.c index 480a7e95533d9..fdea2309ee373 100644 --- a/drivers/media/platform/ti/omap/omap_voutlib.c +++ b/drivers/media/platform/ti/omap/omap_voutlib.c @@ -314,7 +314,7 @@ unsigned long omap_vout_alloc_buffer(u32 buf_size, u32 *phys_addr) if (virt_addr) { while (size > 0) { - SetPageReserved(virt_to_page(addr)); + SetPageReserved(virt_to_page((void *)addr)); addr += PAGE_SIZE; size -= PAGE_SIZE; } @@ -335,7 +335,7 @@ void omap_vout_free_buffer(unsigned long virtaddr, u32 buf_size) order = get_order(size); while (size > 0) { - ClearPageReserved(virt_to_page(addr)); + ClearPageReserved(virt_to_page((void *)addr)); addr += PAGE_SIZE; size -= PAGE_SIZE; } diff --git a/drivers/media/rc/igorplugusb.c b/drivers/media/rc/igorplugusb.c index b40dbf5001869..12ee5dd0a61a0 100644 --- a/drivers/media/rc/igorplugusb.c +++ b/drivers/media/rc/igorplugusb.c @@ -38,7 +38,7 @@ struct igorplugusb { struct timer_list timer; - uint8_t buf_in[MAX_PACKET]; + u8 *buf_in; char phys[64]; }; @@ -110,7 +110,6 @@ static void igorplugusb_callback(struct urb *urb) case -ECONNRESET: case -ENOENT: case -ESHUTDOWN: - usb_unlink_urb(urb); return; default: dev_warn(ir->dev, "Error: urb status = %d\n", urb->status); @@ -126,7 +125,7 @@ static void igorplugusb_cmd(struct igorplugusb *ir, int cmd) ir->request.bRequest = cmd; ir->urb->transfer_flags = 0; ret = usb_submit_urb(ir->urb, GFP_ATOMIC); - if (ret) + if (ret && ret != -EPERM) dev_err(ir->dev, "submit urb failed: %d", ret); } @@ -177,6 +176,9 @@ static int igorplugusb_probe(struct usb_interface *intf, if (!ir->urb) goto fail; + ir->buf_in = kmalloc(MAX_PACKET, GFP_KERNEL); + if (!ir->buf_in) + goto fail; usb_fill_control_urb(ir->urb, udev, usb_rcvctrlpipe(udev, 0), (uint8_t *)&ir->request, ir->buf_in, sizeof(ir->buf_in), igorplugusb_callback, ir); @@ -220,9 +222,12 @@ static int igorplugusb_probe(struct usb_interface *intf, return 0; fail: - rc_free_device(ir->rc); - usb_free_urb(ir->urb); + usb_poison_urb(ir->urb); del_timer(&ir->timer); + usb_unpoison_urb(ir->urb); + usb_free_urb(ir->urb); + rc_free_device(ir->rc); + kfree(ir->buf_in); return ret; } @@ -232,10 +237,12 @@ static void igorplugusb_disconnect(struct usb_interface *intf) struct igorplugusb *ir = usb_get_intfdata(intf); rc_unregister_device(ir->rc); + usb_poison_urb(ir->urb); del_timer_sync(&ir->timer); usb_set_intfdata(intf, NULL); - usb_kill_urb(ir->urb); + usb_unpoison_urb(ir->urb); usb_free_urb(ir->urb); + kfree(ir->buf_in); } static const struct usb_device_id igorplugusb_table[] = { diff --git a/drivers/media/rc/iguanair.c b/drivers/media/rc/iguanair.c index c9cb8277723f4..276bf3c8a8cb4 100644 --- a/drivers/media/rc/iguanair.c +++ b/drivers/media/rc/iguanair.c @@ -149,10 +149,8 @@ static void iguanair_rx(struct urb *urb) return; ir = urb->context; - if (!ir) { - usb_unlink_urb(urb); + if (!ir) return; - } switch (urb->status) { case 0: @@ -161,7 +159,6 @@ static void iguanair_rx(struct urb *urb) case -ECONNRESET: case -ENOENT: case -ESHUTDOWN: - usb_unlink_urb(urb); return; case -EPIPE: default: diff --git a/drivers/media/rc/imon_raw.c b/drivers/media/rc/imon_raw.c index d41580f6e4c71..b02ded52f19e6 100644 --- a/drivers/media/rc/imon_raw.c +++ b/drivers/media/rc/imon_raw.c @@ -14,7 +14,7 @@ struct imon { struct device *dev; struct urb *ir_urb; struct rc_dev *rcdev; - __be64 ir_buf; + __be64 *ir_buf; char phys[64]; }; @@ -29,7 +29,7 @@ struct imon { static void imon_ir_data(struct imon *imon) { struct ir_raw_event rawir = {}; - u64 data = be64_to_cpu(imon->ir_buf); + u64 data = be64_to_cpup(imon->ir_buf); u8 packet_no = data & 0xff; int offset = 40; int bit; @@ -37,7 +37,7 @@ static void imon_ir_data(struct imon *imon) if (packet_no == 0xff) return; - dev_dbg(imon->dev, "data: %*ph", 8, &imon->ir_buf); + dev_dbg(imon->dev, "data: %*ph", 8, imon->ir_buf); /* * Only the first 5 bytes contain IR data. Right shift so we move @@ -137,10 +137,16 @@ static int imon_probe(struct usb_interface *intf, if (!imon->ir_urb) return -ENOMEM; + imon->ir_buf = kmalloc(sizeof(__be64), GFP_KERNEL); + if (!imon->ir_buf) { + ret = -ENOMEM; + goto free_urb; + } + imon->dev = &intf->dev; usb_fill_int_urb(imon->ir_urb, udev, usb_rcvintpipe(udev, ir_ep->bEndpointAddress), - &imon->ir_buf, sizeof(imon->ir_buf), + imon->ir_buf, sizeof(__be64), imon_ir_rx, imon, ir_ep->bInterval); rcdev = devm_rc_allocate_device(&intf->dev, RC_DRIVER_IR_RAW); @@ -177,6 +183,7 @@ static int imon_probe(struct usb_interface *intf, free_urb: usb_free_urb(imon->ir_urb); + kfree(imon->ir_buf); return ret; } @@ -186,6 +193,7 @@ static void imon_disconnect(struct usb_interface *intf) usb_kill_urb(imon->ir_urb); usb_free_urb(imon->ir_urb); + kfree(imon->ir_buf); } static const struct usb_device_id imon_table[] = { diff --git a/drivers/media/rc/lirc_dev.c b/drivers/media/rc/lirc_dev.c index 765375bda0c6e..25ab61dae126d 100644 --- a/drivers/media/rc/lirc_dev.c +++ b/drivers/media/rc/lirc_dev.c @@ -715,7 +715,7 @@ int lirc_register(struct rc_dev *dev) const char *rx_type, *tx_type; int err, minor; - minor = ida_simple_get(&lirc_ida, 0, RC_DEV_MAX, GFP_KERNEL); + minor = ida_alloc_max(&lirc_ida, RC_DEV_MAX - 1, GFP_KERNEL); if (minor < 0) return minor; @@ -760,7 +760,7 @@ int lirc_register(struct rc_dev *dev) return 0; out_ida: - ida_simple_remove(&lirc_ida, minor); + ida_free(&lirc_ida, minor); return err; } @@ -778,7 +778,7 @@ void lirc_unregister(struct rc_dev *dev) spin_unlock_irqrestore(&dev->lirc_fh_lock, flags); cdev_device_del(&dev->lirc_cdev, &dev->lirc_dev); - ida_simple_remove(&lirc_ida, MINOR(dev->lirc_dev.devt)); + ida_free(&lirc_ida, MINOR(dev->lirc_dev.devt)); } int __init lirc_dev_init(void) diff --git a/drivers/media/rc/rc-main.c b/drivers/media/rc/rc-main.c index b90438a71c800..923cc1acda942 100644 --- a/drivers/media/rc/rc-main.c +++ b/drivers/media/rc/rc-main.c @@ -1897,7 +1897,7 @@ int rc_register_device(struct rc_dev *dev) if (!dev) return -EINVAL; - minor = ida_simple_get(&rc_ida, 0, RC_DEV_MAX, GFP_KERNEL); + minor = ida_alloc_max(&rc_ida, RC_DEV_MAX - 1, GFP_KERNEL); if (minor < 0) return minor; @@ -1980,7 +1980,7 @@ out_rx_free: out_raw: ir_raw_event_free(dev); out_minor: - ida_simple_remove(&rc_ida, minor); + ida_free(&rc_ida, minor); return rc; } EXPORT_SYMBOL_GPL(rc_register_device); @@ -2040,7 +2040,7 @@ void rc_unregister_device(struct rc_dev *dev) device_del(&dev->dev); - ida_simple_remove(&rc_ida, dev->minor); + ida_free(&rc_ida, dev->minor); if (!dev->managed_alloc) rc_free_device(dev); diff --git a/drivers/media/rc/redrat3.c b/drivers/media/rc/redrat3.c index cb22316b3f002..9f2947af33aa7 100644 --- a/drivers/media/rc/redrat3.c +++ b/drivers/media/rc/redrat3.c @@ -1155,9 +1155,9 @@ static int redrat3_dev_resume(struct usb_interface *intf) { struct redrat3_dev *rr3 = usb_get_intfdata(intf); - if (usb_submit_urb(rr3->narrow_urb, GFP_ATOMIC)) + if (usb_submit_urb(rr3->narrow_urb, GFP_NOIO)) return -EIO; - if (usb_submit_urb(rr3->wide_urb, GFP_ATOMIC)) + if (usb_submit_urb(rr3->wide_urb, GFP_NOIO)) return -EIO; led_classdev_resume(&rr3->led); return 0; diff --git a/drivers/media/rc/streamzap.c b/drivers/media/rc/streamzap.c index deb85330c9406..9b209e687f256 100644 --- a/drivers/media/rc/streamzap.c +++ b/drivers/media/rc/streamzap.c @@ -406,7 +406,7 @@ static int streamzap_resume(struct usb_interface *intf) { struct streamzap_ir *sz = usb_get_intfdata(intf); - if (usb_submit_urb(sz->urb_in, GFP_ATOMIC)) { + if (usb_submit_urb(sz->urb_in, GFP_NOIO)) { dev_err(sz->dev, "Error submitting urb\n"); return -EIO; } diff --git a/drivers/media/rc/ttusbir.c b/drivers/media/rc/ttusbir.c index 629787d53ee1c..560a26f3965cf 100644 --- a/drivers/media/rc/ttusbir.c +++ b/drivers/media/rc/ttusbir.c @@ -90,7 +90,6 @@ static void ttusbir_bulk_complete(struct urb *urb) case -ECONNRESET: case -ENOENT: case -ESHUTDOWN: - usb_unlink_urb(urb); return; case -EPIPE: default: @@ -166,7 +165,6 @@ static void ttusbir_urb_complete(struct urb *urb) case -ECONNRESET: case -ENOENT: case -ESHUTDOWN: - usb_unlink_urb(urb); return; case -EPIPE: default: @@ -402,7 +400,7 @@ static int ttusbir_resume(struct usb_interface *intf) led_classdev_resume(&tt->led); for (i = 0; i < NUM_URBS; i++) { - rc = usb_submit_urb(tt->urb[i], GFP_KERNEL); + rc = usb_submit_urb(tt->urb[i], GFP_NOIO); if (rc) { dev_warn(tt->dev, "failed to submit urb: %d\n", rc); break; diff --git a/drivers/media/rc/xbox_remote.c b/drivers/media/rc/xbox_remote.c index 7424b2031152c..a1572381d0971 100644 --- a/drivers/media/rc/xbox_remote.c +++ b/drivers/media/rc/xbox_remote.c @@ -163,8 +163,8 @@ static void xbox_remote_rc_init(struct xbox_remote *xbox_remote) rdev->dev.parent = &xbox_remote->interface->dev; } -static int xbox_remote_initialize(struct xbox_remote *xbox_remote, - struct usb_endpoint_descriptor *endpoint_in) +static void xbox_remote_initialize(struct xbox_remote *xbox_remote, + struct usb_endpoint_descriptor *endpoint_in) { struct usb_device *udev = xbox_remote->udev; int pipe, maxp; @@ -177,8 +177,6 @@ static int xbox_remote_initialize(struct xbox_remote *xbox_remote, usb_fill_int_urb(xbox_remote->irq_urb, udev, pipe, xbox_remote->inbuf, maxp, xbox_remote_irq_in, xbox_remote, endpoint_in->bInterval); - - return 0; } /* @@ -249,9 +247,7 @@ static int xbox_remote_probe(struct usb_interface *interface, xbox_remote_rc_init(xbox_remote); /* Device Hardware Initialization */ - err = xbox_remote_initialize(xbox_remote, endpoint_in); - if (err) - goto exit_kill_urbs; + xbox_remote_initialize(xbox_remote, endpoint_in); /* Set up and register rc device */ err = rc_register_device(xbox_remote->rdev); diff --git a/drivers/media/test-drivers/vivid/vivid-ctrls.c b/drivers/media/test-drivers/vivid/vivid-ctrls.c index e7516dc1227b3..7ff8fdfda28e0 100644 --- a/drivers/media/test-drivers/vivid/vivid-ctrls.c +++ b/drivers/media/test-drivers/vivid/vivid-ctrls.c @@ -46,6 +46,7 @@ #define VIVID_CID_INSERT_SAV (VIVID_CID_VIVID_BASE + 6) #define VIVID_CID_INSERT_EAV (VIVID_CID_VIVID_BASE + 7) #define VIVID_CID_VBI_CAP_INTERLACED (VIVID_CID_VIVID_BASE + 8) +#define VIVID_CID_INSERT_HDMI_VIDEO_GUARD_BAND (VIVID_CID_VIVID_BASE + 9) #define VIVID_CID_HFLIP (VIVID_CID_VIVID_BASE + 20) #define VIVID_CID_VFLIP (VIVID_CID_VIVID_BASE + 21) @@ -474,6 +475,9 @@ static int vivid_vid_cap_s_ctrl(struct v4l2_ctrl *ctrl) case VIVID_CID_INSERT_EAV: tpg_s_insert_eav(&dev->tpg, ctrl->val); break; + case VIVID_CID_INSERT_HDMI_VIDEO_GUARD_BAND: + tpg_s_insert_hdmi_video_guard_band(&dev->tpg, ctrl->val); + break; case VIVID_CID_HFLIP: dev->sensor_hflip = ctrl->val; tpg_s_hflip(&dev->tpg, dev->sensor_hflip ^ dev->hflip); @@ -660,6 +664,15 @@ static const struct v4l2_ctrl_config vivid_ctrl_insert_eav = { .step = 1, }; +static const struct v4l2_ctrl_config vivid_ctrl_insert_hdmi_video_guard_band = { + .ops = &vivid_vid_cap_ctrl_ops, + .id = VIVID_CID_INSERT_HDMI_VIDEO_GUARD_BAND, + .name = "Insert Video Guard Band", + .type = V4L2_CTRL_TYPE_BOOLEAN, + .max = 1, + .step = 1, +}; + static const struct v4l2_ctrl_config vivid_ctrl_hflip = { .ops = &vivid_vid_cap_ctrl_ops, .id = VIVID_CID_HFLIP, @@ -1638,6 +1651,7 @@ int vivid_create_controls(struct vivid_dev *dev, bool show_ccs_cap, v4l2_ctrl_new_custom(hdl_vid_cap, &vivid_ctrl_vflip, NULL); v4l2_ctrl_new_custom(hdl_vid_cap, &vivid_ctrl_insert_sav, NULL); v4l2_ctrl_new_custom(hdl_vid_cap, &vivid_ctrl_insert_eav, NULL); + v4l2_ctrl_new_custom(hdl_vid_cap, &vivid_ctrl_insert_hdmi_video_guard_band, NULL); v4l2_ctrl_new_custom(hdl_vid_cap, &vivid_ctrl_reduced_fps, NULL); if (show_ccs_cap) { dev->ctrl_has_crop_cap = v4l2_ctrl_new_custom(hdl_vid_cap, diff --git a/drivers/media/usb/Kconfig b/drivers/media/usb/Kconfig index 8de08704f8e4e..af88e07663881 100644 --- a/drivers/media/usb/Kconfig +++ b/drivers/media/usb/Kconfig @@ -17,7 +17,6 @@ source "drivers/media/usb/cpia2/Kconfig" source "drivers/media/usb/gspca/Kconfig" source "drivers/media/usb/pwc/Kconfig" source "drivers/media/usb/s2255/Kconfig" -source "drivers/media/usb/stkwebcam/Kconfig" source "drivers/media/usb/usbtv/Kconfig" source "drivers/media/usb/uvc/Kconfig" source "drivers/media/usb/zr364xx/Kconfig" diff --git a/drivers/media/usb/Makefile b/drivers/media/usb/Makefile index 044bd46c799c7..25fa2015b1794 100644 --- a/drivers/media/usb/Makefile +++ b/drivers/media/usb/Makefile @@ -10,7 +10,6 @@ obj-y += dvb-usb/ obj-y += dvb-usb-v2/ obj-y += s2255/ obj-y += siano/ -obj-y += stkwebcam/ obj-y += ttusb-budget/ obj-y += ttusb-dec/ obj-y += zr364xx/ diff --git a/drivers/media/usb/airspy/airspy.c b/drivers/media/usb/airspy/airspy.c index d568452618d14..240a7cc56777d 100644 --- a/drivers/media/usb/airspy/airspy.c +++ b/drivers/media/usb/airspy/airspy.c @@ -123,7 +123,7 @@ struct airspy { /* USB control message buffer */ #define BUF_SIZE 128 - u8 buf[BUF_SIZE]; + u8 *buf; /* Current configuration */ unsigned int f_adc; @@ -856,6 +856,7 @@ static void airspy_video_release(struct v4l2_device *v) v4l2_ctrl_handler_free(&s->hdl); v4l2_device_unregister(&s->v4l2_dev); + kfree(s->buf); kfree(s); } @@ -963,7 +964,10 @@ static int airspy_probe(struct usb_interface *intf, { struct airspy *s; int ret; - u8 u8tmp, buf[BUF_SIZE]; + u8 u8tmp, *buf; + + buf = NULL; + ret = -ENOMEM; s = kzalloc(sizeof(struct airspy), GFP_KERNEL); if (s == NULL) { @@ -971,6 +975,13 @@ static int airspy_probe(struct usb_interface *intf, return -ENOMEM; } + s->buf = kzalloc(BUF_SIZE, GFP_KERNEL); + if (!s->buf) + goto err_free_mem; + buf = kzalloc(BUF_SIZE, GFP_KERNEL); + if (!buf) + goto err_free_mem; + mutex_init(&s->v4l2_lock); mutex_init(&s->vb_queue_lock); spin_lock_init(&s->queued_bufs_lock); @@ -1068,6 +1079,8 @@ err_free_controls: v4l2_ctrl_handler_free(&s->hdl); v4l2_device_unregister(&s->v4l2_dev); err_free_mem: + kfree(buf); + kfree(s->buf); kfree(s); return ret; } diff --git a/drivers/media/usb/pvrusb2/pvrusb2-hdw.c b/drivers/media/usb/pvrusb2/pvrusb2-hdw.c index a9666373af6b9..92d6db1ad00f5 100644 --- a/drivers/media/usb/pvrusb2/pvrusb2-hdw.c +++ b/drivers/media/usb/pvrusb2/pvrusb2-hdw.c @@ -2610,6 +2610,7 @@ struct pvr2_hdw *pvr2_hdw_create(struct usb_interface *intf, del_timer_sync(&hdw->encoder_run_timer); del_timer_sync(&hdw->encoder_wait_timer); flush_work(&hdw->workpoll); + v4l2_device_unregister(&hdw->v4l2_dev); usb_free_urb(hdw->ctl_read_urb); usb_free_urb(hdw->ctl_write_urb); kfree(hdw->ctl_read_buffer); diff --git a/drivers/media/usb/usbtv/usbtv-video.c b/drivers/media/usb/usbtv/usbtv-video.c index a714ad77ca8e2..1e30e05953dc6 100644 --- a/drivers/media/usb/usbtv/usbtv-video.c +++ b/drivers/media/usb/usbtv/usbtv-video.c @@ -136,6 +136,8 @@ static uint16_t usbtv_norm_to_16f_reg(v4l2_std_id norm) return 0x00a8; if (norm & (V4L2_STD_PAL_M | V4L2_STD_PAL_60)) return 0x00bc; + if (norm & V4L2_STD_PAL_Nc) + return 0x00fe; /* Fallback to automatic detection for other standards */ return 0x0000; } @@ -241,7 +243,8 @@ static int usbtv_select_norm(struct usbtv *usbtv, v4l2_std_id norm) static const v4l2_std_id ntsc_mask = V4L2_STD_NTSC | V4L2_STD_NTSC_443; static const v4l2_std_id pal_mask = - V4L2_STD_PAL | V4L2_STD_PAL_60 | V4L2_STD_PAL_M; + V4L2_STD_PAL | V4L2_STD_PAL_60 | V4L2_STD_PAL_M | + V4L2_STD_PAL_Nc; if (norm & ntsc_mask) ret = usbtv_set_regs(usbtv, ntsc, ARRAY_SIZE(ntsc)); diff --git a/drivers/media/usb/usbtv/usbtv.h b/drivers/media/usb/usbtv/usbtv.h index 77a368e90fd04..b9fa7c0088c9a 100644 --- a/drivers/media/usb/usbtv/usbtv.h +++ b/drivers/media/usb/usbtv/usbtv.h @@ -68,7 +68,8 @@ #define USBTV_ODD(chunk) ((be32_to_cpu(chunk[0]) & 0x0000f000) >> 15) #define USBTV_CHUNK_NO(chunk) (be32_to_cpu(chunk[0]) & 0x00000fff) -#define USBTV_TV_STD (V4L2_STD_525_60 | V4L2_STD_PAL | V4L2_STD_SECAM) +#define USBTV_TV_STD (V4L2_STD_525_60 | V4L2_STD_PAL | \ + V4L2_STD_PAL_Nc | V4L2_STD_SECAM) /* parameters for supported TV norms */ struct usbtv_norm_params { diff --git a/drivers/media/v4l2-core/v4l2-common.c b/drivers/media/v4l2-core/v4l2-common.c index df34b2a283bc2..1e38ad8906a20 100644 --- a/drivers/media/v4l2-core/v4l2-common.c +++ b/drivers/media/v4l2-core/v4l2-common.c @@ -266,6 +266,7 @@ const struct v4l2_format_info *v4l2_format_info(u32 format) { .format = V4L2_PIX_FMT_NV61, .pixel_enc = V4L2_PIXEL_ENC_YUV, .mem_planes = 1, .comp_planes = 2, .bpp = { 1, 2, 0, 0 }, .hdiv = 2, .vdiv = 1 }, { .format = V4L2_PIX_FMT_NV24, .pixel_enc = V4L2_PIXEL_ENC_YUV, .mem_planes = 1, .comp_planes = 2, .bpp = { 1, 2, 0, 0 }, .hdiv = 1, .vdiv = 1 }, { .format = V4L2_PIX_FMT_NV42, .pixel_enc = V4L2_PIXEL_ENC_YUV, .mem_planes = 1, .comp_planes = 2, .bpp = { 1, 2, 0, 0 }, .hdiv = 1, .vdiv = 1 }, + { .format = V4L2_PIX_FMT_P010, .pixel_enc = V4L2_PIXEL_ENC_YUV, .mem_planes = 1, .comp_planes = 2, .bpp = { 2, 2, 0, 0 }, .hdiv = 2, .vdiv = 1 }, { .format = V4L2_PIX_FMT_YUV410, .pixel_enc = V4L2_PIXEL_ENC_YUV, .mem_planes = 1, .comp_planes = 3, .bpp = { 1, 1, 1, 0 }, .hdiv = 4, .vdiv = 4 }, { .format = V4L2_PIX_FMT_YVU410, .pixel_enc = V4L2_PIXEL_ENC_YUV, .mem_planes = 1, .comp_planes = 3, .bpp = { 1, 1, 1, 0 }, .hdiv = 4, .vdiv = 4 }, diff --git a/drivers/media/v4l2-core/v4l2-ioctl.c b/drivers/media/v4l2-core/v4l2-ioctl.c index 6e0ddb70e341b..95b493ca78643 100644 --- a/drivers/media/v4l2-core/v4l2-ioctl.c +++ b/drivers/media/v4l2-core/v4l2-ioctl.c @@ -1306,6 +1306,7 @@ static void v4l_fill_fmtdesc(struct v4l2_fmtdesc *fmt) case V4L2_PIX_FMT_NV61: descr = "Y/CrCb 4:2:2"; break; case V4L2_PIX_FMT_NV24: descr = "Y/CbCr 4:4:4"; break; case V4L2_PIX_FMT_NV42: descr = "Y/CrCb 4:4:4"; break; + case V4L2_PIX_FMT_P010: descr = "10-bit Y/CrCb 4:2:0"; break; case V4L2_PIX_FMT_NV12_4L4: descr = "Y/CbCr 4:2:0 (4x4 Linear)"; break; case V4L2_PIX_FMT_NV12_16L16: descr = "Y/CbCr 4:2:0 (16x16 Linear)"; break; case V4L2_PIX_FMT_NV12_32L32: descr = "Y/CbCr 4:2:0 (32x32 Linear)"; break; diff --git a/drivers/staging/media/Kconfig b/drivers/staging/media/Kconfig index 1fd6a0c6e1d88..421ce9dbf44c2 100644 --- a/drivers/staging/media/Kconfig +++ b/drivers/staging/media/Kconfig @@ -22,10 +22,14 @@ if STAGING_MEDIA && MEDIA_SUPPORT # Please keep them in alphabetic order source "drivers/staging/media/atomisp/Kconfig" +source "drivers/staging/media/av7110/Kconfig" + source "drivers/staging/media/hantro/Kconfig" source "drivers/staging/media/imx/Kconfig" +source "drivers/staging/media/ipu3/Kconfig" + source "drivers/staging/media/max96712/Kconfig" source "drivers/staging/media/meson/vdec/Kconfig" @@ -34,14 +38,12 @@ source "drivers/staging/media/omap4iss/Kconfig" source "drivers/staging/media/rkvdec/Kconfig" -source "drivers/staging/media/sunxi/Kconfig" +source "drivers/staging/media/stkwebcam/Kconfig" -source "drivers/staging/media/zoran/Kconfig" +source "drivers/staging/media/sunxi/Kconfig" source "drivers/staging/media/tegra-video/Kconfig" -source "drivers/staging/media/ipu3/Kconfig" - -source "drivers/staging/media/av7110/Kconfig" +source "drivers/staging/media/zoran/Kconfig" endif diff --git a/drivers/staging/media/Makefile b/drivers/staging/media/Makefile index 66d6f6d51c863..950e96f10aad7 100644 --- a/drivers/staging/media/Makefile +++ b/drivers/staging/media/Makefile @@ -5,6 +5,7 @@ obj-$(CONFIG_VIDEO_MAX96712) += max96712/ obj-$(CONFIG_VIDEO_MESON_VDEC) += meson/vdec/ obj-$(CONFIG_VIDEO_OMAP4) += omap4iss/ obj-$(CONFIG_VIDEO_ROCKCHIP_VDEC) += rkvdec/ +obj-$(CONFIG_VIDEO_STKWEBCAM) += stkwebcam/ obj-$(CONFIG_VIDEO_SUNXI) += sunxi/ obj-$(CONFIG_VIDEO_TEGRA) += tegra-video/ obj-$(CONFIG_VIDEO_HANTRO) += hantro/ diff --git a/drivers/staging/media/atomisp/i2c/ov5693/ov5693.h b/drivers/staging/media/atomisp/i2c/ov5693/ov5693.h index 79df07bd69b65..a1366666f49ce 100644 --- a/drivers/staging/media/atomisp/i2c/ov5693/ov5693.h +++ b/drivers/staging/media/atomisp/i2c/ov5693/ov5693.h @@ -855,7 +855,7 @@ static struct ov5693_reg const ov5693_1616x1216_30fps[] = { {OV5693_8BIT, 0x3813, 0x06}, /*{3812,3813} windowing Y offset*/ {OV5693_8BIT, 0x3814, 0x11}, /*X subsample control*/ {OV5693_8BIT, 0x3815, 0x11}, /*Y subsample control*/ - {OV5693_8BIT, 0x3820, 0x00}, /*FLIP/Binnning control*/ + {OV5693_8BIT, 0x3820, 0x00}, /*FLIP/Binning control*/ {OV5693_8BIT, 0x3821, 0x1e}, /*MIRROR control*/ {OV5693_8BIT, 0x5002, 0x00}, {OV5693_8BIT, 0x5041, 0x84}, diff --git a/drivers/staging/media/hantro/hantro_drv.c b/drivers/staging/media/hantro/hantro_drv.c index ac232b5f7825c..01d33dcb04679 100644 --- a/drivers/staging/media/hantro/hantro_drv.c +++ b/drivers/staging/media/hantro/hantro_drv.c @@ -253,6 +253,11 @@ queue_init(void *priv, struct vb2_queue *src_vq, struct vb2_queue *dst_vq) static int hantro_try_ctrl(struct v4l2_ctrl *ctrl) { + struct hantro_ctx *ctx; + + ctx = container_of(ctrl->handler, + struct hantro_ctx, ctrl_handler); + if (ctrl->id == V4L2_CID_STATELESS_H264_SPS) { const struct v4l2_ctrl_h264_sps *sps = ctrl->p_new.p_h264_sps; @@ -268,12 +273,7 @@ static int hantro_try_ctrl(struct v4l2_ctrl *ctrl) } else if (ctrl->id == V4L2_CID_MPEG_VIDEO_HEVC_SPS) { const struct v4l2_ctrl_hevc_sps *sps = ctrl->p_new.p_hevc_sps; - if (sps->bit_depth_luma_minus8 != sps->bit_depth_chroma_minus8) - /* Luma and chroma bit depth mismatch */ - return -EINVAL; - if (sps->bit_depth_luma_minus8 != 0) - /* Only 8-bit is supported */ - return -EINVAL; + return hantro_hevc_validate_sps(ctx, sps); } else if (ctrl->id == V4L2_CID_STATELESS_VP9_FRAME) { const struct v4l2_ctrl_vp9_frame *dec_params = ctrl->p_new.p_vp9_frame; diff --git a/drivers/staging/media/hantro/hantro_g2_regs.h b/drivers/staging/media/hantro/hantro_g2_regs.h index 877d663a81813..82606783591a2 100644 --- a/drivers/staging/media/hantro/hantro_g2_regs.h +++ b/drivers/staging/media/hantro/hantro_g2_regs.h @@ -107,7 +107,7 @@ #define g2_start_code_e G2_DEC_REG(10, 31, 0x1) #define g2_init_qp_old G2_DEC_REG(10, 25, 0x3f) -#define g2_init_qp G2_DEC_REG(10, 24, 0x3f) +#define g2_init_qp G2_DEC_REG(10, 24, 0x7f) #define g2_num_tile_cols_old G2_DEC_REG(10, 20, 0x1f) #define g2_num_tile_cols G2_DEC_REG(10, 19, 0x1f) #define g2_num_tile_rows_old G2_DEC_REG(10, 15, 0x1f) diff --git a/drivers/staging/media/hantro/hantro_hevc.c b/drivers/staging/media/hantro/hantro_hevc.c index f86c98e191776..bd924896e409e 100644 --- a/drivers/staging/media/hantro/hantro_hevc.c +++ b/drivers/staging/media/hantro/hantro_hevc.c @@ -154,6 +154,32 @@ err_free_tile_buffers: return -ENOMEM; } +int hantro_hevc_validate_sps(struct hantro_ctx *ctx, const struct v4l2_ctrl_hevc_sps *sps) +{ + if (sps->bit_depth_luma_minus8 != sps->bit_depth_chroma_minus8) + /* Luma and chroma bit depth mismatch */ + return -EINVAL; + if (sps->bit_depth_luma_minus8 != 0) + /* Only 8-bit is supported */ + return -EINVAL; + + /* + * for tile pixel format check if the width and height match + * hardware constraints + */ + if (ctx->vpu_dst_fmt->fourcc == V4L2_PIX_FMT_NV12_4L4) { + if (ctx->dst_fmt.width != + ALIGN(sps->pic_width_in_luma_samples, ctx->vpu_dst_fmt->frmsize.step_width)) + return -EINVAL; + + if (ctx->dst_fmt.height != + ALIGN(sps->pic_height_in_luma_samples, ctx->vpu_dst_fmt->frmsize.step_height)) + return -EINVAL; + } + + return 0; +} + int hantro_hevc_dec_prepare_run(struct hantro_ctx *ctx) { struct hantro_hevc_dec_hw_ctx *hevc_ctx = &ctx->hevc_dec; @@ -177,6 +203,10 @@ int hantro_hevc_dec_prepare_run(struct hantro_ctx *ctx) if (WARN_ON(!ctrls->sps)) return -EINVAL; + ret = hantro_hevc_validate_sps(ctx, ctrls->sps); + if (ret) + return ret; + ctrls->pps = hantro_get_ctrl(ctx, V4L2_CID_MPEG_VIDEO_HEVC_PPS); if (WARN_ON(!ctrls->pps)) diff --git a/drivers/staging/media/hantro/hantro_hw.h b/drivers/staging/media/hantro/hantro_hw.h index 52a960f6fa4a6..a2e0f08362815 100644 --- a/drivers/staging/media/hantro/hantro_hw.h +++ b/drivers/staging/media/hantro/hantro_hw.h @@ -18,9 +18,21 @@ #define DEC_8190_ALIGN_MASK 0x07U #define MB_DIM 16 +#define TILE_MB_DIM 4 #define MB_WIDTH(w) DIV_ROUND_UP(w, MB_DIM) #define MB_HEIGHT(h) DIV_ROUND_UP(h, MB_DIM) +#define FMT_MIN_WIDTH 48 +#define FMT_MIN_HEIGHT 48 +#define FMT_HD_WIDTH 1280 +#define FMT_HD_HEIGHT 720 +#define FMT_FHD_WIDTH 1920 +#define FMT_FHD_HEIGHT 1088 +#define FMT_UHD_WIDTH 3840 +#define FMT_UHD_HEIGHT 2160 +#define FMT_4K_WIDTH 4096 +#define FMT_4K_HEIGHT 2304 + #define NUM_REF_PICTURES (V4L2_HEVC_DPB_ENTRIES_NUM_MAX + 1) struct hantro_dev; @@ -347,6 +359,8 @@ int hantro_hevc_dec_prepare_run(struct hantro_ctx *ctx); void hantro_hevc_ref_init(struct hantro_ctx *ctx); dma_addr_t hantro_hevc_get_ref_buf(struct hantro_ctx *ctx, int poc); int hantro_hevc_add_ref_buf(struct hantro_ctx *ctx, int poc, dma_addr_t addr); +int hantro_hevc_validate_sps(struct hantro_ctx *ctx, const struct v4l2_ctrl_hevc_sps *sps); + static inline unsigned short hantro_vp9_num_sbs(unsigned short dimension) { diff --git a/drivers/staging/media/hantro/hantro_v4l2.c b/drivers/staging/media/hantro/hantro_v4l2.c index 22ad182ee972c..29cc61d53b71a 100644 --- a/drivers/staging/media/hantro/hantro_v4l2.c +++ b/drivers/staging/media/hantro/hantro_v4l2.c @@ -259,7 +259,7 @@ static int hantro_try_fmt(const struct hantro_ctx *ctx, } else if (ctx->is_encoder) { vpu_fmt = ctx->vpu_dst_fmt; } else { - vpu_fmt = ctx->vpu_src_fmt; + vpu_fmt = fmt; /* * Width/height on the CAPTURE end of a decoder are ignored and * replaced by the OUTPUT ones. diff --git a/drivers/staging/media/hantro/imx8m_vpu_hw.c b/drivers/staging/media/hantro/imx8m_vpu_hw.c index 9802508bade27..77f574fdfa77b 100644 --- a/drivers/staging/media/hantro/imx8m_vpu_hw.c +++ b/drivers/staging/media/hantro/imx8m_vpu_hw.c @@ -83,6 +83,14 @@ static const struct hantro_fmt imx8m_vpu_postproc_fmts[] = { .fourcc = V4L2_PIX_FMT_YUYV, .codec_mode = HANTRO_MODE_NONE, .postprocessed = true, + .frmsize = { + .min_width = FMT_MIN_WIDTH, + .max_width = FMT_UHD_WIDTH, + .step_width = MB_DIM, + .min_height = FMT_MIN_HEIGHT, + .max_height = FMT_UHD_HEIGHT, + .step_height = MB_DIM, + }, }, }; @@ -90,17 +98,25 @@ static const struct hantro_fmt imx8m_vpu_dec_fmts[] = { { .fourcc = V4L2_PIX_FMT_NV12, .codec_mode = HANTRO_MODE_NONE, + .frmsize = { + .min_width = FMT_MIN_WIDTH, + .max_width = FMT_UHD_WIDTH, + .step_width = MB_DIM, + .min_height = FMT_MIN_HEIGHT, + .max_height = FMT_UHD_HEIGHT, + .step_height = MB_DIM, + }, }, { .fourcc = V4L2_PIX_FMT_MPEG2_SLICE, .codec_mode = HANTRO_MODE_MPEG2_DEC, .max_depth = 2, .frmsize = { - .min_width = 48, - .max_width = 1920, + .min_width = FMT_MIN_WIDTH, + .max_width = FMT_FHD_WIDTH, .step_width = MB_DIM, - .min_height = 48, - .max_height = 1088, + .min_height = FMT_MIN_HEIGHT, + .max_height = FMT_FHD_HEIGHT, .step_height = MB_DIM, }, }, @@ -109,11 +125,11 @@ static const struct hantro_fmt imx8m_vpu_dec_fmts[] = { .codec_mode = HANTRO_MODE_VP8_DEC, .max_depth = 2, .frmsize = { - .min_width = 48, - .max_width = 3840, + .min_width = FMT_MIN_WIDTH, + .max_width = FMT_UHD_WIDTH, .step_width = MB_DIM, - .min_height = 48, - .max_height = 2160, + .min_height = FMT_MIN_HEIGHT, + .max_height = FMT_UHD_HEIGHT, .step_height = MB_DIM, }, }, @@ -122,11 +138,11 @@ static const struct hantro_fmt imx8m_vpu_dec_fmts[] = { .codec_mode = HANTRO_MODE_H264_DEC, .max_depth = 2, .frmsize = { - .min_width = 48, - .max_width = 3840, + .min_width = FMT_MIN_WIDTH, + .max_width = FMT_UHD_WIDTH, .step_width = MB_DIM, - .min_height = 48, - .max_height = 2160, + .min_height = FMT_MIN_HEIGHT, + .max_height = FMT_UHD_HEIGHT, .step_height = MB_DIM, }, }, @@ -137,6 +153,14 @@ static const struct hantro_fmt imx8m_vpu_g2_postproc_fmts[] = { .fourcc = V4L2_PIX_FMT_NV12, .codec_mode = HANTRO_MODE_NONE, .postprocessed = true, + .frmsize = { + .min_width = FMT_MIN_WIDTH, + .max_width = FMT_UHD_WIDTH, + .step_width = MB_DIM, + .min_height = FMT_MIN_HEIGHT, + .max_height = FMT_UHD_HEIGHT, + .step_height = MB_DIM, + }, }, }; @@ -144,18 +168,26 @@ static const struct hantro_fmt imx8m_vpu_g2_dec_fmts[] = { { .fourcc = V4L2_PIX_FMT_NV12_4L4, .codec_mode = HANTRO_MODE_NONE, + .frmsize = { + .min_width = FMT_MIN_WIDTH, + .max_width = FMT_UHD_WIDTH, + .step_width = TILE_MB_DIM, + .min_height = FMT_MIN_HEIGHT, + .max_height = FMT_UHD_HEIGHT, + .step_height = TILE_MB_DIM, + }, }, { .fourcc = V4L2_PIX_FMT_HEVC_SLICE, .codec_mode = HANTRO_MODE_HEVC_DEC, .max_depth = 2, .frmsize = { - .min_width = 48, - .max_width = 3840, - .step_width = MB_DIM, - .min_height = 48, - .max_height = 2160, - .step_height = MB_DIM, + .min_width = FMT_MIN_WIDTH, + .max_width = FMT_UHD_WIDTH, + .step_width = TILE_MB_DIM, + .min_height = FMT_MIN_HEIGHT, + .max_height = FMT_UHD_HEIGHT, + .step_height = TILE_MB_DIM, }, }, { @@ -163,12 +195,12 @@ static const struct hantro_fmt imx8m_vpu_g2_dec_fmts[] = { .codec_mode = HANTRO_MODE_VP9_DEC, .max_depth = 2, .frmsize = { - .min_width = 48, - .max_width = 3840, - .step_width = MB_DIM, - .min_height = 48, - .max_height = 2160, - .step_height = MB_DIM, + .min_width = FMT_MIN_WIDTH, + .max_width = FMT_UHD_WIDTH, + .step_width = TILE_MB_DIM, + .min_height = FMT_MIN_HEIGHT, + .max_height = FMT_UHD_HEIGHT, + .step_height = TILE_MB_DIM, }, }, }; diff --git a/drivers/staging/media/hantro/rockchip_vpu_hw.c b/drivers/staging/media/hantro/rockchip_vpu_hw.c index fc96501f3bc87..098486b9ec279 100644 --- a/drivers/staging/media/hantro/rockchip_vpu_hw.c +++ b/drivers/staging/media/hantro/rockchip_vpu_hw.c @@ -63,6 +63,14 @@ static const struct hantro_fmt rockchip_vpu1_postproc_fmts[] = { .fourcc = V4L2_PIX_FMT_YUYV, .codec_mode = HANTRO_MODE_NONE, .postprocessed = true, + .frmsize = { + .min_width = FMT_MIN_WIDTH, + .max_width = FMT_FHD_WIDTH, + .step_width = MB_DIM, + .min_height = FMT_MIN_HEIGHT, + .max_height = FMT_FHD_HEIGHT, + .step_height = MB_DIM, + }, }, }; @@ -70,17 +78,25 @@ static const struct hantro_fmt rk3066_vpu_dec_fmts[] = { { .fourcc = V4L2_PIX_FMT_NV12, .codec_mode = HANTRO_MODE_NONE, + .frmsize = { + .min_width = FMT_MIN_WIDTH, + .max_width = FMT_FHD_WIDTH, + .step_width = MB_DIM, + .min_height = FMT_MIN_HEIGHT, + .max_height = FMT_FHD_HEIGHT, + .step_height = MB_DIM, + }, }, { .fourcc = V4L2_PIX_FMT_H264_SLICE, .codec_mode = HANTRO_MODE_H264_DEC, .max_depth = 2, .frmsize = { - .min_width = 48, - .max_width = 1920, + .min_width = FMT_MIN_WIDTH, + .max_width = FMT_FHD_WIDTH, .step_width = MB_DIM, - .min_height = 48, - .max_height = 1088, + .min_height = FMT_MIN_HEIGHT, + .max_height = FMT_FHD_HEIGHT, .step_height = MB_DIM, }, }, @@ -89,11 +105,11 @@ static const struct hantro_fmt rk3066_vpu_dec_fmts[] = { .codec_mode = HANTRO_MODE_MPEG2_DEC, .max_depth = 2, .frmsize = { - .min_width = 48, - .max_width = 1920, + .min_width = FMT_MIN_WIDTH, + .max_width = FMT_FHD_WIDTH, .step_width = MB_DIM, - .min_height = 48, - .max_height = 1088, + .min_height = FMT_MIN_HEIGHT, + .max_height = FMT_FHD_HEIGHT, .step_height = MB_DIM, }, }, @@ -102,11 +118,11 @@ static const struct hantro_fmt rk3066_vpu_dec_fmts[] = { .codec_mode = HANTRO_MODE_VP8_DEC, .max_depth = 2, .frmsize = { - .min_width = 48, - .max_width = 1920, + .min_width = FMT_MIN_WIDTH, + .max_width = FMT_FHD_WIDTH, .step_width = MB_DIM, - .min_height = 48, - .max_height = 1088, + .min_height = FMT_MIN_HEIGHT, + .max_height = FMT_FHD_HEIGHT, .step_height = MB_DIM, }, }, @@ -116,17 +132,25 @@ static const struct hantro_fmt rk3288_vpu_dec_fmts[] = { { .fourcc = V4L2_PIX_FMT_NV12, .codec_mode = HANTRO_MODE_NONE, + .frmsize = { + .min_width = FMT_MIN_WIDTH, + .max_width = FMT_4K_WIDTH, + .step_width = MB_DIM, + .min_height = FMT_MIN_HEIGHT, + .max_height = FMT_4K_HEIGHT, + .step_height = MB_DIM, + }, }, { .fourcc = V4L2_PIX_FMT_H264_SLICE, .codec_mode = HANTRO_MODE_H264_DEC, .max_depth = 2, .frmsize = { - .min_width = 48, - .max_width = 4096, + .min_width = FMT_MIN_WIDTH, + .max_width = FMT_4K_WIDTH, .step_width = MB_DIM, - .min_height = 48, - .max_height = 2304, + .min_height = FMT_MIN_HEIGHT, + .max_height = FMT_4K_HEIGHT, .step_height = MB_DIM, }, }, @@ -135,11 +159,11 @@ static const struct hantro_fmt rk3288_vpu_dec_fmts[] = { .codec_mode = HANTRO_MODE_MPEG2_DEC, .max_depth = 2, .frmsize = { - .min_width = 48, - .max_width = 1920, + .min_width = FMT_MIN_WIDTH, + .max_width = FMT_FHD_WIDTH, .step_width = MB_DIM, - .min_height = 48, - .max_height = 1088, + .min_height = FMT_MIN_HEIGHT, + .max_height = FMT_FHD_HEIGHT, .step_height = MB_DIM, }, }, @@ -148,11 +172,11 @@ static const struct hantro_fmt rk3288_vpu_dec_fmts[] = { .codec_mode = HANTRO_MODE_VP8_DEC, .max_depth = 2, .frmsize = { - .min_width = 48, - .max_width = 3840, + .min_width = FMT_MIN_WIDTH, + .max_width = FMT_UHD_WIDTH, .step_width = MB_DIM, - .min_height = 48, - .max_height = 2160, + .min_height = FMT_MIN_HEIGHT, + .max_height = FMT_UHD_HEIGHT, .step_height = MB_DIM, }, }, @@ -162,17 +186,25 @@ static const struct hantro_fmt rk3399_vpu_dec_fmts[] = { { .fourcc = V4L2_PIX_FMT_NV12, .codec_mode = HANTRO_MODE_NONE, + .frmsize = { + .min_width = FMT_MIN_WIDTH, + .max_width = FMT_FHD_WIDTH, + .step_width = MB_DIM, + .min_height = FMT_MIN_HEIGHT, + .max_height = FMT_FHD_HEIGHT, + .step_height = MB_DIM, + }, }, { .fourcc = V4L2_PIX_FMT_H264_SLICE, .codec_mode = HANTRO_MODE_H264_DEC, .max_depth = 2, .frmsize = { - .min_width = 48, - .max_width = 1920, + .min_width = FMT_MIN_WIDTH, + .max_width = FMT_FHD_WIDTH, .step_width = MB_DIM, - .min_height = 48, - .max_height = 1088, + .min_height = FMT_MIN_HEIGHT, + .max_height = FMT_FHD_HEIGHT, .step_height = MB_DIM, }, }, @@ -181,11 +213,11 @@ static const struct hantro_fmt rk3399_vpu_dec_fmts[] = { .codec_mode = HANTRO_MODE_MPEG2_DEC, .max_depth = 2, .frmsize = { - .min_width = 48, - .max_width = 1920, + .min_width = FMT_MIN_WIDTH, + .max_width = FMT_FHD_WIDTH, .step_width = MB_DIM, - .min_height = 48, - .max_height = 1088, + .min_height = FMT_MIN_HEIGHT, + .max_height = FMT_FHD_HEIGHT, .step_height = MB_DIM, }, }, @@ -194,11 +226,11 @@ static const struct hantro_fmt rk3399_vpu_dec_fmts[] = { .codec_mode = HANTRO_MODE_VP8_DEC, .max_depth = 2, .frmsize = { - .min_width = 48, - .max_width = 3840, + .min_width = FMT_MIN_WIDTH, + .max_width = FMT_UHD_WIDTH, .step_width = MB_DIM, - .min_height = 48, - .max_height = 2160, + .min_height = FMT_MIN_HEIGHT, + .max_height = FMT_UHD_HEIGHT, .step_height = MB_DIM, }, }, diff --git a/drivers/staging/media/hantro/sama5d4_vdec_hw.c b/drivers/staging/media/hantro/sama5d4_vdec_hw.c index b2fc1c5613e19..b205e2db5b04d 100644 --- a/drivers/staging/media/hantro/sama5d4_vdec_hw.c +++ b/drivers/staging/media/hantro/sama5d4_vdec_hw.c @@ -16,6 +16,14 @@ static const struct hantro_fmt sama5d4_vdec_postproc_fmts[] = { .fourcc = V4L2_PIX_FMT_YUYV, .codec_mode = HANTRO_MODE_NONE, .postprocessed = true, + .frmsize = { + .min_width = FMT_MIN_WIDTH, + .max_width = FMT_HD_WIDTH, + .step_width = MB_DIM, + .min_height = FMT_MIN_HEIGHT, + .max_height = FMT_HD_HEIGHT, + .step_height = MB_DIM, + }, }, }; @@ -23,17 +31,25 @@ static const struct hantro_fmt sama5d4_vdec_fmts[] = { { .fourcc = V4L2_PIX_FMT_NV12, .codec_mode = HANTRO_MODE_NONE, + .frmsize = { + .min_width = FMT_MIN_WIDTH, + .max_width = FMT_HD_WIDTH, + .step_width = MB_DIM, + .min_height = FMT_MIN_HEIGHT, + .max_height = FMT_HD_HEIGHT, + .step_height = MB_DIM, + }, }, { .fourcc = V4L2_PIX_FMT_MPEG2_SLICE, .codec_mode = HANTRO_MODE_MPEG2_DEC, .max_depth = 2, .frmsize = { - .min_width = 48, - .max_width = 1280, + .min_width = FMT_MIN_WIDTH, + .max_width = FMT_HD_WIDTH, .step_width = MB_DIM, - .min_height = 48, - .max_height = 720, + .min_height = FMT_MIN_HEIGHT, + .max_height = FMT_HD_HEIGHT, .step_height = MB_DIM, }, }, @@ -42,11 +58,11 @@ static const struct hantro_fmt sama5d4_vdec_fmts[] = { .codec_mode = HANTRO_MODE_VP8_DEC, .max_depth = 2, .frmsize = { - .min_width = 48, - .max_width = 1280, + .min_width = FMT_MIN_WIDTH, + .max_width = FMT_HD_WIDTH, .step_width = MB_DIM, - .min_height = 48, - .max_height = 720, + .min_height = FMT_MIN_HEIGHT, + .max_height = FMT_HD_HEIGHT, .step_height = MB_DIM, }, }, @@ -55,11 +71,11 @@ static const struct hantro_fmt sama5d4_vdec_fmts[] = { .codec_mode = HANTRO_MODE_H264_DEC, .max_depth = 2, .frmsize = { - .min_width = 48, - .max_width = 1280, + .min_width = FMT_MIN_WIDTH, + .max_width = FMT_HD_WIDTH, .step_width = MB_DIM, - .min_height = 48, - .max_height = 720, + .min_height = FMT_MIN_HEIGHT, + .max_height = FMT_HD_HEIGHT, .step_height = MB_DIM, }, }, diff --git a/drivers/staging/media/hantro/sunxi_vpu_hw.c b/drivers/staging/media/hantro/sunxi_vpu_hw.c index c0edd5856a0c8..fbeac81e59e13 100644 --- a/drivers/staging/media/hantro/sunxi_vpu_hw.c +++ b/drivers/staging/media/hantro/sunxi_vpu_hw.c @@ -14,6 +14,14 @@ static const struct hantro_fmt sunxi_vpu_postproc_fmts[] = { .fourcc = V4L2_PIX_FMT_NV12, .codec_mode = HANTRO_MODE_NONE, .postprocessed = true, + .frmsize = { + .min_width = FMT_MIN_WIDTH, + .max_width = FMT_UHD_WIDTH, + .step_width = 32, + .min_height = FMT_MIN_HEIGHT, + .max_height = FMT_UHD_HEIGHT, + .step_height = 32, + }, }, }; @@ -21,17 +29,25 @@ static const struct hantro_fmt sunxi_vpu_dec_fmts[] = { { .fourcc = V4L2_PIX_FMT_NV12_4L4, .codec_mode = HANTRO_MODE_NONE, + .frmsize = { + .min_width = FMT_MIN_WIDTH, + .max_width = FMT_UHD_WIDTH, + .step_width = 32, + .min_height = FMT_MIN_HEIGHT, + .max_height = FMT_UHD_HEIGHT, + .step_height = 32, + }, }, { .fourcc = V4L2_PIX_FMT_VP9_FRAME, .codec_mode = HANTRO_MODE_VP9_DEC, .max_depth = 2, .frmsize = { - .min_width = 48, - .max_width = 3840, + .min_width = FMT_MIN_WIDTH, + .max_width = FMT_UHD_WIDTH, .step_width = 32, - .min_height = 48, - .max_height = 2160, + .min_height = FMT_MIN_HEIGHT, + .max_height = FMT_UHD_HEIGHT, .step_height = 32, }, }, diff --git a/drivers/media/usb/stkwebcam/Kconfig b/drivers/staging/media/stkwebcam/Kconfig index d94d023f1aa0e..4450403dff41f 100644 --- a/drivers/media/usb/stkwebcam/Kconfig +++ b/drivers/staging/media/stkwebcam/Kconfig @@ -1,7 +1,8 @@ # SPDX-License-Identifier: GPL-2.0-only -config USB_STKWEBCAM - tristate "USB Syntek DC1125 Camera support" +config VIDEO_STKWEBCAM + tristate "USB Syntek DC1125 Camera support (DEPRECATED)" depends on VIDEO_DEV + depends on USB help Say Y here if you want to use this type of camera. Supported devices are typically found in some Asus laptops, @@ -9,6 +10,9 @@ config USB_STKWEBCAM may be supported by the stk11xx driver, from which this is derived, see <http://sourceforge.net/projects/syntekdriver/> + This driver is deprecated and is scheduled for removal by + the end of 2022. See the TODO file for more information. + To compile this driver as a module, choose M here: the module will be called stkwebcam. diff --git a/drivers/media/usb/stkwebcam/Makefile b/drivers/staging/media/stkwebcam/Makefile index daa9ae6d48c23..17ad7b6f43d0a 100644 --- a/drivers/media/usb/stkwebcam/Makefile +++ b/drivers/staging/media/stkwebcam/Makefile @@ -1,5 +1,5 @@ # SPDX-License-Identifier: GPL-2.0-only stkwebcam-objs := stk-webcam.o stk-sensor.o -obj-$(CONFIG_USB_STKWEBCAM) += stkwebcam.o +obj-$(CONFIG_VIDEO_STKWEBCAM) += stkwebcam.o diff --git a/drivers/staging/media/stkwebcam/TODO b/drivers/staging/media/stkwebcam/TODO new file mode 100644 index 0000000000000..735304a727292 --- /dev/null +++ b/drivers/staging/media/stkwebcam/TODO @@ -0,0 +1,12 @@ +This is a very old driver for very old hardware (specifically +laptops that use this sensor). In addition according to reports +the picture quality is quite bad. + +This is also one of the few drivers still not using the vb2 +framework (or even the old videobuf framework!), so this driver +is now deprecated with the intent of removing it altogether by +the end of 2022. + +In order to keep this driver it has to be converted to vb2. +If someone is interested in doing this work, then contact the +linux-media mailinglist (https://linuxtv.org/lists.php). diff --git a/drivers/media/usb/stkwebcam/stk-sensor.c b/drivers/staging/media/stkwebcam/stk-sensor.c index 94aa6a27f9341..94aa6a27f9341 100644 --- a/drivers/media/usb/stkwebcam/stk-sensor.c +++ b/drivers/staging/media/stkwebcam/stk-sensor.c diff --git a/drivers/media/usb/stkwebcam/stk-webcam.c b/drivers/staging/media/stkwebcam/stk-webcam.c index 787edb3d47c23..787edb3d47c23 100644 --- a/drivers/media/usb/stkwebcam/stk-webcam.c +++ b/drivers/staging/media/stkwebcam/stk-webcam.c diff --git a/drivers/media/usb/stkwebcam/stk-webcam.h b/drivers/staging/media/stkwebcam/stk-webcam.h index 136decffe9ced..136decffe9ced 100644 --- a/drivers/media/usb/stkwebcam/stk-webcam.h +++ b/drivers/staging/media/stkwebcam/stk-webcam.h diff --git a/drivers/staging/media/zoran/videocodec.c b/drivers/staging/media/zoran/videocodec.c index 3af7d02bd910a..a0c8bde5ec118 100644 --- a/drivers/staging/media/zoran/videocodec.c +++ b/drivers/staging/media/zoran/videocodec.c @@ -16,16 +16,6 @@ #include "videocodec.h" -static int videocodec_debug; -module_param(videocodec_debug, int, 0); -MODULE_PARM_DESC(videocodec_debug, "Debug level (0-4)"); - -#define dprintk(num, format, args...) \ - do { \ - if (videocodec_debug >= num) \ - printk(format, ##args); \ - } while (0) - struct attached_list { struct videocodec *codec; struct attached_list *next; @@ -47,6 +37,7 @@ static struct codec_list *codeclist_top; struct videocodec *videocodec_attach(struct videocodec_master *master) { struct codec_list *h = codeclist_top; + struct zoran *zr; struct attached_list *a, *ptr; struct videocodec *codec; int res; @@ -56,11 +47,13 @@ struct videocodec *videocodec_attach(struct videocodec_master *master) return NULL; } - dprintk(2, "%s: '%s', flags %lx, magic %lx\n", __func__, - master->name, master->flags, master->magic); + zr = videocodec_master_to_zoran(master); + + zrdev_dbg(zr, "%s: '%s', flags %lx, magic %lx\n", __func__, + master->name, master->flags, master->magic); if (!h) { - pr_err("%s: no device available\n", __func__); + zrdev_err(zr, "%s: no device available\n", __func__); return NULL; } @@ -68,7 +61,7 @@ struct videocodec *videocodec_attach(struct videocodec_master *master) // attach only if the slave has at least the flags // expected by the master if ((master->flags & h->codec->flags) == master->flags) { - dprintk(4, "%s: try '%s'\n", __func__, h->codec->name); + zrdev_dbg(zr, "%s: try '%s'\n", __func__, h->codec->name); codec = kmemdup(h->codec, sizeof(struct videocodec), GFP_KERNEL); if (!codec) @@ -79,7 +72,7 @@ struct videocodec *videocodec_attach(struct videocodec_master *master) codec->master_data = master; res = codec->setup(codec); if (res == 0) { - dprintk(3, "%s: '%s'\n", __func__, codec->name); + zrdev_dbg(zr, "%s: '%s'\n", __func__, codec->name); ptr = kzalloc(sizeof(*ptr), GFP_KERNEL); if (!ptr) goto out_kfree; @@ -88,12 +81,13 @@ struct videocodec *videocodec_attach(struct videocodec_master *master) a = h->list; if (!a) { h->list = ptr; - dprintk(4, "videocodec: first element\n"); + zrdev_dbg(zr, "videocodec: first element\n"); } else { while (a->next) a = a->next; // find end a->next = ptr; - dprintk(4, "videocodec: in after '%s'\n", h->codec->name); + zrdev_dbg(zr, "videocodec: in after '%s'\n", + h->codec->name); } h->attached += 1; @@ -105,7 +99,7 @@ struct videocodec *videocodec_attach(struct videocodec_master *master) h = h->next; } - pr_err("%s: no codec found!\n", __func__); + zrdev_err(zr, "%s: no codec found!\n", __func__); return NULL; out_kfree: @@ -116,6 +110,7 @@ struct videocodec *videocodec_attach(struct videocodec_master *master) int videocodec_detach(struct videocodec *codec) { struct codec_list *h = codeclist_top; + struct zoran *zr; struct attached_list *a, *prev; int res; @@ -124,11 +119,13 @@ int videocodec_detach(struct videocodec *codec) return -EINVAL; } - dprintk(2, "%s: '%s', type: %x, flags %lx, magic %lx\n", __func__, - codec->name, codec->type, codec->flags, codec->magic); + zr = videocodec_to_zoran(codec); + + zrdev_dbg(zr, "%s: '%s', type: %x, flags %lx, magic %lx\n", __func__, + codec->name, codec->type, codec->flags, codec->magic); if (!h) { - pr_err("%s: no device left...\n", __func__); + zrdev_err(zr, "%s: no device left...\n", __func__); return -ENXIO; } @@ -139,18 +136,19 @@ int videocodec_detach(struct videocodec *codec) if (codec == a->codec) { res = a->codec->unset(a->codec); if (res >= 0) { - dprintk(3, "%s: '%s'\n", __func__, a->codec->name); + zrdev_dbg(zr, "%s: '%s'\n", __func__, + a->codec->name); a->codec->master_data = NULL; } else { - pr_err("%s: '%s'\n", __func__, a->codec->name); + zrdev_err(zr, "%s: '%s'\n", __func__, a->codec->name); a->codec->master_data = NULL; } if (!prev) { h->list = a->next; - dprintk(4, "videocodec: delete first\n"); + zrdev_dbg(zr, "videocodec: delete first\n"); } else { prev->next = a->next; - dprintk(4, "videocodec: delete middle\n"); + zrdev_dbg(zr, "videocodec: delete middle\n"); } kfree(a->codec); kfree(a); @@ -163,22 +161,25 @@ int videocodec_detach(struct videocodec *codec) h = h->next; } - pr_err("%s: given codec not found!\n", __func__); + zrdev_err(zr, "%s: given codec not found!\n", __func__); return -EINVAL; } int videocodec_register(const struct videocodec *codec) { struct codec_list *ptr, *h = codeclist_top; + struct zoran *zr; if (!codec) { pr_err("%s: no data!\n", __func__); return -EINVAL; } - dprintk(2, - "videocodec: register '%s', type: %x, flags %lx, magic %lx\n", - codec->name, codec->type, codec->flags, codec->magic); + zr = videocodec_to_zoran((struct videocodec *)codec); + + zrdev_dbg(zr, + "videocodec: register '%s', type: %x, flags %lx, magic %lx\n", + codec->name, codec->type, codec->flags, codec->magic); ptr = kzalloc(sizeof(*ptr), GFP_KERNEL); if (!ptr) @@ -187,13 +188,13 @@ int videocodec_register(const struct videocodec *codec) if (!h) { codeclist_top = ptr; - dprintk(4, "videocodec: hooked in as first element\n"); + zrdev_dbg(zr, "videocodec: hooked in as first element\n"); } else { while (h->next) h = h->next; // find the end h->next = ptr; - dprintk(4, "videocodec: hooked in after '%s'\n", - h->codec->name); + zrdev_dbg(zr, "videocodec: hooked in after '%s'\n", + h->codec->name); } return 0; @@ -202,37 +203,41 @@ int videocodec_register(const struct videocodec *codec) int videocodec_unregister(const struct videocodec *codec) { struct codec_list *prev = NULL, *h = codeclist_top; + struct zoran *zr; if (!codec) { pr_err("%s: no data!\n", __func__); return -EINVAL; } - dprintk(2, - "videocodec: unregister '%s', type: %x, flags %lx, magic %lx\n", - codec->name, codec->type, codec->flags, codec->magic); + zr = videocodec_to_zoran((struct videocodec *)codec); + + zrdev_dbg(zr, + "videocodec: unregister '%s', type: %x, flags %lx, magic %lx\n", + codec->name, codec->type, codec->flags, codec->magic); if (!h) { - pr_err("%s: no device left...\n", __func__); + zrdev_err(zr, "%s: no device left...\n", __func__); return -ENXIO; } while (h) { if (codec == h->codec) { if (h->attached) { - pr_err("videocodec: '%s' is used\n", h->codec->name); + zrdev_err(zr, "videocodec: '%s' is used\n", + h->codec->name); return -EBUSY; } - dprintk(3, "videocodec: unregister '%s' is ok.\n", - h->codec->name); + zrdev_dbg(zr, "videocodec: unregister '%s' is ok.\n", + h->codec->name); if (!prev) { codeclist_top = h->next; - dprintk(4, - "videocodec: delete first element\n"); + zrdev_dbg(zr, + "videocodec: delete first element\n"); } else { prev->next = h->next; - dprintk(4, - "videocodec: delete middle element\n"); + zrdev_dbg(zr, + "videocodec: delete middle element\n"); } kfree(h); return 0; @@ -241,7 +246,7 @@ int videocodec_unregister(const struct videocodec *codec) h = h->next; } - pr_err("%s: given codec not found!\n", __func__); + zrdev_err(zr, "%s: given codec not found!\n", __func__); return -EINVAL; } diff --git a/drivers/staging/media/zoran/videocodec.h b/drivers/staging/media/zoran/videocodec.h index 9dea348fee404..5e6057edd3390 100644 --- a/drivers/staging/media/zoran/videocodec.h +++ b/drivers/staging/media/zoran/videocodec.h @@ -307,4 +307,19 @@ extern int videocodec_unregister(const struct videocodec *); int videocodec_debugfs_show(struct seq_file *m); +#include "zoran.h" +static inline struct zoran *videocodec_master_to_zoran(struct videocodec_master *master) +{ + struct zoran *zr = master->data; + + return zr; +} + +static inline struct zoran *videocodec_to_zoran(struct videocodec *codec) +{ + struct videocodec_master *master = codec->master_data; + + return videocodec_master_to_zoran(master); +} + #endif /*ifndef __LINUX_VIDEOCODEC_H */ diff --git a/drivers/staging/media/zoran/zoran.h b/drivers/staging/media/zoran/zoran.h index 654c95fa5aba9..05227e5298f60 100644 --- a/drivers/staging/media/zoran/zoran.h +++ b/drivers/staging/media/zoran/zoran.h @@ -19,6 +19,8 @@ #define _BUZ_H_ #include <linux/debugfs.h> +#include <linux/pci.h> +#include <linux/i2c-algo-bit.h> #include <media/v4l2-device.h> #include <media/v4l2-ctrls.h> #include <media/videobuf2-core.h> @@ -301,6 +303,18 @@ static inline struct zoran *to_zoran(struct v4l2_device *v4l2_dev) #endif +/* + * Debugging macros + */ +#define zrdev_dbg(zr, format, args...) \ + pci_dbg((zr)->pci_dev, format, ##args) \ + +#define zrdev_err(zr, format, args...) \ + pci_err((zr)->pci_dev, format, ##args) \ + +#define zrdev_info(zr, format, args...) \ + pci_info((zr)->pci_dev, format, ##args) \ + int zoran_queue_init(struct zoran *zr, struct vb2_queue *vq, int dir); void zoran_queue_exit(struct zoran *zr); int zr_set_buf(struct zoran *zr); diff --git a/drivers/staging/media/zoran/zr36016.c b/drivers/staging/media/zoran/zr36016.c index 26c7c32b6bc0f..0e0532537a3e0 100644 --- a/drivers/staging/media/zoran/zr36016.c +++ b/drivers/staging/media/zoran/zr36016.c @@ -22,17 +22,6 @@ /* amount of chips attached via this driver */ static int zr36016_codecs; -static int zr36016_debug; -module_param(zr36016_debug, int, 0); -MODULE_PARM_DESC(zr36016_debug, "Debug level (0-4)"); - - -#define dprintk(num, format, args...) \ - do { \ - if (zr36016_debug >= num) \ - printk(format, ##args); \ - } while (0) - /* ========================================================================= Local hardware I/O functions: @@ -43,27 +32,30 @@ MODULE_PARM_DESC(zr36016_debug, "Debug level (0-4)"); static u8 zr36016_read(struct zr36016 *ptr, u16 reg) { u8 value = 0; + struct zoran *zr = videocodec_to_zoran(ptr->codec); /* just in case something is wrong... */ if (ptr->codec->master_data->readreg) value = (ptr->codec->master_data->readreg(ptr->codec, reg)) & 0xFF; else - pr_err("%s: invalid I/O setup, nothing read!\n", ptr->name); + zrdev_err(zr, "%s: invalid I/O setup, nothing read!\n", ptr->name); - dprintk(4, "%s: reading from 0x%04x: %02x\n", ptr->name, reg, value); + zrdev_dbg(zr, "%s: reading from 0x%04x: %02x\n", ptr->name, reg, value); return value; } static void zr36016_write(struct zr36016 *ptr, u16 reg, u8 value) { - dprintk(4, "%s: writing 0x%02x to 0x%04x\n", ptr->name, value, reg); + struct zoran *zr = videocodec_to_zoran(ptr->codec); + + zrdev_dbg(zr, "%s: writing 0x%02x to 0x%04x\n", ptr->name, value, reg); // just in case something is wrong... if (ptr->codec->master_data->writereg) ptr->codec->master_data->writereg(ptr->codec, reg, value); else - pr_err("%s: invalid I/O setup, nothing written!\n", ptr->name); + zrdev_err(zr, "%s: invalid I/O setup, nothing written!\n", ptr->name); } /* indirect read and write functions */ @@ -72,30 +64,34 @@ static void zr36016_write(struct zr36016 *ptr, u16 reg, u8 value) static u8 zr36016_readi(struct zr36016 *ptr, u16 reg) { u8 value = 0; + struct zoran *zr = videocodec_to_zoran(ptr->codec); /* just in case something is wrong... */ if ((ptr->codec->master_data->writereg) && (ptr->codec->master_data->readreg)) { ptr->codec->master_data->writereg(ptr->codec, ZR016_IADDR, reg & 0x0F); // ADDR value = (ptr->codec->master_data->readreg(ptr->codec, ZR016_IDATA)) & 0xFF; // DATA } else { - pr_err("%s: invalid I/O setup, nothing read (i)!\n", ptr->name); + zrdev_err(zr, "%s: invalid I/O setup, nothing read (i)!\n", ptr->name); } - dprintk(4, "%s: reading indirect from 0x%04x: %02x\n", ptr->name, reg, value); + zrdev_dbg(zr, "%s: reading indirect from 0x%04x: %02x\n", + ptr->name, reg, value); return value; } static void zr36016_writei(struct zr36016 *ptr, u16 reg, u8 value) { - dprintk(4, "%s: writing indirect 0x%02x to 0x%04x\n", ptr->name, - value, reg); + struct zoran *zr = videocodec_to_zoran(ptr->codec); + + zrdev_dbg(zr, "%s: writing indirect 0x%02x to 0x%04x\n", ptr->name, + value, reg); /* just in case something is wrong... */ if (ptr->codec->master_data->writereg) { ptr->codec->master_data->writereg(ptr->codec, ZR016_IADDR, reg & 0x0F); // ADDR ptr->codec->master_data->writereg(ptr->codec, ZR016_IDATA, value & 0x0FF); // DATA } else { - pr_err("%s: invalid I/O setup, nothing written (i)!\n", ptr->name); + zrdev_err(zr, "%s: invalid I/O setup, nothing written (i)!\n", ptr->name); } } @@ -120,32 +116,34 @@ static u8 zr36016_read_version(struct zr36016 *ptr) static int zr36016_basic_test(struct zr36016 *ptr) { - if (zr36016_debug) { + struct zoran *zr = videocodec_to_zoran(ptr->codec); + + if (*KERN_INFO <= CONSOLE_LOGLEVEL_DEFAULT) { int i; zr36016_writei(ptr, ZR016I_PAX_LO, 0x55); - dprintk(1, KERN_INFO "%s: registers: ", ptr->name); + zrdev_dbg(zr, "%s: registers: ", ptr->name); for (i = 0; i <= 0x0b; i++) - dprintk(1, "%02x ", zr36016_readi(ptr, i)); - dprintk(1, "\n"); + zrdev_dbg(zr, "%02x ", zr36016_readi(ptr, i)); + zrdev_dbg(zr, "\n"); } // for testing just write 0, then the default value to a register and read // it back in both cases zr36016_writei(ptr, ZR016I_PAX_LO, 0x00); if (zr36016_readi(ptr, ZR016I_PAX_LO) != 0x0) { - pr_err("%s: attach failed, can't connect to vfe processor!\n", ptr->name); + zrdev_err(zr, "%s: attach failed, can't connect to vfe processor!\n", ptr->name); return -ENXIO; } zr36016_writei(ptr, ZR016I_PAX_LO, 0x0d0); if (zr36016_readi(ptr, ZR016I_PAX_LO) != 0x0d0) { - pr_err("%s: attach failed, can't connect to vfe processor!\n", ptr->name); + zrdev_err(zr, "%s: attach failed, can't connect to vfe processor!\n", ptr->name); return -ENXIO; } // we allow version numbers from 0-3, should be enough, though zr36016_read_version(ptr); if (ptr->version & 0x0c) { - pr_err("%s: attach failed, suspicious version %d found...\n", ptr->name, - ptr->version); + zrdev_err(zr, "%s: attach failed, suspicious version %d found...\n", ptr->name, + ptr->version); return -ENXIO; } @@ -164,10 +162,11 @@ static int zr36016_pushit(struct zr36016 *ptr, u16 len, const char *data) { + struct zoran *zr = videocodec_to_zoran(ptr->codec); int i = 0; - dprintk(4, "%s: write data block to 0x%04x (len=%d)\n", - ptr->name, startreg, len); + zrdev_dbg(zr, "%s: write data block to 0x%04x (len=%d)\n", + ptr->name, startreg, len); while (i < len) { zr36016_writei(ptr, startreg++, data[i++]); } @@ -225,8 +224,9 @@ static void zr36016_init(struct zr36016 *ptr) static int zr36016_set_mode(struct videocodec *codec, int mode) { struct zr36016 *ptr = (struct zr36016 *)codec->data; + struct zoran *zr = videocodec_to_zoran(codec); - dprintk(2, "%s: set_mode %d call\n", ptr->name, mode); + zrdev_dbg(zr, "%s: set_mode %d call\n", ptr->name, mode); if ((mode != CODEC_DO_EXPANSION) && (mode != CODEC_DO_COMPRESSION)) return -EINVAL; @@ -242,11 +242,12 @@ static int zr36016_set_video(struct videocodec *codec, const struct tvnorm *norm struct vfe_settings *cap, struct vfe_polarity *pol) { struct zr36016 *ptr = (struct zr36016 *)codec->data; + struct zoran *zr = videocodec_to_zoran(codec); - dprintk(2, "%s: set_video %d.%d, %d/%d-%dx%d (0x%x) call\n", - ptr->name, norm->h_start, norm->v_start, - cap->x, cap->y, cap->width, cap->height, - cap->decimation); + zrdev_dbg(zr, "%s: set_video %d.%d, %d/%d-%dx%d (0x%x) call\n", + ptr->name, norm->h_start, norm->v_start, + cap->x, cap->y, cap->width, cap->height, + cap->decimation); /* if () return -EINVAL; * trust the master driver that it knows what it does - so @@ -276,9 +277,11 @@ static int zr36016_set_video(struct videocodec *codec, const struct tvnorm *norm static int zr36016_control(struct videocodec *codec, int type, int size, void *data) { struct zr36016 *ptr = (struct zr36016 *)codec->data; + struct zoran *zr = videocodec_to_zoran(codec); int *ival = (int *)data; - dprintk(2, "%s: control %d call with %d byte\n", ptr->name, type, size); + zrdev_dbg(zr, "%s: control %d call with %d byte\n", + ptr->name, type, size); switch (type) { case CODEC_G_STATUS: /* get last status - we don't know it ... */ @@ -325,11 +328,12 @@ static int zr36016_control(struct videocodec *codec, int type, int size, void *d static int zr36016_unset(struct videocodec *codec) { struct zr36016 *ptr = codec->data; + struct zoran *zr = videocodec_to_zoran(codec); if (ptr) { /* do wee need some codec deinit here, too ???? */ - dprintk(1, "%s: finished codec #%d\n", ptr->name, ptr->num); + zrdev_dbg(zr, "%s: finished codec #%d\n", ptr->name, ptr->num); kfree(ptr); codec->data = NULL; @@ -352,12 +356,13 @@ static int zr36016_unset(struct videocodec *codec) static int zr36016_setup(struct videocodec *codec) { struct zr36016 *ptr; + struct zoran *zr = videocodec_to_zoran(codec); int res; - dprintk(2, "zr36016: initializing VFE subsystem #%d.\n", zr36016_codecs); + zrdev_dbg(zr, "zr36016: initializing VFE subsystem #%d.\n", zr36016_codecs); if (zr36016_codecs == MAX_CODECS) { - pr_err("zr36016: Can't attach more codecs!\n"); + zrdev_err(zr, "zr36016: Can't attach more codecs!\n"); return -ENOSPC; } //mem structure init @@ -384,7 +389,8 @@ static int zr36016_setup(struct videocodec *codec) ptr->ydec = 0; zr36016_init(ptr); - dprintk(1, KERN_INFO "%s: codec v%d attached and running\n", ptr->name, ptr->version); + zrdev_dbg(zr, "%s: codec v%d attached and running\n", + ptr->name, ptr->version); return 0; } @@ -417,9 +423,8 @@ int zr36016_init_module(void) void zr36016_cleanup_module(void) { if (zr36016_codecs) { - dprintk(1, - "zr36016: something's wrong - %d codecs left somehow.\n", - zr36016_codecs); + pr_debug("zr36016: something's wrong - %d codecs left somehow.\n", + zr36016_codecs); } videocodec_unregister(&zr36016_codec); } diff --git a/drivers/staging/media/zoran/zr36050.c b/drivers/staging/media/zoran/zr36050.c index 38f7021e7b06c..6a7ef28d996cc 100644 --- a/drivers/staging/media/zoran/zr36050.c +++ b/drivers/staging/media/zoran/zr36050.c @@ -29,17 +29,6 @@ /* amount of chips attached via this driver */ static int zr36050_codecs; -/* debugging is available via module parameter */ -static int zr36050_debug; -module_param(zr36050_debug, int, 0); -MODULE_PARM_DESC(zr36050_debug, "Debug level (0-4)"); - -#define dprintk(num, format, args...) \ - do { \ - if (zr36050_debug >= num) \ - printk(format, ##args); \ - } while (0) - /* ========================================================================= Local hardware I/O functions: @@ -49,32 +38,32 @@ MODULE_PARM_DESC(zr36050_debug, "Debug level (0-4)"); /* read and write functions */ static u8 zr36050_read(struct zr36050 *ptr, u16 reg) { + struct zoran *zr = videocodec_to_zoran(ptr->codec); u8 value = 0; /* just in case something is wrong... */ if (ptr->codec->master_data->readreg) value = (ptr->codec->master_data->readreg(ptr->codec, reg)) & 0xFF; else - dprintk(1, - KERN_ERR "%s: invalid I/O setup, nothing read!\n", ptr->name); + zrdev_err(zr, "%s: invalid I/O setup, nothing read!\n", ptr->name); - dprintk(4, "%s: reading from 0x%04x: %02x\n", ptr->name, reg, value); + zrdev_dbg(zr, "%s: reading from 0x%04x: %02x\n", ptr->name, reg, value); return value; } static void zr36050_write(struct zr36050 *ptr, u16 reg, u8 value) { - dprintk(4, "%s: writing 0x%02x to 0x%04x\n", ptr->name, value, reg); + struct zoran *zr = videocodec_to_zoran(ptr->codec); + + zrdev_dbg(zr, "%s: writing 0x%02x to 0x%04x\n", ptr->name, value, reg); /* just in case something is wrong... */ if (ptr->codec->master_data->writereg) ptr->codec->master_data->writereg(ptr->codec, reg, value); else - dprintk(1, - KERN_ERR - "%s: invalid I/O setup, nothing written!\n", - ptr->name); + zrdev_err(zr, "%s: invalid I/O setup, nothing written!\n", + ptr->name); } /* ========================================================================= @@ -117,14 +106,15 @@ static u16 zr36050_read_scalefactor(struct zr36050 *ptr) static void zr36050_wait_end(struct zr36050 *ptr) { + struct zoran *zr = videocodec_to_zoran(ptr->codec); int i = 0; while (!(zr36050_read_status1(ptr) & 0x4)) { udelay(1); if (i++ > 200000) { // 200ms, there is for sure something wrong!!! - dprintk(1, - "%s: timeout at wait_end (last status: 0x%02x)\n", - ptr->name, ptr->status1); + zrdev_err(zr, + "%s: timeout at wait_end (last status: 0x%02x)\n", + ptr->name, ptr->status1); break; } } @@ -138,33 +128,32 @@ static void zr36050_wait_end(struct zr36050 *ptr) static int zr36050_basic_test(struct zr36050 *ptr) { + struct zoran *zr = videocodec_to_zoran(ptr->codec); + zr36050_write(ptr, ZR050_SOF_IDX, 0x00); zr36050_write(ptr, ZR050_SOF_IDX + 1, 0x00); if ((zr36050_read(ptr, ZR050_SOF_IDX) | zr36050_read(ptr, ZR050_SOF_IDX + 1)) != 0x0000) { - dprintk(1, - KERN_ERR - "%s: attach failed, can't connect to jpeg processor!\n", - ptr->name); + zrdev_err(zr, + "%s: attach failed, can't connect to jpeg processor!\n", + ptr->name); return -ENXIO; } zr36050_write(ptr, ZR050_SOF_IDX, 0xff); zr36050_write(ptr, ZR050_SOF_IDX + 1, 0xc0); if (((zr36050_read(ptr, ZR050_SOF_IDX) << 8) | zr36050_read(ptr, ZR050_SOF_IDX + 1)) != 0xffc0) { - dprintk(1, - KERN_ERR - "%s: attach failed, can't connect to jpeg processor!\n", - ptr->name); + zrdev_err(zr, + "%s: attach failed, can't connect to jpeg processor!\n", + ptr->name); return -ENXIO; } zr36050_wait_end(ptr); if ((ptr->status1 & 0x4) == 0) { - dprintk(1, - KERN_ERR - "%s: attach failed, jpeg processor failed (end flag)!\n", - ptr->name); + zrdev_err(zr, + "%s: attach failed, jpeg processor failed (end flag)!\n", + ptr->name); return -EBUSY; } @@ -179,10 +168,11 @@ static int zr36050_basic_test(struct zr36050 *ptr) static int zr36050_pushit(struct zr36050 *ptr, u16 startreg, u16 len, const char *data) { + struct zoran *zr = videocodec_to_zoran(ptr->codec); int i = 0; - dprintk(4, "%s: write data block to 0x%04x (len=%d)\n", ptr->name, - startreg, len); + zrdev_dbg(zr, "%s: write data block to 0x%04x (len=%d)\n", ptr->name, + startreg, len); while (i < len) zr36050_write(ptr, startreg++, data[i++]); @@ -305,11 +295,12 @@ static const char zr36050_decimation_v[8] = { 1, 1, 1, 0, 0, 0, 0, 0 }; static int zr36050_set_sof(struct zr36050 *ptr) { + struct zoran *zr = videocodec_to_zoran(ptr->codec); char sof_data[34]; // max. size of register set int i; - dprintk(3, "%s: write SOF (%dx%d, %d components)\n", ptr->name, - ptr->width, ptr->height, NO_OF_COMPONENTS); + zrdev_dbg(zr, "%s: write SOF (%dx%d, %d components)\n", ptr->name, + ptr->width, ptr->height, NO_OF_COMPONENTS); sof_data[0] = 0xff; sof_data[1] = 0xc0; sof_data[2] = 0x00; @@ -336,10 +327,11 @@ static int zr36050_set_sof(struct zr36050 *ptr) static int zr36050_set_sos(struct zr36050 *ptr) { + struct zoran *zr = videocodec_to_zoran(ptr->codec); char sos_data[16]; // max. size of register set int i; - dprintk(3, "%s: write SOS\n", ptr->name); + zrdev_dbg(zr, "%s: write SOS\n", ptr->name); sos_data[0] = 0xff; sos_data[1] = 0xda; sos_data[2] = 0x00; @@ -363,9 +355,10 @@ static int zr36050_set_sos(struct zr36050 *ptr) static int zr36050_set_dri(struct zr36050 *ptr) { + struct zoran *zr = videocodec_to_zoran(ptr->codec); char dri_data[6]; // max. size of register set - dprintk(3, "%s: write DRI\n", ptr->name); + zrdev_dbg(zr, "%s: write DRI\n", ptr->name); dri_data[0] = 0xff; dri_data[1] = 0xdd; dri_data[2] = 0x00; @@ -387,9 +380,10 @@ static void zr36050_init(struct zr36050 *ptr) { int sum = 0; long bitcnt, tmp; + struct zoran *zr = videocodec_to_zoran(ptr->codec); if (ptr->mode == CODEC_DO_COMPRESSION) { - dprintk(2, "%s: COMPRESSION SETUP\n", ptr->name); + zrdev_dbg(zr, "%s: COMPRESSION SETUP\n", ptr->name); /* 050 communicates with 057 in master mode */ zr36050_write(ptr, ZR050_HARDWARE, ZR050_HW_MSTR); @@ -419,7 +413,7 @@ static void zr36050_init(struct zr36050 *ptr) /* setup the fixed jpeg tables - maybe variable, though - * (see table init section above) */ - dprintk(3, "%s: write DQT, DHT, APP\n", ptr->name); + zrdev_dbg(zr, "%s: write DQT, DHT, APP\n", ptr->name); sum += zr36050_pushit(ptr, ZR050_DQT_IDX, sizeof(zr36050_dqt), zr36050_dqt); sum += zr36050_pushit(ptr, ZR050_DHT_IDX, @@ -442,11 +436,11 @@ static void zr36050_init(struct zr36050 *ptr) zr36050_write(ptr, ZR050_GO, 1); // launch codec zr36050_wait_end(ptr); - dprintk(2, "%s: Status after table preload: 0x%02x\n", - ptr->name, ptr->status1); + zrdev_dbg(zr, "%s: Status after table preload: 0x%02x\n", + ptr->name, ptr->status1); if ((ptr->status1 & 0x4) == 0) { - pr_err("%s: init aborted!\n", ptr->name); + zrdev_err(zr, "%s: init aborted!\n", ptr->name); return; // something is wrong, its timed out!!!! } @@ -457,9 +451,9 @@ static void zr36050_init(struct zr36050 *ptr) bitcnt = sum << 3; /* need the size in bits */ tmp = bitcnt >> 16; - dprintk(3, - "%s: code: csize=%d, tot=%d, bit=%ld, highbits=%ld\n", - ptr->name, sum, ptr->real_code_vol, bitcnt, tmp); + zrdev_dbg(zr, + "%s: code: csize=%d, tot=%d, bit=%ld, highbits=%ld\n", + ptr->name, sum, ptr->real_code_vol, bitcnt, tmp); zr36050_write(ptr, ZR050_TCV_NET_HI, tmp >> 8); zr36050_write(ptr, ZR050_TCV_NET_MH, tmp & 0xff); tmp = bitcnt & 0xffff; @@ -470,8 +464,8 @@ static void zr36050_init(struct zr36050 *ptr) bitcnt -= ((bitcnt * 5) >> 6); // bits without eob tmp = bitcnt >> 16; - dprintk(3, "%s: code: nettobit=%ld, highnettobits=%ld\n", - ptr->name, bitcnt, tmp); + zrdev_dbg(zr, "%s: code: nettobit=%ld, highnettobits=%ld\n", + ptr->name, bitcnt, tmp); zr36050_write(ptr, ZR050_TCV_DATA_HI, tmp >> 8); zr36050_write(ptr, ZR050_TCV_DATA_MH, tmp & 0xff); tmp = bitcnt & 0xffff; @@ -489,7 +483,7 @@ static void zr36050_init(struct zr36050 *ptr) ((ptr->app.len > 0) ? ZR050_ME_APP : 0) | ((ptr->com.len > 0) ? ZR050_ME_COM : 0)); } else { - dprintk(2, "%s: EXPANSION SETUP\n", ptr->name); + zrdev_dbg(zr, "%s: EXPANSION SETUP\n", ptr->name); /* 050 communicates with 055 in master mode */ zr36050_write(ptr, ZR050_HARDWARE, @@ -502,7 +496,7 @@ static void zr36050_init(struct zr36050 *ptr) zr36050_write(ptr, ZR050_INT_REQ_0, 0); zr36050_write(ptr, ZR050_INT_REQ_1, 3); // low 2 bits always 1 - dprintk(3, "%s: write DHT\n", ptr->name); + zrdev_dbg(zr, "%s: write DHT\n", ptr->name); zr36050_pushit(ptr, ZR050_DHT_IDX, sizeof(zr36050_dht), zr36050_dht); @@ -511,11 +505,11 @@ static void zr36050_init(struct zr36050 *ptr) zr36050_write(ptr, ZR050_GO, 1); // launch codec zr36050_wait_end(ptr); - dprintk(2, "%s: Status after table preload: 0x%02x\n", - ptr->name, ptr->status1); + zrdev_dbg(zr, "%s: Status after table preload: 0x%02x\n", + ptr->name, ptr->status1); if ((ptr->status1 & 0x4) == 0) { - pr_err("%s: init aborted!\n", ptr->name); + zrdev_err(zr, "%s: init aborted!\n", ptr->name); return; // something is wrong, its timed out!!!! } @@ -539,8 +533,9 @@ static void zr36050_init(struct zr36050 *ptr) static int zr36050_set_mode(struct videocodec *codec, int mode) { struct zr36050 *ptr = (struct zr36050 *)codec->data; + struct zoran *zr = videocodec_to_zoran(codec); - dprintk(2, "%s: set_mode %d call\n", ptr->name, mode); + zrdev_dbg(zr, "%s: set_mode %d call\n", ptr->name, mode); if ((mode != CODEC_DO_EXPANSION) && (mode != CODEC_DO_COMPRESSION)) return -EINVAL; @@ -556,12 +551,13 @@ static int zr36050_set_video(struct videocodec *codec, const struct tvnorm *norm struct vfe_settings *cap, struct vfe_polarity *pol) { struct zr36050 *ptr = (struct zr36050 *)codec->data; + struct zoran *zr = videocodec_to_zoran(codec); int size; - dprintk(2, "%s: set_video %d.%d, %d/%d-%dx%d (0x%x) q%d call\n", - ptr->name, norm->h_start, norm->v_start, - cap->x, cap->y, cap->width, cap->height, - cap->decimation, cap->quality); + zrdev_dbg(zr, "%s: set_video %d.%d, %d/%d-%dx%d (0x%x) q%d call\n", + ptr->name, norm->h_start, norm->v_start, + cap->x, cap->y, cap->width, cap->height, + cap->decimation, cap->quality); /* if () return -EINVAL; * trust the master driver that it knows what it does - so * we allow invalid startx/y and norm for now ... */ @@ -594,10 +590,11 @@ static int zr36050_set_video(struct videocodec *codec, const struct tvnorm *norm static int zr36050_control(struct videocodec *codec, int type, int size, void *data) { struct zr36050 *ptr = (struct zr36050 *)codec->data; + struct zoran *zr = videocodec_to_zoran(codec); int *ival = (int *)data; - dprintk(2, "%s: control %d call with %d byte\n", ptr->name, type, - size); + zrdev_dbg(zr, "%s: control %d call with %d byte\n", ptr->name, type, + size); switch (type) { case CODEC_G_STATUS: /* get last status */ @@ -713,12 +710,13 @@ static int zr36050_control(struct videocodec *codec, int type, int size, void *d static int zr36050_unset(struct videocodec *codec) { struct zr36050 *ptr = codec->data; + struct zoran *zr = videocodec_to_zoran(codec); if (ptr) { /* do wee need some codec deinit here, too ???? */ - dprintk(1, "%s: finished codec #%d\n", ptr->name, - ptr->num); + zrdev_dbg(zr, "%s: finished codec #%d\n", ptr->name, + ptr->num); kfree(ptr); codec->data = NULL; @@ -741,14 +739,15 @@ static int zr36050_unset(struct videocodec *codec) static int zr36050_setup(struct videocodec *codec) { struct zr36050 *ptr; + struct zoran *zr = videocodec_to_zoran(codec); int res; - dprintk(2, "zr36050: initializing MJPEG subsystem #%d.\n", - zr36050_codecs); + zrdev_dbg(zr, "zr36050: initializing MJPEG subsystem #%d.\n", + zr36050_codecs); if (zr36050_codecs == MAX_CODECS) { - dprintk(1, - KERN_ERR "zr36050: Can't attach more codecs!\n"); + zrdev_err(zr, + "zr36050: Can't attach more codecs!\n"); return -ENOSPC; } //mem structure init @@ -789,8 +788,8 @@ static int zr36050_setup(struct videocodec *codec) zr36050_init(ptr); - dprintk(1, KERN_INFO "%s: codec attached and running\n", - ptr->name); + zrdev_info(zr, "%s: codec attached and running\n", + ptr->name); return 0; } @@ -823,9 +822,8 @@ int zr36050_init_module(void) void zr36050_cleanup_module(void) { if (zr36050_codecs) { - dprintk(1, - "zr36050: something's wrong - %d codecs left somehow.\n", - zr36050_codecs); + pr_debug("zr36050: something's wrong - %d codecs left somehow.\n", + zr36050_codecs); } videocodec_unregister(&zr36050_codec); } diff --git a/drivers/staging/media/zoran/zr36060.c b/drivers/staging/media/zoran/zr36060.c index d0c369e31c81f..7798016f1f962 100644 --- a/drivers/staging/media/zoran/zr36060.c +++ b/drivers/staging/media/zoran/zr36060.c @@ -32,16 +32,6 @@ static bool low_bitrate; module_param(low_bitrate, bool, 0); MODULE_PARM_DESC(low_bitrate, "Buz compatibility option, halves bitrate"); -static int zr36060_debug; -module_param(zr36060_debug, int, 0); -MODULE_PARM_DESC(zr36060_debug, "Debug level (0-4)"); - -#define dprintk(num, format, args...) \ - do { \ - if (zr36060_debug >= num) \ - printk(format, ##args); \ - } while (0) - /* ========================================================================= * Local hardware I/O functions: * read/write via codec layer (registers are located in the master device) @@ -51,25 +41,28 @@ MODULE_PARM_DESC(zr36060_debug, "Debug level (0-4)"); static u8 zr36060_read(struct zr36060 *ptr, u16 reg) { u8 value = 0; + struct zoran *zr = videocodec_to_zoran(ptr->codec); // just in case something is wrong... if (ptr->codec->master_data->readreg) value = (ptr->codec->master_data->readreg(ptr->codec, reg)) & 0xff; else - pr_err("%s: invalid I/O setup, nothing read!\n", ptr->name); + zrdev_err(zr, "%s: invalid I/O setup, nothing read!\n", ptr->name); return value; } static void zr36060_write(struct zr36060 *ptr, u16 reg, u8 value) { - dprintk(4, "0x%02x @0x%04x\n", value, reg); + struct zoran *zr = videocodec_to_zoran(ptr->codec); + + zrdev_dbg(zr, "0x%02x @0x%04x\n", value, reg); // just in case something is wrong... if (ptr->codec->master_data->writereg) ptr->codec->master_data->writereg(ptr->codec, reg, value); else - pr_err("%s: invalid I/O setup, nothing written!\n", ptr->name); + zrdev_err(zr, "%s: invalid I/O setup, nothing written!\n", ptr->name); } /* ========================================================================= @@ -101,14 +94,15 @@ static u16 zr36060_read_scalefactor(struct zr36060 *ptr) /* wait if codec is ready to proceed (end of processing) or time is over */ static void zr36060_wait_end(struct zr36060 *ptr) { + struct zoran *zr = videocodec_to_zoran(ptr->codec); int i = 0; while (zr36060_read_status(ptr) & ZR060_CFSR_BUSY) { udelay(1); if (i++ > 200000) { // 200ms, there is for sure something wrong!!! - dprintk(1, - "%s: timeout at wait_end (last status: 0x%02x)\n", - ptr->name, ptr->status); + zrdev_dbg(zr, + "%s: timeout at wait_end (last status: 0x%02x)\n", + ptr->name, ptr->status); break; } } @@ -117,15 +111,17 @@ static void zr36060_wait_end(struct zr36060 *ptr) /* Basic test of "connectivity", writes/reads to/from memory the SOF marker */ static int zr36060_basic_test(struct zr36060 *ptr) { + struct zoran *zr = videocodec_to_zoran(ptr->codec); + if ((zr36060_read(ptr, ZR060_IDR_DEV) != 0x33) && (zr36060_read(ptr, ZR060_IDR_REV) != 0x01)) { - pr_err("%s: attach failed, can't connect to jpeg processor!\n", ptr->name); + zrdev_err(zr, "%s: attach failed, can't connect to jpeg processor!\n", ptr->name); return -ENXIO; } zr36060_wait_end(ptr); if (ptr->status & ZR060_CFSR_BUSY) { - pr_err("%s: attach failed, jpeg processor failed (end flag)!\n", ptr->name); + zrdev_err(zr, "%s: attach failed, jpeg processor failed (end flag)!\n", ptr->name); return -EBUSY; } @@ -135,10 +131,11 @@ static int zr36060_basic_test(struct zr36060 *ptr) /* simple loop for pushing the init datasets */ static int zr36060_pushit(struct zr36060 *ptr, u16 startreg, u16 len, const char *data) { + struct zoran *zr = videocodec_to_zoran(ptr->codec); int i = 0; - dprintk(4, "%s: write data block to 0x%04x (len=%d)\n", ptr->name, - startreg, len); + zrdev_dbg(zr, "%s: write data block to 0x%04x (len=%d)\n", ptr->name, + startreg, len); while (i < len) zr36060_write(ptr, startreg++, data[i++]); @@ -249,11 +246,12 @@ static const char zr36060_decimation_v[8] = { 1, 1, 1, 0, 0, 0, 0, 0 }; /* SOF (start of frame) segment depends on width, height and sampling ratio of each color component */ static int zr36060_set_sof(struct zr36060 *ptr) { + struct zoran *zr = videocodec_to_zoran(ptr->codec); char sof_data[34]; // max. size of register set int i; - dprintk(3, "%s: write SOF (%dx%d, %d components)\n", ptr->name, - ptr->width, ptr->height, NO_OF_COMPONENTS); + zrdev_dbg(zr, "%s: write SOF (%dx%d, %d components)\n", ptr->name, + ptr->width, ptr->height, NO_OF_COMPONENTS); sof_data[0] = 0xff; sof_data[1] = 0xc0; sof_data[2] = 0x00; @@ -277,10 +275,11 @@ static int zr36060_set_sof(struct zr36060 *ptr) /* SOS (start of scan) segment depends on the used scan components of each color component */ static int zr36060_set_sos(struct zr36060 *ptr) { + struct zoran *zr = videocodec_to_zoran(ptr->codec); char sos_data[16]; // max. size of register set int i; - dprintk(3, "%s: write SOS\n", ptr->name); + zrdev_dbg(zr, "%s: write SOS\n", ptr->name); sos_data[0] = 0xff; sos_data[1] = 0xda; sos_data[2] = 0x00; @@ -302,9 +301,10 @@ static int zr36060_set_sos(struct zr36060 *ptr) /* DRI (define restart interval) */ static int zr36060_set_dri(struct zr36060 *ptr) { + struct zoran *zr = videocodec_to_zoran(ptr->codec); char dri_data[6]; // max. size of register set - dprintk(3, "%s: write DRI\n", ptr->name); + zrdev_dbg(zr, "%s: write DRI\n", ptr->name); dri_data[0] = 0xff; dri_data[1] = 0xdd; dri_data[2] = 0x00; @@ -321,9 +321,10 @@ static void zr36060_init(struct zr36060 *ptr) { int sum = 0; long bitcnt, tmp; + struct zoran *zr = videocodec_to_zoran(ptr->codec); if (ptr->mode == CODEC_DO_COMPRESSION) { - dprintk(2, "%s: COMPRESSION SETUP\n", ptr->name); + zrdev_dbg(zr, "%s: COMPRESSION SETUP\n", ptr->name); zr36060_write(ptr, ZR060_LOAD, ZR060_LOAD_SYNC_RST); @@ -376,9 +377,9 @@ static void zr36060_init(struct zr36060 *ptr) bitcnt = sum << 3; /* need the size in bits */ tmp = bitcnt >> 16; - dprintk(3, - "%s: code: csize=%d, tot=%d, bit=%ld, highbits=%ld\n", - ptr->name, sum, ptr->real_code_vol, bitcnt, tmp); + zrdev_dbg(zr, + "%s: code: csize=%d, tot=%d, bit=%ld, highbits=%ld\n", + ptr->name, sum, ptr->real_code_vol, bitcnt, tmp); zr36060_write(ptr, ZR060_TCV_NET_HI, tmp >> 8); zr36060_write(ptr, ZR060_TCV_NET_MH, tmp & 0xff); tmp = bitcnt & 0xffff; @@ -389,8 +390,8 @@ static void zr36060_init(struct zr36060 *ptr) bitcnt -= ((bitcnt * 5) >> 6); // bits without eob tmp = bitcnt >> 16; - dprintk(3, "%s: code: nettobit=%ld, highnettobits=%ld\n", - ptr->name, bitcnt, tmp); + zrdev_dbg(zr, "%s: code: nettobit=%ld, highnettobits=%ld\n", + ptr->name, bitcnt, tmp); zr36060_write(ptr, ZR060_TCV_DATA_HI, tmp >> 8); zr36060_write(ptr, ZR060_TCV_DATA_MH, tmp & 0xff); tmp = bitcnt & 0xffff; @@ -408,7 +409,7 @@ static void zr36060_init(struct zr36060 *ptr) zr36060_write(ptr, ZR060_VCR, ZR060_VCR_RANGE); } else { - dprintk(2, "%s: EXPANSION SETUP\n", ptr->name); + zrdev_dbg(zr, "%s: EXPANSION SETUP\n", ptr->name); zr36060_write(ptr, ZR060_LOAD, ZR060_LOAD_SYNC_RST); @@ -441,10 +442,11 @@ static void zr36060_init(struct zr36060 *ptr) /* Load the tables */ zr36060_write(ptr, ZR060_LOAD, ZR060_LOAD_SYNC_RST | ZR060_LOAD_LOAD); zr36060_wait_end(ptr); - dprintk(2, "%s: Status after table preload: 0x%02x\n", ptr->name, ptr->status); + zrdev_dbg(zr, "%s: Status after table preload: 0x%02x\n", + ptr->name, ptr->status); if (ptr->status & ZR060_CFSR_BUSY) { - pr_err("%s: init aborted!\n", ptr->name); + zrdev_err(zr, "%s: init aborted!\n", ptr->name); return; // something is wrong, its timed out!!!! } } @@ -461,8 +463,9 @@ static void zr36060_init(struct zr36060 *ptr) static int zr36060_set_mode(struct videocodec *codec, int mode) { struct zr36060 *ptr = (struct zr36060 *)codec->data; + struct zoran *zr = videocodec_to_zoran(codec); - dprintk(2, "%s: set_mode %d call\n", ptr->name, mode); + zrdev_dbg(zr, "%s: set_mode %d call\n", ptr->name, mode); if (mode != CODEC_DO_EXPANSION && mode != CODEC_DO_COMPRESSION) return -EINVAL; @@ -478,11 +481,12 @@ static int zr36060_set_video(struct videocodec *codec, const struct tvnorm *norm struct vfe_settings *cap, struct vfe_polarity *pol) { struct zr36060 *ptr = (struct zr36060 *)codec->data; + struct zoran *zr = videocodec_to_zoran(codec); u32 reg; int size; - dprintk(2, "%s: set_video %d/%d-%dx%d (%%%d) call\n", ptr->name, - cap->x, cap->y, cap->width, cap->height, cap->decimation); + zrdev_dbg(zr, "%s: set_video %d/%d-%dx%d (%%%d) call\n", ptr->name, + cap->x, cap->y, cap->width, cap->height, cap->decimation); /* if () return -EINVAL; * trust the master driver that it knows what it does - so @@ -637,10 +641,11 @@ static int zr36060_set_video(struct videocodec *codec, const struct tvnorm *norm static int zr36060_control(struct videocodec *codec, int type, int size, void *data) { struct zr36060 *ptr = (struct zr36060 *)codec->data; + struct zoran *zr = videocodec_to_zoran(codec); int *ival = (int *)data; - dprintk(2, "%s: control %d call with %d byte\n", ptr->name, type, - size); + zrdev_dbg(zr, "%s: control %d call with %d byte\n", ptr->name, type, + size); switch (type) { case CODEC_G_STATUS: /* get last status */ @@ -753,11 +758,12 @@ static int zr36060_control(struct videocodec *codec, int type, int size, void *d static int zr36060_unset(struct videocodec *codec) { struct zr36060 *ptr = codec->data; + struct zoran *zr = videocodec_to_zoran(codec); if (ptr) { /* do wee need some codec deinit here, too ???? */ - dprintk(1, "%s: finished codec #%d\n", ptr->name, ptr->num); + zrdev_dbg(zr, "%s: finished codec #%d\n", ptr->name, ptr->num); kfree(ptr); codec->data = NULL; @@ -778,12 +784,14 @@ static int zr36060_unset(struct videocodec *codec) static int zr36060_setup(struct videocodec *codec) { struct zr36060 *ptr; + struct zoran *zr = videocodec_to_zoran(codec); int res; - dprintk(2, "zr36060: initializing MJPEG subsystem #%d.\n", zr36060_codecs); + zrdev_dbg(zr, "zr36060: initializing MJPEG subsystem #%d.\n", + zr36060_codecs); if (zr36060_codecs == MAX_CODECS) { - pr_err("zr36060: Can't attach more codecs!\n"); + zrdev_err(zr, "zr36060: Can't attach more codecs!\n"); return -ENOSPC; } //mem structure init @@ -823,7 +831,7 @@ static int zr36060_setup(struct videocodec *codec) zr36060_init(ptr); - dprintk(1, KERN_INFO "%s: codec attached and running\n", ptr->name); + zrdev_info(zr, "%s: codec attached and running\n", ptr->name); return 0; } @@ -852,9 +860,8 @@ int zr36060_init_module(void) void zr36060_cleanup_module(void) { if (zr36060_codecs) { - dprintk(1, - "zr36060: something's wrong - %d codecs left somehow.\n", - zr36060_codecs); + pr_debug("zr36060: something's wrong - %d codecs left somehow.\n", + zr36060_codecs); } /* however, we can't just stay alive */ diff --git a/include/media/tpg/v4l2-tpg.h b/include/media/tpg/v4l2-tpg.h index 181dcbe777f39..a55088921d1d1 100644 --- a/include/media/tpg/v4l2-tpg.h +++ b/include/media/tpg/v4l2-tpg.h @@ -210,6 +210,7 @@ struct tpg_data { bool show_square; bool insert_sav; bool insert_eav; + bool insert_hdmi_video_guard_band; /* Test pattern movement */ enum tpg_move_mode mv_hor_mode; @@ -591,6 +592,21 @@ static inline void tpg_s_insert_eav(struct tpg_data *tpg, bool insert_eav) tpg->insert_eav = insert_eav; } +/* + * This inserts 4 pixels of the RGB color 0xab55ab at the left hand side of the + * image. This is only done for 3 or 4 byte RGB pixel formats. This pixel value + * equals the Video Guard Band value as defined by HDMI (see section 5.2.2.1 + * in the HDMI 1.3 Specification) that preceeds the first actual pixel. If the + * HDMI receiver doesn't handle this correctly, then it might keep skipping + * these Video Guard Band patterns and end up with a shorter video line. So this + * is a nice pattern to test with. + */ +static inline void tpg_s_insert_hdmi_video_guard_band(struct tpg_data *tpg, + bool insert_hdmi_video_guard_band) +{ + tpg->insert_hdmi_video_guard_band = insert_hdmi_video_guard_band; +} + void tpg_update_mv_step(struct tpg_data *tpg); static inline void tpg_s_mv_hor_mode(struct tpg_data *tpg, diff --git a/include/uapi/linux/videodev2.h b/include/uapi/linux/videodev2.h index 343b95107fce5..5311ac4fde35d 100644 --- a/include/uapi/linux/videodev2.h +++ b/include/uapi/linux/videodev2.h @@ -602,6 +602,7 @@ struct v4l2_pix_format { #define V4L2_PIX_FMT_NV61 v4l2_fourcc('N', 'V', '6', '1') /* 16 Y/CrCb 4:2:2 */ #define V4L2_PIX_FMT_NV24 v4l2_fourcc('N', 'V', '2', '4') /* 24 Y/CbCr 4:4:4 */ #define V4L2_PIX_FMT_NV42 v4l2_fourcc('N', 'V', '4', '2') /* 24 Y/CrCb 4:4:4 */ +#define V4L2_PIX_FMT_P010 v4l2_fourcc('P', '0', '1', '0') /* 24 Y/CbCr 4:2:0 10-bit per component */ /* two non contiguous planes - one Y, one Cr + Cb interleaved */ #define V4L2_PIX_FMT_NV12M v4l2_fourcc('N', 'M', '1', '2') /* 12 Y/CbCr 4:2:0 */ |
