Re: [PATCH] imx.rst: fix typo
Acked-by: Steve LongerbeamOn 03/13/2018 11:29 AM, Hans Verkuil wrote: Multpiple -> Multiple Signed-off-by: Hans Verkuil --- diff --git a/Documentation/media/v4l-drivers/imx.rst b/Documentation/media/v4l-drivers/imx.rst index 18e3141304bb..65d3d15eb159 100644 --- a/Documentation/media/v4l-drivers/imx.rst +++ b/Documentation/media/v4l-drivers/imx.rst @@ -109,7 +109,7 @@ imx6-mipi-csi2 This is the MIPI CSI-2 receiver entity. It has one sink pad to receive the MIPI CSI-2 stream (usually from a MIPI CSI-2 camera sensor). It has four source pads, corresponding to the four MIPI CSI-2 demuxed virtual -channel outputs. Multpiple source pads can be enabled to independently +channel outputs. Multiple source pads can be enabled to independently stream from multiple virtual channels. This entity actually consists of two sub-blocks. One is the MIPI CSI-2
[PATCH] pixfmt-v4l2.rst: fix broken enum :c:type:
:c:type:: -> :c:type: Signed-off-by: Hans Verkuil--- diff --git a/Documentation/media/uapi/v4l/pixfmt-v4l2.rst b/Documentation/media/uapi/v4l/pixfmt-v4l2.rst index 2ee164c25637..6622938c1b41 100644 --- a/Documentation/media/uapi/v4l/pixfmt-v4l2.rst +++ b/Documentation/media/uapi/v4l/pixfmt-v4l2.rst @@ -40,7 +40,7 @@ Single-planar format structure RGB formats in :ref:`rgb-formats`, YUV formats in :ref:`yuv-formats`, and reserved codes in :ref:`reserved-formats` -* - enum :c:type::`v4l2_field` +* - enum :c:type:`v4l2_field` - ``field`` - Video images are typically interlaced. Applications can request to capture or output only the top or bottom field, or both fields
Re: [PATCH 1/3] rcar-vin: remove duplicated check of state in irq handler
On 03/09/2018 04:09 PM, Niklas Söderlund wrote: > This is an error from when the driver where converted from soc-camera. where -> was > There is absolutely no gain to check the state variable two times to be > extra sure if the hardware is stopped. I'll wait for v2 before applying this. Regards, Hans > > Signed-off-by: Niklas Söderlund> --- > drivers/media/platform/rcar-vin/rcar-dma.c | 6 -- > 1 file changed, 6 deletions(-) > > diff --git a/drivers/media/platform/rcar-vin/rcar-dma.c > b/drivers/media/platform/rcar-vin/rcar-dma.c > index 23fdff7a7370842e..b4be75d5009080f7 100644 > --- a/drivers/media/platform/rcar-vin/rcar-dma.c > +++ b/drivers/media/platform/rcar-vin/rcar-dma.c > @@ -916,12 +916,6 @@ static irqreturn_t rvin_irq(int irq, void *data) > rvin_ack_interrupt(vin); > handled = 1; > > - /* Nothing to do if capture status is 'STOPPED' */ > - if (vin->state == STOPPED) { > - vin_dbg(vin, "IRQ while state stopped\n"); > - goto done; > - } > - > /* Nothing to do if capture status is 'STOPPING' */ > if (vin->state == STOPPING) { > vin_dbg(vin, "IRQ while state stopping\n"); >
[PATCH] imx.rst: fix typo
Multpiple -> Multiple Signed-off-by: Hans Verkuil--- diff --git a/Documentation/media/v4l-drivers/imx.rst b/Documentation/media/v4l-drivers/imx.rst index 18e3141304bb..65d3d15eb159 100644 --- a/Documentation/media/v4l-drivers/imx.rst +++ b/Documentation/media/v4l-drivers/imx.rst @@ -109,7 +109,7 @@ imx6-mipi-csi2 This is the MIPI CSI-2 receiver entity. It has one sink pad to receive the MIPI CSI-2 stream (usually from a MIPI CSI-2 camera sensor). It has four source pads, corresponding to the four MIPI CSI-2 demuxed virtual -channel outputs. Multpiple source pads can be enabled to independently +channel outputs. Multiple source pads can be enabled to independently stream from multiple virtual channels. This entity actually consists of two sub-blocks. One is the MIPI CSI-2
Re: [PATCH 3/3] rcar-vin: use scratch buffer and always run in continuous mode
On 03/09/2018 04:09 PM, Niklas Söderlund wrote: > Instead of switching capture mode depending on how many buffers are > available use a scratch buffer and always run in continuous mode. By > using a scratch buffer the responsiveness of the capture loop is > increased as it can keep running even if there are no buffers available > from userspace. > > As soon as a userspace queues a buffer it is inserted into the capture > loop and returned as soon as it is filled. This is a improvement on the > previous logic where the whole capture loop was stopped and switched to > single capture mode if userspace did not feed the VIN driver buffers at > the same time it consumed them. To make matters worse it was difficult > for the driver to reenter continues mode if it entered single mode even continues -> continuous > if userspace started to queue buffers faster. This resulted in > suboptimal performance where if userspace where delayed for a short > period the ongoing capture would be slowed down and run in single mode > until the capturing process where restarted. > > An additional effect of this change is that the capture logic can be > made much simple as we know that continues mode will always be used. ditto > > Signed-off-by: Niklas Söderlund> --- > drivers/media/platform/rcar-vin/rcar-dma.c | 187 > - > drivers/media/platform/rcar-vin/rcar-vin.h | 6 +- > 2 files changed, 52 insertions(+), 141 deletions(-) > > diff --git a/drivers/media/platform/rcar-vin/rcar-dma.c > b/drivers/media/platform/rcar-vin/rcar-dma.c > index 8ea73cdc9a720abe..208cf8a0ea77002d 100644 > --- a/drivers/media/platform/rcar-vin/rcar-dma.c > +++ b/drivers/media/platform/rcar-vin/rcar-dma.c > @@ -168,12 +168,8 @@ static int rvin_setup(struct rvin_dev *vin) > break; > case V4L2_FIELD_ALTERNATE: > case V4L2_FIELD_NONE: > - if (vin->continuous) { > - vnmc = VNMC_IM_ODD_EVEN; > - progressive = true; > - } else { > - vnmc = VNMC_IM_ODD; > - } > + vnmc = VNMC_IM_ODD_EVEN; > + progressive = true; > break; > default: > vnmc = VNMC_IM_ODD; > @@ -298,14 +294,6 @@ static bool rvin_capture_active(struct rvin_dev *vin) > return rvin_read(vin, VNMS_REG) & VNMS_CA; > } > > -static int rvin_get_active_slot(struct rvin_dev *vin, u32 vnms) > -{ > - if (vin->continuous) > - return (vnms & VNMS_FBS_MASK) >> VNMS_FBS_SHIFT; > - > - return 0; > -} > - > static enum v4l2_field rvin_get_active_field(struct rvin_dev *vin, u32 vnms) > { > if (vin->format.field == V4L2_FIELD_ALTERNATE) { > @@ -344,76 +332,47 @@ static void rvin_set_slot_addr(struct rvin_dev *vin, > int slot, dma_addr_t addr) > rvin_write(vin, offset, VNMB_REG(slot)); > } > > -/* Moves a buffer from the queue to the HW slots */ > -static bool rvin_fill_hw_slot(struct rvin_dev *vin, int slot) > +/* > + * Moves a buffer from the queue to the HW slot. If no buffer is > + * available use the scratch buffer. The scratch buffer is never > + * returned to userspace, its only function is to enable the capture > + * loop to keep running. > + */ > +static void rvin_fill_hw_slot(struct rvin_dev *vin, int slot) > { > struct rvin_buffer *buf; > struct vb2_v4l2_buffer *vbuf; > - dma_addr_t phys_addr_top; > - > - if (vin->queue_buf[slot] != NULL) > - return true; > + dma_addr_t phys_addr; > > - if (list_empty(>buf_list)) > - return false; > + /* A already populated slot shall never be overwritten. */ > + if (WARN_ON(vin->queue_buf[slot] != NULL)) > + return; > > vin_dbg(vin, "Filling HW slot: %d\n", slot); > > - /* Keep track of buffer we give to HW */ > - buf = list_entry(vin->buf_list.next, struct rvin_buffer, list); > - vbuf = >vb; > - list_del_init(to_buf_list(vbuf)); > - vin->queue_buf[slot] = vbuf; > - > - /* Setup DMA */ > - phys_addr_top = vb2_dma_contig_plane_dma_addr(>vb2_buf, 0); > - rvin_set_slot_addr(vin, slot, phys_addr_top); > - > - return true; > -} > - > -static bool rvin_fill_hw(struct rvin_dev *vin) > -{ > - int slot, limit; > - > - limit = vin->continuous ? HW_BUFFER_NUM : 1; > - > - for (slot = 0; slot < limit; slot++) > - if (!rvin_fill_hw_slot(vin, slot)) > - return false; > - return true; > -} > - > -static void rvin_capture_on(struct rvin_dev *vin) > -{ > - vin_dbg(vin, "Capture on in %s mode\n", > - vin->continuous ? "continuous" : "single"); > + if (list_empty(>buf_list)) { > + vin->queue_buf[slot] = NULL; > + phys_addr = vin->scratch_phys; > + } else { > + /* Keep track of buffer we give to HW */ > + buf = list_entry(vin->buf_list.next, struct
[PATCH] media: staging/imx: fill vb2_v4l2_buffer sequence entry
Signed-off-by: Peter Seiderer--- drivers/staging/media/imx/imx-media-csi.c | 5 + 1 file changed, 5 insertions(+) diff --git a/drivers/staging/media/imx/imx-media-csi.c b/drivers/staging/media/imx/imx-media-csi.c index 5a195f80a24d..3a6a645b9dce 100644 --- a/drivers/staging/media/imx/imx-media-csi.c +++ b/drivers/staging/media/imx/imx-media-csi.c @@ -111,6 +111,7 @@ struct csi_priv { struct v4l2_ctrl_handler ctrl_hdlr; int stream_count; /* streaming counter */ + __u32 frame_sequence; /* frame sequence counter */ bool last_eof; /* waiting for last EOF at stream off */ bool nfb4eof;/* NFB4EOF encountered during streaming */ struct completion last_eof_comp; @@ -234,8 +235,11 @@ static void csi_vb2_buf_done(struct csi_priv *priv) struct vb2_buffer *vb; dma_addr_t phys; + priv->frame_sequence++; + done = priv->active_vb2_buf[priv->ipu_buf_num]; if (done) { + done->vbuf.sequence = priv->frame_sequence; vb = >vbuf.vb2_buf; vb->timestamp = ktime_get_ns(); vb2_buffer_done(vb, priv->nfb4eof ? @@ -543,6 +547,7 @@ static int csi_idmac_start(struct csi_priv *priv) /* init EOF completion waitq */ init_completion(>last_eof_comp); + priv->frame_sequence = 0; priv->last_eof = false; priv->nfb4eof = false; -- 2.16.2
[GIT PULL for 4.17] Pile of atomisp patches
Hi Mauro, Here's the usual pile of atomisp driver patches. Along with the usual cleanups, there's a fix that disables atomisp_compat_ioctl32 as well. The following changes since commit 3f127ce11353fd1071cae9b65bc13add6aec6b90: media: em28xx-cards: fix em28xx_duplicate_dev() (2018-03-08 06:06:51 -0500) are available in the git repository at: ssh://linuxtv.org/git/sailus/media_tree.git atomisp for you to fetch changes up to f105c0b9eae0646ed6d05e6a56a29bb1461e6b9f: staging: media: Replace "cant" with "can't" (2018-03-09 10:56:05 +0200) Alona Solntseva (1): drivers: staging: media: atomisp: pci: atomisp2: css2400: fix misspellings Arnd Bergmann (1): staging: media: atomisp: remove pointless string copy Arushi Singhal (1): staging: media: Replace "cant" with "can't" Colin Ian King (1): media: staging: atomisp: remove redundant assignments to various variables Corentin Labbe (3): staging: media: remove remains of VIDEO_ATOMISP_OV8858 staging: media: atomisp2: remove unused headers staging: media: atomisp: Remove inclusion of non-existing directories Hans Verkuil (1): atomisp_fops.c: disable atomisp_compat_ioctl32 Jeremy Sowden (1): media: atomisp: convert default struct values to use compound-literals with designated initializers. drivers/staging/media/atomisp/i2c/Kconfig | 12 - .../media/atomisp/i2c/ov5693/atomisp-ov5693.c |2 +- drivers/staging/media/atomisp/i2c/ov8858.c | 2169 drivers/staging/media/atomisp/i2c/ov8858.h | 1474 - drivers/staging/media/atomisp/i2c/ov8858_btns.h| 1276 .../media/atomisp/include/linux/vlv2_plat_clock.h | 30 - .../staging/media/atomisp/pci/atomisp2/Makefile| 10 - .../media/atomisp/pci/atomisp2/atomisp_cmd.c |2 +- .../atomisp/pci/atomisp2/atomisp_compat_css20.c|2 +- .../media/atomisp/pci/atomisp2/atomisp_fops.c |6 + .../media/atomisp/pci/atomisp2/atomisp_v4l2.c |1 - .../css2400/css_2400_system/hrt/gp_regs_defs.h | 22 - .../atomisp2/css2400/css_2400_system/hrt/sp_hrt.h | 24 - .../css_2401_csi2p_system/hrt/gp_regs_defs.h | 22 - .../css2400/css_2401_csi2p_system/hrt/sp_hrt.h | 24 - .../css2400/css_2401_system/hrt/gp_regs_defs.h | 22 - .../atomisp2/css2400/css_2401_system/hrt/sp_hrt.h | 24 - .../atomisp/pci/atomisp2/css2400/css_api_version.h | 673 -- .../host/hive_isp_css_ddr_hrt_modified.h | 148 -- .../host/hive_isp_css_hrt_modified.h | 79 - .../hive_isp_css_common/input_formatter_global.h | 16 - .../css2400/hive_isp_css_common/resource_global.h | 35 - .../css2400/hive_isp_css_common/xmem_global.h | 20 - .../atomisp2/css2400/hive_isp_css_include/bamem.h | 46 - .../css2400/hive_isp_css_include/bbb_config.h | 27 - .../css2400/hive_isp_css_include/cpu_mem_support.h | 59 - .../hive_isp_css_include/host/isp2400_config.h | 24 - .../hive_isp_css_include/host/isp2500_config.h | 29 - .../hive_isp_css_include/host/isp2600_config.h | 34 - .../hive_isp_css_include/host/isp2601_config.h | 70 - .../css2400/hive_isp_css_include/host/isp_config.h | 24 - .../css2400/hive_isp_css_include/host/isp_op1w.h | 844 .../hive_isp_css_include/host/isp_op1w_types.h | 54 - .../css2400/hive_isp_css_include/host/isp_op2w.h | 674 -- .../hive_isp_css_include/host/isp_op2w_types.h | 49 - .../hive_isp_css_include/host/isp_op_count.h | 226 -- .../hive_isp_css_include/host/osys_public.h| 20 - .../hive_isp_css_include/host/pipeline_public.h| 18 - .../hive_isp_css_include/host/ref_vector_func.h| 1221 --- .../host/ref_vector_func_types.h | 385 .../atomisp2/css2400/hive_isp_css_include/mpmath.h | 329 --- .../atomisp2/css2400/hive_isp_css_include/osys.h | 47 - .../css2400/hive_isp_css_include/stream_buffer.h | 47 - .../css2400/hive_isp_css_include/vector_func.h | 38 - .../css2400/hive_isp_css_include/vector_ops.h | 31 - .../atomisp2/css2400/hive_isp_css_include/xmem.h | 46 - .../css2400/hive_isp_css_shared/socket_global.h| 53 - .../hive_isp_css_shared/stream_buffer_global.h | 26 - .../pci/atomisp2/css2400/ia_css_frame_public.h | 29 +- .../atomisp/pci/atomisp2/css2400/ia_css_pipe.h | 113 +- .../pci/atomisp2/css2400/ia_css_pipe_public.h | 108 +- .../atomisp/pci/atomisp2/css2400/ia_css_types.h| 64 +- .../css2400/isp/kernels/aa/aa_2/ia_css_aa2_state.h | 41 - .../bayer_ls_1.0/ia_css_bayer_load_param.h | 20 - .../bayer_ls/bayer_ls_1.0/ia_css_bayer_ls_param.h | 42 - .../bayer_ls_1.0/ia_css_bayer_store_param.h| 21 - .../css2400/isp/kernels/bnlm/ia_css_bnlm_state.h | 31 - .../isp/kernels/cnr/cnr_1.0/ia_css_cnr_state.h
RE: [PATCH 02/11] media: vsp1: use kernel __packed for structures
From: Kieran Bingham > Sent: 09 March 2018 22:04 > The kernel provides a __packed definition to abstract away from the > compiler specific attributes tag. > > Convert all packed structures in VSP1 to use it. > > Signed-off-by: Kieran Bingham> --- > drivers/media/platform/vsp1/vsp1_dl.c | 6 +++--- > 1 file changed, 3 insertions(+), 3 deletions(-) > > diff --git a/drivers/media/platform/vsp1/vsp1_dl.c > b/drivers/media/platform/vsp1/vsp1_dl.c > index 37e2c984fbf3..382e45c2054e 100644 > --- a/drivers/media/platform/vsp1/vsp1_dl.c > +++ b/drivers/media/platform/vsp1/vsp1_dl.c > @@ -29,19 +29,19 @@ > struct vsp1_dl_header_list { > u32 num_bytes; > u32 addr; > -} __attribute__((__packed__)); > +} __packed; > > struct vsp1_dl_header { > u32 num_lists; > struct vsp1_dl_header_list lists[8]; > u32 next_header; > u32 flags; > -} __attribute__((__packed__)); > +} __packed; > > struct vsp1_dl_entry { > u32 addr; > u32 data; > -} __attribute__((__packed__)); > +} __packed; Do these structures ever actually appear in misaligned memory? If they don't then they shouldn't be marked 'packed'. David
Re: [RFCv4,19/21] media: vim2m: add request support
On Fri, Mar 9, 2018 at 11:35 PM, Paul Kocialkowskiwrote: > Hi, > > On Thu, 2018-03-08 at 22:48 +0900, Alexandre Courbot wrote: >> Hi Paul! >> >> Thanks a lot for taking the time to try this! I am also working on >> getting it to work with an actual driver, but you apparently found >> rough edges that I missed. >> >> On Thu, Mar 8, 2018 at 1:37 AM, Paul Kocialkowski >> wrote: >> > Hi, >> > >> > First off, I'd like to take the occasion to say thank-you for your >> > work. >> > This is a major piece of plumbing that is required for me to add >> > support >> > for the Allwinner CedarX VPU hardware in upstream Linux. Other >> > drivers, >> > such as tegra-vde (that was recently merged in staging) are also >> > badly >> > in need of this API. >> > >> > I have a few comments based on my experience integrating this >> > request >> > API with the Cedrus VPU driver (and the associated libva backend), >> > that >> > also concern the vim2m driver. >> > >> > On Tue, 2018-02-20 at 13:44 +0900, Alexandre Courbot wrote: >> > > Set the necessary ops for supporting requests in vim2m. >> > > >> > > Signed-off-by: Alexandre Courbot >> > > --- >> > > drivers/media/platform/Kconfig | 1 + >> > > drivers/media/platform/vim2m.c | 75 >> > > ++ >> > > 2 files changed, 76 insertions(+) >> > > >> > > diff --git a/drivers/media/platform/Kconfig >> > > b/drivers/media/platform/Kconfig >> > > index 614fbef08ddc..09be0b5f9afe 100644 >> > > --- a/drivers/media/platform/Kconfig >> > > +++ b/drivers/media/platform/Kconfig >> > >> > [...] >> > >> > > +static int vim2m_request_submit(struct media_request *req, >> > > + struct media_request_entity_data >> > > *_data) >> > > +{ >> > > + struct v4l2_request_entity_data *data; >> > > + >> > > + data = to_v4l2_entity_data(_data); >> > >> > We need to call v4l2_m2m_try_schedule here so that m2m scheduling >> > can >> > happen when only 2 buffers were queued and no other action was taken >> > from usespace. In that scenario, m2m scheduling currently doesn't >> > happen. >> >> I don't think I understand the sequence of events that results in >> v4l2_m2m_try_schedule() not being called. Do you mean something like: >> >> * >> * QBUF on output queue with request set >> * QBUF on capture queue >> * SUBMIT_REQUEST >> >> ? >> >> The call to vb2_request_submit() right after should trigger >> v4l2_m2m_try_schedule(), since the buffers associated to the request >> will enter the vb2 queue and be passed to the m2m framework, which >> will then call v4l2_m2m_try_schedule(). Or maybe you are thinking >> about a different sequence of events? > > This is indeed the sequence of events that I'm seeing, but the > scheduling call simply did not happen on vb2_request_submit. I suppose I will > need to investigate some more to find out exactly why. > > IIRC, the m2m qbuf function is called (and fails to schedule) when the > ioctl happens, not when the task is submitted. > > This issue is seen with vim2m as well as the rencently-submitted sunxi- > cedrus driver (with the in-driver calls to v4l2_m2m_try_schedule > removed, obviously). If needs be, I could provide a standalone test > program to reproduce it. If you have a standalone program that can reproduce this on vim2m, then I would like to see it indeed, if only to understand what I have missed. Thanks, Alex.
[PATCH v3 0/2] media: Introduce Omnivision OV2680 driver
Add driver and bindings for the OV2680 2 megapixel CMOS 1/5" sensor, which has a single MIPI lane interface and output format of 10-bit Raw RGB. Features supported are described in PATCH 2/2. v2->v3: Rob Herring: - add Reviewed-by tag to dts PATCH 1/1 Sakari Ailus: - align register values with bracket - redone the {write|read}_reg i2c functions - add bayer order handling with flip and mirror controls - fix error path in probe release resources - remove i2c_device_id and use probe_new Myself: - remove ; at the end of macros v1->v2: Fabio Estevam: - s/OV5640/OV2680 in PATCH 1/2 changelog Sakari Ailus: - add description on endpoint properties in bindings - add single endpoint in bindings - drop OF dependency - cleanup includes - fix case in Color Bars - remove frame rate selection - 8/16/24 bit register access in the same transaction - merge _reset and _soft_reset to _enable and rename it to power_on - _gain_set use only the gain value (drop & 0x7ff) - _gain_get remove the (0x377) - single write/read at _exposure_set/get use write_reg24/read_reg24 - move mode_set_direct to _mode_set - _mode_set set auto exposure/gain based on ctrl value - s_frame_interval equal to g_frame_interval - use closest match from: v4l: common: Add a function to obtain best size from a list - check v4l2_ctrl_new_std return in _init - fix gain manual value in auto_cluster Cheers, Rui Rui Miguel Silva (2): media: ov2680: dt: Add bindings for OV2680 media: ov2680: Add Omnivision OV2680 sensor driver .../devicetree/bindings/media/i2c/ov2680.txt | 40 + drivers/media/i2c/Kconfig | 12 + drivers/media/i2c/Makefile |1 + drivers/media/i2c/ov2680.c | 1130 4 files changed, 1183 insertions(+) create mode 100644 Documentation/devicetree/bindings/media/i2c/ov2680.txt create mode 100644 drivers/media/i2c/ov2680.c -- 2.16.2
[PATCH v3 1/2] media: ov2680: dt: Add bindings for OV2680
Add device tree binding documentation for the OV2680 camera sensor. Reviewed-by: Rob HerringCC: devicet...@vger.kernel.org Signed-off-by: Rui Miguel Silva --- .../devicetree/bindings/media/i2c/ov2680.txt | 40 ++ 1 file changed, 40 insertions(+) create mode 100644 Documentation/devicetree/bindings/media/i2c/ov2680.txt diff --git a/Documentation/devicetree/bindings/media/i2c/ov2680.txt b/Documentation/devicetree/bindings/media/i2c/ov2680.txt new file mode 100644 index ..0e29f1a113c0 --- /dev/null +++ b/Documentation/devicetree/bindings/media/i2c/ov2680.txt @@ -0,0 +1,40 @@ +* Omnivision OV2680 MIPI CSI-2 sensor + +Required Properties: +- compatible: should be "ovti,ov2680". +- clocks: reference to the xvclk input clock. +- clock-names: should be "xvclk". + +Optional Properties: +- powerdown-gpios: reference to the GPIO connected to the powerdown pin, +if any. This is an active high signal to the OV2680. + +The device node must contain one 'port' child node for its digital output +video port, and this port must have a single endpoint in accordance with + the video interface bindings defined in +Documentation/devicetree/bindings/media/video-interfaces.txt. + +Endpoint node required properties for CSI-2 connection are: +- remote-endpoint: a phandle to the bus receiver's endpoint node. +- clock-lanes: should be set to <0> (clock lane on hardware lane 0). +- data-lanes: should be set to <1> (one CSI-2 lane supported). + +Example: + + { + ov2680: camera-sensor@36 { + compatible = "ovti,ov2680"; + reg = <0x36>; + clocks = <>; + clock-names = "xvclk"; + powerdown-gpios = < 3 GPIO_ACTIVE_HIGH>; + + port { + ov2680_mipi_ep: endpoint { + remote-endpoint = <_sensor_ep>; + clock-lanes = <0>; + data-lanes = <1>; + }; + }; + }; +}; -- 2.16.2
Re: [PATCH] media: omap3isp: fix unbalanced dma_iommu_mapping
Hi Suman, Thanks for the patch. On Mon, Mar 12, 2018 at 11:52:07AM -0500, Suman Anna wrote: > The OMAP3 ISP driver manages its MMU mappings through the IOMMU-aware > ARM DMA backend. The current code creates a dma_iommu_mapping and > attaches this to the ISP device, but never detaches the mapping in > either the probe failure paths or the driver remove path resulting > in an unbalanced mapping refcount and a memory leak. Fix this properly. > > Reported-by: Pavel Machek> Signed-off-by: Suman Anna > Tested-by: Pavel Machek > --- > Hi Mauro, Laurent, > > This fixes an issue reported by Pavel and discussed on this > thread, > https://marc.info/?l=linux-omap=152051945803598=2 > > Posting this again to the appropriate lists. > > regards > Suman > > drivers/media/platform/omap3isp/isp.c | 7 +-- > 1 file changed, 5 insertions(+), 2 deletions(-) > > diff --git a/drivers/media/platform/omap3isp/isp.c > b/drivers/media/platform/omap3isp/isp.c > index 8eb000e3d8fd..c7d667bfc2af 100644 > --- a/drivers/media/platform/omap3isp/isp.c > +++ b/drivers/media/platform/omap3isp/isp.c > @@ -1945,6 +1945,7 @@ static int isp_initialize_modules(struct isp_device > *isp) > > static void isp_detach_iommu(struct isp_device *isp) > { > + arm_iommu_detach_device(isp->dev); > arm_iommu_release_mapping(isp->mapping); > isp->mapping = NULL; > } > @@ -1971,13 +1972,15 @@ static int isp_attach_iommu(struct isp_device *isp) > ret = arm_iommu_attach_device(isp->dev, mapping); > if (ret < 0) { > dev_err(isp->dev, "failed to attach device to VA mapping\n"); > - goto error; > + goto error_attach; Instead of changing the label here, could you return immediately where the previous point of error handling is? No need to add another label. After fixing that you can add: Acked-by: Sakari Ailus > } > > return 0; > > +error_attach: > + arm_iommu_release_mapping(isp->mapping); > + isp->mapping = NULL; > error: > - isp_detach_iommu(isp); > return ret; > } > > -- Sakari Ailus e-mail: sakari.ai...@iki.fi
[PATCH v3 2/2] media: ov2680: Add Omnivision OV2680 sensor driver
This patch adds V4L2 sub-device driver for OV2680 image sensor. The OV2680 is a 1/5" CMOS color sensor from Omnivision. Supports output format: 10-bit Raw RGB. The OV2680 has a single lane MIPI interface. The driver exposes following V4L2 controls: - auto/manual exposure, - exposure, - auto/manual gain, - gain, - horizontal/vertical flip, - test pattern menu. Supported resolution are only: QUXGA, 720P, UXGA. Signed-off-by: Rui Miguel Silva--- drivers/media/i2c/Kconfig | 12 + drivers/media/i2c/Makefile |1 + drivers/media/i2c/ov2680.c | 1130 3 files changed, 1143 insertions(+) create mode 100644 drivers/media/i2c/ov2680.c diff --git a/drivers/media/i2c/Kconfig b/drivers/media/i2c/Kconfig index 9f18cd296841..39dc9f236ffa 100644 --- a/drivers/media/i2c/Kconfig +++ b/drivers/media/i2c/Kconfig @@ -586,6 +586,18 @@ config VIDEO_OV2659 To compile this driver as a module, choose M here: the module will be called ov2659. +config VIDEO_OV2680 + tristate "OmniVision OV2680 sensor support" + depends on GPIOLIB && VIDEO_V4L2 && I2C && VIDEO_V4L2_SUBDEV_API + depends on MEDIA_CAMERA_SUPPORT + select V4L2_FWNODE + ---help--- + This is a Video4Linux2 sensor-level driver for the OmniVision + OV2680 camera sensor with a MIPI CSI-2 interface. + + To compile this driver as a module, choose M here: the + module will be called ov2680. + config VIDEO_OV5640 tristate "OmniVision OV5640 sensor support" depends on OF diff --git a/drivers/media/i2c/Makefile b/drivers/media/i2c/Makefile index c0f94cd8d56d..d0aba4d37b8d 100644 --- a/drivers/media/i2c/Makefile +++ b/drivers/media/i2c/Makefile @@ -61,6 +61,7 @@ obj-$(CONFIG_VIDEO_SONY_BTF_MPX) += sony-btf-mpx.o obj-$(CONFIG_VIDEO_UPD64031A) += upd64031a.o obj-$(CONFIG_VIDEO_UPD64083) += upd64083.o obj-$(CONFIG_VIDEO_OV2640) += ov2640.o +obj-$(CONFIG_VIDEO_OV2680) += ov2680.o obj-$(CONFIG_VIDEO_OV5640) += ov5640.o obj-$(CONFIG_VIDEO_OV5645) += ov5645.o obj-$(CONFIG_VIDEO_OV5647) += ov5647.o diff --git a/drivers/media/i2c/ov2680.c b/drivers/media/i2c/ov2680.c new file mode 100644 index ..a17971ce71bc --- /dev/null +++ b/drivers/media/i2c/ov2680.c @@ -0,0 +1,1130 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Omnivision OV2680 CMOS Image Sensor driver + * + * Copyright (C) 2018 Linaro Ltd + * + * Based on OV5640 Sensor Driver + * Copyright (C) 2011-2013 Freescale Semiconductor, Inc. All Rights Reserved. + * Copyright (C) 2014-2017 Mentor Graphics Inc. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#define OV2680_XVCLK_MIN 600 +#define OV2680_XVCLK_MAX 2400 + +#define OV2680_CHIP_ID 0x2680 + +#define OV2680_REG_STREAM_CTRL 0x0100 +#define OV2680_REG_SOFT_RESET 0x0103 + +#define OV2680_REG_CHIP_ID_HIGH0x300a +#define OV2680_REG_CHIP_ID_LOW 0x300b + +#define OV2680_REG_R_MANUAL0x3503 +#define OV2680_REG_GAIN_PK 0x350a +#define OV2680_REG_EXPOSURE_PK_HIGH0x3500 +#define OV2680_REG_TIMING_HTS 0x380c +#define OV2680_REG_TIMING_VTS 0x380e +#define OV2680_REG_FORMAT1 0x3820 +#define OV2680_REG_FORMAT2 0x3821 + +#define OV2680_REG_ISP_CTRL00 0x5080 + +#define OV2680_FRAME_RATE 30 + +#define OV2680_REG_VALUE_8BIT 1 +#define OV2680_REG_VALUE_16BIT 2 +#define OV2680_REG_VALUE_24BIT 3 + +enum ov2680_mode_id { + OV2680_MODE_QUXGA_800_600, + OV2680_MODE_720P_1280_720, + OV2680_MODE_UXGA_1600_1200, + OV2680_MODE_MAX, +}; + +struct reg_value { + u16 reg_addr; + u8 val; +}; + +struct ov2680_mode_info { + const char *name; + enum ov2680_mode_id id; + u32 width; + u32 height; + const struct reg_value *reg_data; + u32 reg_data_size; +}; + +struct ov2680_ctrls { + struct v4l2_ctrl_handler handler; + struct { + struct v4l2_ctrl *auto_exp; + struct v4l2_ctrl *exposure; + }; + struct { + struct v4l2_ctrl *auto_gain; + struct v4l2_ctrl *gain; + }; + + struct v4l2_ctrl *hflip; + struct v4l2_ctrl *vflip; + struct v4l2_ctrl *test_pattern; +}; + +struct ov2680_dev { + struct i2c_client *i2c_client; + struct v4l2_subdev sd; + + struct media_padpad; + struct clk *xvclk; + u32 xvclk_freq; + + struct gpio_desc*pwdn_gpio; + struct mutexlock; /* protect members */ + + boolmode_pending_changes; + boolis_enabled; + bool
Re: [PATCH 02/11] media: vsp1: use kernel __packed for structures
Hi David, On 13/03/18 11:20, David Laight wrote: > From: Kieran Bingham >> Sent: 09 March 2018 22:04 >> The kernel provides a __packed definition to abstract away from the >> compiler specific attributes tag. >> >> Convert all packed structures in VSP1 to use it. >> >> Signed-off-by: Kieran Bingham>> --- >> drivers/media/platform/vsp1/vsp1_dl.c | 6 +++--- >> 1 file changed, 3 insertions(+), 3 deletions(-) >> >> diff --git a/drivers/media/platform/vsp1/vsp1_dl.c >> b/drivers/media/platform/vsp1/vsp1_dl.c >> index 37e2c984fbf3..382e45c2054e 100644 >> --- a/drivers/media/platform/vsp1/vsp1_dl.c >> +++ b/drivers/media/platform/vsp1/vsp1_dl.c >> @@ -29,19 +29,19 @@ >> struct vsp1_dl_header_list { >> u32 num_bytes; >> u32 addr; >> -} __attribute__((__packed__)); >> +} __packed; >> >> struct vsp1_dl_header { >> u32 num_lists; >> struct vsp1_dl_header_list lists[8]; >> u32 next_header; >> u32 flags; >> -} __attribute__((__packed__)); >> +} __packed; >> >> struct vsp1_dl_entry { >> u32 addr; >> u32 data; >> -} __attribute__((__packed__)); >> +} __packed; > > Do these structures ever actually appear in misaligned memory? > If they don't then they shouldn't be marked 'packed'. I believe the declaration is to ensure that the struct definition is not altered by the compiler as these structures specifically define the layout of how the memory is read by the VSP1 hardware. Certainly 2 u32's sequentially stored in a struct are unlikely to be moved or rearranged by the compiler (though I believe it would be free to do so if it chose without this attribute), but I think the declaration shows the intent of the memory structure. Isn't this a common approach throughout the kernel when dealing with hardware defined memory structures ? Regards -- Kieran > > David >
Re: [PATCH v8 13/13] [media] v4l: Document explicit synchronization behavior
Hi Gustavo, a very small comment below On Fri, Mar 09, 2018 at 02:49:20PM -0300, Gustavo Padovan wrote: > From: Gustavo Padovan> > Add section to VIDIOC_QBUF and VIDIOC_QUERY_BUF about it > > v6: - Close some gaps in the docs (Hans) > > v5: > - Remove V4L2_CAP_ORDERED > - Add doc about V4L2_FMT_FLAG_UNORDERED > > v4: > - Document ordering behavior for in-fences > - Document V4L2_CAP_ORDERED capability > - Remove doc about OUT_FENCE event > - Document immediate return of out-fence in QBUF > > v3: > - make the out_fence refer to the current buffer (Hans) > - Note what happens when the IN_FENCE is not set (Hans) > > v2: > - mention that fences are files (Hans) > - rework for the new API > > Signed-off-by: Gustavo Padovan > --- > Documentation/media/uapi/v4l/vidioc-qbuf.rst | 55 > +++- > Documentation/media/uapi/v4l/vidioc-querybuf.rst | 12 -- > 2 files changed, 63 insertions(+), 4 deletions(-) > [snip] > +Note the the same `fence_fd` field is used for both sending the in-fence as > +input argument to receive the out-fence as a return argument. A buffer can > +have both in-fence ond out-fence. I feel like an "and" is missing here... the same `fence_fd` field is used for both sending the in-fence as input argument to receive the out-fence as a return argument the same `fence_fd` field is used for both sending the in-fence as input argument *and* to receive the out-fence as a return argument I'm not a native speaker so I might be wrong though. Thanks j signature.asc Description: PGP signature
[PATCH] media: s5p-mfc: Use real device for request_firmware() call
Provide proper (real) struct device to request_firmware() call. This fixes following error messages: (NULL device *): Direct firmware load for s5p-mfc-v6-v2.fw failed with error -2 (NULL device *): Direct firmware load for s5p-mfc-v6.fw failed with error -2 into a bit more meaningful ones: s5p-mfc 1100.codec: Direct firmware load for s5p-mfc-v6-v2.fw failed with error -2 s5p-mfc 1100.codec: Direct firmware load for s5p-mfc-v6.fw failed with error -2 Signed-off-by: Marek Szyprowski--- drivers/media/platform/s5p-mfc/s5p_mfc_ctrl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/media/platform/s5p-mfc/s5p_mfc_ctrl.c b/drivers/media/platform/s5p-mfc/s5p_mfc_ctrl.c index f95cd76af537..ef9ae969d307 100644 --- a/drivers/media/platform/s5p-mfc/s5p_mfc_ctrl.c +++ b/drivers/media/platform/s5p-mfc/s5p_mfc_ctrl.c @@ -62,7 +62,7 @@ int s5p_mfc_load_firmware(struct s5p_mfc_dev *dev) if (!dev->variant->fw_name[i]) continue; err = request_firmware((const struct firmware **)_blob, - dev->variant->fw_name[i], dev->v4l2_dev.dev); + dev->variant->fw_name[i], >plat_dev->dev); if (!err) { dev->fw_ver = (enum s5p_mfc_fw_ver) i; break; -- 2.15.0
Re: [PATCH 09/11] media: vsp1: Provide support for extended command pools
Hi Jacopo, On 12/03/18 16:30, jacopo mondi wrote: > Hi Kieran, > just one small thing I noticed below... > > On Fri, Mar 09, 2018 at 10:04:07PM +, Kieran Bingham wrote: >> VSPD and VSP-DL devices can provide extended display lists supporting >> extended command display list objects. >> >> These extended commands require their own dma memory areas for a header >> and body specific to the command type. >> >> Implement a command pool to allocate all necessary memory in a single >> DMA allocation to reduce pressure on the TLB, and provide convenvient >> re-usable command objects for the entities to utilise. >> >> Signed-off-by: Kieran Bingham>> --- >> drivers/media/platform/vsp1/vsp1_dl.c | 189 +++- >> drivers/media/platform/vsp1/vsp1_dl.h | 3 +- >> 2 files changed, 192 insertions(+) >> >> diff --git a/drivers/media/platform/vsp1/vsp1_dl.c >> b/drivers/media/platform/vsp1/vsp1_dl.c >> index 36440a2a2c8b..6d17b8bfa21c 100644 >> --- a/drivers/media/platform/vsp1/vsp1_dl.c >> +++ b/drivers/media/platform/vsp1/vsp1_dl.c >> @@ -121,6 +121,30 @@ struct vsp1_dl_body_pool { >> }; >> >> /** >> + * struct vsp1_cmd_pool - display list body pool >> + * @dma: DMA address of the entries >> + * @size: size of the full DMA memory pool in bytes >> + * @mem: CPU memory pointer for the pool >> + * @bodies: Array of DLB structures for the pool >> + * @free: List of free DLB entries >> + * @lock: Protects the pool and free list >> + * @vsp1: the VSP1 device >> + */ >> +struct vsp1_dl_cmd_pool { >> +/* DMA allocation */ >> +dma_addr_t dma; >> +size_t size; >> +void *mem; >> + >> +struct vsp1_dl_ext_cmd *cmds; >> +struct list_head free; >> + >> +spinlock_t lock; >> + >> +struct vsp1_device *vsp1; >> +}; >> + >> +/** >> * struct vsp1_dl_list - Display list >> * @list: entry in the display list manager lists >> * @dlm: the display list manager >> @@ -176,6 +200,7 @@ struct vsp1_dl_manager { >> struct vsp1_dl_list *pending; >> >> struct vsp1_dl_body_pool *pool; >> +struct vsp1_dl_cmd_pool *autfld_cmds; >> }; >> >> /* >> - >> @@ -339,6 +364,139 @@ void vsp1_dl_body_write(struct vsp1_dl_body *dlb, u32 >> reg, u32 data) >> } >> >> /* >> - >> + * Display List Extended Command Management >> + */ >> + >> +enum vsp1_extcmd_type { >> +VSP1_EXTCMD_AUTODISP, >> +VSP1_EXTCMD_AUTOFLD, >> +}; >> + >> +struct vsp1_extended_command_info { >> +u16 opcode; >> +size_t body_size; >> +} vsp1_extended_commands[] = { >> +[VSP1_EXTCMD_AUTODISP] = { 0x02, 96 }, >> +[VSP1_EXTCMD_AUTOFLD] = { 0x03, 160 }, >> +}; > > How about making this one static and const, since it does not get > modified? Good spot. Certainly. This is just a static descriptor table of the extended command parameter sizes, so it should not change. (but could be added to in later hardware operations I presume). Cheers Kieran > > Thanks >j >
Re: coda: i.MX6 decoding performance issues for multi-streaming
Hi Javier, On Mon, 2018-03-12 at 17:54 +0100, Javier Martin wrote: > Hi, > we have an i.MX6 Solo based board running the latest mainline kernel > (4.15.3). > > As part of our development we were measuring the decoding performance of > the i.MX6 coda chip. > > For that purpose we are feeding the decoder with 640x368 @ 30fps H.264 > streams that have been generated by another i.MX6 coda encoder > configured with fixed qp = 25 and gopsize = 16. > > For 1-2 streams it works smoothly. However, when adding the 3rd stream > the first decoder instance starts to output these kind of errors: > > DEC_PIC_SUCCESS = 2097153 -> 0x21 > DEC_PIC_SUCCESS = 2621441 -> 0x280001 I think these might be (recoverable?) error flags, but so far I have never seen them myself. I've had reports of those occurring occasionally with certain streams (not encoded by coda, regardless of the number of running decoder instances) though. What is the coda firmware version you are using? regards Philipp
[PATCH] venus: vdec: fix format enumeration
find_format_by_index() stops enumerating formats as soon as the index matches, and returns NULL if venus_helper_check_codec() finds out that the format is not supported. This prevents formats to be properly enumerated if a non-supported format is present, as the enumeration will end with it. Fix this by moving the call to venus_helper_check_codec() into the loop, and keep enumerating when it fails. Signed-off-by: Alexandre CourbotChange-Id: I4ff66e0b85172598efa59a6f01da8cb60597a6a5 --- drivers/media/platform/qcom/venus/vdec.c | 13 +++-- drivers/media/platform/qcom/venus/venc.c | 9 +++-- 2 files changed, 14 insertions(+), 8 deletions(-) diff --git a/drivers/media/platform/qcom/venus/vdec.c b/drivers/media/platform/qcom/venus/vdec.c index c9e9576bb08a..3677302cfe43 100644 --- a/drivers/media/platform/qcom/venus/vdec.c +++ b/drivers/media/platform/qcom/venus/vdec.c @@ -135,20 +135,21 @@ find_format_by_index(struct venus_inst *inst, unsigned int index, u32 type) return NULL; for (i = 0; i < size; i++) { + bool valid; + if (fmt[i].type != type) continue; - if (k == index) + valid = (type != V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE || +venus_helper_check_codec(inst, fmt[i].pixfmt)); + if (k == index && valid) break; - k++; + if (valid) + k++; } if (i == size) return NULL; - if (type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE && - !venus_helper_check_codec(inst, fmt[i].pixfmt)) - return NULL; - return [i]; } diff --git a/drivers/media/platform/qcom/venus/venc.c b/drivers/media/platform/qcom/venus/venc.c index e3a10a852cad..5eba4c7cd52e 100644 --- a/drivers/media/platform/qcom/venus/venc.c +++ b/drivers/media/platform/qcom/venus/venc.c @@ -120,11 +120,16 @@ find_format_by_index(struct venus_inst *inst, unsigned int index, u32 type) return NULL; for (i = 0; i < size; i++) { + bool valid; + if (fmt[i].type != type) continue; - if (k == index) + valid = (type != V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE || +venus_helper_check_codec(inst, fmt[i].pixfmt)); + if (k == index && valid) break; - k++; + if (valid) + k++; } if (i == size) -- 2.16.2.660.g709887971b-goog
Re: [PATCH] [media] mceusb: add IR learning support features (IR carrier frequency measurement and wide-band/short range receiver)
Hi, On Sun, Mar 11, 2018 at 05:40:28AM -0400, A Sun wrote: > > Windows Media Center IR transceivers include two IR receivers; > wide-band/short-range and narrow-band/long-range. The short-range > (5cm distance) receiver is for IR learning and has IR carrier > frequency measuring ability. > > Add mceusb driver support to select the short range IR receiver > and enable pass through of its IR carrier frequency measurements. > > RC and LIRC already support these mceusb driver additions. That's great, this feature has been missing for a long time. I've tested it with my four mceusb devices, and I get carrier reports with all of them. Please see the notes below. > Test platform: > > Linux raspberrypi 4.9.59-v7+ #1047 SMP Sun Oct 29 12:19:23 GMT 2017 armv7l > GNU/Linux > mceusb 1-1.2:1.0: Registered Pinnacle Systems PCTV Remote USB with mce > emulator interface version 1 > mceusb 1-1.2:1.0: 2 tx ports (0x0 cabled) and 2 rx sensors (0x1 active) > > Sony TV remote control > > ir-ctl from v4l-utils > > pi@raspberrypi:~ $ ir-ctl -V > IR raw version 1.12.3 > pi@raspberrypi:~ $ ir-ctl -w -m -d /dev/lirc0 -r > ... > pulse 600 > space 600 > pulse 1250 > space 550 > pulse 650 > space 600 > pulse 550 > space 600 > pulse 600 > space 600 > pulse 650 > carrier 38803 Sony protocol remotes have a 4Hz carrier, and I am getting lower values for the carrier with other carrier frequencies as well. Any idea why? > space 16777215 > ^C > pi@raspberrypi:~ $ exit > > Signed-off-by: A Sun> --- > drivers/media/rc/mceusb.c | 90 > ++- > 1 file changed, 82 insertions(+), 8 deletions(-) > > diff --git a/drivers/media/rc/mceusb.c b/drivers/media/rc/mceusb.c > index a9187b0b4..8bbb0f2da 100644 > --- a/drivers/media/rc/mceusb.c > +++ b/drivers/media/rc/mceusb.c > @@ -42,7 +42,7 @@ > #include > #include > > -#define DRIVER_VERSION "1.93" > +#define DRIVER_VERSION "1.94" > #define DRIVER_AUTHOR"Jarod Wilson " > #define DRIVER_DESC "Windows Media Center Ed. eHome Infrared Transceiver " \ > "device driver" > @@ -427,6 +427,7 @@ struct mceusb_dev { > struct rc_dev *rc; > > /* optional features we can enable */ > + bool carrier_report_enabled; > bool learning_enabled; > > /* core device bits */ > @@ -475,6 +476,9 @@ struct mceusb_dev { > u8 txports_cabled; /* bitmask of transmitters with cable */ > u8 rxports_active; /* bitmask of active receive sensors */ > > + /* receiver carrier frequency detection support */ > + u32 pulse_tunit;/* IR pulse "on" cumulative time units */ > + > /* >* support for async error handler mceusb_deferred_kevent() >* where usb_clear_halt(), usb_reset_configuration(), > @@ -956,12 +960,60 @@ static int mceusb_set_tx_carrier(struct rc_dev *dev, > u32 carrier) > } > > /* > + * Select or deselect the 2nd receiver port. > + * Second receiver is learning mode, wide-band, short-range receiver. > + * Only one receiver (long or short range) may be active at a time. > + */ > +static int mceusb_set_rx_wideband(struct rc_dev *dev, int enable) > +{ > + struct mceusb_dev *ir = dev->priv; > + unsigned char cmdbuf[3] = { MCE_CMD_PORT_IR, > + MCE_CMD_SETIRRXPORTEN, 0x00 }; > + > + if (enable != 0 && enable != 1) > + return -EINVAL; > + > + /* > + * cmdbuf[2] is receiver port number > + * port 1 is long range receiver > + * port 2 is short range receiver > + */ > + cmdbuf[2] = enable + 1; You could do enable ? 2 : 1 here and do away with the check above. Enable always is 0 or 1 anyway. > + dev_dbg(ir->dev, "select %s-range receive sensor", > + enable ? "short" : "long"); > + mce_async_out(ir, cmdbuf, sizeof(cmdbuf)); > + > + return 0; > +} > + > +/* > + * Enable/disable receiver carrier frequency pass through reporting. > + * Frequency measurement only works with the short-range receiver. > + * The long-range receiver always reports no carrier frequency > + * (MCE_RSP_EQIRRXCFCNT, 0, 0) so we always ignore its report. > + */ > +static int mceusb_set_rx_carrier_report(struct rc_dev *dev, int enable) > +{ > + struct mceusb_dev *ir = dev->priv; > + > + if (enable != 0 && enable != 1) > + return -EINVAL; This is only called from lirc_dev.c, where the expression is: ret = dev->s_carrier_report(dev, !!val); There is no need to check for enable being not 0 or 1. > + > + dev_dbg(ir->dev, "%s short-range receiver carrier reporting", > + enable ? "enable" : "disable"); > + ir->carrier_report_enabled = (enable == 1); Since enable is 0 or 1, there is no need for the enable == 1 expression. Note that the other drivers that support carrier reports (winbond-cir, redrat3, ene-cir) all enable the wideband receiver when carrier reports are
Re: [PATCH v2 2/2] media: ov2680: Add Omnivision OV2680 sensor driver
Hi Sakari, Thanks for the review... On Fri 09 Mar 2018 at 09:21, Sakari Ailus wrote: Hi Miguel, Thanks for the update. On Wed, Feb 28, 2018 at 03:27:23PM +, Rui Miguel Silva wrote: This patch adds V4L2 sub-device driver for OV2680 image sensor. The OV2680 is a 1/5" CMOS color sensor from Omnivision. Supports output format: 10-bit Raw RGB. The OV2680 has a single lane MIPI interface. The driver exposes following V4L2 controls: - auto/manual exposure, - exposure, - auto/manual gain, - gain, - horizontal/vertical flip, - test pattern menu. Supported resolution are only: QUXGA, 720P, UXGA. Signed-off-by: Rui Miguel Silva--- drivers/media/i2c/Kconfig | 12 + drivers/media/i2c/Makefile |1 + drivers/media/i2c/ov2680.c | 1094 3 files changed, 1107 insertions(+) create mode 100644 drivers/media/i2c/ov2680.c diff --git a/drivers/media/i2c/Kconfig b/drivers/media/i2c/Kconfig index 9f18cd296841..39dc9f236ffa 100644 --- a/drivers/media/i2c/Kconfig +++ b/drivers/media/i2c/Kconfig @@ -586,6 +586,18 @@ config VIDEO_OV2659 To compile this driver as a module, choose M here: the module will be called ov2659. +config VIDEO_OV2680 + tristate "OmniVision OV2680 sensor support" + depends on GPIOLIB && VIDEO_V4L2 && I2C && VIDEO_V4L2_SUBDEV_API + depends on MEDIA_CAMERA_SUPPORT + select V4L2_FWNODE + ---help--- + This is a Video4Linux2 sensor-level driver for the OmniVision + OV2680 camera sensor with a MIPI CSI-2 interface. + + To compile this driver as a module, choose M here: the + module will be called ov2680. + config VIDEO_OV5640 tristate "OmniVision OV5640 sensor support" depends on OF diff --git a/drivers/media/i2c/Makefile b/drivers/media/i2c/Makefile index c0f94cd8d56d..d0aba4d37b8d 100644 --- a/drivers/media/i2c/Makefile +++ b/drivers/media/i2c/Makefile @@ -61,6 +61,7 @@ obj-$(CONFIG_VIDEO_SONY_BTF_MPX) += sony-btf-mpx.o obj-$(CONFIG_VIDEO_UPD64031A) += upd64031a.o obj-$(CONFIG_VIDEO_UPD64083) += upd64083.o obj-$(CONFIG_VIDEO_OV2640) += ov2640.o +obj-$(CONFIG_VIDEO_OV2680) += ov2680.o obj-$(CONFIG_VIDEO_OV5640) += ov5640.o obj-$(CONFIG_VIDEO_OV5645) += ov5645.o obj-$(CONFIG_VIDEO_OV5647) += ov5647.o diff --git a/drivers/media/i2c/ov2680.c b/drivers/media/i2c/ov2680.c new file mode 100644 index ..78f2be27a8f5 --- /dev/null +++ b/drivers/media/i2c/ov2680.c @@ -0,0 +1,1094 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Omnivision OV2680 CMOS Image Sensor driver + * + * Copyright (C) 2018 Linaro Ltd + * + * Based on OV5640 Sensor Driver + * Copyright (C) 2011-2013 Freescale Semiconductor, Inc. All Rights Reserved. + * Copyright (C) 2014-2017 Mentor Graphics Inc. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#define OV2680_XVCLK_MIN 600 +#define OV2680_XVCLK_MAX 2400 + +#define OV2680_CHIP_ID 0x2680 + +#define OV2680_REG_STREAM_CTRL 0x0100 +#define OV2680_REG_SOFT_RESET 0x0103 + +#define OV2680_REG_CHIP_ID_HIGH0x300a +#define OV2680_REG_CHIP_ID_LOW 0x300b + +#define OV2680_REG_R_MANUAL0x3503 +#define OV2680_REG_GAIN_PK 0x350a +#define OV2680_REG_EXPOSURE_PK_HIGH0x3500 +#define OV2680_REG_TIMING_HTS 0x380c +#define OV2680_REG_TIMING_VTS 0x380e +#define OV2680_REG_FORMAT1 0x3820 +#define OV2680_REG_FORMAT2 0x3821 + +#define OV2680_REG_ISP_CTRL00 0x5080 + +#define OV2680_FRAME_RATE 30 + +#define OV2680_REG_VALUE_8BIT 1 +#define OV2680_REG_VALUE_16BIT 2 +#define OV2680_REG_VALUE_24BIT 3 + +enum ov2680_mode_id { + OV2680_MODE_QUXGA_800_600, + OV2680_MODE_720P_1280_720, + OV2680_MODE_UXGA_1600_1200, + OV2680_MODE_MAX, +}; + +struct reg_value { + u16 reg_addr; + u8 val; +}; + +struct ov2680_mode_info { + const char *name; + enum ov2680_mode_id id; + u32 width; + u32 height; + const struct reg_value *reg_data; + u32 reg_data_size; +}; + +struct ov2680_ctrls { + struct v4l2_ctrl_handler handler; + struct { + struct v4l2_ctrl *auto_exp; + struct v4l2_ctrl *exposure; + }; + struct { + struct v4l2_ctrl *auto_gain; + struct v4l2_ctrl *gain; + }; + + struct v4l2_ctrl *hflip; + struct v4l2_ctrl *vflip; + struct v4l2_ctrl *test_pattern; +}; + +struct ov2680_dev { + struct i2c_client *i2c_client; + struct v4l2_subdev sd; + + struct media_padpad; + struct clk *xvclk; + u32 xvclk_freq; + + struct gpio_desc*pwdn_gpio; + struct mutex lock;
Re: [PATCH v2 2/2] media: ov2680: Add Omnivision OV2680 sensor driver
On Tue, Mar 13, 2018 at 11:16:33AM +, Rui Miguel Silva wrote: ... > > > +static int ov2680_gain_set(struct ov2680_dev *sensor, bool > > > auto_gain) > > > +{ > > > + struct ov2680_ctrls *ctrls = >ctrls; > > > + u32 gain; > > > + int ret; > > > + > > > + ret = ov2680_mod_reg(sensor, OV2680_REG_R_MANUAL, BIT(1), > > > + auto_gain ? 0 : BIT(1)); > > > + if (ret < 0) > > > + return ret; > > > + > > > + if (auto_gain || !ctrls->gain->is_new) > > > + return 0; > > > + > > > + gain = ctrls->gain->val; > > > + > > > + ret = ov2680_write_reg16(sensor, OV2680_REG_GAIN_PK, gain); > > > + > > > + return 0; > > > +} > > > + > > > +static int ov2680_gain_get(struct ov2680_dev *sensor) > > > +{ > > > + u32 gain; > > > + int ret; > > > + > > > + ret = ov2680_read_reg16(sensor, OV2680_REG_GAIN_PK, ); > > > + if (ret) > > > + return ret; > > > + > > > + return gain; > > > +} > > > + > > > +static int ov2680_auto_gain_enable(struct ov2680_dev *sensor) > > > +{ > > > + return ov2680_gain_set(sensor, true); > > > > Just call ov2780_gain_set() in the caller. > > Here if you do not mind I would like to have it this way, on the caller > side makes explicit that we are disabling/enabling the auto gain, > instead of going and search what that bool parameter means. > > but, if you do mind... ;) How about renaming that function as e.g. ov2680_autogain_set()? That's what it does, doesn't it? Right now you have these functions doing nothing really useful, cluttering up the code. ... > > > +static const struct i2c_device_id ov2680_id[] = { > > > + {"ov2680", 0}, > > > + { }, > > > > You can remove the i2c_device_id table if you use the probe_new callback > > (instead of probe) below. > > Well this one was hard to debug, so removing the device id table made > the module not to be auto loaded, and after some debug I found the root > cause and it looks it is addressed by this [0]. With that patch removing > the device_id and use probe_new works as expected. > > I will be sending v3 soon. Great, thanks! -- Sakari Ailus sakari.ai...@linux.intel.com
Re: coda: i.MX6 decoding performance issues for multi-streaming
Hi Javier, On Mon, Mar 12, 2018 at 1:54 PM, Javier Martinwrote: > Hi, > we have an i.MX6 Solo based board running the latest mainline kernel > (4.15.3). > > As part of our development we were measuring the decoding performance of the > i.MX6 coda chip. > > For that purpose we are feeding the decoder with 640x368 @ 30fps H.264 > streams that have been generated by another i.MX6 coda encoder configured > with fixed qp = 25 and gopsize = 16. > > For 1-2 streams it works smoothly. However, when adding the 3rd stream the > first decoder instance starts to output these kind of errors: > > DEC_PIC_SUCCESS = 2097153 -> 0x21 > DEC_PIC_SUCCESS = 2621441 -> 0x280001 > > Every time one of these errors appears we can observe a weird artifact in > the decoded video (pixelated macroblocks and/or jumps back in time). > > I tried looking at the original VPU lib implementation by Freescale [1] but > they don't seem to handle these errors either. As I don't have access to any > kind of Coda IP documentation it's quite hard to me to perform any > additional debugging. > > Has anyone experienced these kind of performance issues too? I'm open to any > suggestions and willing to perform extra tests to get to the bottom of this. Are you passing 'capture-io-mode=dmabuf' in your Gstreamer pipeline? This really improves the performance of video decoding.
[PATCH] media: cxd2880-spi: avoid out-of-bounds access warning
The -Warray-bounds warning in gcc-8 triggers for a newly added file: drivers/media/spi/cxd2880-spi.c: In function 'cxd2880_write_reg': drivers/media/spi/cxd2880-spi.c:111:3: error: 'memcpy' forming offset [133, 258] is out of the bounds [0, 132] of object 'send_data' with type 'u8[132]' {aka 'unsigned char[132]'} [-Werror=array-bounds] The problem appears to be that we have two range checks in this function, first comparing against BURST_WRITE_MAX (128) and then comparing against a literal '255'. The logic checking the buffer size looks at the second one and decides that this might be the actual maximum data length. This is understandable behavior from the compiler, but the code is actually safe. Since the first check is already shorter, we can remove the loop and only leave that. To be on the safe side in case BURST_WRITE_MAX might be increased, I'm leaving the check against U8_MAX. Fixes: bd24fcddf6b8 ("media: cxd2880-spi: Add support for CXD2880 SPI interface") Cc: Martin SeborSigned-off-by: Arnd Bergmann --- drivers/media/spi/cxd2880-spi.c | 24 +++- 1 file changed, 7 insertions(+), 17 deletions(-) diff --git a/drivers/media/spi/cxd2880-spi.c b/drivers/media/spi/cxd2880-spi.c index 4df3bd312f48..011a37c2f272 100644 --- a/drivers/media/spi/cxd2880-spi.c +++ b/drivers/media/spi/cxd2880-spi.c @@ -88,7 +88,7 @@ static int cxd2880_write_reg(struct spi_device *spi, pr_err("invalid arg\n"); return -EINVAL; } - if (size > BURST_WRITE_MAX) { + if (size > BURST_WRITE_MAX || size > U8_MAX) { pr_err("data size > WRITE_MAX\n"); return -EINVAL; } @@ -101,24 +101,14 @@ static int cxd2880_write_reg(struct spi_device *spi, send_data[0] = 0x0e; write_data_top = data; - while (size > 0) { - send_data[1] = sub_address; - if (size > 255) - send_data[2] = 255; - else - send_data[2] = (u8)size; + send_data[1] = sub_address; + send_data[2] = (u8)size; - memcpy(_data[3], write_data_top, send_data[2]); + memcpy(_data[3], write_data_top, send_data[2]); - ret = cxd2880_write_spi(spi, send_data, send_data[2] + 3); - if (ret) { - pr_err("write spi failed %d\n", ret); - break; - } - sub_address += send_data[2]; - write_data_top += send_data[2]; - size -= send_data[2]; - } + ret = cxd2880_write_spi(spi, send_data, send_data[2] + 3); + if (ret) + pr_err("write spi failed %d\n", ret); return ret; } -- 2.9.0
[PATCH] media: ngene: avoid unused variable warning
The newly added pdev variable is only used in an #ifdef, causing a build warning without CONFIG_PCI_MSI, unless we move the declaration inside the same #ifdef: drivers/media/pci/ngene/ngene-core.c: In function 'ngene_start': drivers/media/pci/ngene/ngene-core.c:1328:17: error: unused variable 'pdev' [-Werror=unused-variable] Fixes: 6795bf626482 ("media: ngene: convert kernellog printing from printk() to dev_*() macros") Signed-off-by: Arnd Bergmann--- drivers/media/pci/ngene/ngene-core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/media/pci/ngene/ngene-core.c b/drivers/media/pci/ngene/ngene-core.c index 3b9a1bfaf6c0..25f16833a475 100644 --- a/drivers/media/pci/ngene/ngene-core.c +++ b/drivers/media/pci/ngene/ngene-core.c @@ -1325,7 +1325,6 @@ static int ngene_buffer_config(struct ngene *dev) static int ngene_start(struct ngene *dev) { - struct device *pdev = >pci_dev->dev; int stat; int i; @@ -1359,6 +1358,7 @@ static int ngene_start(struct ngene *dev) #ifdef CONFIG_PCI_MSI /* enable MSI if kernel and card support it */ if (pci_msi_enabled() && dev->card_info->msi_supported) { + struct device *pdev = >pci_dev->dev; unsigned long flags; ngwritel(0, NGENE_INT_ENABLE); -- 2.9.0
[PATCH] media: imx: work around false-positive warning
The IS_ERR()/PTR_ERR() combination confuses gcc to the point that it cannot prove the upstream_ep variable to be initialized: drivers/staging/media/imx/imx-media-csi.c: In function 'csi_link_validate': drivers/staging/media/imx/imx-media-csi.c:1025:20: error: 'upstream_ep' may be used uninitialized in this function [-Werror=maybe-uninitialized] priv->upstream_ep = upstream_ep; ~~^ drivers/staging/media/imx/imx-media-csi.c:1026:24: error: 'upstream_ep.bus_type' may be used uninitialized in this function [-Werror=maybe-uninitialized] is_csi2 = (upstream_ep.bus_type == V4L2_MBUS_CSI2); ~~~^ drivers/staging/media/imx/imx-media-csi.c:127:19: error: 'upstream_ep.bus.parallel.bus_width' may be used uninitialized in this function [-Werror=maybe-uninitialized] I could come up with no good way to rewrite this function, as a last resort, this adds an explicit zero-intialization of the structure. Fixes: 52e17089d185 ("media: imx: Don't initialize vars that won't be used") Signed-off-by: Arnd Bergmann--- drivers/staging/media/imx/imx-media-csi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/media/imx/imx-media-csi.c b/drivers/staging/media/imx/imx-media-csi.c index 5a195f80a24d..887fed0c3ce0 100644 --- a/drivers/staging/media/imx/imx-media-csi.c +++ b/drivers/staging/media/imx/imx-media-csi.c @@ -1004,7 +1004,7 @@ static int csi_link_validate(struct v4l2_subdev *sd, struct v4l2_subdev_format *sink_fmt) { struct csi_priv *priv = v4l2_get_subdevdata(sd); - struct v4l2_fwnode_endpoint upstream_ep; + struct v4l2_fwnode_endpoint upstream_ep = {}; const struct imx_media_pixfmt *incc; bool is_csi2; int ret; -- 2.9.0
Re: [PATCH 08/12] media: ov5640: Adjust the clock based on the expected rate
Hi Sakari, On Fri, Mar 09, 2018 at 01:16:24PM +0200, Sakari Ailus wrote: > > + * > > + * +--+ > > + * | Oscillator | > > I wonder if this should be simply called external clock, that's what the > sensor uses. Ack > > + * +--+---+ > > + * | > > + * +--+---+ > > + * | System clock | - reg 0x3035, bits 4-7 > > + * +--+---+ > > + * | > > + * +--+---+ - reg 0x3036, for the multiplier > > + * | PLL | - reg 0x3037, bits 4 for the root divider > > + * +--+---+ - reg 0x3037, bits 0-3 for the pre-divider > > + * | > > + * +--+---+ > > + * | SCLK | - reg 0x3108, bits 0-1 for the root divider > > + * +--+---+ > > + * | > > + * +--+---+ > > + * |PCLK | - reg 0x3108, bits 4-5 for the root divider > > + * +--+ > > + * > > + * This is deviating from the datasheet at least for the register > > + * 0x3108, since it's said here that the PCLK would be clocked from > > + * the PLL. However, changing the SCLK divider value has a direct > > + * effect on the PCLK rate, which wouldn't be the case if both PCLK > > + * and SCLK were to be sourced from the PLL. > > + * > > + * These parameters also match perfectly the rate that is output by > > + * the sensor, so we shouldn't have too much factors missing (or they > > + * would be set to 1). > > + */ > > + > > +/* > > + * FIXME: This is supposed to be ranging from 1 to 16, but the value > > + * is always set to either 1 or 2 in the vendor kernels. > > There could be limits for the clock rates after the first divider. In > practice the clock rates are mostly one of the common frequencies (9,6; 12; > 19,2 or 24 MHz) so there's no need to use the other values. There's probably some limits on the various combinations as well. I first tried to use the full range, and there was some combinations that were not usable, even though the clock rate should have been correct. > > + */ > > +#define OV5640_SYSDIV_MIN 1 > > +#define OV5640_SYSDIV_MAX 2 > > + > > +static unsigned long ov5640_calc_sysclk(struct ov5640_dev *sensor, > > + unsigned long rate, > > + u8 *sysdiv) > > +{ > > + unsigned long best = ~0; > > + u8 best_sysdiv = 1; > > + u8 _sysdiv; > > + > > + for (_sysdiv = OV5640_SYSDIV_MIN; > > +_sysdiv <= OV5640_SYSDIV_MAX; > > +_sysdiv++) { > > + unsigned long tmp; > > + > > + tmp = sensor->xclk_freq / _sysdiv; > > + if (abs(rate - tmp) < abs(rate - best)) { > > + best = tmp; > > + best_sysdiv = _sysdiv; > > + } > > + > > + if (tmp == rate) > > + goto out; > > + } > > + > > +out: > > + *sysdiv = best_sysdiv; > > + return best; > > +} > > + > > +/* > > + * FIXME: This is supposed to be ranging from 1 to 8, but the value is > > + * always set to 3 in the vendor kernels. > > + */ > > +#define OV5640_PLL_PREDIV_MIN 3 > > +#define OV5640_PLL_PREDIV_MAX 3 > > Same reasoning here than above. I might leave a comment documenting the > values the hardware supports, removing FIXME as this isn't really an issue > as far as I see. Ok, I'll do it then > > + > > +/* > > + * FIXME: This is supposed to be ranging from 1 to 2, but the value is > > + * always set to 1 in the vendor kernels. > > + */ > > +#define OV5640_PLL_ROOT_DIV_MIN1 > > +#define OV5640_PLL_ROOT_DIV_MAX1 > > + > > +#define OV5640_PLL_MULT_MIN4 > > +#define OV5640_PLL_MULT_MAX252 > > + > > +static unsigned long ov5640_calc_pll(struct ov5640_dev *sensor, > > +unsigned long rate, > > +u8 *sysdiv, u8 *prediv, u8 *rdiv, u8 *mult) > > +{ > > + unsigned long best = ~0; > > + u8 best_sysdiv = 1, best_prediv = 1, best_mult = 1, best_rdiv = 1; > > + u8 _prediv, _mult, _rdiv; > > + > > + for (_prediv = OV5640_PLL_PREDIV_MIN; > > +_prediv <= OV5640_PLL_PREDIV_MAX; > > +_prediv++) { > > + for (_mult = OV5640_PLL_MULT_MIN; > > +_mult <= OV5640_PLL_MULT_MAX; > > +_mult++) { > > + for (_rdiv = OV5640_PLL_ROOT_DIV_MIN; > > +_rdiv <= OV5640_PLL_ROOT_DIV_MAX; > > +_rdiv++) { > > + unsigned long pll; > > + unsigned long sysclk; > > + u8 _sysdiv; > > + > > + /* > > +* The PLL multiplier cannot be odd if > > +* above 127. > > +*/ > > + if (_mult > 127 && !(_mult % 2)) > > + continue; > > + > > + sysclk = rate * _prediv * _rdiv / _mult; > > + sysclk =
Re: [PATCH 00/12] media: ov5640: Misc cleanup and improvements
Thanks Maxime for this great series ! I've tested this series successfully on STM32 platform, I had a regression on JPEG capture linked to revisit of clocking, but easy to fix. I had another problem claimed by v4l2-compliance on format tests: v4l2-test-formats.cpp(961): Video Capture: S_FMT(G_FMT) != G_FMT this was more tricky to fix, it is linked to changes around framerate handling. See my further comments in corresponding patchsets. Best regards, Hugues. On 03/02/2018 03:34 PM, Maxime Ripard wrote: > Hi, > > Here is a "small" series that mostly cleans up the ov5640 driver code, > slowly getting rid of the big data array for more understandable code > (hopefully). > > The biggest addition would be the clock rate computation at runtime, > instead of relying on those arrays to setup the clock tree > properly. As a side effect, it fixes the framerate that was off by > around 10% on the smaller resolutions, and we now support 60fps. > > This also introduces a bunch of new features. > > Let me know what you think, > Maxime > > Maxime Ripard (10): >media: ov5640: Don't force the auto exposure state at start time >media: ov5640: Init properly the SCLK dividers >media: ov5640: Change horizontal and vertical resolutions name >media: ov5640: Add horizontal and vertical totals >media: ov5640: Program the visible resolution >media: ov5640: Adjust the clock based on the expected rate >media: ov5640: Compute the clock rate at runtime >media: ov5640: Enhance FPS handling >media: ov5640: Add 60 fps support >media: ov5640: Remove duplicate auto-exposure setup > > Mylène Josserand (2): >media: ov5640: Add auto-focus feature >media: ov5640: Add light frequency control > > drivers/media/i2c/ov5640.c | 777 > ++--- > 1 file changed, 452 insertions(+), 325 deletions(-) >
RE: [PATCH 02/11] media: vsp1: use kernel __packed for structures
From: Kieran Bingham [mailto:kieran.bingham+rene...@ideasonboard.com] > On 13/03/18 11:20, David Laight wrote: > > From: Kieran Bingham > >> Sent: 09 March 2018 22:04 > >> The kernel provides a __packed definition to abstract away from the > >> compiler specific attributes tag. > >> > >> Convert all packed structures in VSP1 to use it. > >> > >> Signed-off-by: Kieran Bingham> >> --- > >> drivers/media/platform/vsp1/vsp1_dl.c | 6 +++--- > >> 1 file changed, 3 insertions(+), 3 deletions(-) > >> > >> diff --git a/drivers/media/platform/vsp1/vsp1_dl.c > >> b/drivers/media/platform/vsp1/vsp1_dl.c > >> index 37e2c984fbf3..382e45c2054e 100644 > >> --- a/drivers/media/platform/vsp1/vsp1_dl.c > >> +++ b/drivers/media/platform/vsp1/vsp1_dl.c > >> @@ -29,19 +29,19 @@ > >> struct vsp1_dl_header_list { > >>u32 num_bytes; > >>u32 addr; > >> -} __attribute__((__packed__)); > >> +} __packed; > >> > >> struct vsp1_dl_header { > >>u32 num_lists; > >>struct vsp1_dl_header_list lists[8]; > >>u32 next_header; > >>u32 flags; > >> -} __attribute__((__packed__)); > >> +} __packed; > >> > >> struct vsp1_dl_entry { > >>u32 addr; > >>u32 data; > >> -} __attribute__((__packed__)); > >> +} __packed; > > > > Do these structures ever actually appear in misaligned memory? > > If they don't then they shouldn't be marked 'packed'. > > I believe the declaration is to ensure that the struct definition is not > altered > by the compiler as these structures specifically define the layout of how the > memory is read by the VSP1 hardware. The C language and ABI define structure layouts. > Certainly 2 u32's sequentially stored in a struct are unlikely to be moved or > rearranged by the compiler (though I believe it would be free to do so if it > chose without this attribute), but I think the declaration shows the intent of > the memory structure. The language requires the fields be in order and the ABI stops the compiler adding 'random' padding. > Isn't this a common approach throughout the kernel when dealing with hardware > defined memory structures ? Absolutely not. __packed tells the compiler that the structure might be on any address boundary. On many architectures this means the compiler must use byte accesses with shifts and ors for every access. The most a hardware defined structure will have is a compile-time assert that it is the correct size (to avoid silly errors from changes). David
Re: [PATCH 09/12] media: ov5640: Compute the clock rate at runtime
Hi Maxime, Below comments about JPEG issue. On 03/02/2018 03:34 PM, Maxime Ripard wrote: > The clock rate, while hardcoded until now, is actually a function of the > resolution, framerate and bytes per pixel. Now that we have an algorithm to > adjust our clock rate, we can select it dynamically when we change the > mode. > > This changes a bit the clock rate being used, with the following effect: > > +--+--+--+--+-+-++---+ > | Hact | Vact | Htot | Vtot | FPS | Hardcoded clock | Computed clock | > Deviation | > +--+--+--+--+-+-++---+ > | 640 | 480 | 1896 | 1080 | 15 |5600 | 61430400 | 8.84 % >| > | 640 | 480 | 1896 | 1080 | 30 | 11200 | 122860800 | 8.84 % >| > | 1024 | 768 | 1896 | 1080 | 15 |5600 | 61430400 | 8.84 % >| > | 1024 | 768 | 1896 | 1080 | 30 | 11200 | 122860800 | 8.84 % >| > | 320 | 240 | 1896 | 984 | 15 |5600 | 55969920 | 0.05 % >| > | 320 | 240 | 1896 | 984 | 30 | 11200 | 111939840 | 0.05 % >| > | 176 | 144 | 1896 | 984 | 15 |5600 | 55969920 | 0.05 % >| > | 176 | 144 | 1896 | 984 | 30 | 11200 | 111939840 | 0.05 % >| > | 720 | 480 | 1896 | 984 | 15 |5600 | 55969920 | 0.05 % >| > | 720 | 480 | 1896 | 984 | 30 | 11200 | 111939840 | 0.05 % >| > | 720 | 576 | 1896 | 984 | 15 |5600 | 55969920 | 0.05 % >| > | 720 | 576 | 1896 | 984 | 30 | 11200 | 111939840 | 0.05 % >| > | 1280 | 720 | 1892 | 740 | 15 |4200 | 42002400 | 0.01 % >| > | 1280 | 720 | 1892 | 740 | 30 |8400 | 84004800 | 0.01 % >| > | 1920 | 1080 | 2500 | 1120 | 15 |8400 | 8400 | 0.00 % >| > | 1920 | 1080 | 2500 | 1120 | 30 | 16800 | 16800 | 0.00 % >| > | 2592 | 1944 | 2844 | 1944 | 15 |8400 | 165862080 | 49.36 > % | > +--+--+--+--+-+-++---+ > > Only the 640x480, 1024x768 and 2592x1944 modes are significantly affected > by the new formula. > > In this case, 640x480 and 1024x768 are actually fixed by this driver. > Indeed, the sensor was sending data at, for example, 27.33fps instead of > 30fps. This is -9%, which is roughly what we're seeing in the array. > Testing these modes with the new clock setup actually fix that error, and > data are now sent at around 30fps. > > 2592x1944, on the other hand, is probably due to the fact that this mode > can only be used using MIPI-CSI2, in a two lane mode. This would have to be > tested though. > > Signed-off-by: Maxime Ripard> --- > drivers/media/i2c/ov5640.c | 41 + > 1 file changed, 17 insertions(+), 24 deletions(-) > > diff --git a/drivers/media/i2c/ov5640.c b/drivers/media/i2c/ov5640.c > index 323cde27dd8b..bdf378d80e07 100644 > --- a/drivers/media/i2c/ov5640.c > +++ b/drivers/media/i2c/ov5640.c > @@ -126,6 +126,12 @@ static const struct ov5640_pixfmt ov5640_formats[] = { > { MEDIA_BUS_FMT_RGB565_2X8_BE, V4L2_COLORSPACE_SRGB, }, > }; > > +/* > + * FIXME: If we ever have something else, we'll obviously need to have > + * something smarter. > + */ > +#define OV5640_FORMATS_BPP 2 > + We have the case with JPEG which is 1 byte. > /* >* FIXME: remove this when a subdev API becomes available >* to set the MIPI CSI-2 virtual channel. > @@ -172,7 +178,6 @@ struct ov5640_mode_info { > u32 htot; > u32 vact; > u32 vtot; > - u32 clock; > const struct reg_value *reg_data; > u32 reg_data_size; > }; > @@ -696,7 +701,6 @@ static const struct reg_value > ov5640_setting_15fps_QSXGA_2592_1944[] = { > /* power-on sensor init reg table */ > static const struct ov5640_mode_info ov5640_mode_init_data = { > 0, SUBSAMPLING, 640, 1896, 480, 984, > - 11200, > ov5640_init_setting_30fps_VGA, > ARRAY_SIZE(ov5640_init_setting_30fps_VGA), > }; > @@ -706,91 +710,74 @@ > ov5640_mode_data[OV5640_NUM_FRAMERATES][OV5640_NUM_MODES] = { > { > {OV5640_MODE_QCIF_176_144, SUBSAMPLING, >176, 1896, 144, 984, > - 5600, >ov5640_setting_15fps_QCIF_176_144, >ARRAY_SIZE(ov5640_setting_15fps_QCIF_176_144)}, > {OV5640_MODE_QVGA_320_240, SUBSAMPLING, >320, 1896, 240, 984, > - 5600, >ov5640_setting_15fps_QVGA_320_240, >ARRAY_SIZE(ov5640_setting_15fps_QVGA_320_240)}, > {OV5640_MODE_VGA_640_480, SUBSAMPLING, >640, 1896, 480, 1080, > - 5600, >
Re: [PATCH 02/11] media: vsp1: use kernel __packed for structures
Hi David, On 13/03/18 13:38, David Laight wrote: > From: Kieran Bingham [mailto:kieran.bingham+rene...@ideasonboard.com] >> On 13/03/18 11:20, David Laight wrote: >>> From: Kieran Bingham Sent: 09 March 2018 22:04 The kernel provides a __packed definition to abstract away from the compiler specific attributes tag. Convert all packed structures in VSP1 to use it. Signed-off-by: Kieran Bingham--- drivers/media/platform/vsp1/vsp1_dl.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/media/platform/vsp1/vsp1_dl.c b/drivers/media/platform/vsp1/vsp1_dl.c index 37e2c984fbf3..382e45c2054e 100644 --- a/drivers/media/platform/vsp1/vsp1_dl.c +++ b/drivers/media/platform/vsp1/vsp1_dl.c @@ -29,19 +29,19 @@ struct vsp1_dl_header_list { u32 num_bytes; u32 addr; -} __attribute__((__packed__)); +} __packed; struct vsp1_dl_header { u32 num_lists; struct vsp1_dl_header_list lists[8]; u32 next_header; u32 flags; -} __attribute__((__packed__)); +} __packed; struct vsp1_dl_entry { u32 addr; u32 data; -} __attribute__((__packed__)); +} __packed; >>> >>> Do these structures ever actually appear in misaligned memory? >>> If they don't then they shouldn't be marked 'packed'. >> >> I believe the declaration is to ensure that the struct definition is not >> altered >> by the compiler as these structures specifically define the layout of how the >> memory is read by the VSP1 hardware. > > The C language and ABI define structure layouts. > >> Certainly 2 u32's sequentially stored in a struct are unlikely to be moved or >> rearranged by the compiler (though I believe it would be free to do so if it >> chose without this attribute), but I think the declaration shows the intent >> of >> the memory structure. > > The language requires the fields be in order and the ABI stops the compiler > adding 'random' padding. > >> Isn't this a common approach throughout the kernel when dealing with hardware >> defined memory structures ? > > Absolutely not. > __packed tells the compiler that the structure might be on any address > boundary. > On many architectures this means the compiler must use byte accesses with > shifts > and ors for every access. > The most a hardware defined structure will have is a compile-time assert > that it is the correct size (to avoid silly errors from changes). Ok - interesting, I see what you're saying - and certainly don't want the compiler to be performing byte accesses on the structures unnecessarily. I'm trying to distinguish the difference here. Is the single point that __packed causes byte-access, where as __attribute__((__packed__)); does not? Looking at the GCC docs [0]: I see that __attribute__((__packed__)) tells the compiler that the "structure or union is placed to minimize the memory required". However, the keil compiler docs[1] do certainly declare that __packed causes byte alignment. I was confused/thrown off here by the Kernel defining __packed as __attribute__((packed)) at [2]. Do __attribute__((packed)) and __attribute__((__packed__)) differ ? In which case, from what I've read so far I wish "__packed" was "__unaligned"... [0] https://gcc.gnu.org/onlinedocs/gcc/Common-Type-Attributes.html#index-packed-type-attribute [1] http://www.keil.com/support/man/docs/armcc/armcc_chr1359124230195.htm [2] https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/include/linux/compiler-gcc.h?h=v4.16-rc5#n92 Regards Kieran > David >
[PATCH] media: v4l: omap_vout: vrfb: remove an unused variable
We now get a warning after the 'dmadev' variable is no longer used: drivers/media/platform/omap/omap_vout_vrfb.c: In function 'omap_vout_prepare_vrfb': drivers/media/platform/omap/omap_vout_vrfb.c:239:21: error: unused variable 'dmadev' [-Werror=unused-variable] Fixes: 8f0aa38292f2 ("media: v4l: omap_vout: vrfb: Use the wrapper for prep_interleaved_dma()") Signed-off-by: Arnd Bergmann--- drivers/media/platform/omap/omap_vout_vrfb.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/media/platform/omap/omap_vout_vrfb.c b/drivers/media/platform/omap/omap_vout_vrfb.c index 72c0ac2cbf3d..1d8508237220 100644 --- a/drivers/media/platform/omap/omap_vout_vrfb.c +++ b/drivers/media/platform/omap/omap_vout_vrfb.c @@ -236,7 +236,6 @@ int omap_vout_prepare_vrfb(struct omap_vout_device *vout, struct dma_async_tx_descriptor *tx; enum dma_ctrl_flags flags = DMA_PREP_INTERRUPT | DMA_CTRL_ACK; struct dma_chan *chan = vout->vrfb_dma_tx.chan; - struct dma_device *dmadev = chan->device; struct dma_interleaved_template *xt = vout->vrfb_dma_tx.xt; dma_cookie_t cookie; enum dma_status status; -- 2.9.0
Re: [PATCH] media: v4l: omap_vout: vrfb: remove an unused variable
On 2018-03-13 14:05, Arnd Bergmann wrote: > We now get a warning after the 'dmadev' variable is no longer used: > > drivers/media/platform/omap/omap_vout_vrfb.c: In function > 'omap_vout_prepare_vrfb': > drivers/media/platform/omap/omap_vout_vrfb.c:239:21: error: unused variable > 'dmadev' [-Werror=unused-variable] > > Fixes: 8f0aa38292f2 ("media: v4l: omap_vout: vrfb: Use the wrapper for > prep_interleaved_dma()") > Signed-off-by: Arnd BergmannReviewed-by: Peter Ujfalusi > --- > drivers/media/platform/omap/omap_vout_vrfb.c | 1 - > 1 file changed, 1 deletion(-) > > diff --git a/drivers/media/platform/omap/omap_vout_vrfb.c > b/drivers/media/platform/omap/omap_vout_vrfb.c > index 72c0ac2cbf3d..1d8508237220 100644 > --- a/drivers/media/platform/omap/omap_vout_vrfb.c > +++ b/drivers/media/platform/omap/omap_vout_vrfb.c > @@ -236,7 +236,6 @@ int omap_vout_prepare_vrfb(struct omap_vout_device *vout, > struct dma_async_tx_descriptor *tx; > enum dma_ctrl_flags flags = DMA_PREP_INTERRUPT | DMA_CTRL_ACK; > struct dma_chan *chan = vout->vrfb_dma_tx.chan; > - struct dma_device *dmadev = chan->device; > struct dma_interleaved_template *xt = vout->vrfb_dma_tx.xt; > dma_cookie_t cookie; > enum dma_status status; > - Péter Texas Instruments Finland Oy, Porkkalankatu 22, 00180 Helsinki. Y-tunnus/Business ID: 0615521-4. Kotipaikka/Domicile: Helsinki
Re: [PATCH] media: ov5640: add missing output pixel format setting
2018-03-13 1:18 GMT+09:00 Hugues FRUCHET: > Hi Akinobu, > > Thanks for the patch, could you describe the test you made to reproduce > the issue that I can test on my side ? > > I'm using usually yavta or Gstreamer, but I don't know how to trig the > power on/off independently of streamon/off. Capturing a single image by yavta and gstreamer can reproduce this issue in my environment. I use Xilinx Video IP driver for video device with the following change in order to support pipeline power management. https://patchwork.linuxtv.org/patch/46343/ With this change, when opening the video device, s_power() is called with on=1 for subdevice. I observed the following steps when capturing a single image by 'yavta -n1 -c1 -Ftest.raw /dev/video1'. (The output pixel format is already set up by media-ctl before this run) 1. open /dev/video1 2. ov5640_s_power() is called with on=1 (ov5640_s_power -> ov5640_set_power -> ov5640_restore_mode -> ov5640_set_mode, and pending_mode_change is cleared) 3. ov5640_s_stream() is called with on=1 (But ov5640_set_framefmt() is not called because pending_mode_change has already been cleared in step 2.) As ov5640_set_framefmt() is not called, output pixel format cannot be restored (OV5640_REG_FORMAT_CONTROL00 and OV5640_REG_ISP_FORMAT_MUX_CTRL).
[RfC PATCH] Add udmabuf misc device
A driver to let userspace turn iovecs into dma-bufs. Use case: Allows qemu pass around dmabufs for the guest framebuffer. https://www.kraxel.org/cgit/qemu/log/?h=sirius/udmabuf has an experimental patch. Also allows qemu to export guest virtio-gpu resources as host dmabufs. Should be possible to use it to display guest wayland windows on the host display server. virtio-gpu ressources can be chunked so we will actually need multiple iovec entries. UNTESTED. Want collect some feedback on the general approach with this RfC series. Can this work? If not, better ideas? Question: Must this be hooked into some kind of mlock accounting, to limit the amout of memory userspace is allowed to pin this way? Or will get_user_pages_fast() handle that for me? Known issue: Driver API isn't complete yet. Need add some flags, for example to support read-only buffers. Cc: David AirlieCc: Tomeu Vizoso Signed-off-by: Gerd Hoffmann --- include/uapi/linux/udmabuf.h | 21 drivers/dma-buf/udmabuf.c| 250 +++ drivers/dma-buf/Kconfig | 7 ++ drivers/dma-buf/Makefile | 1 + 4 files changed, 279 insertions(+) create mode 100644 include/uapi/linux/udmabuf.h create mode 100644 drivers/dma-buf/udmabuf.c diff --git a/include/uapi/linux/udmabuf.h b/include/uapi/linux/udmabuf.h new file mode 100644 index 00..fd2fa441fe --- /dev/null +++ b/include/uapi/linux/udmabuf.h @@ -0,0 +1,21 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ +#ifndef _UAPI_LINUX_UDMABUF_H +#define _UAPI_LINUX_UDMABUF_H + +#include +#include + +struct udmabuf_iovec { + __u64 base; + __u64 len; +}; + +struct udmabuf_create { + __u32 flags; + __u32 niov; + struct udmabuf_iovec iovs[]; +}; + +#define UDMABUF_CREATE _IOW(0x42, 0x23, struct udmabuf_create) + +#endif /* _UAPI_LINUX_UDMABUF_H */ diff --git a/drivers/dma-buf/udmabuf.c b/drivers/dma-buf/udmabuf.c new file mode 100644 index 00..ec012d7ac7 --- /dev/null +++ b/drivers/dma-buf/udmabuf.c @@ -0,0 +1,250 @@ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +struct udmabuf { + u32 pagecount; + struct page **pages; +}; + +static int udmabuf_vm_fault(struct vm_fault *vmf) +{ + struct vm_area_struct *vma = vmf->vma; + struct udmabuf *ubuf = vma->vm_private_data; + + if (WARN_ON(vmf->pgoff >= ubuf->pagecount)) + return VM_FAULT_SIGBUS; + + vmf->page = ubuf->pages[vmf->pgoff]; + get_page(vmf->page); + return 0; +} + +static const struct vm_operations_struct udmabuf_vm_ops = { + .fault = udmabuf_vm_fault, +}; + +static int mmap_udmabuf(struct dma_buf *buf, struct vm_area_struct *vma) +{ + struct udmabuf *ubuf = buf->priv; + + if ((vma->vm_flags & VM_SHARED) == 0) + return -EINVAL; + + vma->vm_ops = _vm_ops; + vma->vm_private_data = ubuf; + return 0; +} + +static struct sg_table *map_udmabuf(struct dma_buf_attachment *at, + enum dma_data_direction direction) +{ + struct udmabuf *ubuf = at->dmabuf->priv; + struct sg_table *sg; + + sg = kzalloc(sizeof(*sg), GFP_KERNEL); + if (!sg) + goto err1; + if (sg_alloc_table_from_pages(sg, ubuf->pages, ubuf->pagecount, + 0, ubuf->pagecount << PAGE_SHIFT, + GFP_KERNEL) < 0) + goto err2; + if (!dma_map_sg(at->dev, sg->sgl, sg->nents, direction)) + goto err3; + + return sg; + +err3: + sg_free_table(sg); +err2: + kfree(sg); +err1: + return ERR_PTR(-ENOMEM); +} + +static void unmap_udmabuf(struct dma_buf_attachment *at, + struct sg_table *sg, + enum dma_data_direction direction) +{ + sg_free_table(sg); + kfree(sg); +} + +static void release_udmabuf(struct dma_buf *buf) +{ + struct udmabuf *ubuf = buf->priv; + pgoff_t pg; + + for (pg = 0; pg < ubuf->pagecount; pg++) + put_page(ubuf->pages[pg]); + kfree(ubuf->pages); + kfree(ubuf); +} + +static void *kmap_atomic_udmabuf(struct dma_buf *buf, unsigned long offset) +{ + struct udmabuf *ubuf = buf->priv; + struct page *page = ubuf->pages[offset >> PAGE_SHIFT]; + + return kmap_atomic(page); +} + +static void *kmap_udmabuf(struct dma_buf *buf, unsigned long offset) +{ + struct udmabuf *ubuf = buf->priv; + struct page *page = ubuf->pages[offset >> PAGE_SHIFT]; + + return kmap(page); +} + +static struct dma_buf_ops udmabuf_ops = { +
Re: [PATCH 1/4] dma-buf: add optional invalidate_mappings callback
On Tue, Mar 13, 2018 at 04:52:02PM +0100, Christian König wrote: > Am 13.03.2018 um 16:17 schrieb Daniel Vetter: > > [SNIP] > > > > I think a helper which both unmaps _and_ waits for all the fences to > > > > clear > > > > would be best, with some guarantees that it'll either fail or all the > > > > mappings _will_ be gone. The locking for that one will be hilarious, > > > > since > > > > we need to figure out dmabuf->lock vs. the reservation. I kinda prefer > > > > we > > > > throw away the dmabuf->lock and superseed it entirely by the reservation > > > > lock. > > > Big NAK on that. The whole API is asynchronously, e.g. we never block for > > > any operation to finish. > > > > > > Otherwise you run into big trouble with cross device GPU resets and stuff > > > like that. > > But how will the unmapping work then? You can't throw the sg list away > > before the dma stopped. The dma only stops once the fence is signalled. > > The importer can't call dma_buf_detach because the reservation lock is > > hogged already by the exporter trying to unmap everything. > > > > How is this supposed to work? > > Even after invalidation the sg list stays alive until it is explicitly > destroyed by the importer using dma_buf_unmap_attachment() which in turn is > only allowed after all fences have signaled. > > The implementation is in ttm_bo_pipeline_gutting(), basically we use the > same functionality as for pipelined moves/evictions which hangs the old > backing store on a dummy object and destroys it after all fences signaled. > > While the old sg list is still about to be destroyed the importer can > request a new sg list for the new location of the DMA-buf using > dma_buf_map_attachment(). This new location becomes valid after the move > fence in the reservation object is signaled. > > So from the CPU point of view multiple sg list could exists at the same time > which allows us to have a seamless transition from the old to the new > location from the GPU point of view. Ok, so plan is to support fully pipeline moves and everything, with the old sg tables lazily cleaned up. I was thinking more about evicting stuff and throwing it out, where there's not going to be any new sg list but the object is going to be swapped out. I think some state flow charts (we can do SVG or DOT) in the kerneldoc would be sweet. > > Re GPU might cause a deadlock: Isn't that already a problem if you hold > > reservations of buffers used on other gpus, which want those reservations > > to complete the gpu reset, but that gpu reset blocks some fence that the > > reservation holder is waiting for? > > Correct, that's why amdgpu and TTM tries quite hard to never wait for a > fence while a reservation object is locked. We might have a fairly huge mismatch of expectations here :-/ > The only use case I haven't fixed so far is reaping deleted object during > eviction, but that is only a matter of my free time to fix it. Yeah, this is the hard one. In general the assumption is that dma_fence will get signalled no matter what you're doing, assuming the only thing you need is to not block interrupts. The i915 gpu reset logic to make that work is a bit a work of art ... If we expect amdgpu and i915 to cooperate with shared buffers I guess one has to give in. No idea how to do that best. > > We have tons of fun with deadlocks against GPU resets, and loots of > > testcases, and I kinda get the impression amdgpu is throwing a lot of > > issues under the rug through trylock tricks that shut up lockdep, but > > don't fix much really. > > Hui? Why do you think that? The only trylock I'm aware of is during eviction > and there it isn't a problem. mmap fault handler had one too last time I looked, and it smelled fishy. > > btw adding cross-release lockdep annotations for fences will probably turn > > up _lots_ more bugs in this area. > > At least for amdgpu that should be handled by now. You're sure? :-) Trouble is that cross-release wasn't even ever enabled, much less anyone typed the dma_fence annotations. And just cross-release alone turned up _lost_ of deadlocks in i915 between fences, async workers (userptr, gpu reset) and core mm stuff. I'd be seriously surprised if it wouldn't find an entire rats nest of issues around dma_fence once we enable it. -Daniel > > > > > + * > > > > > + * New mappings can be created immediately, but can't be used > > > > > before the > > > > > + * exclusive fence in the dma_bufs reservation object is > > > > > signaled. > > > > > + */ > > > > > + void (*invalidate_mappings)(struct dma_buf_attachment *attach); > > > > Bunch of questions about exact semantics, but I very much like this. > > > > And I > > > > think besides those technical details, the overall approach seems sound. > > > Yeah this initial implementation was buggy like hell. Just wanted to > > > confirm > > > that the idea is going in the right direction. > > I wanted this 7 years ago, idea very much acked
Re: [PATCH 10/12] media: ov5640: Enhance FPS handling
Hi Maxime, See below comments related to format compliance failing. On 03/02/2018 03:34 PM, Maxime Ripard wrote: > Now that we have moved the clock generation logic out of the bytes array, > these arrays are identical between the 15fps and 30fps variants. > > Remove the duplicate entries, and convert the code accordingly. > > Signed-off-by: Maxime Ripard> --- > drivers/media/i2c/ov5640.c | 312 > - > 1 file changed, 56 insertions(+), 256 deletions(-) > > diff --git a/drivers/media/i2c/ov5640.c b/drivers/media/i2c/ov5640.c > index bdf378d80e07..5510a19281a4 100644 > --- a/drivers/media/i2c/ov5640.c > +++ b/drivers/media/i2c/ov5640.c > @@ -344,66 +344,7 @@ static const struct reg_value > ov5640_init_setting_30fps_VGA[] = { > {0x3a1f, 0x14, 0, 0}, {0x3008, 0x02, 0, 0}, {0x3c00, 0x04, 0, 300}, > }; > > -static const struct reg_value ov5640_setting_30fps_VGA_640_480[] = { > - > - {0x3c07, 0x08, 0, 0}, > - {0x3c09, 0x1c, 0, 0}, {0x3c0a, 0x9c, 0, 0}, {0x3c0b, 0x40, 0, 0}, > - {0x3820, 0x41, 0, 0}, {0x3821, 0x07, 0, 0}, {0x3814, 0x31, 0, 0}, > - {0x3815, 0x31, 0, 0}, {0x3800, 0x00, 0, 0}, {0x3801, 0x00, 0, 0}, > - {0x3802, 0x00, 0, 0}, {0x3803, 0x04, 0, 0}, {0x3804, 0x0a, 0, 0}, > - {0x3805, 0x3f, 0, 0}, {0x3806, 0x07, 0, 0}, {0x3807, 0x9b, 0, 0}, > - {0x3810, 0x00, 0, 0}, > - {0x3811, 0x10, 0, 0}, {0x3812, 0x00, 0, 0}, {0x3813, 0x06, 0, 0}, > - {0x3618, 0x00, 0, 0}, {0x3612, 0x29, 0, 0}, {0x3708, 0x64, 0, 0}, > - {0x3709, 0x52, 0, 0}, {0x370c, 0x03, 0, 0}, {0x3a02, 0x03, 0, 0}, > - {0x3a03, 0xd8, 0, 0}, {0x3a08, 0x01, 0, 0}, {0x3a09, 0x0e, 0, 0}, > - {0x3a0a, 0x00, 0, 0}, {0x3a0b, 0xf6, 0, 0}, {0x3a0e, 0x03, 0, 0}, > - {0x3a0d, 0x04, 0, 0}, {0x3a14, 0x03, 0, 0}, {0x3a15, 0xd8, 0, 0}, > - {0x4001, 0x02, 0, 0}, {0x4004, 0x02, 0, 0}, {0x4713, 0x03, 0, 0}, > - {0x4407, 0x04, 0, 0}, {0x460b, 0x35, 0, 0}, {0x460c, 0x22, 0, 0}, > - {0x3824, 0x02, 0, 0}, {0x5001, 0xa3, 0, 0}, {0x3503, 0x00, 0, 0}, > -}; > - > -static const struct reg_value ov5640_setting_15fps_VGA_640_480[] = { > - {0x3c07, 0x08, 0, 0}, > - {0x3c09, 0x1c, 0, 0}, {0x3c0a, 0x9c, 0, 0}, {0x3c0b, 0x40, 0, 0}, > - {0x3820, 0x41, 0, 0}, {0x3821, 0x07, 0, 0}, {0x3814, 0x31, 0, 0}, > - {0x3815, 0x31, 0, 0}, {0x3800, 0x00, 0, 0}, {0x3801, 0x00, 0, 0}, > - {0x3802, 0x00, 0, 0}, {0x3803, 0x04, 0, 0}, {0x3804, 0x0a, 0, 0}, > - {0x3805, 0x3f, 0, 0}, {0x3806, 0x07, 0, 0}, {0x3807, 0x9b, 0, 0}, > - {0x3810, 0x00, 0, 0}, > - {0x3811, 0x10, 0, 0}, {0x3812, 0x00, 0, 0}, {0x3813, 0x06, 0, 0}, > - {0x3618, 0x00, 0, 0}, {0x3612, 0x29, 0, 0}, {0x3708, 0x64, 0, 0}, > - {0x3709, 0x52, 0, 0}, {0x370c, 0x03, 0, 0}, {0x3a02, 0x03, 0, 0}, > - {0x3a03, 0xd8, 0, 0}, {0x3a08, 0x01, 0, 0}, {0x3a09, 0x27, 0, 0}, > - {0x3a0a, 0x00, 0, 0}, {0x3a0b, 0xf6, 0, 0}, {0x3a0e, 0x03, 0, 0}, > - {0x3a0d, 0x04, 0, 0}, {0x3a14, 0x03, 0, 0}, {0x3a15, 0xd8, 0, 0}, > - {0x4001, 0x02, 0, 0}, {0x4004, 0x02, 0, 0}, {0x4713, 0x03, 0, 0}, > - {0x4407, 0x04, 0, 0}, {0x460b, 0x35, 0, 0}, {0x460c, 0x22, 0, 0}, > - {0x3824, 0x02, 0, 0}, {0x5001, 0xa3, 0, 0}, > -}; > - > -static const struct reg_value ov5640_setting_30fps_XGA_1024_768[] = { > - > - {0x3c07, 0x08, 0, 0}, > - {0x3c09, 0x1c, 0, 0}, {0x3c0a, 0x9c, 0, 0}, {0x3c0b, 0x40, 0, 0}, > - {0x3820, 0x41, 0, 0}, {0x3821, 0x07, 0, 0}, {0x3814, 0x31, 0, 0}, > - {0x3815, 0x31, 0, 0}, {0x3800, 0x00, 0, 0}, {0x3801, 0x00, 0, 0}, > - {0x3802, 0x00, 0, 0}, {0x3803, 0x04, 0, 0}, {0x3804, 0x0a, 0, 0}, > - {0x3805, 0x3f, 0, 0}, {0x3806, 0x07, 0, 0}, {0x3807, 0x9b, 0, 0}, > - {0x3810, 0x00, 0, 0}, > - {0x3811, 0x10, 0, 0}, {0x3812, 0x00, 0, 0}, {0x3813, 0x06, 0, 0}, > - {0x3618, 0x00, 0, 0}, {0x3612, 0x29, 0, 0}, {0x3708, 0x64, 0, 0}, > - {0x3709, 0x52, 0, 0}, {0x370c, 0x03, 0, 0}, {0x3a02, 0x03, 0, 0}, > - {0x3a03, 0xd8, 0, 0}, {0x3a08, 0x01, 0, 0}, {0x3a09, 0x0e, 0, 0}, > - {0x3a0a, 0x00, 0, 0}, {0x3a0b, 0xf6, 0, 0}, {0x3a0e, 0x03, 0, 0}, > - {0x3a0d, 0x04, 0, 0}, {0x3a14, 0x03, 0, 0}, {0x3a15, 0xd8, 0, 0}, > - {0x4001, 0x02, 0, 0}, {0x4004, 0x02, 0, 0}, {0x4713, 0x03, 0, 0}, > - {0x4407, 0x04, 0, 0}, {0x460b, 0x35, 0, 0}, {0x460c, 0x22, 0, 0}, > - {0x3824, 0x02, 0, 0}, {0x5001, 0xa3, 0, 0}, {0x3503, 0x00, 0, 0}, > -}; > - > -static const struct reg_value ov5640_setting_15fps_XGA_1024_768[] = { > +static const struct reg_value ov5640_setting_VGA_640_480[] = { > {0x3c07, 0x08, 0, 0}, > {0x3c09, 0x1c, 0, 0}, {0x3c0a, 0x9c, 0, 0}, {0x3c0b, 0x40, 0, 0}, > {0x3820, 0x41, 0, 0}, {0x3821, 0x07, 0, 0}, {0x3814, 0x31, 0, 0}, > @@ -422,7 +363,7 @@ static const struct reg_value > ov5640_setting_15fps_XGA_1024_768[] = { > {0x3824, 0x02, 0, 0}, {0x5001, 0xa3, 0, 0}, > }; > > -static const struct reg_value ov5640_setting_30fps_QVGA_320_240[] = { > +static const struct
Re: [PATCH 11/12] media: ov5640: Add 60 fps support
Hi Maxime, See below rest of comments regarding framerate and compliance failure. On 03/02/2018 03:34 PM, Maxime Ripard wrote: > Now that we have everything in place to compute the clock rate at runtime, > we can enable the 60fps framerate for the mode we tested it with. > > Signed-off-by: Maxime Ripard> --- > drivers/media/i2c/ov5640.c | 20 +++- > 1 file changed, 15 insertions(+), 5 deletions(-) > > diff --git a/drivers/media/i2c/ov5640.c b/drivers/media/i2c/ov5640.c > index 5510a19281a4..03838f42fb82 100644 > --- a/drivers/media/i2c/ov5640.c > +++ b/drivers/media/i2c/ov5640.c > @@ -111,6 +111,7 @@ enum ov5640_mode_id { > enum ov5640_frame_rate { > OV5640_15_FPS = 0, > OV5640_30_FPS, > + OV5640_60_FPS, > OV5640_NUM_FRAMERATES, > }; > > @@ -144,6 +145,7 @@ MODULE_PARM_DESC(virtual_channel, > static const int ov5640_framerates[] = { > [OV5640_15_FPS] = 15, > [OV5640_30_FPS] = 30, > + [OV5640_60_FPS] = 60, > }; > > /* regulator supplies */ > @@ -1447,6 +1449,11 @@ ov5640_find_mode(struct ov5640_dev *sensor, enum > ov5640_frame_rate fr, > fr != OV5640_15_FPS) > return NULL; > > + /* Only 640x480 can operate at 60fps (for now) */ > + if (fr == OV5640_60_FPS && > + width != 640 && height != 480) > + return NULL; > + Same comment as on patchset 10/12, VGA exception put in for loop: for (i = OV5640_NUM_MODES - 1; i >= 0; i--) { mode = _mode_data[i]; if (!mode->reg_data) continue; if ((nearest && mode->hact <= width && mode->vact <= height) || (!nearest && mode->hact == width && mode->vact == height)) { /* 2592x1944 can only operate at 15fps */ if (mode->hact == 2592 && mode->vact == 1944 && fr != OV5640_15_FPS) continue;/* next lower resolution */ /* Only 640x480 can operate at 60fps (for now) */ if (fr == OV5640_60_FPS && !(mode->hact == 640 && mode->vact == 480)) continue;/* next lower resolution */ break;/* select this resolution */ } } > return mode; > } > > @@ -1875,12 +1882,12 @@ static int ov5640_try_frame_interval(struct > ov5640_dev *sensor, > int ret; > > minfps = ov5640_framerates[OV5640_15_FPS]; > - maxfps = ov5640_framerates[OV5640_30_FPS]; > + maxfps = ov5640_framerates[OV5640_60_FPS]; > > if (fi->numerator == 0) { > fi->denominator = maxfps; > fi->numerator = 1; > - return OV5640_30_FPS; > + return OV5640_60_FPS; There is a problem here because we don't validate that 60fps is supported in the currently set mode, we must inject this framerate value in ov5640_find_mode(framerate, width, height) in order to validate it (-EINVAL if not supported): + ret = OV5640_60_FPS; + goto find_mode; + } [...] +find_mode: mode = ov5640_find_mode(sensor, frame_rate, width, height, false); return mode ? ret : -EINVAL; } Then we have to catch error in ov5640_s_frame_interval() and return an acceptable frame interval to user: frame_rate = ov5640_try_frame_interval(sensor, >interval, mode->hact, mode->vact); - if (frame_rate < 0) - frame_rate = OV5640_15_FPS; - - sensor->current_fr = frame_rate; - sensor->frame_interval = fi->interval; We also have to update current framerate only if framerate has been validated. + if (frame_rate < 0) { + /* return a valid frame interval value */ + fi->interval = sensor->frame_interval; goto out; } + sensor->current_fr = frame_rate; + sensor->frame_interval = fi->interval; sensor->pending_mode_change = true; out: About 60 fps by default if (fi->numerator == 0): shouldn't we stick to a default value supported by all modes such as 30fps ? > } > > fps = DIV_ROUND_CLOSEST(fi->denominator, fi->numerator); > @@ -1892,10 +1899,13 @@ static int ov5640_try_frame_interval(struct > ov5640_dev *sensor, > fi->denominator = minfps; > else if (2 * fps >= 2 * minfps + (maxfps - minfps)) > fi->denominator = maxfps; > - else > - fi->denominator = minfps; > > - ret = (fi->denominator == minfps) ? OV5640_15_FPS : OV5640_30_FPS; > + if (fi->denominator == minfps) > + ret = OV5640_15_FPS; > + else if (fi->denominator == maxfps) > + ret = OV5640_60_FPS; > + else > + ret = OV5640_30_FPS; > >
Re: [PATCH] media: omap3isp: fix unbalanced dma_iommu_mapping
Hi Sakari, On 03/13/2018 06:14 AM, Sakari Ailus wrote: > Hi Suman, > > Thanks for the patch. > > On Mon, Mar 12, 2018 at 11:52:07AM -0500, Suman Anna wrote: >> The OMAP3 ISP driver manages its MMU mappings through the IOMMU-aware >> ARM DMA backend. The current code creates a dma_iommu_mapping and >> attaches this to the ISP device, but never detaches the mapping in >> either the probe failure paths or the driver remove path resulting >> in an unbalanced mapping refcount and a memory leak. Fix this properly. >> >> Reported-by: Pavel Machek>> Signed-off-by: Suman Anna >> Tested-by: Pavel Machek >> --- >> Hi Mauro, Laurent, >> >> This fixes an issue reported by Pavel and discussed on this >> thread, >> https://marc.info/?l=linux-omap=152051945803598=2 >> >> Posting this again to the appropriate lists. >> >> regards >> Suman >> >> drivers/media/platform/omap3isp/isp.c | 7 +-- >> 1 file changed, 5 insertions(+), 2 deletions(-) >> >> diff --git a/drivers/media/platform/omap3isp/isp.c >> b/drivers/media/platform/omap3isp/isp.c >> index 8eb000e3d8fd..c7d667bfc2af 100644 >> --- a/drivers/media/platform/omap3isp/isp.c >> +++ b/drivers/media/platform/omap3isp/isp.c >> @@ -1945,6 +1945,7 @@ static int isp_initialize_modules(struct isp_device >> *isp) >> >> static void isp_detach_iommu(struct isp_device *isp) >> { >> +arm_iommu_detach_device(isp->dev); >> arm_iommu_release_mapping(isp->mapping); >> isp->mapping = NULL; >> } >> @@ -1971,13 +1972,15 @@ static int isp_attach_iommu(struct isp_device *isp) >> ret = arm_iommu_attach_device(isp->dev, mapping); >> if (ret < 0) { >> dev_err(isp->dev, "failed to attach device to VA mapping\n"); >> -goto error; >> +goto error_attach; > > Instead of changing the label here, could you return immediately where the > previous point of error handling is? No need to add another label. Yeah, I debated about this while doing the patch, and chose to retain the previous common return on the error paths. There are only 2 error paths, so didn't want to mix them up. If you still prefer the mixed style, I can post a v2. regards Suman > > After fixing that you can add: > > Acked-by: Sakari Ailus > >> } >> >> return 0; >> >> +error_attach: >> +arm_iommu_release_mapping(isp->mapping); >> +isp->mapping = NULL; >> error: >> -isp_detach_iommu(isp); >> return ret; >> } >> >> >
Re: [PATCH 1/4] dma-buf: add optional invalidate_mappings callback
Am 13.03.2018 um 16:17 schrieb Daniel Vetter: [SNIP] I think a helper which both unmaps _and_ waits for all the fences to clear would be best, with some guarantees that it'll either fail or all the mappings _will_ be gone. The locking for that one will be hilarious, since we need to figure out dmabuf->lock vs. the reservation. I kinda prefer we throw away the dmabuf->lock and superseed it entirely by the reservation lock. Big NAK on that. The whole API is asynchronously, e.g. we never block for any operation to finish. Otherwise you run into big trouble with cross device GPU resets and stuff like that. But how will the unmapping work then? You can't throw the sg list away before the dma stopped. The dma only stops once the fence is signalled. The importer can't call dma_buf_detach because the reservation lock is hogged already by the exporter trying to unmap everything. How is this supposed to work? Even after invalidation the sg list stays alive until it is explicitly destroyed by the importer using dma_buf_unmap_attachment() which in turn is only allowed after all fences have signaled. The implementation is in ttm_bo_pipeline_gutting(), basically we use the same functionality as for pipelined moves/evictions which hangs the old backing store on a dummy object and destroys it after all fences signaled. While the old sg list is still about to be destroyed the importer can request a new sg list for the new location of the DMA-buf using dma_buf_map_attachment(). This new location becomes valid after the move fence in the reservation object is signaled. So from the CPU point of view multiple sg list could exists at the same time which allows us to have a seamless transition from the old to the new location from the GPU point of view. Re GPU might cause a deadlock: Isn't that already a problem if you hold reservations of buffers used on other gpus, which want those reservations to complete the gpu reset, but that gpu reset blocks some fence that the reservation holder is waiting for? Correct, that's why amdgpu and TTM tries quite hard to never wait for a fence while a reservation object is locked. The only use case I haven't fixed so far is reaping deleted object during eviction, but that is only a matter of my free time to fix it. We have tons of fun with deadlocks against GPU resets, and loots of testcases, and I kinda get the impression amdgpu is throwing a lot of issues under the rug through trylock tricks that shut up lockdep, but don't fix much really. Hui? Why do you think that? The only trylock I'm aware of is during eviction and there it isn't a problem. btw adding cross-release lockdep annotations for fences will probably turn up _lots_ more bugs in this area. At least for amdgpu that should be handled by now. +* +* New mappings can be created immediately, but can't be used before the +* exclusive fence in the dma_bufs reservation object is signaled. +*/ + void (*invalidate_mappings)(struct dma_buf_attachment *attach); Bunch of questions about exact semantics, but I very much like this. And I think besides those technical details, the overall approach seems sound. Yeah this initial implementation was buggy like hell. Just wanted to confirm that the idea is going in the right direction. I wanted this 7 years ago, idea very much acked :-) Ok, thanks. Good to know. Christian.
Re: [PATCH 1/4] dma-buf: add optional invalidate_mappings callback
On Mon, Mar 12, 2018 at 08:13:15PM +0100, Christian K??nig wrote: > Am 12.03.2018 um 18:07 schrieb Daniel Vetter: > > On Fri, Mar 09, 2018 at 08:11:41PM +0100, Christian K??nig wrote: > > > [SNIP] > > > +/** > > > + * dma_buf_invalidate_mappings - invalidate all mappings of this dma_buf > > > + * > > > + * @dmabuf: [in]buffer which mappings should be invalidated > > > + * > > > + * Informs all attachmenst that they need to destroy and recreated all > > > their > > > + * mappings. > > > + */ > > > +void dma_buf_invalidate_mappings(struct dma_buf *dmabuf) > > > +{ > > > + struct dma_buf_attachment *attach; > > > + > > > + reservation_object_assert_held(dmabuf->resv); > > > + > > > + list_for_each_entry(attach, >attachments, node) > > > + attach->invalidate_mappings(attach); > > To make the locking work I think we also need to require importers to hold > > the reservation object while attaching/detaching. Otherwise the list walk > > above could go boom. > > Oh, good point. Going, to fix this. > > > [SNIP] > > > + /** > > > + * @supports_mapping_invalidation: > > > + * > > > + * True for exporters which supports unpinned DMA-buf operation using > > > + * the reservation lock. > > > + * > > > + * When attachment->invalidate_mappings is set the @map_dma_buf and > > > + * @unmap_dma_buf callbacks can be called with the reservation lock > > > + * held. > > > + */ > > > + bool supports_mapping_invalidation; > > Why do we need this? Importer could simply always register with the > > invalidate_mapping hook registered, and exporters could use it when they > > see fit. That gives us more lockdep coverage to make sure importers use > > their attachment callbacks correctly (aka they hold the reservation > > object). > > One sole reason: Backward compability. > > I didn't wanted to audit all those different drivers if they can handle > being called with the reservation lock held. > > > > > > + > > > /** > > >* @map_dma_buf: > > >* > > > @@ -326,6 +338,29 @@ struct dma_buf_attachment { > > > struct device *dev; > > > struct list_head node; > > > void *priv; > > > + > > > + /** > > > + * @invalidate_mappings: > > > + * > > > + * Optional callback provided by the importer of the attachment which > > > + * must be set before mappings are created. > > This doesn't work, it must be set before the attachment is created, > > otherwise you race with your invalidate callback. > > Another good point. > > > > > I think the simplest option would be to add a new dma_buf_attach_dynamic > > (well except a less crappy name). > > Well how about adding an optional invalidate_mappings parameter to the > existing dma_buf_attach? Not sure that's best, it might confuse dumb importers and you need to change all the callers. But up to you. > > > + * > > > + * If provided the exporter can avoid pinning the backing store while > > > + * mappings exists. > > > + * > > > + * The function is called with the lock of the reservation object > > > + * associated with the dma_buf held and the mapping function must be > > > + * called with this lock held as well. This makes sure that no mapping > > > + * is created concurrently with an ongoing invalidation. > > > + * > > > + * After the callback all existing mappings are still valid until all > > > + * fences in the dma_bufs reservation object are signaled, but should be > > > + * destroyed by the importer as soon as possible. > > Do we guarantee that the importer will attach a fence, after which the > > mapping will be gone? What about re-trying? Or just best effort (i.e. only > > useful for evicting to try to make room). > > The importer should attach fences for all it's operations with the DMA-buf. > > > I think a helper which both unmaps _and_ waits for all the fences to clear > > would be best, with some guarantees that it'll either fail or all the > > mappings _will_ be gone. The locking for that one will be hilarious, since > > we need to figure out dmabuf->lock vs. the reservation. I kinda prefer we > > throw away the dmabuf->lock and superseed it entirely by the reservation > > lock. > > Big NAK on that. The whole API is asynchronously, e.g. we never block for > any operation to finish. > > Otherwise you run into big trouble with cross device GPU resets and stuff > like that. But how will the unmapping work then? You can't throw the sg list away before the dma stopped. The dma only stops once the fence is signalled. The importer can't call dma_buf_detach because the reservation lock is hogged already by the exporter trying to unmap everything. How is this supposed to work? Re GPU might cause a deadlock: Isn't that already a problem if you hold reservations of buffers used on other gpus, which want those reservations to complete the gpu reset, but that gpu reset blocks some fence that the reservation holder is waiting for? We have tons of fun with deadlocks against GPU
Re: [PATCH 1/3] rcar-vin: remove duplicated check of state in irq handler
Hi Niklas, Thanks for the patch series :) - I've been looking forward to seeing this one ! On 10/03/18 01:09, Niklas Söderlund wrote: > This is an error from when the driver where converted from soc-camera. > There is absolutely no gain to check the state variable two times to be > extra sure if the hardware is stopped. I'll not say this isn't a redundant check ... but isn't the check against two different states, and thus the remaining check doesn't actually catch the case now where state == STOPPED ? (Perhaps state != RUNNING would be better ?, but I haven't checked the rest of the code) -- Kieran > > Signed-off-by: Niklas Söderlund> --- > drivers/media/platform/rcar-vin/rcar-dma.c | 6 -- > 1 file changed, 6 deletions(-) > > diff --git a/drivers/media/platform/rcar-vin/rcar-dma.c > b/drivers/media/platform/rcar-vin/rcar-dma.c > index 23fdff7a7370842e..b4be75d5009080f7 100644 > --- a/drivers/media/platform/rcar-vin/rcar-dma.c > +++ b/drivers/media/platform/rcar-vin/rcar-dma.c > @@ -916,12 +916,6 @@ static irqreturn_t rvin_irq(int irq, void *data) > rvin_ack_interrupt(vin); > handled = 1; > > - /* Nothing to do if capture status is 'STOPPED' */ > - if (vin->state == STOPPED) { > - vin_dbg(vin, "IRQ while state stopped\n"); > - goto done; > - } > - > /* Nothing to do if capture status is 'STOPPING' */ > if (vin->state == STOPPING) { > vin_dbg(vin, "IRQ while state stopping\n"); >
Re: [RfC PATCH] Add udmabuf misc device
On Tue, Mar 13, 2018 at 04:48:26PM +0100, Gerd Hoffmann wrote: > A driver to let userspace turn iovecs into dma-bufs. > > Use case: Allows qemu pass around dmabufs for the guest framebuffer. > https://www.kraxel.org/cgit/qemu/log/?h=sirius/udmabuf has an > experimental patch. > > Also allows qemu to export guest virtio-gpu resources as host dmabufs. > Should be possible to use it to display guest wayland windows on the > host display server. virtio-gpu ressources can be chunked so we will > actually need multiple iovec entries. UNTESTED. > > Want collect some feedback on the general approach with this RfC series. > Can this work? If not, better ideas? > > Question: Must this be hooked into some kind of mlock accounting, to > limit the amout of memory userspace is allowed to pin this way? Or will > get_user_pages_fast() handle that for me? Either mlock account (because it's mlocked defacto), and get_user_pages won't do that for you. Or you write the full-blown userptr implementation, including mmu_notifier support (see i915 or amdgpu), but that also requires Christian Königs latest ->invalidate_mapping RFC for dma-buf (since atm exporting userptr buffers is a no-go). > > Known issue: Driver API isn't complete yet. Need add some flags, for > example to support read-only buffers. dma-buf has no concept of read-only. I don't think we can even enforce that (not many iommus can enforce this iirc), so pretty much need to require r/w memory. > Cc: David Airlie> Cc: Tomeu Vizoso > Signed-off-by: Gerd Hoffmann btw there's also the hyperdmabuf stuff from the xen folks, but imo their solution of forwarding the entire dma-buf api is over the top. This here looks _much_ better, pls cc all the hyperdmabuf people on your next version. Overall I like the idea, but too lazy to review. Can maybe be bribed :-) Oh, some kselftests for this stuff would be lovely. -Daniel > --- > include/uapi/linux/udmabuf.h | 21 > drivers/dma-buf/udmabuf.c| 250 > +++ > drivers/dma-buf/Kconfig | 7 ++ > drivers/dma-buf/Makefile | 1 + > 4 files changed, 279 insertions(+) > create mode 100644 include/uapi/linux/udmabuf.h > create mode 100644 drivers/dma-buf/udmabuf.c > > diff --git a/include/uapi/linux/udmabuf.h b/include/uapi/linux/udmabuf.h > new file mode 100644 > index 00..fd2fa441fe > --- /dev/null > +++ b/include/uapi/linux/udmabuf.h > @@ -0,0 +1,21 @@ > +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ > +#ifndef _UAPI_LINUX_UDMABUF_H > +#define _UAPI_LINUX_UDMABUF_H > + > +#include > +#include > + > +struct udmabuf_iovec { > + __u64 base; > + __u64 len; > +}; > + > +struct udmabuf_create { > + __u32 flags; > + __u32 niov; > + struct udmabuf_iovec iovs[]; > +}; > + > +#define UDMABUF_CREATE _IOW(0x42, 0x23, struct udmabuf_create) > + > +#endif /* _UAPI_LINUX_UDMABUF_H */ > diff --git a/drivers/dma-buf/udmabuf.c b/drivers/dma-buf/udmabuf.c > new file mode 100644 > index 00..ec012d7ac7 > --- /dev/null > +++ b/drivers/dma-buf/udmabuf.c > @@ -0,0 +1,250 @@ > +/* > + * This program is free software; you can redistribute it and/or modify > + * it under the terms of the GNU General Public License version 2 as > + * published by the Free Software Foundation. > + */ > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > + > +#include > + > +struct udmabuf { > + u32 pagecount; > + struct page **pages; > +}; > + > +static int udmabuf_vm_fault(struct vm_fault *vmf) > +{ > + struct vm_area_struct *vma = vmf->vma; > + struct udmabuf *ubuf = vma->vm_private_data; > + > + if (WARN_ON(vmf->pgoff >= ubuf->pagecount)) > + return VM_FAULT_SIGBUS; > + > + vmf->page = ubuf->pages[vmf->pgoff]; > + get_page(vmf->page); > + return 0; > +} > + > +static const struct vm_operations_struct udmabuf_vm_ops = { > + .fault = udmabuf_vm_fault, > +}; > + > +static int mmap_udmabuf(struct dma_buf *buf, struct vm_area_struct *vma) > +{ > + struct udmabuf *ubuf = buf->priv; > + > + if ((vma->vm_flags & VM_SHARED) == 0) > + return -EINVAL; > + > + vma->vm_ops = _vm_ops; > + vma->vm_private_data = ubuf; > + return 0; > +} > + > +static struct sg_table *map_udmabuf(struct dma_buf_attachment *at, > + enum dma_data_direction direction) > +{ > + struct udmabuf *ubuf = at->dmabuf->priv; > + struct sg_table *sg; > + > + sg = kzalloc(sizeof(*sg), GFP_KERNEL); > + if (!sg) > + goto err1; > + if (sg_alloc_table_from_pages(sg, ubuf->pages, ubuf->pagecount, > + 0, ubuf->pagecount << PAGE_SHIFT, > + GFP_KERNEL) < 0) > + goto err2; > + if (!dma_map_sg(at->dev, sg->sgl, sg->nents, direction)) > +
Re: Webcams not recognized on a Dell Latitude 5285 laptop
On Sun, Mar 11, 2018 at 2:38 PM, FRÉDÉRIC PARRENINwrote: > Dear Oliver and all, > > So I was expecting linux-4.16 to recognize my webcams, thanks to this new PCI > driver Oliver mentioned. > Therefore I installed 4.16-rc4. > Unfortunately, there is still no /dev/video* device > > Any idea what could be done to have these webcams working? I guess you need a driver. Cc: + Sakari, and thus leaving the complete message uncut. > > Thanks, > > Frederic > > >> De: "FRÉDÉRIC PARRENIN" >> À: "Oliver Neukum" >> Cc: "linux-usb" >> Envoyé: Lundi 11 Décembre 2017 16:39:41 >> Objet: Re: Webcams not recognized on a Dell Latitude 5285 laptop > >> > > > it looks like you need the experimental driver posted here > >> > > > https://www.spinics.net/lists/linux-media/msg123268.html > >> > > Thanks for the information. >> >> So, if I understand correctly, this driver will not be included in 4.15, >> >> will >> > > it? >> > > Any idea when this will be included in a release? > >> > I have no idea. Could you contact the original developers? >> > The answer is interesting, but I have no idea. > >> It seems it will be included in the 4.16 release: > >> https://www.mail-archive.com/linux-media@vger.kernel.org/msg122619.html > >> Probably just a bit too late for 4.15. > >> Frederic > > !!! WARNING!!! New email address: frederic.parre...@univ-grenoble-alpes.fr > http://pp.ige-grenoble.fr/pageperso/parrenif/index.html > > - Mail original - >> De: "FRÉDÉRIC PARRENIN" >> À: "Oliver Neukum" >> Cc: "linux-usb" >> Envoyé: Lundi 11 Décembre 2017 16:39:41 >> Objet: Re: Webcams not recognized on a Dell Latitude 5285 laptop > >> > > > it looks like you need the experimental driver posted here > >> > > > https://www.spinics.net/lists/linux-media/msg123268.html > >> > > Thanks for the information. >> >> So, if I understand correctly, this driver will not be included in 4.15, >> >> will >> > > it? >> > > Any idea when this will be included in a release? > >> > I have no idea. Could you contact the original developers? >> > The answer is interesting, but I have no idea. > >> It seems it will be included in the 4.16 release: > >> https://www.mail-archive.com/linux-media@vger.kernel.org/msg122619.html > >> Probably just a bit too late for 4.15. > >> Frederic > -- > To unsubscribe from this list: send the line "unsubscribe linux-usb" in > the body of a message to majord...@vger.kernel.org > More majordomo info at http://vger.kernel.org/majordomo-info.html -- With Best Regards, Andy Shevchenko
Re: [PATCH] media: ngene: avoid unused variable warning
Am Tue, 13 Mar 2018 14:06:03 +0100 schrieb Arnd Bergmann: > The newly added pdev variable is only used in an #ifdef, causing a > build warning without CONFIG_PCI_MSI, unless we move the declaration > inside the same #ifdef: > > drivers/media/pci/ngene/ngene-core.c: In function 'ngene_start': > drivers/media/pci/ngene/ngene-core.c:1328:17: error: unused variable 'pdev' > [-Werror=unused-variable] > > Fixes: 6795bf626482 ("media: ngene: convert kernellog printing from printk() > to dev_*() macros") > Signed-off-by: Arnd Bergmann Acked-by: Daniel Scheller Thanks! > --- > drivers/media/pci/ngene/ngene-core.c | 2 +- > 1 file changed, 1 insertion(+), 1 deletion(-) > > diff --git a/drivers/media/pci/ngene/ngene-core.c > b/drivers/media/pci/ngene/ngene-core.c > index 3b9a1bfaf6c0..25f16833a475 100644 > --- a/drivers/media/pci/ngene/ngene-core.c > +++ b/drivers/media/pci/ngene/ngene-core.c > @@ -1325,7 +1325,6 @@ static int ngene_buffer_config(struct ngene *dev) > > static int ngene_start(struct ngene *dev) > { > - struct device *pdev = >pci_dev->dev; > int stat; > int i; > > @@ -1359,6 +1358,7 @@ static int ngene_start(struct ngene *dev) > #ifdef CONFIG_PCI_MSI > /* enable MSI if kernel and card support it */ > if (pci_msi_enabled() && dev->card_info->msi_supported) { > + struct device *pdev = >pci_dev->dev; > unsigned long flags; > > ngwritel(0, NGENE_INT_ENABLE); Best regards, Daniel Scheller -- https://github.com/herrnst
Re: [PATCH 2/3] rcar-vin: allocate a scratch buffer at stream start
Hi Niklas, On 10/03/18 01:09, Niklas Söderlund wrote: > Before starting capturing allocate a scratch buffer which can be used by "Before starting a capture, allocate a..." (two 'ings' together doesn't sound right) > the driver to give to the hardware if no buffers are available from > userspace. The buffer is not used in this patch but prepares for future > refactoring where the scratch buffer can be used to avoid the need to > fallback on single capture mode if userspace don't queue buffers as fast s/don't/doesn't/ or alternatively s/don't/can't/ > as the VIN driver consumes them. > > Signed-off-by: Niklas SöderlundWith minor comments attended to: Reviewed-by: Kieran Bingham > --- > drivers/media/platform/rcar-vin/rcar-dma.c | 19 +++ > drivers/media/platform/rcar-vin/rcar-vin.h | 4 > 2 files changed, 23 insertions(+) > > diff --git a/drivers/media/platform/rcar-vin/rcar-dma.c > b/drivers/media/platform/rcar-vin/rcar-dma.c > index b4be75d5009080f7..8ea73cdc9a720abe 100644 > --- a/drivers/media/platform/rcar-vin/rcar-dma.c > +++ b/drivers/media/platform/rcar-vin/rcar-dma.c > @@ -1070,6 +1070,17 @@ static int rvin_start_streaming(struct vb2_queue *vq, > unsigned int count) > unsigned long flags; > int ret; > > + /* Allocate scratch buffer. */ > + vin->scratch = dma_alloc_coherent(vin->dev, vin->format.sizeimage, > + >scratch_phys, GFP_KERNEL); > + if (!vin->scratch) { > + spin_lock_irqsave(>qlock, flags); > + return_all_buffers(vin, VB2_BUF_STATE_QUEUED); > + spin_unlock_irqrestore(>qlock, flags); > + vin_err(vin, "Failed to allocate scratch buffer\n"); > + return -ENOMEM; > + } > + > sd = vin_to_source(vin); > v4l2_subdev_call(sd, video, s_stream, 1); > > @@ -1085,6 +1096,10 @@ static int rvin_start_streaming(struct vb2_queue *vq, > unsigned int count) > > spin_unlock_irqrestore(>qlock, flags); > > + if (ret) > + dma_free_coherent(vin->dev, vin->format.sizeimage, vin->scratch, > + vin->scratch_phys); > + > return ret; > } > > @@ -1135,6 +1150,10 @@ static void rvin_stop_streaming(struct vb2_queue *vq) > > /* disable interrupts */ > rvin_disable_interrupts(vin); > + > + /* Free scratch buffer. */ > + dma_free_coherent(vin->dev, vin->format.sizeimage, vin->scratch, > + vin->scratch_phys); > } > > static const struct vb2_ops rvin_qops = { > diff --git a/drivers/media/platform/rcar-vin/rcar-vin.h > b/drivers/media/platform/rcar-vin/rcar-vin.h > index 5382078143fb3869..11a981d707c7ca47 100644 > --- a/drivers/media/platform/rcar-vin/rcar-vin.h > +++ b/drivers/media/platform/rcar-vin/rcar-vin.h > @@ -102,6 +102,8 @@ struct rvin_graph_entity { > * > * @lock:protects @queue > * @queue: vb2 buffers queue > + * @scratch: cpu address for scratch buffer > + * @scratch_phys:pysical address of the scratch buffer s/pysical/physical/ > * > * @qlock: protects @queue_buf, @buf_list, @continuous, @sequence > * @state > @@ -130,6 +132,8 @@ struct rvin_dev { > > struct mutex lock; > struct vb2_queue queue; > + void *scratch; > + dma_addr_t scratch_phys; > > spinlock_t qlock; > struct vb2_v4l2_buffer *queue_buf[HW_BUFFER_NUM]; >
Re: [PATCH v2] media: staging/imx: fill vb2_v4l2_buffer sequence entry
Hi Peter, On Tue, Mar 13, 2018 at 7:34 PM, Peter Seidererwrote: > Signed-off-by: Peter Seiderer Could you please resend with a commit log explaining the reason for this patch? Tahnks
[PATCH v3 1/3] [media] dvb_frontend: add S2X and misc. other enums
From: Daniel SchellerAdditional enums: * FEC ratios 1/4 and 1/3 * 64/128/256-APSK modulations (DVB-S2X) * 15%, 10% and 5% rolloff factors (DVB-S2X) * 64K transmission mode (DVB-T2) Add these enums to the frontend.h docs exceptions aswell (uapi docs are updated separately). Also, bump the DVB API version to 5.12 to make userspace aware of these new enums. Signed-off-by: Daniel Scheller --- v2 to v3: - All new enum patches squashed into one commit - DVB API bump to 5.12 Please take note of some additional things in the cover letter. Documentation/media/frontend.h.rst.exceptions | 9 + drivers/media/dvb-core/dvb_frontend.c | 9 + include/uapi/linux/dvb/frontend.h | 29 ++- include/uapi/linux/dvb/version.h | 2 +- 4 files changed, 43 insertions(+), 6 deletions(-) diff --git a/Documentation/media/frontend.h.rst.exceptions b/Documentation/media/frontend.h.rst.exceptions index f7c4df620a52..c1643ce93426 100644 --- a/Documentation/media/frontend.h.rst.exceptions +++ b/Documentation/media/frontend.h.rst.exceptions @@ -84,6 +84,9 @@ ignore symbol APSK_16 ignore symbol APSK_32 ignore symbol DQPSK ignore symbol QAM_4_NR +ignore symbol APSK_64 +ignore symbol APSK_128 +ignore symbol APSK_256 ignore symbol SEC_VOLTAGE_13 ignore symbol SEC_VOLTAGE_18 @@ -117,6 +120,8 @@ ignore symbol FEC_AUTO ignore symbol FEC_3_5 ignore symbol FEC_9_10 ignore symbol FEC_2_5 +ignore symbol FEC_1_4 +ignore symbol FEC_1_3 ignore symbol TRANSMISSION_MODE_AUTO ignore symbol TRANSMISSION_MODE_1K @@ -129,6 +134,7 @@ ignore symbol TRANSMISSION_MODE_C1 ignore symbol TRANSMISSION_MODE_C3780 ignore symbol TRANSMISSION_MODE_2K ignore symbol TRANSMISSION_MODE_8K +ignore symbol TRANSMISSION_MODE_64K ignore symbol GUARD_INTERVAL_AUTO ignore symbol GUARD_INTERVAL_1_128 @@ -161,6 +167,9 @@ ignore symbol ROLLOFF_35 ignore symbol ROLLOFF_20 ignore symbol ROLLOFF_25 ignore symbol ROLLOFF_AUTO +ignore symbol ROLLOFF_15 +ignore symbol ROLLOFF_10 +ignore symbol ROLLOFF_5 ignore symbol INVERSION_ON ignore symbol INVERSION_OFF diff --git a/drivers/media/dvb-core/dvb_frontend.c b/drivers/media/dvb-core/dvb_frontend.c index a7ed16e0841d..52c76e32f864 100644 --- a/drivers/media/dvb-core/dvb_frontend.c +++ b/drivers/media/dvb-core/dvb_frontend.c @@ -2183,6 +2183,15 @@ static int dtv_set_frontend(struct dvb_frontend *fe) break; case SYS_DVBS2: switch (c->rolloff) { + case ROLLOFF_5: + rolloff = 105; + break; + case ROLLOFF_10: + rolloff = 110; + break; + case ROLLOFF_15: + rolloff = 115; + break; case ROLLOFF_20: rolloff = 120; break; diff --git a/include/uapi/linux/dvb/frontend.h b/include/uapi/linux/dvb/frontend.h index 4f9b4551c534..8bf1c63627a2 100644 --- a/include/uapi/linux/dvb/frontend.h +++ b/include/uapi/linux/dvb/frontend.h @@ -296,6 +296,8 @@ enum fe_spectral_inversion { * @FEC_3_5: Forward Error Correction Code 3/5 * @FEC_9_10: Forward Error Correction Code 9/10 * @FEC_2_5: Forward Error Correction Code 2/5 + * @FEC_1_4: Forward Error Correction Code 1/4 + * @FEC_1_3: Forward Error Correction Code 1/3 * * Please note that not all FEC types are supported by a given standard. */ @@ -313,6 +315,8 @@ enum fe_code_rate { FEC_3_5, FEC_9_10, FEC_2_5, + FEC_1_4, + FEC_1_3, }; /** @@ -331,6 +335,9 @@ enum fe_code_rate { * @APSK_32: 32-APSK modulation * @DQPSK: DQPSK modulation * @QAM_4_NR: 4-QAM-NR modulation + * @APSK_64: 64-APSK modulation + * @APSK_128: 128-APSK modulation + * @APSK_256: 256-APSK modulation * * Please note that not all modulations are supported by a given standard. * @@ -350,6 +357,9 @@ enum fe_modulation { APSK_32, DQPSK, QAM_4_NR, + APSK_64, + APSK_128, + APSK_256, }; /** @@ -374,6 +384,8 @@ enum fe_modulation { * Single Carrier (C=1) transmission mode (DTMB only) * @TRANSMISSION_MODE_C3780: * Multi Carrier (C=3780) transmission mode (DTMB only) + * @TRANSMISSION_MODE_64K: + * Transmission mode 64K * * Please note that not all transmission modes are supported by a given * standard. @@ -388,6 +400,7 @@ enum fe_transmit_mode { TRANSMISSION_MODE_32K, TRANSMISSION_MODE_C1, TRANSMISSION_MODE_C3780, + TRANSMISSION_MODE_64K, }; /** @@ -567,20 +580,26 @@ enum fe_pilot { /** * enum fe_rolloff - Rolloff factor - * @ROLLOFF_35:Roloff factor: α=35% - * @ROLLOFF_20:Roloff factor: α=20% - * @ROLLOFF_25:Roloff factor: α=25% - * @ROLLOFF_AUTO: Auto-detect the roloff factor. + *
[PATCH v3 3/3] [media] dvb-frontends/stv0910: more detailed reporting in get_frontend()
From: Daniel SchellerThe first two missing FECs in the modcod2fec fe_code_rate table were 1/4 and 1/3. Add them as they're now defined by the API. Also, report the currently used S2 rolloff factor in get_frontend(). For cosmetic reasons, also change all feroll_off occurences to fe_rolloff. In addition, Richard Scobie suggested to report the currently active delivery system aswell, so add this while at it. Signed-off-by: Daniel Scheller --- v2 to v3: - Squashed all stv0910 get_frontend() reporting into a single commit Please take note of some additional things in the cover letter. drivers/media/dvb-frontends/stv0910.c | 16 +++- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/drivers/media/dvb-frontends/stv0910.c b/drivers/media/dvb-frontends/stv0910.c index 52355c14fd64..e12bc87de87b 100644 --- a/drivers/media/dvb-frontends/stv0910.c +++ b/drivers/media/dvb-frontends/stv0910.c @@ -113,7 +113,7 @@ struct stv { enum fe_stv0910_mod_cod mod_cod; enum dvbs2_fectype fectype; u32 pilots; - enum fe_stv0910_roll_off feroll_off; + enum fe_stv0910_roll_off fe_rolloff; int is_standard_broadcast; int is_vcm; @@ -541,7 +541,7 @@ static int get_signal_parameters(struct stv *state) } state->is_vcm = 0; state->is_standard_broadcast = 1; - state->feroll_off = FE_SAT_35; + state->fe_rolloff = FE_SAT_35; } return 0; } @@ -1300,14 +1300,14 @@ static int manage_matype_info(struct stv *state) read_regs(state, RSTV0910_P2_MATSTR1 + state->regoff, bbheader, 2); - state->feroll_off = + state->fe_rolloff = (enum fe_stv0910_roll_off)(bbheader[0] & 0x03); state->is_vcm = (bbheader[0] & 0x10) == 0; state->is_standard_broadcast = (bbheader[0] & 0xFC) == 0xF0; } else if (state->receive_mode == RCVMODE_DVBS) { state->is_vcm = 0; state->is_standard_broadcast = 1; - state->feroll_off = FE_SAT_35; + state->fe_rolloff = FE_SAT_35; } return 0; } @@ -1562,7 +1562,7 @@ static int get_frontend(struct dvb_frontend *fe, APSK_32, }; const enum fe_code_rate modcod2fec[0x20] = { - FEC_NONE, FEC_NONE, FEC_NONE, FEC_2_5, + FEC_NONE, FEC_1_4, FEC_1_3, FEC_2_5, FEC_1_2, FEC_3_5, FEC_2_3, FEC_3_4, FEC_4_5, FEC_5_6, FEC_8_9, FEC_9_10, FEC_3_5, FEC_2_3, FEC_3_4, FEC_5_6, @@ -1571,11 +1571,16 @@ static int get_frontend(struct dvb_frontend *fe, FEC_3_4, FEC_4_5, FEC_5_6, FEC_8_9, FEC_9_10 }; + const enum fe_rolloff ro2ro[4] = { + ROLLOFF_35, ROLLOFF_25, ROLLOFF_20, ROLLOFF_15, + }; read_reg(state, RSTV0910_P2_DMDMODCOD + state->regoff, ); mc = ((tmp & 0x7c) >> 2); p->pilot = (tmp & 0x01) ? PILOT_ON : PILOT_OFF; p->modulation = modcod2mod[mc]; p->fec_inner = modcod2fec[mc]; + p->rolloff = ro2ro[state->fe_rolloff]; + p->delivery_system = SYS_DVBS2; } else if (state->receive_mode == RCVMODE_DVBS) { read_reg(state, RSTV0910_P2_VITCURPUN + state->regoff, ); switch (tmp & 0x1F) { @@ -1599,6 +1604,7 @@ static int get_frontend(struct dvb_frontend *fe, break; } p->rolloff = ROLLOFF_35; + p->delivery_system = SYS_DVBS; } if (state->receive_mode != RCVMODE_NONE) { -- 2.16.1
[PATCH v3 0/3] Add FEC rates, S2X params and 64K transmission
From: Daniel SchellerNote: This v3 doesn't yet implement anything to allow userspace to detect bits regarding S2X, nor does it implement anything new to report frontend capabilities. At the moment, the main purpose for this is to enable any demod frontend to report the current signal parameters more accurate. Right now this (partially) is for the stv0910 demod, and with additional hardware currently in development in mind which supports more S2X bits. There's quite a lot missing from fe_caps right now which almost all demods autodetect anyway, so let's at least properly report signal stats. dddvb brings a few additional FEC rates (1/4 and 1/3), 64/128/256APSK modulations and more rolloff factors (DVB-S2X), and 64K transmission mode (DVB-T2). These rather trivial patches bring them to mainline, and puts these missing bits into the stv0910's get_frontend() callback (FEC 1/4 and 1/3 are handled throughout the rest of the demod driver already). In addition (as suggestion from Richard Scobie), the stv0910 driver now reports it's active delivery system. Changes from v2 to v3: - API bits squashed into one commit, stv0910 changes squashed into another single commit - DVB-S2X related bits added to the uAPI docs - DVB API bumped to v5.12 Changes from v1 to v2: - DVB-S2X rolloff factors and reporting - report of the active delivery system in stv0910:get_frontend() Daniel Scheller (3): [media] dvb_frontend: add S2X and misc. other enums [media] docs: documentation bits for S2X and the 64K transmission mode [media] dvb-frontends/stv0910: more detailed reporting in get_frontend() Documentation/media/frontend.h.rst.exceptions | 9 .../media/uapi/dvb/fe_property_parameters.rst | 50 ++ .../dvb/frontend-property-satellite-systems.rst| 8 ++-- drivers/media/dvb-core/dvb_frontend.c | 9 drivers/media/dvb-frontends/stv0910.c | 16 --- include/uapi/linux/dvb/frontend.h | 29 ++--- include/uapi/linux/dvb/version.h | 2 +- 7 files changed, 90 insertions(+), 33 deletions(-) -- 2.16.1
[PATCH v3 2/3] [media] docs: documentation bits for S2X and the 64K transmission mode
From: Daniel SchellerAdd documentation bits regarding DVB-S2X. Since S2X only brings more APSK modulations and rolloff's, notice that S2 equals S2X where appropriate, and mention the additional modulations and rolloff's at the appropriate places. Signed-off-by: Daniel Scheller --- v2 to v3: - Added these documentation bits Please take note of some additional things in the cover letter. .../media/uapi/dvb/fe_property_parameters.rst | 50 ++ .../dvb/frontend-property-satellite-systems.rst| 8 ++-- 2 files changed, 36 insertions(+), 22 deletions(-) diff --git a/Documentation/media/uapi/dvb/fe_property_parameters.rst b/Documentation/media/uapi/dvb/fe_property_parameters.rst index 3524dcae4604..fa98a0d6b3fc 100644 --- a/Documentation/media/uapi/dvb/fe_property_parameters.rst +++ b/Documentation/media/uapi/dvb/fe_property_parameters.rst @@ -92,7 +92,8 @@ DVB-C Annex B 64-QAM. DVB-T QPSK, 16-QAM and 64-QAM. DVB-T2 QPSK, 16-QAM, 64-QAM and 256-QAM. DVB-S No need to set. It supports only QPSK. -DVB-S2 QPSK, 8-PSK, 16-APSK and 32-APSK. +DVB-S2(X) QPSK, 8-PSK, 16-APSK and 32-APSK. DVB-S2X additionally + supports 64-APSK, 128-APSK and 256-APSK. ISDB-T QPSK, DQPSK, 16-QAM and 64-QAM. ISDB-S 8-PSK, QPSK and BPSK. === === @@ -146,7 +147,8 @@ ISDB-T 5MHz, 6MHz, 7MHz and 8MHz, although most places :ref:`DTV-SYMBOL-RATE`, and the rolloff factor, with is fixed for DVB-C and DVB-S. - For DVB-S2, the rolloff should also be set via :ref:`DTV-ROLLOFF`. + For DVB-S2 and DVB-S2X, the rolloff should also be set via + :ref:`DTV-ROLLOFF`. .. _DTV-INVERSION: @@ -215,9 +217,9 @@ Currently not used. DTV_PILOT = -Used on DVB-S2. +Used on DVB-S2 and DVB-S2X. -Sets DVB-S2 pilot. +Sets DVB-S2(X) pilot. The acceptable values are defined by :c:type:`fe_pilot`. @@ -227,12 +229,17 @@ The acceptable values are defined by :c:type:`fe_pilot`. DTV_ROLLOFF === -Used on DVB-S2. +Used on DVB-S2 and DVB-S2X. -Sets DVB-S2 rolloff. +Sets DVB-S2(X) rolloff. The acceptable values are defined by :c:type:`fe_rolloff`. +.. note:: + + Rolloff factors 15%, 10% an 5% are part of the DVB-S2X specifications + and thus are valid only for S2X-modulated transponders. + .. _DTV-DISEQC-SLAVE-REPLY: @@ -267,6 +274,12 @@ Specifies the type of the delivery system. The acceptable values are defined by :c:type:`fe_delivery_system`. +.. note:: + + Since DVB-S2X only defines more rolloff's and more APSK modulations + without adding more attributes, DVB-S2X is handled via the DVB-S2 + delivery system. + .. _DTV-ISDBT-PARTIAL-RECEPTION: @@ -894,7 +907,7 @@ The acceptable values are defined by :c:type:`fe_transmit_mode`. #. DVB-T specifies 2K and 8K as valid sizes. - #. DVB-T2 specifies 1K, 2K, 4K, 8K, 16K and 32K. + #. DVB-T2 specifies 1K, 2K, 4K, 8K, 16K, 32K and 64K. #. DTMB specifies C1 and C3780. @@ -916,14 +929,14 @@ The acceptable values are defined by :c:type:`fe_hierarchy`. DTV_STREAM_ID = -Used on DVB-S2, DVB-T2 and ISDB-S. +Used on DVB-S2(X), DVB-T2 and ISDB-S. -DVB-S2, DVB-T2 and ISDB-S support the transmission of several streams on -a single transport stream. This property enables the digital TV driver to -handle substream filtering, when supported by the hardware. By default, +DVB-S2(X), DVB-T2 and ISDB-S support the transmission of several streams +on a single transport stream. This property enables the digital TV driver +to handle substream filtering, when supported by the hardware. By default, substream filtering is disabled. -For DVB-S2 and DVB-T2, the valid substream id range is from 0 to 255. +For DVB-S2(X) and DVB-T2, the valid substream id range is from 0 to 255. For ISDB, the valid substream id range is from 1 to 65535. @@ -994,13 +1007,14 @@ use the special macro LNA_AUTO to set LNA auto DTV_SCRAMBLING_SEQUENCE_INDEX = -Used on DVB-S2. +Used on DVB-S2 and DVB-S2X. -This 18 bit field, when present, carries the index of the DVB-S2 physical -layer scrambling sequence as defined in clause 5.5.4 of EN 302 307. -There is no explicit signalling method to convey scrambling sequence index -to the receiver. If S2 satellite delivery system descriptor is available -it can be used to read the scrambling sequence index (EN 300 468 table 41). +This 18 bit field, when present, carries the index of the DVB-S2(X) +physical layer scrambling sequence as defined in clause 5.5.4 of +EN 302 307. There is no explicit signalling method to convey scrambling +sequence index to the receiver. If S2 satellite delivery system descriptor +is available it can be used to read the scrambling sequence
Re: [PATCH v13 2/2] rcar-csi2: add Renesas R-Car MIPI CSI-2 receiver driver
Hi Niklas Thank you for this patch ... I know it has been a lot of work getting this and the VIN together! On 13/02/18 00:01, Niklas Söderlund wrote: > A V4L2 driver for Renesas R-Car MIPI CSI-2 receiver. The driver > supports the R-Car Gen3 SoCs where separate CSI-2 hardware blocks are > connected between the video sources and the video grabbers (VIN). > > Driver is based on a prototype by Koji Matsuoka in the Renesas BSP. > > Signed-off-by: Niklas Söderlund> Reviewed-by: Hans Verkuil I don't think there's actually anything major in the below - so with any comments addressed, or specifically ignored you can add my: Reviewed-by: Kieran Bingham tag if you like. > --- > drivers/media/platform/rcar-vin/Kconfig | 12 + > drivers/media/platform/rcar-vin/Makefile| 1 + > drivers/media/platform/rcar-vin/rcar-csi2.c | 884 > > 3 files changed, 897 insertions(+) > create mode 100644 drivers/media/platform/rcar-vin/rcar-csi2.c > > diff --git a/drivers/media/platform/rcar-vin/Kconfig > b/drivers/media/platform/rcar-vin/Kconfig > index af4c98b44d2e22cb..6875f30c1ae42631 100644 > --- a/drivers/media/platform/rcar-vin/Kconfig > +++ b/drivers/media/platform/rcar-vin/Kconfig > @@ -1,3 +1,15 @@ > +config VIDEO_RCAR_CSI2 > + tristate "R-Car MIPI CSI-2 Receiver" > + depends on VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API && OF I think I recall recently seeing that depending upon OF is redundant and not necessary (though I think that's minor in this instance) > + depends on ARCH_RENESAS || COMPILE_TEST > + select V4L2_FWNODE > + ---help--- > + Support for Renesas R-Car MIPI CSI-2 receiver. > + Supports R-Car Gen3 SoCs. > + > + To compile this driver as a module, choose M here: the > + module will be called rcar-csi2. > + > config VIDEO_RCAR_VIN > tristate "R-Car Video Input (VIN) Driver" > depends on VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API && OF && HAS_DMA && > MEDIA_CONTROLLER > diff --git a/drivers/media/platform/rcar-vin/Makefile > b/drivers/media/platform/rcar-vin/Makefile > index 48c5632c21dc060b..5ab803d3e7c1aa57 100644 > --- a/drivers/media/platform/rcar-vin/Makefile > +++ b/drivers/media/platform/rcar-vin/Makefile > @@ -1,3 +1,4 @@ > rcar-vin-objs = rcar-core.o rcar-dma.o rcar-v4l2.o > > +obj-$(CONFIG_VIDEO_RCAR_CSI2) += rcar-csi2.o > obj-$(CONFIG_VIDEO_RCAR_VIN) += rcar-vin.o > diff --git a/drivers/media/platform/rcar-vin/rcar-csi2.c > b/drivers/media/platform/rcar-vin/rcar-csi2.c > new file mode 100644 > index ..c0c2a763151bc928 > --- /dev/null > +++ b/drivers/media/platform/rcar-vin/rcar-csi2.c > @@ -0,0 +1,884 @@ > +// SPDX-License-Identifier: GPL-2.0+ > +/* > + * Driver for Renesas R-Car MIPI CSI-2 Receiver > + * > + * Copyright (C) 2018 Renesas Electronics Corp. > + */ > + > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > + > +#include > +#include > +#include > +#include > +#include > + > +/* Register offsets and bits */ > + > +/* Control Timing Select */ > +#define TREF_REG 0x00 > +#define TREF_TREFBIT(0) > + > +/* Software Reset */ > +#define SRST_REG 0x04 > +#define SRST_SRSTBIT(0) > + > +/* PHY Operation Control */ > +#define PHYCNT_REG 0x08 > +#define PHYCNT_SHUTDOWNZ BIT(17) > +#define PHYCNT_RSTZ BIT(16) > +#define PHYCNT_ENABLECLK BIT(4) > +#define PHYCNT_ENABLE_3 BIT(3) > +#define PHYCNT_ENABLE_2 BIT(2) > +#define PHYCNT_ENABLE_1 BIT(1) > +#define PHYCNT_ENABLE_0 BIT(0) > + > +/* Checksum Control */ > +#define CHKSUM_REG 0x0c > +#define CHKSUM_ECC_ENBIT(1) > +#define CHKSUM_CRC_ENBIT(0) > + > +/* > + * Channel Data Type Select > + * VCDT[0-15]: Channel 1 VCDT[16-31]: Channel 2 > + * VCDT2[0-15]: Channel 3 VCDT2[16-31]: Channel 4 > + */ > +#define VCDT_REG 0x10 > +#define VCDT2_REG0x14 > +#define VCDT_VCDTN_ENBIT(15) > +#define VCDT_SEL_VC(n) (((n) & 0x3) << 8) > +#define VCDT_SEL_DTN_ON BIT(6) > +#define VCDT_SEL_DT(n) (((n) & 0x3f) << 0) > + > +/* Frame Data Type Select */ > +#define FRDT_REG 0x18 > + > +/* Field Detection Control */ > +#define FLD_REG 0x1c > +#define FLD_FLD_NUM(n) (((n) & 0xff) << 16) > +#define FLD_FLD_EN4 BIT(3) > +#define FLD_FLD_EN3 BIT(2) > +#define FLD_FLD_EN2 BIT(1) > +#define FLD_FLD_EN BIT(0) > + > +/* Automatic
Re: [PATCH] media: staging/imx: fill vb2_v4l2_buffer sequence entry
Hello Steve, On Tue, 13 Mar 2018 15:03:07 -0700, Steve Longerbeamwrote: > Hi Peter, > > Thanks for the patch. > > This needs to be done in imx-ic-prpencvf.c as well, see > prp_vb2_buf_done(). Ahh, I see, would you prefer an follow up patch or an v2 patch doing the changes on mx-media-csi.c and imx-ic-prpencvf.c at once? Regards, Peter > > Steve > > > On 03/13/2018 01:00 PM, Peter Seiderer wrote: > > Signed-off-by: Peter Seiderer > > --- > > drivers/staging/media/imx/imx-media-csi.c | 5 + > > 1 file changed, 5 insertions(+) > > > > diff --git a/drivers/staging/media/imx/imx-media-csi.c > > b/drivers/staging/media/imx/imx-media-csi.c > > index 5a195f80a24d..3a6a645b9dce 100644 > > --- a/drivers/staging/media/imx/imx-media-csi.c > > +++ b/drivers/staging/media/imx/imx-media-csi.c > > @@ -111,6 +111,7 @@ struct csi_priv { > > struct v4l2_ctrl_handler ctrl_hdlr; > > > > int stream_count; /* streaming counter */ > > + __u32 frame_sequence; /* frame sequence counter */ > > bool last_eof; /* waiting for last EOF at stream off */ > > bool nfb4eof;/* NFB4EOF encountered during streaming */ > > struct completion last_eof_comp; > > @@ -234,8 +235,11 @@ static void csi_vb2_buf_done(struct csi_priv *priv) > > struct vb2_buffer *vb; > > dma_addr_t phys; > > > > + priv->frame_sequence++; > > + > > done = priv->active_vb2_buf[priv->ipu_buf_num]; > > if (done) { > > + done->vbuf.sequence = priv->frame_sequence; > > vb = >vbuf.vb2_buf; > > vb->timestamp = ktime_get_ns(); > > vb2_buffer_done(vb, priv->nfb4eof ? > > @@ -543,6 +547,7 @@ static int csi_idmac_start(struct csi_priv *priv) > > > > /* init EOF completion waitq */ > > init_completion(>last_eof_comp); > > + priv->frame_sequence = 0; > > priv->last_eof = false; > > priv->nfb4eof = false; > > >
Re: [PATCH] media: rc: meson-ir: add timeout on idle
Hi Sean, On Mon, Mar 12, 2018 at 01:58:11PM +, Sean Young wrote: > On Mon, Mar 12, 2018 at 02:20:00PM +0100, Matthias Reichl wrote: > > On Sun, Mar 11, 2018 at 12:55:19PM +, Sean Young wrote: > > > That makes complete sense. I'm actually keen to get this lowered, since > > > this makes it possible to lower the repeat period per-protocol, see > > > commit d57ea877af38 which had to be reverted (the ite driver will > > > need fixing up as well before this can happen). > > > > I remember the commit, this issue hit us in LibreELEC testbuilds > > as well :-) > > > > > Lowering to below 125ms does increase the risk of regressions, so I > > > am weary of that. Do you think there is benefit in doing this? > > > > I'd also say stick to the 125ms default. The default settings > > should always be safe ones IMO. > > Well, yes. I just wanted to explore the ideal situation before making > up our minds. > > > People who want to optimize for the last bit of performance can > > easily do that on their own, at their own risk. > > > > > > Personally I've been using gpio-ir-recv on RPi with the default 125ms > > timeout and a Hauppauge rc-5 remote for about 2 years now and I've > > always been happy with that. > > Ok. We should try to get this change for meson-ir ready for v4.17. I can > write a patch later. Thanks, it worked fine! > > I have to acknowledge though that the responsiveness of a remote > > with short messages, like rc-5, in combination with a low timeout > > (I tested down to 10ms) is pretty impressive. > > I've been thinking about this problem. What we could do is have a > per-protocol maximum space length, and repeat period. The timeout > can then be set to a maximum space length (+safety margin), and the > keyup timer can be set to timeout + repeat period (+safety margin). This sounds like a very good idea. It won't help much with IR receivers that have no configurable timeout or a large minimum timeout (ite-cir has 100ms min, probably a hardware limitation?), but for other receivers this'll be a nice improvement. > If memory serves, the lirc daemon always sets the timeout with > LIRC_SET_REC_TIMEOUT, so it would not affect lirc daemon decoding. Current versions of Lirc (0.9.4 and newer) don't seem to use LIRC_SET_REC_TIMEOUT but handle timeouts on it's own via a timeout value in poll(). There's still some generic code in lircd.cpp that supports setting timeouts via LIRC_SET_REC_TIMEOUT but the default plugin (which handles /dev/lircX) doesn't implement any of the required get/set timeout ioctls. strace on lircd 0.10.0 also shows that only LIRC_GET_FEATURES is used. Older Lirc versions (checked with 0.9.1 source I had here) seem to be using LIRC_SET_REC_TIMEOUT. So I think we should be fine here. Not sure if there are other users of the /dev/lirc interface that could be affected, I'm only familiar with lirc and the tools from v4l-utils. > Anyway, just an idea. Not something for v4.17. No need to rush things, your idea looks good to me but better test it thoroughly. Drop me a line if you have a first implementation, I'd be happy to help with testing. so long, Hias
[PATCH 03/18] af9013: dvbv5 cnr
Implement dvbv5 cnr. Signed-off-by: Antti Palosaari--- drivers/media/dvb-frontends/af9013.c | 88 +-- drivers/media/dvb-frontends/af9013_priv.h | 1 + 2 files changed, 84 insertions(+), 5 deletions(-) diff --git a/drivers/media/dvb-frontends/af9013.c b/drivers/media/dvb-frontends/af9013.c index 4cb6371572c5..b3d08e437478 100644 --- a/drivers/media/dvb-frontends/af9013.c +++ b/drivers/media/dvb-frontends/af9013.c @@ -46,6 +46,7 @@ struct af9013_state { unsigned long set_frontend_jiffies; unsigned long read_status_jiffies; unsigned long strength_jiffies; + unsigned long cnr_jiffies; bool first_tune; bool i2c_gate_state; unsigned int statistics_step:3; @@ -179,7 +180,6 @@ static int af9013_statistics_snr_result(struct dvb_frontend *fe) { struct af9013_state *state = fe->demodulator_priv; struct i2c_client *client = state->client; - struct dtv_frontend_properties *c = >dtv_property_cache; int ret, i, len; unsigned int utmp; u8 buf[3]; @@ -235,9 +235,6 @@ static int af9013_statistics_snr_result(struct dvb_frontend *fe) } state->snr = utmp * 10; /* dB/10 */ - c->cnr.stat[0].svalue = 1000 * utmp; - c->cnr.stat[0].scale = FE_SCALE_DECIBEL; - return 0; err: dev_dbg(>dev, "failed %d\n", ret); @@ -757,7 +754,7 @@ static int af9013_read_status(struct dvb_frontend *fe, enum fe_status *status) struct dtv_frontend_properties *c = >dtv_property_cache; int ret, stmp1; unsigned int utmp, utmp1, utmp2, utmp3, utmp4; - u8 buf[2]; + u8 buf[3]; dev_dbg(>dev, "\n"); @@ -869,6 +866,87 @@ static int af9013_read_status(struct dvb_frontend *fe, enum fe_status *status) break; } + /* CNR */ + switch (state->fe_status & FE_HAS_VITERBI) { + case FE_HAS_VITERBI: + if (time_is_after_jiffies(state->cnr_jiffies + msecs_to_jiffies(2000))) + break; + + /* Check if cnr ready */ + ret = regmap_read(state->regmap, 0xd2e1, ); + if (ret) + goto err; + + if (!((utmp >> 3) & 0x01)) { + dev_dbg(>dev, "cnr not ready\n"); + break; + } + + /* Read value */ + ret = regmap_bulk_read(state->regmap, 0xd2e3, buf, 3); + if (ret) + goto err; + + utmp1 = buf[2] << 16 | buf[1] << 8 | buf[0] << 0; + + /* Read current modulation */ + ret = regmap_read(state->regmap, 0xd3c1, ); + if (ret) + goto err; + + switch ((utmp >> 6) & 3) { + case 0: + /* +* QPSK +* CNR[dB] 13 * -log10((169 - value) / value) + 2.6 +* value [653799, 168], 2.6 / 13 = 3355443 +*/ + utmp1 = clamp(utmp1, 653799U, 168U); + utmp1 = ((u64)(intlog10(utmp1) + - intlog10(169 - utmp1) + + 3355443) * 13 * 1000) >> 24; + break; + case 1: + /* +* QAM-16 +* CNR[dB] 6 * log10((value - 37) / (828000 - value)) + 15.7 +* value [371105, 827999], 15.7 / 6 = 43900382 +*/ + utmp1 = clamp(utmp1, 371105U, 827999U); + utmp1 = ((u64)(intlog10(utmp1 - 37) + - intlog10(828000 - utmp1) + + 43900382) * 6 * 1000) >> 24; + break; + case 2: + /* +* QAM-64 +* CNR[dB] 8 * log10((value - 193000) / (425000 - value)) + 23.8 +* value [193246, 424999], 23.8 / 8 = 49912218 +*/ + utmp1 = clamp(utmp1, 193246U, 424999U); + utmp1 = ((u64)(intlog10(utmp1 - 193000) + - intlog10(425000 - utmp1) + + 49912218) * 8 * 1000) >> 24; + break; + default: + dev_dbg(>dev, "invalid modulation %u\n", + (utmp >> 6) & 3); + utmp1 = 0; + break; + } + + dev_dbg(>dev, "cnr %u\n", utmp1); + + state->cnr_jiffies = jiffies; + + c->cnr.stat[0].scale = FE_SCALE_DECIBEL; + c->cnr.stat[0].svalue = utmp1; + break; + default: + c->cnr.stat[0].scale =
[PATCH 10/18] af9013: remove all legacy media attach releated stuff
No one is binding that driver through media attach so remove it and all related dead code. Signed-off-by: Antti Palosaari--- drivers/media/dvb-frontends/af9013.c | 80 drivers/media/dvb-frontends/af9013.h | 42 --- 2 files changed, 7 insertions(+), 115 deletions(-) diff --git a/drivers/media/dvb-frontends/af9013.c b/drivers/media/dvb-frontends/af9013.c index d55c5f67ce0f..15af3e9482df 100644 --- a/drivers/media/dvb-frontends/af9013.c +++ b/drivers/media/dvb-frontends/af9013.c @@ -48,7 +48,6 @@ struct af9013_state { u32 dvbv3_ber; u32 dvbv3_ucblocks; bool first_tune; - bool i2c_gate_state; }; static int af9013_set_gpio(struct af9013_state *state, u8 gpio, u8 gpioval) @@ -1031,45 +1030,6 @@ static int af9013_sleep(struct dvb_frontend *fe) return ret; } -static int af9013_i2c_gate_ctrl(struct dvb_frontend *fe, int enable) -{ - int ret; - struct af9013_state *state = fe->demodulator_priv; - struct i2c_client *client = state->client; - - dev_dbg(>dev, "enable %d\n", enable); - - /* gate already open or close */ - if (state->i2c_gate_state == enable) - return 0; - - if (state->ts_mode == AF9013_TS_MODE_USB) - ret = regmap_update_bits(state->regmap, 0xd417, 0x08, -enable << 3); - else - ret = regmap_update_bits(state->regmap, 0xd607, 0x04, -enable << 2); - if (ret) - goto err; - - state->i2c_gate_state = enable; - - return 0; -err: - dev_dbg(>dev, "failed %d\n", ret); - return ret; -} - -static void af9013_release(struct dvb_frontend *fe) -{ - struct af9013_state *state = fe->demodulator_priv; - struct i2c_client *client = state->client; - - dev_dbg(>dev, "\n"); - - i2c_unregister_device(client); -} - static const struct dvb_frontend_ops af9013_ops; static int af9013_download_firmware(struct af9013_state *state) @@ -1172,40 +1132,6 @@ static int af9013_download_firmware(struct af9013_state *state) return ret; } -/* - * XXX: That is wrapper to af9013_probe() via driver core in order to provide - * proper I2C client for legacy media attach binding. - * New users must use I2C client binding directly! - */ -struct dvb_frontend *af9013_attach(const struct af9013_config *config, - struct i2c_adapter *i2c) -{ - struct i2c_client *client; - struct i2c_board_info board_info; - struct af9013_platform_data pdata; - - pdata.clk = config->clock; - pdata.tuner = config->tuner; - pdata.if_frequency = config->if_frequency; - pdata.ts_mode = config->ts_mode; - pdata.ts_output_pin = 7; - pdata.spec_inv = config->spec_inv; - memcpy(_version, config->api_version, sizeof(pdata.api_version)); - memcpy(, config->gpio, sizeof(pdata.gpio)); - pdata.attach_in_use = true; - - memset(_info, 0, sizeof(board_info)); - strlcpy(board_info.type, "af9013", sizeof(board_info.type)); - board_info.addr = config->i2c_addr; - board_info.platform_data = - client = i2c_new_device(i2c, _info); - if (!client || !client->dev.driver) - return NULL; - - return pdata.get_dvb_frontend(client); -} -EXPORT_SYMBOL(af9013_attach); - static const struct dvb_frontend_ops af9013_ops = { .delsys = { SYS_DVBT }, .info = { @@ -1231,8 +1157,6 @@ static const struct dvb_frontend_ops af9013_ops = { FE_CAN_MUTE_TS }, - .release = af9013_release, - .init = af9013_init, .sleep = af9013_sleep, @@ -1245,8 +1169,6 @@ static const struct dvb_frontend_ops af9013_ops = { .read_signal_strength = af9013_read_signal_strength, .read_ber = af9013_read_ber, .read_ucblocks = af9013_read_ucblocks, - - .i2c_gate_ctrl = af9013_i2c_gate_ctrl, }; static struct dvb_frontend *af9013_get_dvb_frontend(struct i2c_client *client) @@ -1546,8 +1468,6 @@ static int af9013_probe(struct i2c_client *client, /* Create dvb frontend */ memcpy(>fe.ops, _ops, sizeof(state->fe.ops)); - if (!pdata->attach_in_use) - state->fe.ops.release = NULL; state->fe.demodulator_priv = state; /* Setup callbacks */ diff --git a/drivers/media/dvb-frontends/af9013.h b/drivers/media/dvb-frontends/af9013.h index ea63ff9242f2..8144d4270b58 100644 --- a/drivers/media/dvb-frontends/af9013.h +++ b/drivers/media/dvb-frontends/af9013.h @@ -38,13 +38,6 @@ * @api_version: Firmware API version. * @gpio: GPIOs. * @get_dvb_frontend: Get DVB frontend callback. - * - * AF9013/5 GPIOs (mostly guessed): - * * demod#1-gpio#0 - set demod#2 i2c-addr for dual devices - * * demod#1-gpio#1 - xtal setting (?) - * * demod#1-gpio#3 - tuner#1 - * *
[PATCH 07/18] af9013: convert inittabs suitable for regmap_update_bits
Convert inttabs to format (reg, mask, val) which are suitable parameters to pass directly for regmap_update_bits. Signed-off-by: Antti Palosaari--- drivers/media/dvb-frontends/af9013.c | 62 +- drivers/media/dvb-frontends/af9013_priv.h | 1488 +++-- 2 files changed, 782 insertions(+), 768 deletions(-) diff --git a/drivers/media/dvb-frontends/af9013.c b/drivers/media/dvb-frontends/af9013.c index e81dc827e1b8..87a55cd67e03 100644 --- a/drivers/media/dvb-frontends/af9013.c +++ b/drivers/media/dvb-frontends/af9013.c @@ -843,7 +843,7 @@ static int af9013_init(struct dvb_frontend *fe) int ret, i, len; unsigned int utmp; u8 buf[3]; - const struct af9013_reg_bit *init; + const struct af9013_reg_mask_val *tab; dev_dbg(>dev, "\n"); @@ -898,72 +898,66 @@ static int af9013_init(struct dvb_frontend *fe) if (ret) goto err; - /* load OFSM settings */ - dev_dbg(>dev, "load ofsm settings\n"); - len = ARRAY_SIZE(ofsm_init); - init = ofsm_init; + /* Demod core settings */ + dev_dbg(>dev, "load demod core settings\n"); + len = ARRAY_SIZE(demod_init_tab); + tab = demod_init_tab; for (i = 0; i < len; i++) { - u16 reg = init[i].addr; - u8 mask = GENMASK(init[i].pos + init[i].len - 1, init[i].pos); - u8 val = init[i].val << init[i].pos; - - ret = regmap_update_bits(state->regmap, reg, mask, val); + ret = regmap_update_bits(state->regmap, tab[i].reg, tab[i].mask, +tab[i].val); if (ret) goto err; } - /* load tuner specific settings */ + /* Demod tuner specific settings */ dev_dbg(>dev, "load tuner specific settings\n"); switch (state->tuner) { case AF9013_TUNER_MXL5003D: - len = ARRAY_SIZE(tuner_init_mxl5003d); - init = tuner_init_mxl5003d; + len = ARRAY_SIZE(tuner_init_tab_mxl5003d); + tab = tuner_init_tab_mxl5003d; break; case AF9013_TUNER_MXL5005D: case AF9013_TUNER_MXL5005R: case AF9013_TUNER_MXL5007T: - len = ARRAY_SIZE(tuner_init_mxl5005); - init = tuner_init_mxl5005; + len = ARRAY_SIZE(tuner_init_tab_mxl5005); + tab = tuner_init_tab_mxl5005; break; case AF9013_TUNER_ENV77H11D5: - len = ARRAY_SIZE(tuner_init_env77h11d5); - init = tuner_init_env77h11d5; + len = ARRAY_SIZE(tuner_init_tab_env77h11d5); + tab = tuner_init_tab_env77h11d5; break; case AF9013_TUNER_MT2060: - len = ARRAY_SIZE(tuner_init_mt2060); - init = tuner_init_mt2060; + len = ARRAY_SIZE(tuner_init_tab_mt2060); + tab = tuner_init_tab_mt2060; break; case AF9013_TUNER_MC44S803: - len = ARRAY_SIZE(tuner_init_mc44s803); - init = tuner_init_mc44s803; + len = ARRAY_SIZE(tuner_init_tab_mc44s803); + tab = tuner_init_tab_mc44s803; break; case AF9013_TUNER_QT1010: case AF9013_TUNER_QT1010A: - len = ARRAY_SIZE(tuner_init_qt1010); - init = tuner_init_qt1010; + len = ARRAY_SIZE(tuner_init_tab_qt1010); + tab = tuner_init_tab_qt1010; break; case AF9013_TUNER_MT2060_2: - len = ARRAY_SIZE(tuner_init_mt2060_2); - init = tuner_init_mt2060_2; + len = ARRAY_SIZE(tuner_init_tab_mt2060_2); + tab = tuner_init_tab_mt2060_2; break; case AF9013_TUNER_TDA18271: case AF9013_TUNER_TDA18218: - len = ARRAY_SIZE(tuner_init_tda18271); - init = tuner_init_tda18271; + len = ARRAY_SIZE(tuner_init_tab_tda18271); + tab = tuner_init_tab_tda18271; break; case AF9013_TUNER_UNKNOWN: default: - len = ARRAY_SIZE(tuner_init_unknown); - init = tuner_init_unknown; + len = ARRAY_SIZE(tuner_init_tab_unknown); + tab = tuner_init_tab_unknown; break; } for (i = 0; i < len; i++) { - u16 reg = init[i].addr; - u8 mask = GENMASK(init[i].pos + init[i].len - 1, init[i].pos); - u8 val = init[i].val << init[i].pos; - - ret = regmap_update_bits(state->regmap, reg, mask, val); + ret = regmap_update_bits(state->regmap, tab[i].reg, tab[i].mask, +tab[i].val); if (ret) goto err; } diff --git a/drivers/media/dvb-frontends/af9013_priv.h
[PATCH 05/18] af9013: wrap dvbv3 statistics via dvbv5
Driver has calculated dvbv5 statistics, so use those as a base for legacy dvbv3 statistics. Wrap and convert needed values to dvbv3, remove old dvbv3 statistic implementations. Signed-off-by: Antti Palosaari--- drivers/media/dvb-frontends/af9013.c | 306 +++--- drivers/media/dvb-frontends/af9013_priv.h | 68 --- 2 files changed, 22 insertions(+), 352 deletions(-) diff --git a/drivers/media/dvb-frontends/af9013.c b/drivers/media/dvb-frontends/af9013.c index a054e39510e0..e81dc827e1b8 100644 --- a/drivers/media/dvb-frontends/af9013.c +++ b/drivers/media/dvb-frontends/af9013.c @@ -33,12 +33,6 @@ struct af9013_state { u8 api_version[4]; u8 gpio[4]; - /* tuner/demod RF and IF AGC limits used for signal strength calc */ - u8 signal_strength_en, rf_50, rf_80, if_50, if_80; - u16 signal_strength; - u32 ber; - u32 ucblocks; - u16 snr; u32 bandwidth_hz; enum fe_status fe_status; /* RF and IF AGC limits used for signal strength calc */ @@ -48,10 +42,12 @@ struct af9013_state { unsigned long strength_jiffies; unsigned long cnr_jiffies; unsigned long ber_ucb_jiffies; + u16 dvbv3_snr; + u16 dvbv3_strength; + u32 dvbv3_ber; + u32 dvbv3_ucblocks; bool first_tune; bool i2c_gate_state; - unsigned int statistics_step:3; - struct delayed_work statistics_work; }; static int af9013_set_gpio(struct af9013_state *state, u8 gpio, u8 gpioval) @@ -106,228 +102,6 @@ static int af9013_set_gpio(struct af9013_state *state, u8 gpio, u8 gpioval) return ret; } -static int af9013_statistics_ber_unc_start(struct dvb_frontend *fe) -{ - struct af9013_state *state = fe->demodulator_priv; - struct i2c_client *client = state->client; - int ret; - - dev_dbg(>dev, "\n"); - - /* reset and start BER counter */ - ret = regmap_update_bits(state->regmap, 0xd391, 0x10, 0x10); - if (ret) - goto err; - - return 0; -err: - dev_dbg(>dev, "failed %d\n", ret); - return ret; -} - -static int af9013_statistics_ber_unc_result(struct dvb_frontend *fe) -{ - struct af9013_state *state = fe->demodulator_priv; - struct i2c_client *client = state->client; - int ret; - unsigned int utmp; - u8 buf[5]; - - dev_dbg(>dev, "\n"); - - /* check if error bit count is ready */ - ret = regmap_read(state->regmap, 0xd391, ); - if (ret) - goto err; - - if (!((utmp >> 4) & 0x01)) { - dev_dbg(>dev, "not ready\n"); - return 0; - } - - ret = regmap_bulk_read(state->regmap, 0xd387, buf, 5); - if (ret) - goto err; - - state->ber = (buf[2] << 16) | (buf[1] << 8) | buf[0]; - state->ucblocks += (buf[4] << 8) | buf[3]; - - return 0; -err: - dev_dbg(>dev, "failed %d\n", ret); - return ret; -} - -static int af9013_statistics_snr_start(struct dvb_frontend *fe) -{ - struct af9013_state *state = fe->demodulator_priv; - struct i2c_client *client = state->client; - int ret; - - dev_dbg(>dev, "\n"); - - /* start SNR meas */ - ret = regmap_update_bits(state->regmap, 0xd2e1, 0x08, 0x08); - if (ret) - goto err; - - return 0; -err: - dev_dbg(>dev, "failed %d\n", ret); - return ret; -} - -static int af9013_statistics_snr_result(struct dvb_frontend *fe) -{ - struct af9013_state *state = fe->demodulator_priv; - struct i2c_client *client = state->client; - int ret, i, len; - unsigned int utmp; - u8 buf[3]; - u32 snr_val; - const struct af9013_snr *uninitialized_var(snr_lut); - - dev_dbg(>dev, "\n"); - - /* check if SNR ready */ - ret = regmap_read(state->regmap, 0xd2e1, ); - if (ret) - goto err; - - if (!((utmp >> 3) & 0x01)) { - dev_dbg(>dev, "not ready\n"); - return 0; - } - - /* read value */ - ret = regmap_bulk_read(state->regmap, 0xd2e3, buf, 3); - if (ret) - goto err; - - snr_val = (buf[2] << 16) | (buf[1] << 8) | buf[0]; - - /* read current modulation */ - ret = regmap_read(state->regmap, 0xd3c1, ); - if (ret) - goto err; - - switch ((utmp >> 6) & 3) { - case 0: - len = ARRAY_SIZE(qpsk_snr_lut); - snr_lut = qpsk_snr_lut; - break; - case 1: - len = ARRAY_SIZE(qam16_snr_lut); - snr_lut = qam16_snr_lut; - break; - case 2: - len = ARRAY_SIZE(qam64_snr_lut); - snr_lut = qam64_snr_lut; - break; - default: - goto err; - } - - for (i = 0; i < len; i++) { - utmp = snr_lut[i].snr; - - if
[PATCH 09/18] af9015: attach demod using i2c binding
af9013 demod driver has i2c binding. Use it. Signed-off-by: Antti Palosaari--- drivers/media/usb/dvb-usb-v2/af9015.c | 158 -- drivers/media/usb/dvb-usb-v2/af9015.h | 4 +- 2 files changed, 96 insertions(+), 66 deletions(-) diff --git a/drivers/media/usb/dvb-usb-v2/af9015.c b/drivers/media/usb/dvb-usb-v2/af9015.c index 7e4cce05b911..f07aa42535e5 100644 --- a/drivers/media/usb/dvb-usb-v2/af9015.c +++ b/drivers/media/usb/dvb-usb-v2/af9015.c @@ -148,8 +148,8 @@ static int af9015_write_reg_i2c(struct dvb_usb_device *d, u8 addr, u16 reg, struct af9015_state *state = d_to_priv(d); struct req_t req = {WRITE_I2C, addr, reg, 1, 1, 1, }; - if (addr == state->af9013_config[0].i2c_addr || - addr == state->af9013_config[1].i2c_addr) + if (addr == state->af9013_i2c_addr[0] || + addr == state->af9013_i2c_addr[1]) req.addr_len = 3; return af9015_ctrl_msg(d, ); @@ -161,8 +161,8 @@ static int af9015_read_reg_i2c(struct dvb_usb_device *d, u8 addr, u16 reg, struct af9015_state *state = d_to_priv(d); struct req_t req = {READ_I2C, addr, reg, 0, 1, 1, val}; - if (addr == state->af9013_config[0].i2c_addr || - addr == state->af9013_config[1].i2c_addr) + if (addr == state->af9013_i2c_addr[0] || + addr == state->af9013_i2c_addr[1]) req.addr_len = 3; return af9015_ctrl_msg(d, ); @@ -258,7 +258,7 @@ Due to that the only way to select correct tuner is use demodulator I2C-gate. ret = -EOPNOTSUPP; goto err; } - if (msg[0].addr == state->af9013_config[0].i2c_addr) + if (msg[0].addr == state->af9013_i2c_addr[0]) req.cmd = WRITE_MEMORY; else req.cmd = WRITE_I2C; @@ -276,7 +276,7 @@ Due to that the only way to select correct tuner is use demodulator I2C-gate. ret = -EOPNOTSUPP; goto err; } - if (msg[0].addr == state->af9013_config[0].i2c_addr) + if (msg[0].addr == state->af9013_i2c_addr[0]) req.cmd = READ_MEMORY; else req.cmd = READ_I2C; @@ -293,7 +293,7 @@ Due to that the only way to select correct tuner is use demodulator I2C-gate. ret = -EOPNOTSUPP; goto err; } - if (msg[0].addr == state->af9013_config[0].i2c_addr) { + if (msg[0].addr == state->af9013_i2c_addr[0]) { ret = -EINVAL; goto err; } @@ -478,7 +478,7 @@ static int af9015_read_config(struct dvb_usb_device *d) if (d->udev->speed == USB_SPEED_FULL) state->dual_mode = 0; - state->af9013_config[0].i2c_addr = AF9015_I2C_DEMOD; + state->af9013_i2c_addr[0] = AF9015_I2C_DEMOD; if (state->dual_mode) { /* read 2nd demodulator I2C address */ @@ -487,7 +487,7 @@ static int af9015_read_config(struct dvb_usb_device *d) if (ret) goto error; - state->af9013_config[1].i2c_addr = val >> 1; + state->af9013_i2c_addr[1] = val >> 1; } for (i = 0; i < state->dual_mode + 1; i++) { @@ -500,20 +500,20 @@ static int af9015_read_config(struct dvb_usb_device *d) goto error; switch (val) { case 0: - state->af9013_config[i].clock = 2880; + state->af9013_pdata[i].clk = 2880; break; case 1: - state->af9013_config[i].clock = 2048; + state->af9013_pdata[i].clk = 2048; break; case 2: - state->af9013_config[i].clock = 2800; + state->af9013_pdata[i].clk = 2800; break; case 3: - state->af9013_config[i].clock = 2500; + state->af9013_pdata[i].clk = 2500; break; } - dev_dbg(>dev, "[%d] xtal %02x, clock %u\n", - i, val, state->af9013_config[i].clock); + dev_dbg(>dev, "[%d] xtal %02x, clk %u\n", + i, val, state->af9013_pdata[i].clk); /* IF frequency */ req.addr = AF9015_EEPROM_IF1H + offset; @@ -521,17 +521,17 @@ static int af9015_read_config(struct dvb_usb_device *d) if (ret) goto error; - state->af9013_config[i].if_frequency = val << 8; + state->af9013_pdata[i].if_frequency = val << 8; req.addr =
[PATCH 02/18] af9013: dvbv5 signal strength
Implement dvbv5 signal strength estimate. We know tuner dependent -80dBm and -50dBm agc values, construct line equation and use it to map agc value to signal strength estimate. Signed-off-by: Antti Palosaari--- drivers/media/dvb-frontends/af9013.c | 83 +++- 1 file changed, 81 insertions(+), 2 deletions(-) diff --git a/drivers/media/dvb-frontends/af9013.c b/drivers/media/dvb-frontends/af9013.c index 30cf837058da..4cb6371572c5 100644 --- a/drivers/media/dvb-frontends/af9013.c +++ b/drivers/media/dvb-frontends/af9013.c @@ -41,8 +41,11 @@ struct af9013_state { u16 snr; u32 bandwidth_hz; enum fe_status fe_status; + /* RF and IF AGC limits used for signal strength calc */ + u8 strength_en, rf_agc_50, rf_agc_80, if_agc_50, if_agc_80; unsigned long set_frontend_jiffies; unsigned long read_status_jiffies; + unsigned long strength_jiffies; bool first_tune; bool i2c_gate_state; unsigned int statistics_step:3; @@ -751,8 +754,12 @@ static int af9013_read_status(struct dvb_frontend *fe, enum fe_status *status) { struct af9013_state *state = fe->demodulator_priv; struct i2c_client *client = state->client; - int ret; - unsigned int utmp, utmp1; + struct dtv_frontend_properties *c = >dtv_property_cache; + int ret, stmp1; + unsigned int utmp, utmp1, utmp2, utmp3, utmp4; + u8 buf[2]; + + dev_dbg(>dev, "\n"); /* * Return status from the cache if it is younger than 2000ms with the @@ -791,6 +798,77 @@ static int af9013_read_status(struct dvb_frontend *fe, enum fe_status *status) *status = utmp1; } + /* Signal strength */ + switch (state->strength_en) { + case 0: + /* Check if we support signal strength */ + ret = regmap_read(state->regmap, 0x9bee, ); + if (ret) + goto err; + + if ((utmp >> 0) & 0x01) { + /* Read agc values for signal strength estimation */ + ret = regmap_read(state->regmap, 0x9bbd, ); + if (ret) + goto err; + ret = regmap_read(state->regmap, 0x9bd0, ); + if (ret) + goto err; + ret = regmap_read(state->regmap, 0x9be2, ); + if (ret) + goto err; + ret = regmap_read(state->regmap, 0x9be4, ); + if (ret) + goto err; + + state->rf_agc_50 = utmp1; + state->rf_agc_80 = utmp2; + state->if_agc_50 = utmp3; + state->if_agc_80 = utmp4; + dev_dbg(>dev, + "rf_agc_50 %u, rf_agc_80 %u, if_agc_50 %u, if_agc_80 %u\n", + utmp1, utmp2, utmp3, utmp4); + + state->strength_en = 1; + } else { + /* Signal strength is not supported */ + state->strength_en = 2; + break; + } + /* Fall through */ + case 1: + if (time_is_after_jiffies(state->strength_jiffies + msecs_to_jiffies(2000))) + break; + + /* Read value */ + ret = regmap_bulk_read(state->regmap, 0xd07c, buf, 2); + if (ret) + goto err; + + /* +* Construct line equation from tuner dependent -80/-50 dBm agc +* limits and use it to map current agc value to dBm estimate +*/ + #define agc_gain (buf[0] + buf[1]) + #define agc_gain_50dbm (state->rf_agc_50 + state->if_agc_50) + #define agc_gain_80dbm (state->rf_agc_80 + state->if_agc_80) + stmp1 = 3 * (agc_gain - agc_gain_80dbm) / + (agc_gain_50dbm - agc_gain_80dbm) - 8; + + dev_dbg(>dev, + "strength %d, agc_gain %d, agc_gain_50dbm %d, agc_gain_80dbm %d\n", + stmp1, agc_gain, agc_gain_50dbm, agc_gain_80dbm); + + state->strength_jiffies = jiffies; + + c->strength.stat[0].scale = FE_SCALE_DECIBEL; + c->strength.stat[0].svalue = stmp1; + break; + default: + c->strength.stat[0].scale = FE_SCALE_NOT_AVAILABLE; + break; + } + return 0; err: dev_dbg(>dev, "failed %d\n", ret); @@ -1512,6 +1590,7 @@ static int af9013_probe(struct i2c_client *client, /* Init stats to indicate which stats are supported */ c = >fe.dtv_property_cache; + c->strength.len = 1;
[PATCH 06/18] af9015: fix logging
Pass correct device to dev_* logging functions, which allows us to remove redundant KBUILD_MODNAME and __func__ parameters from log format. Signed-off-by: Antti Palosaari--- drivers/media/usb/dvb-usb-v2/af9015.c | 160 +- 1 file changed, 81 insertions(+), 79 deletions(-) diff --git a/drivers/media/usb/dvb-usb-v2/af9015.c b/drivers/media/usb/dvb-usb-v2/af9015.c index 8013659c41b1..7e4cce05b911 100644 --- a/drivers/media/usb/dvb-usb-v2/af9015.c +++ b/drivers/media/usb/dvb-usb-v2/af9015.c @@ -29,6 +29,7 @@ static int af9015_ctrl_msg(struct dvb_usb_device *d, struct req_t *req) #define REQ_HDR_LEN 8 /* send header size */ #define ACK_HDR_LEN 2 /* rece header size */ struct af9015_state *state = d_to_priv(d); + struct usb_interface *intf = d->intf; int ret, wlen, rlen; u8 write = 1; @@ -66,8 +67,7 @@ static int af9015_ctrl_msg(struct dvb_usb_device *d, struct req_t *req) case BOOT: break; default: - dev_err(>udev->dev, "%s: unknown command=%d\n", - KBUILD_MODNAME, req->cmd); + dev_err(>dev, "unknown cmd %d\n", req->cmd); ret = -EIO; goto error; } @@ -75,8 +75,8 @@ static int af9015_ctrl_msg(struct dvb_usb_device *d, struct req_t *req) /* buffer overflow check */ if ((write && (req->data_len > BUF_LEN - REQ_HDR_LEN)) || (!write && (req->data_len > BUF_LEN - ACK_HDR_LEN))) { - dev_err(>udev->dev, "%s: too much data; cmd=%d len=%d\n", - KBUILD_MODNAME, req->cmd, req->data_len); + dev_err(>dev, "too much data, cmd %u, len %u\n", + req->cmd, req->data_len); ret = -EINVAL; goto error; } @@ -103,8 +103,7 @@ static int af9015_ctrl_msg(struct dvb_usb_device *d, struct req_t *req) /* check status */ if (rlen && state->buf[1]) { - dev_err(>udev->dev, "%s: command failed=%d\n", - KBUILD_MODNAME, state->buf[1]); + dev_err(>dev, "cmd failed %u\n", state->buf[1]); ret = -EIO; goto error; } @@ -206,6 +205,7 @@ static int af9015_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msg[], { struct dvb_usb_device *d = i2c_get_adapdata(adap); struct af9015_state *state = d_to_priv(d); + struct usb_interface *intf = d->intf; int ret; u16 addr; u8 mbox, addr_len; @@ -307,15 +307,14 @@ Due to that the only way to select correct tuner is use demodulator I2C-gate. ret = af9015_ctrl_msg(d, ); } else { ret = -EOPNOTSUPP; - dev_dbg(>udev->dev, "%s: unknown msg, num %u\n", - __func__, num); + dev_dbg(>dev, "unknown msg, num %u\n", num); } if (ret) goto err; return num; err: - dev_dbg(>udev->dev, "%s: failed %d\n", __func__, ret); + dev_dbg(>dev, "failed %d\n", ret); return ret; } @@ -331,6 +330,7 @@ static struct i2c_algorithm af9015_i2c_algo = { static int af9015_identify_state(struct dvb_usb_device *d, const char **name) { + struct usb_interface *intf = d->intf; int ret; u8 reply; struct req_t req = {GET_CONFIG, 0, 0, 0, 0, 1, }; @@ -339,7 +339,7 @@ static int af9015_identify_state(struct dvb_usb_device *d, const char **name) if (ret) return ret; - dev_dbg(>udev->dev, "%s: reply=%02x\n", __func__, reply); + dev_dbg(>dev, "reply %02x\n", reply); if (reply == 0x02) ret = WARM; @@ -353,10 +353,12 @@ static int af9015_download_firmware(struct dvb_usb_device *d, const struct firmware *fw) { struct af9015_state *state = d_to_priv(d); + struct usb_interface *intf = d->intf; int i, len, remaining, ret; struct req_t req = {DOWNLOAD_FIRMWARE, 0, 0, 0, 0, 0, NULL}; u16 checksum = 0; - dev_dbg(>udev->dev, "%s:\n", __func__); + + dev_dbg(>dev, "\n"); /* calc checksum */ for (i = 0; i < fw->size; i++) @@ -378,9 +380,8 @@ static int af9015_download_firmware(struct dvb_usb_device *d, ret = af9015_ctrl_msg(d, ); if (ret) { - dev_err(>udev->dev, - "%s: firmware download failed=%d\n", - KBUILD_MODNAME, ret); + dev_err(>dev, "firmware download failed %d\n", + ret); goto error; } } @@ -390,8 +391,7 @@ static int af9015_download_firmware(struct dvb_usb_device *d, req.data_len = 0; ret = af9015_ctrl_msg(d, ); if (ret) { -
[PATCH 12/18] af9015: use af9013 demod pid filters
PID filters are moved to af9013 demod driver as those are property of demod. As pid filters are now implemented correctly by demod driver, we could enable pid filter support for possible slave demod too on dual tuner configuration. Signed-off-by: Antti Palosaari--- drivers/media/usb/dvb-usb-v2/af9015.c | 49 +-- 1 file changed, 18 insertions(+), 31 deletions(-) diff --git a/drivers/media/usb/dvb-usb-v2/af9015.c b/drivers/media/usb/dvb-usb-v2/af9015.c index f07aa42535e5..8e2f704c6ca5 100644 --- a/drivers/media/usb/dvb-usb-v2/af9015.c +++ b/drivers/media/usb/dvb-usb-v2/af9015.c @@ -474,10 +474,6 @@ static int af9015_read_config(struct dvb_usb_device *d) state->dual_mode = val; dev_dbg(>dev, "ts mode %02x\n", state->dual_mode); - /* disable 2nd adapter because we don't have PID-filters */ - if (d->udev->speed == USB_SPEED_FULL) - state->dual_mode = 0; - state->af9013_i2c_addr[0] = AF9015_I2C_DEMOD; if (state->dual_mode) { @@ -1045,43 +1041,28 @@ static int af9015_tuner_attach(struct dvb_usb_adapter *adap) static int af9015_pid_filter_ctrl(struct dvb_usb_adapter *adap, int onoff) { - struct dvb_usb_device *d = adap_to_d(adap); - struct usb_interface *intf = d->intf; + struct af9015_state *state = adap_to_priv(adap); + struct af9013_platform_data *pdata = >af9013_pdata[adap->id]; int ret; - dev_dbg(>dev, "onoff %d\n", onoff); - - if (onoff) - ret = af9015_set_reg_bit(d, 0xd503, 0); - else - ret = af9015_clear_reg_bit(d, 0xd503, 0); + mutex_lock(>fe_mutex); + ret = pdata->pid_filter_ctrl(adap->fe[0], onoff); + mutex_unlock(>fe_mutex); return ret; } -static int af9015_pid_filter(struct dvb_usb_adapter *adap, int index, u16 pid, - int onoff) +static int af9015_pid_filter(struct dvb_usb_adapter *adap, int index, +u16 pid, int onoff) { - struct dvb_usb_device *d = adap_to_d(adap); - struct usb_interface *intf = d->intf; + struct af9015_state *state = adap_to_priv(adap); + struct af9013_platform_data *pdata = >af9013_pdata[adap->id]; int ret; - u8 idx; - - dev_dbg(>dev, "index %d, pid %04x, onoff %d\n", - index, pid, onoff); - ret = af9015_write_reg(d, 0xd505, (pid & 0xff)); - if (ret) - goto error; - - ret = af9015_write_reg(d, 0xd506, (pid >> 8)); - if (ret) - goto error; - - idx = ((index & 0x1f) | (1 << 5)); - ret = af9015_write_reg(d, 0xd504, idx); + mutex_lock(>fe_mutex); + ret = pdata->pid_filter(adap->fe[0], index, pid, onoff); + mutex_unlock(>fe_mutex); -error: return ret; } @@ -1448,6 +1429,12 @@ static struct dvb_usb_device_properties af9015_props = { .stream = DVB_USB_STREAM_BULK(0x84, 8, TS_USB20_FRAME_SIZE), }, { + .caps = DVB_USB_ADAP_HAS_PID_FILTER | + DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF, + .pid_filter_count = 32, + .pid_filter = af9015_pid_filter, + .pid_filter_ctrl = af9015_pid_filter_ctrl, + .stream = DVB_USB_STREAM_BULK(0x85, 8, TS_USB20_FRAME_SIZE), }, }, -- 2.14.3
[PATCH 15/18] af9015: enhance streaming config
Replace static stream settings by one which enables and disables stream interface when needed (TS streaming control). 1) Configure both TS IF and USB endpoints according to current use case 2) Disable streaming USB endpoints when streaming is stopped and enable when streaming is started. Reduces sleep power consumption slightly. 3) Reduce USB buffersize slightly, from 130848 to 98136 bytes Signed-off-by: Antti Palosaari--- drivers/media/usb/dvb-usb-v2/af9015.c | 220 ++ drivers/media/usb/dvb-usb-v2/af9015.h | 14 +-- 2 files changed, 115 insertions(+), 119 deletions(-) diff --git a/drivers/media/usb/dvb-usb-v2/af9015.c b/drivers/media/usb/dvb-usb-v2/af9015.c index 1f352307a00a..99e3b14d493e 100644 --- a/drivers/media/usb/dvb-usb-v2/af9015.c +++ b/drivers/media/usb/dvb-usb-v2/af9015.c @@ -607,11 +607,121 @@ static int af9015_get_stream_config(struct dvb_frontend *fe, u8 *ts_type, dev_dbg(>dev, "adap %u\n", fe_to_adap(fe)->id); if (d->udev->speed == USB_SPEED_FULL) - stream->u.bulk.buffersize = TS_USB11_FRAME_SIZE; + stream->u.bulk.buffersize = 5 * 188; return 0; } +static int af9015_streaming_ctrl(struct dvb_frontend *fe, int onoff) +{ + struct dvb_usb_device *d = fe_to_d(fe); + struct af9015_state *state = d_to_priv(d); + struct usb_interface *intf = d->intf; + int ret; + unsigned int utmp1, utmp2, reg1, reg2; + u8 buf[2]; + const unsigned int adap_id = fe_to_adap(fe)->id; + + dev_dbg(>dev, "adap id %d, onoff %d\n", adap_id, onoff); + + if (state->usb_ts_if_configured[adap_id] == false) { + dev_dbg(>dev, "set usb and ts interface\n"); + + /* USB IF stream settings */ + utmp1 = (d->udev->speed == USB_SPEED_FULL ? 5 : 87) * 188 / 4; + utmp2 = (d->udev->speed == USB_SPEED_FULL ? 64 : 512) / 4; + + buf[0] = (utmp1 >> 0) & 0xff; + buf[1] = (utmp1 >> 8) & 0xff; + if (adap_id == 0) { + /* 1st USB IF (EP4) stream settings */ + reg1 = 0xdd88; + reg2 = 0xdd0c; + } else { + /* 2nd USB IF (EP5) stream settings */ + reg1 = 0xdd8a; + reg2 = 0xdd0d; + } + + ret = af9015_write_regs(d, reg1, buf, 2); + if (ret) + goto err; + ret = af9015_write_reg(d, reg2, utmp2); + if (ret) + goto err; + + /* TS IF settings */ + if (state->dual_mode) { + ret = af9015_set_reg_bit(d, 0xd50b, 0); + if (ret) + goto err; + ret = af9015_set_reg_bit(d, 0xd520, 4); + if (ret) + goto err; + } else { + ret = af9015_clear_reg_bit(d, 0xd50b, 0); + if (ret) + goto err; + ret = af9015_clear_reg_bit(d, 0xd520, 4); + if (ret) + goto err; + } + + state->usb_ts_if_configured[adap_id] = true; + } + + if (adap_id == 0 && onoff) { + /* Adapter 0 stream on. EP4: clear NAK, enable, clear reset */ + ret = af9015_clear_reg_bit(d, 0xdd13, 5); + if (ret) + goto err; + ret = af9015_set_reg_bit(d, 0xdd11, 5); + if (ret) + goto err; + ret = af9015_clear_reg_bit(d, 0xd507, 2); + if (ret) + goto err; + } else if (adap_id == 1 && onoff) { + /* Adapter 1 stream on. EP5: clear NAK, enable, clear reset */ + ret = af9015_clear_reg_bit(d, 0xdd13, 6); + if (ret) + goto err; + ret = af9015_set_reg_bit(d, 0xdd11, 6); + if (ret) + goto err; + ret = af9015_clear_reg_bit(d, 0xd50b, 1); + if (ret) + goto err; + } else if (adap_id == 0 && !onoff) { + /* Adapter 0 stream off. EP4: set reset, disable, set NAK */ + ret = af9015_set_reg_bit(d, 0xd507, 2); + if (ret) + goto err; + ret = af9015_clear_reg_bit(d, 0xdd11, 5); + if (ret) + goto err; + ret = af9015_set_reg_bit(d, 0xdd13, 5); + if (ret) + goto err; + } else if (adap_id == 1 && !onoff) { + /* Adapter 1 stream off. EP5: set reset, disable, set NAK */ + ret = af9015_set_reg_bit(d, 0xd50b, 1); + if
[PATCH 13/18] af9015: refactor firmware download
Small revise, no functional changes. Signed-off-by: Antti Palosaari--- drivers/media/usb/dvb-usb-v2/af9015.c | 39 +++ 1 file changed, 17 insertions(+), 22 deletions(-) diff --git a/drivers/media/usb/dvb-usb-v2/af9015.c b/drivers/media/usb/dvb-usb-v2/af9015.c index 8e2f704c6ca5..ffd4b225e439 100644 --- a/drivers/media/usb/dvb-usb-v2/af9015.c +++ b/drivers/media/usb/dvb-usb-v2/af9015.c @@ -350,52 +350,47 @@ static int af9015_identify_state(struct dvb_usb_device *d, const char **name) } static int af9015_download_firmware(struct dvb_usb_device *d, - const struct firmware *fw) + const struct firmware *firmware) { struct af9015_state *state = d_to_priv(d); struct usb_interface *intf = d->intf; - int i, len, remaining, ret; + int ret, i, rem; struct req_t req = {DOWNLOAD_FIRMWARE, 0, 0, 0, 0, 0, NULL}; - u16 checksum = 0; + u16 checksum; dev_dbg(>dev, "\n"); - /* calc checksum */ - for (i = 0; i < fw->size; i++) - checksum += fw->data[i]; + /* Calc checksum, we need it when copy firmware to slave demod */ + for (i = 0, checksum = 0; i < firmware->size; i++) + checksum += firmware->data[i]; - state->firmware_size = fw->size; + state->firmware_size = firmware->size; state->firmware_checksum = checksum; - #define FW_ADDR 0x5100 /* firmware start address */ - #define LEN_MAX 55 /* max packet size */ - for (remaining = fw->size; remaining > 0; remaining -= LEN_MAX) { - len = remaining; - if (len > LEN_MAX) - len = LEN_MAX; - - req.data_len = len; - req.data = (u8 *) >data[fw->size - remaining]; - req.addr = FW_ADDR + fw->size - remaining; - + #define LEN_MAX (BUF_LEN - REQ_HDR_LEN) /* Max payload size */ + for (rem = firmware->size; rem > 0; rem -= LEN_MAX) { + req.data_len = min(LEN_MAX, rem); + req.data = (u8 *) >data[firmware->size - rem]; + req.addr = 0x5100 + firmware->size - rem; ret = af9015_ctrl_msg(d, ); if (ret) { dev_err(>dev, "firmware download failed %d\n", ret); - goto error; + goto err; } } - /* firmware loaded, request boot */ req.cmd = BOOT; req.data_len = 0; ret = af9015_ctrl_msg(d, ); if (ret) { dev_err(>dev, "firmware boot failed %d\n", ret); - goto error; + goto err; } -error: + return 0; +err: + dev_dbg(>dev, "failed %d\n", ret); return ret; } -- 2.14.3
[PATCH 04/18] af9013: dvbv5 ber and per
Implement dvbv5 ber and per. Signed-off-by: Antti Palosaari--- drivers/media/dvb-frontends/af9013.c | 73 +++- 1 file changed, 72 insertions(+), 1 deletion(-) diff --git a/drivers/media/dvb-frontends/af9013.c b/drivers/media/dvb-frontends/af9013.c index b3d08e437478..a054e39510e0 100644 --- a/drivers/media/dvb-frontends/af9013.c +++ b/drivers/media/dvb-frontends/af9013.c @@ -47,6 +47,7 @@ struct af9013_state { unsigned long read_status_jiffies; unsigned long strength_jiffies; unsigned long cnr_jiffies; + unsigned long ber_ucb_jiffies; bool first_tune; bool i2c_gate_state; unsigned int statistics_step:3; @@ -754,7 +755,7 @@ static int af9013_read_status(struct dvb_frontend *fe, enum fe_status *status) struct dtv_frontend_properties *c = >dtv_property_cache; int ret, stmp1; unsigned int utmp, utmp1, utmp2, utmp3, utmp4; - u8 buf[3]; + u8 buf[7]; dev_dbg(>dev, "\n"); @@ -947,6 +948,72 @@ static int af9013_read_status(struct dvb_frontend *fe, enum fe_status *status) break; } + /* BER / PER */ + switch (state->fe_status & FE_HAS_SYNC) { + case FE_HAS_SYNC: + if (time_is_after_jiffies(state->ber_ucb_jiffies + msecs_to_jiffies(2000))) + break; + + /* Check if ber / ucb is ready */ + ret = regmap_read(state->regmap, 0xd391, ); + if (ret) + goto err; + + if (!((utmp >> 4) & 0x01)) { + dev_dbg(>dev, "ber not ready\n"); + break; + } + + /* Read value */ + ret = regmap_bulk_read(state->regmap, 0xd385, buf, 7); + if (ret) + goto err; + + utmp1 = buf[4] << 16 | buf[3] << 8 | buf[2] << 0; + utmp2 = (buf[1] << 8 | buf[0] << 0) * 204 * 8; + utmp3 = buf[6] << 8 | buf[5] << 0; + utmp4 = buf[1] << 8 | buf[0] << 0; + + /* Use 1 TS packets for measure */ + if (utmp4 != 1) { + buf[0] = (1 >> 0) & 0xff; + buf[1] = (1 >> 8) & 0xff; + ret = regmap_bulk_write(state->regmap, 0xd385, buf, 2); + if (ret) + goto err; + } + + /* Reset ber / ucb counter */ + ret = regmap_update_bits(state->regmap, 0xd391, 0x20, 0x20); + if (ret) + goto err; + + dev_dbg(>dev, "post_bit_error %u, post_bit_count %u\n", + utmp1, utmp2); + dev_dbg(>dev, "block_error %u, block_count %u\n", + utmp3, utmp4); + + state->ber_ucb_jiffies = jiffies; + + c->post_bit_error.stat[0].scale = FE_SCALE_COUNTER; + c->post_bit_error.stat[0].uvalue += utmp1; + c->post_bit_count.stat[0].scale = FE_SCALE_COUNTER; + c->post_bit_count.stat[0].uvalue += utmp2; + + c->block_error.stat[0].scale = FE_SCALE_COUNTER; + c->block_error.stat[0].uvalue += utmp3; + c->block_count.stat[0].scale = FE_SCALE_COUNTER; + c->block_count.stat[0].uvalue += utmp4; + break; + default: + c->post_bit_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE; + c->post_bit_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE; + + c->block_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE; + c->block_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE; + break; + } + return 0; err: dev_dbg(>dev, "failed %d\n", ret); @@ -1670,6 +1737,10 @@ static int af9013_probe(struct i2c_client *client, c = >fe.dtv_property_cache; c->strength.len = 1; c->cnr.len = 1; + c->post_bit_error.len = 1; + c->post_bit_count.len = 1; + c->block_error.len = 1; + c->block_count.len = 1; dev_info(>dev, "Afatech AF9013 successfully attached\n"); dev_info(>dev, "firmware version: %d.%d.%d.%d\n", -- 2.14.3
[PATCH 18/18] af9015: correct some coding style issues
Correct coding style issues reported mostly by checkpatch.pl. Signed-off-by: Antti Palosaari--- drivers/media/usb/dvb-usb-v2/af9015.c | 172 +- 1 file changed, 88 insertions(+), 84 deletions(-) diff --git a/drivers/media/usb/dvb-usb-v2/af9015.c b/drivers/media/usb/dvb-usb-v2/af9015.c index 8379ef164fad..39f9ffce3caa 100644 --- a/drivers/media/usb/dvb-usb-v2/af9015.c +++ b/drivers/media/usb/dvb-usb-v2/af9015.c @@ -72,17 +72,19 @@ static int af9015_ctrl_msg(struct dvb_usb_device *d, struct req_t *req) goto error; } - /* buffer overflow check */ + /* Buffer overflow check */ if ((write && (req->data_len > BUF_LEN - REQ_HDR_LEN)) || - (!write && (req->data_len > BUF_LEN - ACK_HDR_LEN))) { + (!write && (req->data_len > BUF_LEN - ACK_HDR_LEN))) { dev_err(>dev, "too much data, cmd %u, len %u\n", req->cmd, req->data_len); ret = -EINVAL; goto error; } - /* write receives seq + status = 2 bytes - read receives seq + status + data = 2 + N bytes */ + /* +* Write receives seq + status = 2 bytes +* Read receives seq + status + data = 2 + N bytes +*/ wlen = REQ_HDR_LEN; rlen = ACK_HDR_LEN; if (write) { @@ -96,8 +98,8 @@ static int af9015_ctrl_msg(struct dvb_usb_device *d, struct req_t *req) if (req->cmd == DOWNLOAD_FIRMWARE || req->cmd == RECONNECT_USB) rlen = 0; - ret = dvb_usbv2_generic_rw_locked(d, - state->buf, wlen, state->buf, rlen); + ret = dvb_usbv2_generic_rw_locked(d, state->buf, wlen, + state->buf, rlen); if (ret) goto error; @@ -118,7 +120,7 @@ static int af9015_ctrl_msg(struct dvb_usb_device *d, struct req_t *req) } static int af9015_write_reg_i2c(struct dvb_usb_device *d, u8 addr, u16 reg, - u8 val) + u8 val) { struct af9015_state *state = d_to_priv(d); struct req_t req = {WRITE_I2C, addr, reg, 1, 1, 1, }; @@ -131,7 +133,7 @@ static int af9015_write_reg_i2c(struct dvb_usb_device *d, u8 addr, u16 reg, } static int af9015_read_reg_i2c(struct dvb_usb_device *d, u8 addr, u16 reg, - u8 *val) + u8 *val) { struct af9015_state *state = d_to_priv(d); struct req_t req = {READ_I2C, addr, reg, 0, 1, 1, val}; @@ -144,7 +146,7 @@ static int af9015_read_reg_i2c(struct dvb_usb_device *d, u8 addr, u16 reg, } static int af9015_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msg[], - int num) + int num) { struct dvb_usb_device *d = i2c_get_adapdata(adap); struct af9015_state *state = d_to_priv(d); @@ -154,28 +156,29 @@ static int af9015_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msg[], u8 mbox, addr_len; struct req_t req; -/* -The bus lock is needed because there is two tuners both using same I2C-address. -Due to that the only way to select correct tuner is use demodulator I2C-gate. - - -. AF9015 includes integrated AF9013 demodulator. -. . -.| uC | | demod| . |tuner | -.|| || . || -.| AF9015 | | AF9013/5 | . | MXL5003 | -.||--+I2C---|-/ -|-.-I2C---|| -.|| | | addr 0x38 | . | addr 0xc6 | -.|| | || . || -.|.. -| -| | demod| |tuner | -| || || -| | AF9013 | | MXL5003 | -+I2C---|-/ -|---I2C---|| - | addr 0x3a | | addr 0xc6 | - || || -*/ + /* +* I2C multiplexing: +* There could be two tuners, both using same I2C address. Demodulator +* I2C-gate is only possibility to select correct tuner. +* +* ... +* . AF9015 integrates AF9013 demodulator. +* . . +* .| USB IF | | demod|.| tuner| +* .|| ||.
[PATCH 14/18] af9015: refactor copy firmware to slave demod
Small improvements. Signed-off-by: Antti Palosaari--- drivers/media/usb/dvb-usb-v2/af9015.c | 88 +-- 1 file changed, 44 insertions(+), 44 deletions(-) diff --git a/drivers/media/usb/dvb-usb-v2/af9015.c b/drivers/media/usb/dvb-usb-v2/af9015.c index ffd4b225e439..1f352307a00a 100644 --- a/drivers/media/usb/dvb-usb-v2/af9015.c +++ b/drivers/media/usb/dvb-usb-v2/af9015.c @@ -720,79 +720,79 @@ static int af9015_copy_firmware(struct dvb_usb_device *d) struct af9015_state *state = d_to_priv(d); struct usb_interface *intf = d->intf; int ret; - u8 fw_params[4]; - u8 val, i; - struct req_t req = {COPY_FIRMWARE, 0, 0x5100, 0, 0, sizeof(fw_params), - fw_params }; + unsigned long timeout; + u8 val, firmware_info[4]; + struct req_t req = {COPY_FIRMWARE, 0, 0x5100, 0, 0, 4, firmware_info}; dev_dbg(>dev, "\n"); - fw_params[0] = state->firmware_size >> 8; - fw_params[1] = state->firmware_size & 0xff; - fw_params[2] = state->firmware_checksum >> 8; - fw_params[3] = state->firmware_checksum & 0xff; + firmware_info[0] = (state->firmware_size >> 8) & 0xff; + firmware_info[1] = (state->firmware_size >> 0) & 0xff; + firmware_info[2] = (state->firmware_checksum >> 8) & 0xff; + firmware_info[3] = (state->firmware_checksum >> 0) & 0xff; - ret = af9015_read_reg_i2c(d, state->af9013_i2c_addr[1], - 0x98be, ); + /* Check whether firmware is already running */ + ret = af9015_read_reg_i2c(d, state->af9013_i2c_addr[1], 0x98be, ); if (ret) - goto error; - else - dev_dbg(>dev, "firmware status %02x\n", val); + goto err; - if (val == 0x0c) /* fw is running, no need for download */ - goto exit; + dev_dbg(>dev, "firmware status %02x\n", val); - /* set I2C master clock to fast (to speed up firmware copy) */ - ret = af9015_write_reg(d, 0xd416, 0x04); /* 0x04 * 400ns */ - if (ret) - goto error; + if (val == 0x0c) + return 0; - msleep(50); + /* Set i2c clock to 625kHz to speed up firmware copy */ + ret = af9015_write_reg(d, 0xd416, 0x04); + if (ret) + goto err; - /* copy firmware */ + /* Copy firmware from master demod to slave demod */ ret = af9015_ctrl_msg(d, ); - if (ret) + if (ret) { dev_err(>dev, "firmware copy cmd failed %d\n", ret); + goto err; + } - dev_dbg(>dev, "firmware copy done\n"); - - /* set I2C master clock back to normal */ - ret = af9015_write_reg(d, 0xd416, 0x14); /* 0x14 * 400ns */ + /* Set i2c clock to 125kHz */ + ret = af9015_write_reg(d, 0xd416, 0x14); if (ret) - goto error; + goto err; - /* request boot firmware */ - ret = af9015_write_reg_i2c(d, state->af9013_i2c_addr[1], - 0xe205, 1); - dev_dbg(>dev, "firmware boot cmd status %d\n", ret); + /* Boot firmware */ + ret = af9015_write_reg_i2c(d, state->af9013_i2c_addr[1], 0xe205, 0x01); if (ret) - goto error; + goto err; - for (i = 0; i < 15; i++) { - msleep(100); + /* Poll firmware ready */ + for (val = 0x00, timeout = jiffies + msecs_to_jiffies(1000); +!time_after(jiffies, timeout) && val != 0x0c && val != 0x04;) { + msleep(20); - /* check firmware status */ + /* Check firmware status. 0c=OK, 04=fail */ ret = af9015_read_reg_i2c(d, state->af9013_i2c_addr[1], - 0x98be, ); - dev_dbg(>dev, "firmware status cmd status %d, firmware status %02x\n", - ret, val); + 0x98be, ); if (ret) - goto error; + goto err; - if (val == 0x0c || val == 0x04) /* success or fail */ - break; + dev_dbg(>dev, "firmware status %02x\n", val); } + dev_dbg(>dev, "firmware boot took %u ms\n", + jiffies_to_msecs(jiffies) - (jiffies_to_msecs(timeout) - 1000)); + if (val == 0x04) { - ret = -ETIMEDOUT; + ret = -ENODEV; dev_err(>dev, "firmware did not run\n"); + goto err; } else if (val != 0x0c) { ret = -ETIMEDOUT; dev_err(>dev, "firmware boot timeout\n"); + goto err; } -error: -exit: + return 0; +err: + dev_dbg(>dev, "failed %d\n", ret); return ret; } -- 2.14.3
[PATCH 08/18] af9013: add i2c mux adapter for tuner bus
Add muxed i2c adapter for demod tuner i2c bus gate control. Signed-off-by: Antti Palosaari--- drivers/media/dvb-frontends/Kconfig | 2 +- drivers/media/dvb-frontends/af9013.c | 126 +- drivers/media/dvb-frontends/af9013.h | 1 + drivers/media/dvb-frontends/af9013_priv.h | 1 + 4 files changed, 111 insertions(+), 19 deletions(-) diff --git a/drivers/media/dvb-frontends/Kconfig b/drivers/media/dvb-frontends/Kconfig index 687086cdb870..0712069fd9fe 100644 --- a/drivers/media/dvb-frontends/Kconfig +++ b/drivers/media/dvb-frontends/Kconfig @@ -462,7 +462,7 @@ config DVB_TDA10048 config DVB_AF9013 tristate "Afatech AF9013 demodulator" - depends on DVB_CORE && I2C + depends on DVB_CORE && I2C && I2C_MUX select REGMAP default m if !MEDIA_SUBDRV_AUTOSELECT help diff --git a/drivers/media/dvb-frontends/af9013.c b/drivers/media/dvb-frontends/af9013.c index 87a55cd67e03..d55c5f67ce0f 100644 --- a/drivers/media/dvb-frontends/af9013.c +++ b/drivers/media/dvb-frontends/af9013.c @@ -23,6 +23,7 @@ struct af9013_state { struct i2c_client *client; struct regmap *regmap; + struct i2c_mux_core *muxc; struct dvb_frontend fe; u32 clk; u8 tuner; @@ -1257,9 +1258,65 @@ static struct dvb_frontend *af9013_get_dvb_frontend(struct i2c_client *client) return >fe; } +static struct i2c_adapter *af9013_get_i2c_adapter(struct i2c_client *client) +{ + struct af9013_state *state = i2c_get_clientdata(client); + + dev_dbg(>dev, "\n"); + + return state->muxc->adapter[0]; +} + +/* + * XXX: Hackish solution. We use virtual register, reg bit 16, to carry info + * about i2c adapter locking. Own locking is needed because i2c mux call has + * already locked i2c adapter. + */ +static int af9013_select(struct i2c_mux_core *muxc, u32 chan) +{ + struct af9013_state *state = i2c_mux_priv(muxc); + struct i2c_client *client = state->client; + int ret; + + dev_dbg(>dev, "\n"); + + if (state->ts_mode == AF9013_TS_MODE_USB) + ret = regmap_update_bits(state->regmap, 0x1d417, 0x08, 0x08); + else + ret = regmap_update_bits(state->regmap, 0x1d607, 0x04, 0x04); + if (ret) + goto err; + + return 0; +err: + dev_dbg(>dev, "failed %d\n", ret); + return ret; +} + +static int af9013_deselect(struct i2c_mux_core *muxc, u32 chan) +{ + struct af9013_state *state = i2c_mux_priv(muxc); + struct i2c_client *client = state->client; + int ret; + + dev_dbg(>dev, "\n"); + + if (state->ts_mode == AF9013_TS_MODE_USB) + ret = regmap_update_bits(state->regmap, 0x1d417, 0x08, 0x00); + else + ret = regmap_update_bits(state->regmap, 0x1d607, 0x04, 0x00); + if (ret) + goto err; + + return 0; +err: + dev_dbg(>dev, "failed %d\n", ret); + return ret; +} + /* Own I2C access routines needed for regmap as chip uses extra command byte */ static int af9013_wregs(struct i2c_client *client, u8 cmd, u16 reg, - const u8 *val, int len) + const u8 *val, int len, u8 lock) { int ret; u8 buf[21]; @@ -1281,7 +1338,12 @@ static int af9013_wregs(struct i2c_client *client, u8 cmd, u16 reg, buf[1] = (reg >> 0) & 0xff; buf[2] = cmd; memcpy([3], val, len); - ret = i2c_transfer(client->adapter, msg, 1); + + if (lock) + i2c_lock_adapter(client->adapter); + ret = __i2c_transfer(client->adapter, msg, 1); + if (lock) + i2c_unlock_adapter(client->adapter); if (ret < 0) { goto err; } else if (ret != 1) { @@ -1296,7 +1358,7 @@ static int af9013_wregs(struct i2c_client *client, u8 cmd, u16 reg, } static int af9013_rregs(struct i2c_client *client, u8 cmd, u16 reg, - u8 *val, int len) + u8 *val, int len, u8 lock) { int ret; u8 buf[3]; @@ -1317,7 +1379,12 @@ static int af9013_rregs(struct i2c_client *client, u8 cmd, u16 reg, buf[0] = (reg >> 8) & 0xff; buf[1] = (reg >> 0) & 0xff; buf[2] = cmd; - ret = i2c_transfer(client->adapter, msg, 2); + + if (lock) + i2c_lock_adapter(client->adapter); + ret = __i2c_transfer(client->adapter, msg, 2); + if (lock) + i2c_unlock_adapter(client->adapter); if (ret < 0) { goto err; } else if (ret != 2) { @@ -1337,25 +1404,27 @@ static int af9013_regmap_write(void *context, const void *data, size_t count) struct af9013_state *state = i2c_get_clientdata(client); int ret, i; u8 cmd; - u16 reg = ((u8 *)data)[0] << 8|((u8 *)data)[1] << 0; - u8 *val = &((u8 *)data)[2]; - const unsigned int len = count - 2; + u8 lock =
[PATCH 01/18] af9013: change lock detection slightly
Whilst rewritten largely, the basic logic remains same with one exception: do not return immediately on success case. We are going to add statistics that function and cannot return too early. Signed-off-by: Antti Palosaari--- drivers/media/dvb-frontends/af9013.c | 55 ++-- 1 file changed, 27 insertions(+), 28 deletions(-) diff --git a/drivers/media/dvb-frontends/af9013.c b/drivers/media/dvb-frontends/af9013.c index b8f3ebfc3e27..30cf837058da 100644 --- a/drivers/media/dvb-frontends/af9013.c +++ b/drivers/media/dvb-frontends/af9013.c @@ -752,45 +752,44 @@ static int af9013_read_status(struct dvb_frontend *fe, enum fe_status *status) struct af9013_state *state = fe->demodulator_priv; struct i2c_client *client = state->client; int ret; - unsigned int utmp; + unsigned int utmp, utmp1; /* * Return status from the cache if it is younger than 2000ms with the * exception of last tune is done during 4000ms. */ - if (time_is_after_jiffies( - state->read_status_jiffies + msecs_to_jiffies(2000)) && - time_is_before_jiffies( - state->set_frontend_jiffies + msecs_to_jiffies(4000)) - ) { - *status = state->fe_status; - return 0; + if (time_is_after_jiffies(state->read_status_jiffies + msecs_to_jiffies(2000)) && + time_is_before_jiffies(state->set_frontend_jiffies + msecs_to_jiffies(4000))) { + *status = state->fe_status; } else { - *status = 0; - } + /* MPEG2 lock */ + ret = regmap_read(state->regmap, 0xd507, ); + if (ret) + goto err; - /* MPEG2 lock */ - ret = regmap_read(state->regmap, 0xd507, ); - if (ret) - goto err; + if ((utmp >> 6) & 0x01) { + utmp1 = FE_HAS_SIGNAL | FE_HAS_CARRIER | + FE_HAS_VITERBI | FE_HAS_SYNC | FE_HAS_LOCK; + } else { + /* TPS lock */ + ret = regmap_read(state->regmap, 0xd330, ); + if (ret) + goto err; - if ((utmp >> 6) & 0x01) - *status |= FE_HAS_SIGNAL | FE_HAS_CARRIER | FE_HAS_VITERBI | - FE_HAS_SYNC | FE_HAS_LOCK; + if ((utmp >> 3) & 0x01) + utmp1 = FE_HAS_SIGNAL | FE_HAS_CARRIER | + FE_HAS_VITERBI; + else + utmp1 = 0; + } - if (!*status) { - /* TPS lock */ - ret = regmap_read(state->regmap, 0xd330, ); - if (ret) - goto err; + dev_dbg(>dev, "fe_status %02x\n", utmp1); - if ((utmp >> 3) & 0x01) - *status |= FE_HAS_SIGNAL | FE_HAS_CARRIER | - FE_HAS_VITERBI; - } + state->read_status_jiffies = jiffies; - state->fe_status = *status; - state->read_status_jiffies = jiffies; + state->fe_status = utmp1; + *status = utmp1; + } return 0; err: -- 2.14.3
[PATCH 17/18] af9015: convert to regmap api
Use regmap for chip register access. Signed-off-by: Antti Palosaari--- drivers/media/usb/dvb-usb-v2/Kconfig | 1 + drivers/media/usb/dvb-usb-v2/af9015.c | 209 ++ drivers/media/usb/dvb-usb-v2/af9015.h | 2 + 3 files changed, 115 insertions(+), 97 deletions(-) diff --git a/drivers/media/usb/dvb-usb-v2/Kconfig b/drivers/media/usb/dvb-usb-v2/Kconfig index 0e4944b2b0f4..09a52aae299a 100644 --- a/drivers/media/usb/dvb-usb-v2/Kconfig +++ b/drivers/media/usb/dvb-usb-v2/Kconfig @@ -16,6 +16,7 @@ config DVB_USB_V2 config DVB_USB_AF9015 tristate "Afatech AF9015 DVB-T USB2.0 support" depends on DVB_USB_V2 + select REGMAP select DVB_AF9013 select DVB_PLL if MEDIA_SUBDRV_AUTOSELECT select MEDIA_TUNER_MT2060 if MEDIA_SUBDRV_AUTOSELECT diff --git a/drivers/media/usb/dvb-usb-v2/af9015.c b/drivers/media/usb/dvb-usb-v2/af9015.c index 99e3b14d493e..8379ef164fad 100644 --- a/drivers/media/usb/dvb-usb-v2/af9015.c +++ b/drivers/media/usb/dvb-usb-v2/af9015.c @@ -117,31 +117,6 @@ static int af9015_ctrl_msg(struct dvb_usb_device *d, struct req_t *req) return ret; } -static int af9015_write_regs(struct dvb_usb_device *d, u16 addr, u8 *val, - u8 len) -{ - struct req_t req = {WRITE_MEMORY, AF9015_I2C_DEMOD, addr, 0, 0, len, - val}; - return af9015_ctrl_msg(d, ); -} - -static int af9015_read_regs(struct dvb_usb_device *d, u16 addr, u8 *val, u8 len) -{ - struct req_t req = {READ_MEMORY, AF9015_I2C_DEMOD, addr, 0, 0, len, - val}; - return af9015_ctrl_msg(d, ); -} - -static int af9015_write_reg(struct dvb_usb_device *d, u16 addr, u8 val) -{ - return af9015_write_regs(d, addr, , 1); -} - -static int af9015_read_reg(struct dvb_usb_device *d, u16 addr, u8 *val) -{ - return af9015_read_regs(d, addr, val, 1); -} - static int af9015_write_reg_i2c(struct dvb_usb_device *d, u8 addr, u16 reg, u8 val) { @@ -168,38 +143,6 @@ static int af9015_read_reg_i2c(struct dvb_usb_device *d, u8 addr, u16 reg, return af9015_ctrl_msg(d, ); } -static int af9015_do_reg_bit(struct dvb_usb_device *d, u16 addr, u8 bit, u8 op) -{ - int ret; - u8 val, mask = 0x01; - - ret = af9015_read_reg(d, addr, ); - if (ret) - return ret; - - mask <<= bit; - if (op) { - /* set bit */ - val |= mask; - } else { - /* clear bit */ - mask ^= 0xff; - val &= mask; - } - - return af9015_write_reg(d, addr, val); -} - -static int af9015_set_reg_bit(struct dvb_usb_device *d, u16 addr, u8 bit) -{ - return af9015_do_reg_bit(d, addr, bit, 1); -} - -static int af9015_clear_reg_bit(struct dvb_usb_device *d, u16 addr, u8 bit) -{ - return af9015_do_reg_bit(d, addr, bit, 0); -} - static int af9015_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msg[], int num) { @@ -642,76 +585,73 @@ static int af9015_streaming_ctrl(struct dvb_frontend *fe, int onoff) reg1 = 0xdd8a; reg2 = 0xdd0d; } - - ret = af9015_write_regs(d, reg1, buf, 2); + ret = regmap_bulk_write(state->regmap, reg1, buf, 2); if (ret) goto err; - ret = af9015_write_reg(d, reg2, utmp2); + ret = regmap_write(state->regmap, reg2, utmp2); if (ret) goto err; /* TS IF settings */ if (state->dual_mode) { - ret = af9015_set_reg_bit(d, 0xd50b, 0); - if (ret) - goto err; - ret = af9015_set_reg_bit(d, 0xd520, 4); - if (ret) - goto err; + utmp1 = 0x01; + utmp2 = 0x10; } else { - ret = af9015_clear_reg_bit(d, 0xd50b, 0); - if (ret) - goto err; - ret = af9015_clear_reg_bit(d, 0xd520, 4); - if (ret) - goto err; + utmp1 = 0x00; + utmp2 = 0x00; } + ret = regmap_update_bits(state->regmap, 0xd50b, 0x01, utmp1); + if (ret) + goto err; + ret = regmap_update_bits(state->regmap, 0xd520, 0x10, utmp2); + if (ret) + goto err; state->usb_ts_if_configured[adap_id] = true; } if (adap_id == 0 && onoff) { /* Adapter 0 stream on. EP4: clear NAK, enable, clear reset */ - ret = af9015_clear_reg_bit(d, 0xdd13, 5); + ret = regmap_update_bits(state->regmap, 0xdd13, 0x20, 0x00);
[PATCH 16/18] dvb-usb-v2: add probe/disconnect callbacks
Add probe and disconnect callbacks that behaves similarly than ones used commonly on Linux driver model. We need those to get early / late access to driver in order to use normal probe time stuff, like regmap, extra bus adapters and so. Signed-off-by: Antti Palosaari--- drivers/media/usb/dvb-usb-v2/dvb_usb.h | 4 drivers/media/usb/dvb-usb-v2/dvb_usb_core.c | 24 2 files changed, 24 insertions(+), 4 deletions(-) diff --git a/drivers/media/usb/dvb-usb-v2/dvb_usb.h b/drivers/media/usb/dvb-usb-v2/dvb_usb.h index d2e80537b2f7..3fd6cc0d6340 100644 --- a/drivers/media/usb/dvb-usb-v2/dvb_usb.h +++ b/drivers/media/usb/dvb-usb-v2/dvb_usb.h @@ -203,6 +203,8 @@ struct dvb_usb_adapter_properties { * @generic_bulk_ctrl_endpoint_response: bulk control endpoint number for * receive * @generic_bulk_ctrl_delay: delay between bulk control sent and receive message + * @probe: like probe on driver model + * @disconnect: like disconnect on driver model * @identify_state: called to determine the firmware state (cold or warm) and * return possible firmware file name to be loaded * @firmware: name of the firmware file to be loaded @@ -239,6 +241,8 @@ struct dvb_usb_device_properties { u8 generic_bulk_ctrl_endpoint_response; unsigned int generic_bulk_ctrl_delay; + int (*probe)(struct dvb_usb_device *); + void (*disconnect)(struct dvb_usb_device *); #define WARM 0 #define COLD 1 int (*identify_state) (struct dvb_usb_device *, const char **); diff --git a/drivers/media/usb/dvb-usb-v2/dvb_usb_core.c b/drivers/media/usb/dvb-usb-v2/dvb_usb_core.c index 2bf3bd81280a..afdcdbf005e9 100644 --- a/drivers/media/usb/dvb-usb-v2/dvb_usb_core.c +++ b/drivers/media/usb/dvb-usb-v2/dvb_usb_core.c @@ -854,8 +854,6 @@ static int dvb_usbv2_exit(struct dvb_usb_device *d) dvb_usbv2_remote_exit(d); dvb_usbv2_adapter_exit(d); dvb_usbv2_i2c_exit(d); - kfree(d->priv); - kfree(d); return 0; } @@ -934,7 +932,7 @@ int dvb_usbv2_probe(struct usb_interface *intf, if (intf->cur_altsetting->desc.bInterfaceNumber != d->props->bInterfaceNumber) { ret = -ENODEV; - goto err_free_all; + goto err_kfree_d; } mutex_init(>usb_mutex); @@ -946,10 +944,16 @@ int dvb_usbv2_probe(struct usb_interface *intf, dev_err(>udev->dev, "%s: kzalloc() failed\n", KBUILD_MODNAME); ret = -ENOMEM; - goto err_free_all; + goto err_kfree_d; } } + if (d->props->probe) { + ret = d->props->probe(d); + if (ret) + goto err_kfree_priv; + } + if (d->props->identify_state) { const char *name = NULL; ret = d->props->identify_state(d, ); @@ -1001,6 +1005,12 @@ int dvb_usbv2_probe(struct usb_interface *intf, return 0; err_free_all: dvb_usbv2_exit(d); + if (d->props->disconnect) + d->props->disconnect(d); +err_kfree_priv: + kfree(d->priv); +err_kfree_d: + kfree(d); err: dev_dbg(>dev, "%s: failed=%d\n", __func__, ret); return ret; @@ -1021,6 +1031,12 @@ void dvb_usbv2_disconnect(struct usb_interface *intf) dvb_usbv2_exit(d); + if (d->props->disconnect) + d->props->disconnect(d); + + kfree(d->priv); + kfree(d); + pr_info("%s: '%s:%s' successfully deinitialized and disconnected\n", KBUILD_MODNAME, drvname, devname); kfree(devname); -- 2.14.3
[PATCH 11/18] af9013: add pid filter support
af9013 demod has pid filter. Add support for it. Signed-off-by: Antti Palosaari--- drivers/media/dvb-frontends/af9013.c | 52 drivers/media/dvb-frontends/af9013.h | 5 2 files changed, 57 insertions(+) diff --git a/drivers/media/dvb-frontends/af9013.c b/drivers/media/dvb-frontends/af9013.c index 15af3e9482df..482bce49819a 100644 --- a/drivers/media/dvb-frontends/af9013.c +++ b/drivers/media/dvb-frontends/af9013.c @@ -1171,6 +1171,56 @@ static const struct dvb_frontend_ops af9013_ops = { .read_ucblocks = af9013_read_ucblocks, }; +static int af9013_pid_filter_ctrl(struct dvb_frontend *fe, int onoff) +{ + struct af9013_state *state = fe->demodulator_priv; + struct i2c_client *client = state->client; + int ret; + + dev_dbg(>dev, "onoff %d\n", onoff); + + ret = regmap_update_bits(state->regmap, 0xd503, 0x01, onoff); + if (ret) + goto err; + + return 0; +err: + dev_dbg(>dev, "failed %d\n", ret); + return ret; +} + +static int af9013_pid_filter(struct dvb_frontend *fe, u8 index, u16 pid, +int onoff) +{ + struct af9013_state *state = fe->demodulator_priv; + struct i2c_client *client = state->client; + int ret; + u8 buf[2]; + + dev_dbg(>dev, "index %d, pid %04x, onoff %d\n", + index, pid, onoff); + + if (pid > 0x1fff) { + /* 0x2000 is kernel virtual pid for whole ts (all pids) */ + ret = 0; + goto err; + } + + buf[0] = (pid >> 0) & 0xff; + buf[1] = (pid >> 8) & 0xff; + ret = regmap_bulk_write(state->regmap, 0xd505, buf, 2); + if (ret) + goto err; + ret = regmap_write(state->regmap, 0xd504, onoff << 5 | index << 0); + if (ret) + goto err; + + return 0; +err: + dev_dbg(>dev, "failed %d\n", ret); + return ret; +} + static struct dvb_frontend *af9013_get_dvb_frontend(struct i2c_client *client) { struct af9013_state *state = i2c_get_clientdata(client); @@ -1473,6 +1523,8 @@ static int af9013_probe(struct i2c_client *client, /* Setup callbacks */ pdata->get_dvb_frontend = af9013_get_dvb_frontend; pdata->get_i2c_adapter = af9013_get_i2c_adapter; + pdata->pid_filter = af9013_pid_filter; + pdata->pid_filter_ctrl = af9013_pid_filter_ctrl; /* Init stats to indicate which stats are supported */ c = >fe.dtv_property_cache; diff --git a/drivers/media/dvb-frontends/af9013.h b/drivers/media/dvb-frontends/af9013.h index 8144d4270b58..165ae29ccac4 100644 --- a/drivers/media/dvb-frontends/af9013.h +++ b/drivers/media/dvb-frontends/af9013.h @@ -38,6 +38,9 @@ * @api_version: Firmware API version. * @gpio: GPIOs. * @get_dvb_frontend: Get DVB frontend callback. + * @get_i2c_adapter: Get I2C adapter. + * @pid_filter_ctrl: Control PID filter. + * @pid_filter: Set PID to PID filter. */ struct af9013_platform_data { /* @@ -78,6 +81,8 @@ struct af9013_platform_data { struct dvb_frontend* (*get_dvb_frontend)(struct i2c_client *); struct i2c_adapter* (*get_i2c_adapter)(struct i2c_client *); + int (*pid_filter_ctrl)(struct dvb_frontend *, int); + int (*pid_filter)(struct dvb_frontend *, u8, u16, int); }; /* -- 2.14.3
Re: [PATCH] media: staging/imx: fill vb2_v4l2_buffer sequence entry
Hi Peter, Thanks for the patch. This needs to be done in imx-ic-prpencvf.c as well, see prp_vb2_buf_done(). Steve On 03/13/2018 01:00 PM, Peter Seiderer wrote: Signed-off-by: Peter Seiderer--- drivers/staging/media/imx/imx-media-csi.c | 5 + 1 file changed, 5 insertions(+) diff --git a/drivers/staging/media/imx/imx-media-csi.c b/drivers/staging/media/imx/imx-media-csi.c index 5a195f80a24d..3a6a645b9dce 100644 --- a/drivers/staging/media/imx/imx-media-csi.c +++ b/drivers/staging/media/imx/imx-media-csi.c @@ -111,6 +111,7 @@ struct csi_priv { struct v4l2_ctrl_handler ctrl_hdlr; int stream_count; /* streaming counter */ + __u32 frame_sequence; /* frame sequence counter */ bool last_eof; /* waiting for last EOF at stream off */ bool nfb4eof;/* NFB4EOF encountered during streaming */ struct completion last_eof_comp; @@ -234,8 +235,11 @@ static void csi_vb2_buf_done(struct csi_priv *priv) struct vb2_buffer *vb; dma_addr_t phys; + priv->frame_sequence++; + done = priv->active_vb2_buf[priv->ipu_buf_num]; if (done) { + done->vbuf.sequence = priv->frame_sequence; vb = >vbuf.vb2_buf; vb->timestamp = ktime_get_ns(); vb2_buffer_done(vb, priv->nfb4eof ? @@ -543,6 +547,7 @@ static int csi_idmac_start(struct csi_priv *priv) /* init EOF completion waitq */ init_completion(>last_eof_comp); + priv->frame_sequence = 0; priv->last_eof = false; priv->nfb4eof = false;
Re: [PATCH] media: rc: meson-ir: lower timeout and make configurable
On Mon, Mar 12, 2018 at 09:48:40PM +, Sean Young wrote: > A timeout of 200ms is much longer than necessary, and delays the decoding > decoding of a single scancode and the last scancode when a button is being > held. This makes the remote seem sluggish. > > If the min_timeout and max_timeout values are set, the timeout is > configurable via the LIRC_SET_REC_TIMEOUT ioctl. > > Signed-off-by: Sean YoungTested-by: Matthias Reichl Thanks a lot, this is working fine! so long, Hias > --- > drivers/media/rc/meson-ir.c | 4 +++- > 1 file changed, 3 insertions(+), 1 deletion(-) > > diff --git a/drivers/media/rc/meson-ir.c b/drivers/media/rc/meson-ir.c > index 64b0aa4f4db7..f449b35d25e7 100644 > --- a/drivers/media/rc/meson-ir.c > +++ b/drivers/media/rc/meson-ir.c > @@ -144,7 +144,9 @@ static int meson_ir_probe(struct platform_device *pdev) > ir->rc->map_name = map_name ? map_name : RC_MAP_EMPTY; > ir->rc->allowed_protocols = RC_PROTO_BIT_ALL_IR_DECODER; > ir->rc->rx_resolution = US_TO_NS(MESON_TRATE); > - ir->rc->timeout = MS_TO_NS(200); > + ir->rc->min_timeout = 1; > + ir->rc->timeout = IR_DEFAULT_TIMEOUT; > + ir->rc->max_timeout = 10 * IR_DEFAULT_TIMEOUT; > ir->rc->driver_name = DRIVER_NAME; > > spin_lock_init(>lock); > -- > 2.14.3 >
Re: [PATCH] media: staging/imx: fill vb2_v4l2_buffer sequence entry
On 03/13/2018 03:24 PM, Peter Seiderer wrote: Hello Steve, On Tue, 13 Mar 2018 15:03:07 -0700, Steve Longerbeamwrote: Hi Peter, Thanks for the patch. This needs to be done in imx-ic-prpencvf.c as well, see prp_vb2_buf_done(). Ahh, I see, would you prefer an follow up patch or an v2 patch doing the changes on mx-media-csi.c and imx-ic-prpencvf.c at once? Hi Peter, a v2 patch would be fine. Steve On 03/13/2018 01:00 PM, Peter Seiderer wrote: Signed-off-by: Peter Seiderer --- drivers/staging/media/imx/imx-media-csi.c | 5 + 1 file changed, 5 insertions(+) diff --git a/drivers/staging/media/imx/imx-media-csi.c b/drivers/staging/media/imx/imx-media-csi.c index 5a195f80a24d..3a6a645b9dce 100644 --- a/drivers/staging/media/imx/imx-media-csi.c +++ b/drivers/staging/media/imx/imx-media-csi.c @@ -111,6 +111,7 @@ struct csi_priv { struct v4l2_ctrl_handler ctrl_hdlr; int stream_count; /* streaming counter */ + __u32 frame_sequence; /* frame sequence counter */ bool last_eof; /* waiting for last EOF at stream off */ bool nfb4eof;/* NFB4EOF encountered during streaming */ struct completion last_eof_comp; @@ -234,8 +235,11 @@ static void csi_vb2_buf_done(struct csi_priv *priv) struct vb2_buffer *vb; dma_addr_t phys; + priv->frame_sequence++; + done = priv->active_vb2_buf[priv->ipu_buf_num]; if (done) { + done->vbuf.sequence = priv->frame_sequence; vb = >vbuf.vb2_buf; vb->timestamp = ktime_get_ns(); vb2_buffer_done(vb, priv->nfb4eof ? @@ -543,6 +547,7 @@ static int csi_idmac_start(struct csi_priv *priv) /* init EOF completion waitq */ init_completion(>last_eof_comp); + priv->frame_sequence = 0; priv->last_eof = false; priv->nfb4eof = false;
Re: [PATCH 02/11] media: vsp1: use kernel __packed for structures
Hi David, Just for reference here, I've posted a v2 of this patch now titled: [PATCH v2 02/11] media: vsp1: Remove packed attributes from aligned structures which removes the attributes instead of modifying them. Thanks for the pointers! Regards Kieran On 13/03/18 15:03, Kieran Bingham wrote: > Hi David, > > On 13/03/18 13:38, David Laight wrote: >> From: Kieran Bingham [mailto:kieran.bingham+rene...@ideasonboard.com] >>> On 13/03/18 11:20, David Laight wrote: From: Kieran Bingham > Sent: 09 March 2018 22:04 > The kernel provides a __packed definition to abstract away from the > compiler specific attributes tag. > > Convert all packed structures in VSP1 to use it. > > Signed-off-by: Kieran Bingham> --- > drivers/media/platform/vsp1/vsp1_dl.c | 6 +++--- > 1 file changed, 3 insertions(+), 3 deletions(-) > > diff --git a/drivers/media/platform/vsp1/vsp1_dl.c > b/drivers/media/platform/vsp1/vsp1_dl.c > index 37e2c984fbf3..382e45c2054e 100644 > --- a/drivers/media/platform/vsp1/vsp1_dl.c > +++ b/drivers/media/platform/vsp1/vsp1_dl.c > @@ -29,19 +29,19 @@ > struct vsp1_dl_header_list { > u32 num_bytes; > u32 addr; > -} __attribute__((__packed__)); > +} __packed; > > struct vsp1_dl_header { > u32 num_lists; > struct vsp1_dl_header_list lists[8]; > u32 next_header; > u32 flags; > -} __attribute__((__packed__)); > +} __packed; > > struct vsp1_dl_entry { > u32 addr; > u32 data; > -} __attribute__((__packed__)); > +} __packed; Do these structures ever actually appear in misaligned memory? If they don't then they shouldn't be marked 'packed'. >>> >>> I believe the declaration is to ensure that the struct definition is not >>> altered >>> by the compiler as these structures specifically define the layout of how >>> the >>> memory is read by the VSP1 hardware. >> >> The C language and ABI define structure layouts. >> >>> Certainly 2 u32's sequentially stored in a struct are unlikely to be moved >>> or >>> rearranged by the compiler (though I believe it would be free to do so if it >>> chose without this attribute), but I think the declaration shows the intent >>> of >>> the memory structure. >> >> The language requires the fields be in order and the ABI stops the compiler >> adding 'random' padding. >> >>> Isn't this a common approach throughout the kernel when dealing with >>> hardware >>> defined memory structures ? >> >> Absolutely not. >> __packed tells the compiler that the structure might be on any address >> boundary. >> On many architectures this means the compiler must use byte accesses with >> shifts >> and ors for every access. >> The most a hardware defined structure will have is a compile-time assert >> that it is the correct size (to avoid silly errors from changes). > > > > Ok - interesting, I see what you're saying - and certainly don't want the > compiler to be performing byte accesses on the structures unnecessarily. > > I'm trying to distinguish the difference here. Is the single point that > __packed > > causes byte-access, where as > > __attribute__((__packed__)); > > does not? > > Looking at the GCC docs [0]: I see that __attribute__((__packed__)) tells the > compiler that the "structure or union is placed to minimize the memory > required". > > However, the keil compiler docs[1] do certainly declare that __packed causes > byte alignment. > > I was confused/thrown off here by the Kernel defining __packed as > __attribute__((packed)) at [2]. > > Do __attribute__((packed)) and __attribute__((__packed__)) differ ? > > In which case, from what I've read so far I wish "__packed" was > "__unaligned"... > > > [0] > https://gcc.gnu.org/onlinedocs/gcc/Common-Type-Attributes.html#index-packed-type-attribute > > [1] http://www.keil.com/support/man/docs/armcc/armcc_chr1359124230195.htm > > [2] > https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/include/linux/compiler-gcc.h?h=v4.16-rc5#n92 > > > Regards > > Kieran > > >> David >>
[PATCH v2] media: staging/imx: fill vb2_v4l2_buffer sequence entry
Signed-off-by: Peter Seiderer--- drivers/staging/media/imx/imx-ic-prpencvf.c | 5 + drivers/staging/media/imx/imx-media-csi.c | 5 + 2 files changed, 10 insertions(+) diff --git a/drivers/staging/media/imx/imx-ic-prpencvf.c b/drivers/staging/media/imx/imx-ic-prpencvf.c index ae453fd422f0..eaca74b72114 100644 --- a/drivers/staging/media/imx/imx-ic-prpencvf.c +++ b/drivers/staging/media/imx/imx-ic-prpencvf.c @@ -103,6 +103,7 @@ struct prp_priv { int nfb4eof_irq; int stream_count; + __u32 frame_sequence; /* frame sequence counter */ bool last_eof; /* waiting for last EOF at stream off */ bool nfb4eof;/* NFB4EOF encountered during streaming */ struct completion last_eof_comp; @@ -208,8 +209,11 @@ static void prp_vb2_buf_done(struct prp_priv *priv, struct ipuv3_channel *ch) struct vb2_buffer *vb; dma_addr_t phys; + priv->frame_sequence++; + done = priv->active_vb2_buf[priv->ipu_buf_num]; if (done) { + done->vbuf.sequence = priv->frame_sequence; vb = >vbuf.vb2_buf; vb->timestamp = ktime_get_ns(); vb2_buffer_done(vb, priv->nfb4eof ? @@ -637,6 +641,7 @@ static int prp_start(struct prp_priv *priv) /* init EOF completion waitq */ init_completion(>last_eof_comp); + priv->frame_sequence = 0; priv->last_eof = false; priv->nfb4eof = false; diff --git a/drivers/staging/media/imx/imx-media-csi.c b/drivers/staging/media/imx/imx-media-csi.c index 5a195f80a24d..3a6a645b9dce 100644 --- a/drivers/staging/media/imx/imx-media-csi.c +++ b/drivers/staging/media/imx/imx-media-csi.c @@ -111,6 +111,7 @@ struct csi_priv { struct v4l2_ctrl_handler ctrl_hdlr; int stream_count; /* streaming counter */ + __u32 frame_sequence; /* frame sequence counter */ bool last_eof; /* waiting for last EOF at stream off */ bool nfb4eof;/* NFB4EOF encountered during streaming */ struct completion last_eof_comp; @@ -234,8 +235,11 @@ static void csi_vb2_buf_done(struct csi_priv *priv) struct vb2_buffer *vb; dma_addr_t phys; + priv->frame_sequence++; + done = priv->active_vb2_buf[priv->ipu_buf_num]; if (done) { + done->vbuf.sequence = priv->frame_sequence; vb = >vbuf.vb2_buf; vb->timestamp = ktime_get_ns(); vb2_buffer_done(vb, priv->nfb4eof ? @@ -543,6 +547,7 @@ static int csi_idmac_start(struct csi_priv *priv) /* init EOF completion waitq */ init_completion(>last_eof_comp); + priv->frame_sequence = 0; priv->last_eof = false; priv->nfb4eof = false; -- 2.16.2
Re: [PATCH 1/4] dma-buf: add optional invalidate_mappings callback
Am 13.03.2018 um 17:00 schrieb Daniel Vetter: On Tue, Mar 13, 2018 at 04:52:02PM +0100, Christian König wrote: Am 13.03.2018 um 16:17 schrieb Daniel Vetter: [SNIP] Ok, so plan is to support fully pipeline moves and everything, with the old sg tables lazily cleaned up. I was thinking more about evicting stuff and throwing it out, where there's not going to be any new sg list but the object is going to be swapped out. Yes, exactly. Well my example was the unlikely case when the object is swapped out and immediately swapped in again because somebody needs it. I think some state flow charts (we can do SVG or DOT) in the kerneldoc would be sweet.Yeah, probably a good idea. Sounds good and I find it great that you're volunteering for that :D Ok seriously, my drawing capabilities are a bit underdeveloped. So I would prefer if somebody could at least help with that. Re GPU might cause a deadlock: Isn't that already a problem if you hold reservations of buffers used on other gpus, which want those reservations to complete the gpu reset, but that gpu reset blocks some fence that the reservation holder is waiting for? Correct, that's why amdgpu and TTM tries quite hard to never wait for a fence while a reservation object is locked. We might have a fairly huge mismatch of expectations here :-/ What do you mean with that? The only use case I haven't fixed so far is reaping deleted object during eviction, but that is only a matter of my free time to fix it. Yeah, this is the hard one. Actually it isn't so hard, it's just that I didn't had time so far to clean it up and we never hit that issue so far during our reset testing. The main point missing just a bit of functionality in the reservation object and Chris and I already had a good idea how to implement that. In general the assumption is that dma_fence will get signalled no matter what you're doing, assuming the only thing you need is to not block interrupts. The i915 gpu reset logic to make that work is a bit a work of art ... Correct, but I don't understand why that is so hard on i915? Our GPU scheduler makes all of that rather trivial, e.g. fences either signal correctly or are aborted and set as erroneous after a timeout. If we expect amdgpu and i915 to cooperate with shared buffers I guess one has to give in. No idea how to do that best. Again at least from amdgpu side I don't see much of an issue with that. So what exactly do you have in mind here? We have tons of fun with deadlocks against GPU resets, and loots of testcases, and I kinda get the impression amdgpu is throwing a lot of issues under the rug through trylock tricks that shut up lockdep, but don't fix much really. Hui? Why do you think that? The only trylock I'm aware of is during eviction and there it isn't a problem. mmap fault handler had one too last time I looked, and it smelled fishy. Good point, never wrapped my head fully around that one either. btw adding cross-release lockdep annotations for fences will probably turn up _lots_ more bugs in this area. At least for amdgpu that should be handled by now. You're sure? :-) Yes, except for fallback paths and bootup self tests we simply never wait for fences while holding locks. Trouble is that cross-release wasn't even ever enabled, much less anyone typed the dma_fence annotations. And just cross-release alone turned up _lost_ of deadlocks in i915 between fences, async workers (userptr, gpu reset) and core mm stuff. Yeah, we had lots of fun with the mm locks as well but as far as I know Felix and I already fixed all of them. Christian. I'd be seriously surprised if it wouldn't find an entire rats nest of issues around dma_fence once we enable it. -Daniel +* +* New mappings can be created immediately, but can't be used before the +* exclusive fence in the dma_bufs reservation object is signaled. +*/ + void (*invalidate_mappings)(struct dma_buf_attachment *attach); Bunch of questions about exact semantics, but I very much like this. And I think besides those technical details, the overall approach seems sound. Yeah this initial implementation was buggy like hell. Just wanted to confirm that the idea is going in the right direction. I wanted this 7 years ago, idea very much acked :-) Ok, thanks. Good to know. Christian.
[PATCH v2 06/11] media: vsp1: Provide VSP1 feature helper macro
The VSP1 devices define their specific capabilities through features marked in their device info structure. Various parts of the code read this info structure to infer if the features are available. Wrap this into a more readable vsp1_feature(vsp1, f) macro to ensure that usage is consistent throughout the driver. Signed-off-by: Kieran Bingham--- drivers/media/platform/vsp1/vsp1.h | 2 ++ drivers/media/platform/vsp1/vsp1_drv.c | 16 drivers/media/platform/vsp1/vsp1_wpf.c | 6 +++--- 3 files changed, 13 insertions(+), 11 deletions(-) diff --git a/drivers/media/platform/vsp1/vsp1.h b/drivers/media/platform/vsp1/vsp1.h index 78ef838416b3..1c080538c993 100644 --- a/drivers/media/platform/vsp1/vsp1.h +++ b/drivers/media/platform/vsp1/vsp1.h @@ -69,6 +69,8 @@ struct vsp1_device_info { bool uapi; }; +#define vsp1_feature(vsp1, f) ((vsp1)->info->features & (f)) + struct vsp1_device { struct device *dev; const struct vsp1_device_info *info; diff --git a/drivers/media/platform/vsp1/vsp1_drv.c b/drivers/media/platform/vsp1/vsp1_drv.c index eed9516e25e1..6fa0019ffc6e 100644 --- a/drivers/media/platform/vsp1/vsp1_drv.c +++ b/drivers/media/platform/vsp1/vsp1_drv.c @@ -268,7 +268,7 @@ static int vsp1_create_entities(struct vsp1_device *vsp1) } /* Instantiate all the entities. */ - if (vsp1->info->features & VSP1_HAS_BRS) { + if (vsp1_feature(vsp1, VSP1_HAS_BRS)) { vsp1->brs = vsp1_bru_create(vsp1, VSP1_ENTITY_BRS); if (IS_ERR(vsp1->brs)) { ret = PTR_ERR(vsp1->brs); @@ -278,7 +278,7 @@ static int vsp1_create_entities(struct vsp1_device *vsp1) list_add_tail(>brs->entity.list_dev, >entities); } - if (vsp1->info->features & VSP1_HAS_BRU) { + if (vsp1_feature(vsp1, VSP1_HAS_BRU)) { vsp1->bru = vsp1_bru_create(vsp1, VSP1_ENTITY_BRU); if (IS_ERR(vsp1->bru)) { ret = PTR_ERR(vsp1->bru); @@ -288,7 +288,7 @@ static int vsp1_create_entities(struct vsp1_device *vsp1) list_add_tail(>bru->entity.list_dev, >entities); } - if (vsp1->info->features & VSP1_HAS_CLU) { + if (vsp1_feature(vsp1, VSP1_HAS_CLU)) { vsp1->clu = vsp1_clu_create(vsp1); if (IS_ERR(vsp1->clu)) { ret = PTR_ERR(vsp1->clu); @@ -314,7 +314,7 @@ static int vsp1_create_entities(struct vsp1_device *vsp1) list_add_tail(>hst->entity.list_dev, >entities); - if (vsp1->info->features & VSP1_HAS_HGO && vsp1->info->uapi) { + if (vsp1_feature(vsp1, VSP1_HAS_HGO) && vsp1->info->uapi) { vsp1->hgo = vsp1_hgo_create(vsp1); if (IS_ERR(vsp1->hgo)) { ret = PTR_ERR(vsp1->hgo); @@ -325,7 +325,7 @@ static int vsp1_create_entities(struct vsp1_device *vsp1) >entities); } - if (vsp1->info->features & VSP1_HAS_HGT && vsp1->info->uapi) { + if (vsp1_feature(vsp1, VSP1_HAS_HGT) && vsp1->info->uapi) { vsp1->hgt = vsp1_hgt_create(vsp1); if (IS_ERR(vsp1->hgt)) { ret = PTR_ERR(vsp1->hgt); @@ -356,7 +356,7 @@ static int vsp1_create_entities(struct vsp1_device *vsp1) } } - if (vsp1->info->features & VSP1_HAS_LUT) { + if (vsp1_feature(vsp1, VSP1_HAS_LUT)) { vsp1->lut = vsp1_lut_create(vsp1); if (IS_ERR(vsp1->lut)) { ret = PTR_ERR(vsp1->lut); @@ -390,7 +390,7 @@ static int vsp1_create_entities(struct vsp1_device *vsp1) } } - if (vsp1->info->features & VSP1_HAS_SRU) { + if (vsp1_feature(vsp1, VSP1_HAS_SRU)) { vsp1->sru = vsp1_sru_create(vsp1); if (IS_ERR(vsp1->sru)) { ret = PTR_ERR(vsp1->sru); @@ -524,7 +524,7 @@ static int vsp1_device_init(struct vsp1_device *vsp1) vsp1_write(vsp1, VI6_DPR_HSI_ROUTE, VI6_DPR_NODE_UNUSED); vsp1_write(vsp1, VI6_DPR_BRU_ROUTE, VI6_DPR_NODE_UNUSED); - if (vsp1->info->features & VSP1_HAS_BRS) + if (vsp1_feature(vsp1, VSP1_HAS_BRS)) vsp1_write(vsp1, VI6_DPR_ILV_BRS_ROUTE, VI6_DPR_NODE_UNUSED); vsp1_write(vsp1, VI6_DPR_HGO_SMPPT, (7 << VI6_DPR_SMPPT_TGW_SHIFT) | diff --git a/drivers/media/platform/vsp1/vsp1_wpf.c b/drivers/media/platform/vsp1/vsp1_wpf.c index 68218625549e..f90e474cf2cc 100644 --- a/drivers/media/platform/vsp1/vsp1_wpf.c +++ b/drivers/media/platform/vsp1/vsp1_wpf.c @@ -146,13 +146,13 @@ static int wpf_init_controls(struct vsp1_rwpf *wpf) if (wpf->entity.index != 0) { /* Only WPF0 supports flipping. */ num_flip_ctrls = 0; - } else if (vsp1->info->features & VSP1_HAS_WPF_HFLIP) { + } else if (vsp1_feature(vsp1,
[PATCH v2 09/11] media: vsp1: Provide support for extended command pools
VSPD and VSP-DL devices can provide extended display lists supporting extended command display list objects. These extended commands require their own dma memory areas for a header and body specific to the command type. Implement a command pool to allocate all necessary memory in a single DMA allocation to reduce pressure on the TLB, and provide convenient re-usable command objects for the entities to utilise. Signed-off-by: Kieran Bingham--- v2: - Fix spelling typo in commit message - constify, and staticify the instantiation of vsp1_extended_commands - s/autfld_cmds/autofld_cmds/ - staticify cmd pool functions (Thanks kbuild-bot) drivers/media/platform/vsp1/vsp1_dl.c | 190 +++- drivers/media/platform/vsp1/vsp1_dl.h | 3 +- 2 files changed, 193 insertions(+) diff --git a/drivers/media/platform/vsp1/vsp1_dl.c b/drivers/media/platform/vsp1/vsp1_dl.c index cd91b50deed1..d8392bd866f1 100644 --- a/drivers/media/platform/vsp1/vsp1_dl.c +++ b/drivers/media/platform/vsp1/vsp1_dl.c @@ -121,6 +121,30 @@ struct vsp1_dl_body_pool { }; /** + * struct vsp1_cmd_pool - display list body pool + * @dma: DMA address of the entries + * @size: size of the full DMA memory pool in bytes + * @mem: CPU memory pointer for the pool + * @bodies: Array of DLB structures for the pool + * @free: List of free DLB entries + * @lock: Protects the pool and free list + * @vsp1: the VSP1 device + */ +struct vsp1_dl_cmd_pool { + /* DMA allocation */ + dma_addr_t dma; + size_t size; + void *mem; + + struct vsp1_dl_ext_cmd *cmds; + struct list_head free; + + spinlock_t lock; + + struct vsp1_device *vsp1; +}; + +/** * struct vsp1_dl_list - Display list * @list: entry in the display list manager lists * @dlm: the display list manager @@ -163,6 +187,7 @@ struct vsp1_dl_list { * @queued: list queued to the hardware (written to the DL registers) * @pending: list waiting to be queued to the hardware * @pool: body pool for the display list bodies + * @autofld_cmds: command pool to support auto-fld interlaced mode */ struct vsp1_dl_manager { unsigned int index; @@ -176,6 +201,7 @@ struct vsp1_dl_manager { struct vsp1_dl_list *pending; struct vsp1_dl_body_pool *pool; + struct vsp1_dl_cmd_pool *autofld_cmds; }; /* - @@ -339,6 +365,139 @@ void vsp1_dl_body_write(struct vsp1_dl_body *dlb, u32 reg, u32 data) } /* - + * Display List Extended Command Management + */ + +enum vsp1_extcmd_type { + VSP1_EXTCMD_AUTODISP, + VSP1_EXTCMD_AUTOFLD, +}; + +struct vsp1_extended_command_info { + u16 opcode; + size_t body_size; +} static const vsp1_extended_commands[] = { + [VSP1_EXTCMD_AUTODISP] = { 0x02, 96 }, + [VSP1_EXTCMD_AUTOFLD] = { 0x03, 160 }, +}; + +/** + * vsp1_dl_cmd_pool_create - Create a pool of commands from a single allocation + * @vsp1: The VSP1 device + * @type: The command pool type + * @num_commands: The quantity of commands to allocate + * + * Allocate a pool of commands each with enough memory to contain the private + * data of each command. The allocation sizes are dependent upon the command + * type. + * + * Return a pointer to a pool on success or NULL if memory can't be allocated. + */ +static struct vsp1_dl_cmd_pool * +vsp1_dl_cmd_pool_create(struct vsp1_device *vsp1, enum vsp1_extcmd_type type, + unsigned int num_cmds) +{ + struct vsp1_dl_cmd_pool *pool; + unsigned int i; + size_t cmd_size; + + pool = kzalloc(sizeof(*pool), GFP_KERNEL); + if (!pool) + return NULL; + + pool->cmds = kcalloc(num_cmds, sizeof(*pool->cmds), GFP_KERNEL); + if (!pool->cmds) { + kfree(pool); + return NULL; + } + + cmd_size = sizeof(struct vsp1_dl_ext_cmd_header) + + vsp1_extended_commands[type].body_size; + cmd_size = ALIGN(cmd_size, 16); + + pool->size = cmd_size * num_cmds; + pool->mem = dma_alloc_wc(vsp1->bus_master, pool->size, >dma, +GFP_KERNEL); + if (!pool->mem) { + kfree(pool->cmds); + kfree(pool); + return NULL; + } + + spin_lock_init(>lock); + INIT_LIST_HEAD(>free); + + for (i = 0; i < num_cmds; ++i) { + struct vsp1_dl_ext_cmd *cmd = >cmds[i]; + size_t cmd_offset = i * cmd_size; + size_t data_offset = sizeof(struct vsp1_dl_ext_cmd_header) + +cmd_offset; + + cmd->pool = pool; + cmd->cmd_opcode = vsp1_extended_commands[type].opcode; + + /* TODO: Auto-disp can utilise more than one command per cmd */ +
[PATCH v2 10/11] media: vsp1: Support Interlaced display pipelines
Calculate the top and bottom fields for the interlaced frames and utilise the extended display list command feature to implement the auto-field operations. This allows the DU to update the VSP2 registers dynamically based upon the currently processing field. Signed-off-by: Kieran Bingham--- v2: - fix erroneous BIT value which enabled interlaced - fix field handling at frame_end interrupt drivers/media/platform/vsp1/vsp1_dl.c | 10 - drivers/media/platform/vsp1/vsp1_drm.c | 11 - drivers/media/platform/vsp1/vsp1_regs.h | 1 +- drivers/media/platform/vsp1/vsp1_rpf.c | 72 -- drivers/media/platform/vsp1/vsp1_rwpf.h | 1 +- include/media/vsp1.h| 1 +- 6 files changed, 93 insertions(+), 3 deletions(-) diff --git a/drivers/media/platform/vsp1/vsp1_dl.c b/drivers/media/platform/vsp1/vsp1_dl.c index d8392bd866f1..08715ce6db1e 100644 --- a/drivers/media/platform/vsp1/vsp1_dl.c +++ b/drivers/media/platform/vsp1/vsp1_dl.c @@ -889,7 +889,9 @@ void vsp1_dl_list_commit(struct vsp1_dl_list *dl) */ bool vsp1_dlm_irq_frame_end(struct vsp1_dl_manager *dlm) { + struct vsp1_device *vsp1 = dlm->vsp1; bool completed = false; + u32 status = vsp1_read(vsp1, VI6_STATUS); spin_lock(>lock); @@ -914,6 +916,14 @@ bool vsp1_dlm_irq_frame_end(struct vsp1_dl_manager *dlm) goto done; /* +* Progressive streams report only TOP fields. If we have a BOTTOM +* field, we are interlaced, and expect the frame to complete on the +* next frame end interrupt. +*/ + if (status & VI6_STATUS_FLD_STD(dlm->index)) + goto done; + + /* * The device starts processing the queued display list right after the * frame end interrupt. The display list thus becomes active. */ diff --git a/drivers/media/platform/vsp1/vsp1_drm.c b/drivers/media/platform/vsp1/vsp1_drm.c index 0459b970e9da..a714c53601b6 100644 --- a/drivers/media/platform/vsp1/vsp1_drm.c +++ b/drivers/media/platform/vsp1/vsp1_drm.c @@ -368,6 +368,17 @@ int vsp1_du_atomic_update(struct device *dev, unsigned int pipe_index, return -EINVAL; } + if (!(vsp1_feature(vsp1, VSP1_HAS_EXT_DL)) && cfg->interlaced) { + /* +* Interlaced support requires extended display lists to +* provide the auto-fld feature with the DU. +*/ + dev_dbg(vsp1->dev, "Interlaced unsupported on this output\n"); + return -EINVAL; + } + + rpf->interlaced = cfg->interlaced; + rpf->fmtinfo = fmtinfo; rpf->format.num_planes = fmtinfo->planes; rpf->format.plane_fmt[0].bytesperline = cfg->pitch; diff --git a/drivers/media/platform/vsp1/vsp1_regs.h b/drivers/media/platform/vsp1/vsp1_regs.h index 43ad68ff3167..e2dffbe82809 100644 --- a/drivers/media/platform/vsp1/vsp1_regs.h +++ b/drivers/media/platform/vsp1/vsp1_regs.h @@ -31,6 +31,7 @@ #define VI6_SRESET_SRTS(n) (1 << (n)) #define VI6_STATUS 0x0038 +#define VI6_STATUS_FLD_STD(n) (1 << ((n) + 28)) #define VI6_STATUS_SYS_ACT(n) (1 << ((n) + 8)) #define VI6_WPF_IRQ_ENB(n) (0x0048 + (n) * 12) diff --git a/drivers/media/platform/vsp1/vsp1_rpf.c b/drivers/media/platform/vsp1/vsp1_rpf.c index 67f2fb3e0611..86ac8f488b7a 100644 --- a/drivers/media/platform/vsp1/vsp1_rpf.c +++ b/drivers/media/platform/vsp1/vsp1_rpf.c @@ -24,6 +24,20 @@ #define RPF_MAX_WIDTH 8190 #define RPF_MAX_HEIGHT 8190 +/* Pre extended display list command data structure */ +struct vsp1_extcmd_auto_fld_body { + u32 top_y0; + u32 bottom_y0; + u32 top_c0; + u32 bottom_c0; + u32 top_c1; + u32 bottom_c1; + u32 reserved0; + u32 reserved1; +} __packed; + +#define VSP1_DL_EXT_AUTOFLD_INTBIT(0) + /* - * Device Access */ @@ -68,6 +82,14 @@ static void rpf_configure_stream(struct vsp1_entity *entity, pstride |= format->plane_fmt[1].bytesperline << VI6_RPF_SRCM_PSTRIDE_C_SHIFT; + /* +* pstride has both STRIDE_Y and STRIDE_C, but multiplying the whole +* of pstride by 2 is conveniently OK here as we are multiplying both +* values. +*/ + if (rpf->interlaced) + pstride *= 2; + vsp1_rpf_write(rpf, dlb, VI6_RPF_SRCM_PSTRIDE, pstride); /* Format */ @@ -104,6 +126,9 @@ static void rpf_configure_stream(struct vsp1_entity *entity, top = compose->top; } + if (rpf->interlaced) + top /= 2; + vsp1_rpf_write(rpf, dlb, VI6_RPF_LOC, (left << VI6_RPF_LOC_HCOORD_SHIFT) |
[PATCH v2 08/11] media: vsp1: Add support for extended display list headers
Extended display list headers allow pre and post command lists to be executed by the VSP pipeline. This provides the base support for features such as AUTO_FLD (for interlaced support) and AUTO_DISP (for supporting continuous camera preview pipelines. Signed-off-by: Kieran Bingham--- v2: - remove __packed attributes drivers/media/platform/vsp1/vsp1.h | 1 +- drivers/media/platform/vsp1/vsp1_dl.c | 83 +- drivers/media/platform/vsp1/vsp1_dl.h | 29 - drivers/media/platform/vsp1/vsp1_drv.c | 7 +- drivers/media/platform/vsp1/vsp1_regs.h | 5 +- 5 files changed, 116 insertions(+), 9 deletions(-) diff --git a/drivers/media/platform/vsp1/vsp1.h b/drivers/media/platform/vsp1/vsp1.h index 1c080538c993..bb3b32795206 100644 --- a/drivers/media/platform/vsp1/vsp1.h +++ b/drivers/media/platform/vsp1/vsp1.h @@ -55,6 +55,7 @@ struct vsp1_uds; #define VSP1_HAS_HGO (1 << 7) #define VSP1_HAS_HGT (1 << 8) #define VSP1_HAS_BRS (1 << 9) +#define VSP1_HAS_EXT_DL(1 << 10) struct vsp1_device_info { u32 version; diff --git a/drivers/media/platform/vsp1/vsp1_dl.c b/drivers/media/platform/vsp1/vsp1_dl.c index 5f5706f8a84c..cd91b50deed1 100644 --- a/drivers/media/platform/vsp1/vsp1_dl.c +++ b/drivers/media/platform/vsp1/vsp1_dl.c @@ -26,6 +26,9 @@ #define VSP1_DLH_INT_ENABLE(1 << 1) #define VSP1_DLH_AUTO_START(1 << 0) +#define VSP1_DLH_EXT_PRE_CMD_EXEC (1 << 9) +#define VSP1_DLH_EXT_POST_CMD_EXEC (1 << 8) + struct vsp1_dl_header_list { u32 num_bytes; u32 addr; @@ -38,11 +41,34 @@ struct vsp1_dl_header { u32 flags; }; +struct vsp1_dl_ext_header { + u32 reserved0; /* alignment padding */ + + u16 pre_ext_cmd_qty; + u16 flags; + u32 pre_ext_cmd_plist; + + u32 post_ext_cmd_qty; + u32 post_ext_cmd_plist; +}; + +struct vsp1_dl_header_extended { + struct vsp1_dl_header header; + struct vsp1_dl_ext_header ext; +}; + struct vsp1_dl_entry { u32 addr; u32 data; }; +struct vsp1_dl_ext_cmd_header { + u32 cmd; + u32 flags; + u32 data; + u32 reserved; +}; + /** * struct vsp1_dl_body - Display list body * @list: entry in the display list list of bodies @@ -99,9 +125,12 @@ struct vsp1_dl_body_pool { * @list: entry in the display list manager lists * @dlm: the display list manager * @header: display list header + * @extended: extended display list header. NULL for normal lists * @dma: DMA address for the header * @body0: first display list body * @bodies: list of extra display list bodies + * @pre_cmd: pre cmd to be issued through extended dl header + * @post_cmd: post cmd to be issued through extended dl header * @has_chain: if true, indicates that there's a partition chain * @chain: entry in the display list partition chain */ @@ -110,11 +139,15 @@ struct vsp1_dl_list { struct vsp1_dl_manager *dlm; struct vsp1_dl_header *header; + struct vsp1_dl_ext_header *extended; dma_addr_t dma; struct vsp1_dl_body *body0; struct list_head bodies; + struct vsp1_dl_ext_cmd *pre_cmd; + struct vsp1_dl_ext_cmd *post_cmd; + bool has_chain; struct list_head chain; }; @@ -498,6 +531,14 @@ int vsp1_dl_list_add_chain(struct vsp1_dl_list *head, return 0; } +static void vsp1_dl_ext_cmd_fill_header(struct vsp1_dl_ext_cmd *cmd) +{ + cmd->cmds[0].cmd = cmd->cmd_opcode; + cmd->cmds[0].flags = cmd->flags; + cmd->cmds[0].data = cmd->data_dma; + cmd->cmds[0].reserved = 0; +} + static void vsp1_dl_list_fill_header(struct vsp1_dl_list *dl, bool is_last) { struct vsp1_dl_manager *dlm = dl->dlm; @@ -550,6 +591,27 @@ static void vsp1_dl_list_fill_header(struct vsp1_dl_list *dl, bool is_last) */ dl->header->flags = VSP1_DLH_INT_ENABLE; } + + if (!dl->extended) + return; + + dl->extended->flags = 0; + + if (dl->pre_cmd) { + dl->extended->pre_ext_cmd_plist = dl->pre_cmd->cmd_dma; + dl->extended->pre_ext_cmd_qty = dl->pre_cmd->num_cmds; + dl->extended->flags |= VSP1_DLH_EXT_PRE_CMD_EXEC; + + vsp1_dl_ext_cmd_fill_header(dl->pre_cmd); + } + + if (dl->post_cmd) { + dl->extended->pre_ext_cmd_plist = dl->post_cmd->cmd_dma; + dl->extended->pre_ext_cmd_qty = dl->post_cmd->num_cmds; + dl->extended->flags |= VSP1_DLH_EXT_POST_CMD_EXEC; + + vsp1_dl_ext_cmd_fill_header(dl->pre_cmd); + } } static bool vsp1_dl_list_hw_update_pending(struct vsp1_dl_manager *dlm) @@ -715,14 +777,20 @@ bool vsp1_dlm_irq_frame_end(struct vsp1_dl_manager *dlm) } /* Hardware Setup */ -void vsp1_dlm_setup(struct vsp1_device *vsp1) +void
[PATCH v2 11/11] drm: rcar-du: Support interlaced video output through vsp1
Use the newly exposed VSP1 interface to enable interlaced frame support through the VSP1 lif pipelines. Signed-off-by: Kieran Bingham--- drivers/gpu/drm/rcar-du/rcar_du_crtc.c | 1 + drivers/gpu/drm/rcar-du/rcar_du_vsp.c | 3 +++ 2 files changed, 4 insertions(+) diff --git a/drivers/gpu/drm/rcar-du/rcar_du_crtc.c b/drivers/gpu/drm/rcar-du/rcar_du_crtc.c index 5685d5af6998..9854d9deb944 100644 --- a/drivers/gpu/drm/rcar-du/rcar_du_crtc.c +++ b/drivers/gpu/drm/rcar-du/rcar_du_crtc.c @@ -248,6 +248,7 @@ static void rcar_du_crtc_set_display_timing(struct rcar_du_crtc *rcrtc) /* Signal polarities */ value = ((mode->flags & DRM_MODE_FLAG_PVSYNC) ? DSMR_VSL : 0) | ((mode->flags & DRM_MODE_FLAG_PHSYNC) ? DSMR_HSL : 0) + | ((mode->flags & DRM_MODE_FLAG_INTERLACE) ? DSMR_ODEV : 0) | DSMR_DIPM_DISP | DSMR_CSPM; rcar_du_crtc_write(rcrtc, DSMR, value); diff --git a/drivers/gpu/drm/rcar-du/rcar_du_vsp.c b/drivers/gpu/drm/rcar-du/rcar_du_vsp.c index 2c260c33840b..5e47daef8bd2 100644 --- a/drivers/gpu/drm/rcar-du/rcar_du_vsp.c +++ b/drivers/gpu/drm/rcar-du/rcar_du_vsp.c @@ -178,6 +178,9 @@ static void rcar_du_vsp_plane_setup(struct rcar_du_vsp_plane *plane) }; unsigned int i; + cfg.interlaced = !!(plane->plane.state->crtc->mode.flags + & DRM_MODE_FLAG_INTERLACE); + cfg.src.left = state->state.src.x1 >> 16; cfg.src.top = state->state.src.y1 >> 16; cfg.src.width = drm_rect_width(>state.src) >> 16; -- git-series 0.9.1
[PATCH v2 07/11] media: vsp1: Use header display lists for all WPF outputs linked to the DU
Header mode display lists are now supported on all WPF outputs. To support extended headers and auto-fld capabilities for interlaced mode handling only header mode display lists can be used. Disable the headerless display list configuration, and remove the dead code. Signed-off-by: Kieran Bingham--- drivers/media/platform/vsp1/vsp1_dl.c | 107 ++- 1 file changed, 27 insertions(+), 80 deletions(-) diff --git a/drivers/media/platform/vsp1/vsp1_dl.c b/drivers/media/platform/vsp1/vsp1_dl.c index 680eedb6fc9f..5f5706f8a84c 100644 --- a/drivers/media/platform/vsp1/vsp1_dl.c +++ b/drivers/media/platform/vsp1/vsp1_dl.c @@ -98,7 +98,7 @@ struct vsp1_dl_body_pool { * struct vsp1_dl_list - Display list * @list: entry in the display list manager lists * @dlm: the display list manager - * @header: display list header, NULL for headerless lists + * @header: display list header * @dma: DMA address for the header * @body0: first display list body * @bodies: list of extra display list bodies @@ -119,15 +119,9 @@ struct vsp1_dl_list { struct list_head chain; }; -enum vsp1_dl_mode { - VSP1_DL_MODE_HEADER, - VSP1_DL_MODE_HEADERLESS, -}; - /** * struct vsp1_dl_manager - Display List manager * @index: index of the related WPF - * @mode: display list operation mode (header or headerless) * @singleshot: execute the display list in single-shot mode * @vsp1: the VSP1 device * @lock: protects the free, active, queued, pending and gc_bodies lists @@ -139,7 +133,6 @@ enum vsp1_dl_mode { */ struct vsp1_dl_manager { unsigned int index; - enum vsp1_dl_mode mode; bool singleshot; struct vsp1_device *vsp1; @@ -320,6 +313,7 @@ static struct vsp1_dl_list *vsp1_dl_list_alloc(struct vsp1_dl_manager *dlm, struct vsp1_dl_body_pool *pool) { struct vsp1_dl_list *dl; + size_t header_offset; dl = kzalloc(sizeof(*dl), GFP_KERNEL); if (!dl) @@ -332,16 +326,15 @@ static struct vsp1_dl_list *vsp1_dl_list_alloc(struct vsp1_dl_manager *dlm, dl->body0 = vsp1_dl_body_get(pool); if (!dl->body0) return NULL; - if (dlm->mode == VSP1_DL_MODE_HEADER) { - size_t header_offset = dl->body0->max_entries -* sizeof(*dl->body0->entries); - dl->header = ((void *)dl->body0->entries) + header_offset; - dl->dma = dl->body0->dma + header_offset; + header_offset = dl->body0->max_entries +* sizeof(*dl->body0->entries); - memset(dl->header, 0, sizeof(*dl->header)); - dl->header->lists[0].addr = dl->body0->dma; - } + dl->header = ((void *)dl->body0->entries) + header_offset; + dl->dma = dl->body0->dma + header_offset; + + memset(dl->header, 0, sizeof(*dl->header)); + dl->header->lists[0].addr = dl->body0->dma; return dl; } @@ -473,16 +466,9 @@ struct vsp1_dl_body *vsp1_dl_list_get_body0(struct vsp1_dl_list *dl) * * The reference must be explicitly released by a call to vsp1_dl_body_put() * when the body isn't needed anymore. - * - * Additional bodies are only usable for display lists in header mode. - * Attempting to add a body to a header-less display list will return an error. */ int vsp1_dl_list_add_body(struct vsp1_dl_list *dl, struct vsp1_dl_body *dlb) { - /* Multi-body lists are only available in header mode. */ - if (dl->dlm->mode != VSP1_DL_MODE_HEADER) - return -EINVAL; - refcount_inc(>refcnt); list_add_tail(>list, >bodies); @@ -503,17 +489,10 @@ int vsp1_dl_list_add_body(struct vsp1_dl_list *dl, struct vsp1_dl_body *dlb) * Adding a display list to a chain passes ownership of the display list to * the head display list item. The chain is released when the head dl item is * put back with __vsp1_dl_list_put(). - * - * Chained display lists are only usable in header mode. Attempts to add a - * display list to a chain in header-less mode will return an error. */ int vsp1_dl_list_add_chain(struct vsp1_dl_list *head, struct vsp1_dl_list *dl) { - /* Chained lists are only available in header mode. */ - if (head->dlm->mode != VSP1_DL_MODE_HEADER) - return -EINVAL; - head->has_chain = true; list_add_tail(>chain, >chain); return 0; @@ -581,17 +560,10 @@ static bool vsp1_dl_list_hw_update_pending(struct vsp1_dl_manager *dlm) return false; /* -* Check whether the VSP1 has taken the update. In headerless mode the -* hardware indicates this by clearing the UPD bit in the DL_BODY_SIZE -* register, and in header mode by clearing the UPDHDR bit in the CMD -* register. +* Check whether the VSP1 has taken the update. In header mode
[PATCH v2 05/11] media: vsp1: Clean up DLM objects on error
If there is an error allocating a display list within a DLM object the existing display lists are not free'd, and neither is the DL body pool. Use the existing vsp1_dlm_destroy() function to clean up on error. Signed-off-by: Kieran Bingham--- drivers/media/platform/vsp1/vsp1_dl.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/media/platform/vsp1/vsp1_dl.c b/drivers/media/platform/vsp1/vsp1_dl.c index 310ce81cd724..680eedb6fc9f 100644 --- a/drivers/media/platform/vsp1/vsp1_dl.c +++ b/drivers/media/platform/vsp1/vsp1_dl.c @@ -831,8 +831,10 @@ struct vsp1_dl_manager *vsp1_dlm_create(struct vsp1_device *vsp1, struct vsp1_dl_list *dl; dl = vsp1_dl_list_alloc(dlm, dlm->pool); - if (!dl) + if (!dl) { + vsp1_dlm_destroy(dlm); return NULL; + } list_add_tail(>list, >free); } -- git-series 0.9.1
[PATCH v2 02/11] media: vsp1: Remove packed attributes from aligned structures
The use of the packed attribute can cause a performance penalty for all accesses to the struct members, as the compiler will assume that the structure has the potential to have an unaligned base. These structures are all correctly aligned and contain no holes, thus the attribute is redundant and negatively impacts performance, so we remove the attributes entirely. Signed-off-by: Kieran Bingham--- v2 - Remove attributes entirely drivers/media/platform/vsp1/vsp1_dl.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/media/platform/vsp1/vsp1_dl.c b/drivers/media/platform/vsp1/vsp1_dl.c index 37e2c984fbf3..85795b55a357 100644 --- a/drivers/media/platform/vsp1/vsp1_dl.c +++ b/drivers/media/platform/vsp1/vsp1_dl.c @@ -29,19 +29,19 @@ struct vsp1_dl_header_list { u32 num_bytes; u32 addr; -} __attribute__((__packed__)); +}; struct vsp1_dl_header { u32 num_lists; struct vsp1_dl_header_list lists[8]; u32 next_header; u32 flags; -} __attribute__((__packed__)); +}; struct vsp1_dl_entry { u32 addr; u32 data; -} __attribute__((__packed__)); +}; /** * struct vsp1_dl_body - Display list body -- git-series 0.9.1
[PATCH v2 01/11] media: vsp1: drm: Fix minor grammar error
The pixel format is 'unsupported'. Fix the small debug message which incorrectly declares this. Signed-off-by: Kieran Bingham--- drivers/media/platform/vsp1/vsp1_drm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/media/platform/vsp1/vsp1_drm.c b/drivers/media/platform/vsp1/vsp1_drm.c index 3c8b1952799d..0459b970e9da 100644 --- a/drivers/media/platform/vsp1/vsp1_drm.c +++ b/drivers/media/platform/vsp1/vsp1_drm.c @@ -363,7 +363,7 @@ int vsp1_du_atomic_update(struct device *dev, unsigned int pipe_index, */ fmtinfo = vsp1_get_format_info(vsp1, cfg->pixelformat); if (!fmtinfo) { - dev_dbg(vsp1->dev, "Unsupport pixel format %08x for RPF\n", + dev_dbg(vsp1->dev, "Unsupported pixel format %08x for RPF\n", cfg->pixelformat); return -EINVAL; } -- git-series 0.9.1
[PATCH v2 04/11] media: vsp1: Remove unused display list structure field
The vsp1 reference in the vsp1_dl_body structure is not used. Remove it. Signed-off-by: Kieran Bingham--- drivers/media/platform/vsp1/vsp1_dl.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/media/platform/vsp1/vsp1_dl.c b/drivers/media/platform/vsp1/vsp1_dl.c index 8162f4ce66eb..310ce81cd724 100644 --- a/drivers/media/platform/vsp1/vsp1_dl.c +++ b/drivers/media/platform/vsp1/vsp1_dl.c @@ -48,7 +48,6 @@ struct vsp1_dl_entry { * @list: entry in the display list list of bodies * @free: entry in the pool free body list * @pool: pool to which this body belongs - * @vsp1: the VSP1 device * @entries: array of entries * @dma: DMA address of the entries * @size: size of the DMA memory in bytes @@ -62,7 +61,6 @@ struct vsp1_dl_body { refcount_t refcnt; struct vsp1_dl_body_pool *pool; - struct vsp1_device *vsp1; struct vsp1_dl_entry *entries; dma_addr_t dma; -- git-series 0.9.1
Re: [PATCH 1/3] rcar-vin: remove duplicated check of state in irq handler
Hi Kieran, Thanks for your feedback. On 2018-03-13 17:42:25 +0100, Kieran Bingham wrote: > Hi Niklas, > > Thanks for the patch series :) - I've been looking forward to seeing this one > ! > > On 10/03/18 01:09, Niklas Söderlund wrote: > > This is an error from when the driver where converted from soc-camera. > > There is absolutely no gain to check the state variable two times to be > > extra sure if the hardware is stopped. > > I'll not say this isn't a redundant check ... but isn't the check against two > different states, and thus the remaining check doesn't actually catch the case > now where state == STOPPED ? Thanks for noticing this, you are correct. I think I need to refresh my glasses subscription after missing this :-) > > (Perhaps state != RUNNING would be better ?, but I haven't checked the rest of > the code) I will respin this in a v2 and either use state != RUNNING or at least combine the two checks to prevent future embarrassing mistakes like this. > > -- > Kieran > > > > > > Signed-off-by: Niklas Söderlund> > --- > > drivers/media/platform/rcar-vin/rcar-dma.c | 6 -- > > 1 file changed, 6 deletions(-) > > > > diff --git a/drivers/media/platform/rcar-vin/rcar-dma.c > > b/drivers/media/platform/rcar-vin/rcar-dma.c > > index 23fdff7a7370842e..b4be75d5009080f7 100644 > > --- a/drivers/media/platform/rcar-vin/rcar-dma.c > > +++ b/drivers/media/platform/rcar-vin/rcar-dma.c > > @@ -916,12 +916,6 @@ static irqreturn_t rvin_irq(int irq, void *data) > > rvin_ack_interrupt(vin); > > handled = 1; > > > > - /* Nothing to do if capture status is 'STOPPED' */ > > - if (vin->state == STOPPED) { > > - vin_dbg(vin, "IRQ while state stopped\n"); > > - goto done; > > - } > > - > > /* Nothing to do if capture status is 'STOPPING' */ > > if (vin->state == STOPPING) { > > vin_dbg(vin, "IRQ while state stopping\n"); > > -- Regards, Niklas Söderlund
[PATCH v2 00/11] R-Car DU Interlaced support through VSP1
The Gen3 R-Car DU devices make use of the VSP to handle frame processing. In this series we implement support for handling interlaced pipelines by using the auto-fld feature of the VSP hardware. The implementation is preceded by some cleanup work and refactoring, through patches 1 to 6. These are trivial and could be collected earlier and independently if this series requires further revisions. Patch 7 makes a key distinctive change to remove all existing support for headerless display lists throughout the VSP1 driver, and ensures that all pipelines use the same code path. This simplifies the code and reduces opportunity for untested code paths to exist. Patches 8, 9 and 10 implement the relevant support in the VSP1 driver, before patch 11 finally enables the feature through the drm R-Car DU driver. This series is based upon my previous TLB optimise and body rework (v7), and is available from the following URL: git://git.kernel.org/pub/scm/linux/kernel/git/kbingham/rcar.git tags/vsp1/du/interlaced/v2 ChangeLog: v2: - media: vsp1: use kernel __packed for structures became: media: vsp1: Remove packed attributes from aligned structures - media: vsp1: Add support for extended display list headers - No longer declares structs __packed - media: vsp1: Provide support for extended command pools - Fix spelling typo in commit message - constify, and staticify the instantiation of vsp1_extended_commands - s/autfld_cmds/autofld_cmds/ - staticify cmd pool functions (Thanks kbuild-bot) - media: vsp1: Support Interlaced display pipelines - fix erroneous BIT value which enabled interlaced - fix field handling at frame_end interrupt Kieran Bingham (11): media: vsp1: drm: Fix minor grammar error media: vsp1: Remove packed attributes from aligned structures media: vsp1: Rename dl_child to dl_next media: vsp1: Remove unused display list structure field media: vsp1: Clean up DLM objects on error media: vsp1: Provide VSP1 feature helper macro media: vsp1: Use header display lists for all WPF outputs linked to the DU media: vsp1: Add support for extended display list headers media: vsp1: Provide support for extended command pools media: vsp1: Support Interlaced display pipelines drm: rcar-du: Support interlaced video output through vsp1 drivers/gpu/drm/rcar-du/rcar_du_crtc.c | 1 +- drivers/gpu/drm/rcar-du/rcar_du_vsp.c | 3 +- drivers/media/platform/vsp1/vsp1.h | 3 +- drivers/media/platform/vsp1/vsp1_dl.c | 406 +++-- drivers/media/platform/vsp1/vsp1_dl.h | 32 +- drivers/media/platform/vsp1/vsp1_drm.c | 13 +- drivers/media/platform/vsp1/vsp1_drv.c | 23 +- drivers/media/platform/vsp1/vsp1_regs.h | 6 +- drivers/media/platform/vsp1/vsp1_rpf.c | 72 +++- drivers/media/platform/vsp1/vsp1_rwpf.h | 1 +- drivers/media/platform/vsp1/vsp1_wpf.c | 6 +- include/media/vsp1.h| 1 +- 12 files changed, 455 insertions(+), 112 deletions(-) base-commit: 397eb3811ec096d0ceefa1dbea2d0ae68feb0587 -- git-series 0.9.1
[PATCH v2 03/11] media: vsp1: Rename dl_child to dl_next
Both vsp1_dl_list_commit() and __vsp1_dl_list_put() walk the display list chain referencing the nodes as children, when in reality they are siblings. Update the terminology to 'dl_next' to be consistent with the vsp1_video_pipeline_run() usage. Signed-off-by: Kieran Bingham--- drivers/media/platform/vsp1/vsp1_dl.c | 14 +++--- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/drivers/media/platform/vsp1/vsp1_dl.c b/drivers/media/platform/vsp1/vsp1_dl.c index 85795b55a357..8162f4ce66eb 100644 --- a/drivers/media/platform/vsp1/vsp1_dl.c +++ b/drivers/media/platform/vsp1/vsp1_dl.c @@ -400,7 +400,7 @@ struct vsp1_dl_list *vsp1_dl_list_get(struct vsp1_dl_manager *dlm) /* This function must be called with the display list manager lock held.*/ static void __vsp1_dl_list_put(struct vsp1_dl_list *dl) { - struct vsp1_dl_list *dl_child; + struct vsp1_dl_list *dl_next; if (!dl) return; @@ -410,8 +410,8 @@ static void __vsp1_dl_list_put(struct vsp1_dl_list *dl) * hardware operation. */ if (dl->has_chain) { - list_for_each_entry(dl_child, >chain, chain) - __vsp1_dl_list_put(dl_child); + list_for_each_entry(dl_next, >chain, chain) + __vsp1_dl_list_put(dl_next); } dl->has_chain = false; @@ -667,17 +667,17 @@ static void vsp1_dl_list_commit_singleshot(struct vsp1_dl_list *dl) void vsp1_dl_list_commit(struct vsp1_dl_list *dl) { struct vsp1_dl_manager *dlm = dl->dlm; - struct vsp1_dl_list *dl_child; + struct vsp1_dl_list *dl_next; unsigned long flags; if (dlm->mode == VSP1_DL_MODE_HEADER) { /* Fill the header for the head and chained display lists. */ vsp1_dl_list_fill_header(dl, list_empty(>chain)); - list_for_each_entry(dl_child, >chain, chain) { - bool last = list_is_last(_child->chain, >chain); + list_for_each_entry(dl_next, >chain, chain) { + bool last = list_is_last(_next->chain, >chain); - vsp1_dl_list_fill_header(dl_child, last); + vsp1_dl_list_fill_header(dl_next, last); } } -- git-series 0.9.1
Re: [PATCH v8 03/13] [media] omap3isp: group device capabilities
On 03/09/2018 09:49 AM, Gustavo Padovan wrote: > From: Gustavo Padovan> > Instead of putting V4L2_CAP_STREAMING everywhere, set device_caps > earlier with this value. > > Signed-off-by: Gustavo Padovan > --- > drivers/media/platform/omap3isp/ispvideo.c | 9 + > 1 file changed, 5 insertions(+), 4 deletions(-) > > diff --git a/drivers/media/platform/omap3isp/ispvideo.c > b/drivers/media/platform/omap3isp/ispvideo.c > index a751c89a3ea8..b4d4ef926749 100644 > --- a/drivers/media/platform/omap3isp/ispvideo.c > +++ b/drivers/media/platform/omap3isp/ispvideo.c > @@ -658,13 +658,14 @@ isp_video_querycap(struct file *file, void *fh, struct > v4l2_capability *cap) > strlcpy(cap->card, video->video.name, sizeof(cap->card)); > strlcpy(cap->bus_info, "media", sizeof(cap->bus_info)); > > - cap->capabilities = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_VIDEO_OUTPUT > - | V4L2_CAP_STREAMING | V4L2_CAP_DEVICE_CAPS; > + cap->device_caps = V4L2_CAP_STREAMING; > + cap->capabilities = cap->device_caps | V4L2_CAP_VIDEO_CAPTURE | > + V4L2_CAP_VIDEO_OUTPUT | V4L2_CAP_DEVICE_CAPS; Same as in patch 1: I'd move this down to after the if-else. It makes more sense that way. > > if (video->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) > - cap->device_caps = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING; > + cap->device_caps |= V4L2_CAP_VIDEO_CAPTURE; > else > - cap->device_caps = V4L2_CAP_VIDEO_OUTPUT | V4L2_CAP_STREAMING; > + cap->device_caps |= V4L2_CAP_VIDEO_OUTPUT; > > return 0; > } > Regards, Hans
Re: [PATCH v8 04/13] [media] vb2: add is_unordered callback for drivers
On 03/09/2018 09:49 AM, Gustavo Padovan wrote: > From: Gustavo Padovan> > Explicit synchronization benefits a lot from ordered queues, they fit > better in a pipeline with DRM for example so create a opt-in way for > drivers notify videobuf2 that the queue is unordered. > > Drivers don't need implement it if the queue is ordered. > > v2: - improve comments for is_unordered flag (Hans) > > v3: - make it bool (Hans) > - create vb2_ops_set_unordered() helper > > Signed-off-by: Gustavo Padovan > --- > drivers/media/common/videobuf2/videobuf2-v4l2.c | 6 ++ > include/media/videobuf2-core.h | 6 ++ > include/media/videobuf2-v4l2.h | 10 ++ > 3 files changed, 22 insertions(+) > > diff --git a/drivers/media/common/videobuf2/videobuf2-v4l2.c > b/drivers/media/common/videobuf2/videobuf2-v4l2.c > index 886a2d8d5c6c..68291ba8632d 100644 > --- a/drivers/media/common/videobuf2/videobuf2-v4l2.c > +++ b/drivers/media/common/videobuf2/videobuf2-v4l2.c > @@ -961,6 +961,12 @@ void vb2_ops_wait_finish(struct vb2_queue *vq) > } > EXPORT_SYMBOL_GPL(vb2_ops_wait_finish); > > +bool vb2_ops_set_unordered(struct vb2_queue *q) > +{ > + return true; > +} > +EXPORT_SYMBOL_GPL(vb2_ops_set_unordered); This should be called vb2_ops_is_unordered. The name after the vb2_ops_ prefix should match the op name (is_unordered). I also would add this to videobuf2-core.c since there is nothing V4L2 specific about this. > + > MODULE_DESCRIPTION("Driver helper framework for Video for Linux 2"); > MODULE_AUTHOR("Pawel Osciak , Marek Szyprowski"); > MODULE_LICENSE("GPL"); > diff --git a/include/media/videobuf2-core.h b/include/media/videobuf2-core.h > index 5b6c541e4e1b..46a9e674f7e1 100644 > --- a/include/media/videobuf2-core.h > +++ b/include/media/videobuf2-core.h > @@ -370,6 +370,10 @@ struct vb2_buffer { > * callback by calling vb2_buffer_done() with either > * %VB2_BUF_STATE_DONE or %VB2_BUF_STATE_ERROR; may use > * vb2_wait_for_all_buffers() function > + * @is_unordered:tell if the queue is unordered, i.e. buffers can be > + * dequeued in a different order from how they were queued. > + * The default is assumed to be ordered and this function > + * only needs to be implemented for unordered queues. > * @buf_queue: passes buffer vb to the driver; driver may start > * hardware operation on this buffer; driver should give > * the buffer back by calling vb2_buffer_done() function; > @@ -393,6 +397,7 @@ struct vb2_ops { > > int (*start_streaming)(struct vb2_queue *q, unsigned int count); > void (*stop_streaming)(struct vb2_queue *q); > + bool (*is_unordered)(struct vb2_queue *q); > > void (*buf_queue)(struct vb2_buffer *vb); > }; > @@ -566,6 +571,7 @@ struct vb2_queue { > u32 cnt_wait_finish; > u32 cnt_start_streaming; > u32 cnt_stop_streaming; > + u32 cnt_is_unordered; > #endif > }; > > diff --git a/include/media/videobuf2-v4l2.h b/include/media/videobuf2-v4l2.h > index 3d5e2d739f05..9de3c887c875 100644 > --- a/include/media/videobuf2-v4l2.h > +++ b/include/media/videobuf2-v4l2.h > @@ -291,4 +291,14 @@ void vb2_ops_wait_prepare(struct vb2_queue *vq); > */ > void vb2_ops_wait_finish(struct vb2_queue *vq); > > +/** > + * vb2_ops_set_unordered - helper function to mark queue as unordered > + * > + * @vq: pointer to vb2_queue > + * > + * This helper just return true to notify that the driver can't deal with return -> returns > + * ordered queues. > + */ > +bool vb2_ops_set_unordered(struct vb2_queue *q); > + > #endif /* _MEDIA_VIDEOBUF2_V4L2_H */ > Regards, Hans
Re: [PATCH v8 11/13] [media] v4l: introduce the fences capability
On 03/09/2018 09:49 AM, Gustavo Padovan wrote: > From: Gustavo Padovan> > Drivers capable of using fences (vb2 drivers) should report the > V4L2_CAP_FENCES to userspace, so add this flag to the uapi. > > Signed-off-by: Gustavo Padovan > --- > Documentation/media/uapi/v4l/vidioc-querycap.rst | 3 +++ > include/uapi/linux/videodev2.h | 1 + > 2 files changed, 4 insertions(+) > > diff --git a/Documentation/media/uapi/v4l/vidioc-querycap.rst > b/Documentation/media/uapi/v4l/vidioc-querycap.rst > index 66fb1b3d6e6e..414016065309 100644 > --- a/Documentation/media/uapi/v4l/vidioc-querycap.rst > +++ b/Documentation/media/uapi/v4l/vidioc-querycap.rst > @@ -254,6 +254,9 @@ specification the ioctl returns an ``EINVAL`` error code. > * - ``V4L2_CAP_TOUCH`` >- 0x1000 >- This is a touch device. > +* - ``V4L2_CAP_FENCES`` > + - 0x2000 > + - The device support explicit synchronization. support -> supports > * - ``V4L2_CAP_DEVICE_CAPS`` >- 0x8000 >- The driver fills the ``device_caps`` field. This capability can > diff --git a/include/uapi/linux/videodev2.h b/include/uapi/linux/videodev2.h > index 2d424aebdd1e..db58204e346e 100644 > --- a/include/uapi/linux/videodev2.h > +++ b/include/uapi/linux/videodev2.h > @@ -460,6 +460,7 @@ struct v4l2_capability { > #define V4L2_CAP_STREAMING 0x0400 /* streaming I/O ioctls > */ > > #define V4L2_CAP_TOUCH 0x1000 /* Is a touch device */ > +#define V4L2_CAP_FENCES 0x2000 /* Supports explicit > synchronization */ > > #define V4L2_CAP_DEVICE_CAPS0x8000 /* sets device > capabilities field */ > > Regards, Hans
[PATCH v2 1/2] rcar-vin: allocate a scratch buffer at stream start
Before starting a capture, allocate a scratch buffer which can be used by the driver to give to the hardware if no buffers are available from userspace. The buffer is not used in this patch but prepares for future refactoring where the scratch buffer can be used to avoid the need to fallback on single capture mode if userspace can't queue buffers as fast as the VIN driver consumes them. Signed-off-by: Niklas SöderlundReviewed-by: Jacopo Mondi Reviewed-by: Kieran Bingham --- drivers/media/platform/rcar-vin/rcar-dma.c | 19 +++ drivers/media/platform/rcar-vin/rcar-vin.h | 4 2 files changed, 23 insertions(+) diff --git a/drivers/media/platform/rcar-vin/rcar-dma.c b/drivers/media/platform/rcar-vin/rcar-dma.c index 23fdff7a7370842e..1f91b056188ebdb3 100644 --- a/drivers/media/platform/rcar-vin/rcar-dma.c +++ b/drivers/media/platform/rcar-vin/rcar-dma.c @@ -1076,6 +1076,17 @@ static int rvin_start_streaming(struct vb2_queue *vq, unsigned int count) unsigned long flags; int ret; + /* Allocate scratch buffer. */ + vin->scratch = dma_alloc_coherent(vin->dev, vin->format.sizeimage, + >scratch_phys, GFP_KERNEL); + if (!vin->scratch) { + spin_lock_irqsave(>qlock, flags); + return_all_buffers(vin, VB2_BUF_STATE_QUEUED); + spin_unlock_irqrestore(>qlock, flags); + vin_err(vin, "Failed to allocate scratch buffer\n"); + return -ENOMEM; + } + sd = vin_to_source(vin); v4l2_subdev_call(sd, video, s_stream, 1); @@ -1091,6 +1102,10 @@ static int rvin_start_streaming(struct vb2_queue *vq, unsigned int count) spin_unlock_irqrestore(>qlock, flags); + if (ret) + dma_free_coherent(vin->dev, vin->format.sizeimage, vin->scratch, + vin->scratch_phys); + return ret; } @@ -1141,6 +1156,10 @@ static void rvin_stop_streaming(struct vb2_queue *vq) /* disable interrupts */ rvin_disable_interrupts(vin); + + /* Free scratch buffer. */ + dma_free_coherent(vin->dev, vin->format.sizeimage, vin->scratch, + vin->scratch_phys); } static const struct vb2_ops rvin_qops = { diff --git a/drivers/media/platform/rcar-vin/rcar-vin.h b/drivers/media/platform/rcar-vin/rcar-vin.h index 5382078143fb3869..00b405f78d0912c9 100644 --- a/drivers/media/platform/rcar-vin/rcar-vin.h +++ b/drivers/media/platform/rcar-vin/rcar-vin.h @@ -102,6 +102,8 @@ struct rvin_graph_entity { * * @lock: protects @queue * @queue: vb2 buffers queue + * @scratch: cpu address for scratch buffer + * @scratch_phys: physical address of the scratch buffer * * @qlock: protects @queue_buf, @buf_list, @continuous, @sequence * @state @@ -130,6 +132,8 @@ struct rvin_dev { struct mutex lock; struct vb2_queue queue; + void *scratch; + dma_addr_t scratch_phys; spinlock_t qlock; struct vb2_v4l2_buffer *queue_buf[HW_BUFFER_NUM]; -- 2.16.2
[PATCH v2 0/2] rcar-vin: always run in continues mode
Hi, This series reworks the R-Car VIN driver to only run using its continues capture mode. This improves performance a lot when userspace struggles to keep up and queue buffers as fast as the VIN driver consumes them. The solution to always be able to run in continues is to introduce a scratch buffer inside the VIN driver which it can pad the hardware capture buffer ring with if it have no buffer from userspace. Using this scratch buffer allows the driver to not need to stop capturing when it run out of buffers and then restart it once it have more buffers. Patch 1/2 adds the allocation of the scratch buffer. And patch 2/2 drops the single capture mode in favor of always running in continues capture mode and the scratch buffer. The series is based on top of the latest media-tree master branch and can be fetched from. git://git.ragnatech.se/linux v4l2/next/vin/mode-v2 It is tested on R-Car Koelsch Gen2 board using the onboard HDMI and CVBS inputs. The test application v4l2-compliance pass for both inputs without issues or warnings. A slight adaption of these patches to the pending VIN Gen3 patches have been tested with great improvement in capture speed for buffer strained situations and no regressions in the vin-tests suite. * Changes since v1 - Dropped first patch in series as it removed a correct check due to my poor reading skills. - Corrected spelling in commit messages and comments. - Added review tags from Jacopo and Kieran, thanks! Niklas Söderlund (2): rcar-vin: allocate a scratch buffer at stream start rcar-vin: use scratch buffer and always run in continuous mode drivers/media/platform/rcar-vin/rcar-dma.c | 206 ++--- drivers/media/platform/rcar-vin/rcar-vin.h | 10 +- 2 files changed, 75 insertions(+), 141 deletions(-) -- 2.16.2
Re: [PATCH v8 06/13] [media] cobalt: add .is_unordered() for cobalt
On 03/09/2018 09:49 AM, Gustavo Padovan wrote: > From: Gustavo Padovan> > The cobalt driver may reorder the capture buffers so we need to report > it as such. > > v2: - use vb2_ops_set_unordered() helper > > Signed-off-by: Gustavo Padovan > --- > drivers/media/pci/cobalt/cobalt-v4l2.c | 1 + > 1 file changed, 1 insertion(+) > > diff --git a/drivers/media/pci/cobalt/cobalt-v4l2.c > b/drivers/media/pci/cobalt/cobalt-v4l2.c > index e2a4c705d353..6b6611a0e190 100644 > --- a/drivers/media/pci/cobalt/cobalt-v4l2.c > +++ b/drivers/media/pci/cobalt/cobalt-v4l2.c > @@ -430,6 +430,7 @@ static const struct vb2_ops cobalt_qops = { > .stop_streaming = cobalt_stop_streaming, > .wait_prepare = vb2_ops_wait_prepare, > .wait_finish = vb2_ops_wait_finish, > + .is_unordered = vb2_ops_set_unordered, > }; If you do this, then you should also set the UNORDERED format flag for all formats used by cobalt. Regards, Hans > > /* V4L2 ioctls */ >
Re: [PATCH v8 08/13] [media] vb2: add explicit fence user API
On 03/09/2018 09:49 AM, Gustavo Padovan wrote: > From: Gustavo Padovan> > Turn the reserved2 field into fence_fd that we will use to send > an in-fence to the kernel or return an out-fence from the kernel to > userspace. > > Two new flags were added, V4L2_BUF_FLAG_IN_FENCE, that should be used > when sending a fence to the kernel to be waited on, and > V4L2_BUF_FLAG_OUT_FENCE, to ask the kernel to give back an out-fence. > > v6: - big improvement on doc (Hans Verkuil) > > v5: > - keep using reserved2 field for cpia2 > - set fence_fd to 0 for now, for compat with userspace(Mauro) > > v4: > - make it a union with reserved2 and fence_fd (Hans Verkuil) > > v3: > - make the out_fence refer to the current buffer (Hans Verkuil) > > v2: add documentation > > Signed-off-by: Gustavo Padovan > --- > Documentation/media/uapi/v4l/buffer.rst | 45 > +++-- > drivers/media/common/videobuf2/videobuf2-v4l2.c | 2 +- > drivers/media/v4l2-core/v4l2-compat-ioctl32.c | 4 +-- > include/uapi/linux/videodev2.h | 7 +++- > 4 files changed, 51 insertions(+), 7 deletions(-) > > diff --git a/Documentation/media/uapi/v4l/buffer.rst > b/Documentation/media/uapi/v4l/buffer.rst > index e2c85ddc990b..49273026740f 100644 > --- a/Documentation/media/uapi/v4l/buffer.rst > +++ b/Documentation/media/uapi/v4l/buffer.rst > @@ -301,10 +301,22 @@ struct v4l2_buffer > elements in the ``planes`` array. The driver will fill in the > actual number of valid elements in that array. > * - __u32 > - - ``reserved2`` > + - ``fence_fd`` >- > - - A place holder for future extensions. Drivers and applications > - must set this to 0. > + - Used to communicate fences file descriptors from userspace to kernel fences file descriptors -> a fence file descriptor > + and vice-versa. On :ref:`VIDIOC_QBUF ` when sending > + an in-fence for V4L2 to wait on, the ``V4L2_BUF_FLAG_IN_FENCE`` flag > must > + be used and this field set to the fence file descriptor of the in-fence Missing period at the end of this sentence. > + If the in-fence is not valid ` VIDIOC_QBUF`` returns an error. ` -> `` > + > +To get an out-fence back from V4L2 the ``V4L2_BUF_FLAG_OUT_FENCE`` > + must be set, the kernel will return the out-fence file descriptor on on -> in > + this field. If it fails to create the out-fence ``VIDIOC_QBUF` returns ` -> `` > +an error. > + > + In all other ioctls V4L2 sets this field to -1 if In all other -> For all other buffer > + ``V4L2_BUF_FLAG_IN_FENCE`` and/or ``V4L2_BUF_FLAG_OUT_FENCE`` are set, > + otherwise this field is set to 0 for backward compatibility. > * - __u32 >- ``reserved`` >- > @@ -648,6 +660,33 @@ Buffer Flags >- Start Of Exposure. The buffer timestamp has been taken when the > exposure of the frame has begun. This is only valid for the > ``V4L2_BUF_TYPE_VIDEO_CAPTURE`` buffer type. > +* .. _`V4L2-BUF-FLAG-IN-FENCE`: > + > + - ``V4L2_BUF_FLAG_IN_FENCE`` > + - 0x0020 > + - Ask V4L2 to wait on the fence passed in the ``fence_fd`` field. The > + buffer won't be queued to the driver until the fence signals. The order > + in which buffers are queued is guaranteed to be preserved, so any > + buffers queued after this buffer will also be blocked until this fence > + signals. This flag must be set before calling ``VIDIOC_QBUF``. For > + other ioctls the driver just report the value of the flag. report -> reports > + > +If the fence signals the flag is cleared and not reported anymore. > + If the fence is not valid ``VIDIOC_QBUF`` returns an error. > + > + > +* .. _`V4L2-BUF-FLAG-OUT-FENCE`: > + > + - ``V4L2_BUF_FLAG_OUT_FENCE`` > + - 0x0040 > + - Request for a fence to be attached to the buffer. The driver will > fill > + in the out-fence fd in the ``fence_fd`` field when :ref:`VIDIOC_QBUF > + ` returns. This flag must be set before calling > + ``VIDIOC_QBUF``. For other ioctls the driver just report the value of report -> reports > + the flag. > + > +If the creation of the out-fence fails ``VIDIOC_QBUF`` returns an double spaces before and after 'out-fence'. > + error. > > > > diff --git a/drivers/media/common/videobuf2/videobuf2-v4l2.c > b/drivers/media/common/videobuf2/videobuf2-v4l2.c > index 68291ba8632d..ad1e032c3bf5 100644 > --- a/drivers/media/common/videobuf2/videobuf2-v4l2.c > +++ b/drivers/media/common/videobuf2/videobuf2-v4l2.c > @@ -203,7 +203,7 @@ static void __fill_v4l2_buffer(struct vb2_buffer *vb, > void *pb) > b->timestamp = ns_to_timeval(vb->timestamp); > b->timecode = vbuf->timecode; > b->sequence = vbuf->sequence; > - b->reserved2 = 0; > + b->fence_fd = 0; > b->reserved = 0; >
Re: [PATCH v8 07/13] [media] vb2: mark codec drivers as unordered
On 03/09/2018 09:49 AM, Gustavo Padovan wrote: > From: Gustavo Padovan> > In preparation to have full support to explicit fence we are > marking codec as non-ordered preventively. It is easier and safer from an > uAPI point of view to move from unordered to ordered than the opposite. Same comment as for the cobalt driver: if you mark these drivers as unordered, shouldn't you mark the compressed formats as UNORDERED as well? Should we perhaps do this by default for compressed formats (except MJPEG) in v4l2-ioctl.c? Thus requiring drivers to clear the flag if they are actually ordered. > > Signed-off-by: Gustavo Padovan > --- > drivers/media/platform/coda/coda-common.c | 1 + > drivers/media/platform/exynos-gsc/gsc-m2m.c| 1 + > drivers/media/platform/exynos4-is/fimc-m2m.c | 1 + > drivers/media/platform/m2m-deinterlace.c | 1 + This is a deinterlaced, so this should be ordered. > drivers/media/platform/mtk-jpeg/mtk_jpeg_core.c| 1 + JPEG is ordered. > drivers/media/platform/mtk-mdp/mtk_mdp_m2m.c | 1 + > drivers/media/platform/mtk-vcodec/mtk_vcodec_dec.c | 1 + > drivers/media/platform/mtk-vcodec/mtk_vcodec_enc.c | 1 + > drivers/media/platform/mx2_emmaprp.c | 1 + I believe this is also not a codec, so ordered, > drivers/media/platform/qcom/venus/vdec.c | 1 + > drivers/media/platform/qcom/venus/venc.c | 1 + > drivers/media/platform/rcar_fdp1.c | 1 + > drivers/media/platform/rcar_jpu.c | 1 + I don't think these two R-Car drivers are codecs, so these would be ordered (the 2nd is a JPEG codec, not sure about the first one). > drivers/media/platform/rockchip/rga/rga-buf.c | 1 + Not a codec driver, this is ordered, > drivers/media/platform/s5p-g2d/g2d.c | 1 + Not sure about this one, I don't think it is a codec driver, > drivers/media/platform/s5p-jpeg/jpeg-core.c| 1 + MJPEG, so ordered, > drivers/media/platform/s5p-mfc/s5p_mfc_dec.c | 1 + > drivers/media/platform/s5p-mfc/s5p_mfc_enc.c | 1 + > drivers/media/platform/sh_veu.c| 1 + Not a codec, so ordered, > drivers/media/platform/sti/bdisp/bdisp-v4l2.c | 1 + > drivers/media/platform/ti-vpe/vpe.c| 1 + > drivers/media/platform/vim2m.c | 1 + Same for these three. Regards, Hans > 22 files changed, 22 insertions(+) > > diff --git a/drivers/media/platform/coda/coda-common.c > b/drivers/media/platform/coda/coda-common.c > index 04e35d70ce2e..6deb29fe6eb7 100644 > --- a/drivers/media/platform/coda/coda-common.c > +++ b/drivers/media/platform/coda/coda-common.c > @@ -1649,6 +1649,7 @@ static const struct vb2_ops coda_qops = { > .stop_streaming = coda_stop_streaming, > .wait_prepare = vb2_ops_wait_prepare, > .wait_finish= vb2_ops_wait_finish, > + .is_unordered = vb2_ops_set_unordered, > }; > > static int coda_s_ctrl(struct v4l2_ctrl *ctrl) > diff --git a/drivers/media/platform/exynos-gsc/gsc-m2m.c > b/drivers/media/platform/exynos-gsc/gsc-m2m.c > index e9ff27949a91..10c3e4659d38 100644 > --- a/drivers/media/platform/exynos-gsc/gsc-m2m.c > +++ b/drivers/media/platform/exynos-gsc/gsc-m2m.c > @@ -286,6 +286,7 @@ static const struct vb2_ops gsc_m2m_qops = { > .wait_finish = vb2_ops_wait_finish, > .stop_streaming = gsc_m2m_stop_streaming, > .start_streaming = gsc_m2m_start_streaming, > + .is_unordered= vb2_ops_set_unordered, > }; > > static int gsc_m2m_querycap(struct file *file, void *fh, > diff --git a/drivers/media/platform/exynos4-is/fimc-m2m.c > b/drivers/media/platform/exynos4-is/fimc-m2m.c > index a19f8b164a47..dfc487a582c0 100644 > --- a/drivers/media/platform/exynos4-is/fimc-m2m.c > +++ b/drivers/media/platform/exynos4-is/fimc-m2m.c > @@ -227,6 +227,7 @@ static const struct vb2_ops fimc_qops = { > .wait_finish = vb2_ops_wait_finish, > .stop_streaming = stop_streaming, > .start_streaming = start_streaming, > + .is_unordered= vb2_ops_set_unordered, > }; > > /* > diff --git a/drivers/media/platform/m2m-deinterlace.c > b/drivers/media/platform/m2m-deinterlace.c > index 1e4195144f39..35a0f45d2a51 100644 > --- a/drivers/media/platform/m2m-deinterlace.c > +++ b/drivers/media/platform/m2m-deinterlace.c > @@ -856,6 +856,7 @@ static const struct vb2_ops deinterlace_qops = { > .queue_setup = deinterlace_queue_setup, > .buf_prepare = deinterlace_buf_prepare, > .buf_queue = deinterlace_buf_queue, > + .is_unordered= vb2_ops_set_unordered, > }; > > static int queue_init(void *priv, struct vb2_queue *src_vq, > diff --git a/drivers/media/platform/mtk-jpeg/mtk_jpeg_core.c > b/drivers/media/platform/mtk-jpeg/mtk_jpeg_core.c > index 226f90886484..34a4b5b2e1b5 100644 > ---
cron job: media_tree daily build: ERRORS
This message is generated daily by a cron job that builds media_tree for the kernels and architectures in the list below. Results of the daily build of media_tree: date: Wed Mar 14 05:00:10 CET 2018 media-tree git hash:e68854a2588a923b31eebce348f8020374843f8e media_build git hash: 2a1900fddab68c7686e6b146ff91e02b32675fae v4l-utils git hash: 14ce03c18ef67aa7a3d5781f015be855fd43839c gcc version:i686-linux-gcc (GCC) 7.3.0 sparse version: v0.5.0-3994-g45eb2282 smatch version: v0.5.0-3994-g45eb2282 host hardware: x86_64 host os:4.14.0-3-amd64 linux-git-arm-at91: OK linux-git-arm-davinci: OK linux-git-arm-multi: WARNINGS linux-git-arm-pxa: OK linux-git-arm-stm32: OK linux-git-arm64: OK linux-git-blackfin-bf561: OK linux-git-i686: OK linux-git-m32r: OK linux-git-mips: OK linux-git-powerpc64: OK linux-git-sh: OK linux-git-x86_64: OK linux-2.6.36.4-i686: ERRORS linux-2.6.36.4-x86_64: ERRORS linux-2.6.37.6-i686: WARNINGS linux-2.6.37.6-x86_64: WARNINGS linux-2.6.38.8-i686: WARNINGS linux-2.6.38.8-x86_64: WARNINGS linux-2.6.39.4-i686: WARNINGS linux-2.6.39.4-x86_64: WARNINGS linux-3.0.60-i686: WARNINGS linux-3.0.60-x86_64: WARNINGS linux-3.1.10-i686: WARNINGS linux-3.1.10-x86_64: WARNINGS linux-3.2.98-i686: ERRORS linux-3.2.98-x86_64: ERRORS linux-3.3.8-i686: ERRORS linux-3.3.8-x86_64: ERRORS linux-3.4.27-i686: ERRORS linux-3.4.27-x86_64: ERRORS linux-3.5.7-i686: WARNINGS linux-3.5.7-x86_64: WARNINGS linux-3.6.11-i686: WARNINGS linux-3.6.11-x86_64: WARNINGS linux-3.7.4-i686: WARNINGS linux-3.7.4-x86_64: WARNINGS linux-3.8-i686: WARNINGS linux-3.8-x86_64: WARNINGS linux-3.9.2-i686: WARNINGS linux-3.9.2-x86_64: WARNINGS linux-3.10.1-i686: WARNINGS linux-3.10.1-x86_64: WARNINGS linux-3.11.1-i686: WARNINGS linux-3.11.1-x86_64: WARNINGS linux-3.12.67-i686: WARNINGS linux-3.12.67-x86_64: WARNINGS linux-3.13.11-i686: WARNINGS linux-3.13.11-x86_64: WARNINGS linux-3.14.9-i686: WARNINGS linux-3.14.9-x86_64: WARNINGS linux-3.15.2-i686: WARNINGS linux-3.15.2-x86_64: WARNINGS linux-3.16.53-i686: WARNINGS linux-3.16.53-x86_64: WARNINGS linux-3.17.8-i686: WARNINGS linux-3.17.8-x86_64: WARNINGS linux-3.18.93-i686: WARNINGS linux-3.18.93-x86_64: WARNINGS linux-3.19-i686: WARNINGS linux-3.19-x86_64: WARNINGS linux-4.0.9-i686: WARNINGS linux-4.0.9-x86_64: WARNINGS linux-4.1.49-i686: WARNINGS linux-4.1.49-x86_64: WARNINGS linux-4.2.8-i686: WARNINGS linux-4.2.8-x86_64: WARNINGS linux-4.3.6-i686: WARNINGS linux-4.3.6-x86_64: WARNINGS linux-4.4.115-i686: OK linux-4.4.115-x86_64: OK linux-4.5.7-i686: WARNINGS linux-4.5.7-x86_64: WARNINGS linux-4.6.7-i686: OK linux-4.6.7-x86_64: WARNINGS linux-4.7.5-i686: OK linux-4.7.5-x86_64: WARNINGS linux-4.8-i686: OK linux-4.8-x86_64: WARNINGS linux-4.9.80-i686: OK linux-4.9.80-x86_64: OK linux-4.10.14-i686: OK linux-4.10.14-x86_64: WARNINGS linux-4.11-i686: OK linux-4.11-x86_64: WARNINGS linux-4.12.1-i686: OK linux-4.12.1-x86_64: WARNINGS linux-4.13-i686: OK linux-4.13-x86_64: OK linux-4.14.17-i686: OK linux-4.14.17-x86_64: OK linux-4.15.2-i686: WARNINGS linux-4.15.2-x86_64: WARNINGS linux-4.16-rc1-i686: WARNINGS linux-4.16-rc1-x86_64: WARNINGS apps: WARNINGS spec-git: OK sparse: WARNINGS smatch: OK Detailed results are available here: http://www.xs4all.nl/~hverkuil/logs/Wednesday.log Full logs are available here: http://www.xs4all.nl/~hverkuil/logs/Wednesday.tar.bz2 The Media Infrastructure API from this daily build is here: http://www.xs4all.nl/~hverkuil/spec/index.html