[v2,00/15] Add mediatek mipicsi driver for Mediatek SOC MT2712
mbox series

Message ID 1555407015-18130-1-git-send-email-stu.hsieh@mediatek.com
Headers show
Series
  • Add mediatek mipicsi driver for Mediatek SOC MT2712
Related show

Message

Stu Hsieh April 16, 2019, 9:30 a.m. UTC
Add mediatek mipicsi driver for Mediatek SOC MT2712

Change in v2:
- Add the dt-binding document for mediatek mipicsi driver
- Modify the logic about "is_support" function in patch
  "[media] mtk-mipicsi: add color format support for mt2712"

Stu Hsieh (15):
  dt-bindings: media: Add binding for MT2712 MIPI-CSI2
  [media] mtk-mipicsi: add mediatek mipicsi driver for mt2712
  [media] mtk-mipicsi: add pm function
  [media] mtk-mipicsi: add color format support for mt2712
  [media] mtk-mipicsi: get the w/h/bytepwerline for mtk_mipicsi
  [media] mtk-mipicsi: add function to support SerDes for link number
  [media] mtk-mipicsi: add mipicsi reg setting for mt2712
  [media] mtk-mipicsi: enable/disable ana clk
  [media] mtk-mipicsi: enable/disable cmos for mt2712
  [media] mtk-mipicsi: add ISR for writing the data to buffer
  [media] mtk-mipicsi: set the output address in HW reg
  [media] mtk-mipicsi: add function to get the format
  [media] mtk-mipicsi: add the function for Get/Set PARM for application
  [media] mtk-mipicsi: add debug message for mipicsi driver
  [media] mtk-mipicsi: add debugfs for mipicsi driver

 .../bindings/media/mediatek-mipicsi-camsv.txt |   53 +
 .../media/mediatek-mipicsi-common.txt         |   19 +
 .../bindings/media/mediatek-mipicsi.txt       |   54 +
 drivers/media/platform/mtk-mipicsi/Makefile   |    4 +
 .../media/platform/mtk-mipicsi/mtk_mipicsi.c  | 1686 +++++++++++++++++
 5 files changed, 1816 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/media/mediatek-mipicsi-camsv.txt
 create mode 100644 Documentation/devicetree/bindings/media/mediatek-mipicsi-common.txt
 create mode 100644 Documentation/devicetree/bindings/media/mediatek-mipicsi.txt
 create mode 100644 drivers/media/platform/mtk-mipicsi/Makefile
 create mode 100644 drivers/media/platform/mtk-mipicsi/mtk_mipicsi.c

Comments

CK Hu April 18, 2019, 1:34 a.m. UTC | #1
Hi, Stu:

On Tue, 2019-04-16 at 17:30 +0800, Stu Hsieh wrote:
> This patch add mediatek mipicsi driver for mt2712,
> including probe function to get the value from device tree,
> and register to v4l2 the host device.
> 
> Signed-off-by: Stu Hsieh <stu.hsieh@mediatek.com>
> ---
>  drivers/media/platform/mtk-mipicsi/Makefile   |   4 +
>  .../media/platform/mtk-mipicsi/mtk_mipicsi.c  | 767 ++++++++++++++++++
>  2 files changed, 771 insertions(+)
>  create mode 100644 drivers/media/platform/mtk-mipicsi/Makefile
>  create mode 100644 drivers/media/platform/mtk-mipicsi/mtk_mipicsi.c
> 
> diff --git a/drivers/media/platform/mtk-mipicsi/Makefile b/drivers/media/platform/mtk-mipicsi/Makefile
> new file mode 100644
> index 000000000000..326a5e3808fa
> --- /dev/null
> +++ b/drivers/media/platform/mtk-mipicsi/Makefile
> @@ -0,0 +1,4 @@
> +mtk-mipicsi-y += mtk_mipicsi.o
> +
> +obj-$(CONFIG_VIDEO_MEDIATEK_MIPICSI) += mtk-mipicsi.o
> +
> diff --git a/drivers/media/platform/mtk-mipicsi/mtk_mipicsi.c b/drivers/media/platform/mtk-mipicsi/mtk_mipicsi.c
> new file mode 100644
> index 000000000000..e26bebe17fe5
> --- /dev/null
> +++ b/drivers/media/platform/mtk-mipicsi/mtk_mipicsi.c
> @@ -0,0 +1,767 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * Copyright (C) 2017 MediaTek Inc.
> + * Author: Ricky Zhang <ricky.zhang@mediatek.com>
> + *         Baoyin Zhang <baoyin.zhang@mediatek.com>
> + *         Alan Yue <alan.yue@mediatek.com>
> + *
> + * 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.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
> + * http://www.gnu.org/licenses/gpl-2.0.html for more details.
> + */
> +
> +#include <linux/init.h>
> +#include <linux/module.h>
> +#include <linux/io.h>
> +#include <linux/delay.h>
> +#include <linux/dma-mapping.h>
> +#include <linux/err.h>
> +#include <linux/errno.h>
> +#include <linux/fs.h>
> +#include <linux/interrupt.h>
> +#include <linux/kernel.h>
> +#include <linux/mm.h>
> +#include <linux/moduleparam.h>
> +#include <linux/device.h>
> +#include <linux/platform_device.h>
> +#include <linux/clk.h>
> +#include <linux/sched.h>
> +#include <linux/slab.h>
> +#include <linux/pm_runtime.h>
> +#include <linux/iommu.h>
> +#include <linux/of.h>
> +#include <linux/of_platform.h>
> +#include <media/v4l2-common.h>
> +#include <media/v4l2-dev.h>
> +#include <media/videobuf2-dma-contig.h>
> +#include <media/soc_camera.h>
> +#include <media/drv-intf/soc_mediabus.h>
> +#include <media/videobuf2-core.h>
> +#include <linux/videodev2.h>
> +#include <soc/mediatek/smi.h>
> +#include <linux/regmap.h>
> +#include <linux/mfd/syscon.h>
> +
> +#ifdef CONFIG_VB2_MEDIATEK_DMA_SG
> +#include "mtkbuf-dma-cache-sg.h"
> +#endif
> +
> +#define MTK_MIPICSI_DRV_NAME "mtk-mipicsi"
> +#define MTK_PLATFORM_STR "platform:mt2712"
> +#define MIPICSI_COMMON_CLK 2
> +#define MTK_CAMDMA_MAX_NUM 4U
> +#define MIPICSI_CLK (MIPICSI_COMMON_CLK + MTK_CAMDMA_MAX_NUM)
> +#define MTK_DATAWIDTH_8					(0x01U << 7U)
> +#define MAX_SUPPORT_WIDTH             4096U
> +#define MAX_SUPPORT_HEIGHT            4096U
> +#define MAX_BUFFER_NUM			32U
> +#define VID_LIMIT_BYTES			(100U * 1024U * 1024U)
> +
> +/* buffer for one video frame */
> +struct mtk_mipicsi_buf {
> +	struct list_head queue;
> +	struct vb2_buffer *vb;
> +	dma_addr_t vb_dma_addr_phy;
> +	int prepare_flag;
> +};
> +
> +struct mtk_mipicsi_dev {
> +	struct soc_camera_host	soc_host;
> +	struct platform_device *pdev;
> +	unsigned int camsv_num;
> +	struct v4l2_device	v4l2_dev;
> +	struct device *larb_pdev;
> +	void __iomem		*ana;
> +	void __iomem		*seninf_ctrl;

Separating register control to another patch looks strange to me.
Register control is the bottom part and this patch is the top part. You
send a top part first then the bottom part. 'seninf_ctrl' is useless in
this patch, you may move this to the patch that use this variable or
merge that patch into this patch.

Regards,
CK

> +	void __iomem		*seninf;
> +	struct regmap		*seninf_top;
> +	void __iomem		*seninf_mux[MTK_CAMDMA_MAX_NUM];
> +	void __iomem		*camsv[MTK_CAMDMA_MAX_NUM];
> +	const struct soc_camera_format_xlate *current_fmt;
> +	u16				width_flags;	/* max 12 bits */
> +	struct list_head	capture_list[MTK_CAMDMA_MAX_NUM];
> +	struct list_head	fb_list;
> +	spinlock_t		lock;
> +	spinlock_t		queue_lock;
> +	struct mtk_mipicsi_buf	cam_buf[MAX_BUFFER_NUM];
> +	bool streamon;
> +	unsigned long frame_cnt[MTK_CAMDMA_MAX_NUM];
> +	unsigned int link;
> +	unsigned long enqueue_cnt;
> +	unsigned long dequeue_cnt;
> +	struct v4l2_ctrl_handler ctrl_hdl;
> +	char drv_name[16];
> +	u32 id;
> +	int clk_num;
> +	struct clk		*clk[MIPICSI_CLK];
> +};
> +
CK Hu April 18, 2019, 1:39 a.m. UTC | #2
Hi, Stu:

On Tue, 2019-04-16 at 17:30 +0800, Stu Hsieh wrote:
> This patch add color format support for mt2712

Without this patch, I think this driver still support these color
format. In this patch, you just check for the non-supported color
format.

Regards,
CK

> 
> Signed-off-by: Stu Hsieh <stu.hsieh@mediatek.com>
> ---
>  .../media/platform/mtk-mipicsi/mtk_mipicsi.c  | 20 +++++++++++++++++++
>  1 file changed, 20 insertions(+)
> 
> diff --git a/drivers/media/platform/mtk-mipicsi/mtk_mipicsi.c b/drivers/media/platform/mtk-mipicsi/mtk_mipicsi.c
> index ec4f6b503b32..16f6bc480f4e 100644
> --- a/drivers/media/platform/mtk-mipicsi/mtk_mipicsi.c
> +++ b/drivers/media/platform/mtk-mipicsi/mtk_mipicsi.c
> @@ -138,6 +138,20 @@ static void mtk_mipicsi_remove_device(struct soc_camera_device *icd)
>  	(void)pm_runtime_put_sync(icd->parent);
>  }
>  
> +static bool is_supported(const u32 pixformat)
> +{
> +	switch (pixformat) {
> +	/* YUV422 */
> +	case V4L2_PIX_FMT_YUYV:
> +	case V4L2_PIX_FMT_UYVY:
> +	case V4L2_PIX_FMT_YVYU:
> +	case V4L2_PIX_FMT_VYUY:
> +		return true;
> +	}
> +
> +	return false;
> +}
> +
>  static int mtk_mipicsi_set_fmt(struct soc_camera_device *icd,
>  				struct v4l2_format *f)
>  {
> @@ -153,6 +167,12 @@ static int mtk_mipicsi_set_fmt(struct soc_camera_device *icd,
>  	struct v4l2_mbus_framefmt *mf = &format.format;
>  	int ret = 0;
>  
> +	if (!is_supported(pix->pixelformat)) {
> +		dev_err(dev, "Format %x not support. set V4L2_PIX_FMT_YUYV as default\n",
> +			pix->pixelformat);
> +		pix->pixelformat = V4L2_PIX_FMT_YUYV;
> +	}
> +
>  	xlate = soc_camera_xlate_by_fourcc(icd, pix->pixelformat);
>  	if (xlate == NULL) {
>  		dev_err(dev, "Format 0x%x not found\n", pix->pixelformat);
CK Hu April 19, 2019, 3:52 a.m. UTC | #3
Hi, Stu:

On Tue, 2019-04-16 at 17:30 +0800, Stu Hsieh wrote:
> This patch get the w/h/bytepwerline to save in mtk_mipicsi.
> 
> Signed-off-by: Stu Hsieh <stu.hsieh@mediatek.com>
> ---
>  .../media/platform/mtk-mipicsi/mtk_mipicsi.c  | 39 +++++++++++++++++++
>  1 file changed, 39 insertions(+)
> 
> diff --git a/drivers/media/platform/mtk-mipicsi/mtk_mipicsi.c b/drivers/media/platform/mtk-mipicsi/mtk_mipicsi.c
> index 16f6bc480f4e..10782fccca79 100644
> --- a/drivers/media/platform/mtk-mipicsi/mtk_mipicsi.c
> +++ b/drivers/media/platform/mtk-mipicsi/mtk_mipicsi.c
> @@ -99,6 +99,9 @@ struct mtk_mipicsi_dev {
>  	u32 id;
>  	int clk_num;
>  	struct clk		*clk[MIPICSI_CLK];
> +	u32 width;
> +	u32 height;
> +	u32 bytesperline;
>  };
>  
>  #define MTK_MIPICSI_BUS_PARAM (V4L2_MBUS_MASTER |	\
> @@ -110,13 +113,36 @@ struct mtk_mipicsi_dev {
>  		V4L2_MBUS_PCLK_SAMPLE_FALLING |	\
>  		V4L2_MBUS_DATA_ACTIVE_HIGH)
>  
> +static u32 get_bytesperline(const u32 fmt, const u32 width)
> +{
> +	u32 bytesperline = 0;
> +
> +	switch (fmt) {
> +	case MEDIA_BUS_FMT_UYVY8_2X8:
> +	case MEDIA_BUS_FMT_VYUY8_2X8:
> +	case MEDIA_BUS_FMT_YUYV8_2X8:
> +	case MEDIA_BUS_FMT_YVYU8_2X8:
> +		bytesperline = width * 2U;
> +		break;
> +	default:
> +		break;
> +	}
> +
> +	return bytesperline;
> +}
> +
>  static int mtk_mipicsi_add_device(struct soc_camera_device *icd)
>  {
> +	struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
> +	struct mtk_mipicsi_dev *mipicsi = ici->priv;
>  	struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
>  	struct v4l2_subdev_format format = {
>  		.which = V4L2_SUBDEV_FORMAT_ACTIVE,
>  	};
>  	int ret;
> +	u32 width;
> +	u32 height;
> +	u32 fmt;
>  
>  	/* Get width/height info from subdev. Then use them to set register */
>  	ret = v4l2_subdev_call(sd, pad, get_fmt, NULL, &format);
> @@ -125,6 +151,19 @@ static int mtk_mipicsi_add_device(struct soc_camera_device *icd)
>  		return ret;
>  	}
>  
> +	width = format.format.width;
> +	height = format.format.height;
> +	fmt = format.format.code;
> +	mipicsi->bytesperline = get_bytesperline(fmt, width);
> +	if ((width == 0U) || (height == 0U) || (mipicsi->bytesperline == 0U)) {

You could check more completely, for example, if the valid range of width is 1 ~ 4095, you could check as:

#define WIDTH_MIN 1
#define WIDTH_MAX 4095

if ((width < WIDTH_MIN) || (width > WIDTH_MAX)) {
	/* invalid value */
}

Regards,
CK

> +		dev_err(icd->parent, "invalid sub device width/height/bytesperline %d/%d/%d\n",
> +			width, height, mipicsi->bytesperline);
> +		return -EINVAL;
> +	}
> +
> +	mipicsi->width = width;
> +	mipicsi->height = height;
> +
>  	/*
>  	 * If power domain was closed before, it will be open.
>  	 * Then clock will be open and register will be set