davinci: VPIF: add DT support
v5 cover davinci: VPIF: add DT support
Prepare the groundwork for adding DT support for davinci VPIF drivers. This series does some fixups/cleanups and then adds the DT binding and DT compatible string matching for DT probing.
The controversial part from previous versions around async subdev parsing, and specifically hard-coding the input/output routing of subdevs, has been left out of this series. That part can be done as a follow-on step after agreement has been reached on the path forward. With this version, platforms can still use the VPIF capture/display drivers, but must provide platform_data for the subdevs and subdev routing.
Tested video capture to memory on da850-lcdk board using composite input.
Changes since v4:
- dropped controversial async subdev parsing support. That can be done as a follow-up step after the discussions have finalized on the right approach.
- DT binding Acked by DT maintainer (Rob H.)
- reworked locking fix (suggested by Laurent)
Changes since v3:
- move to a single VPIF node, DT binding updated accordingly
- misc fixes/updates based on reviews from Sakari
Changes since v2:
- DT binding doc: fix example to use correct compatible
Changes since v1:
- more specific compatible strings, based on SoC: ti,da850-vpif*
- fix locking bug when unlocking over subdev s_stream
Kevin Hilman (5):
[media] davinci: VPIF: fix module loading, init errors [media] davinci: vpif_capture: remove hard-coded I2C adapter id [media] davinci: vpif_capture: fix start/stop streaming locking [media] dt-bindings: add TI VPIF documentation [media] davinci: VPIF: add basic support for DT init
.../devicetree/bindings/media/ti,da850-vpif.txt | 67 ++++++++++++++++++++++ drivers/media/platform/davinci/vpif.c | 14 ++++- drivers/media/platform/davinci/vpif_capture.c | 26 +++++++-- drivers/media/platform/davinci/vpif_display.c | 6 ++ include/media/davinci/vpif_types.h | 1 + 5 files changed, 108 insertions(+), 6 deletions(-) create mode 100644 Documentation/devicetree/bindings/media/ti,da850-vpif.txt
Signature · 1 line
2.9.3
PATCH v5 1/5 davinci: VPIF: fix module loading, init errors
Fix problems with automatic module loading by adding MODULE_ALIAS. Also fix various load-time errors cause by incorrect or not present platform_data.
--- drivers/media/platform/davinci/vpif.c | 5 ++++- drivers/media/platform/davinci/vpif_capture.c | 15 ++++++++++++++- drivers/media/platform/davinci/vpif_display.c | 6 ++++++ 3 files changed, 24 insertions(+), 2 deletions(-)
drivers/media/platform/davinci/vpif.c +4 -1
@@ -32,6 +32,9 @@MODULE_DESCRIPTION ("TI DaVinci Video Port Interface driver" );MODULE_LICENSE ("GPL" ); +#define VPIF_DRIVER_NAME "vpif" +MODULE_ALIAS ("platform:" VPIF_DRIVER_NAME ); +#define VPIF_CH0_MAX_MODES 22#define VPIF_CH1_MAX_MODES 2#define VPIF_CH2_MAX_MODES 15
@@ -466,7 +469,7 @@ static const struct dev_pm_ops vpif_pm = {static struct platform_driver vpif_driver = { .driver = { - .name ="vpif" , + .name =VPIF_DRIVER_NAME , .pm = vpif_pm_ops, }, .remove = vpif_remove,
drivers/media/platform/davinci/vpif_capture.c +14 -1
@@ -45,6 +45,7 @@ module_param(debug, int, 0644);MODULE_PARM_DESC (debug,"Debug level 0-1" );#define VPIF_DRIVER_NAME "vpif_capture" +MODULE_ALIAS ("platform:" VPIF_DRIVER_NAME );/* global variables */ static struct vpif_device vpif_obj = { {NULL } };
@@ -647,6 +648,10 @@ static int vpif_input_to_subdev(vpif_dbg (2 , debug,"vpif_input_to_subdev\n" ); +if (!chan_cfg) +return -1 ; +if (input_index >= chan_cfg->input_count) +return -1 ; subdev_name = chan_cfg->inputs[input_index].subdev_name;if (subdev_name ==NULL )return -1 ;
@@ -654,7 +659,7 @@ static int vpif_input_to_subdev(/* loop through the sub device list to get the sub device info */ for (i =0 ; i < vpif_cfg->subdev_count; i++) { subdev_info = &vpif_cfg->subdev_info[i]; -if (!strcmp (subdev_info->name, subdev_name)) +if (subdev_info && !strcmp (subdev_info->name, subdev_name))return i; }return -1 ;
@@ -685,6 +690,9 @@ static int vpif_set_input(if (sd_index >=0 ) { sd = vpif_obj.sd[sd_index]; subdev_info = &vpif_cfg->subdev_info[sd_index]; + }else { +/* no subdevice, no input to setup */ +return 0 ; }/* first setup input path from sub device to vpif */
@@ -1435,6 +1443,11 @@ static __init int vpif_probe(struct platform_device *pdev)int res_idx =0 ;int i, err; +if (!pdev->dev.platform_data) { +dev_warn (&pdev->dev,"Missing platform data. Giving up.\n" ); +return -EINVAL ; + } + vpif_dev = &pdev->dev; err =initialize_vpif ();
drivers/media/platform/davinci/vpif_display.c +6 -0
@@ -42,6 +42,7 @@ module_param(debug, int, 0644);MODULE_PARM_DESC (debug,"Debug level 0-1" );#define VPIF_DRIVER_NAME "vpif_display" +MODULE_ALIAS ("platform:" VPIF_DRIVER_NAME );/* Is set to 1 in case of SDTV formats, 2 in case of HDTV formats. */ static int ycmux_mode;
@@ -1249,6 +1250,11 @@ static __init int vpif_probe(struct platform_device *pdev)int res_idx =0 ;int i, err; +if (!pdev->dev.platform_data) { +dev_warn (&pdev->dev,"Missing platform data. Giving up.\n" ); +return -EINVAL ; + } + vpif_dev = &pdev->dev; err =initialize_vpif ();
Signature · 1 line
2.9.3
PATCH v5 2/5 davinci: vpif_capture: remove hard-coded I2C adapter id
In reply to Kevin HilmanRemove hard-coded I2C adapter in favor of getting the ID from platform_data.
--- drivers/media/platform/davinci/vpif_capture.c | 5 ++++- include/media/davinci/vpif_types.h | 1 + 2 files changed, 5 insertions(+), 1 deletion(-)
drivers/media/platform/davinci/vpif_capture.c +4 -1
@@ -1486,7 +1486,10 @@ static __init int vpif_probe(struct platform_device *pdev) }if (!vpif_obj.config->asd_sizes) { - i2c_adap =i2c_get_adapter (1 ); +int i2c_id = vpif_obj.config->i2c_adapter_id; + + i2c_adap =i2c_get_adapter (i2c_id); +WARN_ON (!i2c_adap);for (i =0 ; i < subdev_count; i++) { subdevdata = &vpif_obj.config->subdev_info[i]; vpif_obj.sd[i] =
include/media/davinci/vpif_types.h +1 -0
@@ -82,6 +82,7 @@ struct vpif_capture_config {struct vpif_capture_chan_config chan_config[VPIF_CAPTURE_MAX_CHANNELS ];struct vpif_subdev_info *subdev_info;int subdev_count; +int i2c_adapter_id;const char *card_name;struct v4l2_async_subdev **asd;/* Flat array, arranged in groups */ int *asd_sizes;/* 0-terminated array of asd group sizes */
Signature · 1 line
2.9.3
PATCH v5 3/5 davinci: vpif_capture: fix start/stop streaming locking
In reply to Kevin HilmanVideo capture subdevs may be over I2C and may sleep during xfer, so we cannot do IRQ-disabled locking when calling the subdev.
The IRQ-disabled locking is meant to protect the DMA queue list throughout the rest of the driver, so update the locking in [start|stop]_streaming to protect just this list.
--- drivers/media/platform/davinci/vpif_capture.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
drivers/media/platform/davinci/vpif_capture.c +3 -3
@@ -179,8 +179,6 @@ static int vpif_start_streaming(struct vb2_queue *vq, unsigned int count)unsigned long addr, flags;int ret; -spin_lock_irqsave (&common->irqlock, flags); -/* Initialize field_id */ ch->field_id =0 ;
@@ -211,6 +209,7 @@ static int vpif_start_streaming(struct vb2_queue *vq, unsigned int count)vpif_config_addr (ch, ret);/* Get the next frame from the buffer queue */ +spin_lock_irqsave (&common->irqlock, flags); common->cur_frm = common->next_frm =list_entry (common->dma_queue.next, struct vpif_cap_buffer, list);/* Remove buffer from the buffer queue */
@@ -244,6 +243,7 @@ static int vpif_start_streaming(struct vb2_queue *vq, unsigned int count)return 0 ; err: +spin_lock_irqsave (&common->irqlock, flags);list_for_each_entry_safe (buf, tmp, &common->dma_queue, list) {list_del (&buf->list);vb2_buffer_done (&buf->vb.vb2_buf,VB2_BUF_STATE_QUEUED );
@@ -287,7 +287,6 @@ static void vpif_stop_streaming(struct vb2_queue *vq)vpif_dbg (1 , debug,"stream off failed in subdev\n" );/* release all active buffers */ -spin_lock_irqsave (&common->irqlock, flags);if (common->cur_frm == common->next_frm) {vb2_buffer_done (&common->cur_frm->vb.vb2_buf,VB2_BUF_STATE_ERROR );
@@ -300,6 +299,7 @@ static void vpif_stop_streaming(struct vb2_queue *vq) VB2_BUF_STATE_ERROR); } +spin_lock_irqsave (&common->irqlock, flags);while (!list_empty (&common->dma_queue)) { common->next_frm =list_entry (common->dma_queue.next, struct vpif_cap_buffer, list);
Signature · 1 line
2.9.3
PATCH v5 3/5 davinci: vpif_capture: fix start/stop streaming locking
Hi Kevin,
Thank you for the patch.
Quoted 9 lines · On Tuesday 06 Dec 2016 21:08:24 Kevin Hilman wrote:
Video capture subdevs may be over I2C and may sleep during xfer, so we cannot do IRQ-disabled locking when calling the subdev.
The IRQ-disabled locking is meant to protect the DMA queue list throughout the rest of the driver, so update the locking in [start|stop]_streaming to protect just this list.
Suggested-by Laurent Pinchart <[email protected]>Signed-off-by Kevin Hilman <[email protected]>
I would also add a comment to document the irqlock field as protecting the dma_queue list only. Something like
- /* Used in video-buf */
+ /* Protects the dma_queue field */
spinlock_t irqlock;
With that,
Quoted 51 lines
--- drivers/media/platform/davinci/vpif_capture.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)(quoted diff) +0
-0
b/drivers/media/platform/davinci/vpif_capture.cindexc24049acd40a..f72a719efb3d100644drivers/media/platform/davinci/vpif_capture.c +1
-2@@ -179,8 +179,6 @@ static int vpif_start_streaming(struct vb2_queue *vq, unsigned int count) unsigned long addr, flags;int ret; -spin_lock_irqsave (&common->irqlock, flags); -/* Initialize field_id */ ch->field_id =0 ;@@ -211,6 +209,7 @@ static int vpif_start_streaming(struct vb2_queue *vq, unsigned int count) vpif_config_addr(ch, ret);/* Get the next frame from the buffer queue */ +spin_lock_irqsave (&common->irqlock, flags); common->cur_frm = common->next_frm =list_entry (common- dma_queue.next, struct vpif_cap_buffer, list);drivers/media/platform/davinci/vpif_capture.c +2
-1/* Remove buffer from the buffer queue */ @@ -244,6 +243,7 @@ static int vpif_start_streaming(struct vb2_queue *vq, unsigned int count) return 0; err: +spin_lock_irqsave (&common->irqlock, flags);list_for_each_entry_safe (buf, tmp, &common->dma_queue, list) {list_del (&buf->list);vb2_buffer_done (&buf->vb.vb2_buf,VB2_BUF_STATE_QUEUED );@@ -287,7 +287,6 @@ static void vpif_stop_streaming(struct vb2_queue *vq)vpif_dbg (1 , debug,"stream off failed in subdev\n" );/* release all active buffers */ -spin_lock_irqsave (&common->irqlock, flags);if (common->cur_frm == common->next_frm) {vb2_buffer_done (&common->cur_frm->vb.vb2_buf,VB2_BUF_STATE_ERROR );@@ -300,6 +299,7 @@ static void vpif_stop_streaming(struct vb2_queue *vq) VB2_BUF_STATE_ERROR); } +spin_lock_irqsave (&common->irqlock, flags);while (!list_empty (&common->dma_queue)) { common->next_frm =list_entry (common->dma_queue.next, struct vpif_cap_buffer, list);
Signature · 3 lines
Regards, Laurent Pinchart
PATCH v5 3/5 davinci: vpif_capture: fix start/stop streaming locking
Quoted 22 lines · Laurent Pinchart
Hi Kevin,
Thank you for the patch.
Quoted 9 lines · On Tuesday 06 Dec 2016 21:08:24 Kevin Hilman wrote:
Video capture subdevs may be over I2C and may sleep during xfer, so we cannot do IRQ-disabled locking when calling the subdev.
The IRQ-disabled locking is meant to protect the DMA queue list throughout the rest of the driver, so update the locking in [start|stop]_streaming to protect just this list.
Suggested-by Laurent Pinchart <[email protected]>Signed-off-by Kevin Hilman <[email protected]>I would also add a comment to document the irqlock field as protecting the
dma_queuelist only. Something like(quoted diff) +1
-1- /* Used in video-buf */ + /* Protects the dma_queue field */spinlock_t irqlock;
Quoted 3 lines
With that,
Reviewed-by Laurent Pinchart <[email protected]>
OK, will update the comment. Thanks for the review,
Kevin
PATCH v5 4/5 dt-bindings: add TI VPIF documentation
In reply to Kevin Hilman--- .../devicetree/bindings/media/ti,da850-vpif.txt | 67 ++++++++++++++++++++++ 1 file changed, 67 insertions(+) create mode 100644 Documentation/devicetree/bindings/media/ti,da850-vpif.txt
Documentation/devicetree/bindings/media/ti,da850-vpif.txt new file +67 -0
@@ -0,0 +1,67 @@ +Texas Instruments VPIF +---------------------- + +The TI Video Port InterFace (VPIF) is the primary component for video +capture and display on the DA850/AM18x family of TI DaVinci/Sitara +SoCs. + +TI Document reference: SPRUH82C, Chapter 35 +http://www.ti.com/lit/pdf/spruh82 + +Required properties: +- compatible: must be "ti,da850-vpif" +- reg: physical base address and length of the registers set for the device; +- interrupts: should contain IRQ line for the VPIF + +Video Capture: + +VPIF has a 16-bit parallel bus input, supporting 2 8-bit channels or a +single 16-bit channel. It should contain at least one port child node +with child 'endpoint' node. Please refer to the bindings defined in +Documentation/devicetree/bindings/media/video-interfaces.txt. + +Example using 2 8-bit input channels, one of which is connected to an +I2C-connected TVP5147 decoder: + + vpif: vpif at 217000 { + compatible = "ti,da850-vpif"; + reg = <0x217000 0x1000>; + interrupts = <92>; + + port { + vpif_ch0: endpoint at 0 { + reg = <0>; + bus-width = <8>; + remote-endpoint = <&composite>; + }; + + vpif_ch1: endpoint at 1 { + reg = <1>; + bus-width = <8>; + data-shift = <8>; + }; + }; + }; + +[ ... ] + +&i2c0 { + + tvp5147 at 5d { + compatible = "ti,tvp5147"; + reg = <0x5d>; + status = "okay"; + + port { + composite: endpoint { + hsync-active = <1>; + vsync-active = <1>; + pclk-sample = <0>; + + /* VPIF channel 0 (lower 8-bits) */ + remote-endpoint = <&vpif_ch0>; + bus-width = <8>; + }; + }; + }; +};
Signature · 1 line
2.9.3
PATCH v5 4/5 dt-bindings: add TI VPIF documentation
Hi Kevin,
Thank you for the patch.
Quoted 30 lines · On Tuesday 06 Dec 2016 21:08:25 Kevin Hilman wrote:
Acked-by Rob Herring <[email protected]>Signed-off-by Kevin Hilman <[email protected]>---
.../devicetree/bindings/media/ti,da850-vpif.txt| 67 +++++++++++++++++++1 file changed, 67 insertions(+)create mode 100644
Documentation/devicetree/bindings/media/ti,da850-vpif.txt(quoted diff) +0
-0
b/Documentation/devicetree/bindings/media/ti,da850-vpif.txtnew file mode 100644
index 000000000000..fa06dfdb6898Documentation/devicetree/bindings/media/ti,da850-vpif.txt new file +13
-0@@ -0,0 +1,67 @@ +Texas Instruments VPIF +---------------------- + +The TI Video Port InterFace (VPIF) is the primary component for video +capture and display on the DA850/AM18x family of TI DaVinci/Sitara +SoCs. + +TI Document reference: SPRUH82C, Chapter 35 +http://www.ti.com/lit/pdf/spruh82 + +Required properties: +- compatible: must be "ti,da850-vpif" +- reg: physical base address and length of the registers set for thedevice;
+- interrupts: should contain IRQ line for the VPIF
Documentation/devicetree/bindings/media/ti,da850-vpif.txt line 21
Quoted 7 lines
Documentation/devicetree/bindings/media/ti,da850-vpif.txt new file +7
-0+ +Video Capture: + +VPIF has a 16-bit parallel bus input, supporting 2 8-bit channels or a +single 16-bit channel. It should contain at least one port child node +with child 'endpoint' node. Please refer to the bindings defined in +Documentation/devicetree/bindings/media/video-interfaces.txt.
You might want to clarify how endpoints are use in the two cases. Apart from that,
Quoted 45 lines
Documentation/devicetree/bindings/media/ti,da850-vpif.txt new file +45
-0+Example using 2 8-bit input channels, one of which is connected to an +I2C-connected TVP5147 decoder: + + vpif: vpif@217000 { + compatible = "ti,da850-vpif"; + reg = <0x217000 0x1000>; + interrupts = <92>; + + port { + vpif_ch0: endpoint@0 { + reg = <0>; + bus-width = <8>; + remote-endpoint = <&composite>; + }; + + vpif_ch1: endpoint@1 { + reg = <1>; + bus-width = <8>; + data-shift = <8>; + }; + }; + }; + +[ ... ] + +&i2c0 { + + tvp5147@5d { + compatible = "ti,tvp5147"; + reg = <0x5d>; + status = "okay"; + + port { + composite: endpoint { + hsync-active = <1>; + vsync-active = <1>; + pclk-sample = <0>; + + /* VPIF channel 0 (lower 8-bits) */ + remote-endpoint = <&vpif_ch0>; + bus-width = <8>; + }; + }; + }; +};
Signature · 3 lines
Regards, Laurent Pinchart
PATCH v5 4/5 dt-bindings: add TI VPIF documentation
Quoted 37 lines · Laurent Pinchart
Hi Kevin,
Thank you for the patch.
Quoted 32 lines · On Tuesday 06 Dec 2016 21:08:25 Kevin Hilman wrote:
Acked-by Rob Herring <[email protected]>Signed-off-by Kevin Hilman <[email protected]>---
.../devicetree/bindings/media/ti,da850-vpif.txt| 67 +++++++++++++++++++1 file changed, 67 insertions(+)create mode 100644
Documentation/devicetree/bindings/media/ti,da850-vpif.txt(quoted diff) +0
-0
b/Documentation/devicetree/bindings/media/ti,da850-vpif.txtnew file mode 100644
index 000000000000..fa06dfdb6898Documentation/devicetree/bindings/media/ti,da850-vpif.txt new file +13
-0@@ -0,0 +1,67 @@ +Texas Instruments VPIF +---------------------- + +The TI Video Port InterFace (VPIF) is the primary component for video +capture and display on the DA850/AM18x family of TI DaVinci/Sitara +SoCs. + +TI Document reference: SPRUH82C, Chapter 35 +http://www.ti.com/lit/pdf/spruh82 + +Required properties: +- compatible: must be "ti,da850-vpif" +- reg: physical base address and length of the registers set for thedevice;
+- interrupts: should contain IRQ line for the VPIFDocumentation/devicetree/bindings/media/ti,da850-vpif.txt new file +2
-0+ +Video Capture:
Quoted 8 lines
Documentation/devicetree/bindings/media/ti,da850-vpif.txt line 21
Quoted 5 lines
Documentation/devicetree/bindings/media/ti,da850-vpif.txt new file +5
-0+ +VPIF has a 16-bit parallel bus input, supporting 2 8-bit channels or a +single 16-bit channel. It should contain at least one port child node +with child 'endpoint' node. Please refer to the bindings defined in +Documentation/devicetree/bindings/media/video-interfaces.txt.You might want to clarify how endpoints are use in the two cases. Apart from that,
OK, I'll add another example for the 16-bit case. Something like...
Quoted 37 lines
Quoted 37 lines
Documentation/devicetree/bindings/media/ti,da850-vpif.txt new file +37
-0+Example using 2 8-bit input channels, one of which is connected to an +I2C-connected TVP5147 decoder: + + vpif: vpif at 217000 { + compatible = "ti,da850-vpif"; + reg = <0x217000 0x1000>; + interrupts = <92>; + + port { + vpif_ch0: endpoint at 0 { + reg = <0>; + bus-width = <8>; + remote-endpoint = <&composite>; + }; + + vpif_ch1: endpoint at 1 { + reg = <1>; + bus-width = <8>; + data-shift = <8>; + }; + }; + }; + +[ ... ] + +&i2c0 { + + tvp5147 at 5d { + compatible = "ti,tvp5147"; + reg = <0x5d>; + status = "okay"; + + port { + composite: endpoint { + hsync-active = <1>; + vsync-active = <1>; + pclk-sample = <0>;
Quoted 8 lines
Documentation/devicetree/bindings/media/ti,da850-vpif.txt line 67
Quoted 8 lines
Documentation/devicetree/bindings/media/ti,da850-vpif.txt new file +8
-0+ + /* VPIF channel 0 (lower 8-bits) */ + remote-endpoint = <&vpif_ch0>; + bus-width = <8>; + }; + }; + }; +};
...this, at the end of the binding doc:
Alternatively, an example when the bus is configured as a single 16-bit input (e.g. for raw-capture mode):
vpif: vpif at 217000 {
compatible = "ti,da850-vpif";
reg = <0x217000 0x1000>;
interrupts = <92>;
port {
vpif_ch0: endpoint {
bus-width = <16>;
};
};
};Thanks for the review,
Kevin
PATCH v5 5/5 davinci: VPIF: add basic support for DT init
In reply to Kevin HilmanAdd basic support for initialization via DT
--- drivers/media/platform/davinci/vpif.c | 9 +++++++++ 1 file changed, 9 insertions(+)
drivers/media/platform/davinci/vpif.c +9 -0
@@ -467,8 +467,17 @@ static const struct dev_pm_ops vpif_pm = {#define vpif_pm_ops NULL#endif +#if IS_ENABLED (CONFIG_OF ) +static const struct of_device_id vpif_of_match[] = { + { .compatible ="ti,da850-vpif" , }, + {/* sentinel */ }, +}; +MODULE_DEVICE_TABLE (of, vpif_of_match); +#endif +static struct platform_driver vpif_driver = { .driver = { + .of_match_table =of_match_ptr (vpif_of_match), .name =VPIF_DRIVER_NAME , .pm = vpif_pm_ops, },
Signature · 1 line
2.9.3