Skip to contentSkip to conversation

blackfin: add video display device driver

RFC PATCH Superseded Scott Jiang 2 participants 2 messages Apr 28, 2013 – Apr 29, 2013 Media (V4L/DVB)

v2 of 4 Superseded Latest is v4 →

lore
Share & tools
lore
#0 lore raw

RFC PATCH v2 1/1 blackfin: add video display device driver

This is a V4L2 driver for Blackfin video display (E)PPI interface. This module is common for BF537/BF561/BF548/BF609.

---
 drivers/media/platform/blackfin/Kconfig        |   15 +-
 drivers/media/platform/blackfin/Makefile       |    1 +
 drivers/media/platform/blackfin/bfin_display.c |  934 ++++++++++++++++++++++++
 include/media/blackfin/bfin_display.h          |   38 +
 4 files changed, 986 insertions(+), 2 deletions(-)
 create mode 100644 drivers/media/platform/blackfin/bfin_display.c
 create mode 100644 include/media/blackfin/bfin_display.h
drivers/media/platform/blackfin/Kconfig +13 -2
index cc23997..10aa435 100644
@@ -9,7 +9,18 @@ config VIDEO_BLACKFIN_CAPTURE
 	  To compile this driver as a module, choose M here: the
 	  module will be called bfin_capture.
 
+config VIDEO_BLACKFIN_DISPLAY
+	tristate "Blackfin Video Display Driver"
+	depends on VIDEO_V4L2 && BLACKFIN && I2C
+	select VIDEOBUF2_DMA_CONTIG
+	help
+	  V4L2 driver for Blackfin video display (E)PPI interface.
+	  This module is common for BF537/BF561/BF548/BF609.
+
+	  To compile this driver as a module, choose M here: the
+	  module will be called bfin_display.
+
 config VIDEO_BLACKFIN_PPI
 	tristate
-	depends on VIDEO_BLACKFIN_CAPTURE
-	default VIDEO_BLACKFIN_CAPTURE
+	depends on VIDEO_BLACKFIN_CAPTURE || VIDEO_BLACKFIN_DISPLAY
+	default VIDEO_BLACKFIN_CAPTURE || VIDEO_BLACKFIN_DISPLAY
drivers/media/platform/blackfin/Makefile +1 -0
index 30421bc..015c8f0 100644
@@ -1,2 +1,3 @@
 obj-$(CONFIG_VIDEO_BLACKFIN_CAPTURE) += bfin_capture.o
+obj-$(CONFIG_VIDEO_BLACKFIN_DISPLAY) += bfin_display.o
 obj-$(CONFIG_VIDEO_BLACKFIN_PPI)     += ppi.o
drivers/media/platform/blackfin/bfin_display.c new file +934 -0

934 lines not on this page · raw message

include/media/blackfin/bfin_display.h new file +38 -0
new file mode 100644
index 0000000..6eb1d5a
@@ -0,0 +1,38 @@
+#ifndef _BFIN_DISPLAY_H_
+#define _BFIN_DISPLAY_H_
+
+#include <linux/i2c.h>
+
+struct v4l2_output;
+struct ppi_info;
+
+struct disp_route {
+	u32 output;
+	u32 config;
+	u32 ppi_control;
+};
+
+struct bfin_display_config {
+	/* card name */
+	char *card_name;
+	/* outputs available at the sub device */
+	struct v4l2_output *outputs;
+	/* number of outputs supported */
+	int num_outputs;
+	/* routing information for each output */
+	struct disp_route *routes;
+	/* i2c bus adapter no */
+	int i2c_adapter_id;
+	/* i2c subdevice board info */
+	struct i2c_board_info board_info;
+	/* ppi board info */
+	const struct ppi_info *ppi_info;
+	/* ppi control */
+	u32 ppi_control;
+	/* ppi interrupt mask */
+	u32 int_mask;
+	/* horizontal blanking pixels */
+	int blank_pixels;
+};
+
+#endif
Signature · 1 line
1.7.0.4
Reviewed-by on v2 1/1
#1 lore raw

Hi Scott,

Quoted 6 lines · Scott Jiang

This is a V4L2 driver for Blackfin video display (E)PPI interface. This module is common for BF537/BF561/BF548/BF609.

From a quick review this patch looks good to me. Feel free to add

Just couple remarks below.

drivers/media/platform/blackfin/bfin_display.c line 110

Quoted 3 lines
drivers/media/platform/blackfin/bfin_display.c new file +3 -0
+static const struct bfin_disp_format bfin_disp_formats[] = {
+	{
+		.desc        = "YCbCr 4:2:2 Interleaved UYVY 8bits",

This string will like get truncated, since buffer is only 32 character long, including trailing 0. It could be verified with e.g. v4l2-ctl how much of this string actually shows up in user space.

drivers/media/platform/blackfin/bfin_display.c line 117

Quoted 7 lines
drivers/media/platform/blackfin/bfin_display.c new file +7 -0
+		.pixelformat = V4L2_PIX_FMT_UYVY,
+		.mbus_code   = V4L2_MBUS_FMT_UYVY8_2X8,
+		.bpp         = 16,
+		.dlen        = 8,
+	},
+	{
+		.desc        = "YCbCr 4:2:2 Interleaved YUYV 8bits",

Ditto.

drivers/media/platform/blackfin/bfin_display.c line 124

Quoted 7 lines
drivers/media/platform/blackfin/bfin_display.c new file +7 -0
+		.pixelformat = V4L2_PIX_FMT_YUYV,
+		.mbus_code   = V4L2_MBUS_FMT_YUYV8_2X8,
+		.bpp         = 16,
+		.dlen        = 8,
+	},
+	{
+		.desc        = "YCbCr 4:2:2 Interleaved UYVY 16bits",

Ditto.

Quoted 5 lines
drivers/media/platform/blackfin/bfin_display.c new file +5 -0
+		.pixelformat = V4L2_PIX_FMT_UYVY,
+		.mbus_code   = V4L2_MBUS_FMT_UYVY8_1X16,
+		.bpp         = 16,
+		.dlen        = 16,
+	},

[...]

drivers/media/platform/blackfin/bfin_display.c line 270

Quoted 12 lines
drivers/media/platform/blackfin/bfin_display.c new file +12 -0
+static irqreturn_t bfin_disp_isr(int irq, void *dev_id)
+{
+	struct ppi_if *ppi = dev_id;
+	struct bfin_disp_device *disp = ppi->priv;
+	struct vb2_buffer *vb = &disp->cur_frm->vb;
+	dma_addr_t addr;
+
+	spin_lock(&disp->lock);
+
+	if (!list_empty(&disp->dma_queue)) {
+		v4l2_get_timestamp(&vb->v4l2_buf.timestamp);
+		vb->v4l2_buf.flags |= V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;

There is no need to set this flag for each buffer, it will be done internally in videbuf2, if timestamp_type type is set before calling vb2_queue_init().

Quoted 24 lines
drivers/media/platform/blackfin/bfin_display.c new file +23 -0
+		vb2_buffer_done(vb, VB2_BUF_STATE_DONE);
+		disp->cur_frm = list_entry(disp->dma_queue.next,
+				struct bfin_disp_buffer, list);
+		list_del(&disp->cur_frm->list);
+	}
+
+	clear_dma_irqstat(ppi->info->dma_ch);
+
+	addr = vb2_dma_contig_plane_dma_addr(&disp->cur_frm->vb, 0);
+	ppi->ops->update_addr(ppi, (unsigned long)addr);
+	ppi->ops->start(ppi);
+
+	spin_unlock(&disp->lock);
+
+	return IRQ_HANDLED;
+}
 
+static int bfin_disp_probe(struct platform_device *pdev)
+{
+	struct bfin_disp_device *disp;
+	struct video_device *vfd;
+	struct i2c_adapter *i2c_adap;
+	struct bfin_display_config *config;
+	struct vb2_queue *q;

drivers/media/platform/blackfin/bfin_display.c

Quoted 10 lines
drivers/media/platform/blackfin/bfin_display.c new file +10 -0
+	struct disp_route *route;
+	int ret;
+
+	config = pdev->dev.platform_data;
+	if (!config || !config->num_outputs) {
+		v4l2_err(pdev->dev.driver, "Invalid board config\n");
+		return -ENODEV;
+	}
+
+	disp = kzalloc(sizeof(*disp), GFP_KERNEL);

devm_kzalloc() ?

Quoted 2 lines
drivers/media/platform/blackfin/bfin_display.c new file +2 -0
+	if (!disp)
+		return -ENOMEM;

[...]

drivers/media/platform/blackfin/bfin_display.c line 784

Quoted 11 lines
drivers/media/platform/blackfin/bfin_display.c new file +11 -0
+
+	/* initialize queue */
+	q = &disp->buffer_queue;
+	q->type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
+	q->io_modes = VB2_MMAP;
+	q->drv_priv = disp;
+	q->buf_struct_size = sizeof(struct bfin_disp_buffer);
+	q->ops = &bfin_disp_video_qops;
+	q->mem_ops = &vb2_dma_contig_memops;
+	/* provide a mutex to vb2 queue */
+	q->lock = &disp->qlock;

And the timestamp type set up:

	q->timestamp_type = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;

drivers/media/platform/blackfin/bfin_display.c line 791

Quoted 6 lines
drivers/media/platform/blackfin/bfin_display.c new file +6 -0
+	ret = vb2_queue_init(q);
+	if (ret) {
+		v4l2_err(&disp->v4l2_dev,
+				"Unable to init videobuf2 queue\n");
+		goto err_free_handler;
+	}

Thanks,
Sylwester