summaryrefslogtreecommitdiff
path: root/drivers/media/platform/exynos4-is
diff options
context:
space:
mode:
authorMauro Carvalho Chehab <mchehab@kernel.org>2022-03-13 11:18:16 +0100
committerMauro Carvalho Chehab <mchehab@kernel.org>2022-03-18 05:56:51 +0100
commit238c84f71120f41c45301359902a912a19370f3d (patch)
treec16ced196c926c08b0c1e9513a19710bbbfc9bfa /drivers/media/platform/exynos4-is
parent9b18ef7c9ff408df170ac339c57a759145c055d2 (diff)
media: platform: rename exynos4-is/ to samsung/exynos4-is/
As the end goal is to have platform drivers split by vendor, rename exynos4-is/ to samsung/exynos4-is/. Signed-off-by: Mauro Carvalho Chehab <mchehab@kernel.org>
Diffstat (limited to 'drivers/media/platform/exynos4-is')
-rw-r--r--drivers/media/platform/exynos4-is/Kconfig84
-rw-r--r--drivers/media/platform/exynos4-is/Makefile18
-rw-r--r--drivers/media/platform/exynos4-is/common.c49
-rw-r--r--drivers/media/platform/exynos4-is/common.h12
-rw-r--r--drivers/media/platform/exynos4-is/fimc-capture.c1894
-rw-r--r--drivers/media/platform/exynos4-is/fimc-core.c1179
-rw-r--r--drivers/media/platform/exynos4-is/fimc-core.h725
-rw-r--r--drivers/media/platform/exynos4-is/fimc-is-command.h134
-rw-r--r--drivers/media/platform/exynos4-is/fimc-is-errno.c269
-rw-r--r--drivers/media/platform/exynos4-is/fimc-is-errno.h245
-rw-r--r--drivers/media/platform/exynos4-is/fimc-is-i2c.c159
-rw-r--r--drivers/media/platform/exynos4-is/fimc-is-i2c.h12
-rw-r--r--drivers/media/platform/exynos4-is/fimc-is-param.c893
-rw-r--r--drivers/media/platform/exynos4-is/fimc-is-param.h1022
-rw-r--r--drivers/media/platform/exynos4-is/fimc-is-regs.c230
-rw-r--r--drivers/media/platform/exynos4-is/fimc-is-regs.h161
-rw-r--r--drivers/media/platform/exynos4-is/fimc-is-sensor.c31
-rw-r--r--drivers/media/platform/exynos4-is/fimc-is-sensor.h53
-rw-r--r--drivers/media/platform/exynos4-is/fimc-is.c986
-rw-r--r--drivers/media/platform/exynos4-is/fimc-is.h359
-rw-r--r--drivers/media/platform/exynos4-is/fimc-isp-video.c656
-rw-r--r--drivers/media/platform/exynos4-is/fimc-isp-video.h41
-rw-r--r--drivers/media/platform/exynos4-is/fimc-isp.c789
-rw-r--r--drivers/media/platform/exynos4-is/fimc-isp.h197
-rw-r--r--drivers/media/platform/exynos4-is/fimc-lite-reg.c346
-rw-r--r--drivers/media/platform/exynos4-is/fimc-lite-reg.h155
-rw-r--r--drivers/media/platform/exynos4-is/fimc-lite.c1673
-rw-r--r--drivers/media/platform/exynos4-is/fimc-lite.h224
-rw-r--r--drivers/media/platform/exynos4-is/fimc-m2m.c773
-rw-r--r--drivers/media/platform/exynos4-is/fimc-reg.c846
-rw-r--r--drivers/media/platform/exynos4-is/fimc-reg.h338
-rw-r--r--drivers/media/platform/exynos4-is/media-dev.c1604
-rw-r--r--drivers/media/platform/exynos4-is/media-dev.h201
-rw-r--r--drivers/media/platform/exynos4-is/mipi-csis.c1037
-rw-r--r--drivers/media/platform/exynos4-is/mipi-csis.h23
35 files changed, 0 insertions, 17418 deletions
diff --git a/drivers/media/platform/exynos4-is/Kconfig b/drivers/media/platform/exynos4-is/Kconfig
deleted file mode 100644
index 868bb86c7699..000000000000
--- a/drivers/media/platform/exynos4-is/Kconfig
+++ /dev/null
@@ -1,84 +0,0 @@
-# SPDX-License-Identifier: GPL-2.0-only
-
-config VIDEO_SAMSUNG_EXYNOS4_IS
- tristate "Samsung S5P/EXYNOS4 SoC series Camera Subsystem driver"
- depends on V4L_PLATFORM_DRIVERS
- depends on VIDEO_V4L2 && OF && COMMON_CLK
- depends on ARCH_S5PV210 || ARCH_EXYNOS || COMPILE_TEST
- select MEDIA_CONTROLLER
- select VIDEO_V4L2_SUBDEV_API
- select V4L2_FWNODE
- help
- Say Y here to enable camera host interface devices for
- Samsung S5P and EXYNOS SoC series.
-
-if VIDEO_SAMSUNG_EXYNOS4_IS
-
-config VIDEO_EXYNOS4_IS_COMMON
- tristate
-
-config VIDEO_S5P_FIMC
- tristate "S5P/EXYNOS4 FIMC/CAMIF camera interface driver"
- depends on I2C
- depends on HAS_DMA
- select VIDEOBUF2_DMA_CONTIG
- select V4L2_MEM2MEM_DEV
- select MFD_SYSCON
- select VIDEO_EXYNOS4_IS_COMMON
- help
- This is a V4L2 driver for Samsung S5P and EXYNOS4 SoC camera host
- interface and video postprocessor (FIMC) devices.
-
- To compile this driver as a module, choose M here: the
- module will be called s5p-fimc.
-
-config VIDEO_S5P_MIPI_CSIS
- tristate "S5P/EXYNOS MIPI-CSI2 receiver (MIPI-CSIS) driver"
- depends on REGULATOR
- select GENERIC_PHY
- select V4L2_FWNODE
- help
- This is a V4L2 driver for Samsung S5P and EXYNOS4 SoC MIPI-CSI2
- receiver (MIPI-CSIS) devices.
-
- To compile this driver as a module, choose M here: the
- module will be called s5p-csis.
-
-config VIDEO_EXYNOS_FIMC_LITE
- tristate "EXYNOS FIMC-LITE camera interface driver"
- depends on I2C
- depends on SOC_EXYNOS4412 || SOC_EXYNOS5250 || COMPILE_TEST
- depends on HAS_DMA
- select VIDEOBUF2_DMA_CONTIG
- select VIDEO_EXYNOS4_IS_COMMON
- help
- This is a V4L2 driver for Samsung EXYNOS4/5 SoC FIMC-LITE camera
- host interface.
-
- To compile this driver as a module, choose M here: the
- module will be called exynos-fimc-lite.
-
-config VIDEO_EXYNOS4_FIMC_IS
- tristate "EXYNOS4x12 FIMC-IS (Imaging Subsystem) driver"
- depends on I2C
- depends on HAS_DMA
- select VIDEOBUF2_DMA_CONTIG
- depends on OF
- select FW_LOADER
- help
- This is a V4L2 driver for Samsung EXYNOS4x12 SoC series
- FIMC-IS (Imaging Subsystem).
-
- To compile this driver as a module, choose M here: the
- module will be called exynos4-fimc-is.
-
-config VIDEO_EXYNOS4_ISP_DMA_CAPTURE
- bool "EXYNOS4x12 FIMC-IS ISP Direct DMA capture support"
- depends on VIDEO_EXYNOS4_FIMC_IS
- select VIDEO_EXYNOS4_IS_COMMON
- default y
- help
- This option enables an additional video device node exposing a V4L2
- video capture interface for the FIMC-IS ISP raw (Bayer) capture DMA.
-
-endif # VIDEO_SAMSUNG_EXYNOS4_IS
diff --git a/drivers/media/platform/exynos4-is/Makefile b/drivers/media/platform/exynos4-is/Makefile
deleted file mode 100644
index a5ab01c73b95..000000000000
--- a/drivers/media/platform/exynos4-is/Makefile
+++ /dev/null
@@ -1,18 +0,0 @@
-# SPDX-License-Identifier: GPL-2.0
-s5p-fimc-objs := fimc-core.o fimc-reg.o fimc-m2m.o fimc-capture.o media-dev.o
-exynos-fimc-lite-objs += fimc-lite-reg.o fimc-lite.o
-s5p-csis-objs := mipi-csis.o
-exynos4-is-common-objs := common.o
-
-exynos-fimc-is-objs := fimc-is.o fimc-isp.o fimc-is-sensor.o fimc-is-regs.o
-exynos-fimc-is-objs += fimc-is-param.o fimc-is-errno.o fimc-is-i2c.o
-
-ifeq ($(CONFIG_VIDEO_EXYNOS4_ISP_DMA_CAPTURE),y)
-exynos-fimc-is-objs += fimc-isp-video.o
-endif
-
-obj-$(CONFIG_VIDEO_S5P_MIPI_CSIS) += s5p-csis.o
-obj-$(CONFIG_VIDEO_EXYNOS_FIMC_LITE) += exynos-fimc-lite.o
-obj-$(CONFIG_VIDEO_EXYNOS4_FIMC_IS) += exynos-fimc-is.o
-obj-$(CONFIG_VIDEO_S5P_FIMC) += s5p-fimc.o
-obj-$(CONFIG_VIDEO_EXYNOS4_IS_COMMON) += exynos4-is-common.o
diff --git a/drivers/media/platform/exynos4-is/common.c b/drivers/media/platform/exynos4-is/common.c
deleted file mode 100644
index 023f624d29d5..000000000000
--- a/drivers/media/platform/exynos4-is/common.c
+++ /dev/null
@@ -1,49 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-/*
- * Samsung S5P/EXYNOS4 SoC Camera Subsystem driver
- *
- * Copyright (C) 2013 Samsung Electronics Co., Ltd.
- * Author: Sylwester Nawrocki <s.nawrocki@samsung.com>
- */
-
-#include <linux/module.h>
-#include <media/drv-intf/exynos-fimc.h>
-#include "common.h"
-
-/*
- * Called with the media graph mutex held or media_entity_is_streaming(entity)
- * true.
- */
-struct v4l2_subdev *fimc_find_remote_sensor(struct media_entity *entity)
-{
- struct media_pad *pad = &entity->pads[0];
- struct v4l2_subdev *sd;
-
- while (pad->flags & MEDIA_PAD_FL_SINK) {
- /* source pad */
- pad = media_entity_remote_pad(pad);
- if (!pad || !is_media_entity_v4l2_subdev(pad->entity))
- break;
-
- sd = media_entity_to_v4l2_subdev(pad->entity);
-
- if (sd->grp_id == GRP_ID_FIMC_IS_SENSOR ||
- sd->grp_id == GRP_ID_SENSOR)
- return sd;
- /* sink pad */
- pad = &sd->entity.pads[0];
- }
- return NULL;
-}
-EXPORT_SYMBOL(fimc_find_remote_sensor);
-
-void __fimc_vidioc_querycap(struct device *dev, struct v4l2_capability *cap)
-{
- strscpy(cap->driver, dev->driver->name, sizeof(cap->driver));
- strscpy(cap->card, dev->driver->name, sizeof(cap->card));
- snprintf(cap->bus_info, sizeof(cap->bus_info),
- "platform:%s", dev_name(dev));
-}
-EXPORT_SYMBOL(__fimc_vidioc_querycap);
-
-MODULE_LICENSE("GPL");
diff --git a/drivers/media/platform/exynos4-is/common.h b/drivers/media/platform/exynos4-is/common.h
deleted file mode 100644
index 0389b66e5144..000000000000
--- a/drivers/media/platform/exynos4-is/common.h
+++ /dev/null
@@ -1,12 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-only */
-/*
- * Copyright (C) 2013 Samsung Electronics Co., Ltd.
- */
-
-#include <linux/device.h>
-#include <linux/videodev2.h>
-#include <media/media-entity.h>
-#include <media/v4l2-subdev.h>
-
-struct v4l2_subdev *fimc_find_remote_sensor(struct media_entity *entity);
-void __fimc_vidioc_querycap(struct device *dev, struct v4l2_capability *cap);
diff --git a/drivers/media/platform/exynos4-is/fimc-capture.c b/drivers/media/platform/exynos4-is/fimc-capture.c
deleted file mode 100644
index 7ff4024003f4..000000000000
--- a/drivers/media/platform/exynos4-is/fimc-capture.c
+++ /dev/null
@@ -1,1894 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-/*
- * Samsung S5P/EXYNOS4 SoC series camera interface (camera capture) driver
- *
- * Copyright (C) 2010 - 2012 Samsung Electronics Co., Ltd.
- * Sylwester Nawrocki <s.nawrocki@samsung.com>
- */
-
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/types.h>
-#include <linux/errno.h>
-#include <linux/bug.h>
-#include <linux/interrupt.h>
-#include <linux/device.h>
-#include <linux/pm_runtime.h>
-#include <linux/list.h>
-#include <linux/slab.h>
-
-#include <linux/videodev2.h>
-#include <media/v4l2-device.h>
-#include <media/v4l2-ioctl.h>
-#include <media/v4l2-mem2mem.h>
-#include <media/v4l2-rect.h>
-#include <media/videobuf2-v4l2.h>
-#include <media/videobuf2-dma-contig.h>
-
-#include "common.h"
-#include "fimc-core.h"
-#include "fimc-reg.h"
-#include "media-dev.h"
-
-static int fimc_capture_hw_init(struct fimc_dev *fimc)
-{
- struct fimc_source_info *si = &fimc->vid_cap.source_config;
- struct fimc_ctx *ctx = fimc->vid_cap.ctx;
- int ret;
- unsigned long flags;
-
- if (ctx == NULL || ctx->s_frame.fmt == NULL)
- return -EINVAL;
-
- if (si->fimc_bus_type == FIMC_BUS_TYPE_ISP_WRITEBACK) {
- ret = fimc_hw_camblk_cfg_writeback(fimc);
- if (ret < 0)
- return ret;
- }
-
- spin_lock_irqsave(&fimc->slock, flags);
- fimc_prepare_dma_offset(ctx, &ctx->d_frame);
- fimc_set_yuv_order(ctx);
-
- fimc_hw_set_camera_polarity(fimc, si);
- fimc_hw_set_camera_type(fimc, si);
- fimc_hw_set_camera_source(fimc, si);
- fimc_hw_set_camera_offset(fimc, &ctx->s_frame);
-
- ret = fimc_set_scaler_info(ctx);
- if (!ret) {
- fimc_hw_set_input_path(ctx);
- fimc_hw_set_prescaler(ctx);
- fimc_hw_set_mainscaler(ctx);
- fimc_hw_set_target_format(ctx);
- fimc_hw_set_rotation(ctx);
- fimc_hw_set_effect(ctx);
- fimc_hw_set_output_path(ctx);
- fimc_hw_set_out_dma(ctx);
- if (fimc->drv_data->alpha_color)
- fimc_hw_set_rgb_alpha(ctx);
- clear_bit(ST_CAPT_APPLY_CFG, &fimc->state);
- }
- spin_unlock_irqrestore(&fimc->slock, flags);
- return ret;
-}
-
-/*
- * Reinitialize the driver so it is ready to start the streaming again.
- * Set fimc->state to indicate stream off and the hardware shut down state.
- * If not suspending (@suspend is false), return any buffers to videobuf2.
- * Otherwise put any owned buffers onto the pending buffers queue, so they
- * can be re-spun when the device is being resumed. Also perform FIMC
- * software reset and disable streaming on the whole pipeline if required.
- */
-static int fimc_capture_state_cleanup(struct fimc_dev *fimc, bool suspend)
-{
- struct fimc_vid_cap *cap = &fimc->vid_cap;
- struct fimc_vid_buffer *buf;
- unsigned long flags;
- bool streaming;
-
- spin_lock_irqsave(&fimc->slock, flags);
- streaming = fimc->state & (1 << ST_CAPT_ISP_STREAM);
-
- fimc->state &= ~(1 << ST_CAPT_RUN | 1 << ST_CAPT_SHUT |
- 1 << ST_CAPT_STREAM | 1 << ST_CAPT_ISP_STREAM);
- if (suspend)
- fimc->state |= (1 << ST_CAPT_SUSPENDED);
- else
- fimc->state &= ~(1 << ST_CAPT_PEND | 1 << ST_CAPT_SUSPENDED);
-
- /* Release unused buffers */
- while (!suspend && !list_empty(&cap->pending_buf_q)) {
- buf = fimc_pending_queue_pop(cap);
- vb2_buffer_done(&buf->vb.vb2_buf, VB2_BUF_STATE_ERROR);
- }
- /* If suspending put unused buffers onto pending queue */
- while (!list_empty(&cap->active_buf_q)) {
- buf = fimc_active_queue_pop(cap);
- if (suspend)
- fimc_pending_queue_add(cap, buf);
- else
- vb2_buffer_done(&buf->vb.vb2_buf, VB2_BUF_STATE_ERROR);
- }
-
- fimc_hw_reset(fimc);
- cap->buf_index = 0;
-
- spin_unlock_irqrestore(&fimc->slock, flags);
-
- if (streaming)
- return fimc_pipeline_call(&cap->ve, set_stream, 0);
- else
- return 0;
-}
-
-static int fimc_stop_capture(struct fimc_dev *fimc, bool suspend)
-{
- unsigned long flags;
-
- if (!fimc_capture_active(fimc))
- return 0;
-
- spin_lock_irqsave(&fimc->slock, flags);
- set_bit(ST_CAPT_SHUT, &fimc->state);
- fimc_deactivate_capture(fimc);
- spin_unlock_irqrestore(&fimc->slock, flags);
-
- wait_event_timeout(fimc->irq_queue,
- !test_bit(ST_CAPT_SHUT, &fimc->state),
- (2*HZ/10)); /* 200 ms */
-
- return fimc_capture_state_cleanup(fimc, suspend);
-}
-
-/**
- * fimc_capture_config_update - apply the camera interface configuration
- * @ctx: FIMC capture context
- *
- * To be called from within the interrupt handler with fimc.slock
- * spinlock held. It updates the camera pixel crop, rotation and
- * image flip in H/W.
- */
-static int fimc_capture_config_update(struct fimc_ctx *ctx)
-{
- struct fimc_dev *fimc = ctx->fimc_dev;
- int ret;
-
- fimc_hw_set_camera_offset(fimc, &ctx->s_frame);
-
- ret = fimc_set_scaler_info(ctx);
- if (ret)
- return ret;
-
- fimc_hw_set_prescaler(ctx);
- fimc_hw_set_mainscaler(ctx);
- fimc_hw_set_target_format(ctx);
- fimc_hw_set_rotation(ctx);
- fimc_hw_set_effect(ctx);
- fimc_prepare_dma_offset(ctx, &ctx->d_frame);
- fimc_hw_set_out_dma(ctx);
- if (fimc->drv_data->alpha_color)
- fimc_hw_set_rgb_alpha(ctx);
-
- clear_bit(ST_CAPT_APPLY_CFG, &fimc->state);
- return ret;
-}
-
-void fimc_capture_irq_handler(struct fimc_dev *fimc, int deq_buf)
-{
- struct fimc_vid_cap *cap = &fimc->vid_cap;
- struct fimc_pipeline *p = to_fimc_pipeline(cap->ve.pipe);
- struct v4l2_subdev *csis = p->subdevs[IDX_CSIS];
- struct fimc_frame *f = &cap->ctx->d_frame;
- struct fimc_vid_buffer *v_buf;
-
- if (test_and_clear_bit(ST_CAPT_SHUT, &fimc->state)) {
- wake_up(&fimc->irq_queue);
- goto done;
- }
-
- if (!list_empty(&cap->active_buf_q) &&
- test_bit(ST_CAPT_RUN, &fimc->state) && deq_buf) {
- v_buf = fimc_active_queue_pop(cap);
-
- v_buf->vb.vb2_buf.timestamp = ktime_get_ns();
- v_buf->vb.sequence = cap->frame_count++;
-
- vb2_buffer_done(&v_buf->vb.vb2_buf, VB2_BUF_STATE_DONE);
- }
-
- if (!list_empty(&cap->pending_buf_q)) {
-
- v_buf = fimc_pending_queue_pop(cap);
- fimc_hw_set_output_addr(fimc, &v_buf->addr, cap->buf_index);
- v_buf->index = cap->buf_index;
-
- /* Move the buffer to the capture active queue */
- fimc_active_queue_add(cap, v_buf);
-
- dbg("next frame: %d, done frame: %d",
- fimc_hw_get_frame_index(fimc), v_buf->index);
-
- if (++cap->buf_index >= FIMC_MAX_OUT_BUFS)
- cap->buf_index = 0;
- }
- /*
- * Set up a buffer at MIPI-CSIS if current image format
- * requires the frame embedded data capture.
- */
- if (f->fmt->mdataplanes && !list_empty(&cap->active_buf_q)) {
- unsigned int plane = ffs(f->fmt->mdataplanes) - 1;
- unsigned int size = f->payload[plane];
- s32 index = fimc_hw_get_frame_index(fimc);
- void *vaddr;
-
- list_for_each_entry(v_buf, &cap->active_buf_q, list) {
- if (v_buf->index != index)
- continue;
- vaddr = vb2_plane_vaddr(&v_buf->vb.vb2_buf, plane);
- v4l2_subdev_call(csis, video, s_rx_buffer,
- vaddr, &size);
- break;
- }
- }
-
- if (cap->active_buf_cnt == 0) {
- if (deq_buf)
- clear_bit(ST_CAPT_RUN, &fimc->state);
-
- if (++cap->buf_index >= FIMC_MAX_OUT_BUFS)
- cap->buf_index = 0;
- } else {
- set_bit(ST_CAPT_RUN, &fimc->state);
- }
-
- if (test_bit(ST_CAPT_APPLY_CFG, &fimc->state))
- fimc_capture_config_update(cap->ctx);
-done:
- if (cap->active_buf_cnt == 1) {
- fimc_deactivate_capture(fimc);
- clear_bit(ST_CAPT_STREAM, &fimc->state);
- }
-
- dbg("frame: %d, active_buf_cnt: %d",
- fimc_hw_get_frame_index(fimc), cap->active_buf_cnt);
-}
-
-
-static int start_streaming(struct vb2_queue *q, unsigned int count)
-{
- struct fimc_ctx *ctx = q->drv_priv;
- struct fimc_dev *fimc = ctx->fimc_dev;
- struct fimc_vid_cap *vid_cap = &fimc->vid_cap;
- int min_bufs;
- int ret;
-
- vid_cap->frame_count = 0;
-
- ret = fimc_capture_hw_init(fimc);
- if (ret) {
- fimc_capture_state_cleanup(fimc, false);
- return ret;
- }
-
- set_bit(ST_CAPT_PEND, &fimc->state);
-
- min_bufs = fimc->vid_cap.reqbufs_count > 1 ? 2 : 1;
-
- if (vid_cap->active_buf_cnt >= min_bufs &&
- !test_and_set_bit(ST_CAPT_STREAM, &fimc->state)) {
- fimc_activate_capture(ctx);
-
- if (!test_and_set_bit(ST_CAPT_ISP_STREAM, &fimc->state))
- return fimc_pipeline_call(&vid_cap->ve, set_stream, 1);
- }
-
- return 0;
-}
-
-static void stop_streaming(struct vb2_queue *q)
-{
- struct fimc_ctx *ctx = q->drv_priv;
- struct fimc_dev *fimc = ctx->fimc_dev;
-
- if (!fimc_capture_active(fimc))
- return;
-
- fimc_stop_capture(fimc, false);
-}
-
-int fimc_capture_suspend(struct fimc_dev *fimc)
-{
- bool suspend = fimc_capture_busy(fimc);
-
- int ret = fimc_stop_capture(fimc, suspend);
- if (ret)
- return ret;
- return fimc_pipeline_call(&fimc->vid_cap.ve, close);
-}
-
-static void buffer_queue(struct vb2_buffer *vb);
-
-int fimc_capture_resume(struct fimc_dev *fimc)
-{
- struct fimc_vid_cap *vid_cap = &fimc->vid_cap;
- struct exynos_video_entity *ve = &vid_cap->ve;
- struct fimc_vid_buffer *buf;
- int i;
-
- if (!test_and_clear_bit(ST_CAPT_SUSPENDED, &fimc->state))
- return 0;
-
- INIT_LIST_HEAD(&fimc->vid_cap.active_buf_q);
- vid_cap->buf_index = 0;
- fimc_pipeline_call(ve, open, &ve->vdev.entity, false);
- fimc_capture_hw_init(fimc);
-
- clear_bit(ST_CAPT_SUSPENDED, &fimc->state);
-
- for (i = 0; i < vid_cap->reqbufs_count; i++) {
- if (list_empty(&vid_cap->pending_buf_q))
- break;
- buf = fimc_pending_queue_pop(vid_cap);
- buffer_queue(&buf->vb.vb2_buf);
- }
- return 0;
-
-}
-
-static int queue_setup(struct vb2_queue *vq,
- unsigned int *num_buffers, unsigned int *num_planes,
- unsigned int sizes[], struct device *alloc_devs[])
-{
- struct fimc_ctx *ctx = vq->drv_priv;
- struct fimc_frame *frame = &ctx->d_frame;
- struct fimc_fmt *fmt = frame->fmt;
- unsigned long wh = frame->f_width * frame->f_height;
- int i;
-
- if (fmt == NULL)
- return -EINVAL;
-
- if (*num_planes) {
- if (*num_planes != fmt->memplanes)
- return -EINVAL;
- for (i = 0; i < *num_planes; i++)
- if (sizes[i] < (wh * fmt->depth[i]) / 8)
- return -EINVAL;
- return 0;
- }
-
- *num_planes = fmt->memplanes;
-
- for (i = 0; i < fmt->memplanes; i++) {
- unsigned int size = (wh * fmt->depth[i]) / 8;
-
- if (fimc_fmt_is_user_defined(fmt->color))
- sizes[i] = frame->payload[i];
- else
- sizes[i] = max_t(u32, size, frame->payload[i]);
- }
-
- return 0;
-}
-
-static int buffer_prepare(struct vb2_buffer *vb)
-{
- struct vb2_queue *vq = vb->vb2_queue;
- struct fimc_ctx *ctx = vq->drv_priv;
- int i;
-
- if (ctx->d_frame.fmt == NULL)
- return -EINVAL;
-
- for (i = 0; i < ctx->d_frame.fmt->memplanes; i++) {
- unsigned long size = ctx->d_frame.payload[i];
-
- if (vb2_plane_size(vb, i) < size) {
- v4l2_err(&ctx->fimc_dev->vid_cap.ve.vdev,
- "User buffer too small (%ld < %ld)\n",
- vb2_plane_size(vb, i), size);
- return -EINVAL;
- }
- vb2_set_plane_payload(vb, i, size);
- }
-
- return 0;
-}
-
-static void buffer_queue(struct vb2_buffer *vb)
-{
- struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
- struct fimc_vid_buffer *buf
- = container_of(vbuf, struct fimc_vid_buffer, vb);
- struct fimc_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue);
- struct fimc_dev *fimc = ctx->fimc_dev;
- struct fimc_vid_cap *vid_cap = &fimc->vid_cap;
- struct exynos_video_entity *ve = &vid_cap->ve;
- unsigned long flags;
- int min_bufs;
-
- spin_lock_irqsave(&fimc->slock, flags);
- fimc_prepare_addr(ctx, &buf->vb.vb2_buf, &ctx->d_frame, &buf->addr);
-
- if (!test_bit(ST_CAPT_SUSPENDED, &fimc->state) &&
- !test_bit(ST_CAPT_STREAM, &fimc->state) &&
- vid_cap->active_buf_cnt < FIMC_MAX_OUT_BUFS) {
- /* Setup the buffer directly for processing. */
- int buf_id = (vid_cap->reqbufs_count == 1) ? -1 :
- vid_cap->buf_index;
-
- fimc_hw_set_output_addr(fimc, &buf->addr, buf_id);
- buf->index = vid_cap->buf_index;
- fimc_active_queue_add(vid_cap, buf);
-
- if (++vid_cap->buf_index >= FIMC_MAX_OUT_BUFS)
- vid_cap->buf_index = 0;
- } else {
- fimc_pending_queue_add(vid_cap, buf);
- }
-
- min_bufs = vid_cap->reqbufs_count > 1 ? 2 : 1;
-
-
- if (vb2_is_streaming(&vid_cap->vbq) &&
- vid_cap->active_buf_cnt >= min_bufs &&
- !test_and_set_bit(ST_CAPT_STREAM, &fimc->state)) {
- int ret;
-
- fimc_activate_capture(ctx);
- spin_unlock_irqrestore(&fimc->slock, flags);
-
- if (test_and_set_bit(ST_CAPT_ISP_STREAM, &fimc->state))
- return;
-
- ret = fimc_pipeline_call(ve, set_stream, 1);
- if (ret < 0)
- v4l2_err(&ve->vdev, "stream on failed: %d\n", ret);
- return;
- }
- spin_unlock_irqrestore(&fimc->slock, flags);
-}
-
-static const struct vb2_ops fimc_capture_qops = {
- .queue_setup = queue_setup,
- .buf_prepare = buffer_prepare,
- .buf_queue = buffer_queue,
- .wait_prepare = vb2_ops_wait_prepare,
- .wait_finish = vb2_ops_wait_finish,
- .start_streaming = start_streaming,
- .stop_streaming = stop_streaming,
-};
-
-static int fimc_capture_set_default_format(struct fimc_dev *fimc);
-
-static int fimc_capture_open(struct file *file)
-{
- struct fimc_dev *fimc = video_drvdata(file);
- struct fimc_vid_cap *vc = &fimc->vid_cap;
- struct exynos_video_entity *ve = &vc->ve;
- int ret = -EBUSY;
-
- dbg("pid: %d, state: 0x%lx", task_pid_nr(current), fimc->state);
-
- mutex_lock(&fimc->lock);
-
- if (fimc_m2m_active(fimc))
- goto unlock;
-
- set_bit(ST_CAPT_BUSY, &fimc->state);
- ret = pm_runtime_resume_and_get(&fimc->pdev->dev);
- if (ret < 0)
- goto unlock;
-
- ret = v4l2_fh_open(file);
- if (ret) {
- pm_runtime_put_sync(&fimc->pdev->dev);
- goto unlock;
- }
-
- if (v4l2_fh_is_singular_file(file)) {
- fimc_md_graph_lock(ve);
-
- ret = fimc_pipeline_call(ve, open, &ve->vdev.entity, true);
-
- if (ret == 0)
- ve->vdev.entity.use_count++;
-
- fimc_md_graph_unlock(ve);
-
- if (ret == 0)
- ret = fimc_capture_set_default_format(fimc);
-
- if (ret < 0) {
- clear_bit(ST_CAPT_BUSY, &fimc->state);
- pm_runtime_put_sync(&fimc->pdev->dev);
- v4l2_fh_release(file);
- }
- }
-unlock:
- mutex_unlock(&fimc->lock);
- return ret;
-}
-
-static int fimc_capture_release(struct file *file)
-{
- struct fimc_dev *fimc = video_drvdata(file);
- struct fimc_vid_cap *vc = &fimc->vid_cap;
- bool close = v4l2_fh_is_singular_file(file);
- int ret;
-
- dbg("pid: %d, state: 0x%lx", task_pid_nr(current), fimc->state);
-
- mutex_lock(&fimc->lock);
-
- if (close && vc->streaming) {
- media_pipeline_stop(&vc->ve.vdev.entity);
- vc->streaming = false;
- }
-
- ret = _vb2_fop_release(file, NULL);
-
- if (close) {
- clear_bit(ST_CAPT_BUSY, &fimc->state);
- fimc_pipeline_call(&vc->ve, close);
- clear_bit(ST_CAPT_SUSPENDED, &fimc->state);
-
- fimc_md_graph_lock(&vc->ve);
- vc->ve.vdev.entity.use_count--;
- fimc_md_graph_unlock(&vc->ve);
- }
-
- pm_runtime_put_sync(&fimc->pdev->dev);
- mutex_unlock(&fimc->lock);
-
- return ret;
-}
-
-static const struct v4l2_file_operations fimc_capture_fops = {
- .owner = THIS_MODULE,
- .open = fimc_capture_open,
- .release = fimc_capture_release,
- .poll = vb2_fop_poll,
- .unlocked_ioctl = video_ioctl2,
- .mmap = vb2_fop_mmap,
-};
-
-/*
- * Format and crop negotiation helpers
- */
-
-static struct fimc_fmt *fimc_capture_try_format(struct fimc_ctx *ctx,
- u32 *width, u32 *height,
- u32 *code, u32 *fourcc, int pad)
-{
- bool rotation = ctx->rotation == 90 || ctx->rotation == 270;
- struct fimc_dev *fimc = ctx->fimc_dev;
- const struct fimc_variant *var = fimc->variant;
- const struct fimc_pix_limit *pl = var->pix_limit;
- struct fimc_frame *dst = &ctx->d_frame;
- u32 depth, min_w, max_w, min_h, align_h = 3;
- u32 mask = FMT_FLAGS_CAM;
- struct fimc_fmt *ffmt;
-
- /* Conversion from/to JPEG or User Defined format is not supported */
- if (code && ctx->s_frame.fmt && pad == FIMC_SD_PAD_SOURCE &&
- fimc_fmt_is_user_defined(ctx->s_frame.fmt->color))
- *code = ctx->s_frame.fmt->mbus_code;
-
- if (fourcc && *fourcc != V4L2_PIX_FMT_JPEG && pad == FIMC_SD_PAD_SOURCE)
- mask |= FMT_FLAGS_M2M;
-
- if (pad == FIMC_SD_PAD_SINK_FIFO)
- mask = FMT_FLAGS_WRITEBACK;
-
- ffmt = fimc_find_format(fourcc, code, mask, 0);
- if (WARN_ON(!ffmt))
- return NULL;
-
- if (code)
- *code = ffmt->mbus_code;
- if (fourcc)
- *fourcc = ffmt->fourcc;
-
- if (pad != FIMC_SD_PAD_SOURCE) {
- max_w = fimc_fmt_is_user_defined(ffmt->color) ?
- pl->scaler_dis_w : pl->scaler_en_w;
- /* Apply the camera input interface pixel constraints */
- v4l_bound_align_image(width, max_t(u32, *width, 32), max_w, 4,
- height, max_t(u32, *height, 32),
- FIMC_CAMIF_MAX_HEIGHT,
- fimc_fmt_is_user_defined(ffmt->color) ?
- 3 : 1,
- 0);
- return ffmt;
- }
- /* Can't scale or crop in transparent (JPEG) transfer mode */
- if (fimc_fmt_is_user_defined(ffmt->color)) {
- *width = ctx->s_frame.f_width;
- *height = ctx->s_frame.f_height;
- return ffmt;
- }
- /* Apply the scaler and the output DMA constraints */
- max_w = rotation ? pl->out_rot_en_w : pl->out_rot_dis_w;
- if (ctx->state & FIMC_COMPOSE) {
- min_w = dst->offs_h + dst->width;
- min_h = dst->offs_v + dst->height;
- } else {
- min_w = var->min_out_pixsize;
- min_h = var->min_out_pixsize;
- }
- if (var->min_vsize_align == 1 && !rotation)
- align_h = fimc_fmt_is_rgb(ffmt->color) ? 0 : 1;
-
- depth = fimc_get_format_depth(ffmt);
- v4l_bound_align_image(width, min_w, max_w,
- ffs(var->min_out_pixsize) - 1,
- height, min_h, FIMC_CAMIF_MAX_HEIGHT,
- align_h,
- 64/(ALIGN(depth, 8)));
-
- dbg("pad%d: code: 0x%x, %dx%d. dst fmt: %dx%d",
- pad, code ? *code : 0, *width, *height,
- dst->f_width, dst->f_height);
-
- return ffmt;
-}
-
-static void fimc_capture_try_selection(struct fimc_ctx *ctx,
- struct v4l2_rect *r,
- int target)
-{
- bool rotate = ctx->rotation == 90 || ctx->rotation == 270;
- struct fimc_dev *fimc = ctx->fimc_dev;
- const struct fimc_variant *var = fimc->variant;
- const struct fimc_pix_limit *pl = var->pix_limit;
- struct fimc_frame *sink = &ctx->s_frame;
- u32 max_w, max_h, min_w = 0, min_h = 0, min_sz;
- u32 align_sz = 0, align_h = 4;
- u32 max_sc_h, max_sc_v;
-
- /* In JPEG transparent transfer mode cropping is not supported */
- if (fimc_fmt_is_user_defined(ctx->d_frame.fmt->color)) {
- r->width = sink->f_width;
- r->height = sink->f_height;
- r->left = r->top = 0;
- return;
- }
- if (target == V4L2_SEL_TGT_COMPOSE) {
- u32 tmp_min_h = ffs(sink->width) - 3;
- u32 tmp_min_v = ffs(sink->height) - 1;
-
- if (ctx->rotation != 90 && ctx->rotation != 270)
- align_h = 1;
- max_sc_h = min(SCALER_MAX_HRATIO, 1 << tmp_min_h);
- max_sc_v = min(SCALER_MAX_VRATIO, 1 << tmp_min_v);
- min_sz = var->min_out_pixsize;
- } else {
- u32 depth = fimc_get_format_depth(sink->fmt);
- align_sz = 64/ALIGN(depth, 8);
- min_sz = var->min_inp_pixsize;
- min_w = min_h = min_sz;
- max_sc_h = max_sc_v = 1;
- }
- /*
- * For the compose rectangle the following constraints must be met:
- * - it must fit in the sink pad format rectangle (f_width/f_height);
- * - maximum downscaling ratio is 64;
- * - maximum crop size depends if the rotator is used or not;
- * - the sink pad format width/height must be 4 multiple of the
- * prescaler ratios determined by sink pad size and source pad crop,
- * the prescaler ratio is returned by fimc_get_scaler_factor().
- */
- max_w = min_t(u32,
- rotate ? pl->out_rot_en_w : pl->out_rot_dis_w,
- rotate ? sink->f_height : sink->f_width);
- max_h = min_t(u32, FIMC_CAMIF_MAX_HEIGHT, sink->f_height);
-
- if (target == V4L2_SEL_TGT_COMPOSE) {
- min_w = min_t(u32, max_w, sink->f_width / max_sc_h);
- min_h = min_t(u32, max_h, sink->f_height / max_sc_v);
- if (rotate) {
- swap(max_sc_h, max_sc_v);
- swap(min_w, min_h);
- }
- }
- v4l_bound_align_image(&r->width, min_w, max_w, ffs(min_sz) - 1,
- &r->height, min_h, max_h, align_h,
- align_sz);
- /* Adjust left/top if crop/compose rectangle is out of bounds */
- r->left = clamp_t(u32, r->left, 0, sink->f_width - r->width);
- r->top = clamp_t(u32, r->top, 0, sink->f_height - r->height);
- r->left = round_down(r->left, var->hor_offs_align);
-
- dbg("target %#x: (%d,%d)/%dx%d, sink fmt: %dx%d",
- target, r->left, r->top, r->width, r->height,
- sink->f_width, sink->f_height);
-}
-
-/*
- * The video node ioctl operations
- */
-static int fimc_cap_querycap(struct file *file, void *priv,
- struct v4l2_capability *cap)
-{
- struct fimc_dev *fimc = video_drvdata(file);
-
- __fimc_vidioc_querycap(&fimc->pdev->dev, cap);
- return 0;
-}
-
-static int fimc_cap_enum_fmt(struct file *file, void *priv,
- struct v4l2_fmtdesc *f)
-{
- struct fimc_fmt *fmt;
-
- fmt = fimc_find_format(NULL, NULL, FMT_FLAGS_CAM | FMT_FLAGS_M2M,
- f->index);
- if (!fmt)
- return -EINVAL;
- f->pixelformat = fmt->fourcc;
- return 0;
-}
-
-static struct media_entity *fimc_pipeline_get_head(struct media_entity *me)
-{
- struct media_pad *pad = &me->pads[0];
-
- while (!(pad->flags & MEDIA_PAD_FL_SOURCE)) {
- pad = media_entity_remote_pad(pad);
- if (!pad)
- break;
- me = pad->entity;
- pad = &me->pads[0];
- }
-
- return me;
-}
-
-/**
- * fimc_pipeline_try_format - negotiate and/or set formats at pipeline
- * elements
- * @ctx: FIMC capture context
- * @tfmt: media bus format to try/set on subdevs
- * @fmt_id: fimc pixel format id corresponding to returned @tfmt (output)
- * @set: true to set format on subdevs, false to try only
- */
-static int fimc_pipeline_try_format(struct fimc_ctx *ctx,
- struct v4l2_mbus_framefmt *tfmt,
- struct fimc_fmt **fmt_id,
- bool set)
-{
- struct fimc_dev *fimc = ctx->fimc_dev;
- struct fimc_pipeline *p = to_fimc_pipeline(fimc->vid_cap.ve.pipe);
- struct v4l2_subdev *sd = p->subdevs[IDX_SENSOR];
- struct v4l2_subdev_format sfmt;
- struct v4l2_mbus_framefmt *mf = &sfmt.format;
- struct media_entity *me;
- struct fimc_fmt *ffmt;
- struct media_pad *pad;
- int ret, i = 1;
- u32 fcc;
-
- if (WARN_ON(!sd || !tfmt))
- return -EINVAL;
-
- memset(&sfmt, 0, sizeof(sfmt));
- sfmt.format = *tfmt;
- sfmt.which = set ? V4L2_SUBDEV_FORMAT_ACTIVE : V4L2_SUBDEV_FORMAT_TRY;
-
- me = fimc_pipeline_get_head(&sd->entity);
-
- while (1) {
- ffmt = fimc_find_format(NULL, mf->code != 0 ? &mf->code : NULL,
- FMT_FLAGS_CAM, i++);
- if (ffmt == NULL) {
- /*
- * Notify user-space if common pixel code for
- * host and sensor does not exist.
- */
- return -EINVAL;
- }
- mf->code = tfmt->code = ffmt->mbus_code;
-
- /* set format on all pipeline subdevs */
- while (me != &fimc->vid_cap.subdev.entity) {
- sd = media_entity_to_v4l2_subdev(me);
-
- sfmt.pad = 0;
- ret = v4l2_subdev_call(sd, pad, set_fmt, NULL, &sfmt);
- if (ret)
- return ret;
-
- if (me->pads[0].flags & MEDIA_PAD_FL_SINK) {
- sfmt.pad = me->num_pads - 1;
- mf->code = tfmt->code;
- ret = v4l2_subdev_call(sd, pad, set_fmt, NULL,
- &sfmt);
- if (ret)
- return ret;
- }
-
- pad = media_entity_remote_pad(&me->pads[sfmt.pad]);
- if (!pad)
- return -EINVAL;
- me = pad->entity;
- }
-
- if (mf->code != tfmt->code)
- continue;
-
- fcc = ffmt->fourcc;
- tfmt->width = mf->width;
- tfmt->height = mf->height;
- ffmt = fimc_capture_try_format(ctx, &tfmt->width, &tfmt->height,
- NULL, &fcc, FIMC_SD_PAD_SINK_CAM);
- ffmt = fimc_capture_try_format(ctx, &tfmt->width, &tfmt->height,
- NULL, &fcc, FIMC_SD_PAD_SOURCE);
- if (ffmt && ffmt->mbus_code)
- mf->code = ffmt->mbus_code;
- if (mf->width != tfmt->width || mf->height != tfmt->height)
- continue;
- tfmt->code = mf->code;
- break;
- }
-
- if (fmt_id && ffmt)
- *fmt_id = ffmt;
- *tfmt = *mf;
-
- return 0;
-}
-
-/**
- * fimc_get_sensor_frame_desc - query the sensor for media bus frame parameters
- * @sensor: pointer to the sensor subdev
- * @plane_fmt: provides plane sizes corresponding to the frame layout entries
- * @num_planes: number of planes
- * @try: true to set the frame parameters, false to query only
- *
- * This function is used by this driver only for compressed/blob data formats.
- */
-static int fimc_get_sensor_frame_desc(struct v4l2_subdev *sensor,
- struct v4l2_plane_pix_format *plane_fmt,
- unsigned int num_planes, bool try)
-{
- struct v4l2_mbus_frame_desc fd;
- int i, ret;
- int pad;
-
- for (i = 0; i < num_planes; i++)
- fd.entry[i].length = plane_fmt[i].sizeimage;
-
- pad = sensor->entity.num_pads - 1;
- if (try)
- ret = v4l2_subdev_call(sensor, pad, set_frame_desc, pad, &fd);
- else
- ret = v4l2_subdev_call(sensor, pad, get_frame_desc, pad, &fd);
-
- if (ret < 0)
- return ret;
-
- if (num_planes != fd.num_entries)
- return -EINVAL;
-
- for (i = 0; i < num_planes; i++)
- plane_fmt[i].sizeimage = fd.entry[i].length;
-
- if (fd.entry[0].length > FIMC_MAX_JPEG_BUF_SIZE) {
- v4l2_err(sensor->v4l2_dev, "Unsupported buffer size: %u\n",
- fd.entry[0].length);
-
- return -EINVAL;
- }
-
- return 0;
-}
-
-static int fimc_cap_g_fmt_mplane(struct file *file, void *fh,
- struct v4l2_format *f)
-{
- struct fimc_dev *fimc = video_drvdata(file);
-
- __fimc_get_format(&fimc->vid_cap.ctx->d_frame, f);
- return 0;
-}
-
-/*
- * Try or set format on the fimc.X.capture video node and additionally
- * on the whole pipeline if @try is false.
- * Locking: the caller must _not_ hold the graph mutex.
- */
-static int __video_try_or_set_format(struct fimc_dev *fimc,
- struct v4l2_format *f, bool try,
- struct fimc_fmt **inp_fmt,
- struct fimc_fmt **out_fmt)
-{
- struct v4l2_pix_format_mplane *pix = &f->fmt.pix_mp;
- struct fimc_vid_cap *vc = &fimc->vid_cap;
- struct exynos_video_entity *ve = &vc->ve;
- struct fimc_ctx *ctx = vc->ctx;
- unsigned int width = 0, height = 0;
- int ret = 0;
-
- /* Pre-configure format at the camera input interface, for JPEG only */
- if (fimc_jpeg_fourcc(pix->pixelformat)) {
- fimc_capture_try_format(ctx, &pix->width, &pix->height,
- NULL, &pix->pixelformat,
- FIMC_SD_PAD_SINK_CAM);
- if (try) {
- width = pix->width;
- height = pix->height;
- } else {
- ctx->s_frame.f_width = pix->width;
- ctx->s_frame.f_height = pix->height;
- }
- }
-
- /* Try the format at the scaler and the DMA output */
- *out_fmt = fimc_capture_try_format(ctx, &pix->width, &pix->height,
- NULL, &pix->pixelformat,
- FIMC_SD_PAD_SOURCE);
- if (*out_fmt == NULL)
- return -EINVAL;
-
- /* Restore image width/height for JPEG (no resizing supported). */
- if (try && fimc_jpeg_fourcc(pix->pixelformat)) {
- pix->width = width;
- pix->height = height;
- }
-
- /* Try to match format at the host and the sensor */
- if (!vc->user_subdev_api) {
- struct v4l2_mbus_framefmt mbus_fmt;
- struct v4l2_mbus_framefmt *mf;
-
- mf = try ? &mbus_fmt : &fimc->vid_cap.ci_fmt;
-
- mf->code = (*out_fmt)->mbus_code;
- mf->width = pix->width;
- mf->height = pix->height;
-
- fimc_md_graph_lock(ve);
- ret = fimc_pipeline_try_format(ctx, mf, inp_fmt, try);
- fimc_md_graph_unlock(ve);
-
- if (ret < 0)
- return ret;
-
- pix->width = mf->width;
- pix->height = mf->height;
- }
-
- fimc_adjust_mplane_format(*out_fmt, pix->width, pix->height, pix);
-
- if ((*out_fmt)->flags & FMT_FLAGS_COMPRESSED) {
- struct v4l2_subdev *sensor;
-
- fimc_md_graph_lock(ve);
-
- sensor = __fimc_md_get_subdev(ve->pipe, IDX_SENSOR);
- if (sensor)
- fimc_get_sensor_frame_desc(sensor, pix->plane_fmt,
- (*out_fmt)->memplanes, try);
- else
- ret = -EPIPE;
-
- fimc_md_graph_unlock(ve);
- }
-
- return ret;
-}
-
-static int fimc_cap_try_fmt_mplane(struct file *file, void *fh,
- struct v4l2_format *f)
-{
- struct fimc_dev *fimc = video_drvdata(file);
- struct fimc_fmt *out_fmt = NULL, *inp_fmt = NULL;
-
- return __video_try_or_set_format(fimc, f, true, &inp_fmt, &out_fmt);
-}
-
-static void fimc_capture_mark_jpeg_xfer(struct fimc_ctx *ctx,
- enum fimc_color_fmt color)
-{
- bool jpeg = fimc_fmt_is_user_defined(color);
-
- ctx->scaler.enabled = !jpeg;
- fimc_ctrls_activate(ctx, !jpeg);
-
- if (jpeg)
- set_bit(ST_CAPT_JPEG, &ctx->fimc_dev->state);
- else
- clear_bit(ST_CAPT_JPEG, &ctx->fimc_dev->state);
-}
-
-static int __fimc_capture_set_format(struct fimc_dev *fimc,
- struct v4l2_format *f)
-{
- struct fimc_vid_cap *vc = &fimc->vid_cap;
- struct fimc_ctx *ctx = vc->ctx;
- struct v4l2_pix_format_mplane *pix = &f->fmt.pix_mp;
- struct fimc_frame *ff = &ctx->d_frame;
- struct fimc_fmt *inp_fmt = NULL;
- int ret, i;
-
- if (vb2_is_busy(&fimc->vid_cap.vbq))
- return -EBUSY;
-
- ret = __video_try_or_set_format(fimc, f, false, &inp_fmt, &ff->fmt);
- if (ret < 0)
- return ret;
-
- /* Update RGB Alpha control state and value range */
- fimc_alpha_ctrl_update(ctx);
-
- for (i = 0; i < ff->fmt->memplanes; i++) {
- ff->bytesperline[i] = pix->plane_fmt[i].bytesperline;
- ff->payload[i] = pix->plane_fmt[i].sizeimage;
- }
-
- set_frame_bounds(ff, pix->width, pix->height);
- /* Reset the composition rectangle if not yet configured */
- if (!(ctx->state & FIMC_COMPOSE))
- set_frame_crop(ff, 0, 0, pix->width, pix->height);
-
- fimc_capture_mark_jpeg_xfer(ctx, ff->fmt->color);
-
- /* Reset cropping and set format at the camera interface input */
- if (!vc->user_subdev_api) {
- ctx->s_frame.fmt = inp_fmt;
- set_frame_bounds(&ctx->s_frame, pix->width, pix->height);
- set_frame_crop(&ctx->s_frame, 0, 0, pix->width, pix->height);
- }
-
- return ret;
-}
-
-static int fimc_cap_s_fmt_mplane(struct file *file, void *priv,
- struct v4l2_format *f)
-{
- struct fimc_dev *fimc = video_drvdata(file);
-
- return __fimc_capture_set_format(fimc, f);
-}
-
-static int fimc_cap_enum_input(struct file *file, void *priv,
- struct v4l2_input *i)
-{
- struct fimc_dev *fimc = video_drvdata(file);
- struct exynos_video_entity *ve = &fimc->vid_cap.ve;
- struct v4l2_subdev *sd;
-
- if (i->index != 0)
- return -EINVAL;
-
- i->type = V4L2_INPUT_TYPE_CAMERA;
- fimc_md_graph_lock(ve);
- sd = __fimc_md_get_subdev(ve->pipe, IDX_SENSOR);
- fimc_md_graph_unlock(ve);
-
- if (sd)
- strscpy(i->name, sd->name, sizeof(i->name));
-
- return 0;
-}
-
-static int fimc_cap_s_input(struct file *file, void *priv, unsigned int i)
-{
- return i == 0 ? i : -EINVAL;
-}
-
-static int fimc_cap_g_input(struct file *file, void *priv, unsigned int *i)
-{
- *i = 0;
- return 0;
-}
-
-/**
- * fimc_pipeline_validate - check for formats inconsistencies
- * between source and sink pad of each link
- * @fimc: the FIMC device this context applies to
- *
- * Return 0 if all formats match or -EPIPE otherwise.
- */
-static int fimc_pipeline_validate(struct fimc_dev *fimc)
-{
- struct v4l2_subdev_format sink_fmt, src_fmt;
- struct fimc_vid_cap *vc = &fimc->vid_cap;
- struct v4l2_subdev *sd = &vc->subdev;
- struct fimc_pipeline *p = to_fimc_pipeline(vc->ve.pipe);
- struct media_pad *sink_pad, *src_pad;
- int i, ret;
-
- while (1) {
- /*
- * Find current entity sink pad and any remote sink pad linked
- * to it. We stop if there is no sink pad in current entity or
- * it is not linked to any other remote entity.
- */
- src_pad = NULL;
-
- for (i = 0; i < sd->entity.num_pads; i++) {
- struct media_pad *p = &sd->entity.pads[i];
-
- if (p->flags & MEDIA_PAD_FL_SINK) {
- sink_pad = p;
- src_pad = media_entity_remote_pad(sink_pad);
- if (src_pad)
- break;
- }
- }
-
- if (!src_pad || !is_media_entity_v4l2_subdev(src_pad->entity))
- break;
-
- /* Don't call FIMC subdev operation to avoid nested locking */
- if (sd == &vc->subdev) {
- struct fimc_frame *ff = &vc->ctx->s_frame;
- sink_fmt.format.width = ff->f_width;
- sink_fmt.format.height = ff->f_height;
- sink_fmt.format.code = ff->fmt ? ff->fmt->mbus_code : 0;
- } else {
- sink_fmt.pad = sink_pad->index;
- sink_fmt.which = V4L2_SUBDEV_FORMAT_ACTIVE;
- ret = v4l2_subdev_call(sd, pad, get_fmt, NULL, &sink_fmt);
- if (ret < 0 && ret != -ENOIOCTLCMD)
- return -EPIPE;
- }
-
- /* Retrieve format at the source pad */
- sd = media_entity_to_v4l2_subdev(src_pad->entity);
- src_fmt.pad = src_pad->index;
- src_fmt.which = V4L2_SUBDEV_FORMAT_ACTIVE;
- ret = v4l2_subdev_call(sd, pad, get_fmt, NULL, &src_fmt);
- if (ret < 0 && ret != -ENOIOCTLCMD)
- return -EPIPE;
-
- if (src_fmt.format.width != sink_fmt.format.width ||
- src_fmt.format.height != sink_fmt.format.height ||
- src_fmt.format.code != sink_fmt.format.code)
- return -EPIPE;
-
- if (sd == p->subdevs[IDX_SENSOR] &&
- fimc_user_defined_mbus_fmt(src_fmt.format.code)) {
- struct v4l2_plane_pix_format plane_fmt[FIMC_MAX_PLANES];
- struct fimc_frame *frame = &vc->ctx->d_frame;
- unsigned int i;
-
- ret = fimc_get_sensor_frame_desc(sd, plane_fmt,
- frame->fmt->memplanes,
- false);
- if (ret < 0)
- return -EPIPE;
-
- for (i = 0; i < frame->fmt->memplanes; i++)
- if (frame->payload[i] < plane_fmt[i].sizeimage)
- return -EPIPE;
- }
- }
- return 0;
-}
-
-static int fimc_cap_streamon(struct file *file, void *priv,
- enum v4l2_buf_type type)
-{
- struct fimc_dev *fimc = video_drvdata(file);
- struct fimc_vid_cap *vc = &fimc->vid_cap;
- struct media_entity *entity = &vc->ve.vdev.entity;
- struct fimc_source_info *si = NULL;
- struct v4l2_subdev *sd;
- int ret;
-
- if (fimc_capture_active(fimc))
- return -EBUSY;
-
- ret = media_pipeline_start(entity, &vc->ve.pipe->mp);
- if (ret < 0)
- return ret;
-
- sd = __fimc_md_get_subdev(vc->ve.pipe, IDX_SENSOR);
- if (sd)
- si = v4l2_get_subdev_hostdata(sd);
-
- if (si == NULL) {
- ret = -EPIPE;
- goto err_p_stop;
- }
- /*
- * Save configuration data related to currently attached image
- * sensor or other data source, e.g. FIMC-IS.
- */
- vc->source_config = *si;
-
- if (vc->input == GRP_ID_FIMC_IS)
- vc->source_config.fimc_bus_type = FIMC_BUS_TYPE_ISP_WRITEBACK;
-
- if (vc->user_subdev_api) {
- ret = fimc_pipeline_validate(fimc);
- if (ret < 0)
- goto err_p_stop;
- }
-
- ret = vb2_ioctl_streamon(file, priv, type);
- if (!ret) {
- vc->streaming = true;
- return ret;
- }
-
-err_p_stop:
- media_pipeline_stop(entity);
- return ret;
-}
-
-static int fimc_cap_streamoff(struct file *file, void *priv,
- enum v4l2_buf_type type)
-{
- struct fimc_dev *fimc = video_drvdata(file);
- struct fimc_vid_cap *vc = &fimc->vid_cap;
- int ret;
-
- ret = vb2_ioctl_streamoff(file, priv, type);
- if (ret < 0)
- return ret;
-
- if (vc->streaming) {
- media_pipeline_stop(&vc->ve.vdev.entity);
- vc->streaming = false;
- }
-
- return 0;
-}
-
-static int fimc_cap_reqbufs(struct file *file, void *priv,
- struct v4l2_requestbuffers *reqbufs)
-{
- struct fimc_dev *fimc = video_drvdata(file);
- int ret;
-
- ret = vb2_ioctl_reqbufs(file, priv, reqbufs);
-
- if (!ret)
- fimc->vid_cap.reqbufs_count = reqbufs->count;
-
- return ret;
-}
-
-static int fimc_cap_g_selection(struct file *file, void *fh,
- struct v4l2_selection *s)
-{
- struct fimc_dev *fimc = video_drvdata(file);
- struct fimc_ctx *ctx = fimc->vid_cap.ctx;
- struct fimc_frame *f = &ctx->s_frame;
-
- if (s->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
- return -EINVAL;
-
- switch (s->target) {
- case V4L2_SEL_TGT_COMPOSE_DEFAULT:
- case V4L2_SEL_TGT_COMPOSE_BOUNDS:
- f = &ctx->d_frame;
- fallthrough;
- case V4L2_SEL_TGT_CROP_BOUNDS:
- case V4L2_SEL_TGT_CROP_DEFAULT:
- s->r.left = 0;
- s->r.top = 0;
- s->r.width = f->o_width;
- s->r.height = f->o_height;
- return 0;
-
- case V4L2_SEL_TGT_COMPOSE:
- f = &ctx->d_frame;
- fallthrough;
- case V4L2_SEL_TGT_CROP:
- s->r.left = f->offs_h;
- s->r.top = f->offs_v;
- s->r.width = f->width;
- s->r.height = f->height;
- return 0;
- }
-
- return -EINVAL;
-}
-
-static int fimc_cap_s_selection(struct file *file, void *fh,
- struct v4l2_selection *s)
-{
- struct fimc_dev *fimc = video_drvdata(file);
- struct fimc_ctx *ctx = fimc->vid_cap.ctx;
- struct v4l2_rect rect = s->r;
- struct fimc_frame *f;
- unsigned long flags;
-
- if (s->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
- return -EINVAL;
-
- if (s->target == V4L2_SEL_TGT_COMPOSE)
- f = &ctx->d_frame;
- else if (s->target == V4L2_SEL_TGT_CROP)
- f = &ctx->s_frame;
- else
- return -EINVAL;
-
- fimc_capture_try_selection(ctx, &rect, s->target);
-
- if (s->flags & V4L2_SEL_FLAG_LE &&
- !v4l2_rect_enclosed(&rect, &s->r))
- return -ERANGE;
-
- if (s->flags & V4L2_SEL_FLAG_GE &&
- !v4l2_rect_enclosed(&s->r, &rect))
- return -ERANGE;
-
- s->r = rect;
- spin_lock_irqsave(&fimc->slock, flags);
- set_frame_crop(f, s->r.left, s->r.top, s->r.width,
- s->r.height);
- spin_unlock_irqrestore(&fimc->slock, flags);
-
- set_bit(ST_CAPT_APPLY_CFG, &fimc->state);
- return 0;
-}
-
-static const struct v4l2_ioctl_ops fimc_capture_ioctl_ops = {
- .vidioc_querycap = fimc_cap_querycap,
-
- .vidioc_enum_fmt_vid_cap = fimc_cap_enum_fmt,
- .vidioc_try_fmt_vid_cap_mplane = fimc_cap_try_fmt_mplane,
- .vidioc_s_fmt_vid_cap_mplane = fimc_cap_s_fmt_mplane,
- .vidioc_g_fmt_vid_cap_mplane = fimc_cap_g_fmt_mplane,
-
- .vidioc_reqbufs = fimc_cap_reqbufs,
- .vidioc_querybuf = vb2_ioctl_querybuf,
- .vidioc_qbuf = vb2_ioctl_qbuf,
- .vidioc_dqbuf = vb2_ioctl_dqbuf,
- .vidioc_expbuf = vb2_ioctl_expbuf,
- .vidioc_prepare_buf = vb2_ioctl_prepare_buf,
- .vidioc_create_bufs = vb2_ioctl_create_bufs,
-
- .vidioc_streamon = fimc_cap_streamon,
- .vidioc_streamoff = fimc_cap_streamoff,
-
- .vidioc_g_selection = fimc_cap_g_selection,
- .vidioc_s_selection = fimc_cap_s_selection,
-
- .vidioc_enum_input = fimc_cap_enum_input,
- .vidioc_s_input = fimc_cap_s_input,
- .vidioc_g_input = fimc_cap_g_input,
-};
-
-/* Capture subdev media entity operations */
-static int fimc_link_setup(struct media_entity *entity,
- const struct media_pad *local,
- const struct media_pad *remote, u32 flags)
-{
- struct v4l2_subdev *sd = media_entity_to_v4l2_subdev(entity);
- struct fimc_dev *fimc = v4l2_get_subdevdata(sd);
- struct fimc_vid_cap *vc = &fimc->vid_cap;
- struct v4l2_subdev *sensor;
-
- if (!is_media_entity_v4l2_subdev(remote->entity))
- return -EINVAL;
-
- if (WARN_ON(fimc == NULL))
- return 0;
-
- dbg("%s --> %s, flags: 0x%x. input: 0x%x",
- local->entity->name, remote->entity->name, flags,
- fimc->vid_cap.input);
-
- if (!(flags & MEDIA_LNK_FL_ENABLED)) {
- fimc->vid_cap.input = 0;
- return 0;
- }
-
- if (vc->input != 0)
- return -EBUSY;
-
- vc->input = sd->grp_id;
-
- if (vc->user_subdev_api)
- return 0;
-
- /* Inherit V4L2 controls from the image sensor subdev. */
- sensor = fimc_find_remote_sensor(&vc->subdev.entity);
- if (sensor == NULL)
- return 0;
-
- return v4l2_ctrl_add_handler(&vc->ctx->ctrls.handler,
- sensor->ctrl_handler, NULL, true);
-}
-
-static const struct media_entity_operations fimc_sd_media_ops = {
- .link_setup = fimc_link_setup,
-};
-
-/**
- * fimc_sensor_notify - v4l2_device notification from a sensor subdev
- * @sd: pointer to a subdev generating the notification
- * @notification: the notification type, must be S5P_FIMC_TX_END_NOTIFY
- * @arg: pointer to an u32 type integer that stores the frame payload value
- *
- * The End Of Frame notification sent by sensor subdev in its still capture
- * mode. If there is only a single VSYNC generated by the sensor at the
- * beginning of a frame transmission, FIMC does not issue the LastIrq
- * (end of frame) interrupt. And this notification is used to complete the
- * frame capture and returning a buffer to user-space. Subdev drivers should
- * call this notification from their last 'End of frame capture' interrupt.
- */
-void fimc_sensor_notify(struct v4l2_subdev *sd, unsigned int notification,
- void *arg)
-{
- struct fimc_source_info *si;
- struct fimc_vid_buffer *buf;
- struct fimc_md *fmd;
- struct fimc_dev *fimc;
- unsigned long flags;
-
- if (sd == NULL)
- return;
-
- si = v4l2_get_subdev_hostdata(sd);
- fmd = entity_to_fimc_mdev(&sd->entity);
-
- spin_lock_irqsave(&fmd->slock, flags);
-
- fimc = si ? source_to_sensor_info(si)->host : NULL;
-
- if (fimc && arg && notification == S5P_FIMC_TX_END_NOTIFY &&
- test_bit(ST_CAPT_PEND, &fimc->state)) {
- unsigned long irq_flags;
- spin_lock_irqsave(&fimc->slock, irq_flags);
- if (!list_empty(&fimc->vid_cap.active_buf_q)) {
- buf = list_entry(fimc->vid_cap.active_buf_q.next,
- struct fimc_vid_buffer, list);
- vb2_set_plane_payload(&buf->vb.vb2_buf, 0,
- *((u32 *)arg));
- }
- fimc_capture_irq_handler(fimc, 1);
- fimc_deactivate_capture(fimc);
- spin_unlock_irqrestore(&fimc->slock, irq_flags);
- }
- spin_unlock_irqrestore(&fmd->slock, flags);
-}
-
-static int fimc_subdev_enum_mbus_code(struct v4l2_subdev *sd,
- struct v4l2_subdev_state *sd_state,
- struct v4l2_subdev_mbus_code_enum *code)
-{
- struct fimc_fmt *fmt;
-
- fmt = fimc_find_format(NULL, NULL, FMT_FLAGS_CAM, code->index);
- if (!fmt)
- return -EINVAL;
- code->code = fmt->mbus_code;
- return 0;
-}
-
-static int fimc_subdev_get_fmt(struct v4l2_subdev *sd,
- struct v4l2_subdev_state *sd_state,
- struct v4l2_subdev_format *fmt)
-{
- struct fimc_dev *fimc = v4l2_get_subdevdata(sd);
- struct fimc_ctx *ctx = fimc->vid_cap.ctx;
- struct fimc_frame *ff = &ctx->s_frame;
- struct v4l2_mbus_framefmt *mf;
-
- if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) {
- mf = v4l2_subdev_get_try_format(sd, sd_state, fmt->pad);
- fmt->format = *mf;
- return 0;
- }
-
- mf = &fmt->format;
- mutex_lock(&fimc->lock);
-
- switch (fmt->pad) {
- case FIMC_SD_PAD_SOURCE:
- if (!WARN_ON(ff->fmt == NULL))
- mf->code = ff->fmt->mbus_code;
- /* Sink pads crop rectangle size */
- mf->width = ff->width;
- mf->height = ff->height;
- break;
- case FIMC_SD_PAD_SINK_FIFO:
- *mf = fimc->vid_cap.wb_fmt;
- break;
- case FIMC_SD_PAD_SINK_CAM:
- default:
- *mf = fimc->vid_cap.ci_fmt;
- break;
- }
-
- mutex_unlock(&fimc->lock);
- mf->colorspace = V4L2_COLORSPACE_JPEG;
-
- return 0;
-}
-
-static int fimc_subdev_set_fmt(struct v4l2_subdev *sd,
- struct v4l2_subdev_state *sd_state,
- struct v4l2_subdev_format *fmt)
-{
- struct fimc_dev *fimc = v4l2_get_subdevdata(sd);
- struct v4l2_mbus_framefmt *mf = &fmt->format;
- struct fimc_vid_cap *vc = &fimc->vid_cap;
- struct fimc_ctx *ctx = vc->ctx;
- struct fimc_frame *ff;
- struct fimc_fmt *ffmt;
-
- dbg("pad%d: code: 0x%x, %dx%d",
- fmt->pad, mf->code, mf->width, mf->height);
-
- if (fmt->pad == FIMC_SD_PAD_SOURCE && vb2_is_busy(&vc->vbq))
- return -EBUSY;
-
- mutex_lock(&fimc->lock);
- ffmt = fimc_capture_try_format(ctx, &mf->width, &mf->height,
- &mf->code, NULL, fmt->pad);
- mutex_unlock(&fimc->lock);
- mf->colorspace = V4L2_COLORSPACE_JPEG;
-
- if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) {
- mf = v4l2_subdev_get_try_format(sd, sd_state, fmt->pad);
- *mf = fmt->format;
- return 0;
- }
- /* There must be a bug in the driver if this happens */
- if (WARN_ON(ffmt == NULL))
- return -EINVAL;
-
- /* Update RGB Alpha control state and value range */
- fimc_alpha_ctrl_update(ctx);
-
- fimc_capture_mark_jpeg_xfer(ctx, ffmt->color);
- if (fmt->pad == FIMC_SD_PAD_SOURCE) {
- ff = &ctx->d_frame;
- /* Sink pads crop rectangle size */
- mf->width = ctx->s_frame.width;
- mf->height = ctx->s_frame.height;
- } else {
- ff = &ctx->s_frame;
- }
-
- mutex_lock(&fimc->lock);
- set_frame_bounds(ff, mf->width, mf->height);
-
- if (fmt->pad == FIMC_SD_PAD_SINK_FIFO)
- vc->wb_fmt = *mf;
- else if (fmt->pad == FIMC_SD_PAD_SINK_CAM)
- vc->ci_fmt = *mf;
-
- ff->fmt = ffmt;
-
- /* Reset the crop rectangle if required. */
- if (!(fmt->pad == FIMC_SD_PAD_SOURCE && (ctx->state & FIMC_COMPOSE)))
- set_frame_crop(ff, 0, 0, mf->width, mf->height);
-
- if (fmt->pad != FIMC_SD_PAD_SOURCE)
- ctx->state &= ~FIMC_COMPOSE;
-
- mutex_unlock(&fimc->lock);
- return 0;
-}
-
-static int fimc_subdev_get_selection(struct v4l2_subdev *sd,
- struct v4l2_subdev_state *sd_state,
- struct v4l2_subdev_selection *sel)
-{
- struct fimc_dev *fimc = v4l2_get_subdevdata(sd);
- struct fimc_ctx *ctx = fimc->vid_cap.ctx;
- struct fimc_frame *f = &ctx->s_frame;
- struct v4l2_rect *r = &sel->r;
- struct v4l2_rect *try_sel;
-
- if (sel->pad == FIMC_SD_PAD_SOURCE)
- return -EINVAL;
-
- mutex_lock(&fimc->lock);
-
- switch (sel->target) {
- case V4L2_SEL_TGT_COMPOSE_BOUNDS:
- f = &ctx->d_frame;
- fallthrough;
- case V4L2_SEL_TGT_CROP_BOUNDS:
- r->width = f->o_width;
- r->height = f->o_height;
- r->left = 0;
- r->top = 0;
- mutex_unlock(&fimc->lock);
- return 0;
-
- case V4L2_SEL_TGT_CROP:
- try_sel = v4l2_subdev_get_try_crop(sd, sd_state, sel->pad);
- break;
- case V4L2_SEL_TGT_COMPOSE:
- try_sel = v4l2_subdev_get_try_compose(sd, sd_state, sel->pad);
- f = &ctx->d_frame;
- break;
- default:
- mutex_unlock(&fimc->lock);
- return -EINVAL;
- }
-
- if (sel->which == V4L2_SUBDEV_FORMAT_TRY) {
- sel->r = *try_sel;
- } else {
- r->left = f->offs_h;
- r->top = f->offs_v;
- r->width = f->width;
- r->height = f->height;
- }
-
- dbg("target %#x: l:%d, t:%d, %dx%d, f_w: %d, f_h: %d",
- sel->pad, r->left, r->top, r->width, r->height,
- f->f_width, f->f_height);
-
- mutex_unlock(&fimc->lock);
- return 0;
-}
-
-static int fimc_subdev_set_selection(struct v4l2_subdev *sd,
- struct v4l2_subdev_state *sd_state,
- struct v4l2_subdev_selection *sel)
-{
- struct fimc_dev *fimc = v4l2_get_subdevdata(sd);
- struct fimc_ctx *ctx = fimc->vid_cap.ctx;
- struct fimc_frame *f = &ctx->s_frame;
- struct v4l2_rect *r = &sel->r;
- struct v4l2_rect *try_sel;
- unsigned long flags;
-
- if (sel->pad == FIMC_SD_PAD_SOURCE)
- return -EINVAL;
-
- mutex_lock(&fimc->lock);
- fimc_capture_try_selection(ctx, r, V4L2_SEL_TGT_CROP);
-
- switch (sel->target) {
- case V4L2_SEL_TGT_CROP:
- try_sel = v4l2_subdev_get_try_crop(sd, sd_state, sel->pad);
- break;
- case V4L2_SEL_TGT_COMPOSE:
- try_sel = v4l2_subdev_get_try_compose(sd, sd_state, sel->pad);
- f = &ctx->d_frame;
- break;
- default:
- mutex_unlock(&fimc->lock);
- return -EINVAL;
- }
-
- if (sel->which == V4L2_SUBDEV_FORMAT_TRY) {
- *try_sel = sel->r;
- } else {
- spin_lock_irqsave(&fimc->slock, flags);
- set_frame_crop(f, r->left, r->top, r->width, r->height);
- set_bit(ST_CAPT_APPLY_CFG, &fimc->state);
- if (sel->target == V4L2_SEL_TGT_COMPOSE)
- ctx->state |= FIMC_COMPOSE;
- spin_unlock_irqrestore(&fimc->slock, flags);
- }
-
- dbg("target %#x: (%d,%d)/%dx%d", sel->target, r->left, r->top,
- r->width, r->height);
-
- mutex_unlock(&fimc->lock);
- return 0;
-}
-
-static const struct v4l2_subdev_pad_ops fimc_subdev_pad_ops = {
- .enum_mbus_code = fimc_subdev_enum_mbus_code,
- .get_selection = fimc_subdev_get_selection,
- .set_selection = fimc_subdev_set_selection,
- .get_fmt = fimc_subdev_get_fmt,
- .set_fmt = fimc_subdev_set_fmt,
-};
-
-static const struct v4l2_subdev_ops fimc_subdev_ops = {
- .pad = &fimc_subdev_pad_ops,
-};
-
-/* Set default format at the sensor and host interface */
-static int fimc_capture_set_default_format(struct fimc_dev *fimc)
-{
- struct v4l2_format fmt = {
- .type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE,
- .fmt.pix_mp = {
- .width = FIMC_DEFAULT_WIDTH,
- .height = FIMC_DEFAULT_HEIGHT,
- .pixelformat = V4L2_PIX_FMT_YUYV,
- .field = V4L2_FIELD_NONE,
- .colorspace = V4L2_COLORSPACE_JPEG,
- },
- };
-
- return __fimc_capture_set_format(fimc, &fmt);
-}
-
-/* fimc->lock must be already initialized */
-static int fimc_register_capture_device(struct fimc_dev *fimc,
- struct v4l2_device *v4l2_dev)
-{
- struct video_device *vfd = &fimc->vid_cap.ve.vdev;
- struct vb2_queue *q = &fimc->vid_cap.vbq;
- struct fimc_ctx *ctx;
- struct fimc_vid_cap *vid_cap;
- struct fimc_fmt *fmt;
- int ret = -ENOMEM;
-
- ctx = kzalloc(sizeof(*ctx), GFP_KERNEL);
- if (!ctx)
- return -ENOMEM;
-
- ctx->fimc_dev = fimc;
- ctx->in_path = FIMC_IO_CAMERA;
- ctx->out_path = FIMC_IO_DMA;
- ctx->state = FIMC_CTX_CAP;
- ctx->s_frame.fmt = fimc_find_format(NULL, NULL, FMT_FLAGS_CAM, 0);
- ctx->d_frame.fmt = ctx->s_frame.fmt;
-
- memset(vfd, 0, sizeof(*vfd));
- snprintf(vfd->name, sizeof(vfd->name), "fimc.%d.capture", fimc->id);
-
- vfd->fops = &fimc_capture_fops;
- vfd->ioctl_ops = &fimc_capture_ioctl_ops;
- vfd->v4l2_dev = v4l2_dev;
- vfd->minor = -1;
- vfd->release = video_device_release_empty;
- vfd->queue = q;
- vfd->lock = &fimc->lock;
- vfd->device_caps = V4L2_CAP_STREAMING | V4L2_CAP_VIDEO_CAPTURE_MPLANE;
-
- video_set_drvdata(vfd, fimc);
- vid_cap = &fimc->vid_cap;
- vid_cap->active_buf_cnt = 0;
- vid_cap->reqbufs_count = 0;
- vid_cap->ctx = ctx;
-
- INIT_LIST_HEAD(&vid_cap->pending_buf_q);
- INIT_LIST_HEAD(&vid_cap->active_buf_q);
-
- memset(q, 0, sizeof(*q));
- q->type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
- q->io_modes = VB2_MMAP | VB2_USERPTR | VB2_DMABUF;
- q->drv_priv = ctx;
- q->ops = &fimc_capture_qops;
- q->mem_ops = &vb2_dma_contig_memops;
- q->buf_struct_size = sizeof(struct fimc_vid_buffer);
- q->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
- q->lock = &fimc->lock;
- q->dev = &fimc->pdev->dev;
-
- ret = vb2_queue_init(q);
- if (ret)
- goto err_free_ctx;
-
- /* Default format configuration */
- fmt = fimc_find_format(NULL, NULL, FMT_FLAGS_CAM, 0);
- vid_cap->ci_fmt.width = FIMC_DEFAULT_WIDTH;
- vid_cap->ci_fmt.height = FIMC_DEFAULT_HEIGHT;
- vid_cap->ci_fmt.code = fmt->mbus_code;
-
- ctx->s_frame.width = FIMC_DEFAULT_WIDTH;
- ctx->s_frame.height = FIMC_DEFAULT_HEIGHT;
- ctx->s_frame.fmt = fmt;
-
- fmt = fimc_find_format(NULL, NULL, FMT_FLAGS_WRITEBACK, 0);
- vid_cap->wb_fmt = vid_cap->ci_fmt;
- vid_cap->wb_fmt.code = fmt->mbus_code;
-
- vid_cap->vd_pad.flags = MEDIA_PAD_FL_SINK;
- vfd->entity.function = MEDIA_ENT_F_PROC_VIDEO_SCALER;
- ret = media_entity_pads_init(&vfd->entity, 1, &vid_cap->vd_pad);
- if (ret)
- goto err_free_ctx;
-
- ret = fimc_ctrls_create(ctx);
- if (ret)
- goto err_me_cleanup;
-
- ret = video_register_device(vfd, VFL_TYPE_VIDEO, -1);
- if (ret)
- goto err_ctrl_free;
-
- v4l2_info(v4l2_dev, "Registered %s as /dev/%s\n",
- vfd->name, video_device_node_name(vfd));
-
- vfd->ctrl_handler = &ctx->ctrls.handler;
- return 0;
-
-err_ctrl_free:
- fimc_ctrls_delete(ctx);
-err_me_cleanup:
- media_entity_cleanup(&vfd->entity);
-err_free_ctx:
- kfree(ctx);
- return ret;
-}
-
-static int fimc_capture_subdev_registered(struct v4l2_subdev *sd)
-{
- struct fimc_dev *fimc = v4l2_get_subdevdata(sd);
- int ret;
-
- if (fimc == NULL)
- return -ENXIO;
-
- ret = fimc_register_m2m_device(fimc, sd->v4l2_dev);
- if (ret)
- return ret;
-
- fimc->vid_cap.ve.pipe = v4l2_get_subdev_hostdata(sd);
-
- ret = fimc_register_capture_device(fimc, sd->v4l2_dev);
- if (ret) {
- fimc_unregister_m2m_device(fimc);
- fimc->vid_cap.ve.pipe = NULL;
- }
-
- return ret;
-}
-
-static void fimc_capture_subdev_unregistered(struct v4l2_subdev *sd)
-{
- struct fimc_dev *fimc = v4l2_get_subdevdata(sd);
- struct video_device *vdev;
-
- if (fimc == NULL)
- return;
-
- mutex_lock(&fimc->lock);
-
- fimc_unregister_m2m_device(fimc);
- vdev = &fimc->vid_cap.ve.vdev;
-
- if (video_is_registered(vdev)) {
- video_unregister_device(vdev);
- media_entity_cleanup(&vdev->entity);
- fimc_ctrls_delete(fimc->vid_cap.ctx);
- fimc->vid_cap.ve.pipe = NULL;
- }
- kfree(fimc->vid_cap.ctx);
- fimc->vid_cap.ctx = NULL;
-
- mutex_unlock(&fimc->lock);
-}
-
-static const struct v4l2_subdev_internal_ops fimc_capture_sd_internal_ops = {
- .registered = fimc_capture_subdev_registered,
- .unregistered = fimc_capture_subdev_unregistered,
-};
-
-int fimc_initialize_capture_subdev(struct fimc_dev *fimc)
-{
- struct v4l2_subdev *sd = &fimc->vid_cap.subdev;
- int ret;
-
- v4l2_subdev_init(sd, &fimc_subdev_ops);
- sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
- snprintf(sd->name, sizeof(sd->name), "FIMC.%d", fimc->id);
-
- fimc->vid_cap.sd_pads[FIMC_SD_PAD_SINK_CAM].flags = MEDIA_PAD_FL_SINK;
- fimc->vid_cap.sd_pads[FIMC_SD_PAD_SINK_FIFO].flags = MEDIA_PAD_FL_SINK;
- fimc->vid_cap.sd_pads[FIMC_SD_PAD_SOURCE].flags = MEDIA_PAD_FL_SOURCE;
- ret = media_entity_pads_init(&sd->entity, FIMC_SD_PADS_NUM,
- fimc->vid_cap.sd_pads);
- if (ret)
- return ret;
-
- sd->entity.ops = &fimc_sd_media_ops;
- sd->entity.function = MEDIA_ENT_F_PROC_VIDEO_SCALER;
- sd->internal_ops = &fimc_capture_sd_internal_ops;
- v4l2_set_subdevdata(sd, fimc);
- return 0;
-}
-
-void fimc_unregister_capture_subdev(struct fimc_dev *fimc)
-{
- struct v4l2_subdev *sd = &fimc->vid_cap.subdev;
-
- v4l2_device_unregister_subdev(sd);
- media_entity_cleanup(&sd->entity);
- v4l2_set_subdevdata(sd, NULL);
-}
diff --git a/drivers/media/platform/exynos4-is/fimc-core.c b/drivers/media/platform/exynos4-is/fimc-core.c
deleted file mode 100644
index 91cc8d58a663..000000000000
--- a/drivers/media/platform/exynos4-is/fimc-core.c
+++ /dev/null
@@ -1,1179 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-or-later
-/*
- * Samsung S5P/EXYNOS4 SoC series FIMC (CAMIF) driver
- *
- * Copyright (C) 2010-2012 Samsung Electronics Co., Ltd.
- * Sylwester Nawrocki <s.nawrocki@samsung.com>
- */
-
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/types.h>
-#include <linux/errno.h>
-#include <linux/bug.h>
-#include <linux/interrupt.h>
-#include <linux/device.h>
-#include <linux/platform_device.h>
-#include <linux/pm_runtime.h>
-#include <linux/list.h>
-#include <linux/mfd/syscon.h>
-#include <linux/io.h>
-#include <linux/of.h>
-#include <linux/of_device.h>
-#include <linux/slab.h>
-#include <linux/clk.h>
-#include <media/v4l2-ioctl.h>
-#include <media/videobuf2-v4l2.h>
-#include <media/videobuf2-dma-contig.h>
-
-#include "fimc-core.h"
-#include "fimc-reg.h"
-#include "media-dev.h"
-
-static char *fimc_clocks[MAX_FIMC_CLOCKS] = {
- "sclk_fimc", "fimc"
-};
-
-static struct fimc_fmt fimc_formats[] = {
- {
- .fourcc = V4L2_PIX_FMT_RGB565,
- .depth = { 16 },
- .color = FIMC_FMT_RGB565,
- .memplanes = 1,
- .colplanes = 1,
- .flags = FMT_FLAGS_M2M,
- }, {
- .fourcc = V4L2_PIX_FMT_BGR666,
- .depth = { 32 },
- .color = FIMC_FMT_RGB666,
- .memplanes = 1,
- .colplanes = 1,
- .flags = FMT_FLAGS_M2M,
- }, {
- .fourcc = V4L2_PIX_FMT_BGR32,
- .depth = { 32 },
- .color = FIMC_FMT_RGB888,
- .memplanes = 1,
- .colplanes = 1,
- .flags = FMT_FLAGS_M2M | FMT_HAS_ALPHA,
- }, {
- .fourcc = V4L2_PIX_FMT_RGB555,
- .depth = { 16 },
- .color = FIMC_FMT_RGB555,
- .memplanes = 1,
- .colplanes = 1,
- .flags = FMT_FLAGS_M2M_OUT | FMT_HAS_ALPHA,
- }, {
- .fourcc = V4L2_PIX_FMT_RGB444,
- .depth = { 16 },
- .color = FIMC_FMT_RGB444,
- .memplanes = 1,
- .colplanes = 1,
- .flags = FMT_FLAGS_M2M_OUT | FMT_HAS_ALPHA,
- }, {
- .mbus_code = MEDIA_BUS_FMT_YUV10_1X30,
- .flags = FMT_FLAGS_WRITEBACK,
- }, {
- .fourcc = V4L2_PIX_FMT_YUYV,
- .depth = { 16 },
- .color = FIMC_FMT_YCBYCR422,
- .memplanes = 1,
- .colplanes = 1,
- .mbus_code = MEDIA_BUS_FMT_YUYV8_2X8,
- .flags = FMT_FLAGS_M2M | FMT_FLAGS_CAM,
- }, {
- .fourcc = V4L2_PIX_FMT_UYVY,
- .depth = { 16 },
- .color = FIMC_FMT_CBYCRY422,
- .memplanes = 1,
- .colplanes = 1,
- .mbus_code = MEDIA_BUS_FMT_UYVY8_2X8,
- .flags = FMT_FLAGS_M2M | FMT_FLAGS_CAM,
- }, {
- .fourcc = V4L2_PIX_FMT_VYUY,
- .depth = { 16 },
- .color = FIMC_FMT_CRYCBY422,
- .memplanes = 1,
- .colplanes = 1,
- .mbus_code = MEDIA_BUS_FMT_VYUY8_2X8,
- .flags = FMT_FLAGS_M2M | FMT_FLAGS_CAM,
- }, {
- .fourcc = V4L2_PIX_FMT_YVYU,
- .depth = { 16 },
- .color = FIMC_FMT_YCRYCB422,
- .memplanes = 1,
- .colplanes = 1,
- .mbus_code = MEDIA_BUS_FMT_YVYU8_2X8,
- .flags = FMT_FLAGS_M2M | FMT_FLAGS_CAM,
- }, {
- .fourcc = V4L2_PIX_FMT_YUV422P,
- .depth = { 16 },
- .color = FIMC_FMT_YCBYCR422,
- .memplanes = 1,
- .colplanes = 3,
- .flags = FMT_FLAGS_M2M,
- }, {
- .fourcc = V4L2_PIX_FMT_NV16,
- .depth = { 16 },
- .color = FIMC_FMT_YCBYCR422,
- .memplanes = 1,
- .colplanes = 2,
- .flags = FMT_FLAGS_M2M,
- }, {
- .fourcc = V4L2_PIX_FMT_NV61,
- .depth = { 16 },
- .color = FIMC_FMT_YCRYCB422,
- .memplanes = 1,
- .colplanes = 2,
- .flags = FMT_FLAGS_M2M,
- }, {
- .fourcc = V4L2_PIX_FMT_YUV420,
- .depth = { 12 },
- .color = FIMC_FMT_YCBCR420,
- .memplanes = 1,
- .colplanes = 3,
- .flags = FMT_FLAGS_M2M,
- }, {
- .fourcc = V4L2_PIX_FMT_NV12,
- .depth = { 12 },
- .color = FIMC_FMT_YCBCR420,
- .memplanes = 1,
- .colplanes = 2,
- .flags = FMT_FLAGS_M2M,
- }, {
- .fourcc = V4L2_PIX_FMT_NV12M,
- .color = FIMC_FMT_YCBCR420,
- .depth = { 8, 4 },
- .memplanes = 2,
- .colplanes = 2,
- .flags = FMT_FLAGS_M2M,
- }, {
- .fourcc = V4L2_PIX_FMT_YUV420M,
- .color = FIMC_FMT_YCBCR420,
- .depth = { 8, 2, 2 },
- .memplanes = 3,
- .colplanes = 3,
- .flags = FMT_FLAGS_M2M,
- }, {
- .fourcc = V4L2_PIX_FMT_NV12MT,
- .color = FIMC_FMT_YCBCR420,
- .depth = { 8, 4 },
- .memplanes = 2,
- .colplanes = 2,
- .flags = FMT_FLAGS_M2M,
- }, {
- .fourcc = V4L2_PIX_FMT_JPEG,
- .color = FIMC_FMT_JPEG,
- .depth = { 8 },
- .memplanes = 1,
- .colplanes = 1,
- .mbus_code = MEDIA_BUS_FMT_JPEG_1X8,
- .flags = FMT_FLAGS_CAM | FMT_FLAGS_COMPRESSED,
- }, {
- .fourcc = V4L2_PIX_FMT_S5C_UYVY_JPG,
- .color = FIMC_FMT_YUYV_JPEG,
- .depth = { 8 },
- .memplanes = 2,
- .colplanes = 1,
- .mdataplanes = 0x2, /* plane 1 holds frame meta data */
- .mbus_code = MEDIA_BUS_FMT_S5C_UYVY_JPEG_1X8,
- .flags = FMT_FLAGS_CAM | FMT_FLAGS_COMPRESSED,
- },
-};
-
-struct fimc_fmt *fimc_get_format(unsigned int index)
-{
- if (index >= ARRAY_SIZE(fimc_formats))
- return NULL;
-
- return &fimc_formats[index];
-}
-
-int fimc_check_scaler_ratio(struct fimc_ctx *ctx, int sw, int sh,
- int dw, int dh, int rotation)
-{
- if (rotation == 90 || rotation == 270)
- swap(dw, dh);
-
- if (!ctx->scaler.enabled)
- return (sw == dw && sh == dh) ? 0 : -EINVAL;
-
- if ((sw >= SCALER_MAX_HRATIO * dw) || (sh >= SCALER_MAX_VRATIO * dh))
- return -EINVAL;
-
- return 0;
-}
-
-static int fimc_get_scaler_factor(u32 src, u32 tar, u32 *ratio, u32 *shift)
-{
- u32 sh = 6;
-
- if (src >= 64 * tar)
- return -EINVAL;
-
- while (sh--) {
- u32 tmp = 1 << sh;
- if (src >= tar * tmp) {
- *shift = sh;
- *ratio = tmp;
- return 0;
- }
- }
- *shift = 0;
- *ratio = 1;
- return 0;
-}
-
-int fimc_set_scaler_info(struct fimc_ctx *ctx)
-{
- const struct fimc_variant *variant = ctx->fimc_dev->variant;
- struct device *dev = &ctx->fimc_dev->pdev->dev;
- struct fimc_scaler *sc = &ctx->scaler;
- struct fimc_frame *s_frame = &ctx->s_frame;
- struct fimc_frame *d_frame = &ctx->d_frame;
- int tx, ty, sx, sy;
- int ret;
-
- if (ctx->rotation == 90 || ctx->rotation == 270) {
- ty = d_frame->width;
- tx = d_frame->height;
- } else {
- tx = d_frame->width;
- ty = d_frame->height;
- }
- if (tx <= 0 || ty <= 0) {
- dev_err(dev, "Invalid target size: %dx%d\n", tx, ty);
- return -EINVAL;
- }
-
- sx = s_frame->width;
- sy = s_frame->height;
- if (sx <= 0 || sy <= 0) {
- dev_err(dev, "Invalid source size: %dx%d\n", sx, sy);
- return -EINVAL;
- }
- sc->real_width = sx;
- sc->real_height = sy;
-
- ret = fimc_get_scaler_factor(sx, tx, &sc->pre_hratio, &sc->hfactor);
- if (ret)
- return ret;
-
- ret = fimc_get_scaler_factor(sy, ty, &sc->pre_vratio, &sc->vfactor);
- if (ret)
- return ret;
-
- sc->pre_dst_width = sx / sc->pre_hratio;
- sc->pre_dst_height = sy / sc->pre_vratio;
-
- if (variant->has_mainscaler_ext) {
- sc->main_hratio = (sx << 14) / (tx << sc->hfactor);
- sc->main_vratio = (sy << 14) / (ty << sc->vfactor);
- } else {
- sc->main_hratio = (sx << 8) / (tx << sc->hfactor);
- sc->main_vratio = (sy << 8) / (ty << sc->vfactor);
-
- }
-
- sc->scaleup_h = (tx >= sx) ? 1 : 0;
- sc->scaleup_v = (ty >= sy) ? 1 : 0;
-
- /* check to see if input and output size/format differ */
- if (s_frame->fmt->color == d_frame->fmt->color
- && s_frame->width == d_frame->width
- && s_frame->height == d_frame->height)
- sc->copy_mode = 1;
- else
- sc->copy_mode = 0;
-
- return 0;
-}
-
-static irqreturn_t fimc_irq_handler(int irq, void *priv)
-{
- struct fimc_dev *fimc = priv;
- struct fimc_ctx *ctx;
-
- fimc_hw_clear_irq(fimc);
-
- spin_lock(&fimc->slock);
-
- if (test_and_clear_bit(ST_M2M_PEND, &fimc->state)) {
- if (test_and_clear_bit(ST_M2M_SUSPENDING, &fimc->state)) {
- set_bit(ST_M2M_SUSPENDED, &fimc->state);
- wake_up(&fimc->irq_queue);
- goto out;
- }
- ctx = v4l2_m2m_get_curr_priv(fimc->m2m.m2m_dev);
- if (ctx != NULL) {
- spin_unlock(&fimc->slock);
- fimc_m2m_job_finish(ctx, VB2_BUF_STATE_DONE);
-
- if (ctx->state & FIMC_CTX_SHUT) {
- ctx->state &= ~FIMC_CTX_SHUT;
- wake_up(&fimc->irq_queue);
- }
- return IRQ_HANDLED;
- }
- } else if (test_bit(ST_CAPT_PEND, &fimc->state)) {
- int last_buf = test_bit(ST_CAPT_JPEG, &fimc->state) &&
- fimc->vid_cap.reqbufs_count == 1;
- fimc_capture_irq_handler(fimc, !last_buf);
- }
-out:
- spin_unlock(&fimc->slock);
- return IRQ_HANDLED;
-}
-
-/* The color format (colplanes, memplanes) must be already configured. */
-int fimc_prepare_addr(struct fimc_ctx *ctx, struct vb2_buffer *vb,
- struct fimc_frame *frame, struct fimc_addr *addr)
-{
- int ret = 0;
- u32 pix_size;
-
- if (vb == NULL || frame == NULL)
- return -EINVAL;
-
- pix_size = frame->width * frame->height;
-
- dbg("memplanes= %d, colplanes= %d, pix_size= %d",
- frame->fmt->memplanes, frame->fmt->colplanes, pix_size);
-
- addr->y = vb2_dma_contig_plane_dma_addr(vb, 0);
-
- if (frame->fmt->memplanes == 1) {
- switch (frame->fmt->colplanes) {
- case 1:
- addr->cb = 0;
- addr->cr = 0;
- break;
- case 2:
- /* decompose Y into Y/Cb */
- addr->cb = (u32)(addr->y + pix_size);
- addr->cr = 0;
- break;
- case 3:
- addr->cb = (u32)(addr->y + pix_size);
- /* decompose Y into Y/Cb/Cr */
- if (FIMC_FMT_YCBCR420 == frame->fmt->color)
- addr->cr = (u32)(addr->cb + (pix_size >> 2));
- else /* 422 */
- addr->cr = (u32)(addr->cb + (pix_size >> 1));
- break;
- default:
- return -EINVAL;
- }
- } else if (!frame->fmt->mdataplanes) {
- if (frame->fmt->memplanes >= 2)
- addr->cb = vb2_dma_contig_plane_dma_addr(vb, 1);
-
- if (frame->fmt->memplanes == 3)
- addr->cr = vb2_dma_contig_plane_dma_addr(vb, 2);
- }
-
- dbg("DMA ADDR: y= 0x%X cb= 0x%X cr= 0x%X ret= %d",
- addr->y, addr->cb, addr->cr, ret);
-
- return ret;
-}
-
-/* Set order for 1 and 2 plane YCBCR 4:2:2 formats. */
-void fimc_set_yuv_order(struct fimc_ctx *ctx)
-{
- /* The one only mode supported in SoC. */
- ctx->in_order_2p = FIMC_REG_CIOCTRL_ORDER422_2P_LSB_CRCB;
- ctx->out_order_2p = FIMC_REG_CIOCTRL_ORDER422_2P_LSB_CRCB;
-
- /* Set order for 1 plane input formats. */
- switch (ctx->s_frame.fmt->color) {
- case FIMC_FMT_YCRYCB422:
- ctx->in_order_1p = FIMC_REG_MSCTRL_ORDER422_YCRYCB;
- break;
- case FIMC_FMT_CBYCRY422:
- ctx->in_order_1p = FIMC_REG_MSCTRL_ORDER422_CBYCRY;
- break;
- case FIMC_FMT_CRYCBY422:
- ctx->in_order_1p = FIMC_REG_MSCTRL_ORDER422_CRYCBY;
- break;
- case FIMC_FMT_YCBYCR422:
- default:
- ctx->in_order_1p = FIMC_REG_MSCTRL_ORDER422_YCBYCR;
- break;
- }
- dbg("ctx->in_order_1p= %d", ctx->in_order_1p);
-
- switch (ctx->d_frame.fmt->color) {
- case FIMC_FMT_YCRYCB422:
- ctx->out_order_1p = FIMC_REG_CIOCTRL_ORDER422_YCRYCB;
- break;
- case FIMC_FMT_CBYCRY422:
- ctx->out_order_1p = FIMC_REG_CIOCTRL_ORDER422_CBYCRY;
- break;
- case FIMC_FMT_CRYCBY422:
- ctx->out_order_1p = FIMC_REG_CIOCTRL_ORDER422_CRYCBY;
- break;
- case FIMC_FMT_YCBYCR422:
- default:
- ctx->out_order_1p = FIMC_REG_CIOCTRL_ORDER422_YCBYCR;
- break;
- }
- dbg("ctx->out_order_1p= %d", ctx->out_order_1p);
-}
-
-void fimc_prepare_dma_offset(struct fimc_ctx *ctx, struct fimc_frame *f)
-{
- bool pix_hoff = ctx->fimc_dev->drv_data->dma_pix_hoff;
- u32 i, depth = 0;
-
- for (i = 0; i < f->fmt->memplanes; i++)
- depth += f->fmt->depth[i];
-
- f->dma_offset.y_h = f->offs_h;
- if (!pix_hoff)
- f->dma_offset.y_h *= (depth >> 3);
-
- f->dma_offset.y_v = f->offs_v;
-
- f->dma_offset.cb_h = f->offs_h;
- f->dma_offset.cb_v = f->offs_v;
-
- f->dma_offset.cr_h = f->offs_h;
- f->dma_offset.cr_v = f->offs_v;
-
- if (!pix_hoff) {
- if (f->fmt->colplanes == 3) {
- f->dma_offset.cb_h >>= 1;
- f->dma_offset.cr_h >>= 1;
- }
- if (f->fmt->color == FIMC_FMT_YCBCR420) {
- f->dma_offset.cb_v >>= 1;
- f->dma_offset.cr_v >>= 1;
- }
- }
-
- dbg("in_offset: color= %d, y_h= %d, y_v= %d",
- f->fmt->color, f->dma_offset.y_h, f->dma_offset.y_v);
-}
-
-static int fimc_set_color_effect(struct fimc_ctx *ctx, enum v4l2_colorfx colorfx)
-{
- struct fimc_effect *effect = &ctx->effect;
-
- switch (colorfx) {
- case V4L2_COLORFX_NONE:
- effect->type = FIMC_REG_CIIMGEFF_FIN_BYPASS;
- break;
- case V4L2_COLORFX_BW:
- effect->type = FIMC_REG_CIIMGEFF_FIN_ARBITRARY;
- effect->pat_cb = 128;
- effect->pat_cr = 128;
- break;
- case V4L2_COLORFX_SEPIA:
- effect->type = FIMC_REG_CIIMGEFF_FIN_ARBITRARY;
- effect->pat_cb = 115;
- effect->pat_cr = 145;
- break;
- case V4L2_COLORFX_NEGATIVE:
- effect->type = FIMC_REG_CIIMGEFF_FIN_NEGATIVE;
- break;
- case V4L2_COLORFX_EMBOSS:
- effect->type = FIMC_REG_CIIMGEFF_FIN_EMBOSSING;
- break;
- case V4L2_COLORFX_ART_FREEZE:
- effect->type = FIMC_REG_CIIMGEFF_FIN_ARTFREEZE;
- break;
- case V4L2_COLORFX_SILHOUETTE:
- effect->type = FIMC_REG_CIIMGEFF_FIN_SILHOUETTE;
- break;
- case V4L2_COLORFX_SET_CBCR:
- effect->type = FIMC_REG_CIIMGEFF_FIN_ARBITRARY;
- effect->pat_cb = ctx->ctrls.colorfx_cbcr->val >> 8;
- effect->pat_cr = ctx->ctrls.colorfx_cbcr->val & 0xff;
- break;
- default:
- return -EINVAL;
- }
-
- return 0;
-}
-
-/*
- * V4L2 controls handling
- */
-#define ctrl_to_ctx(__ctrl) \
- container_of((__ctrl)->handler, struct fimc_ctx, ctrls.handler)
-
-static int __fimc_s_ctrl(struct fimc_ctx *ctx, struct v4l2_ctrl *ctrl)
-{
- struct fimc_dev *fimc = ctx->fimc_dev;
- const struct fimc_variant *variant = fimc->variant;
- int ret = 0;
-
- if (ctrl->flags & V4L2_CTRL_FLAG_INACTIVE)
- return 0;
-
- switch (ctrl->id) {
- case V4L2_CID_HFLIP:
- ctx->hflip = ctrl->val;
- break;
-
- case V4L2_CID_VFLIP:
- ctx->vflip = ctrl->val;
- break;
-
- case V4L2_CID_ROTATE:
- if (fimc_capture_pending(fimc)) {
- ret = fimc_check_scaler_ratio(ctx, ctx->s_frame.width,
- ctx->s_frame.height, ctx->d_frame.width,
- ctx->d_frame.height, ctrl->val);
- if (ret)
- return -EINVAL;
- }
- if ((ctrl->val == 90 || ctrl->val == 270) &&
- !variant->has_out_rot)
- return -EINVAL;
-
- ctx->rotation = ctrl->val;
- break;
-
- case V4L2_CID_ALPHA_COMPONENT:
- ctx->d_frame.alpha = ctrl->val;
- break;
-
- case V4L2_CID_COLORFX:
- ret = fimc_set_color_effect(ctx, ctrl->val);
- if (ret)
- return ret;
- break;
- }
-
- ctx->state |= FIMC_PARAMS;
- set_bit(ST_CAPT_APPLY_CFG, &fimc->state);
- return 0;
-}
-
-static int fimc_s_ctrl(struct v4l2_ctrl *ctrl)
-{
- struct fimc_ctx *ctx = ctrl_to_ctx(ctrl);
- unsigned long flags;
- int ret;
-
- spin_lock_irqsave(&ctx->fimc_dev->slock, flags);
- ret = __fimc_s_ctrl(ctx, ctrl);
- spin_unlock_irqrestore(&ctx->fimc_dev->slock, flags);
-
- return ret;
-}
-
-static const struct v4l2_ctrl_ops fimc_ctrl_ops = {
- .s_ctrl = fimc_s_ctrl,
-};
-
-int fimc_ctrls_create(struct fimc_ctx *ctx)
-{
- unsigned int max_alpha = fimc_get_alpha_mask(ctx->d_frame.fmt);
- struct fimc_ctrls *ctrls = &ctx->ctrls;
- struct v4l2_ctrl_handler *handler = &ctrls->handler;
-
- if (ctx->ctrls.ready)
- return 0;
-
- v4l2_ctrl_handler_init(handler, 6);
-
- ctrls->rotate = v4l2_ctrl_new_std(handler, &fimc_ctrl_ops,
- V4L2_CID_ROTATE, 0, 270, 90, 0);
- ctrls->hflip = v4l2_ctrl_new_std(handler, &fimc_ctrl_ops,
- V4L2_CID_HFLIP, 0, 1, 1, 0);
- ctrls->vflip = v4l2_ctrl_new_std(handler, &fimc_ctrl_ops,
- V4L2_CID_VFLIP, 0, 1, 1, 0);
-
- if (ctx->fimc_dev->drv_data->alpha_color)
- ctrls->alpha = v4l2_ctrl_new_std(handler, &fimc_ctrl_ops,
- V4L2_CID_ALPHA_COMPONENT,
- 0, max_alpha, 1, 0);
- else
- ctrls->alpha = NULL;
-
- ctrls->colorfx = v4l2_ctrl_new_std_menu(handler, &fimc_ctrl_ops,
- V4L2_CID_COLORFX, V4L2_COLORFX_SET_CBCR,
- ~0x983f, V4L2_COLORFX_NONE);
-
- ctrls->colorfx_cbcr = v4l2_ctrl_new_std(handler, &fimc_ctrl_ops,
- V4L2_CID_COLORFX_CBCR, 0, 0xffff, 1, 0);
-
- ctx->effect.type = FIMC_REG_CIIMGEFF_FIN_BYPASS;
-
- if (!handler->error) {
- v4l2_ctrl_cluster(2, &ctrls->colorfx);
- ctrls->ready = true;
- }
-
- return handler->error;
-}
-
-void fimc_ctrls_delete(struct fimc_ctx *ctx)
-{
- struct fimc_ctrls *ctrls = &ctx->ctrls;
-
- if (ctrls->ready) {
- v4l2_ctrl_handler_free(&ctrls->handler);
- ctrls->ready = false;
- ctrls->alpha = NULL;
- }
-}
-
-void fimc_ctrls_activate(struct fimc_ctx *ctx, bool active)
-{
- unsigned int has_alpha = ctx->d_frame.fmt->flags & FMT_HAS_ALPHA;
- struct fimc_ctrls *ctrls = &ctx->ctrls;
-
- if (!ctrls->ready)
- return;
-
- mutex_lock(ctrls->handler.lock);
- v4l2_ctrl_activate(ctrls->rotate, active);
- v4l2_ctrl_activate(ctrls->hflip, active);
- v4l2_ctrl_activate(ctrls->vflip, active);
- v4l2_ctrl_activate(ctrls->colorfx, active);
- if (ctrls->alpha)
- v4l2_ctrl_activate(ctrls->alpha, active && has_alpha);
-
- if (active) {
- fimc_set_color_effect(ctx, ctrls->colorfx->cur.val);
- ctx->rotation = ctrls->rotate->val;
- ctx->hflip = ctrls->hflip->val;
- ctx->vflip = ctrls->vflip->val;
- } else {
- ctx->effect.type = FIMC_REG_CIIMGEFF_FIN_BYPASS;
- ctx->rotation = 0;
- ctx->hflip = 0;
- ctx->vflip = 0;
- }
- mutex_unlock(ctrls->handler.lock);
-}
-
-/* Update maximum value of the alpha color control */
-void fimc_alpha_ctrl_update(struct fimc_ctx *ctx)
-{
- struct fimc_dev *fimc = ctx->fimc_dev;
- struct v4l2_ctrl *ctrl = ctx->ctrls.alpha;
-
- if (ctrl == NULL || !fimc->drv_data->alpha_color)
- return;
-
- v4l2_ctrl_lock(ctrl);
- ctrl->maximum = fimc_get_alpha_mask(ctx->d_frame.fmt);
-
- if (ctrl->cur.val > ctrl->maximum)
- ctrl->cur.val = ctrl->maximum;
-
- v4l2_ctrl_unlock(ctrl);
-}
-
-void __fimc_get_format(struct fimc_frame *frame, struct v4l2_format *f)
-{
- struct v4l2_pix_format_mplane *pixm = &f->fmt.pix_mp;
- int i;
-
- pixm->width = frame->o_width;
- pixm->height = frame->o_height;
- pixm->field = V4L2_FIELD_NONE;
- pixm->pixelformat = frame->fmt->fourcc;
- pixm->colorspace = V4L2_COLORSPACE_JPEG;
- pixm->num_planes = frame->fmt->memplanes;
-
- for (i = 0; i < pixm->num_planes; ++i) {
- pixm->plane_fmt[i].bytesperline = frame->bytesperline[i];
- pixm->plane_fmt[i].sizeimage = frame->payload[i];
- }
-}
-
-/**
- * fimc_adjust_mplane_format - adjust bytesperline/sizeimage for each plane
- * @fmt: fimc pixel format description (input)
- * @width: requested pixel width
- * @height: requested pixel height
- * @pix: multi-plane format to adjust
- */
-void fimc_adjust_mplane_format(struct fimc_fmt *fmt, u32 width, u32 height,
- struct v4l2_pix_format_mplane *pix)
-{
- u32 bytesperline = 0;
- int i;
-
- pix->colorspace = V4L2_COLORSPACE_JPEG;
- pix->field = V4L2_FIELD_NONE;
- pix->num_planes = fmt->memplanes;
- pix->pixelformat = fmt->fourcc;
- pix->height = height;
- pix->width = width;
-
- for (i = 0; i < pix->num_planes; ++i) {
- struct v4l2_plane_pix_format *plane_fmt = &pix->plane_fmt[i];
- u32 bpl = plane_fmt->bytesperline;
- u32 sizeimage;
-
- if (fmt->colplanes > 1 && (bpl == 0 || bpl < pix->width))
- bpl = pix->width; /* Planar */
-
- if (fmt->colplanes == 1 && /* Packed */
- (bpl == 0 || ((bpl * 8) / fmt->depth[i]) < pix->width))
- bpl = (pix->width * fmt->depth[0]) / 8;
- /*
- * Currently bytesperline for each plane is same, except
- * V4L2_PIX_FMT_YUV420M format. This calculation may need
- * to be changed when other multi-planar formats are added
- * to the fimc_formats[] array.
- */
- if (i == 0)
- bytesperline = bpl;
- else if (i == 1 && fmt->memplanes == 3)
- bytesperline /= 2;
-
- plane_fmt->bytesperline = bytesperline;
- sizeimage = pix->width * pix->height * fmt->depth[i] / 8;
-
- /* Ensure full last row for tiled formats */
- if (tiled_fmt(fmt)) {
- /* 64 * 32 * plane_fmt->bytesperline / 64 */
- u32 row_size = plane_fmt->bytesperline * 32;
-
- sizeimage = roundup(sizeimage, row_size);
- }
-
- plane_fmt->sizeimage = max(sizeimage, plane_fmt->sizeimage);
- }
-}
-
-/**
- * fimc_find_format - lookup fimc color format by fourcc or media bus format
- * @pixelformat: fourcc to match, ignored if null
- * @mbus_code: media bus code to match, ignored if null
- * @mask: the color flags to match
- * @index: offset in the fimc_formats array, ignored if negative
- */
-struct fimc_fmt *fimc_find_format(const u32 *pixelformat, const u32 *mbus_code,
- unsigned int mask, int index)
-{
- struct fimc_fmt *fmt, *def_fmt = NULL;
- unsigned int i;
- int id = 0;
-
- if (index >= (int)ARRAY_SIZE(fimc_formats))
- return NULL;
-
- for (i = 0; i < ARRAY_SIZE(fimc_formats); ++i) {
- fmt = &fimc_formats[i];
- if (!(fmt->flags & mask))
- continue;
- if (pixelformat && fmt->fourcc == *pixelformat)
- return fmt;
- if (mbus_code && fmt->mbus_code == *mbus_code)
- return fmt;
- if (index == id)
- def_fmt = fmt;
- id++;
- }
- return def_fmt;
-}
-
-static void fimc_clk_put(struct fimc_dev *fimc)
-{
- int i;
- for (i = 0; i < MAX_FIMC_CLOCKS; i++) {
- if (IS_ERR(fimc->clock[i]))
- continue;
- clk_unprepare(fimc->clock[i]);
- clk_put(fimc->clock[i]);
- fimc->clock[i] = ERR_PTR(-EINVAL);
- }
-}
-
-static int fimc_clk_get(struct fimc_dev *fimc)
-{
- int i, ret;
-
- for (i = 0; i < MAX_FIMC_CLOCKS; i++)
- fimc->clock[i] = ERR_PTR(-EINVAL);
-
- for (i = 0; i < MAX_FIMC_CLOCKS; i++) {
- fimc->clock[i] = clk_get(&fimc->pdev->dev, fimc_clocks[i]);
- if (IS_ERR(fimc->clock[i])) {
- ret = PTR_ERR(fimc->clock[i]);
- goto err;
- }
- ret = clk_prepare(fimc->clock[i]);
- if (ret < 0) {
- clk_put(fimc->clock[i]);
- fimc->clock[i] = ERR_PTR(-EINVAL);
- goto err;
- }
- }
- return 0;
-err:
- fimc_clk_put(fimc);
- dev_err(&fimc->pdev->dev, "failed to get clock: %s\n",
- fimc_clocks[i]);
- return -ENXIO;
-}
-
-#ifdef CONFIG_PM
-static int fimc_m2m_suspend(struct fimc_dev *fimc)
-{
- unsigned long flags;
- int timeout;
-
- spin_lock_irqsave(&fimc->slock, flags);
- if (!fimc_m2m_pending(fimc)) {
- spin_unlock_irqrestore(&fimc->slock, flags);
- return 0;
- }
- clear_bit(ST_M2M_SUSPENDED, &fimc->state);
- set_bit(ST_M2M_SUSPENDING, &fimc->state);
- spin_unlock_irqrestore(&fimc->slock, flags);
-
- timeout = wait_event_timeout(fimc->irq_queue,
- test_bit(ST_M2M_SUSPENDED, &fimc->state),
- FIMC_SHUTDOWN_TIMEOUT);
-
- clear_bit(ST_M2M_SUSPENDING, &fimc->state);
- return timeout == 0 ? -EAGAIN : 0;
-}
-
-static int fimc_m2m_resume(struct fimc_dev *fimc)
-{
- struct fimc_ctx *ctx;
- unsigned long flags;
-
- spin_lock_irqsave(&fimc->slock, flags);
- /* Clear for full H/W setup in first run after resume */
- ctx = fimc->m2m.ctx;
- fimc->m2m.ctx = NULL;
- spin_unlock_irqrestore(&fimc->slock, flags);
-
- if (test_and_clear_bit(ST_M2M_SUSPENDED, &fimc->state))
- fimc_m2m_job_finish(ctx, VB2_BUF_STATE_ERROR);
-
- return 0;
-}
-#endif /* CONFIG_PM */
-
-static const struct of_device_id fimc_of_match[];
-
-static int fimc_parse_dt(struct fimc_dev *fimc, u32 *clk_freq)
-{
- struct device *dev = &fimc->pdev->dev;
- struct device_node *node = dev->of_node;
- const struct of_device_id *of_id;
- struct fimc_variant *v;
- struct fimc_pix_limit *lim;
- u32 args[FIMC_PIX_LIMITS_MAX];
- int ret;
-
- if (of_property_read_bool(node, "samsung,lcd-wb"))
- return -ENODEV;
-
- v = devm_kzalloc(dev, sizeof(*v) + sizeof(*lim), GFP_KERNEL);
- if (!v)
- return -ENOMEM;
-
- of_id = of_match_node(fimc_of_match, node);
- if (!of_id)
- return -EINVAL;
- fimc->drv_data = of_id->data;
- ret = of_property_read_u32_array(node, "samsung,pix-limits",
- args, FIMC_PIX_LIMITS_MAX);
- if (ret < 0)
- return ret;
-
- lim = (struct fimc_pix_limit *)&v[1];
-
- lim->scaler_en_w = args[0];
- lim->scaler_dis_w = args[1];
- lim->out_rot_en_w = args[2];
- lim->out_rot_dis_w = args[3];
- v->pix_limit = lim;
-
- ret = of_property_read_u32_array(node, "samsung,min-pix-sizes",
- args, 2);
- v->min_inp_pixsize = ret ? FIMC_DEF_MIN_SIZE : args[0];
- v->min_out_pixsize = ret ? FIMC_DEF_MIN_SIZE : args[1];
- ret = of_property_read_u32_array(node, "samsung,min-pix-alignment",
- args, 2);
- v->min_vsize_align = ret ? FIMC_DEF_HEIGHT_ALIGN : args[0];
- v->hor_offs_align = ret ? FIMC_DEF_HOR_OFFS_ALIGN : args[1];
-
- ret = of_property_read_u32(node, "samsung,rotators", &args[1]);
- v->has_inp_rot = ret ? 1 : args[1] & 0x01;
- v->has_out_rot = ret ? 1 : args[1] & 0x10;
- v->has_mainscaler_ext = of_property_read_bool(node,
- "samsung,mainscaler-ext");
-
- v->has_isp_wb = of_property_read_bool(node, "samsung,isp-wb");
- v->has_cam_if = of_property_read_bool(node, "samsung,cam-if");
- of_property_read_u32(node, "clock-frequency", clk_freq);
- fimc->id = of_alias_get_id(node, "fimc");
-
- fimc->variant = v;
- return 0;
-}
-
-static int fimc_probe(struct platform_device *pdev)
-{
- struct device *dev = &pdev->dev;
- u32 lclk_freq = 0;
- struct fimc_dev *fimc;
- struct resource *res;
- int ret = 0;
- int irq;
-
- fimc = devm_kzalloc(dev, sizeof(*fimc), GFP_KERNEL);
- if (!fimc)
- return -ENOMEM;
-
- fimc->pdev = pdev;
-
- if (dev->of_node) {
- ret = fimc_parse_dt(fimc, &lclk_freq);
- if (ret < 0)
- return ret;
- } else {
- fimc->drv_data = fimc_get_drvdata(pdev);
- fimc->id = pdev->id;
- }
- if (!fimc->drv_data || fimc->id >= fimc->drv_data->num_entities ||
- fimc->id < 0) {
- dev_err(dev, "Invalid driver data or device id (%d)\n",
- fimc->id);
- return -EINVAL;
- }
- if (!dev->of_node)
- fimc->variant = fimc->drv_data->variant[fimc->id];
-
- init_waitqueue_head(&fimc->irq_queue);
- spin_lock_init(&fimc->slock);
- mutex_init(&fimc->lock);
-
- if (fimc->variant->has_isp_wb) {
- fimc->sysreg = fimc_get_sysreg_regmap(dev->of_node);
- if (IS_ERR(fimc->sysreg))
- return PTR_ERR(fimc->sysreg);
- }
-
- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- fimc->regs = devm_ioremap_resource(dev, res);
- if (IS_ERR(fimc->regs))
- return PTR_ERR(fimc->regs);
-
- irq = platform_get_irq(pdev, 0);
- if (irq < 0)
- return irq;
-
- ret = fimc_clk_get(fimc);
- if (ret)
- return ret;
-
- if (lclk_freq == 0)
- lclk_freq = fimc->drv_data->lclk_frequency;
-
- ret = clk_set_rate(fimc->clock[CLK_BUS], lclk_freq);
- if (ret < 0)
- return ret;
-
- ret = clk_enable(fimc->clock[CLK_BUS]);
- if (ret < 0)
- return ret;
-
- ret = devm_request_irq(dev, irq, fimc_irq_handler,
- 0, dev_name(dev), fimc);
- if (ret < 0) {
- dev_err(dev, "failed to install irq (%d)\n", ret);
- goto err_sclk;
- }
-
- ret = fimc_initialize_capture_subdev(fimc);
- if (ret < 0)
- goto err_sclk;
-
- platform_set_drvdata(pdev, fimc);
- pm_runtime_enable(dev);
-
- if (!pm_runtime_enabled(dev)) {
- ret = clk_enable(fimc->clock[CLK_GATE]);
- if (ret < 0)
- goto err_sd;
- }
-
- vb2_dma_contig_set_max_seg_size(dev, DMA_BIT_MASK(32));
-
- dev_dbg(dev, "FIMC.%d registered successfully\n", fimc->id);
- return 0;
-
-err_sd:
- fimc_unregister_capture_subdev(fimc);
-err_sclk:
- clk_disable(fimc->clock[CLK_BUS]);
- fimc_clk_put(fimc);
- return ret;
-}
-
-#ifdef CONFIG_PM
-static int fimc_runtime_resume(struct device *dev)
-{
- struct fimc_dev *fimc = dev_get_drvdata(dev);
-
- dbg("fimc%d: state: 0x%lx", fimc->id, fimc->state);
-
- /* Enable clocks and perform basic initialization */
- clk_enable(fimc->clock[CLK_GATE]);
- fimc_hw_reset(fimc);
-
- /* Resume the capture or mem-to-mem device */
- if (fimc_capture_busy(fimc))
- return fimc_capture_resume(fimc);
-
- return fimc_m2m_resume(fimc);
-}
-
-static int fimc_runtime_suspend(struct device *dev)
-{
- struct fimc_dev *fimc = dev_get_drvdata(dev);
- int ret = 0;
-
- if (fimc_capture_busy(fimc))
- ret = fimc_capture_suspend(fimc);
- else
- ret = fimc_m2m_suspend(fimc);
- if (!ret)
- clk_disable(fimc->clock[CLK_GATE]);
-
- dbg("fimc%d: state: 0x%lx", fimc->id, fimc->state);
- return ret;
-}
-#endif
-
-#ifdef CONFIG_PM_SLEEP
-static int fimc_resume(struct device *dev)
-{
- struct fimc_dev *fimc = dev_get_drvdata(dev);
- unsigned long flags;
-
- dbg("fimc%d: state: 0x%lx", fimc->id, fimc->state);
-
- /* Do not resume if the device was idle before system suspend */
- spin_lock_irqsave(&fimc->slock, flags);
- if (!test_and_clear_bit(ST_LPM, &fimc->state) ||
- (!fimc_m2m_active(fimc) && !fimc_capture_busy(fimc))) {
- spin_unlock_irqrestore(&fimc->slock, flags);
- return 0;
- }
- fimc_hw_reset(fimc);
- spin_unlock_irqrestore(&fimc->slock, flags);
-
- if (fimc_capture_busy(fimc))
- return fimc_capture_resume(fimc);
-
- return fimc_m2m_resume(fimc);
-}
-
-static int fimc_suspend(struct device *dev)
-{
- struct fimc_dev *fimc = dev_get_drvdata(dev);
-
- dbg("fimc%d: state: 0x%lx", fimc->id, fimc->state);
-
- if (test_and_set_bit(ST_LPM, &fimc->state))
- return 0;
- if (fimc_capture_busy(fimc))
- return fimc_capture_suspend(fimc);
-
- return fimc_m2m_suspend(fimc);
-}
-#endif /* CONFIG_PM_SLEEP */
-
-static int fimc_remove(struct platform_device *pdev)
-{
- struct fimc_dev *fimc = platform_get_drvdata(pdev);
-
- pm_runtime_disable(&pdev->dev);
- if (!pm_runtime_status_suspended(&pdev->dev))
- clk_disable(fimc->clock[CLK_GATE]);
- pm_runtime_set_suspended(&pdev->dev);
-
- fimc_unregister_capture_subdev(fimc);
- vb2_dma_contig_clear_max_seg_size(&pdev->dev);
-
- clk_disable(fimc->clock[CLK_BUS]);
- fimc_clk_put(fimc);
-
- dev_info(&pdev->dev, "driver unloaded\n");
- return 0;
-}
-
-/* S5PV210, S5PC110 */
-static const struct fimc_drvdata fimc_drvdata_s5pv210 = {
- .num_entities = 3,
- .lclk_frequency = 166000000UL,
- .out_buf_count = 4,
- .dma_pix_hoff = 1,
-};
-
-/* EXYNOS4210, S5PV310, S5PC210 */
-static const struct fimc_drvdata fimc_drvdata_exynos4210 = {
- .num_entities = 4,
- .lclk_frequency = 166000000UL,
- .dma_pix_hoff = 1,
- .cistatus2 = 1,
- .alpha_color = 1,
- .out_buf_count = 32,
-};
-
-/* EXYNOS4412 */
-static const struct fimc_drvdata fimc_drvdata_exynos4x12 = {
- .num_entities = 4,
- .lclk_frequency = 166000000UL,
- .dma_pix_hoff = 1,
- .cistatus2 = 1,
- .alpha_color = 1,
- .out_buf_count = 32,
-};
-
-static const struct of_device_id fimc_of_match[] = {
- {
- .compatible = "samsung,s5pv210-fimc",
- .data = &fimc_drvdata_s5pv210,
- }, {
- .compatible = "samsung,exynos4210-fimc",
- .data = &fimc_drvdata_exynos4210,
- }, {
- .compatible = "samsung,exynos4212-fimc",
- .data = &fimc_drvdata_exynos4x12,
- },
- { /* sentinel */ },
-};
-
-static const struct dev_pm_ops fimc_pm_ops = {
- SET_SYSTEM_SLEEP_PM_OPS(fimc_suspend, fimc_resume)
- SET_RUNTIME_PM_OPS(fimc_runtime_suspend, fimc_runtime_resume, NULL)
-};
-
-static struct platform_driver fimc_driver = {
- .probe = fimc_probe,
- .remove = fimc_remove,
- .driver = {
- .of_match_table = fimc_of_match,
- .name = FIMC_DRIVER_NAME,
- .pm = &fimc_pm_ops,
- }
-};
-
-int __init fimc_register_driver(void)
-{
- return platform_driver_register(&fimc_driver);
-}
-
-void __exit fimc_unregister_driver(void)
-{
- platform_driver_unregister(&fimc_driver);
-}
diff --git a/drivers/media/platform/exynos4-is/fimc-core.h b/drivers/media/platform/exynos4-is/fimc-core.h
deleted file mode 100644
index 7a058f3e6298..000000000000
--- a/drivers/media/platform/exynos4-is/fimc-core.h
+++ /dev/null
@@ -1,725 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-only */
-/*
- * Copyright (C) 2010 - 2012 Samsung Electronics Co., Ltd.
- */
-
-#ifndef FIMC_CORE_H_
-#define FIMC_CORE_H_
-
-/*#define DEBUG*/
-
-#include <linux/platform_device.h>
-#include <linux/regmap.h>
-#include <linux/sched.h>
-#include <linux/spinlock.h>
-#include <linux/mfd/syscon.h>
-#include <linux/types.h>
-#include <linux/videodev2.h>
-#include <linux/io.h>
-#include <linux/sizes.h>
-
-#include <media/media-entity.h>
-#include <media/videobuf2-v4l2.h>
-#include <media/v4l2-ctrls.h>
-#include <media/v4l2-device.h>
-#include <media/v4l2-mem2mem.h>
-#include <media/v4l2-mediabus.h>
-#include <media/drv-intf/exynos-fimc.h>
-
-#define dbg(fmt, args...) \
- pr_debug("%s:%d: " fmt "\n", __func__, __LINE__, ##args)
-
-/* Time to wait for next frame VSYNC interrupt while stopping operation. */
-#define FIMC_SHUTDOWN_TIMEOUT ((100*HZ)/1000)
-#define MAX_FIMC_CLOCKS 2
-#define FIMC_DRIVER_NAME "exynos4-fimc"
-#define FIMC_MAX_DEVS 4
-#define FIMC_MAX_OUT_BUFS 4
-#define SCALER_MAX_HRATIO 64
-#define SCALER_MAX_VRATIO 64
-#define DMA_MIN_SIZE 8
-#define FIMC_CAMIF_MAX_HEIGHT 0x2000
-#define FIMC_MAX_JPEG_BUF_SIZE (10 * SZ_1M)
-#define FIMC_MAX_PLANES 3
-#define FIMC_PIX_LIMITS_MAX 4
-#define FIMC_DEF_MIN_SIZE 16
-#define FIMC_DEF_HEIGHT_ALIGN 2
-#define FIMC_DEF_HOR_OFFS_ALIGN 1
-#define FIMC_DEFAULT_WIDTH 640
-#define FIMC_DEFAULT_HEIGHT 480
-
-/* indices to the clocks array */
-enum {
- CLK_BUS,
- CLK_GATE,
-};
-
-enum fimc_dev_flags {
- ST_LPM,
- /* m2m node */
- ST_M2M_RUN,
- ST_M2M_PEND,
- ST_M2M_SUSPENDING,
- ST_M2M_SUSPENDED,
- /* capture node */
- ST_CAPT_PEND,
- ST_CAPT_RUN,
- ST_CAPT_STREAM,
- ST_CAPT_ISP_STREAM,
- ST_CAPT_SUSPENDED,
- ST_CAPT_SHUT,
- ST_CAPT_BUSY,
- ST_CAPT_APPLY_CFG,
- ST_CAPT_JPEG,
-};
-
-#define fimc_m2m_active(dev) test_bit(ST_M2M_RUN, &(dev)->state)
-#define fimc_m2m_pending(dev) test_bit(ST_M2M_PEND, &(dev)->state)
-
-#define fimc_capture_running(dev) test_bit(ST_CAPT_RUN, &(dev)->state)
-#define fimc_capture_pending(dev) test_bit(ST_CAPT_PEND, &(dev)->state)
-#define fimc_capture_busy(dev) test_bit(ST_CAPT_BUSY, &(dev)->state)
-
-enum fimc_datapath {
- FIMC_IO_NONE,
- FIMC_IO_CAMERA,
- FIMC_IO_DMA,
- FIMC_IO_LCDFIFO,
- FIMC_IO_WRITEBACK,
- FIMC_IO_ISP,
-};
-
-enum fimc_color_fmt {
- FIMC_FMT_RGB444 = 0x10,
- FIMC_FMT_RGB555,
- FIMC_FMT_RGB565,
- FIMC_FMT_RGB666,
- FIMC_FMT_RGB888,
- FIMC_FMT_RGB30_LOCAL,
- FIMC_FMT_YCBCR420 = 0x20,
- FIMC_FMT_YCBYCR422,
- FIMC_FMT_YCRYCB422,
- FIMC_FMT_CBYCRY422,
- FIMC_FMT_CRYCBY422,
- FIMC_FMT_YCBCR444_LOCAL,
- FIMC_FMT_RAW8 = 0x40,
- FIMC_FMT_RAW10,
- FIMC_FMT_RAW12,
- FIMC_FMT_JPEG = 0x80,
- FIMC_FMT_YUYV_JPEG = 0x100,
-};
-
-#define fimc_fmt_is_user_defined(x) (!!((x) & 0x180))
-#define fimc_fmt_is_rgb(x) (!!((x) & 0x10))
-
-#define IS_M2M(__strt) ((__strt) == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE || \
- __strt == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE)
-
-/* The hardware context state. */
-#define FIMC_PARAMS (1 << 0)
-#define FIMC_COMPOSE (1 << 1)
-#define FIMC_CTX_M2M (1 << 16)
-#define FIMC_CTX_CAP (1 << 17)
-#define FIMC_CTX_SHUT (1 << 18)
-
-/* Image conversion flags */
-#define FIMC_IN_DMA_ACCESS_TILED (1 << 0)
-#define FIMC_IN_DMA_ACCESS_LINEAR (0 << 0)
-#define FIMC_OUT_DMA_ACCESS_TILED (1 << 1)
-#define FIMC_OUT_DMA_ACCESS_LINEAR (0 << 1)
-#define FIMC_SCAN_MODE_PROGRESSIVE (0 << 2)
-#define FIMC_SCAN_MODE_INTERLACED (1 << 2)
-/*
- * YCbCr data dynamic range for RGB-YUV color conversion.
- * Y/Cb/Cr: (0 ~ 255) */
-#define FIMC_COLOR_RANGE_WIDE (0 << 3)
-/* Y (16 ~ 235), Cb/Cr (16 ~ 240) */
-#define FIMC_COLOR_RANGE_NARROW (1 << 3)
-
-/**
- * struct fimc_dma_offset - pixel offset information for DMA
- * @y_h: y value horizontal offset
- * @y_v: y value vertical offset
- * @cb_h: cb value horizontal offset
- * @cb_v: cb value vertical offset
- * @cr_h: cr value horizontal offset
- * @cr_v: cr value vertical offset
- */
-struct fimc_dma_offset {
- int y_h;
- int y_v;
- int cb_h;
- int cb_v;
- int cr_h;
- int cr_v;
-};
-
-/**
- * struct fimc_effect - color effect information
- * @type: effect type
- * @pat_cb: cr value when type is "arbitrary"
- * @pat_cr: cr value when type is "arbitrary"
- */
-struct fimc_effect {
- u32 type;
- u8 pat_cb;
- u8 pat_cr;
-};
-
-/**
- * struct fimc_scaler - the configuration data for FIMC inetrnal scaler
- * @scaleup_h: flag indicating scaling up horizontally
- * @scaleup_v: flag indicating scaling up vertically
- * @copy_mode: flag indicating transparent DMA transfer (no scaling
- * and color format conversion)
- * @enabled: flag indicating if the scaler is used
- * @hfactor: horizontal shift factor
- * @vfactor: vertical shift factor
- * @pre_hratio: horizontal ratio of the prescaler
- * @pre_vratio: vertical ratio of the prescaler
- * @pre_dst_width: the prescaler's destination width
- * @pre_dst_height: the prescaler's destination height
- * @main_hratio: the main scaler's horizontal ratio
- * @main_vratio: the main scaler's vertical ratio
- * @real_width: source pixel (width - offset)
- * @real_height: source pixel (height - offset)
- */
-struct fimc_scaler {
- unsigned int scaleup_h:1;
- unsigned int scaleup_v:1;
- unsigned int copy_mode:1;
- unsigned int enabled:1;
- u32 hfactor;
- u32 vfactor;
- u32 pre_hratio;
- u32 pre_vratio;
- u32 pre_dst_width;
- u32 pre_dst_height;
- u32 main_hratio;
- u32 main_vratio;
- u32 real_width;
- u32 real_height;
-};
-
-/**
- * struct fimc_addr - the FIMC address set for DMA
- * @y: luminance plane address
- * @cb: Cb plane address
- * @cr: Cr plane address
- */
-struct fimc_addr {
- u32 y;
- u32 cb;
- u32 cr;
-};
-
-/**
- * struct fimc_vid_buffer - the driver's video buffer
- * @vb: v4l videobuf buffer
- * @list: linked list structure for buffer queue
- * @addr: precalculated DMA address set
- * @index: buffer index for the output DMA engine
- */
-struct fimc_vid_buffer {
- struct vb2_v4l2_buffer vb;
- struct list_head list;
- struct fimc_addr addr;
- int index;
-};
-
-/**
- * struct fimc_frame - source/target frame properties
- * @f_width: image full width (virtual screen size)
- * @f_height: image full height (virtual screen size)
- * @o_width: original image width as set by S_FMT
- * @o_height: original image height as set by S_FMT
- * @offs_h: image horizontal pixel offset
- * @offs_v: image vertical pixel offset
- * @width: image pixel width
- * @height: image pixel weight
- * @payload: image size in bytes (w x h x bpp)
- * @bytesperline: bytesperline value for each plane
- * @addr: image frame buffer DMA addresses
- * @dma_offset: DMA offset in bytes
- * @fmt: fimc color format pointer
- * @alpha: alpha value
- */
-struct fimc_frame {
- u32 f_width;
- u32 f_height;
- u32 o_width;
- u32 o_height;
- u32 offs_h;
- u32 offs_v;
- u32 width;
- u32 height;
- unsigned int payload[VIDEO_MAX_PLANES];
- unsigned int bytesperline[VIDEO_MAX_PLANES];
- struct fimc_addr addr;
- struct fimc_dma_offset dma_offset;
- struct fimc_fmt *fmt;
- u8 alpha;
-};
-
-/**
- * struct fimc_m2m_device - v4l2 memory-to-memory device data
- * @vfd: the video device node for v4l2 m2m mode
- * @m2m_dev: v4l2 memory-to-memory device data
- * @ctx: hardware context data
- * @refcnt: the reference counter
- */
-struct fimc_m2m_device {
- struct video_device vfd;
- struct v4l2_m2m_dev *m2m_dev;
- struct fimc_ctx *ctx;
- int refcnt;
-};
-
-#define FIMC_SD_PAD_SINK_CAM 0
-#define FIMC_SD_PAD_SINK_FIFO 1
-#define FIMC_SD_PAD_SOURCE 2
-#define FIMC_SD_PADS_NUM 3
-
-/**
- * struct fimc_vid_cap - camera capture device information
- * @ctx: hardware context data
- * @subdev: subdev exposing the FIMC processing block
- * @ve: exynos video device entity structure
- * @vd_pad: fimc video capture node pad
- * @sd_pads: fimc video processing block pads
- * @ci_fmt: image format at the FIMC camera input (and the scaler output)
- * @wb_fmt: image format at the FIMC ISP Writeback input
- * @source_config: external image source related configuration structure
- * @pending_buf_q: the pending buffer queue head
- * @active_buf_q: the queue head of buffers scheduled in hardware
- * @vbq: the capture am video buffer queue
- * @active_buf_cnt: number of video buffers scheduled in hardware
- * @buf_index: index for managing the output DMA buffers
- * @frame_count: the frame counter for statistics
- * @reqbufs_count: the number of buffers requested in REQBUFS ioctl
- * @streaming: is streaming in progress?
- * @input: capture input type, grp_id of the attached subdev
- * @user_subdev_api: true if subdevs are not configured by the host driver
- */
-struct fimc_vid_cap {
- struct fimc_ctx *ctx;
- struct v4l2_subdev subdev;
- struct exynos_video_entity ve;
- struct media_pad vd_pad;
- struct media_pad sd_pads[FIMC_SD_PADS_NUM];
- struct v4l2_mbus_framefmt ci_fmt;
- struct v4l2_mbus_framefmt wb_fmt;
- struct fimc_source_info source_config;
- struct list_head pending_buf_q;
- struct list_head active_buf_q;
- struct vb2_queue vbq;
- int active_buf_cnt;
- int buf_index;
- unsigned int frame_count;
- unsigned int reqbufs_count;
- bool streaming;
- u32 input;
- bool user_subdev_api;
-};
-
-/**
- * struct fimc_pix_limit - image pixel size limits in various IP configurations
- *
- * @scaler_en_w: max input pixel width when the scaler is enabled
- * @scaler_dis_w: max input pixel width when the scaler is disabled
- * @in_rot_en_h: max input width with the input rotator is on
- * @in_rot_dis_w: max input width with the input rotator is off
- * @out_rot_en_w: max output width with the output rotator on
- * @out_rot_dis_w: max output width with the output rotator off
- */
-struct fimc_pix_limit {
- u16 scaler_en_w;
- u16 scaler_dis_w;
- u16 in_rot_en_h;
- u16 in_rot_dis_w;
- u16 out_rot_en_w;
- u16 out_rot_dis_w;
-};
-
-/**
- * struct fimc_variant - FIMC device variant information
- * @has_inp_rot: set if has input rotator
- * @has_out_rot: set if has output rotator
- * @has_mainscaler_ext: 1 if extended mainscaler ratios in CIEXTEN register
- * are present in this IP revision
- * @has_cam_if: set if this instance has a camera input interface
- * @has_isp_wb: set if this instance has ISP writeback input
- * @pix_limit: pixel size constraints for the scaler
- * @min_inp_pixsize: minimum input pixel size
- * @min_out_pixsize: minimum output pixel size
- * @hor_offs_align: horizontal pixel offset alignment
- * @min_vsize_align: minimum vertical pixel size alignment
- */
-struct fimc_variant {
- unsigned int has_inp_rot:1;
- unsigned int has_out_rot:1;
- unsigned int has_mainscaler_ext:1;
- unsigned int has_cam_if:1;
- unsigned int has_isp_wb:1;
- const struct fimc_pix_limit *pix_limit;
- u16 min_inp_pixsize;
- u16 min_out_pixsize;
- u16 hor_offs_align;
- u16 min_vsize_align;
-};
-
-/**
- * struct fimc_drvdata - per device type driver data
- * @variant: variant information for this device
- * @num_entities: number of fimc instances available in a SoC
- * @lclk_frequency: local bus clock frequency
- * @cistatus2: 1 if the FIMC IPs have CISTATUS2 register
- * @dma_pix_hoff: the horizontal DMA offset unit: 1 - pixels, 0 - bytes
- * @alpha_color: 1 if alpha color component is supported
- * @out_buf_count: maximum number of output DMA buffers supported
- */
-struct fimc_drvdata {
- const struct fimc_variant *variant[FIMC_MAX_DEVS];
- int num_entities;
- unsigned long lclk_frequency;
- /* Fields common to all FIMC IP instances */
- u8 cistatus2;
- u8 dma_pix_hoff;
- u8 alpha_color;
- u8 out_buf_count;
-};
-
-#define fimc_get_drvdata(_pdev) \
- ((struct fimc_drvdata *) platform_get_device_id(_pdev)->driver_data)
-
-struct fimc_ctx;
-
-/**
- * struct fimc_dev - abstraction for FIMC entity
- * @slock: the spinlock protecting this data structure
- * @lock: the mutex protecting this data structure
- * @pdev: pointer to the FIMC platform device
- * @pdata: pointer to the device platform data
- * @sysreg: pointer to the SYSREG regmap
- * @variant: the IP variant information
- * @drv_data: driver data
- * @id: FIMC device index (0..FIMC_MAX_DEVS)
- * @clock: clocks required for FIMC operation
- * @regs: the mapped hardware registers
- * @irq_queue: interrupt handler waitqueue
- * @v4l2_dev: root v4l2_device
- * @m2m: memory-to-memory V4L2 device information
- * @vid_cap: camera capture device information
- * @state: flags used to synchronize m2m and capture mode operation
- */
-struct fimc_dev {
- spinlock_t slock;
- struct mutex lock;
- struct platform_device *pdev;
- struct s5p_platform_fimc *pdata;
- struct regmap *sysreg;
- const struct fimc_variant *variant;
- const struct fimc_drvdata *drv_data;
- int id;
- struct clk *clock[MAX_FIMC_CLOCKS];
- void __iomem *regs;
- wait_queue_head_t irq_queue;
- struct v4l2_device *v4l2_dev;
- struct fimc_m2m_device m2m;
- struct fimc_vid_cap vid_cap;
- unsigned long state;
-};
-
-/**
- * struct fimc_ctrls - v4l2 controls structure
- * @handler: the control handler
- * @colorfx: image effect control
- * @colorfx_cbcr: Cb/Cr coefficients control
- * @rotate: image rotation control
- * @hflip: horizontal flip control
- * @vflip: vertical flip control
- * @alpha: RGB alpha control
- * @ready: true if @handler is initialized
- */
-struct fimc_ctrls {
- struct v4l2_ctrl_handler handler;
- struct {
- struct v4l2_ctrl *colorfx;
- struct v4l2_ctrl *colorfx_cbcr;
- };
- struct v4l2_ctrl *rotate;
- struct v4l2_ctrl *hflip;
- struct v4l2_ctrl *vflip;
- struct v4l2_ctrl *alpha;
- bool ready;
-};
-
-/**
- * struct fimc_ctx - the device context data
- * @s_frame: source frame properties
- * @d_frame: destination frame properties
- * @out_order_1p: output 1-plane YCBCR order
- * @out_order_2p: output 2-plane YCBCR order
- * @in_order_1p: input 1-plane YCBCR order
- * @in_order_2p: input 2-plane YCBCR order
- * @in_path: input mode (DMA or camera)
- * @out_path: output mode (DMA or FIFO)
- * @scaler: image scaler properties
- * @effect: image effect
- * @rotation: image clockwise rotation in degrees
- * @hflip: indicates image horizontal flip if set
- * @vflip: indicates image vertical flip if set
- * @flags: additional flags for image conversion
- * @state: flags to keep track of user configuration
- * @fimc_dev: the FIMC device this context applies to
- * @fh: v4l2 file handle
- * @ctrls: v4l2 controls structure
- */
-struct fimc_ctx {
- struct fimc_frame s_frame;
- struct fimc_frame d_frame;
- u32 out_order_1p;
- u32 out_order_2p;
- u32 in_order_1p;
- u32 in_order_2p;
- enum fimc_datapath in_path;
- enum fimc_datapath out_path;
- struct fimc_scaler scaler;
- struct fimc_effect effect;
- int rotation;
- unsigned int hflip:1;
- unsigned int vflip:1;
- u32 flags;
- u32 state;
- struct fimc_dev *fimc_dev;
- struct v4l2_fh fh;
- struct fimc_ctrls ctrls;
-};
-
-#define fh_to_ctx(__fh) container_of(__fh, struct fimc_ctx, fh)
-
-static inline void set_frame_bounds(struct fimc_frame *f, u32 width, u32 height)
-{
- f->o_width = width;
- f->o_height = height;
- f->f_width = width;
- f->f_height = height;
-}
-
-static inline void set_frame_crop(struct fimc_frame *f,
- u32 left, u32 top, u32 width, u32 height)
-{
- f->offs_h = left;
- f->offs_v = top;
- f->width = width;
- f->height = height;
-}
-
-static inline u32 fimc_get_format_depth(struct fimc_fmt *ff)
-{
- u32 i, depth = 0;
-
- if (ff != NULL)
- for (i = 0; i < ff->colplanes; i++)
- depth += ff->depth[i];
- return depth;
-}
-
-static inline bool fimc_capture_active(struct fimc_dev *fimc)
-{
- unsigned long flags;
- bool ret;
-
- spin_lock_irqsave(&fimc->slock, flags);
- ret = !!(fimc->state & (1 << ST_CAPT_RUN) ||
- fimc->state & (1 << ST_CAPT_PEND));
- spin_unlock_irqrestore(&fimc->slock, flags);
- return ret;
-}
-
-static inline void fimc_ctx_state_set(u32 state, struct fimc_ctx *ctx)
-{
- unsigned long flags;
-
- spin_lock_irqsave(&ctx->fimc_dev->slock, flags);
- ctx->state |= state;
- spin_unlock_irqrestore(&ctx->fimc_dev->slock, flags);
-}
-
-static inline bool fimc_ctx_state_is_set(u32 mask, struct fimc_ctx *ctx)
-{
- unsigned long flags;
- bool ret;
-
- spin_lock_irqsave(&ctx->fimc_dev->slock, flags);
- ret = (ctx->state & mask) == mask;
- spin_unlock_irqrestore(&ctx->fimc_dev->slock, flags);
- return ret;
-}
-
-static inline int tiled_fmt(struct fimc_fmt *fmt)
-{
- return fmt->fourcc == V4L2_PIX_FMT_NV12MT;
-}
-
-static inline bool fimc_jpeg_fourcc(u32 pixelformat)
-{
- return (pixelformat == V4L2_PIX_FMT_JPEG ||
- pixelformat == V4L2_PIX_FMT_S5C_UYVY_JPG);
-}
-
-static inline bool fimc_user_defined_mbus_fmt(u32 code)
-{
- return (code == MEDIA_BUS_FMT_JPEG_1X8 ||
- code == MEDIA_BUS_FMT_S5C_UYVY_JPEG_1X8);
-}
-
-/* Return the alpha component bit mask */
-static inline int fimc_get_alpha_mask(struct fimc_fmt *fmt)
-{
- switch (fmt->color) {
- case FIMC_FMT_RGB444: return 0x0f;
- case FIMC_FMT_RGB555: return 0x01;
- case FIMC_FMT_RGB888: return 0xff;
- default: return 0;
- };
-}
-
-static inline struct fimc_frame *ctx_get_frame(struct fimc_ctx *ctx,
- enum v4l2_buf_type type)
-{
- struct fimc_frame *frame;
-
- if (type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE ||
- type == V4L2_BUF_TYPE_VIDEO_OUTPUT) {
- if (fimc_ctx_state_is_set(FIMC_CTX_M2M, ctx))
- frame = &ctx->s_frame;
- else
- return ERR_PTR(-EINVAL);
- } else if (type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE ||
- type == V4L2_BUF_TYPE_VIDEO_CAPTURE) {
- frame = &ctx->d_frame;
- } else {
- v4l2_err(ctx->fimc_dev->v4l2_dev,
- "Wrong buffer/video queue type (%d)\n", type);
- return ERR_PTR(-EINVAL);
- }
-
- return frame;
-}
-
-/* -----------------------------------------------------*/
-/* fimc-core.c */
-int fimc_vidioc_enum_fmt_mplane(struct file *file, void *priv,
- struct v4l2_fmtdesc *f);
-int fimc_ctrls_create(struct fimc_ctx *ctx);
-void fimc_ctrls_delete(struct fimc_ctx *ctx);
-void fimc_ctrls_activate(struct fimc_ctx *ctx, bool active);
-void fimc_alpha_ctrl_update(struct fimc_ctx *ctx);
-void __fimc_get_format(struct fimc_frame *frame, struct v4l2_format *f);
-void fimc_adjust_mplane_format(struct fimc_fmt *fmt, u32 width, u32 height,
- struct v4l2_pix_format_mplane *pix);
-struct fimc_fmt *fimc_find_format(const u32 *pixelformat, const u32 *mbus_code,
- unsigned int mask, int index);
-struct fimc_fmt *fimc_get_format(unsigned int index);
-
-int fimc_check_scaler_ratio(struct fimc_ctx *ctx, int sw, int sh,
- int dw, int dh, int rotation);
-int fimc_set_scaler_info(struct fimc_ctx *ctx);
-int fimc_prepare_config(struct fimc_ctx *ctx, u32 flags);
-int fimc_prepare_addr(struct fimc_ctx *ctx, struct vb2_buffer *vb,
- struct fimc_frame *frame, struct fimc_addr *addr);
-void fimc_prepare_dma_offset(struct fimc_ctx *ctx, struct fimc_frame *f);
-void fimc_set_yuv_order(struct fimc_ctx *ctx);
-void fimc_capture_irq_handler(struct fimc_dev *fimc, int deq_buf);
-
-int fimc_register_m2m_device(struct fimc_dev *fimc,
- struct v4l2_device *v4l2_dev);
-void fimc_unregister_m2m_device(struct fimc_dev *fimc);
-int fimc_register_driver(void);
-void fimc_unregister_driver(void);
-
-#ifdef CONFIG_MFD_SYSCON
-static inline struct regmap * fimc_get_sysreg_regmap(struct device_node *node)
-{
- return syscon_regmap_lookup_by_phandle(node, "samsung,sysreg");
-}
-#else
-#define fimc_get_sysreg_regmap(node) (NULL)
-#endif
-
-/* -----------------------------------------------------*/
-/* fimc-m2m.c */
-void fimc_m2m_job_finish(struct fimc_ctx *ctx, int vb_state);
-
-/* -----------------------------------------------------*/
-/* fimc-capture.c */
-int fimc_initialize_capture_subdev(struct fimc_dev *fimc);
-void fimc_unregister_capture_subdev(struct fimc_dev *fimc);
-int fimc_capture_ctrls_create(struct fimc_dev *fimc);
-void fimc_sensor_notify(struct v4l2_subdev *sd, unsigned int notification,
- void *arg);
-int fimc_capture_suspend(struct fimc_dev *fimc);
-int fimc_capture_resume(struct fimc_dev *fimc);
-
-/*
- * Buffer list manipulation functions. Must be called with fimc.slock held.
- */
-
-/**
- * fimc_active_queue_add - add buffer to the capture active buffers queue
- * @vid_cap: camera capture device information
- * @buf: buffer to add to the active buffers list
- */
-static inline void fimc_active_queue_add(struct fimc_vid_cap *vid_cap,
- struct fimc_vid_buffer *buf)
-{
- list_add_tail(&buf->list, &vid_cap->active_buf_q);
- vid_cap->active_buf_cnt++;
-}
-
-/**
- * fimc_active_queue_pop - pop buffer from the capture active buffers queue
- * @vid_cap: camera capture device information
- *
- * The caller must assure the active_buf_q list is not empty.
- */
-static inline struct fimc_vid_buffer *fimc_active_queue_pop(
- struct fimc_vid_cap *vid_cap)
-{
- struct fimc_vid_buffer *buf;
- buf = list_entry(vid_cap->active_buf_q.next,
- struct fimc_vid_buffer, list);
- list_del(&buf->list);
- vid_cap->active_buf_cnt--;
- return buf;
-}
-
-/**
- * fimc_pending_queue_add - add buffer to the capture pending buffers queue
- * @vid_cap: camera capture device information
- * @buf: buffer to add to the pending buffers list
- */
-static inline void fimc_pending_queue_add(struct fimc_vid_cap *vid_cap,
- struct fimc_vid_buffer *buf)
-{
- list_add_tail(&buf->list, &vid_cap->pending_buf_q);
-}
-
-/**
- * fimc_pending_queue_pop - pop buffer from the capture pending buffers queue
- * @vid_cap: camera capture device information
- *
- * The caller must assure the pending_buf_q list is not empty.
- */
-static inline struct fimc_vid_buffer *fimc_pending_queue_pop(
- struct fimc_vid_cap *vid_cap)
-{
- struct fimc_vid_buffer *buf;
- buf = list_entry(vid_cap->pending_buf_q.next,
- struct fimc_vid_buffer, list);
- list_del(&buf->list);
- return buf;
-}
-
-#endif /* FIMC_CORE_H_ */
diff --git a/drivers/media/platform/exynos4-is/fimc-is-command.h b/drivers/media/platform/exynos4-is/fimc-is-command.h
deleted file mode 100644
index 87978609ad55..000000000000
--- a/drivers/media/platform/exynos4-is/fimc-is-command.h
+++ /dev/null
@@ -1,134 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-only */
-/*
- * Samsung Exynos4x12 FIMC-IS (Imaging Subsystem) driver
- *
- * FIMC-IS command set definitions
- *
- * Copyright (C) 2013 Samsung Electronics Co., Ltd.
- *
- * Authors: Younghwan Joo <yhwan.joo@samsung.com>
- * Sylwester Nawrocki <s.nawrocki@samsung.com>
- */
-
-#ifndef FIMC_IS_CMD_H_
-#define FIMC_IS_CMD_H_
-
-#define FIMC_IS_COMMAND_VER 110 /* FIMC-IS command set version 1.10 */
-
-/* Enumeration of commands between the FIMC-IS and the host processor. */
-
-/* HOST to FIMC-IS */
-#define HIC_PREVIEW_STILL 0x0001
-#define HIC_PREVIEW_VIDEO 0x0002
-#define HIC_CAPTURE_STILL 0x0003
-#define HIC_CAPTURE_VIDEO 0x0004
-#define HIC_STREAM_ON 0x0005
-#define HIC_STREAM_OFF 0x0006
-#define HIC_SET_PARAMETER 0x0007
-#define HIC_GET_PARAMETER 0x0008
-#define HIC_SET_TUNE 0x0009
-#define HIC_GET_STATUS 0x000b
-/* Sensor part */
-#define HIC_OPEN_SENSOR 0x000c
-#define HIC_CLOSE_SENSOR 0x000d
-#define HIC_SIMMIAN_INIT 0x000e
-#define HIC_SIMMIAN_WRITE 0x000f
-#define HIC_SIMMIAN_READ 0x0010
-#define HIC_POWER_DOWN 0x0011
-#define HIC_GET_SET_FILE_ADDR 0x0012
-#define HIC_LOAD_SET_FILE 0x0013
-#define HIC_MSG_CONFIG 0x0014
-#define HIC_MSG_TEST 0x0015
-/* FIMC-IS to HOST */
-#define IHC_GET_SENSOR_NUM 0x1000
-#define IHC_SET_SHOT_MARK 0x1001
-/* parameter1: frame number */
-/* parameter2: confidence level (smile 0~100) */
-/* parameter3: confidence level (blink 0~100) */
-#define IHC_SET_FACE_MARK 0x1002
-/* parameter1: coordinate count */
-/* parameter2: coordinate buffer address */
-#define IHC_FRAME_DONE 0x1003
-/* parameter1: frame start number */
-/* parameter2: frame count */
-#define IHC_AA_DONE 0x1004
-#define IHC_NOT_READY 0x1005
-
-#define IH_REPLY_DONE 0x2000
-#define IH_REPLY_NOT_DONE 0x2001
-
-enum fimc_is_scenario {
- IS_SC_PREVIEW_STILL,
- IS_SC_PREVIEW_VIDEO,
- IS_SC_CAPTURE_STILL,
- IS_SC_CAPTURE_VIDEO,
- IS_SC_MAX
-};
-
-enum fimc_is_sub_scenario {
- IS_SC_SUB_DEFAULT,
- IS_SC_SUB_PS_VTCALL,
- IS_SC_SUB_CS_VTCALL,
- IS_SC_SUB_PV_VTCALL,
- IS_SC_SUB_CV_VTCALL,
-};
-
-struct is_common_regs {
- u32 hicmd;
- u32 hic_sensorid;
- u32 hic_param[4];
- u32 reserved1[4];
-
- u32 ihcmd;
- u32 ihc_sensorid;
- u32 ihc_param[4];
- u32 reserved2[4];
-
- u32 isp_sensor_id;
- u32 isp_param[2];
- u32 reserved3[1];
-
- u32 scc_sensor_id;
- u32 scc_param[2];
- u32 reserved4[1];
-
- u32 dnr_sensor_id;
- u32 dnr_param[2];
- u32 reserved5[1];
-
- u32 scp_sensor_id;
- u32 scp_param[2];
- u32 reserved6[29];
-} __packed;
-
-struct is_mcuctl_reg {
- u32 mcuctl;
- u32 bboar;
-
- u32 intgr0;
- u32 intcr0;
- u32 intmr0;
- u32 intsr0;
- u32 intmsr0;
-
- u32 intgr1;
- u32 intcr1;
- u32 intmr1;
- u32 intsr1;
- u32 intmsr1;
-
- u32 intcr2;
- u32 intmr2;
- u32 intsr2;
- u32 intmsr2;
-
- u32 gpoctrl;
- u32 cpoenctlr;
- u32 gpictlr;
-
- u32 reserved[0xd];
-
- struct is_common_regs common;
-} __packed;
-
-#endif /* FIMC_IS_CMD_H_ */
diff --git a/drivers/media/platform/exynos4-is/fimc-is-errno.c b/drivers/media/platform/exynos4-is/fimc-is-errno.c
deleted file mode 100644
index 5d9f4c1cdc5e..000000000000
--- a/drivers/media/platform/exynos4-is/fimc-is-errno.c
+++ /dev/null
@@ -1,269 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-/*
- * Samsung Exynos4 SoC series FIMC-IS slave interface driver
- *
- * Error log interface functions
- *
- * Copyright (C) 2011 - 2013 Samsung Electronics Co., Ltd.
- *
- * Authors: Younghwan Joo <yhwan.joo@samsung.com>
- * Sylwester Nawrocki <s.nawrocki@samsung.com>
- */
-
-#include "fimc-is-errno.h"
-
-const char *fimc_is_param_strerr(unsigned int error)
-{
- switch (error) {
- case ERROR_COMMON_CMD:
- return "ERROR_COMMON_CMD: Invalid Command";
- case ERROR_COMMON_PARAMETER:
- return "ERROR_COMMON_PARAMETER: Invalid Parameter";
- case ERROR_COMMON_SETFILE_LOAD:
- return "ERROR_COMMON_SETFILE_LOAD: Illegal Setfile Loading";
- case ERROR_COMMON_SETFILE_ADJUST:
- return "ERROR_COMMON_SETFILE_ADJUST: Setfile isn't adjusted";
- case ERROR_COMMON_SETFILE_INDEX:
- return "ERROR_COMMON_SETFILE_INDEX: Invalid setfile index";
- case ERROR_COMMON_INPUT_PATH:
- return "ERROR_COMMON_INPUT_PATH: Input path can be changed in ready state";
- case ERROR_COMMON_INPUT_INIT:
- return "ERROR_COMMON_INPUT_INIT: IP can not start if input path is not set";
- case ERROR_COMMON_OUTPUT_PATH:
- return "ERROR_COMMON_OUTPUT_PATH: Output path can be changed in ready state (stop)";
- case ERROR_COMMON_OUTPUT_INIT:
- return "ERROR_COMMON_OUTPUT_INIT: IP can not start if output path is not set";
- case ERROR_CONTROL_BYPASS:
- return "ERROR_CONTROL_BYPASS";
- case ERROR_OTF_INPUT_FORMAT:
- return "ERROR_OTF_INPUT_FORMAT: Invalid format (DRC: YUV444, FD: YUV444, 422, 420)";
- case ERROR_OTF_INPUT_WIDTH:
- return "ERROR_OTF_INPUT_WIDTH: Invalid width (DRC: 128~8192, FD: 32~8190)";
- case ERROR_OTF_INPUT_HEIGHT:
- return "ERROR_OTF_INPUT_HEIGHT: Invalid bit-width (DRC: 8~12bits, FD: 8bit)";
- case ERROR_OTF_INPUT_BIT_WIDTH:
- return "ERROR_OTF_INPUT_BIT_WIDTH: Invalid bit-width (DRC: 8~12bits, FD: 8bit)";
- case ERROR_DMA_INPUT_WIDTH:
- return "ERROR_DMA_INPUT_WIDTH: Invalid width (DRC: 128~8192, FD: 32~8190)";
- case ERROR_DMA_INPUT_HEIGHT:
- return "ERROR_DMA_INPUT_HEIGHT: Invalid height (DRC: 64~8192, FD: 16~8190)";
- case ERROR_DMA_INPUT_FORMAT:
- return "ERROR_DMA_INPUT_FORMAT: Invalid format (DRC: YUV444 or YUV422, FD: YUV444,422,420)";
- case ERROR_DMA_INPUT_BIT_WIDTH:
- return "ERROR_DMA_INPUT_BIT_WIDTH: Invalid bit-width (DRC: 8~12bits, FD: 8bit)";
- case ERROR_DMA_INPUT_ORDER:
- return "ERROR_DMA_INPUT_ORDER: Invalid order(DRC: YYCbCr,YCbYCr,FD:NO,YYCbCr,YCbYCr,CbCr,CrCb)";
- case ERROR_DMA_INPUT_PLANE:
- return "ERROR_DMA_INPUT_PLANE: Invalid palne (DRC: 3, FD: 1, 2, 3)";
- case ERROR_OTF_OUTPUT_WIDTH:
- return "ERROR_OTF_OUTPUT_WIDTH: Invalid width (DRC: 128~8192)";
- case ERROR_OTF_OUTPUT_HEIGHT:
- return "ERROR_OTF_OUTPUT_HEIGHT: Invalid height (DRC: 64~8192)";
- case ERROR_OTF_OUTPUT_FORMAT:
- return "ERROR_OTF_OUTPUT_FORMAT: Invalid format (DRC: YUV444)";
- case ERROR_OTF_OUTPUT_BIT_WIDTH:
- return "ERROR_OTF_OUTPUT_BIT_WIDTH: Invalid bit-width (DRC: 8~12bits, FD: 8bit)";
- case ERROR_DMA_OUTPUT_WIDTH:
- return "ERROR_DMA_OUTPUT_WIDTH";
- case ERROR_DMA_OUTPUT_HEIGHT:
- return "ERROR_DMA_OUTPUT_HEIGHT";
- case ERROR_DMA_OUTPUT_FORMAT:
- return "ERROR_DMA_OUTPUT_FORMAT";
- case ERROR_DMA_OUTPUT_BIT_WIDTH:
- return "ERROR_DMA_OUTPUT_BIT_WIDTH";
- case ERROR_DMA_OUTPUT_PLANE:
- return "ERROR_DMA_OUTPUT_PLANE";
- case ERROR_DMA_OUTPUT_ORDER:
- return "ERROR_DMA_OUTPUT_ORDER";
-
- /* Sensor Error(100~199) */
- case ERROR_SENSOR_I2C_FAIL:
- return "ERROR_SENSOR_I2C_FAIL";
- case ERROR_SENSOR_INVALID_FRAMERATE:
- return "ERROR_SENSOR_INVALID_FRAMERATE";
- case ERROR_SENSOR_INVALID_EXPOSURETIME:
- return "ERROR_SENSOR_INVALID_EXPOSURETIME";
- case ERROR_SENSOR_INVALID_SIZE:
- return "ERROR_SENSOR_INVALID_SIZE";
- case ERROR_SENSOR_INVALID_SETTING:
- return "ERROR_SENSOR_INVALID_SETTING";
- case ERROR_SENSOR_ACTUATOR_INIT_FAIL:
- return "ERROR_SENSOR_ACTUATOR_INIT_FAIL";
- case ERROR_SENSOR_INVALID_AF_POS:
- return "ERROR_SENSOR_INVALID_AF_POS";
- case ERROR_SENSOR_UNSUPPORT_FUNC:
- return "ERROR_SENSOR_UNSUPPORT_FUNC";
- case ERROR_SENSOR_UNSUPPORT_PERI:
- return "ERROR_SENSOR_UNSUPPORT_PERI";
- case ERROR_SENSOR_UNSUPPORT_AF:
- return "ERROR_SENSOR_UNSUPPORT_AF";
-
- /* ISP Error (200~299) */
- case ERROR_ISP_AF_BUSY:
- return "ERROR_ISP_AF_BUSY";
- case ERROR_ISP_AF_INVALID_COMMAND:
- return "ERROR_ISP_AF_INVALID_COMMAND";
- case ERROR_ISP_AF_INVALID_MODE:
- return "ERROR_ISP_AF_INVALID_MODE";
-
- /* DRC Error (300~399) */
- /* FD Error (400~499) */
- case ERROR_FD_CONFIG_MAX_NUMBER_STATE:
- return "ERROR_FD_CONFIG_MAX_NUMBER_STATE";
- case ERROR_FD_CONFIG_MAX_NUMBER_INVALID:
- return "ERROR_FD_CONFIG_MAX_NUMBER_INVALID";
- case ERROR_FD_CONFIG_YAW_ANGLE_STATE:
- return "ERROR_FD_CONFIG_YAW_ANGLE_STATE";
- case ERROR_FD_CONFIG_YAW_ANGLE_INVALID:
- return "ERROR_FD_CONFIG_YAW_ANGLE_INVALID\n";
- case ERROR_FD_CONFIG_ROLL_ANGLE_STATE:
- return "ERROR_FD_CONFIG_ROLL_ANGLE_STATE";
- case ERROR_FD_CONFIG_ROLL_ANGLE_INVALID:
- return "ERROR_FD_CONFIG_ROLL_ANGLE_INVALID";
- case ERROR_FD_CONFIG_SMILE_MODE_INVALID:
- return "ERROR_FD_CONFIG_SMILE_MODE_INVALID";
- case ERROR_FD_CONFIG_BLINK_MODE_INVALID:
- return "ERROR_FD_CONFIG_BLINK_MODE_INVALID";
- case ERROR_FD_CONFIG_EYES_DETECT_INVALID:
- return "ERROR_FD_CONFIG_EYES_DETECT_INVALID";
- case ERROR_FD_CONFIG_MOUTH_DETECT_INVALID:
- return "ERROR_FD_CONFIG_MOUTH_DETECT_INVALID";
- case ERROR_FD_CONFIG_ORIENTATION_STATE:
- return "ERROR_FD_CONFIG_ORIENTATION_STATE";
- case ERROR_FD_CONFIG_ORIENTATION_INVALID:
- return "ERROR_FD_CONFIG_ORIENTATION_INVALID";
- case ERROR_FD_CONFIG_ORIENTATION_VALUE_INVALID:
- return "ERROR_FD_CONFIG_ORIENTATION_VALUE_INVALID";
- case ERROR_FD_RESULT:
- return "ERROR_FD_RESULT";
- case ERROR_FD_MODE:
- return "ERROR_FD_MODE";
- default:
- return "Unknown";
- }
-}
-
-const char *fimc_is_strerr(unsigned int error)
-{
- error &= ~IS_ERROR_TIME_OUT_FLAG;
-
- switch (error) {
- /* General */
- case IS_ERROR_INVALID_COMMAND:
- return "IS_ERROR_INVALID_COMMAND";
- case IS_ERROR_REQUEST_FAIL:
- return "IS_ERROR_REQUEST_FAIL";
- case IS_ERROR_INVALID_SCENARIO:
- return "IS_ERROR_INVALID_SCENARIO";
- case IS_ERROR_INVALID_SENSORID:
- return "IS_ERROR_INVALID_SENSORID";
- case IS_ERROR_INVALID_MODE_CHANGE:
- return "IS_ERROR_INVALID_MODE_CHANGE";
- case IS_ERROR_INVALID_MAGIC_NUMBER:
- return "IS_ERROR_INVALID_MAGIC_NUMBER";
- case IS_ERROR_INVALID_SETFILE_HDR:
- return "IS_ERROR_INVALID_SETFILE_HDR";
- case IS_ERROR_BUSY:
- return "IS_ERROR_BUSY";
- case IS_ERROR_SET_PARAMETER:
- return "IS_ERROR_SET_PARAMETER";
- case IS_ERROR_INVALID_PATH:
- return "IS_ERROR_INVALID_PATH";
- case IS_ERROR_OPEN_SENSOR_FAIL:
- return "IS_ERROR_OPEN_SENSOR_FAIL";
- case IS_ERROR_ENTRY_MSG_THREAD_DOWN:
- return "IS_ERROR_ENTRY_MSG_THREAD_DOWN";
- case IS_ERROR_ISP_FRAME_END_NOT_DONE:
- return "IS_ERROR_ISP_FRAME_END_NOT_DONE";
- case IS_ERROR_DRC_FRAME_END_NOT_DONE:
- return "IS_ERROR_DRC_FRAME_END_NOT_DONE";
- case IS_ERROR_SCALERC_FRAME_END_NOT_DONE:
- return "IS_ERROR_SCALERC_FRAME_END_NOT_DONE";
- case IS_ERROR_ODC_FRAME_END_NOT_DONE:
- return "IS_ERROR_ODC_FRAME_END_NOT_DONE";
- case IS_ERROR_DIS_FRAME_END_NOT_DONE:
- return "IS_ERROR_DIS_FRAME_END_NOT_DONE";
- case IS_ERROR_TDNR_FRAME_END_NOT_DONE:
- return "IS_ERROR_TDNR_FRAME_END_NOT_DONE";
- case IS_ERROR_SCALERP_FRAME_END_NOT_DONE:
- return "IS_ERROR_SCALERP_FRAME_END_NOT_DONE";
- case IS_ERROR_WAIT_STREAM_OFF_NOT_DONE:
- return "IS_ERROR_WAIT_STREAM_OFF_NOT_DONE";
- case IS_ERROR_NO_MSG_IS_RECEIVED:
- return "IS_ERROR_NO_MSG_IS_RECEIVED";
- case IS_ERROR_SENSOR_MSG_FAIL:
- return "IS_ERROR_SENSOR_MSG_FAIL";
- case IS_ERROR_ISP_MSG_FAIL:
- return "IS_ERROR_ISP_MSG_FAIL";
- case IS_ERROR_DRC_MSG_FAIL:
- return "IS_ERROR_DRC_MSG_FAIL";
- case IS_ERROR_LHFD_MSG_FAIL:
- return "IS_ERROR_LHFD_MSG_FAIL";
- case IS_ERROR_UNKNOWN:
- return "IS_ERROR_UNKNOWN";
-
- /* Sensor */
- case IS_ERROR_SENSOR_PWRDN_FAIL:
- return "IS_ERROR_SENSOR_PWRDN_FAIL";
-
- /* ISP */
- case IS_ERROR_ISP_PWRDN_FAIL:
- return "IS_ERROR_ISP_PWRDN_FAIL";
- case IS_ERROR_ISP_MULTIPLE_INPUT:
- return "IS_ERROR_ISP_MULTIPLE_INPUT";
- case IS_ERROR_ISP_ABSENT_INPUT:
- return "IS_ERROR_ISP_ABSENT_INPUT";
- case IS_ERROR_ISP_ABSENT_OUTPUT:
- return "IS_ERROR_ISP_ABSENT_OUTPUT";
- case IS_ERROR_ISP_NONADJACENT_OUTPUT:
- return "IS_ERROR_ISP_NONADJACENT_OUTPUT";
- case IS_ERROR_ISP_FORMAT_MISMATCH:
- return "IS_ERROR_ISP_FORMAT_MISMATCH";
- case IS_ERROR_ISP_WIDTH_MISMATCH:
- return "IS_ERROR_ISP_WIDTH_MISMATCH";
- case IS_ERROR_ISP_HEIGHT_MISMATCH:
- return "IS_ERROR_ISP_HEIGHT_MISMATCH";
- case IS_ERROR_ISP_BITWIDTH_MISMATCH:
- return "IS_ERROR_ISP_BITWIDTH_MISMATCH";
- case IS_ERROR_ISP_FRAME_END_TIME_OUT:
- return "IS_ERROR_ISP_FRAME_END_TIME_OUT";
-
- /* DRC */
- case IS_ERROR_DRC_PWRDN_FAIL:
- return "IS_ERROR_DRC_PWRDN_FAIL";
- case IS_ERROR_DRC_MULTIPLE_INPUT:
- return "IS_ERROR_DRC_MULTIPLE_INPUT";
- case IS_ERROR_DRC_ABSENT_INPUT:
- return "IS_ERROR_DRC_ABSENT_INPUT";
- case IS_ERROR_DRC_NONADJACENT_INPUT:
- return "IS_ERROR_DRC_NONADJACENT_INPUT";
- case IS_ERROR_DRC_ABSENT_OUTPUT:
- return "IS_ERROR_DRC_ABSENT_OUTPUT";
- case IS_ERROR_DRC_NONADJACENT_OUTPUT:
- return "IS_ERROR_DRC_NONADJACENT_OUTPUT";
- case IS_ERROR_DRC_FORMAT_MISMATCH:
- return "IS_ERROR_DRC_FORMAT_MISMATCH";
- case IS_ERROR_DRC_WIDTH_MISMATCH:
- return "IS_ERROR_DRC_WIDTH_MISMATCH";
- case IS_ERROR_DRC_HEIGHT_MISMATCH:
- return "IS_ERROR_DRC_HEIGHT_MISMATCH";
- case IS_ERROR_DRC_BITWIDTH_MISMATCH:
- return "IS_ERROR_DRC_BITWIDTH_MISMATCH";
- case IS_ERROR_DRC_FRAME_END_TIME_OUT:
- return "IS_ERROR_DRC_FRAME_END_TIME_OUT";
-
- /* FD */
- case IS_ERROR_FD_PWRDN_FAIL:
- return "IS_ERROR_FD_PWRDN_FAIL";
- case IS_ERROR_FD_MULTIPLE_INPUT:
- return "IS_ERROR_FD_MULTIPLE_INPUT";
- case IS_ERROR_FD_ABSENT_INPUT:
- return "IS_ERROR_FD_ABSENT_INPUT";
- case IS_ERROR_FD_NONADJACENT_INPUT:
- return "IS_ERROR_FD_NONADJACENT_INPUT";
- case IS_ERROR_LHFD_FRAME_END_TIME_OUT:
- return "IS_ERROR_LHFD_FRAME_END_TIME_OUT";
- default:
- return "Unknown";
- }
-}
diff --git a/drivers/media/platform/exynos4-is/fimc-is-errno.h b/drivers/media/platform/exynos4-is/fimc-is-errno.h
deleted file mode 100644
index da36b48b8f9f..000000000000
--- a/drivers/media/platform/exynos4-is/fimc-is-errno.h
+++ /dev/null
@@ -1,245 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-only */
-/*
- * Samsung Exynos4 SoC series FIMC-IS slave interface driver
- *
- * FIMC-IS error code definition
- *
- * Copyright (C) 2011 - 2013 Samsung Electronics Co., Ltd.
- *
- * Authors: Younghwan Joo <yhwan.joo@samsung.com>
- * Sylwester Nawrocki <s.nawrocki@samsung.com>
-*/
-
-#ifndef FIMC_IS_ERR_H_
-#define FIMC_IS_ERR_H_
-
-#define IS_ERROR_VER 011 /* IS ERROR VERSION 0.11 */
-
-enum {
- IS_ERROR_NONE,
-
- /* General 1 ~ 99 */
- IS_ERROR_INVALID_COMMAND,
- IS_ERROR_REQUEST_FAIL,
- IS_ERROR_INVALID_SCENARIO,
- IS_ERROR_INVALID_SENSORID,
- IS_ERROR_INVALID_MODE_CHANGE,
- IS_ERROR_INVALID_MAGIC_NUMBER,
- IS_ERROR_INVALID_SETFILE_HDR,
- IS_ERROR_BUSY,
- IS_ERROR_SET_PARAMETER,
- IS_ERROR_INVALID_PATH,
- IS_ERROR_OPEN_SENSOR_FAIL,
- IS_ERROR_ENTRY_MSG_THREAD_DOWN,
- IS_ERROR_ISP_FRAME_END_NOT_DONE,
- IS_ERROR_DRC_FRAME_END_NOT_DONE,
- IS_ERROR_SCALERC_FRAME_END_NOT_DONE,
- IS_ERROR_ODC_FRAME_END_NOT_DONE,
- IS_ERROR_DIS_FRAME_END_NOT_DONE,
- IS_ERROR_TDNR_FRAME_END_NOT_DONE,
- IS_ERROR_SCALERP_FRAME_END_NOT_DONE,
- IS_ERROR_WAIT_STREAM_OFF_NOT_DONE,
- IS_ERROR_NO_MSG_IS_RECEIVED,
- IS_ERROR_SENSOR_MSG_FAIL,
- IS_ERROR_ISP_MSG_FAIL,
- IS_ERROR_DRC_MSG_FAIL,
- IS_ERROR_SCALERC_MSG_FAIL,
- IS_ERROR_ODC_MSG_FAIL,
- IS_ERROR_DIS_MSG_FAIL,
- IS_ERROR_TDNR_MSG_FAIL,
- IS_ERROR_SCALERP_MSG_FAIL,
- IS_ERROR_LHFD_MSG_FAIL,
- IS_ERROR_LHFD_INTERNAL_STOP,
-
- /* Sensor 100 ~ 199 */
- IS_ERROR_SENSOR_PWRDN_FAIL = 100,
- IS_ERROR_SENSOR_STREAM_ON_FAIL,
- IS_ERROR_SENSOR_STREAM_OFF_FAIL,
-
- /* ISP 200 ~ 299 */
- IS_ERROR_ISP_PWRDN_FAIL = 200,
- IS_ERROR_ISP_MULTIPLE_INPUT,
- IS_ERROR_ISP_ABSENT_INPUT,
- IS_ERROR_ISP_ABSENT_OUTPUT,
- IS_ERROR_ISP_NONADJACENT_OUTPUT,
- IS_ERROR_ISP_FORMAT_MISMATCH,
- IS_ERROR_ISP_WIDTH_MISMATCH,
- IS_ERROR_ISP_HEIGHT_MISMATCH,
- IS_ERROR_ISP_BITWIDTH_MISMATCH,
- IS_ERROR_ISP_FRAME_END_TIME_OUT,
-
- /* DRC 300 ~ 399 */
- IS_ERROR_DRC_PWRDN_FAIL = 300,
- IS_ERROR_DRC_MULTIPLE_INPUT,
- IS_ERROR_DRC_ABSENT_INPUT,
- IS_ERROR_DRC_NONADJACENT_INPUT,
- IS_ERROR_DRC_ABSENT_OUTPUT,
- IS_ERROR_DRC_NONADJACENT_OUTPUT,
- IS_ERROR_DRC_FORMAT_MISMATCH,
- IS_ERROR_DRC_WIDTH_MISMATCH,
- IS_ERROR_DRC_HEIGHT_MISMATCH,
- IS_ERROR_DRC_BITWIDTH_MISMATCH,
- IS_ERROR_DRC_FRAME_END_TIME_OUT,
-
- /* SCALERC 400 ~ 499 */
- IS_ERROR_SCALERC_PWRDN_FAIL = 400,
-
- /* ODC 500 ~ 599 */
- IS_ERROR_ODC_PWRDN_FAIL = 500,
-
- /* DIS 600 ~ 699 */
- IS_ERROR_DIS_PWRDN_FAIL = 600,
-
- /* TDNR 700 ~ 799 */
- IS_ERROR_TDNR_PWRDN_FAIL = 700,
-
- /* SCALERC 800 ~ 899 */
- IS_ERROR_SCALERP_PWRDN_FAIL = 800,
-
- /* FD 900 ~ 999 */
- IS_ERROR_FD_PWRDN_FAIL = 900,
- IS_ERROR_FD_MULTIPLE_INPUT,
- IS_ERROR_FD_ABSENT_INPUT,
- IS_ERROR_FD_NONADJACENT_INPUT,
- IS_ERROR_LHFD_FRAME_END_TIME_OUT,
-
- IS_ERROR_UNKNOWN = 1000,
-};
-
-#define IS_ERROR_TIME_OUT_FLAG 0x80000000
-
-/* Set parameter error enum */
-enum fimc_is_error {
- /* Common error (0~99) */
- ERROR_COMMON_NONE = 0,
- ERROR_COMMON_CMD = 1, /* Invalid command */
- ERROR_COMMON_PARAMETER = 2, /* Invalid parameter */
- /* setfile is not loaded before adjusting */
- ERROR_COMMON_SETFILE_LOAD = 3,
- /* setfile is not Adjusted before runnng. */
- ERROR_COMMON_SETFILE_ADJUST = 4,
- /* Index of setfile is not valid (0~MAX_SETFILE_NUM-1) */
- ERROR_COMMON_SETFILE_INDEX = 5,
- /* Input path can be changed in ready state(stop) */
- ERROR_COMMON_INPUT_PATH = 6,
- /* IP can not start if input path is not set */
- ERROR_COMMON_INPUT_INIT = 7,
- /* Output path can be changed in ready state (stop) */
- ERROR_COMMON_OUTPUT_PATH = 8,
- /* IP can not start if output path is not set */
- ERROR_COMMON_OUTPUT_INIT = 9,
-
- ERROR_CONTROL_NONE = ERROR_COMMON_NONE,
- ERROR_CONTROL_BYPASS = 11, /* Enable or Disable */
-
- ERROR_OTF_INPUT_NONE = ERROR_COMMON_NONE,
- ERROR_OTF_INPUT_CMD = 21,
- /* invalid format (DRC: YUV444, FD: YUV444, 422, 420) */
- ERROR_OTF_INPUT_FORMAT = 22,
- /* invalid width (DRC: 128~8192, FD: 32~8190) */
- ERROR_OTF_INPUT_WIDTH = 23,
- /* invalid height (DRC: 64~8192, FD: 16~8190) */
- ERROR_OTF_INPUT_HEIGHT = 24,
- /* invalid bit-width (DRC: 8~12bits, FD: 8bit) */
- ERROR_OTF_INPUT_BIT_WIDTH = 25,
- /* invalid FrameTime for ISP */
- ERROR_OTF_INPUT_USER_FRAMETIIME = 26,
-
- ERROR_DMA_INPUT_NONE = ERROR_COMMON_NONE,
- /* invalid width (DRC: 128~8192, FD: 32~8190) */
- ERROR_DMA_INPUT_WIDTH = 31,
- /* invalid height (DRC: 64~8192, FD: 16~8190) */
- ERROR_DMA_INPUT_HEIGHT = 32,
- /* invalid format (DRC: YUV444 or YUV422, FD: YUV444, 422, 420) */
- ERROR_DMA_INPUT_FORMAT = 33,
- /* invalid bit-width (DRC: 8~12bit, FD: 8bit) */
- ERROR_DMA_INPUT_BIT_WIDTH = 34,
- /* invalid order(DRC: YYCbCrorYCbYCr, FD:NO,YYCbCr,YCbYCr,CbCr,CrCb) */
- ERROR_DMA_INPUT_ORDER = 35,
- /* invalid palne (DRC: 3, FD: 1, 2, 3) */
- ERROR_DMA_INPUT_PLANE = 36,
-
- ERROR_OTF_OUTPUT_NONE = ERROR_COMMON_NONE,
- /* invalid width (DRC: 128~8192) */
- ERROR_OTF_OUTPUT_WIDTH = 41,
- /* invalid height (DRC: 64~8192) */
- ERROR_OTF_OUTPUT_HEIGHT = 42,
- /* invalid format (DRC: YUV444) */
- ERROR_OTF_OUTPUT_FORMAT = 43,
- /* invalid bit-width (DRC: 8~12bits) */
- ERROR_OTF_OUTPUT_BIT_WIDTH = 44,
-
- ERROR_DMA_OUTPUT_NONE = ERROR_COMMON_NONE,
- ERROR_DMA_OUTPUT_WIDTH = 51, /* invalid width */
- ERROR_DMA_OUTPUT_HEIGHT = 52, /* invalid height */
- ERROR_DMA_OUTPUT_FORMAT = 53, /* invalid format */
- ERROR_DMA_OUTPUT_BIT_WIDTH = 54, /* invalid bit-width */
- ERROR_DMA_OUTPUT_PLANE = 55, /* invalid plane */
- ERROR_DMA_OUTPUT_ORDER = 56, /* invalid order */
-
- ERROR_GLOBAL_SHOTMODE_NONE = ERROR_COMMON_NONE,
-
- /* SENSOR Error(100~199) */
- ERROR_SENSOR_NONE = ERROR_COMMON_NONE,
- ERROR_SENSOR_I2C_FAIL = 101,
- ERROR_SENSOR_INVALID_FRAMERATE,
- ERROR_SENSOR_INVALID_EXPOSURETIME,
- ERROR_SENSOR_INVALID_SIZE,
- ERROR_SENSOR_INVALID_SETTING,
- ERROR_SENSOR_ACTUATOR_INIT_FAIL,
- ERROR_SENSOR_INVALID_AF_POS,
- ERROR_SENSOR_UNSUPPORT_FUNC,
- ERROR_SENSOR_UNSUPPORT_PERI,
- ERROR_SENSOR_UNSUPPORT_AF,
-
- /* ISP Error (200~299) */
- ERROR_ISP_AF_NONE = ERROR_COMMON_NONE,
- ERROR_ISP_AF_BUSY = 201,
- ERROR_ISP_AF_INVALID_COMMAND = 202,
- ERROR_ISP_AF_INVALID_MODE = 203,
- ERROR_ISP_FLASH_NONE = ERROR_COMMON_NONE,
- ERROR_ISP_AWB_NONE = ERROR_COMMON_NONE,
- ERROR_ISP_IMAGE_EFFECT_NONE = ERROR_COMMON_NONE,
- ERROR_ISP_ISO_NONE = ERROR_COMMON_NONE,
- ERROR_ISP_ADJUST_NONE = ERROR_COMMON_NONE,
- ERROR_ISP_METERING_NONE = ERROR_COMMON_NONE,
- ERROR_ISP_AFC_NONE = ERROR_COMMON_NONE,
-
- /* DRC Error (300~399) */
-
- /* FD Error (400~499) */
- ERROR_FD_NONE = ERROR_COMMON_NONE,
- /* Invalid max number (1~16) */
- ERROR_FD_CONFIG_MAX_NUMBER_STATE = 401,
- ERROR_FD_CONFIG_MAX_NUMBER_INVALID = 402,
- ERROR_FD_CONFIG_YAW_ANGLE_STATE = 403,
- ERROR_FD_CONFIG_YAW_ANGLE_INVALID = 404,
- ERROR_FD_CONFIG_ROLL_ANGLE_STATE = 405,
- ERROR_FD_CONFIG_ROLL_ANGLE_INVALID = 406,
- ERROR_FD_CONFIG_SMILE_MODE_INVALID = 407,
- ERROR_FD_CONFIG_BLINK_MODE_INVALID = 408,
- ERROR_FD_CONFIG_EYES_DETECT_INVALID = 409,
- ERROR_FD_CONFIG_MOUTH_DETECT_INVALID = 410,
- ERROR_FD_CONFIG_ORIENTATION_STATE = 411,
- ERROR_FD_CONFIG_ORIENTATION_INVALID = 412,
- ERROR_FD_CONFIG_ORIENTATION_VALUE_INVALID = 413,
- /* PARAM_FdResultStr can be only applied in ready-state or stream off */
- ERROR_FD_RESULT = 414,
- /* PARAM_FdModeStr can be only applied in ready-state or stream off */
- ERROR_FD_MODE = 415,
- /* Scaler Error (500 ~ 599) */
- ERROR_SCALER_NO_NONE = ERROR_COMMON_NONE,
- ERROR_SCALER_DMA_OUTSEL = 501,
- ERROR_SCALER_H_RATIO = 502,
- ERROR_SCALER_V_RATIO = 503,
-
- ERROR_SCALER_IMAGE_EFFECT = 510,
-
- ERROR_SCALER_ROTATE = 520,
- ERROR_SCALER_FLIP = 521,
-};
-
-const char *fimc_is_strerr(unsigned int error);
-const char *fimc_is_param_strerr(unsigned int error);
-
-#endif /* FIMC_IS_ERR_H_ */
diff --git a/drivers/media/platform/exynos4-is/fimc-is-i2c.c b/drivers/media/platform/exynos4-is/fimc-is-i2c.c
deleted file mode 100644
index 83a28ef8e099..000000000000
--- a/drivers/media/platform/exynos4-is/fimc-is-i2c.c
+++ /dev/null
@@ -1,159 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-/*
- * Samsung EXYNOS4x12 FIMC-IS (Imaging Subsystem) driver
- *
- * Copyright (C) 2013 Samsung Electronics Co., Ltd.
- *
- * Author: Sylwester Nawrocki <s.nawrocki@samsung.com>
- */
-
-#include <linux/clk.h>
-#include <linux/module.h>
-#include <linux/i2c.h>
-#include <linux/platform_device.h>
-#include <linux/pm_runtime.h>
-#include <linux/slab.h>
-#include "fimc-is-i2c.h"
-
-struct fimc_is_i2c {
- struct i2c_adapter adapter;
- struct clk *clock;
-};
-
-/*
- * An empty algorithm is used as the actual I2C bus controller driver
- * is implemented in the FIMC-IS subsystem firmware and the host CPU
- * doesn't access the I2C bus controller.
- */
-static u32 is_i2c_func(struct i2c_adapter *adap)
-{
- return I2C_FUNC_I2C;
-}
-
-static const struct i2c_algorithm fimc_is_i2c_algorithm = {
- .functionality = is_i2c_func,
-};
-
-static int fimc_is_i2c_probe(struct platform_device *pdev)
-{
- struct device_node *node = pdev->dev.of_node;
- struct fimc_is_i2c *isp_i2c;
- struct i2c_adapter *i2c_adap;
- int ret;
-
- isp_i2c = devm_kzalloc(&pdev->dev, sizeof(*isp_i2c), GFP_KERNEL);
- if (!isp_i2c)
- return -ENOMEM;
-
- isp_i2c->clock = devm_clk_get(&pdev->dev, "i2c_isp");
- if (IS_ERR(isp_i2c->clock)) {
- dev_err(&pdev->dev, "failed to get the clock\n");
- return PTR_ERR(isp_i2c->clock);
- }
-
- i2c_adap = &isp_i2c->adapter;
- i2c_adap->dev.of_node = node;
- i2c_adap->dev.parent = &pdev->dev;
- strscpy(i2c_adap->name, "exynos4x12-isp-i2c", sizeof(i2c_adap->name));
- i2c_adap->owner = THIS_MODULE;
- i2c_adap->algo = &fimc_is_i2c_algorithm;
- i2c_adap->class = I2C_CLASS_SPD;
-
- platform_set_drvdata(pdev, isp_i2c);
- pm_runtime_enable(&pdev->dev);
-
- ret = i2c_add_adapter(i2c_adap);
- if (ret < 0)
- goto err_pm_dis;
- /*
- * Client drivers of this adapter don't do any I2C transfers as that
- * is handled by the ISP firmware. But we rely on the runtime PM
- * state propagation from the clients up to the adapter driver so
- * clear the ignore_children flags here. PM rutnime calls are not
- * used in probe() handler of clients of this adapter so there is
- * no issues with clearing the flag right after registering the I2C
- * adapter.
- */
- pm_suspend_ignore_children(&i2c_adap->dev, false);
- return 0;
-
-err_pm_dis:
- pm_runtime_disable(&pdev->dev);
- return ret;
-}
-
-static int fimc_is_i2c_remove(struct platform_device *pdev)
-{
- struct fimc_is_i2c *isp_i2c = platform_get_drvdata(pdev);
-
- pm_runtime_disable(&pdev->dev);
- i2c_del_adapter(&isp_i2c->adapter);
-
- return 0;
-}
-
-#ifdef CONFIG_PM
-static int fimc_is_i2c_runtime_suspend(struct device *dev)
-{
- struct fimc_is_i2c *isp_i2c = dev_get_drvdata(dev);
-
- clk_disable_unprepare(isp_i2c->clock);
- return 0;
-}
-
-static int fimc_is_i2c_runtime_resume(struct device *dev)
-{
- struct fimc_is_i2c *isp_i2c = dev_get_drvdata(dev);
-
- return clk_prepare_enable(isp_i2c->clock);
-}
-#endif
-
-#ifdef CONFIG_PM_SLEEP
-static int fimc_is_i2c_suspend(struct device *dev)
-{
- if (pm_runtime_suspended(dev))
- return 0;
-
- return fimc_is_i2c_runtime_suspend(dev);
-}
-
-static int fimc_is_i2c_resume(struct device *dev)
-{
- if (pm_runtime_suspended(dev))
- return 0;
-
- return fimc_is_i2c_runtime_resume(dev);
-}
-#endif
-
-static const struct dev_pm_ops fimc_is_i2c_pm_ops = {
- SET_RUNTIME_PM_OPS(fimc_is_i2c_runtime_suspend,
- fimc_is_i2c_runtime_resume, NULL)
- SET_SYSTEM_SLEEP_PM_OPS(fimc_is_i2c_suspend, fimc_is_i2c_resume)
-};
-
-static const struct of_device_id fimc_is_i2c_of_match[] = {
- { .compatible = FIMC_IS_I2C_COMPATIBLE },
- { },
-};
-
-static struct platform_driver fimc_is_i2c_driver = {
- .probe = fimc_is_i2c_probe,
- .remove = fimc_is_i2c_remove,
- .driver = {
- .of_match_table = fimc_is_i2c_of_match,
- .name = "fimc-isp-i2c",
- .pm = &fimc_is_i2c_pm_ops,
- }
-};
-
-int fimc_is_register_i2c_driver(void)
-{
- return platform_driver_register(&fimc_is_i2c_driver);
-}
-
-void fimc_is_unregister_i2c_driver(void)
-{
- platform_driver_unregister(&fimc_is_i2c_driver);
-}
diff --git a/drivers/media/platform/exynos4-is/fimc-is-i2c.h b/drivers/media/platform/exynos4-is/fimc-is-i2c.h
deleted file mode 100644
index a23bd20be6c8..000000000000
--- a/drivers/media/platform/exynos4-is/fimc-is-i2c.h
+++ /dev/null
@@ -1,12 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-only */
-/*
- * Samsung EXYNOS4x12 FIMC-IS (Imaging Subsystem) driver
- *
- * Copyright (C) 2013 Samsung Electronics Co., Ltd.
- * Sylwester Nawrocki <s.nawrocki@samsung.com>
- */
-
-#define FIMC_IS_I2C_COMPATIBLE "samsung,exynos4212-i2c-isp"
-
-int fimc_is_register_i2c_driver(void);
-void fimc_is_unregister_i2c_driver(void);
diff --git a/drivers/media/platform/exynos4-is/fimc-is-param.c b/drivers/media/platform/exynos4-is/fimc-is-param.c
deleted file mode 100644
index 9c816ae3b3e5..000000000000
--- a/drivers/media/platform/exynos4-is/fimc-is-param.c
+++ /dev/null
@@ -1,893 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-/*
- * Samsung EXYNOS4x12 FIMC-IS (Imaging Subsystem) driver
- *
- * Copyright (C) 2013 Samsung Electronics Co., Ltd.
- *
- * Authors: Younghwan Joo <yhwan.joo@samsung.com>
- * Sylwester Nawrocki <s.nawrocki@samsung.com>
- */
-#define pr_fmt(fmt) "%s:%d " fmt, __func__, __LINE__
-
-#include <linux/bitops.h>
-#include <linux/bug.h>
-#include <linux/device.h>
-#include <linux/errno.h>
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/platform_device.h>
-#include <linux/slab.h>
-#include <linux/types.h>
-#include <linux/videodev2.h>
-
-#include <media/v4l2-device.h>
-#include <media/v4l2-ioctl.h>
-
-#include "fimc-is.h"
-#include "fimc-is-command.h"
-#include "fimc-is-errno.h"
-#include "fimc-is-param.h"
-#include "fimc-is-regs.h"
-#include "fimc-is-sensor.h"
-
-static void __hw_param_copy(void *dst, void *src)
-{
- memcpy(dst, src, FIMC_IS_PARAM_MAX_SIZE);
-}
-
-static void __fimc_is_hw_update_param_global_shotmode(struct fimc_is *is)
-{
- struct param_global_shotmode *dst, *src;
-
- dst = &is->is_p_region->parameter.global.shotmode;
- src = &is->config[is->config_index].global.shotmode;
- __hw_param_copy(dst, src);
-}
-
-static void __fimc_is_hw_update_param_sensor_framerate(struct fimc_is *is)
-{
- struct param_sensor_framerate *dst, *src;
-
- dst = &is->is_p_region->parameter.sensor.frame_rate;
- src = &is->config[is->config_index].sensor.frame_rate;
- __hw_param_copy(dst, src);
-}
-
-int __fimc_is_hw_update_param(struct fimc_is *is, u32 offset)
-{
- struct is_param_region *par = &is->is_p_region->parameter;
- struct chain_config *cfg = &is->config[is->config_index];
-
- switch (offset) {
- case PARAM_ISP_CONTROL:
- __hw_param_copy(&par->isp.control, &cfg->isp.control);
- break;
-
- case PARAM_ISP_OTF_INPUT:
- __hw_param_copy(&par->isp.otf_input, &cfg->isp.otf_input);
- break;
-
- case PARAM_ISP_DMA1_INPUT:
- __hw_param_copy(&par->isp.dma1_input, &cfg->isp.dma1_input);
- break;
-
- case PARAM_ISP_DMA2_INPUT:
- __hw_param_copy(&par->isp.dma2_input, &cfg->isp.dma2_input);
- break;
-
- case PARAM_ISP_AA:
- __hw_param_copy(&par->isp.aa, &cfg->isp.aa);
- break;
-
- case PARAM_ISP_FLASH:
- __hw_param_copy(&par->isp.flash, &cfg->isp.flash);
- break;
-
- case PARAM_ISP_AWB:
- __hw_param_copy(&par->isp.awb, &cfg->isp.awb);
- break;
-
- case PARAM_ISP_IMAGE_EFFECT:
- __hw_param_copy(&par->isp.effect, &cfg->isp.effect);
- break;
-
- case PARAM_ISP_ISO:
- __hw_param_copy(&par->isp.iso, &cfg->isp.iso);
- break;
-
- case PARAM_ISP_ADJUST:
- __hw_param_copy(&par->isp.adjust, &cfg->isp.adjust);
- break;
-
- case PARAM_ISP_METERING:
- __hw_param_copy(&par->isp.metering, &cfg->isp.metering);
- break;
-
- case PARAM_ISP_AFC:
- __hw_param_copy(&par->isp.afc, &cfg->isp.afc);
- break;
-
- case PARAM_ISP_OTF_OUTPUT:
- __hw_param_copy(&par->isp.otf_output, &cfg->isp.otf_output);
- break;
-
- case PARAM_ISP_DMA1_OUTPUT:
- __hw_param_copy(&par->isp.dma1_output, &cfg->isp.dma1_output);
- break;
-
- case PARAM_ISP_DMA2_OUTPUT:
- __hw_param_copy(&par->isp.dma2_output, &cfg->isp.dma2_output);
- break;
-
- case PARAM_DRC_CONTROL:
- __hw_param_copy(&par->drc.control, &cfg->drc.control);
- break;
-
- case PARAM_DRC_OTF_INPUT:
- __hw_param_copy(&par->drc.otf_input, &cfg->drc.otf_input);
- break;
-
- case PARAM_DRC_DMA_INPUT:
- __hw_param_copy(&par->drc.dma_input, &cfg->drc.dma_input);
- break;
-
- case PARAM_DRC_OTF_OUTPUT:
- __hw_param_copy(&par->drc.otf_output, &cfg->drc.otf_output);
- break;
-
- case PARAM_FD_CONTROL:
- __hw_param_copy(&par->fd.control, &cfg->fd.control);
- break;
-
- case PARAM_FD_OTF_INPUT:
- __hw_param_copy(&par->fd.otf_input, &cfg->fd.otf_input);
- break;
-
- case PARAM_FD_DMA_INPUT:
- __hw_param_copy(&par->fd.dma_input, &cfg->fd.dma_input);
- break;
-
- case PARAM_FD_CONFIG:
- __hw_param_copy(&par->fd.config, &cfg->fd.config);
- break;
-
- default:
- return -EINVAL;
- }
-
- return 0;
-}
-
-unsigned int __get_pending_param_count(struct fimc_is *is)
-{
- struct chain_config *config = &is->config[is->config_index];
- unsigned long flags;
- unsigned int count;
-
- spin_lock_irqsave(&is->slock, flags);
- count = hweight32(config->p_region_index[0]);
- count += hweight32(config->p_region_index[1]);
- spin_unlock_irqrestore(&is->slock, flags);
-
- return count;
-}
-
-int __is_hw_update_params(struct fimc_is *is)
-{
- unsigned long *p_index;
- int i, id, ret = 0;
-
- id = is->config_index;
- p_index = &is->config[id].p_region_index[0];
-
- if (test_bit(PARAM_GLOBAL_SHOTMODE, p_index))
- __fimc_is_hw_update_param_global_shotmode(is);
-
- if (test_bit(PARAM_SENSOR_FRAME_RATE, p_index))
- __fimc_is_hw_update_param_sensor_framerate(is);
-
- for (i = PARAM_ISP_CONTROL; i < PARAM_DRC_CONTROL; i++) {
- if (test_bit(i, p_index))
- ret = __fimc_is_hw_update_param(is, i);
- }
-
- for (i = PARAM_DRC_CONTROL; i < PARAM_SCALERC_CONTROL; i++) {
- if (test_bit(i, p_index))
- ret = __fimc_is_hw_update_param(is, i);
- }
-
- for (i = PARAM_FD_CONTROL; i <= PARAM_FD_CONFIG; i++) {
- if (test_bit(i, p_index))
- ret = __fimc_is_hw_update_param(is, i);
- }
-
- return ret;
-}
-
-void __is_get_frame_size(struct fimc_is *is, struct v4l2_mbus_framefmt *mf)
-{
- struct isp_param *isp;
-
- isp = &is->config[is->config_index].isp;
- mf->width = isp->otf_input.width;
- mf->height = isp->otf_input.height;
-}
-
-void __is_set_frame_size(struct fimc_is *is, struct v4l2_mbus_framefmt *mf)
-{
- unsigned int index = is->config_index;
- struct isp_param *isp;
- struct drc_param *drc;
- struct fd_param *fd;
-
- isp = &is->config[index].isp;
- drc = &is->config[index].drc;
- fd = &is->config[index].fd;
-
- /* Update isp size info (OTF only) */
- isp->otf_input.width = mf->width;
- isp->otf_input.height = mf->height;
- isp->otf_output.width = mf->width;
- isp->otf_output.height = mf->height;
- /* Update drc size info (OTF only) */
- drc->otf_input.width = mf->width;
- drc->otf_input.height = mf->height;
- drc->otf_output.width = mf->width;
- drc->otf_output.height = mf->height;
- /* Update fd size info (OTF only) */
- fd->otf_input.width = mf->width;
- fd->otf_input.height = mf->height;
-
- if (test_bit(PARAM_ISP_OTF_INPUT,
- &is->config[index].p_region_index[0]))
- return;
-
- /* Update field */
- fimc_is_set_param_bit(is, PARAM_ISP_OTF_INPUT);
- fimc_is_set_param_bit(is, PARAM_ISP_OTF_OUTPUT);
- fimc_is_set_param_bit(is, PARAM_DRC_OTF_INPUT);
- fimc_is_set_param_bit(is, PARAM_DRC_OTF_OUTPUT);
- fimc_is_set_param_bit(is, PARAM_FD_OTF_INPUT);
-}
-
-int fimc_is_hw_get_sensor_max_framerate(struct fimc_is *is)
-{
- switch (is->sensor->drvdata->id) {
- case FIMC_IS_SENSOR_ID_S5K6A3:
- return 30;
- default:
- return 15;
- }
-}
-
-void __is_set_sensor(struct fimc_is *is, int fps)
-{
- unsigned int index = is->config_index;
- struct sensor_param *sensor;
- struct isp_param *isp;
-
- sensor = &is->config[index].sensor;
- isp = &is->config[index].isp;
-
- if (fps == 0) {
- sensor->frame_rate.frame_rate =
- fimc_is_hw_get_sensor_max_framerate(is);
- isp->otf_input.frametime_min = 0;
- isp->otf_input.frametime_max = 66666;
- } else {
- sensor->frame_rate.frame_rate = fps;
- isp->otf_input.frametime_min = 0;
- isp->otf_input.frametime_max = (u32)1000000 / fps;
- }
-
- fimc_is_set_param_bit(is, PARAM_SENSOR_FRAME_RATE);
- fimc_is_set_param_bit(is, PARAM_ISP_OTF_INPUT);
-}
-
-static void __maybe_unused __is_set_init_isp_aa(struct fimc_is *is)
-{
- struct isp_param *isp;
-
- isp = &is->config[is->config_index].isp;
-
- isp->aa.cmd = ISP_AA_COMMAND_START;
- isp->aa.target = ISP_AA_TARGET_AF | ISP_AA_TARGET_AE |
- ISP_AA_TARGET_AWB;
- isp->aa.mode = 0;
- isp->aa.scene = 0;
- isp->aa.sleep = 0;
- isp->aa.face = 0;
- isp->aa.touch_x = 0;
- isp->aa.touch_y = 0;
- isp->aa.manual_af_setting = 0;
- isp->aa.err = ISP_AF_ERROR_NONE;
-
- fimc_is_set_param_bit(is, PARAM_ISP_AA);
-}
-
-void __is_set_isp_flash(struct fimc_is *is, u32 cmd, u32 redeye)
-{
- unsigned int index = is->config_index;
- struct isp_param *isp = &is->config[index].isp;
-
- isp->flash.cmd = cmd;
- isp->flash.redeye = redeye;
- isp->flash.err = ISP_FLASH_ERROR_NONE;
-
- fimc_is_set_param_bit(is, PARAM_ISP_FLASH);
-}
-
-void __is_set_isp_awb(struct fimc_is *is, u32 cmd, u32 val)
-{
- unsigned int index = is->config_index;
- struct isp_param *isp;
-
- isp = &is->config[index].isp;
-
- isp->awb.cmd = cmd;
- isp->awb.illumination = val;
- isp->awb.err = ISP_AWB_ERROR_NONE;
-
- fimc_is_set_param_bit(is, PARAM_ISP_AWB);
-}
-
-void __is_set_isp_effect(struct fimc_is *is, u32 cmd)
-{
- unsigned int index = is->config_index;
- struct isp_param *isp;
-
- isp = &is->config[index].isp;
-
- isp->effect.cmd = cmd;
- isp->effect.err = ISP_IMAGE_EFFECT_ERROR_NONE;
-
- fimc_is_set_param_bit(is, PARAM_ISP_IMAGE_EFFECT);
-}
-
-void __is_set_isp_iso(struct fimc_is *is, u32 cmd, u32 val)
-{
- unsigned int index = is->config_index;
- struct isp_param *isp;
-
- isp = &is->config[index].isp;
-
- isp->iso.cmd = cmd;
- isp->iso.value = val;
- isp->iso.err = ISP_ISO_ERROR_NONE;
-
- fimc_is_set_param_bit(is, PARAM_ISP_ISO);
-}
-
-void __is_set_isp_adjust(struct fimc_is *is, u32 cmd, u32 val)
-{
- unsigned int index = is->config_index;
- unsigned long *p_index;
- struct isp_param *isp;
-
- p_index = &is->config[index].p_region_index[0];
- isp = &is->config[index].isp;
-
- switch (cmd) {
- case ISP_ADJUST_COMMAND_MANUAL_CONTRAST:
- isp->adjust.contrast = val;
- break;
- case ISP_ADJUST_COMMAND_MANUAL_SATURATION:
- isp->adjust.saturation = val;
- break;
- case ISP_ADJUST_COMMAND_MANUAL_SHARPNESS:
- isp->adjust.sharpness = val;
- break;
- case ISP_ADJUST_COMMAND_MANUAL_EXPOSURE:
- isp->adjust.exposure = val;
- break;
- case ISP_ADJUST_COMMAND_MANUAL_BRIGHTNESS:
- isp->adjust.brightness = val;
- break;
- case ISP_ADJUST_COMMAND_MANUAL_HUE:
- isp->adjust.hue = val;
- break;
- case ISP_ADJUST_COMMAND_AUTO:
- isp->adjust.contrast = 0;
- isp->adjust.saturation = 0;
- isp->adjust.sharpness = 0;
- isp->adjust.exposure = 0;
- isp->adjust.brightness = 0;
- isp->adjust.hue = 0;
- break;
- }
-
- if (!test_bit(PARAM_ISP_ADJUST, p_index)) {
- isp->adjust.cmd = cmd;
- isp->adjust.err = ISP_ADJUST_ERROR_NONE;
- fimc_is_set_param_bit(is, PARAM_ISP_ADJUST);
- } else {
- isp->adjust.cmd |= cmd;
- }
-}
-
-void __is_set_isp_metering(struct fimc_is *is, u32 id, u32 val)
-{
- unsigned int index = is->config_index;
- struct isp_param *isp;
- unsigned long *p_index;
-
- p_index = &is->config[index].p_region_index[0];
- isp = &is->config[index].isp;
-
- switch (id) {
- case IS_METERING_CONFIG_CMD:
- isp->metering.cmd = val;
- break;
- case IS_METERING_CONFIG_WIN_POS_X:
- isp->metering.win_pos_x = val;
- break;
- case IS_METERING_CONFIG_WIN_POS_Y:
- isp->metering.win_pos_y = val;
- break;
- case IS_METERING_CONFIG_WIN_WIDTH:
- isp->metering.win_width = val;
- break;
- case IS_METERING_CONFIG_WIN_HEIGHT:
- isp->metering.win_height = val;
- break;
- default:
- return;
- }
-
- if (!test_bit(PARAM_ISP_METERING, p_index)) {
- isp->metering.err = ISP_METERING_ERROR_NONE;
- fimc_is_set_param_bit(is, PARAM_ISP_METERING);
- }
-}
-
-void __is_set_isp_afc(struct fimc_is *is, u32 cmd, u32 val)
-{
- unsigned int index = is->config_index;
- struct isp_param *isp;
-
- isp = &is->config[index].isp;
-
- isp->afc.cmd = cmd;
- isp->afc.manual = val;
- isp->afc.err = ISP_AFC_ERROR_NONE;
-
- fimc_is_set_param_bit(is, PARAM_ISP_AFC);
-}
-
-void __is_set_drc_control(struct fimc_is *is, u32 val)
-{
- unsigned int index = is->config_index;
- struct drc_param *drc;
-
- drc = &is->config[index].drc;
-
- drc->control.bypass = val;
-
- fimc_is_set_param_bit(is, PARAM_DRC_CONTROL);
-}
-
-void __is_set_fd_control(struct fimc_is *is, u32 val)
-{
- unsigned int index = is->config_index;
- struct fd_param *fd;
- unsigned long *p_index;
-
- p_index = &is->config[index].p_region_index[1];
- fd = &is->config[index].fd;
-
- fd->control.cmd = val;
-
- if (!test_bit((PARAM_FD_CONFIG - 32), p_index))
- fimc_is_set_param_bit(is, PARAM_FD_CONTROL);
-}
-
-void __is_set_fd_config_maxface(struct fimc_is *is, u32 val)
-{
- unsigned int index = is->config_index;
- struct fd_param *fd;
- unsigned long *p_index;
-
- p_index = &is->config[index].p_region_index[1];
- fd = &is->config[index].fd;
-
- fd->config.max_number = val;
-
- if (!test_bit((PARAM_FD_CONFIG - 32), p_index)) {
- fd->config.cmd = FD_CONFIG_COMMAND_MAXIMUM_NUMBER;
- fd->config.err = ERROR_FD_NONE;
- fimc_is_set_param_bit(is, PARAM_FD_CONFIG);
- } else {
- fd->config.cmd |= FD_CONFIG_COMMAND_MAXIMUM_NUMBER;
- }
-}
-
-void __is_set_fd_config_rollangle(struct fimc_is *is, u32 val)
-{
- unsigned int index = is->config_index;
- struct fd_param *fd;
- unsigned long *p_index;
-
- p_index = &is->config[index].p_region_index[1];
- fd = &is->config[index].fd;
-
- fd->config.roll_angle = val;
-
- if (!test_bit((PARAM_FD_CONFIG - 32), p_index)) {
- fd->config.cmd = FD_CONFIG_COMMAND_ROLL_ANGLE;
- fd->config.err = ERROR_FD_NONE;
- fimc_is_set_param_bit(is, PARAM_FD_CONFIG);
- } else {
- fd->config.cmd |= FD_CONFIG_COMMAND_ROLL_ANGLE;
- }
-}
-
-void __is_set_fd_config_yawangle(struct fimc_is *is, u32 val)
-{
- unsigned int index = is->config_index;
- struct fd_param *fd;
- unsigned long *p_index;
-
- p_index = &is->config[index].p_region_index[1];
- fd = &is->config[index].fd;
-
- fd->config.yaw_angle = val;
-
- if (!test_bit((PARAM_FD_CONFIG - 32), p_index)) {
- fd->config.cmd = FD_CONFIG_COMMAND_YAW_ANGLE;
- fd->config.err = ERROR_FD_NONE;
- fimc_is_set_param_bit(is, PARAM_FD_CONFIG);
- } else {
- fd->config.cmd |= FD_CONFIG_COMMAND_YAW_ANGLE;
- }
-}
-
-void __is_set_fd_config_smilemode(struct fimc_is *is, u32 val)
-{
- unsigned int index = is->config_index;
- struct fd_param *fd;
- unsigned long *p_index;
-
- p_index = &is->config[index].p_region_index[1];
- fd = &is->config[index].fd;
-
- fd->config.smile_mode = val;
-
- if (!test_bit((PARAM_FD_CONFIG - 32), p_index)) {
- fd->config.cmd = FD_CONFIG_COMMAND_SMILE_MODE;
- fd->config.err = ERROR_FD_NONE;
- fimc_is_set_param_bit(is, PARAM_FD_CONFIG);
- } else {
- fd->config.cmd |= FD_CONFIG_COMMAND_SMILE_MODE;
- }
-}
-
-void __is_set_fd_config_blinkmode(struct fimc_is *is, u32 val)
-{
- unsigned int index = is->config_index;
- struct fd_param *fd;
- unsigned long *p_index;
-
- p_index = &is->config[index].p_region_index[1];
- fd = &is->config[index].fd;
-
- fd->config.blink_mode = val;
-
- if (!test_bit((PARAM_FD_CONFIG - 32), p_index)) {
- fd->config.cmd = FD_CONFIG_COMMAND_BLINK_MODE;
- fd->config.err = ERROR_FD_NONE;
- fimc_is_set_param_bit(is, PARAM_FD_CONFIG);
- } else {
- fd->config.cmd |= FD_CONFIG_COMMAND_BLINK_MODE;
- }
-}
-
-void __is_set_fd_config_eyedetect(struct fimc_is *is, u32 val)
-{
- unsigned int index = is->config_index;
- struct fd_param *fd;
- unsigned long *p_index;
-
- p_index = &is->config[index].p_region_index[1];
- fd = &is->config[index].fd;
-
- fd->config.eye_detect = val;
-
- if (!test_bit((PARAM_FD_CONFIG - 32), p_index)) {
- fd->config.cmd = FD_CONFIG_COMMAND_EYES_DETECT;
- fd->config.err = ERROR_FD_NONE;
- fimc_is_set_param_bit(is, PARAM_FD_CONFIG);
- } else {
- fd->config.cmd |= FD_CONFIG_COMMAND_EYES_DETECT;
- }
-}
-
-void __is_set_fd_config_mouthdetect(struct fimc_is *is, u32 val)
-{
- unsigned int index = is->config_index;
- struct fd_param *fd;
- unsigned long *p_index;
-
- p_index = &is->config[index].p_region_index[1];
- fd = &is->config[index].fd;
-
- fd->config.mouth_detect = val;
-
- if (!test_bit((PARAM_FD_CONFIG - 32), p_index)) {
- fd->config.cmd = FD_CONFIG_COMMAND_MOUTH_DETECT;
- fd->config.err = ERROR_FD_NONE;
- fimc_is_set_param_bit(is, PARAM_FD_CONFIG);
- } else {
- fd->config.cmd |= FD_CONFIG_COMMAND_MOUTH_DETECT;
- }
-}
-
-void __is_set_fd_config_orientation(struct fimc_is *is, u32 val)
-{
- unsigned int index = is->config_index;
- struct fd_param *fd;
- unsigned long *p_index;
-
- p_index = &is->config[index].p_region_index[1];
- fd = &is->config[index].fd;
-
- fd->config.orientation = val;
-
- if (!test_bit((PARAM_FD_CONFIG - 32), p_index)) {
- fd->config.cmd = FD_CONFIG_COMMAND_ORIENTATION;
- fd->config.err = ERROR_FD_NONE;
- fimc_is_set_param_bit(is, PARAM_FD_CONFIG);
- } else {
- fd->config.cmd |= FD_CONFIG_COMMAND_ORIENTATION;
- }
-}
-
-void __is_set_fd_config_orientation_val(struct fimc_is *is, u32 val)
-{
- unsigned int index = is->config_index;
- struct fd_param *fd;
- unsigned long *p_index;
-
- p_index = &is->config[index].p_region_index[1];
- fd = &is->config[index].fd;
-
- fd->config.orientation_value = val;
-
- if (!test_bit((PARAM_FD_CONFIG - 32), p_index)) {
- fd->config.cmd = FD_CONFIG_COMMAND_ORIENTATION_VALUE;
- fd->config.err = ERROR_FD_NONE;
- fimc_is_set_param_bit(is, PARAM_FD_CONFIG);
- } else {
- fd->config.cmd |= FD_CONFIG_COMMAND_ORIENTATION_VALUE;
- }
-}
-
-void fimc_is_set_initial_params(struct fimc_is *is)
-{
- struct global_param *global;
- struct isp_param *isp;
- struct drc_param *drc;
- struct fd_param *fd;
- unsigned long *p_index;
- unsigned int index;
-
- index = is->config_index;
- global = &is->config[index].global;
- isp = &is->config[index].isp;
- drc = &is->config[index].drc;
- fd = &is->config[index].fd;
- p_index = &is->config[index].p_region_index[0];
-
- /* Global */
- global->shotmode.cmd = 1;
- fimc_is_set_param_bit(is, PARAM_GLOBAL_SHOTMODE);
-
- /* ISP */
- isp->control.cmd = CONTROL_COMMAND_START;
- isp->control.bypass = CONTROL_BYPASS_DISABLE;
- isp->control.err = CONTROL_ERROR_NONE;
- fimc_is_set_param_bit(is, PARAM_ISP_CONTROL);
-
- isp->otf_input.cmd = OTF_INPUT_COMMAND_ENABLE;
- if (!test_bit(PARAM_ISP_OTF_INPUT, p_index)) {
- isp->otf_input.width = DEFAULT_PREVIEW_STILL_WIDTH;
- isp->otf_input.height = DEFAULT_PREVIEW_STILL_HEIGHT;
- fimc_is_set_param_bit(is, PARAM_ISP_OTF_INPUT);
- }
- if (is->sensor->test_pattern)
- isp->otf_input.format = OTF_INPUT_FORMAT_STRGEN_COLORBAR_BAYER;
- else
- isp->otf_input.format = OTF_INPUT_FORMAT_BAYER;
- isp->otf_input.bitwidth = 10;
- isp->otf_input.order = OTF_INPUT_ORDER_BAYER_GR_BG;
- isp->otf_input.crop_offset_x = 0;
- isp->otf_input.crop_offset_y = 0;
- isp->otf_input.err = OTF_INPUT_ERROR_NONE;
-
- isp->dma1_input.cmd = DMA_INPUT_COMMAND_DISABLE;
- isp->dma1_input.width = 0;
- isp->dma1_input.height = 0;
- isp->dma1_input.format = 0;
- isp->dma1_input.bitwidth = 0;
- isp->dma1_input.plane = 0;
- isp->dma1_input.order = 0;
- isp->dma1_input.buffer_number = 0;
- isp->dma1_input.width = 0;
- isp->dma1_input.err = DMA_INPUT_ERROR_NONE;
- fimc_is_set_param_bit(is, PARAM_ISP_DMA1_INPUT);
-
- isp->dma2_input.cmd = DMA_INPUT_COMMAND_DISABLE;
- isp->dma2_input.width = 0;
- isp->dma2_input.height = 0;
- isp->dma2_input.format = 0;
- isp->dma2_input.bitwidth = 0;
- isp->dma2_input.plane = 0;
- isp->dma2_input.order = 0;
- isp->dma2_input.buffer_number = 0;
- isp->dma2_input.width = 0;
- isp->dma2_input.err = DMA_INPUT_ERROR_NONE;
- fimc_is_set_param_bit(is, PARAM_ISP_DMA2_INPUT);
-
- isp->aa.cmd = ISP_AA_COMMAND_START;
- isp->aa.target = ISP_AA_TARGET_AE | ISP_AA_TARGET_AWB;
- fimc_is_set_param_bit(is, PARAM_ISP_AA);
-
- if (!test_bit(PARAM_ISP_FLASH, p_index))
- __is_set_isp_flash(is, ISP_FLASH_COMMAND_DISABLE,
- ISP_FLASH_REDEYE_DISABLE);
-
- if (!test_bit(PARAM_ISP_AWB, p_index))
- __is_set_isp_awb(is, ISP_AWB_COMMAND_AUTO, 0);
-
- if (!test_bit(PARAM_ISP_IMAGE_EFFECT, p_index))
- __is_set_isp_effect(is, ISP_IMAGE_EFFECT_DISABLE);
-
- if (!test_bit(PARAM_ISP_ISO, p_index))
- __is_set_isp_iso(is, ISP_ISO_COMMAND_AUTO, 0);
-
- if (!test_bit(PARAM_ISP_ADJUST, p_index)) {
- __is_set_isp_adjust(is, ISP_ADJUST_COMMAND_MANUAL_CONTRAST, 0);
- __is_set_isp_adjust(is,
- ISP_ADJUST_COMMAND_MANUAL_SATURATION, 0);
- __is_set_isp_adjust(is, ISP_ADJUST_COMMAND_MANUAL_SHARPNESS, 0);
- __is_set_isp_adjust(is, ISP_ADJUST_COMMAND_MANUAL_EXPOSURE, 0);
- __is_set_isp_adjust(is,
- ISP_ADJUST_COMMAND_MANUAL_BRIGHTNESS, 0);
- __is_set_isp_adjust(is, ISP_ADJUST_COMMAND_MANUAL_HUE, 0);
- }
-
- if (!test_bit(PARAM_ISP_METERING, p_index)) {
- __is_set_isp_metering(is, 0, ISP_METERING_COMMAND_CENTER);
- __is_set_isp_metering(is, 1, 0);
- __is_set_isp_metering(is, 2, 0);
- __is_set_isp_metering(is, 3, 0);
- __is_set_isp_metering(is, 4, 0);
- }
-
- if (!test_bit(PARAM_ISP_AFC, p_index))
- __is_set_isp_afc(is, ISP_AFC_COMMAND_AUTO, 0);
-
- isp->otf_output.cmd = OTF_OUTPUT_COMMAND_ENABLE;
- if (!test_bit(PARAM_ISP_OTF_OUTPUT, p_index)) {
- isp->otf_output.width = DEFAULT_PREVIEW_STILL_WIDTH;
- isp->otf_output.height = DEFAULT_PREVIEW_STILL_HEIGHT;
- fimc_is_set_param_bit(is, PARAM_ISP_OTF_OUTPUT);
- }
- isp->otf_output.format = OTF_OUTPUT_FORMAT_YUV444;
- isp->otf_output.bitwidth = 12;
- isp->otf_output.order = 0;
- isp->otf_output.err = OTF_OUTPUT_ERROR_NONE;
-
- if (!test_bit(PARAM_ISP_DMA1_OUTPUT, p_index)) {
- isp->dma1_output.cmd = DMA_OUTPUT_COMMAND_DISABLE;
- isp->dma1_output.width = 0;
- isp->dma1_output.height = 0;
- isp->dma1_output.format = 0;
- isp->dma1_output.bitwidth = 0;
- isp->dma1_output.plane = 0;
- isp->dma1_output.order = 0;
- isp->dma1_output.buffer_number = 0;
- isp->dma1_output.buffer_address = 0;
- isp->dma1_output.notify_dma_done = 0;
- isp->dma1_output.dma_out_mask = 0;
- isp->dma1_output.err = DMA_OUTPUT_ERROR_NONE;
- fimc_is_set_param_bit(is, PARAM_ISP_DMA1_OUTPUT);
- }
-
- if (!test_bit(PARAM_ISP_DMA2_OUTPUT, p_index)) {
- isp->dma2_output.cmd = DMA_OUTPUT_COMMAND_DISABLE;
- isp->dma2_output.width = 0;
- isp->dma2_output.height = 0;
- isp->dma2_output.format = 0;
- isp->dma2_output.bitwidth = 0;
- isp->dma2_output.plane = 0;
- isp->dma2_output.order = 0;
- isp->dma2_output.buffer_number = 0;
- isp->dma2_output.buffer_address = 0;
- isp->dma2_output.notify_dma_done = 0;
- isp->dma2_output.dma_out_mask = 0;
- isp->dma2_output.err = DMA_OUTPUT_ERROR_NONE;
- fimc_is_set_param_bit(is, PARAM_ISP_DMA2_OUTPUT);
- }
-
- /* Sensor */
- if (!test_bit(PARAM_SENSOR_FRAME_RATE, p_index)) {
- if (is->config_index == 0)
- __is_set_sensor(is, 0);
- }
-
- /* DRC */
- drc->control.cmd = CONTROL_COMMAND_START;
- __is_set_drc_control(is, CONTROL_BYPASS_ENABLE);
-
- drc->otf_input.cmd = OTF_INPUT_COMMAND_ENABLE;
- if (!test_bit(PARAM_DRC_OTF_INPUT, p_index)) {
- drc->otf_input.width = DEFAULT_PREVIEW_STILL_WIDTH;
- drc->otf_input.height = DEFAULT_PREVIEW_STILL_HEIGHT;
- fimc_is_set_param_bit(is, PARAM_DRC_OTF_INPUT);
- }
- drc->otf_input.format = OTF_INPUT_FORMAT_YUV444;
- drc->otf_input.bitwidth = 12;
- drc->otf_input.order = 0;
- drc->otf_input.err = OTF_INPUT_ERROR_NONE;
-
- drc->dma_input.cmd = DMA_INPUT_COMMAND_DISABLE;
- drc->dma_input.width = 0;
- drc->dma_input.height = 0;
- drc->dma_input.format = 0;
- drc->dma_input.bitwidth = 0;
- drc->dma_input.plane = 0;
- drc->dma_input.order = 0;
- drc->dma_input.buffer_number = 0;
- drc->dma_input.width = 0;
- drc->dma_input.err = DMA_INPUT_ERROR_NONE;
- fimc_is_set_param_bit(is, PARAM_DRC_DMA_INPUT);
-
- drc->otf_output.cmd = OTF_OUTPUT_COMMAND_ENABLE;
- if (!test_bit(PARAM_DRC_OTF_OUTPUT, p_index)) {
- drc->otf_output.width = DEFAULT_PREVIEW_STILL_WIDTH;
- drc->otf_output.height = DEFAULT_PREVIEW_STILL_HEIGHT;
- fimc_is_set_param_bit(is, PARAM_DRC_OTF_OUTPUT);
- }
- drc->otf_output.format = OTF_OUTPUT_FORMAT_YUV444;
- drc->otf_output.bitwidth = 8;
- drc->otf_output.order = 0;
- drc->otf_output.err = OTF_OUTPUT_ERROR_NONE;
-
- /* FD */
- __is_set_fd_control(is, CONTROL_COMMAND_STOP);
- fd->control.bypass = CONTROL_BYPASS_DISABLE;
-
- fd->otf_input.cmd = OTF_INPUT_COMMAND_ENABLE;
- if (!test_bit(PARAM_FD_OTF_INPUT, p_index)) {
- fd->otf_input.width = DEFAULT_PREVIEW_STILL_WIDTH;
- fd->otf_input.height = DEFAULT_PREVIEW_STILL_HEIGHT;
- fimc_is_set_param_bit(is, PARAM_FD_OTF_INPUT);
- }
-
- fd->otf_input.format = OTF_INPUT_FORMAT_YUV444;
- fd->otf_input.bitwidth = 8;
- fd->otf_input.order = 0;
- fd->otf_input.err = OTF_INPUT_ERROR_NONE;
-
- fd->dma_input.cmd = DMA_INPUT_COMMAND_DISABLE;
- fd->dma_input.width = 0;
- fd->dma_input.height = 0;
- fd->dma_input.format = 0;
- fd->dma_input.bitwidth = 0;
- fd->dma_input.plane = 0;
- fd->dma_input.order = 0;
- fd->dma_input.buffer_number = 0;
- fd->dma_input.width = 0;
- fd->dma_input.err = DMA_INPUT_ERROR_NONE;
- fimc_is_set_param_bit(is, PARAM_FD_DMA_INPUT);
-
- __is_set_fd_config_maxface(is, 5);
- __is_set_fd_config_rollangle(is, FD_CONFIG_ROLL_ANGLE_FULL);
- __is_set_fd_config_yawangle(is, FD_CONFIG_YAW_ANGLE_45_90);
- __is_set_fd_config_smilemode(is, FD_CONFIG_SMILE_MODE_DISABLE);
- __is_set_fd_config_blinkmode(is, FD_CONFIG_BLINK_MODE_DISABLE);
- __is_set_fd_config_eyedetect(is, FD_CONFIG_EYES_DETECT_ENABLE);
- __is_set_fd_config_mouthdetect(is, FD_CONFIG_MOUTH_DETECT_DISABLE);
- __is_set_fd_config_orientation(is, FD_CONFIG_ORIENTATION_DISABLE);
- __is_set_fd_config_orientation_val(is, 0);
-}
diff --git a/drivers/media/platform/exynos4-is/fimc-is-param.h b/drivers/media/platform/exynos4-is/fimc-is-param.h
deleted file mode 100644
index 206904674927..000000000000
--- a/drivers/media/platform/exynos4-is/fimc-is-param.h
+++ /dev/null
@@ -1,1022 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-only */
-/*
- * Samsung EXYNOS4x12 FIMC-IS (Imaging Subsystem) driver
- *
- * Copyright (C) 2011 - 2013 Samsung Electronics Co., Ltd.
- *
- * Authors: Younghwan Joo <yhwan.joo@samsung.com>
- * Sylwester Nawrocki <s.nawrocki@samsung.com>
- */
-#ifndef FIMC_IS_PARAM_H_
-#define FIMC_IS_PARAM_H_
-
-#include <linux/compiler.h>
-
-#define FIMC_IS_CONFIG_TIMEOUT 3000 /* ms */
-#define IS_DEFAULT_WIDTH 1280
-#define IS_DEFAULT_HEIGHT 720
-
-#define DEFAULT_PREVIEW_STILL_WIDTH IS_DEFAULT_WIDTH
-#define DEFAULT_PREVIEW_STILL_HEIGHT IS_DEFAULT_HEIGHT
-#define DEFAULT_CAPTURE_STILL_WIDTH IS_DEFAULT_WIDTH
-#define DEFAULT_CAPTURE_STILL_HEIGHT IS_DEFAULT_HEIGHT
-#define DEFAULT_PREVIEW_VIDEO_WIDTH IS_DEFAULT_WIDTH
-#define DEFAULT_PREVIEW_VIDEO_HEIGHT IS_DEFAULT_HEIGHT
-#define DEFAULT_CAPTURE_VIDEO_WIDTH IS_DEFAULT_WIDTH
-#define DEFAULT_CAPTURE_VIDEO_HEIGHT IS_DEFAULT_HEIGHT
-
-#define DEFAULT_PREVIEW_STILL_FRAMERATE 30
-#define DEFAULT_CAPTURE_STILL_FRAMERATE 15
-#define DEFAULT_PREVIEW_VIDEO_FRAMERATE 30
-#define DEFAULT_CAPTURE_VIDEO_FRAMERATE 30
-
-#define FIMC_IS_REGION_VER 124 /* IS REGION VERSION 1.24 */
-#define FIMC_IS_PARAM_SIZE (FIMC_IS_REGION_SIZE + 1)
-#define FIMC_IS_MAGIC_NUMBER 0x01020304
-#define FIMC_IS_PARAM_MAX_SIZE 64 /* in bytes */
-#define FIMC_IS_PARAM_MAX_ENTRIES (FIMC_IS_PARAM_MAX_SIZE / 4)
-
-/* The parameter bitmask bit definitions. */
-enum is_param_bit {
- PARAM_GLOBAL_SHOTMODE,
- PARAM_SENSOR_CONTROL,
- PARAM_SENSOR_OTF_OUTPUT,
- PARAM_SENSOR_FRAME_RATE,
- PARAM_BUFFER_CONTROL,
- PARAM_BUFFER_OTF_INPUT,
- PARAM_BUFFER_OTF_OUTPUT,
- PARAM_ISP_CONTROL,
- PARAM_ISP_OTF_INPUT,
- PARAM_ISP_DMA1_INPUT,
- /* 10 */
- PARAM_ISP_DMA2_INPUT,
- PARAM_ISP_AA,
- PARAM_ISP_FLASH,
- PARAM_ISP_AWB,
- PARAM_ISP_IMAGE_EFFECT,
- PARAM_ISP_ISO,
- PARAM_ISP_ADJUST,
- PARAM_ISP_METERING,
- PARAM_ISP_AFC,
- PARAM_ISP_OTF_OUTPUT,
- /* 20 */
- PARAM_ISP_DMA1_OUTPUT,
- PARAM_ISP_DMA2_OUTPUT,
- PARAM_DRC_CONTROL,
- PARAM_DRC_OTF_INPUT,
- PARAM_DRC_DMA_INPUT,
- PARAM_DRC_OTF_OUTPUT,
- PARAM_SCALERC_CONTROL,
- PARAM_SCALERC_OTF_INPUT,
- PARAM_SCALERC_IMAGE_EFFECT,
- PARAM_SCALERC_INPUT_CROP,
- /* 30 */
- PARAM_SCALERC_OUTPUT_CROP,
- PARAM_SCALERC_OTF_OUTPUT,
- PARAM_SCALERC_DMA_OUTPUT,
- PARAM_ODC_CONTROL,
- PARAM_ODC_OTF_INPUT,
- PARAM_ODC_OTF_OUTPUT,
- PARAM_DIS_CONTROL,
- PARAM_DIS_OTF_INPUT,
- PARAM_DIS_OTF_OUTPUT,
- PARAM_TDNR_CONTROL,
- /* 40 */
- PARAM_TDNR_OTF_INPUT,
- PARAM_TDNR_1ST_FRAME,
- PARAM_TDNR_OTF_OUTPUT,
- PARAM_TDNR_DMA_OUTPUT,
- PARAM_SCALERP_CONTROL,
- PARAM_SCALERP_OTF_INPUT,
- PARAM_SCALERP_IMAGE_EFFECT,
- PARAM_SCALERP_INPUT_CROP,
- PARAM_SCALERP_OUTPUT_CROP,
- PARAM_SCALERP_ROTATION,
- /* 50 */
- PARAM_SCALERP_FLIP,
- PARAM_SCALERP_OTF_OUTPUT,
- PARAM_SCALERP_DMA_OUTPUT,
- PARAM_FD_CONTROL,
- PARAM_FD_OTF_INPUT,
- PARAM_FD_DMA_INPUT,
- PARAM_FD_CONFIG,
-};
-
-/* Interrupt map */
-#define FIMC_IS_INT_GENERAL 0
-#define FIMC_IS_INT_FRAME_DONE_ISP 1
-
-/* Input */
-
-#define CONTROL_COMMAND_STOP 0
-#define CONTROL_COMMAND_START 1
-
-#define CONTROL_BYPASS_DISABLE 0
-#define CONTROL_BYPASS_ENABLE 1
-
-#define CONTROL_ERROR_NONE 0
-
-/* OTF (On-The-Fly) input interface commands */
-#define OTF_INPUT_COMMAND_DISABLE 0
-#define OTF_INPUT_COMMAND_ENABLE 1
-
-/* OTF input interface color formats */
-enum oft_input_fmt {
- OTF_INPUT_FORMAT_BAYER = 0, /* 1 channel */
- OTF_INPUT_FORMAT_YUV444 = 1, /* 3 channels */
- OTF_INPUT_FORMAT_YUV422 = 2, /* 3 channels */
- OTF_INPUT_FORMAT_YUV420 = 3, /* 3 channels */
- OTF_INPUT_FORMAT_STRGEN_COLORBAR_BAYER = 10,
- OTF_INPUT_FORMAT_BAYER_DMA = 11,
-};
-
-#define OTF_INPUT_ORDER_BAYER_GR_BG 0
-
-/* OTF input error codes */
-#define OTF_INPUT_ERROR_NONE 0 /* Input setting is done */
-
-/* DMA input commands */
-#define DMA_INPUT_COMMAND_DISABLE 0
-#define DMA_INPUT_COMMAND_ENABLE 1
-
-/* DMA input color formats */
-enum dma_input_fmt {
- DMA_INPUT_FORMAT_BAYER = 0,
- DMA_INPUT_FORMAT_YUV444 = 1,
- DMA_INPUT_FORMAT_YUV422 = 2,
- DMA_INPUT_FORMAT_YUV420 = 3,
-};
-
-enum dma_input_order {
- /* (for DMA_INPUT_PLANE_3) */
- DMA_INPUT_ORDER_NO = 0,
- /* (only valid at DMA_INPUT_PLANE_2) */
- DMA_INPUT_ORDER_CBCR = 1,
- /* (only valid at DMA_INPUT_PLANE_2) */
- DMA_INPUT_ORDER_CRCB = 2,
- /* (only valid at DMA_INPUT_PLANE_1 & DMA_INPUT_FORMAT_YUV444) */
- DMA_INPUT_ORDER_YCBCR = 3,
- /* (only valid at DMA_INPUT_FORMAT_YUV422 & DMA_INPUT_PLANE_1) */
- DMA_INPUT_ORDER_YYCBCR = 4,
- /* (only valid at DMA_INPUT_FORMAT_YUV422 & DMA_INPUT_PLANE_1) */
- DMA_INPUT_ORDER_YCBYCR = 5,
- /* (only valid at DMA_INPUT_FORMAT_YUV422 & DMA_INPUT_PLANE_1) */
- DMA_INPUT_ORDER_YCRYCB = 6,
- /* (only valid at DMA_INPUT_FORMAT_YUV422 & DMA_INPUT_PLANE_1) */
- DMA_INPUT_ORDER_CBYCRY = 7,
- /* (only valid at DMA_INPUT_FORMAT_YUV422 & DMA_INPUT_PLANE_1) */
- DMA_INPUT_ORDER_CRYCBY = 8,
- /* (only valid at DMA_INPUT_FORMAT_BAYER) */
- DMA_INPUT_ORDER_GR_BG = 9
-};
-
-#define DMA_INPUT_ERROR_NONE 0 /* DMA input setting
- is done */
-/*
- * Data output parameter definitions
- */
-#define OTF_OUTPUT_CROP_DISABLE 0
-#define OTF_OUTPUT_CROP_ENABLE 1
-
-#define OTF_OUTPUT_COMMAND_DISABLE 0
-#define OTF_OUTPUT_COMMAND_ENABLE 1
-
-enum otf_output_fmt {
- OTF_OUTPUT_FORMAT_YUV444 = 1,
- OTF_OUTPUT_FORMAT_YUV422 = 2,
- OTF_OUTPUT_FORMAT_YUV420 = 3,
- OTF_OUTPUT_FORMAT_RGB = 4,
-};
-
-#define OTF_OUTPUT_ORDER_BAYER_GR_BG 0
-
-#define OTF_OUTPUT_ERROR_NONE 0 /* Output Setting is done */
-
-#define DMA_OUTPUT_COMMAND_DISABLE 0
-#define DMA_OUTPUT_COMMAND_ENABLE 1
-
-enum dma_output_fmt {
- DMA_OUTPUT_FORMAT_BAYER = 0,
- DMA_OUTPUT_FORMAT_YUV444 = 1,
- DMA_OUTPUT_FORMAT_YUV422 = 2,
- DMA_OUTPUT_FORMAT_YUV420 = 3,
- DMA_OUTPUT_FORMAT_RGB = 4,
-};
-
-enum dma_output_order {
- DMA_OUTPUT_ORDER_NO = 0,
- /* for DMA_OUTPUT_PLANE_3 */
- DMA_OUTPUT_ORDER_CBCR = 1,
- /* only valid at DMA_INPUT_PLANE_2) */
- DMA_OUTPUT_ORDER_CRCB = 2,
- /* only valid at DMA_OUTPUT_PLANE_2) */
- DMA_OUTPUT_ORDER_YYCBCR = 3,
- /* only valid at DMA_OUTPUT_FORMAT_YUV422 & DMA_OUTPUT_PLANE_1 */
- DMA_OUTPUT_ORDER_YCBYCR = 4,
- /* only valid at DMA_OUTPUT_FORMAT_YUV422 & DMA_OUTPUT_PLANE_1 */
- DMA_OUTPUT_ORDER_YCRYCB = 5,
- /* only valid at DMA_OUTPUT_FORMAT_YUV422 & DMA_OUTPUT_PLANE_1 */
- DMA_OUTPUT_ORDER_CBYCRY = 6,
- /* only valid at DMA_OUTPUT_FORMAT_YUV422 & DMA_OUTPUT_PLANE_1 */
- DMA_OUTPUT_ORDER_CRYCBY = 7,
- /* only valid at DMA_OUTPUT_FORMAT_YUV422 & DMA_OUTPUT_PLANE_1 */
- DMA_OUTPUT_ORDER_YCBCR = 8,
- /* only valid at DMA_OUTPUT_FORMAT_YUV444 & DMA_OUPUT_PLANE_1 */
- DMA_OUTPUT_ORDER_CRYCB = 9,
- /* only valid at DMA_OUTPUT_FORMAT_YUV444 & DMA_OUPUT_PLANE_1 */
- DMA_OUTPUT_ORDER_CRCBY = 10,
- /* only valid at DMA_OUTPUT_FORMAT_YUV444 & DMA_OUPUT_PLANE_1 */
- DMA_OUTPUT_ORDER_CBYCR = 11,
- /* only valid at DMA_OUTPUT_FORMAT_YUV444 & DMA_OUPUT_PLANE_1 */
- DMA_OUTPUT_ORDER_YCRCB = 12,
- /* only valid at DMA_OUTPUT_FORMAT_YUV444 & DMA_OUPUT_PLANE_1 */
- DMA_OUTPUT_ORDER_CBCRY = 13,
- /* only valid at DMA_OUTPUT_FORMAT_YUV444 & DMA_OUPUT_PLANE_1 */
- DMA_OUTPUT_ORDER_BGR = 14,
- /* only valid at DMA_OUTPUT_FORMAT_RGB */
- DMA_OUTPUT_ORDER_GB_BG = 15
- /* only valid at DMA_OUTPUT_FORMAT_BAYER */
-};
-
-/* enum dma_output_notify_dma_done */
-#define DMA_OUTPUT_NOTIFY_DMA_DONE_DISABLE 0
-#define DMA_OUTPUT_NOTIFY_DMA_DONE_ENABLE 1
-
-/* DMA output error codes */
-#define DMA_OUTPUT_ERROR_NONE 0 /* DMA output setting
- is done */
-
-/* ---------------------- Global ----------------------------------- */
-#define GLOBAL_SHOTMODE_ERROR_NONE 0 /* shot-mode setting
- is done */
-/* 3A lock commands */
-#define ISP_AA_COMMAND_START 0
-#define ISP_AA_COMMAND_STOP 1
-
-/* 3A lock target */
-#define ISP_AA_TARGET_AF 1
-#define ISP_AA_TARGET_AE 2
-#define ISP_AA_TARGET_AWB 4
-
-enum isp_af_mode {
- ISP_AF_MODE_MANUAL = 0,
- ISP_AF_MODE_SINGLE = 1,
- ISP_AF_MODE_CONTINUOUS = 2,
- ISP_AF_MODE_TOUCH = 3,
- ISP_AF_MODE_SLEEP = 4,
- ISP_AF_MODE_INIT = 5,
- ISP_AF_MODE_SET_CENTER_WINDOW = 6,
- ISP_AF_MODE_SET_TOUCH_WINDOW = 7
-};
-
-/* Face AF commands */
-#define ISP_AF_FACE_DISABLE 0
-#define ISP_AF_FACE_ENABLE 1
-
-/* AF range */
-#define ISP_AF_RANGE_NORMAL 0
-#define ISP_AF_RANGE_MACRO 1
-
-/* AF sleep */
-#define ISP_AF_SLEEP_OFF 0
-#define ISP_AF_SLEEP_ON 1
-
-/* Continuous AF commands */
-#define ISP_AF_CONTINUOUS_DISABLE 0
-#define ISP_AF_CONTINUOUS_ENABLE 1
-
-/* ISP AF error codes */
-#define ISP_AF_ERROR_NONE 0 /* AF mode change is done */
-#define ISP_AF_ERROR_NONE_LOCK_DONE 1 /* AF lock is done */
-
-/* Flash commands */
-#define ISP_FLASH_COMMAND_DISABLE 0
-#define ISP_FLASH_COMMAND_MANUAL_ON 1 /* (forced flash) */
-#define ISP_FLASH_COMMAND_AUTO 2
-#define ISP_FLASH_COMMAND_TORCH 3 /* 3 sec */
-
-/* Flash red-eye commands */
-#define ISP_FLASH_REDEYE_DISABLE 0
-#define ISP_FLASH_REDEYE_ENABLE 1
-
-/* Flash error codes */
-#define ISP_FLASH_ERROR_NONE 0 /* Flash setting is done */
-
-/* -------------------------- AWB ------------------------------------ */
-enum isp_awb_command {
- ISP_AWB_COMMAND_AUTO = 0,
- ISP_AWB_COMMAND_ILLUMINATION = 1,
- ISP_AWB_COMMAND_MANUAL = 2
-};
-
-enum isp_awb_illumination {
- ISP_AWB_ILLUMINATION_DAYLIGHT = 0,
- ISP_AWB_ILLUMINATION_CLOUDY = 1,
- ISP_AWB_ILLUMINATION_TUNGSTEN = 2,
- ISP_AWB_ILLUMINATION_FLUORESCENT = 3
-};
-
-/* ISP AWN error codes */
-#define ISP_AWB_ERROR_NONE 0 /* AWB setting is done */
-
-/* -------------------------- Effect ----------------------------------- */
-enum isp_imageeffect_command {
- ISP_IMAGE_EFFECT_DISABLE = 0,
- ISP_IMAGE_EFFECT_MONOCHROME = 1,
- ISP_IMAGE_EFFECT_NEGATIVE_MONO = 2,
- ISP_IMAGE_EFFECT_NEGATIVE_COLOR = 3,
- ISP_IMAGE_EFFECT_SEPIA = 4
-};
-
-/* Image effect error codes */
-#define ISP_IMAGE_EFFECT_ERROR_NONE 0 /* Image effect setting
- is done */
-/* ISO commands */
-#define ISP_ISO_COMMAND_AUTO 0
-#define ISP_ISO_COMMAND_MANUAL 1
-
-/* ISO error codes */
-#define ISP_ISO_ERROR_NONE 0 /* ISO setting is done */
-
-/* ISP adjust commands */
-#define ISP_ADJUST_COMMAND_AUTO (0 << 0)
-#define ISP_ADJUST_COMMAND_MANUAL_CONTRAST (1 << 0)
-#define ISP_ADJUST_COMMAND_MANUAL_SATURATION (1 << 1)
-#define ISP_ADJUST_COMMAND_MANUAL_SHARPNESS (1 << 2)
-#define ISP_ADJUST_COMMAND_MANUAL_EXPOSURE (1 << 3)
-#define ISP_ADJUST_COMMAND_MANUAL_BRIGHTNESS (1 << 4)
-#define ISP_ADJUST_COMMAND_MANUAL_HUE (1 << 5)
-#define ISP_ADJUST_COMMAND_MANUAL_ALL 0x7f
-
-/* ISP adjustment error codes */
-#define ISP_ADJUST_ERROR_NONE 0 /* Adjust setting is done */
-
-/*
- * Exposure metering
- */
-enum isp_metering_command {
- ISP_METERING_COMMAND_AVERAGE = 0,
- ISP_METERING_COMMAND_SPOT = 1,
- ISP_METERING_COMMAND_MATRIX = 2,
- ISP_METERING_COMMAND_CENTER = 3
-};
-
-/* ISP metering error codes */
-#define ISP_METERING_ERROR_NONE 0 /* Metering setting is done */
-
-/*
- * AFC
- */
-enum isp_afc_command {
- ISP_AFC_COMMAND_DISABLE = 0,
- ISP_AFC_COMMAND_AUTO = 1,
- ISP_AFC_COMMAND_MANUAL = 2,
-};
-
-#define ISP_AFC_MANUAL_50HZ 50
-#define ISP_AFC_MANUAL_60HZ 60
-
-/* ------------------------ SCENE MODE--------------------------------- */
-enum isp_scene_mode {
- ISP_SCENE_NONE = 0,
- ISP_SCENE_PORTRAIT = 1,
- ISP_SCENE_LANDSCAPE = 2,
- ISP_SCENE_SPORTS = 3,
- ISP_SCENE_PARTYINDOOR = 4,
- ISP_SCENE_BEACHSNOW = 5,
- ISP_SCENE_SUNSET = 6,
- ISP_SCENE_DAWN = 7,
- ISP_SCENE_FALL = 8,
- ISP_SCENE_NIGHT = 9,
- ISP_SCENE_AGAINSTLIGHTWLIGHT = 10,
- ISP_SCENE_AGAINSTLIGHTWOLIGHT = 11,
- ISP_SCENE_FIRE = 12,
- ISP_SCENE_TEXT = 13,
- ISP_SCENE_CANDLE = 14
-};
-
-/* AFC error codes */
-#define ISP_AFC_ERROR_NONE 0 /* AFC setting is done */
-
-/* ---------------------------- FD ------------------------------------- */
-enum fd_config_command {
- FD_CONFIG_COMMAND_MAXIMUM_NUMBER = 0x1,
- FD_CONFIG_COMMAND_ROLL_ANGLE = 0x2,
- FD_CONFIG_COMMAND_YAW_ANGLE = 0x4,
- FD_CONFIG_COMMAND_SMILE_MODE = 0x8,
- FD_CONFIG_COMMAND_BLINK_MODE = 0x10,
- FD_CONFIG_COMMAND_EYES_DETECT = 0x20,
- FD_CONFIG_COMMAND_MOUTH_DETECT = 0x40,
- FD_CONFIG_COMMAND_ORIENTATION = 0x80,
- FD_CONFIG_COMMAND_ORIENTATION_VALUE = 0x100
-};
-
-enum fd_config_roll_angle {
- FD_CONFIG_ROLL_ANGLE_BASIC = 0,
- FD_CONFIG_ROLL_ANGLE_PRECISE_BASIC = 1,
- FD_CONFIG_ROLL_ANGLE_SIDES = 2,
- FD_CONFIG_ROLL_ANGLE_PRECISE_SIDES = 3,
- FD_CONFIG_ROLL_ANGLE_FULL = 4,
- FD_CONFIG_ROLL_ANGLE_PRECISE_FULL = 5,
-};
-
-enum fd_config_yaw_angle {
- FD_CONFIG_YAW_ANGLE_0 = 0,
- FD_CONFIG_YAW_ANGLE_45 = 1,
- FD_CONFIG_YAW_ANGLE_90 = 2,
- FD_CONFIG_YAW_ANGLE_45_90 = 3,
-};
-
-/* Smile mode configuration */
-#define FD_CONFIG_SMILE_MODE_DISABLE 0
-#define FD_CONFIG_SMILE_MODE_ENABLE 1
-
-/* Blink mode configuration */
-#define FD_CONFIG_BLINK_MODE_DISABLE 0
-#define FD_CONFIG_BLINK_MODE_ENABLE 1
-
-/* Eyes detection configuration */
-#define FD_CONFIG_EYES_DETECT_DISABLE 0
-#define FD_CONFIG_EYES_DETECT_ENABLE 1
-
-/* Mouth detection configuration */
-#define FD_CONFIG_MOUTH_DETECT_DISABLE 0
-#define FD_CONFIG_MOUTH_DETECT_ENABLE 1
-
-#define FD_CONFIG_ORIENTATION_DISABLE 0
-#define FD_CONFIG_ORIENTATION_ENABLE 1
-
-struct param_control {
- u32 cmd;
- u32 bypass;
- u32 buffer_address;
- u32 buffer_size;
- u32 skip_frames; /* only valid at ISP */
- u32 reserved[FIMC_IS_PARAM_MAX_ENTRIES - 6];
- u32 err;
-};
-
-struct param_otf_input {
- u32 cmd;
- u32 width;
- u32 height;
- u32 format;
- u32 bitwidth;
- u32 order;
- u32 crop_offset_x;
- u32 crop_offset_y;
- u32 crop_width;
- u32 crop_height;
- u32 frametime_min;
- u32 frametime_max;
- u32 reserved[FIMC_IS_PARAM_MAX_ENTRIES - 13];
- u32 err;
-};
-
-struct param_dma_input {
- u32 cmd;
- u32 width;
- u32 height;
- u32 format;
- u32 bitwidth;
- u32 plane;
- u32 order;
- u32 buffer_number;
- u32 buffer_address;
- u32 reserved[FIMC_IS_PARAM_MAX_ENTRIES - 10];
- u32 err;
-};
-
-struct param_otf_output {
- u32 cmd;
- u32 width;
- u32 height;
- u32 format;
- u32 bitwidth;
- u32 order;
- u32 reserved[FIMC_IS_PARAM_MAX_ENTRIES - 7];
- u32 err;
-};
-
-struct param_dma_output {
- u32 cmd;
- u32 width;
- u32 height;
- u32 format;
- u32 bitwidth;
- u32 plane;
- u32 order;
- u32 buffer_number;
- u32 buffer_address;
- u32 notify_dma_done;
- u32 dma_out_mask;
- u32 reserved[FIMC_IS_PARAM_MAX_ENTRIES - 12];
- u32 err;
-};
-
-struct param_global_shotmode {
- u32 cmd;
- u32 skip_frames;
- u32 reserved[FIMC_IS_PARAM_MAX_ENTRIES - 3];
- u32 err;
-};
-
-struct param_sensor_framerate {
- u32 frame_rate;
- u32 reserved[FIMC_IS_PARAM_MAX_ENTRIES - 2];
- u32 err;
-};
-
-struct param_isp_aa {
- u32 cmd;
- u32 target;
- u32 mode;
- u32 scene;
- u32 sleep;
- u32 face;
- u32 touch_x;
- u32 touch_y;
- u32 manual_af_setting;
- u32 reserved[FIMC_IS_PARAM_MAX_ENTRIES - 10];
- u32 err;
-};
-
-struct param_isp_flash {
- u32 cmd;
- u32 redeye;
- u32 reserved[FIMC_IS_PARAM_MAX_ENTRIES - 3];
- u32 err;
-};
-
-struct param_isp_awb {
- u32 cmd;
- u32 illumination;
- u32 reserved[FIMC_IS_PARAM_MAX_ENTRIES - 3];
- u32 err;
-};
-
-struct param_isp_imageeffect {
- u32 cmd;
- u32 reserved[FIMC_IS_PARAM_MAX_ENTRIES - 2];
- u32 err;
-};
-
-struct param_isp_iso {
- u32 cmd;
- u32 value;
- u32 reserved[FIMC_IS_PARAM_MAX_ENTRIES - 3];
- u32 err;
-};
-
-struct param_isp_adjust {
- u32 cmd;
- s32 contrast;
- s32 saturation;
- s32 sharpness;
- s32 exposure;
- s32 brightness;
- s32 hue;
- u32 reserved[FIMC_IS_PARAM_MAX_ENTRIES - 8];
- u32 err;
-};
-
-struct param_isp_metering {
- u32 cmd;
- u32 win_pos_x;
- u32 win_pos_y;
- u32 win_width;
- u32 win_height;
- u32 reserved[FIMC_IS_PARAM_MAX_ENTRIES - 6];
- u32 err;
-};
-
-struct param_isp_afc {
- u32 cmd;
- u32 manual;
- u32 reserved[FIMC_IS_PARAM_MAX_ENTRIES - 3];
- u32 err;
-};
-
-struct param_scaler_imageeffect {
- u32 cmd;
- u32 arbitrary_cb;
- u32 arbitrary_cr;
- u32 reserved[FIMC_IS_PARAM_MAX_ENTRIES - 4];
- u32 err;
-};
-
-struct param_scaler_input_crop {
- u32 cmd;
- u32 crop_offset_x;
- u32 crop_offset_y;
- u32 crop_width;
- u32 crop_height;
- u32 in_width;
- u32 in_height;
- u32 out_width;
- u32 out_height;
- u32 reserved[FIMC_IS_PARAM_MAX_ENTRIES - 10];
- u32 err;
-};
-
-struct param_scaler_output_crop {
- u32 cmd;
- u32 crop_offset_x;
- u32 crop_offset_y;
- u32 crop_width;
- u32 crop_height;
- u32 out_format;
- u32 reserved[FIMC_IS_PARAM_MAX_ENTRIES - 7];
- u32 err;
-};
-
-struct param_scaler_rotation {
- u32 cmd;
- u32 reserved[FIMC_IS_PARAM_MAX_ENTRIES - 2];
- u32 err;
-};
-
-struct param_scaler_flip {
- u32 cmd;
- u32 reserved[FIMC_IS_PARAM_MAX_ENTRIES - 2];
- u32 err;
-};
-
-struct param_3dnr_1stframe {
- u32 cmd;
- u32 reserved[FIMC_IS_PARAM_MAX_ENTRIES - 2];
- u32 err;
-};
-
-struct param_fd_config {
- u32 cmd;
- u32 max_number;
- u32 roll_angle;
- u32 yaw_angle;
- u32 smile_mode;
- u32 blink_mode;
- u32 eye_detect;
- u32 mouth_detect;
- u32 orientation;
- u32 orientation_value;
- u32 reserved[FIMC_IS_PARAM_MAX_ENTRIES - 11];
- u32 err;
-};
-
-struct global_param {
- struct param_global_shotmode shotmode;
-};
-
-struct sensor_param {
- struct param_control control;
- struct param_otf_output otf_output;
- struct param_sensor_framerate frame_rate;
-} __packed;
-
-struct buffer_param {
- struct param_control control;
- struct param_otf_input otf_input;
- struct param_otf_output otf_output;
-} __packed;
-
-struct isp_param {
- struct param_control control;
- struct param_otf_input otf_input;
- struct param_dma_input dma1_input;
- struct param_dma_input dma2_input;
- struct param_isp_aa aa;
- struct param_isp_flash flash;
- struct param_isp_awb awb;
- struct param_isp_imageeffect effect;
- struct param_isp_iso iso;
- struct param_isp_adjust adjust;
- struct param_isp_metering metering;
- struct param_isp_afc afc;
- struct param_otf_output otf_output;
- struct param_dma_output dma1_output;
- struct param_dma_output dma2_output;
-} __packed;
-
-struct drc_param {
- struct param_control control;
- struct param_otf_input otf_input;
- struct param_dma_input dma_input;
- struct param_otf_output otf_output;
-} __packed;
-
-struct scalerc_param {
- struct param_control control;
- struct param_otf_input otf_input;
- struct param_scaler_imageeffect effect;
- struct param_scaler_input_crop input_crop;
- struct param_scaler_output_crop output_crop;
- struct param_otf_output otf_output;
- struct param_dma_output dma_output;
-} __packed;
-
-struct odc_param {
- struct param_control control;
- struct param_otf_input otf_input;
- struct param_otf_output otf_output;
-} __packed;
-
-struct dis_param {
- struct param_control control;
- struct param_otf_output otf_input;
- struct param_otf_output otf_output;
-} __packed;
-
-struct tdnr_param {
- struct param_control control;
- struct param_otf_input otf_input;
- struct param_3dnr_1stframe frame;
- struct param_otf_output otf_output;
- struct param_dma_output dma_output;
-} __packed;
-
-struct scalerp_param {
- struct param_control control;
- struct param_otf_input otf_input;
- struct param_scaler_imageeffect effect;
- struct param_scaler_input_crop input_crop;
- struct param_scaler_output_crop output_crop;
- struct param_scaler_rotation rotation;
- struct param_scaler_flip flip;
- struct param_otf_output otf_output;
- struct param_dma_output dma_output;
-} __packed;
-
-struct fd_param {
- struct param_control control;
- struct param_otf_input otf_input;
- struct param_dma_input dma_input;
- struct param_fd_config config;
-} __packed;
-
-struct is_param_region {
- struct global_param global;
- struct sensor_param sensor;
- struct buffer_param buf;
- struct isp_param isp;
- struct drc_param drc;
- struct scalerc_param scalerc;
- struct odc_param odc;
- struct dis_param dis;
- struct tdnr_param tdnr;
- struct scalerp_param scalerp;
- struct fd_param fd;
-} __packed;
-
-#define NUMBER_OF_GAMMA_CURVE_POINTS 32
-
-struct is_tune_sensor {
- u32 exposure;
- u32 analog_gain;
- u32 frame_rate;
- u32 actuator_position;
-};
-
-struct is_tune_gammacurve {
- u32 num_pts_x[NUMBER_OF_GAMMA_CURVE_POINTS];
- u32 num_pts_y_r[NUMBER_OF_GAMMA_CURVE_POINTS];
- u32 num_pts_y_g[NUMBER_OF_GAMMA_CURVE_POINTS];
- u32 num_pts_y_b[NUMBER_OF_GAMMA_CURVE_POINTS];
-};
-
-struct is_tune_isp {
- /* Brightness level: range 0...100, default 7. */
- u32 brightness_level;
- /* Contrast level: range -127...127, default 0. */
- s32 contrast_level;
- /* Saturation level: range -127...127, default 0. */
- s32 saturation_level;
- s32 gamma_level;
- struct is_tune_gammacurve gamma_curve[4];
- /* Hue: range -127...127, default 0. */
- s32 hue;
- /* Sharpness blur: range -127...127, default 0. */
- s32 sharpness_blur;
- /* Despeckle : range -127~127, default : 0 */
- s32 despeckle;
- /* Edge color supression: range -127...127, default 0. */
- s32 edge_color_supression;
- /* Noise reduction: range -127...127, default 0. */
- s32 noise_reduction;
- /* (32 * 4 + 9) * 4 = 548 bytes */
-} __packed;
-
-struct is_tune_region {
- struct is_tune_sensor sensor;
- struct is_tune_isp isp;
-} __packed;
-
-struct rational {
- u32 num;
- u32 den;
-};
-
-struct srational {
- s32 num;
- s32 den;
-};
-
-#define FLASH_FIRED_SHIFT 0
-#define FLASH_NOT_FIRED 0
-#define FLASH_FIRED 1
-
-#define FLASH_STROBE_SHIFT 1
-#define FLASH_STROBE_NO_DETECTION 0
-#define FLASH_STROBE_RESERVED 1
-#define FLASH_STROBE_RETURN_LIGHT_NOT_DETECTED 2
-#define FLASH_STROBE_RETURN_LIGHT_DETECTED 3
-
-#define FLASH_MODE_SHIFT 3
-#define FLASH_MODE_UNKNOWN 0
-#define FLASH_MODE_COMPULSORY_FLASH_FIRING 1
-#define FLASH_MODE_COMPULSORY_FLASH_SUPPRESSION 2
-#define FLASH_MODE_AUTO_MODE 3
-
-#define FLASH_FUNCTION_SHIFT 5
-#define FLASH_FUNCTION_PRESENT 0
-#define FLASH_FUNCTION_NONE 1
-
-#define FLASH_RED_EYE_SHIFT 6
-#define FLASH_RED_EYE_DISABLED 0
-#define FLASH_RED_EYE_SUPPORTED 1
-
-enum apex_aperture_value {
- F1_0 = 0,
- F1_4 = 1,
- F2_0 = 2,
- F2_8 = 3,
- F4_0 = 4,
- F5_6 = 5,
- F8_9 = 6,
- F11_0 = 7,
- F16_0 = 8,
- F22_0 = 9,
- F32_0 = 10,
-};
-
-struct exif_attribute {
- struct rational exposure_time;
- struct srational shutter_speed;
- u32 iso_speed_rating;
- u32 flash;
- struct srational brightness;
-} __packed;
-
-struct is_frame_header {
- u32 valid;
- u32 bad_mark;
- u32 captured;
- u32 frame_number;
- struct exif_attribute exif;
-} __packed;
-
-struct is_fd_rect {
- u32 offset_x;
- u32 offset_y;
- u32 width;
- u32 height;
-};
-
-struct is_face_marker {
- u32 frame_number;
- struct is_fd_rect face;
- struct is_fd_rect left_eye;
- struct is_fd_rect right_eye;
- struct is_fd_rect mouth;
- u32 roll_angle;
- u32 yaw_angle;
- u32 confidence;
- s32 smile_level;
- s32 blink_level;
-} __packed;
-
-#define MAX_FRAME_COUNT 8
-#define MAX_FRAME_COUNT_PREVIEW 4
-#define MAX_FRAME_COUNT_CAPTURE 1
-#define MAX_FACE_COUNT 16
-#define MAX_SHARED_COUNT 500
-
-struct is_region {
- struct is_param_region parameter;
- struct is_tune_region tune;
- struct is_frame_header header[MAX_FRAME_COUNT];
- struct is_face_marker face[MAX_FACE_COUNT];
- u32 shared[MAX_SHARED_COUNT];
-} __packed;
-
-/* Offset to the ISP DMA2 output buffer address array. */
-#define DMA2_OUTPUT_ADDR_ARRAY_OFFS \
- (offsetof(struct is_region, shared) + 32 * sizeof(u32))
-
-struct is_debug_frame_descriptor {
- u32 sensor_frame_time;
- u32 sensor_exposure_time;
- s32 sensor_analog_gain;
- /* monitor for AA */
- u32 req_lei;
-
- u32 next_next_lei_exp;
- u32 next_next_lei_a_gain;
- u32 next_next_lei_d_gain;
- u32 next_next_lei_statlei;
- u32 next_next_lei_lei;
-
- u32 dummy0;
-};
-
-#define MAX_FRAMEDESCRIPTOR_CONTEXT_NUM (30*20) /* 600 frames */
-#define MAX_VERSION_DISPLAY_BUF 32
-
-struct is_share_region {
- u32 frame_time;
- u32 exposure_time;
- s32 analog_gain;
-
- u32 r_gain;
- u32 g_gain;
- u32 b_gain;
-
- u32 af_position;
- u32 af_status;
- /* 0 : SIRC_ISP_CAMERA_AUTOFOCUSMESSAGE_NOMESSAGE */
- /* 1 : SIRC_ISP_CAMERA_AUTOFOCUSMESSAGE_REACHED */
- /* 2 : SIRC_ISP_CAMERA_AUTOFOCUSMESSAGE_UNABLETOREACH */
- /* 3 : SIRC_ISP_CAMERA_AUTOFOCUSMESSAGE_LOST */
- /* default : unknown */
- u32 af_scene_type;
-
- u32 frame_descp_onoff_control;
- u32 frame_descp_update_done;
- u32 frame_descp_idx;
- u32 frame_descp_max_idx;
- struct is_debug_frame_descriptor
- dbg_frame_descp_ctx[MAX_FRAMEDESCRIPTOR_CONTEXT_NUM];
-
- u32 chip_id;
- u32 chip_rev_no;
- u8 isp_fw_ver_no[MAX_VERSION_DISPLAY_BUF];
- u8 isp_fw_ver_date[MAX_VERSION_DISPLAY_BUF];
- u8 sirc_sdk_ver_no[MAX_VERSION_DISPLAY_BUF];
- u8 sirc_sdk_rev_no[MAX_VERSION_DISPLAY_BUF];
- u8 sirc_sdk_rev_date[MAX_VERSION_DISPLAY_BUF];
-} __packed;
-
-struct is_debug_control {
- u32 write_point; /* 0~ 500KB boundary */
- u32 assert_flag; /* 0: Not invoked, 1: Invoked */
- u32 pabort_flag; /* 0: Not invoked, 1: Invoked */
- u32 dabort_flag; /* 0: Not invoked, 1: Invoked */
-};
-
-struct sensor_open_extended {
- u32 actuator_type;
- u32 mclk;
- u32 mipi_lane_num;
- u32 mipi_speed;
- /* Skip setfile loading when fast_open_sensor is not 0 */
- u32 fast_open_sensor;
- /* Activating sensor self calibration mode (6A3) */
- u32 self_calibration_mode;
- /* This field is to adjust I2c clock based on ACLK200 */
- /* This value is varied in case of rev 0.2 */
- u32 i2c_sclk;
-};
-
-struct fimc_is;
-
-int fimc_is_hw_get_sensor_max_framerate(struct fimc_is *is);
-int __fimc_is_hw_update_param(struct fimc_is *is, u32 offset);
-void fimc_is_set_initial_params(struct fimc_is *is);
-unsigned int __get_pending_param_count(struct fimc_is *is);
-
-int __is_hw_update_params(struct fimc_is *is);
-void __is_get_frame_size(struct fimc_is *is, struct v4l2_mbus_framefmt *mf);
-void __is_set_frame_size(struct fimc_is *is, struct v4l2_mbus_framefmt *mf);
-void __is_set_sensor(struct fimc_is *is, int fps);
-void __is_set_isp_aa_ae(struct fimc_is *is);
-void __is_set_isp_flash(struct fimc_is *is, u32 cmd, u32 redeye);
-void __is_set_isp_awb(struct fimc_is *is, u32 cmd, u32 val);
-void __is_set_isp_effect(struct fimc_is *is, u32 cmd);
-void __is_set_isp_iso(struct fimc_is *is, u32 cmd, u32 val);
-void __is_set_isp_adjust(struct fimc_is *is, u32 cmd, u32 val);
-void __is_set_isp_metering(struct fimc_is *is, u32 id, u32 val);
-void __is_set_isp_afc(struct fimc_is *is, u32 cmd, u32 val);
-void __is_set_drc_control(struct fimc_is *is, u32 val);
-void __is_set_fd_control(struct fimc_is *is, u32 val);
-void __is_set_fd_config_maxface(struct fimc_is *is, u32 val);
-void __is_set_fd_config_rollangle(struct fimc_is *is, u32 val);
-void __is_set_fd_config_yawangle(struct fimc_is *is, u32 val);
-void __is_set_fd_config_smilemode(struct fimc_is *is, u32 val);
-void __is_set_fd_config_blinkmode(struct fimc_is *is, u32 val);
-void __is_set_fd_config_eyedetect(struct fimc_is *is, u32 val);
-void __is_set_fd_config_mouthdetect(struct fimc_is *is, u32 val);
-void __is_set_fd_config_orientation(struct fimc_is *is, u32 val);
-void __is_set_fd_config_orientation_val(struct fimc_is *is, u32 val);
-void __is_set_isp_aa_af_mode(struct fimc_is *is, int cmd);
-void __is_set_isp_aa_af_start_stop(struct fimc_is *is, int cmd);
-
-#endif
diff --git a/drivers/media/platform/exynos4-is/fimc-is-regs.c b/drivers/media/platform/exynos4-is/fimc-is-regs.c
deleted file mode 100644
index 366e6393817d..000000000000
--- a/drivers/media/platform/exynos4-is/fimc-is-regs.c
+++ /dev/null
@@ -1,230 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-/*
- * Samsung EXYNOS4x12 FIMC-IS (Imaging Subsystem) driver
- *
- * Copyright (C) 2012 - 2013 Samsung Electronics Co., Ltd.
- *
- * Authors: Younghwan Joo <yhwan.joo@samsung.com>
- * Sylwester Nawrocki <s.nawrocki@samsung.com>
- */
-#include <linux/delay.h>
-
-#include "fimc-is.h"
-#include "fimc-is-command.h"
-#include "fimc-is-regs.h"
-#include "fimc-is-sensor.h"
-
-void fimc_is_fw_clear_irq1(struct fimc_is *is, unsigned int nr)
-{
- mcuctl_write(1UL << nr, is, MCUCTL_REG_INTCR1);
-}
-
-void fimc_is_fw_clear_irq2(struct fimc_is *is)
-{
- u32 cfg = mcuctl_read(is, MCUCTL_REG_INTSR2);
- mcuctl_write(cfg, is, MCUCTL_REG_INTCR2);
-}
-
-void fimc_is_hw_set_intgr0_gd0(struct fimc_is *is)
-{
- mcuctl_write(INTGR0_INTGD(0), is, MCUCTL_REG_INTGR0);
-}
-
-int fimc_is_hw_wait_intmsr0_intmsd0(struct fimc_is *is)
-{
- unsigned int timeout = 2000;
- u32 cfg, status;
-
- do {
- cfg = mcuctl_read(is, MCUCTL_REG_INTMSR0);
- status = INTMSR0_GET_INTMSD(0, cfg);
-
- if (--timeout == 0) {
- dev_warn(&is->pdev->dev, "%s timeout\n",
- __func__);
- return -ETIMEDOUT;
- }
- udelay(1);
- } while (status != 0);
-
- return 0;
-}
-
-int fimc_is_hw_set_param(struct fimc_is *is)
-{
- struct chain_config *config = &is->config[is->config_index];
- unsigned int param_count = __get_pending_param_count(is);
-
- fimc_is_hw_wait_intmsr0_intmsd0(is);
-
- mcuctl_write(HIC_SET_PARAMETER, is, MCUCTL_REG_ISSR(0));
- mcuctl_write(is->sensor_index, is, MCUCTL_REG_ISSR(1));
- mcuctl_write(is->config_index, is, MCUCTL_REG_ISSR(2));
-
- mcuctl_write(param_count, is, MCUCTL_REG_ISSR(3));
- mcuctl_write(config->p_region_index[0], is, MCUCTL_REG_ISSR(4));
- mcuctl_write(config->p_region_index[1], is, MCUCTL_REG_ISSR(5));
-
- fimc_is_hw_set_intgr0_gd0(is);
- return 0;
-}
-
-static int __maybe_unused fimc_is_hw_set_tune(struct fimc_is *is)
-{
- fimc_is_hw_wait_intmsr0_intmsd0(is);
-
- mcuctl_write(HIC_SET_TUNE, is, MCUCTL_REG_ISSR(0));
- mcuctl_write(is->sensor_index, is, MCUCTL_REG_ISSR(1));
- mcuctl_write(is->h2i_cmd.entry_id, is, MCUCTL_REG_ISSR(2));
-
- fimc_is_hw_set_intgr0_gd0(is);
- return 0;
-}
-
-#define FIMC_IS_MAX_PARAMS 4
-
-int fimc_is_hw_get_params(struct fimc_is *is, unsigned int num_args)
-{
- int i;
-
- if (num_args > FIMC_IS_MAX_PARAMS)
- return -EINVAL;
-
- is->i2h_cmd.num_args = num_args;
-
- for (i = 0; i < FIMC_IS_MAX_PARAMS; i++) {
- if (i < num_args)
- is->i2h_cmd.args[i] = mcuctl_read(is,
- MCUCTL_REG_ISSR(12 + i));
- else
- is->i2h_cmd.args[i] = 0;
- }
- return 0;
-}
-
-void fimc_is_hw_set_isp_buf_mask(struct fimc_is *is, unsigned int mask)
-{
- if (hweight32(mask) == 1) {
- dev_err(&is->pdev->dev, "%s(): not enough buffers (mask %#x)\n",
- __func__, mask);
- return;
- }
-
- if (mcuctl_read(is, MCUCTL_REG_ISSR(23)) != 0)
- dev_dbg(&is->pdev->dev, "non-zero DMA buffer mask\n");
-
- mcuctl_write(mask, is, MCUCTL_REG_ISSR(23));
-}
-
-void fimc_is_hw_set_sensor_num(struct fimc_is *is)
-{
- pr_debug("setting sensor index to: %d\n", is->sensor_index);
-
- mcuctl_write(IH_REPLY_DONE, is, MCUCTL_REG_ISSR(0));
- mcuctl_write(is->sensor_index, is, MCUCTL_REG_ISSR(1));
- mcuctl_write(IHC_GET_SENSOR_NUM, is, MCUCTL_REG_ISSR(2));
- mcuctl_write(FIMC_IS_SENSORS_NUM, is, MCUCTL_REG_ISSR(3));
-}
-
-void fimc_is_hw_close_sensor(struct fimc_is *is, unsigned int index)
-{
- if (is->sensor_index != index)
- return;
-
- fimc_is_hw_wait_intmsr0_intmsd0(is);
- mcuctl_write(HIC_CLOSE_SENSOR, is, MCUCTL_REG_ISSR(0));
- mcuctl_write(is->sensor_index, is, MCUCTL_REG_ISSR(1));
- mcuctl_write(is->sensor_index, is, MCUCTL_REG_ISSR(2));
- fimc_is_hw_set_intgr0_gd0(is);
-}
-
-void fimc_is_hw_get_setfile_addr(struct fimc_is *is)
-{
- fimc_is_hw_wait_intmsr0_intmsd0(is);
- mcuctl_write(HIC_GET_SET_FILE_ADDR, is, MCUCTL_REG_ISSR(0));
- mcuctl_write(is->sensor_index, is, MCUCTL_REG_ISSR(1));
- fimc_is_hw_set_intgr0_gd0(is);
-}
-
-void fimc_is_hw_load_setfile(struct fimc_is *is)
-{
- fimc_is_hw_wait_intmsr0_intmsd0(is);
- mcuctl_write(HIC_LOAD_SET_FILE, is, MCUCTL_REG_ISSR(0));
- mcuctl_write(is->sensor_index, is, MCUCTL_REG_ISSR(1));
- fimc_is_hw_set_intgr0_gd0(is);
-}
-
-int fimc_is_hw_change_mode(struct fimc_is *is)
-{
- static const u8 cmd[] = {
- HIC_PREVIEW_STILL, HIC_PREVIEW_VIDEO,
- HIC_CAPTURE_STILL, HIC_CAPTURE_VIDEO,
- };
-
- if (WARN_ON(is->config_index >= ARRAY_SIZE(cmd)))
- return -EINVAL;
-
- mcuctl_write(cmd[is->config_index], is, MCUCTL_REG_ISSR(0));
- mcuctl_write(is->sensor_index, is, MCUCTL_REG_ISSR(1));
- mcuctl_write(is->setfile.sub_index, is, MCUCTL_REG_ISSR(2));
- fimc_is_hw_set_intgr0_gd0(is);
- return 0;
-}
-
-void fimc_is_hw_stream_on(struct fimc_is *is)
-{
- fimc_is_hw_wait_intmsr0_intmsd0(is);
- mcuctl_write(HIC_STREAM_ON, is, MCUCTL_REG_ISSR(0));
- mcuctl_write(is->sensor_index, is, MCUCTL_REG_ISSR(1));
- mcuctl_write(0, is, MCUCTL_REG_ISSR(2));
- fimc_is_hw_set_intgr0_gd0(is);
-}
-
-void fimc_is_hw_stream_off(struct fimc_is *is)
-{
- fimc_is_hw_wait_intmsr0_intmsd0(is);
- mcuctl_write(HIC_STREAM_OFF, is, MCUCTL_REG_ISSR(0));
- mcuctl_write(is->sensor_index, is, MCUCTL_REG_ISSR(1));
- fimc_is_hw_set_intgr0_gd0(is);
-}
-
-void fimc_is_hw_subip_power_off(struct fimc_is *is)
-{
- fimc_is_hw_wait_intmsr0_intmsd0(is);
- mcuctl_write(HIC_POWER_DOWN, is, MCUCTL_REG_ISSR(0));
- mcuctl_write(is->sensor_index, is, MCUCTL_REG_ISSR(1));
- fimc_is_hw_set_intgr0_gd0(is);
-}
-
-int fimc_is_itf_s_param(struct fimc_is *is, bool update)
-{
- int ret;
-
- if (update)
- __is_hw_update_params(is);
-
- fimc_is_mem_barrier();
-
- clear_bit(IS_ST_BLOCK_CMD_CLEARED, &is->state);
- fimc_is_hw_set_param(is);
- ret = fimc_is_wait_event(is, IS_ST_BLOCK_CMD_CLEARED, 1,
- FIMC_IS_CONFIG_TIMEOUT);
- if (ret < 0)
- dev_err(&is->pdev->dev, "%s() timeout\n", __func__);
-
- return ret;
-}
-
-int fimc_is_itf_mode_change(struct fimc_is *is)
-{
- int ret;
-
- clear_bit(IS_ST_CHANGE_MODE, &is->state);
- fimc_is_hw_change_mode(is);
- ret = fimc_is_wait_event(is, IS_ST_CHANGE_MODE, 1,
- FIMC_IS_CONFIG_TIMEOUT);
- if (ret < 0)
- dev_err(&is->pdev->dev, "%s(): mode change (%d) timeout\n",
- __func__, is->config_index);
- return ret;
-}
diff --git a/drivers/media/platform/exynos4-is/fimc-is-regs.h b/drivers/media/platform/exynos4-is/fimc-is-regs.h
deleted file mode 100644
index 5d8b01bc84a2..000000000000
--- a/drivers/media/platform/exynos4-is/fimc-is-regs.h
+++ /dev/null
@@ -1,161 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-only */
-/*
- * Samsung EXYNOS4x12 FIMC-IS (Imaging Subsystem) driver
- *
- * Copyright (C) 2013 Samsung Electronics Co., Ltd.
- *
- * Authors: Sylwester Nawrocki <s.nawrocki@samsung.com>
- * Younghwan Joo <yhwan.joo@samsung.com>
- */
-#ifndef FIMC_IS_REG_H_
-#define FIMC_IS_REG_H_
-
-/* WDT_ISP register */
-#define REG_WDT_ISP 0x00170000
-
-/* MCUCTL registers base offset */
-#define MCUCTL_BASE 0x00180000
-
-/* MCU Controller Register */
-#define MCUCTL_REG_MCUCTRL (MCUCTL_BASE + 0x00)
-#define MCUCTRL_MSWRST (1 << 0)
-
-/* Boot Base Offset Address Register */
-#define MCUCTL_REG_BBOAR (MCUCTL_BASE + 0x04)
-
-/* Interrupt Generation Register 0 from Host CPU to VIC */
-#define MCUCTL_REG_INTGR0 (MCUCTL_BASE + 0x08)
-/* __n = 0...9 */
-#define INTGR0_INTGC(__n) (1 << ((__n) + 16))
-/* __n = 0...5 */
-#define INTGR0_INTGD(__n) (1 << (__n))
-
-/* Interrupt Clear Register 0 from Host CPU to VIC */
-#define MCUCTL_REG_INTCR0 (MCUCTL_BASE + 0x0c)
-/* __n = 0...9 */
-#define INTCR0_INTGC(__n) (1 << ((__n) + 16))
-/* __n = 0...5 */
-#define INTCR0_INTCD(__n) (1 << ((__n) + 16))
-
-/* Interrupt Mask Register 0 from Host CPU to VIC */
-#define MCUCTL_REG_INTMR0 (MCUCTL_BASE + 0x10)
-/* __n = 0...9 */
-#define INTMR0_INTMC(__n) (1 << ((__n) + 16))
-/* __n = 0...5 */
-#define INTMR0_INTMD(__n) (1 << (__n))
-
-/* Interrupt Status Register 0 from Host CPU to VIC */
-#define MCUCTL_REG_INTSR0 (MCUCTL_BASE + 0x14)
-/* __n (bit number) = 0...4 */
-#define INTSR0_GET_INTSD(x, __n) (((x) >> (__n)) & 0x1)
-/* __n (bit number) = 0...9 */
-#define INTSR0_GET_INTSC(x, __n) (((x) >> ((__n) + 16)) & 0x1)
-
-/* Interrupt Mask Status Register 0 from Host CPU to VIC */
-#define MCUCTL_REG_INTMSR0 (MCUCTL_BASE + 0x18)
-/* __n (bit number) = 0...4 */
-#define INTMSR0_GET_INTMSD(x, __n) (((x) >> (__n)) & 0x1)
-/* __n (bit number) = 0...9 */
-#define INTMSR0_GET_INTMSC(x, __n) (((x) >> ((__n) + 16)) & 0x1)
-
-/* Interrupt Generation Register 1 from ISP CPU to Host IC */
-#define MCUCTL_REG_INTGR1 (MCUCTL_BASE + 0x1c)
-/* __n = 0...9 */
-#define INTGR1_INTGC(__n) (1 << (__n))
-
-/* Interrupt Clear Register 1 from ISP CPU to Host IC */
-#define MCUCTL_REG_INTCR1 (MCUCTL_BASE + 0x20)
-/* __n = 0...9 */
-#define INTCR1_INTCC(__n) (1 << (__n))
-
-/* Interrupt Mask Register 1 from ISP CPU to Host IC */
-#define MCUCTL_REG_INTMR1 (MCUCTL_BASE + 0x24)
-/* __n = 0...9 */
-#define INTMR1_INTMC(__n) (1 << (__n))
-
-/* Interrupt Status Register 1 from ISP CPU to Host IC */
-#define MCUCTL_REG_INTSR1 (MCUCTL_BASE + 0x28)
-/* Interrupt Mask Status Register 1 from ISP CPU to Host IC */
-#define MCUCTL_REG_INTMSR1 (MCUCTL_BASE + 0x2c)
-
-/* Interrupt Clear Register 2 from ISP BLK's interrupts to Host IC */
-#define MCUCTL_REG_INTCR2 (MCUCTL_BASE + 0x30)
-/* __n = 0...5 */
-#define INTCR2_INTCC(__n) (1 << ((__n) + 16))
-
-/* Interrupt Mask Register 2 from ISP BLK's interrupts to Host IC */
-#define MCUCTL_REG_INTMR2 (MCUCTL_BASE + 0x34)
-/* __n = 0...25 */
-#define INTMR2_INTMCIS(__n) (1 << (__n))
-
-/* Interrupt Status Register 2 from ISP BLK's interrupts to Host IC */
-#define MCUCTL_REG_INTSR2 (MCUCTL_BASE + 0x38)
-/* Interrupt Mask Status Register 2 from ISP BLK's interrupts to Host IC */
-#define MCUCTL_REG_INTMSR2 (MCUCTL_BASE + 0x3c)
-
-/* General Purpose Output Control Register (0~17) */
-#define MCUCTL_REG_GPOCTLR (MCUCTL_BASE + 0x40)
-/* __n = 0...17 */
-#define GPOCTLR_GPOG(__n) (1 << (__n))
-
-/* General Purpose Pad Output Enable Register (0~17) */
-#define MCUCTL_REG_GPOENCTLR (MCUCTL_BASE + 0x44)
-/* __n = 0...17 */
-#define GPOENCTLR_GPOEN(__n) (1 << (__n))
-
-/* General Purpose Input Control Register (0~17) */
-#define MCUCTL_REG_GPICTLR (MCUCTL_BASE + 0x48)
-
-/* Shared registers between ISP CPU and the host CPU - ISSRxx */
-
-/* ISSR(1): Command Host -> IS */
-/* ISSR(1): Sensor ID for Command, ISSR2...5 = Parameter 1...4 */
-
-/* ISSR(10): Reply IS -> Host */
-/* ISSR(11): Sensor ID for Reply, ISSR12...15 = Parameter 1...4 */
-
-/* ISSR(20): ISP_FRAME_DONE : SENSOR ID */
-/* ISSR(21): ISP_FRAME_DONE : PARAMETER 1 */
-
-/* ISSR(24): SCALERC_FRAME_DONE : SENSOR ID */
-/* ISSR(25): SCALERC_FRAME_DONE : PARAMETER 1 */
-
-/* ISSR(28): 3DNR_FRAME_DONE : SENSOR ID */
-/* ISSR(29): 3DNR_FRAME_DONE : PARAMETER 1 */
-
-/* ISSR(32): SCALERP_FRAME_DONE : SENSOR ID */
-/* ISSR(33): SCALERP_FRAME_DONE : PARAMETER 1 */
-
-/* __n = 0...63 */
-#define MCUCTL_REG_ISSR(__n) (MCUCTL_BASE + 0x80 + ((__n) * 4))
-
-/* PMU ISP register offsets */
-#define REG_CMU_RESET_ISP_SYS_PWR_REG 0x1174
-#define REG_CMU_SYSCLK_ISP_SYS_PWR_REG 0x13b8
-#define REG_PMU_ISP_ARM_SYS 0x1050
-#define REG_PMU_ISP_ARM_CONFIGURATION 0x2280
-#define REG_PMU_ISP_ARM_STATUS 0x2284
-#define REG_PMU_ISP_ARM_OPTION 0x2288
-
-void fimc_is_fw_clear_irq1(struct fimc_is *is, unsigned int bit);
-void fimc_is_fw_clear_irq2(struct fimc_is *is);
-int fimc_is_hw_get_params(struct fimc_is *is, unsigned int num);
-
-void fimc_is_hw_set_intgr0_gd0(struct fimc_is *is);
-int fimc_is_hw_wait_intmsr0_intmsd0(struct fimc_is *is);
-void fimc_is_hw_set_sensor_num(struct fimc_is *is);
-void fimc_is_hw_set_isp_buf_mask(struct fimc_is *is, unsigned int mask);
-void fimc_is_hw_stream_on(struct fimc_is *is);
-void fimc_is_hw_stream_off(struct fimc_is *is);
-int fimc_is_hw_set_param(struct fimc_is *is);
-int fimc_is_hw_change_mode(struct fimc_is *is);
-
-void fimc_is_hw_close_sensor(struct fimc_is *is, unsigned int index);
-void fimc_is_hw_get_setfile_addr(struct fimc_is *is);
-void fimc_is_hw_load_setfile(struct fimc_is *is);
-void fimc_is_hw_subip_power_off(struct fimc_is *is);
-
-int fimc_is_itf_s_param(struct fimc_is *is, bool update);
-int fimc_is_itf_mode_change(struct fimc_is *is);
-
-#endif /* FIMC_IS_REG_H_ */
diff --git a/drivers/media/platform/exynos4-is/fimc-is-sensor.c b/drivers/media/platform/exynos4-is/fimc-is-sensor.c
deleted file mode 100644
index 0e5b9fede4ae..000000000000
--- a/drivers/media/platform/exynos4-is/fimc-is-sensor.c
+++ /dev/null
@@ -1,31 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-/*
- * Samsung EXYNOS4x12 FIMC-IS (Imaging Subsystem) driver
- *
- * Copyright (C) 2013 Samsung Electronics Co., Ltd.
- * Author: Sylwester Nawrocki <s.nawrocki@samsung.com>
- */
-
-#include "fimc-is-sensor.h"
-
-static const struct sensor_drv_data s5k6a3_drvdata = {
- .id = FIMC_IS_SENSOR_ID_S5K6A3,
- .open_timeout = S5K6A3_OPEN_TIMEOUT,
-};
-
-static const struct of_device_id fimc_is_sensor_of_ids[] = {
- {
- .compatible = "samsung,s5k6a3",
- .data = &s5k6a3_drvdata,
- },
- { }
-};
-
-const struct sensor_drv_data *fimc_is_sensor_get_drvdata(
- struct device_node *node)
-{
- const struct of_device_id *of_id;
-
- of_id = of_match_node(fimc_is_sensor_of_ids, node);
- return of_id ? of_id->data : NULL;
-}
diff --git a/drivers/media/platform/exynos4-is/fimc-is-sensor.h b/drivers/media/platform/exynos4-is/fimc-is-sensor.h
deleted file mode 100644
index 9aefc63889de..000000000000
--- a/drivers/media/platform/exynos4-is/fimc-is-sensor.h
+++ /dev/null
@@ -1,53 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-only */
-/*
- * Samsung EXYNOS4x12 FIMC-IS (Imaging Subsystem) driver
- *
- * Copyright (C) 2013 Samsung Electronics Co., Ltd.
- *
- * Authors: Sylwester Nawrocki <s.nawrocki@samsung.com>
- * Younghwan Joo <yhwan.joo@samsung.com>
- */
-#ifndef FIMC_IS_SENSOR_H_
-#define FIMC_IS_SENSOR_H_
-
-#include <linux/of.h>
-#include <linux/types.h>
-
-#define S5K6A3_OPEN_TIMEOUT 2000 /* ms */
-#define S5K6A3_SENSOR_WIDTH 1392
-#define S5K6A3_SENSOR_HEIGHT 1392
-
-enum fimc_is_sensor_id {
- FIMC_IS_SENSOR_ID_S5K3H2 = 1,
- FIMC_IS_SENSOR_ID_S5K6A3,
- FIMC_IS_SENSOR_ID_S5K4E5,
- FIMC_IS_SENSOR_ID_S5K3H7,
- FIMC_IS_SENSOR_ID_CUSTOM,
- FIMC_IS_SENSOR_ID_END
-};
-
-#define IS_SENSOR_CTRL_BUS_I2C0 0
-#define IS_SENSOR_CTRL_BUS_I2C1 1
-
-struct sensor_drv_data {
- enum fimc_is_sensor_id id;
- /* sensor open timeout in ms */
- unsigned short open_timeout;
-};
-
-/**
- * struct fimc_is_sensor - fimc-is sensor data structure
- * @drvdata: a pointer to the sensor's parameters data structure
- * @i2c_bus: ISP I2C bus index (0...1)
- * @test_pattern: true to enable video test pattern
- */
-struct fimc_is_sensor {
- const struct sensor_drv_data *drvdata;
- unsigned int i2c_bus;
- u8 test_pattern;
-};
-
-const struct sensor_drv_data *fimc_is_sensor_get_drvdata(
- struct device_node *node);
-
-#endif /* FIMC_IS_SENSOR_H_ */
diff --git a/drivers/media/platform/exynos4-is/fimc-is.c b/drivers/media/platform/exynos4-is/fimc-is.c
deleted file mode 100644
index e55e411038f4..000000000000
--- a/drivers/media/platform/exynos4-is/fimc-is.c
+++ /dev/null
@@ -1,986 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-/*
- * Samsung EXYNOS4x12 FIMC-IS (Imaging Subsystem) driver
- *
- * Copyright (C) 2013 Samsung Electronics Co., Ltd.
- *
- * Authors: Sylwester Nawrocki <s.nawrocki@samsung.com>
- * Younghwan Joo <yhwan.joo@samsung.com>
- */
-#define pr_fmt(fmt) "%s:%d " fmt, __func__, __LINE__
-
-#include <linux/device.h>
-#include <linux/debugfs.h>
-#include <linux/delay.h>
-#include <linux/errno.h>
-#include <linux/firmware.h>
-#include <linux/interrupt.h>
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/i2c.h>
-#include <linux/of_irq.h>
-#include <linux/of_address.h>
-#include <linux/of_graph.h>
-#include <linux/of_platform.h>
-#include <linux/platform_device.h>
-#include <linux/pm_runtime.h>
-#include <linux/slab.h>
-#include <linux/types.h>
-#include <linux/videodev2.h>
-#include <media/videobuf2-dma-contig.h>
-
-#include "media-dev.h"
-#include "fimc-is.h"
-#include "fimc-is-command.h"
-#include "fimc-is-errno.h"
-#include "fimc-is-i2c.h"
-#include "fimc-is-param.h"
-#include "fimc-is-regs.h"
-
-
-static char *fimc_is_clocks[ISS_CLKS_MAX] = {
- [ISS_CLK_PPMUISPX] = "ppmuispx",
- [ISS_CLK_PPMUISPMX] = "ppmuispmx",
- [ISS_CLK_LITE0] = "lite0",
- [ISS_CLK_LITE1] = "lite1",
- [ISS_CLK_MPLL] = "mpll",
- [ISS_CLK_ISP] = "isp",
- [ISS_CLK_DRC] = "drc",
- [ISS_CLK_FD] = "fd",
- [ISS_CLK_MCUISP] = "mcuisp",
- [ISS_CLK_GICISP] = "gicisp",
- [ISS_CLK_PWM_ISP] = "pwm_isp",
- [ISS_CLK_MCUCTL_ISP] = "mcuctl_isp",
- [ISS_CLK_UART] = "uart",
- [ISS_CLK_ISP_DIV0] = "ispdiv0",
- [ISS_CLK_ISP_DIV1] = "ispdiv1",
- [ISS_CLK_MCUISP_DIV0] = "mcuispdiv0",
- [ISS_CLK_MCUISP_DIV1] = "mcuispdiv1",
- [ISS_CLK_ACLK200] = "aclk200",
- [ISS_CLK_ACLK200_DIV] = "div_aclk200",
- [ISS_CLK_ACLK400MCUISP] = "aclk400mcuisp",
- [ISS_CLK_ACLK400MCUISP_DIV] = "div_aclk400mcuisp",
-};
-
-static void fimc_is_put_clocks(struct fimc_is *is)
-{
- int i;
-
- for (i = 0; i < ISS_CLKS_MAX; i++) {
- if (IS_ERR(is->clocks[i]))
- continue;
- clk_put(is->clocks[i]);
- is->clocks[i] = ERR_PTR(-EINVAL);
- }
-}
-
-static int fimc_is_get_clocks(struct fimc_is *is)
-{
- int i, ret;
-
- for (i = 0; i < ISS_CLKS_MAX; i++)
- is->clocks[i] = ERR_PTR(-EINVAL);
-
- for (i = 0; i < ISS_CLKS_MAX; i++) {
- is->clocks[i] = clk_get(&is->pdev->dev, fimc_is_clocks[i]);
- if (IS_ERR(is->clocks[i])) {
- ret = PTR_ERR(is->clocks[i]);
- goto err;
- }
- }
-
- return 0;
-err:
- fimc_is_put_clocks(is);
- dev_err(&is->pdev->dev, "failed to get clock: %s\n",
- fimc_is_clocks[i]);
- return ret;
-}
-
-static int fimc_is_setup_clocks(struct fimc_is *is)
-{
- int ret;
-
- ret = clk_set_parent(is->clocks[ISS_CLK_ACLK200],
- is->clocks[ISS_CLK_ACLK200_DIV]);
- if (ret < 0)
- return ret;
-
- ret = clk_set_parent(is->clocks[ISS_CLK_ACLK400MCUISP],
- is->clocks[ISS_CLK_ACLK400MCUISP_DIV]);
- if (ret < 0)
- return ret;
-
- ret = clk_set_rate(is->clocks[ISS_CLK_ISP_DIV0], ACLK_AXI_FREQUENCY);
- if (ret < 0)
- return ret;
-
- ret = clk_set_rate(is->clocks[ISS_CLK_ISP_DIV1], ACLK_AXI_FREQUENCY);
- if (ret < 0)
- return ret;
-
- ret = clk_set_rate(is->clocks[ISS_CLK_MCUISP_DIV0],
- ATCLK_MCUISP_FREQUENCY);
- if (ret < 0)
- return ret;
-
- return clk_set_rate(is->clocks[ISS_CLK_MCUISP_DIV1],
- ATCLK_MCUISP_FREQUENCY);
-}
-
-static int fimc_is_enable_clocks(struct fimc_is *is)
-{
- int i, ret;
-
- for (i = 0; i < ISS_GATE_CLKS_MAX; i++) {
- if (IS_ERR(is->clocks[i]))
- continue;
- ret = clk_prepare_enable(is->clocks[i]);
- if (ret < 0) {
- dev_err(&is->pdev->dev, "clock %s enable failed\n",
- fimc_is_clocks[i]);
- for (--i; i >= 0; i--)
- clk_disable(is->clocks[i]);
- return ret;
- }
- pr_debug("enabled clock: %s\n", fimc_is_clocks[i]);
- }
- return 0;
-}
-
-static void fimc_is_disable_clocks(struct fimc_is *is)
-{
- int i;
-
- for (i = 0; i < ISS_GATE_CLKS_MAX; i++) {
- if (!IS_ERR(is->clocks[i])) {
- clk_disable_unprepare(is->clocks[i]);
- pr_debug("disabled clock: %s\n", fimc_is_clocks[i]);
- }
- }
-}
-
-static int fimc_is_parse_sensor_config(struct fimc_is *is, unsigned int index,
- struct device_node *node)
-{
- struct fimc_is_sensor *sensor = &is->sensor[index];
- struct device_node *ep, *port;
- u32 tmp = 0;
- int ret;
-
- sensor->drvdata = fimc_is_sensor_get_drvdata(node);
- if (!sensor->drvdata) {
- dev_err(&is->pdev->dev, "no driver data found for: %pOF\n",
- node);
- return -EINVAL;
- }
-
- ep = of_graph_get_next_endpoint(node, NULL);
- if (!ep)
- return -ENXIO;
-
- port = of_graph_get_remote_port(ep);
- of_node_put(ep);
- if (!port)
- return -ENXIO;
-
- /* Use MIPI-CSIS channel id to determine the ISP I2C bus index. */
- ret = of_property_read_u32(port, "reg", &tmp);
- if (ret < 0) {
- dev_err(&is->pdev->dev, "reg property not found at: %pOF\n",
- port);
- of_node_put(port);
- return ret;
- }
-
- of_node_put(port);
- sensor->i2c_bus = tmp - FIMC_INPUT_MIPI_CSI2_0;
- return 0;
-}
-
-static int fimc_is_register_subdevs(struct fimc_is *is)
-{
- struct device_node *i2c_bus, *child;
- int ret, index = 0;
-
- ret = fimc_isp_subdev_create(&is->isp);
- if (ret < 0)
- return ret;
-
- for_each_compatible_node(i2c_bus, NULL, FIMC_IS_I2C_COMPATIBLE) {
- for_each_available_child_of_node(i2c_bus, child) {
- ret = fimc_is_parse_sensor_config(is, index, child);
-
- if (ret < 0 || index >= FIMC_IS_SENSORS_NUM) {
- of_node_put(child);
- return ret;
- }
- index++;
- }
- }
- return 0;
-}
-
-static int fimc_is_unregister_subdevs(struct fimc_is *is)
-{
- fimc_isp_subdev_destroy(&is->isp);
- return 0;
-}
-
-static int fimc_is_load_setfile(struct fimc_is *is, char *file_name)
-{
- const struct firmware *fw;
- void *buf;
- int ret;
-
- ret = request_firmware(&fw, file_name, &is->pdev->dev);
- if (ret < 0) {
- dev_err(&is->pdev->dev, "firmware request failed (%d)\n", ret);
- return ret;
- }
- buf = is->memory.vaddr + is->setfile.base;
- memcpy(buf, fw->data, fw->size);
- fimc_is_mem_barrier();
- is->setfile.size = fw->size;
-
- pr_debug("mem vaddr: %p, setfile buf: %p\n", is->memory.vaddr, buf);
-
- memcpy(is->fw.setfile_info,
- fw->data + fw->size - FIMC_IS_SETFILE_INFO_LEN,
- FIMC_IS_SETFILE_INFO_LEN - 1);
-
- is->fw.setfile_info[FIMC_IS_SETFILE_INFO_LEN - 1] = '\0';
- is->setfile.state = 1;
-
- pr_debug("FIMC-IS setfile loaded: base: %#x, size: %zu B\n",
- is->setfile.base, fw->size);
-
- release_firmware(fw);
- return ret;
-}
-
-int fimc_is_cpu_set_power(struct fimc_is *is, int on)
-{
- unsigned int timeout = FIMC_IS_POWER_ON_TIMEOUT;
-
- if (on) {
- /* Disable watchdog */
- mcuctl_write(0, is, REG_WDT_ISP);
-
- /* Cortex-A5 start address setting */
- mcuctl_write(is->memory.addr, is, MCUCTL_REG_BBOAR);
-
- /* Enable and start Cortex-A5 */
- pmuisp_write(0x18000, is, REG_PMU_ISP_ARM_OPTION);
- pmuisp_write(0x1, is, REG_PMU_ISP_ARM_CONFIGURATION);
- } else {
- /* A5 power off */
- pmuisp_write(0x10000, is, REG_PMU_ISP_ARM_OPTION);
- pmuisp_write(0x0, is, REG_PMU_ISP_ARM_CONFIGURATION);
-
- while (pmuisp_read(is, REG_PMU_ISP_ARM_STATUS) & 1) {
- if (timeout == 0)
- return -ETIME;
- timeout--;
- udelay(1);
- }
- }
-
- return 0;
-}
-
-/* Wait until @bit of @is->state is set to @state in the interrupt handler. */
-int fimc_is_wait_event(struct fimc_is *is, unsigned long bit,
- unsigned int state, unsigned int timeout)
-{
-
- int ret = wait_event_timeout(is->irq_queue,
- !state ^ test_bit(bit, &is->state),
- timeout);
- if (ret == 0) {
- dev_WARN(&is->pdev->dev, "%s() timed out\n", __func__);
- return -ETIME;
- }
- return 0;
-}
-
-int fimc_is_start_firmware(struct fimc_is *is)
-{
- struct device *dev = &is->pdev->dev;
- int ret;
-
- if (is->fw.f_w == NULL) {
- dev_err(dev, "firmware is not loaded\n");
- return -EINVAL;
- }
-
- memcpy(is->memory.vaddr, is->fw.f_w->data, is->fw.f_w->size);
- wmb();
-
- ret = fimc_is_cpu_set_power(is, 1);
- if (ret < 0)
- return ret;
-
- ret = fimc_is_wait_event(is, IS_ST_A5_PWR_ON, 1,
- msecs_to_jiffies(FIMC_IS_FW_LOAD_TIMEOUT));
- if (ret < 0)
- dev_err(dev, "FIMC-IS CPU power on failed\n");
-
- return ret;
-}
-
-/* Allocate working memory for the FIMC-IS CPU. */
-static int fimc_is_alloc_cpu_memory(struct fimc_is *is)
-{
- struct device *dev = &is->pdev->dev;
-
- is->memory.vaddr = dma_alloc_coherent(dev, FIMC_IS_CPU_MEM_SIZE,
- &is->memory.addr, GFP_KERNEL);
- if (is->memory.vaddr == NULL)
- return -ENOMEM;
-
- is->memory.size = FIMC_IS_CPU_MEM_SIZE;
-
- dev_info(dev, "FIMC-IS CPU memory base: %pad\n", &is->memory.addr);
-
- if (((u32)is->memory.addr) & FIMC_IS_FW_ADDR_MASK) {
- dev_err(dev, "invalid firmware memory alignment: %#x\n",
- (u32)is->memory.addr);
- dma_free_coherent(dev, is->memory.size, is->memory.vaddr,
- is->memory.addr);
- return -EIO;
- }
-
- is->is_p_region = (struct is_region *)(is->memory.vaddr +
- FIMC_IS_CPU_MEM_SIZE - FIMC_IS_REGION_SIZE);
-
- is->is_dma_p_region = is->memory.addr +
- FIMC_IS_CPU_MEM_SIZE - FIMC_IS_REGION_SIZE;
-
- is->is_shared_region = (struct is_share_region *)(is->memory.vaddr +
- FIMC_IS_SHARED_REGION_OFFSET);
- return 0;
-}
-
-static void fimc_is_free_cpu_memory(struct fimc_is *is)
-{
- struct device *dev = &is->pdev->dev;
-
- if (is->memory.vaddr == NULL)
- return;
-
- dma_free_coherent(dev, is->memory.size, is->memory.vaddr,
- is->memory.addr);
-}
-
-static void fimc_is_load_firmware(const struct firmware *fw, void *context)
-{
- struct fimc_is *is = context;
- struct device *dev = &is->pdev->dev;
- void *buf;
- int ret;
-
- if (fw == NULL) {
- dev_err(dev, "firmware request failed\n");
- return;
- }
- mutex_lock(&is->lock);
-
- if (fw->size < FIMC_IS_FW_SIZE_MIN || fw->size > FIMC_IS_FW_SIZE_MAX) {
- dev_err(dev, "wrong firmware size: %zu\n", fw->size);
- goto done;
- }
-
- is->fw.size = fw->size;
-
- ret = fimc_is_alloc_cpu_memory(is);
- if (ret < 0) {
- dev_err(dev, "failed to allocate FIMC-IS CPU memory\n");
- goto done;
- }
-
- memcpy(is->memory.vaddr, fw->data, fw->size);
- wmb();
-
- /* Read firmware description. */
- buf = (void *)(is->memory.vaddr + fw->size - FIMC_IS_FW_DESC_LEN);
- memcpy(&is->fw.info, buf, FIMC_IS_FW_INFO_LEN);
- is->fw.info[FIMC_IS_FW_INFO_LEN] = 0;
-
- buf = (void *)(is->memory.vaddr + fw->size - FIMC_IS_FW_VER_LEN);
- memcpy(&is->fw.version, buf, FIMC_IS_FW_VER_LEN);
- is->fw.version[FIMC_IS_FW_VER_LEN - 1] = 0;
-
- is->fw.state = 1;
-
- dev_info(dev, "loaded firmware: %s, rev. %s\n",
- is->fw.info, is->fw.version);
- dev_dbg(dev, "FW size: %zu, DMA addr: %pad\n", fw->size, &is->memory.addr);
-
- is->is_shared_region->chip_id = 0xe4412;
- is->is_shared_region->chip_rev_no = 1;
-
- fimc_is_mem_barrier();
-
- /*
- * FIXME: The firmware is not being released for now, as it is
- * needed around for copying to the IS working memory every
- * time before the Cortex-A5 is restarted.
- */
- release_firmware(is->fw.f_w);
- is->fw.f_w = fw;
-done:
- mutex_unlock(&is->lock);
-}
-
-static int fimc_is_request_firmware(struct fimc_is *is, const char *fw_name)
-{
- return request_firmware_nowait(THIS_MODULE,
- FW_ACTION_UEVENT, fw_name, &is->pdev->dev,
- GFP_KERNEL, is, fimc_is_load_firmware);
-}
-
-/* General IS interrupt handler */
-static void fimc_is_general_irq_handler(struct fimc_is *is)
-{
- is->i2h_cmd.cmd = mcuctl_read(is, MCUCTL_REG_ISSR(10));
-
- switch (is->i2h_cmd.cmd) {
- case IHC_GET_SENSOR_NUM:
- fimc_is_hw_get_params(is, 1);
- fimc_is_hw_wait_intmsr0_intmsd0(is);
- fimc_is_hw_set_sensor_num(is);
- pr_debug("ISP FW version: %#x\n", is->i2h_cmd.args[0]);
- break;
- case IHC_SET_FACE_MARK:
- case IHC_FRAME_DONE:
- fimc_is_hw_get_params(is, 2);
- break;
- case IHC_SET_SHOT_MARK:
- case IHC_AA_DONE:
- case IH_REPLY_DONE:
- fimc_is_hw_get_params(is, 3);
- break;
- case IH_REPLY_NOT_DONE:
- fimc_is_hw_get_params(is, 4);
- break;
- case IHC_NOT_READY:
- break;
- default:
- pr_info("unknown command: %#x\n", is->i2h_cmd.cmd);
- }
-
- fimc_is_fw_clear_irq1(is, FIMC_IS_INT_GENERAL);
-
- switch (is->i2h_cmd.cmd) {
- case IHC_GET_SENSOR_NUM:
- fimc_is_hw_set_intgr0_gd0(is);
- set_bit(IS_ST_A5_PWR_ON, &is->state);
- break;
-
- case IHC_SET_SHOT_MARK:
- break;
-
- case IHC_SET_FACE_MARK:
- is->fd_header.count = is->i2h_cmd.args[0];
- is->fd_header.index = is->i2h_cmd.args[1];
- is->fd_header.offset = 0;
- break;
-
- case IHC_FRAME_DONE:
- break;
-
- case IHC_AA_DONE:
- pr_debug("AA_DONE - %d, %d, %d\n", is->i2h_cmd.args[0],
- is->i2h_cmd.args[1], is->i2h_cmd.args[2]);
- break;
-
- case IH_REPLY_DONE:
- pr_debug("ISR_DONE: args[0]: %#x\n", is->i2h_cmd.args[0]);
-
- switch (is->i2h_cmd.args[0]) {
- case HIC_PREVIEW_STILL...HIC_CAPTURE_VIDEO:
- /* Get CAC margin */
- set_bit(IS_ST_CHANGE_MODE, &is->state);
- is->isp.cac_margin_x = is->i2h_cmd.args[1];
- is->isp.cac_margin_y = is->i2h_cmd.args[2];
- pr_debug("CAC margin (x,y): (%d,%d)\n",
- is->isp.cac_margin_x, is->isp.cac_margin_y);
- break;
-
- case HIC_STREAM_ON:
- clear_bit(IS_ST_STREAM_OFF, &is->state);
- set_bit(IS_ST_STREAM_ON, &is->state);
- break;
-
- case HIC_STREAM_OFF:
- clear_bit(IS_ST_STREAM_ON, &is->state);
- set_bit(IS_ST_STREAM_OFF, &is->state);
- break;
-
- case HIC_SET_PARAMETER:
- is->config[is->config_index].p_region_index[0] = 0;
- is->config[is->config_index].p_region_index[1] = 0;
- set_bit(IS_ST_BLOCK_CMD_CLEARED, &is->state);
- pr_debug("HIC_SET_PARAMETER\n");
- break;
-
- case HIC_GET_PARAMETER:
- break;
-
- case HIC_SET_TUNE:
- break;
-
- case HIC_GET_STATUS:
- break;
-
- case HIC_OPEN_SENSOR:
- set_bit(IS_ST_OPEN_SENSOR, &is->state);
- pr_debug("data lanes: %d, settle line: %d\n",
- is->i2h_cmd.args[2], is->i2h_cmd.args[1]);
- break;
-
- case HIC_CLOSE_SENSOR:
- clear_bit(IS_ST_OPEN_SENSOR, &is->state);
- is->sensor_index = 0;
- break;
-
- case HIC_MSG_TEST:
- pr_debug("config MSG level completed\n");
- break;
-
- case HIC_POWER_DOWN:
- clear_bit(IS_ST_PWR_SUBIP_ON, &is->state);
- break;
-
- case HIC_GET_SET_FILE_ADDR:
- is->setfile.base = is->i2h_cmd.args[1];
- set_bit(IS_ST_SETFILE_LOADED, &is->state);
- break;
-
- case HIC_LOAD_SET_FILE:
- set_bit(IS_ST_SETFILE_LOADED, &is->state);
- break;
- }
- break;
-
- case IH_REPLY_NOT_DONE:
- pr_err("ISR_NDONE: %d: %#x, %s\n", is->i2h_cmd.args[0],
- is->i2h_cmd.args[1],
- fimc_is_strerr(is->i2h_cmd.args[1]));
-
- if (is->i2h_cmd.args[1] & IS_ERROR_TIME_OUT_FLAG)
- pr_err("IS_ERROR_TIME_OUT\n");
-
- switch (is->i2h_cmd.args[1]) {
- case IS_ERROR_SET_PARAMETER:
- fimc_is_mem_barrier();
- }
-
- switch (is->i2h_cmd.args[0]) {
- case HIC_SET_PARAMETER:
- is->config[is->config_index].p_region_index[0] = 0;
- is->config[is->config_index].p_region_index[1] = 0;
- set_bit(IS_ST_BLOCK_CMD_CLEARED, &is->state);
- break;
- }
- break;
-
- case IHC_NOT_READY:
- pr_err("IS control sequence error: Not Ready\n");
- break;
- }
-
- wake_up(&is->irq_queue);
-}
-
-static irqreturn_t fimc_is_irq_handler(int irq, void *priv)
-{
- struct fimc_is *is = priv;
- unsigned long flags;
- u32 status;
-
- spin_lock_irqsave(&is->slock, flags);
- status = mcuctl_read(is, MCUCTL_REG_INTSR1);
-
- if (status & (1UL << FIMC_IS_INT_GENERAL))
- fimc_is_general_irq_handler(is);
-
- if (status & (1UL << FIMC_IS_INT_FRAME_DONE_ISP))
- fimc_isp_irq_handler(is);
-
- spin_unlock_irqrestore(&is->slock, flags);
- return IRQ_HANDLED;
-}
-
-static int fimc_is_hw_open_sensor(struct fimc_is *is,
- struct fimc_is_sensor *sensor)
-{
- struct sensor_open_extended *soe = (void *)&is->is_p_region->shared;
-
- fimc_is_hw_wait_intmsr0_intmsd0(is);
-
- soe->self_calibration_mode = 1;
- soe->actuator_type = 0;
- soe->mipi_lane_num = 0;
- soe->mclk = 0;
- soe->mipi_speed = 0;
- soe->fast_open_sensor = 0;
- soe->i2c_sclk = 88000000;
-
- fimc_is_mem_barrier();
-
- /*
- * Some user space use cases hang up here without this
- * empirically chosen delay.
- */
- udelay(100);
-
- mcuctl_write(HIC_OPEN_SENSOR, is, MCUCTL_REG_ISSR(0));
- mcuctl_write(is->sensor_index, is, MCUCTL_REG_ISSR(1));
- mcuctl_write(sensor->drvdata->id, is, MCUCTL_REG_ISSR(2));
- mcuctl_write(sensor->i2c_bus, is, MCUCTL_REG_ISSR(3));
- mcuctl_write(is->is_dma_p_region, is, MCUCTL_REG_ISSR(4));
-
- fimc_is_hw_set_intgr0_gd0(is);
-
- return fimc_is_wait_event(is, IS_ST_OPEN_SENSOR, 1,
- sensor->drvdata->open_timeout);
-}
-
-
-int fimc_is_hw_initialize(struct fimc_is *is)
-{
- static const int config_ids[] = {
- IS_SC_PREVIEW_STILL, IS_SC_PREVIEW_VIDEO,
- IS_SC_CAPTURE_STILL, IS_SC_CAPTURE_VIDEO
- };
- struct device *dev = &is->pdev->dev;
- u32 prev_id;
- int i, ret;
-
- /* Sensor initialization. Only one sensor is currently supported. */
- ret = fimc_is_hw_open_sensor(is, &is->sensor[0]);
- if (ret < 0)
- return ret;
-
- /* Get the setfile address. */
- fimc_is_hw_get_setfile_addr(is);
-
- ret = fimc_is_wait_event(is, IS_ST_SETFILE_LOADED, 1,
- FIMC_IS_CONFIG_TIMEOUT);
- if (ret < 0) {
- dev_err(dev, "get setfile address timed out\n");
- return ret;
- }
- pr_debug("setfile.base: %#x\n", is->setfile.base);
-
- /* Load the setfile. */
- fimc_is_load_setfile(is, FIMC_IS_SETFILE_6A3);
- clear_bit(IS_ST_SETFILE_LOADED, &is->state);
- fimc_is_hw_load_setfile(is);
- ret = fimc_is_wait_event(is, IS_ST_SETFILE_LOADED, 1,
- FIMC_IS_CONFIG_TIMEOUT);
- if (ret < 0) {
- dev_err(dev, "loading setfile timed out\n");
- return ret;
- }
-
- pr_debug("setfile: base: %#x, size: %d\n",
- is->setfile.base, is->setfile.size);
- pr_info("FIMC-IS Setfile info: %s\n", is->fw.setfile_info);
-
- /* Check magic number. */
- if (is->is_p_region->shared[MAX_SHARED_COUNT - 1] !=
- FIMC_IS_MAGIC_NUMBER) {
- dev_err(dev, "magic number error!\n");
- return -EIO;
- }
-
- pr_debug("shared region: %pad, parameter region: %pad\n",
- &is->memory.addr + FIMC_IS_SHARED_REGION_OFFSET,
- &is->is_dma_p_region);
-
- is->setfile.sub_index = 0;
-
- /* Stream off. */
- fimc_is_hw_stream_off(is);
- ret = fimc_is_wait_event(is, IS_ST_STREAM_OFF, 1,
- FIMC_IS_CONFIG_TIMEOUT);
- if (ret < 0) {
- dev_err(dev, "stream off timeout\n");
- return ret;
- }
-
- /* Preserve previous mode. */
- prev_id = is->config_index;
-
- /* Set initial parameter values. */
- for (i = 0; i < ARRAY_SIZE(config_ids); i++) {
- is->config_index = config_ids[i];
- fimc_is_set_initial_params(is);
- ret = fimc_is_itf_s_param(is, true);
- if (ret < 0) {
- is->config_index = prev_id;
- return ret;
- }
- }
- is->config_index = prev_id;
-
- set_bit(IS_ST_INIT_DONE, &is->state);
- dev_info(dev, "initialization sequence completed (%d)\n",
- is->config_index);
- return 0;
-}
-
-static int fimc_is_show(struct seq_file *s, void *data)
-{
- struct fimc_is *is = s->private;
- const u8 *buf = is->memory.vaddr + FIMC_IS_DEBUG_REGION_OFFSET;
-
- if (is->memory.vaddr == NULL) {
- dev_err(&is->pdev->dev, "firmware memory is not initialized\n");
- return -EIO;
- }
-
- seq_printf(s, "%s\n", buf);
- return 0;
-}
-
-DEFINE_SHOW_ATTRIBUTE(fimc_is);
-
-static void fimc_is_debugfs_remove(struct fimc_is *is)
-{
- debugfs_remove_recursive(is->debugfs_entry);
- is->debugfs_entry = NULL;
-}
-
-static void fimc_is_debugfs_create(struct fimc_is *is)
-{
- is->debugfs_entry = debugfs_create_dir("fimc_is", NULL);
-
- debugfs_create_file("fw_log", S_IRUGO, is->debugfs_entry, is,
- &fimc_is_fops);
-}
-
-static int fimc_is_runtime_resume(struct device *dev);
-static int fimc_is_runtime_suspend(struct device *dev);
-
-static int fimc_is_probe(struct platform_device *pdev)
-{
- struct device *dev = &pdev->dev;
- struct fimc_is *is;
- struct resource res;
- struct device_node *node;
- int ret;
-
- is = devm_kzalloc(&pdev->dev, sizeof(*is), GFP_KERNEL);
- if (!is)
- return -ENOMEM;
-
- is->pdev = pdev;
- is->isp.pdev = pdev;
-
- init_waitqueue_head(&is->irq_queue);
- spin_lock_init(&is->slock);
- mutex_init(&is->lock);
-
- ret = of_address_to_resource(dev->of_node, 0, &res);
- if (ret < 0)
- return ret;
-
- is->regs = devm_ioremap_resource(dev, &res);
- if (IS_ERR(is->regs))
- return PTR_ERR(is->regs);
-
- node = of_get_child_by_name(dev->of_node, "pmu");
- if (!node)
- return -ENODEV;
-
- is->pmu_regs = of_iomap(node, 0);
- of_node_put(node);
- if (!is->pmu_regs)
- return -ENOMEM;
-
- is->irq = irq_of_parse_and_map(dev->of_node, 0);
- if (!is->irq) {
- dev_err(dev, "no irq found\n");
- ret = -EINVAL;
- goto err_iounmap;
- }
-
- ret = fimc_is_get_clocks(is);
- if (ret < 0)
- goto err_iounmap;
-
- platform_set_drvdata(pdev, is);
-
- ret = request_irq(is->irq, fimc_is_irq_handler, 0, dev_name(dev), is);
- if (ret < 0) {
- dev_err(dev, "irq request failed\n");
- goto err_clk;
- }
- pm_runtime_enable(dev);
-
- if (!pm_runtime_enabled(dev)) {
- ret = fimc_is_runtime_resume(dev);
- if (ret < 0)
- goto err_irq;
- }
-
- ret = pm_runtime_resume_and_get(dev);
- if (ret < 0)
- goto err_irq;
-
- vb2_dma_contig_set_max_seg_size(dev, DMA_BIT_MASK(32));
-
- ret = devm_of_platform_populate(dev);
- if (ret < 0)
- goto err_pm;
-
- /*
- * Register FIMC-IS V4L2 subdevs to this driver. The video nodes
- * will be created within the subdev's registered() callback.
- */
- ret = fimc_is_register_subdevs(is);
- if (ret < 0)
- goto err_pm;
-
- fimc_is_debugfs_create(is);
-
- ret = fimc_is_request_firmware(is, FIMC_IS_FW_FILENAME);
- if (ret < 0)
- goto err_dfs;
-
- pm_runtime_put_sync(dev);
-
- dev_dbg(dev, "FIMC-IS registered successfully\n");
- return 0;
-
-err_dfs:
- fimc_is_debugfs_remove(is);
- fimc_is_unregister_subdevs(is);
-err_pm:
- pm_runtime_put_noidle(dev);
- if (!pm_runtime_enabled(dev))
- fimc_is_runtime_suspend(dev);
-err_irq:
- free_irq(is->irq, is);
-err_clk:
- fimc_is_put_clocks(is);
-err_iounmap:
- iounmap(is->pmu_regs);
- return ret;
-}
-
-static int fimc_is_runtime_resume(struct device *dev)
-{
- struct fimc_is *is = dev_get_drvdata(dev);
- int ret;
-
- ret = fimc_is_setup_clocks(is);
- if (ret)
- return ret;
-
- return fimc_is_enable_clocks(is);
-}
-
-static int fimc_is_runtime_suspend(struct device *dev)
-{
- struct fimc_is *is = dev_get_drvdata(dev);
-
- fimc_is_disable_clocks(is);
- return 0;
-}
-
-#ifdef CONFIG_PM_SLEEP
-static int fimc_is_resume(struct device *dev)
-{
- /* TODO: */
- return 0;
-}
-
-static int fimc_is_suspend(struct device *dev)
-{
- struct fimc_is *is = dev_get_drvdata(dev);
-
- /* TODO: */
- if (test_bit(IS_ST_A5_PWR_ON, &is->state))
- return -EBUSY;
-
- return 0;
-}
-#endif /* CONFIG_PM_SLEEP */
-
-static int fimc_is_remove(struct platform_device *pdev)
-{
- struct device *dev = &pdev->dev;
- struct fimc_is *is = dev_get_drvdata(dev);
-
- pm_runtime_disable(dev);
- pm_runtime_set_suspended(dev);
- if (!pm_runtime_status_suspended(dev))
- fimc_is_runtime_suspend(dev);
- free_irq(is->irq, is);
- fimc_is_unregister_subdevs(is);
- vb2_dma_contig_clear_max_seg_size(dev);
- fimc_is_put_clocks(is);
- iounmap(is->pmu_regs);
- fimc_is_debugfs_remove(is);
- release_firmware(is->fw.f_w);
- fimc_is_free_cpu_memory(is);
-
- return 0;
-}
-
-static const struct of_device_id fimc_is_of_match[] = {
- { .compatible = "samsung,exynos4212-fimc-is" },
- { /* sentinel */ },
-};
-MODULE_DEVICE_TABLE(of, fimc_is_of_match);
-
-static const struct dev_pm_ops fimc_is_pm_ops = {
- SET_SYSTEM_SLEEP_PM_OPS(fimc_is_suspend, fimc_is_resume)
- SET_RUNTIME_PM_OPS(fimc_is_runtime_suspend, fimc_is_runtime_resume,
- NULL)
-};
-
-static struct platform_driver fimc_is_driver = {
- .probe = fimc_is_probe,
- .remove = fimc_is_remove,
- .driver = {
- .of_match_table = fimc_is_of_match,
- .name = FIMC_IS_DRV_NAME,
- .pm = &fimc_is_pm_ops,
- }
-};
-
-static int fimc_is_module_init(void)
-{
- int ret;
-
- ret = fimc_is_register_i2c_driver();
- if (ret < 0)
- return ret;
-
- ret = platform_driver_register(&fimc_is_driver);
-
- if (ret < 0)
- fimc_is_unregister_i2c_driver();
-
- return ret;
-}
-
-static void fimc_is_module_exit(void)
-{
- fimc_is_unregister_i2c_driver();
- platform_driver_unregister(&fimc_is_driver);
-}
-
-module_init(fimc_is_module_init);
-module_exit(fimc_is_module_exit);
-
-MODULE_ALIAS("platform:" FIMC_IS_DRV_NAME);
-MODULE_AUTHOR("Younghwan Joo <yhwan.joo@samsung.com>");
-MODULE_AUTHOR("Sylwester Nawrocki <s.nawrocki@samsung.com>");
-MODULE_LICENSE("GPL v2");
diff --git a/drivers/media/platform/exynos4-is/fimc-is.h b/drivers/media/platform/exynos4-is/fimc-is.h
deleted file mode 100644
index 06586e455b1d..000000000000
--- a/drivers/media/platform/exynos4-is/fimc-is.h
+++ /dev/null
@@ -1,359 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-only */
-/*
- * Samsung EXYNOS4x12 FIMC-IS (Imaging Subsystem) driver
- *
- * Copyright (C) 2013 Samsung Electronics Co., Ltd.
- *
- * Authors: Younghwan Joo <yhwan.joo@samsung.com>
- * Sylwester Nawrocki <s.nawrocki@samsung.com>
- */
-#ifndef FIMC_IS_H_
-#define FIMC_IS_H_
-
-#include <asm/barrier.h>
-#include <linux/clk.h>
-#include <linux/device.h>
-#include <linux/kernel.h>
-#include <linux/pinctrl/consumer.h>
-#include <linux/platform_device.h>
-#include <linux/sizes.h>
-#include <linux/spinlock.h>
-#include <linux/types.h>
-#include <media/videobuf2-v4l2.h>
-#include <media/v4l2-ctrls.h>
-
-#include "fimc-isp.h"
-#include "fimc-is-command.h"
-#include "fimc-is-sensor.h"
-#include "fimc-is-param.h"
-#include "fimc-is-regs.h"
-
-#define FIMC_IS_DRV_NAME "exynos4-fimc-is"
-
-#define FIMC_IS_FW_FILENAME "exynos4_fimc_is_fw.bin"
-#define FIMC_IS_SETFILE_6A3 "exynos4_s5k6a3_setfile.bin"
-
-#define FIMC_IS_FW_LOAD_TIMEOUT 1000 /* ms */
-#define FIMC_IS_POWER_ON_TIMEOUT 1000 /* us */
-
-#define FIMC_IS_SENSORS_NUM 2
-
-/* Memory definitions */
-#define FIMC_IS_CPU_MEM_SIZE (0xa00000)
-#define FIMC_IS_CPU_BASE_MASK ((1 << 26) - 1)
-#define FIMC_IS_REGION_SIZE 0x5000
-
-#define FIMC_IS_DEBUG_REGION_OFFSET 0x0084b000
-#define FIMC_IS_SHARED_REGION_OFFSET 0x008c0000
-#define FIMC_IS_FW_INFO_LEN 31
-#define FIMC_IS_FW_VER_LEN 7
-#define FIMC_IS_FW_DESC_LEN (FIMC_IS_FW_INFO_LEN + \
- FIMC_IS_FW_VER_LEN)
-#define FIMC_IS_SETFILE_INFO_LEN 39
-
-#define FIMC_IS_EXTRA_MEM_SIZE (FIMC_IS_EXTRA_FW_SIZE + \
- FIMC_IS_EXTRA_SETFILE_SIZE + 0x1000)
-#define FIMC_IS_EXTRA_FW_SIZE 0x180000
-#define FIMC_IS_EXTRA_SETFILE_SIZE 0x4b000
-
-/* TODO: revisit */
-#define FIMC_IS_FW_ADDR_MASK ((1 << 26) - 1)
-#define FIMC_IS_FW_SIZE_MAX (SZ_4M)
-#define FIMC_IS_FW_SIZE_MIN (SZ_32K)
-
-#define ATCLK_MCUISP_FREQUENCY 100000000UL
-#define ACLK_AXI_FREQUENCY 100000000UL
-
-enum {
- ISS_CLK_PPMUISPX,
- ISS_CLK_PPMUISPMX,
- ISS_CLK_LITE0,
- ISS_CLK_LITE1,
- ISS_CLK_MPLL,
- ISS_CLK_ISP,
- ISS_CLK_DRC,
- ISS_CLK_FD,
- ISS_CLK_MCUISP,
- ISS_CLK_GICISP,
- ISS_CLK_PWM_ISP,
- ISS_CLK_MCUCTL_ISP,
- ISS_CLK_UART,
- ISS_GATE_CLKS_MAX,
- ISS_CLK_ISP_DIV0 = ISS_GATE_CLKS_MAX,
- ISS_CLK_ISP_DIV1,
- ISS_CLK_MCUISP_DIV0,
- ISS_CLK_MCUISP_DIV1,
- ISS_CLK_ACLK200,
- ISS_CLK_ACLK200_DIV,
- ISS_CLK_ACLK400MCUISP,
- ISS_CLK_ACLK400MCUISP_DIV,
- ISS_CLKS_MAX
-};
-
-/* The driver's internal state flags */
-enum {
- IS_ST_IDLE,
- IS_ST_PWR_ON,
- IS_ST_A5_PWR_ON,
- IS_ST_FW_LOADED,
- IS_ST_OPEN_SENSOR,
- IS_ST_SETFILE_LOADED,
- IS_ST_INIT_DONE,
- IS_ST_STREAM_ON,
- IS_ST_STREAM_OFF,
- IS_ST_CHANGE_MODE,
- IS_ST_BLOCK_CMD_CLEARED,
- IS_ST_SET_ZOOM,
- IS_ST_PWR_SUBIP_ON,
- IS_ST_END,
-};
-
-enum af_state {
- FIMC_IS_AF_IDLE = 0,
- FIMC_IS_AF_SETCONFIG = 1,
- FIMC_IS_AF_RUNNING = 2,
- FIMC_IS_AF_LOCK = 3,
- FIMC_IS_AF_ABORT = 4,
- FIMC_IS_AF_FAILED = 5,
-};
-
-enum af_lock_state {
- FIMC_IS_AF_UNLOCKED = 0,
- FIMC_IS_AF_LOCKED = 2
-};
-
-enum ae_lock_state {
- FIMC_IS_AE_UNLOCKED = 0,
- FIMC_IS_AE_LOCKED = 1
-};
-
-enum awb_lock_state {
- FIMC_IS_AWB_UNLOCKED = 0,
- FIMC_IS_AWB_LOCKED = 1
-};
-
-enum {
- IS_METERING_CONFIG_CMD,
- IS_METERING_CONFIG_WIN_POS_X,
- IS_METERING_CONFIG_WIN_POS_Y,
- IS_METERING_CONFIG_WIN_WIDTH,
- IS_METERING_CONFIG_WIN_HEIGHT,
- IS_METERING_CONFIG_MAX
-};
-
-struct is_setfile {
- const struct firmware *info;
- int state;
- u32 sub_index;
- u32 base;
- size_t size;
-};
-
-struct is_fd_result_header {
- u32 offset;
- u32 count;
- u32 index;
- u32 curr_index;
- u32 width;
- u32 height;
-};
-
-struct is_af_info {
- u16 mode;
- u32 af_state;
- u32 af_lock_state;
- u32 ae_lock_state;
- u32 awb_lock_state;
- u16 pos_x;
- u16 pos_y;
- u16 prev_pos_x;
- u16 prev_pos_y;
- u16 use_af;
-};
-
-struct fimc_is_firmware {
- const struct firmware *f_w;
-
- dma_addr_t addr;
- void *vaddr;
- unsigned int size;
-
- char info[FIMC_IS_FW_INFO_LEN + 1];
- char version[FIMC_IS_FW_VER_LEN + 1];
- char setfile_info[FIMC_IS_SETFILE_INFO_LEN + 1];
- u8 state;
-};
-
-struct fimc_is_memory {
- /* DMA base address */
- dma_addr_t addr;
- /* virtual base address */
- void *vaddr;
- /* total length */
- unsigned int size;
-};
-
-#define FIMC_IS_I2H_MAX_ARGS 12
-
-struct i2h_cmd {
- u32 cmd;
- u32 sensor_id;
- u16 num_args;
- u32 args[FIMC_IS_I2H_MAX_ARGS];
-};
-
-struct h2i_cmd {
- u16 cmd_type;
- u32 entry_id;
-};
-
-#define FIMC_IS_DEBUG_MSG 0x3f
-#define FIMC_IS_DEBUG_LEVEL 3
-
-struct fimc_is_setfile {
- const struct firmware *info;
- unsigned int state;
- unsigned int size;
- u32 sub_index;
- u32 base;
-};
-
-struct chain_config {
- struct global_param global;
- struct sensor_param sensor;
- struct isp_param isp;
- struct drc_param drc;
- struct fd_param fd;
-
- unsigned long p_region_index[2];
-};
-
-/**
- * struct fimc_is - fimc-is data structure
- * @pdev: pointer to FIMC-IS platform device
- * @pctrl: pointer to pinctrl structure for this device
- * @v4l2_dev: pointer to the top level v4l2_device
- * @fw: data structure describing the FIMC-IS firmware binary
- * @memory: memory region assigned for the FIMC-IS (firmware)
- * @isp: the ISP block data structure
- * @sensor: fimc-is sensor subdevice array
- * @setfile: descriptor of the imaging pipeline calibration data
- * @ctrl_handler: the v4l2 controls handler
- * @lock: mutex serializing video device and the subdev operations
- * @slock: spinlock protecting this data structure and the hw registers
- * @clocks: FIMC-LITE gate clock
- * @regs: MCUCTL mmapped registers region
- * @pmu_regs: PMU ISP mmapped registers region
- * @irq: FIMC-IS interrupt
- * @irq_queue: interrupt handling waitqueue
- * @lpm: low power mode flag
- * @state: internal driver's state flags
- * @sensor_index: image sensor index for the firmware
- * @i2h_cmd: FIMC-IS to the host (CPU) mailbox command data structure
- * @h2i_cmd: the host (CPU) to FIMC-IS mailbox command data structure
- * @fd_header: the face detection result data structure
- * @config: shared HW pipeline configuration data
- * @config_index: index to the @config entry currently in use
- * @is_p_region: pointer to the shared parameter memory region
- * @is_dma_p_region: DMA address of the shared parameter memory region
- * @is_shared_region: pointer to the IS shared region data structure
- * @af: auto focus data
- * @debugfs_entry: debugfs entry for the firmware log
- */
-struct fimc_is {
- struct platform_device *pdev;
- struct pinctrl *pctrl;
- struct v4l2_device *v4l2_dev;
-
- struct fimc_is_firmware fw;
- struct fimc_is_memory memory;
-
- struct fimc_isp isp;
- struct fimc_is_sensor sensor[FIMC_IS_SENSORS_NUM];
- struct fimc_is_setfile setfile;
-
- struct v4l2_ctrl_handler ctrl_handler;
-
- struct mutex lock;
- spinlock_t slock;
-
- struct clk *clocks[ISS_CLKS_MAX];
- void __iomem *regs;
- void __iomem *pmu_regs;
- int irq;
- wait_queue_head_t irq_queue;
- u8 lpm;
-
- unsigned long state;
- unsigned int sensor_index;
-
- struct i2h_cmd i2h_cmd;
- struct h2i_cmd h2i_cmd;
- struct is_fd_result_header fd_header;
-
- struct chain_config config[IS_SC_MAX];
- unsigned config_index;
-
- struct is_region *is_p_region;
- dma_addr_t is_dma_p_region;
- struct is_share_region *is_shared_region;
- struct is_af_info af;
-
- struct dentry *debugfs_entry;
-};
-
-static inline struct fimc_is *fimc_isp_to_is(struct fimc_isp *isp)
-{
- return container_of(isp, struct fimc_is, isp);
-}
-
-static inline struct chain_config *__get_curr_is_config(struct fimc_is *is)
-{
- return &is->config[is->config_index];
-}
-
-static inline void fimc_is_mem_barrier(void)
-{
- mb();
-}
-
-static inline void fimc_is_set_param_bit(struct fimc_is *is, int num)
-{
- struct chain_config *cfg = &is->config[is->config_index];
-
- set_bit(num, &cfg->p_region_index[0]);
-}
-
-static inline void fimc_is_set_param_ctrl_cmd(struct fimc_is *is, int cmd)
-{
- is->is_p_region->parameter.isp.control.cmd = cmd;
-}
-
-static inline void mcuctl_write(u32 v, struct fimc_is *is, unsigned int offset)
-{
- writel(v, is->regs + offset);
-}
-
-static inline u32 mcuctl_read(struct fimc_is *is, unsigned int offset)
-{
- return readl(is->regs + offset);
-}
-
-static inline void pmuisp_write(u32 v, struct fimc_is *is, unsigned int offset)
-{
- writel(v, is->pmu_regs + offset);
-}
-
-static inline u32 pmuisp_read(struct fimc_is *is, unsigned int offset)
-{
- return readl(is->pmu_regs + offset);
-}
-
-int fimc_is_wait_event(struct fimc_is *is, unsigned long bit,
- unsigned int state, unsigned int timeout);
-int fimc_is_cpu_set_power(struct fimc_is *is, int on);
-int fimc_is_start_firmware(struct fimc_is *is);
-int fimc_is_hw_initialize(struct fimc_is *is);
-void fimc_is_log_dump(const char *level, const void *buf, size_t len);
-
-#endif /* FIMC_IS_H_ */
diff --git a/drivers/media/platform/exynos4-is/fimc-isp-video.c b/drivers/media/platform/exynos4-is/fimc-isp-video.c
deleted file mode 100644
index 83688a7982f7..000000000000
--- a/drivers/media/platform/exynos4-is/fimc-isp-video.c
+++ /dev/null
@@ -1,656 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-/*
- * Samsung EXYNOS4x12 FIMC-IS (Imaging Subsystem) driver
- *
- * FIMC-IS ISP video input and video output DMA interface driver
- *
- * Copyright (C) 2013 Samsung Electronics Co., Ltd.
- * Author: Sylwester Nawrocki <s.nawrocki@samsung.com>
- *
- * The hardware handling code derived from a driver written by
- * Younghwan Joo <yhwan.joo@samsung.com>.
- */
-
-#include <linux/bitops.h>
-#include <linux/device.h>
-#include <linux/delay.h>
-#include <linux/errno.h>
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/types.h>
-#include <linux/printk.h>
-#include <linux/pm_runtime.h>
-#include <linux/slab.h>
-#include <linux/videodev2.h>
-
-#include <media/v4l2-device.h>
-#include <media/v4l2-ioctl.h>
-#include <media/videobuf2-v4l2.h>
-#include <media/videobuf2-dma-contig.h>
-#include <media/drv-intf/exynos-fimc.h>
-
-#include "common.h"
-#include "media-dev.h"
-#include "fimc-is.h"
-#include "fimc-isp-video.h"
-#include "fimc-is-param.h"
-
-static int isp_video_capture_queue_setup(struct vb2_queue *vq,
- unsigned int *num_buffers, unsigned int *num_planes,
- unsigned int sizes[], struct device *alloc_devs[])
-{
- struct fimc_isp *isp = vb2_get_drv_priv(vq);
- struct v4l2_pix_format_mplane *vid_fmt = &isp->video_capture.pixfmt;
- const struct fimc_fmt *fmt = isp->video_capture.format;
- unsigned int wh, i;
-
- wh = vid_fmt->width * vid_fmt->height;
-
- if (fmt == NULL)
- return -EINVAL;
-
- *num_buffers = clamp_t(u32, *num_buffers, FIMC_ISP_REQ_BUFS_MIN,
- FIMC_ISP_REQ_BUFS_MAX);
- if (*num_planes) {
- if (*num_planes != fmt->memplanes)
- return -EINVAL;
- for (i = 0; i < *num_planes; i++)
- if (sizes[i] < (wh * fmt->depth[i]) / 8)
- return -EINVAL;
- return 0;
- }
-
- *num_planes = fmt->memplanes;
-
- for (i = 0; i < fmt->memplanes; i++)
- sizes[i] = (wh * fmt->depth[i]) / 8;
-
- return 0;
-}
-
-static inline struct param_dma_output *__get_isp_dma2(struct fimc_is *is)
-{
- return &__get_curr_is_config(is)->isp.dma2_output;
-}
-
-static int isp_video_capture_start_streaming(struct vb2_queue *q,
- unsigned int count)
-{
- struct fimc_isp *isp = vb2_get_drv_priv(q);
- struct fimc_is *is = fimc_isp_to_is(isp);
- struct param_dma_output *dma = __get_isp_dma2(is);
- struct fimc_is_video *video = &isp->video_capture;
- int ret;
-
- if (!test_bit(ST_ISP_VID_CAP_BUF_PREP, &isp->state) ||
- test_bit(ST_ISP_VID_CAP_STREAMING, &isp->state))
- return 0;
-
-
- dma->cmd = DMA_OUTPUT_COMMAND_ENABLE;
- dma->notify_dma_done = DMA_OUTPUT_NOTIFY_DMA_DONE_ENABLE;
- dma->buffer_address = is->is_dma_p_region +
- DMA2_OUTPUT_ADDR_ARRAY_OFFS;
- dma->buffer_number = video->reqbufs_count;
- dma->dma_out_mask = video->buf_mask;
-
- isp_dbg(2, &video->ve.vdev,
- "buf_count: %d, planes: %d, dma addr table: %#x\n",
- video->buf_count, video->format->memplanes,
- dma->buffer_address);
-
- fimc_is_mem_barrier();
-
- fimc_is_set_param_bit(is, PARAM_ISP_DMA2_OUTPUT);
- __fimc_is_hw_update_param(is, PARAM_ISP_DMA2_OUTPUT);
-
- ret = fimc_is_itf_s_param(is, false);
- if (ret < 0)
- return ret;
-
- ret = fimc_pipeline_call(&video->ve, set_stream, 1);
- if (ret < 0)
- return ret;
-
- set_bit(ST_ISP_VID_CAP_STREAMING, &isp->state);
- return ret;
-}
-
-static void isp_video_capture_stop_streaming(struct vb2_queue *q)
-{
- struct fimc_isp *isp = vb2_get_drv_priv(q);
- struct fimc_is *is = fimc_isp_to_is(isp);
- struct param_dma_output *dma = __get_isp_dma2(is);
- int ret;
-
- ret = fimc_pipeline_call(&isp->video_capture.ve, set_stream, 0);
- if (ret < 0)
- return;
-
- dma->cmd = DMA_OUTPUT_COMMAND_DISABLE;
- dma->notify_dma_done = DMA_OUTPUT_NOTIFY_DMA_DONE_DISABLE;
- dma->buffer_number = 0;
- dma->buffer_address = 0;
- dma->dma_out_mask = 0;
-
- fimc_is_set_param_bit(is, PARAM_ISP_DMA2_OUTPUT);
- __fimc_is_hw_update_param(is, PARAM_ISP_DMA2_OUTPUT);
-
- ret = fimc_is_itf_s_param(is, false);
- if (ret < 0)
- dev_warn(&is->pdev->dev, "%s: DMA stop failed\n", __func__);
-
- fimc_is_hw_set_isp_buf_mask(is, 0);
-
- clear_bit(ST_ISP_VID_CAP_BUF_PREP, &isp->state);
- clear_bit(ST_ISP_VID_CAP_STREAMING, &isp->state);
-
- isp->video_capture.buf_count = 0;
-}
-
-static int isp_video_capture_buffer_prepare(struct vb2_buffer *vb)
-{
- struct fimc_isp *isp = vb2_get_drv_priv(vb->vb2_queue);
- struct fimc_is_video *video = &isp->video_capture;
- int i;
-
- if (video->format == NULL)
- return -EINVAL;
-
- for (i = 0; i < video->format->memplanes; i++) {
- unsigned long size = video->pixfmt.plane_fmt[i].sizeimage;
-
- if (vb2_plane_size(vb, i) < size) {
- v4l2_err(&video->ve.vdev,
- "User buffer too small (%ld < %ld)\n",
- vb2_plane_size(vb, i), size);
- return -EINVAL;
- }
- vb2_set_plane_payload(vb, i, size);
- }
-
- /* Check if we get one of the already known buffers. */
- if (test_bit(ST_ISP_VID_CAP_BUF_PREP, &isp->state)) {
- dma_addr_t dma_addr = vb2_dma_contig_plane_dma_addr(vb, 0);
- int i;
-
- for (i = 0; i < video->buf_count; i++)
- if (video->buffers[i]->dma_addr[0] == dma_addr)
- return 0;
- return -ENXIO;
- }
-
- return 0;
-}
-
-static void isp_video_capture_buffer_queue(struct vb2_buffer *vb)
-{
- struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
- struct fimc_isp *isp = vb2_get_drv_priv(vb->vb2_queue);
- struct fimc_is_video *video = &isp->video_capture;
- struct fimc_is *is = fimc_isp_to_is(isp);
- struct isp_video_buf *ivb = to_isp_video_buf(vbuf);
- unsigned long flags;
- unsigned int i;
-
- if (test_bit(ST_ISP_VID_CAP_BUF_PREP, &isp->state)) {
- spin_lock_irqsave(&is->slock, flags);
- video->buf_mask |= BIT(ivb->index);
- spin_unlock_irqrestore(&is->slock, flags);
- } else {
- unsigned int num_planes = video->format->memplanes;
-
- ivb->index = video->buf_count;
- video->buffers[ivb->index] = ivb;
-
- for (i = 0; i < num_planes; i++) {
- int buf_index = ivb->index * num_planes + i;
-
- ivb->dma_addr[i] = vb2_dma_contig_plane_dma_addr(vb, i);
- is->is_p_region->shared[32 + buf_index] =
- ivb->dma_addr[i];
-
- isp_dbg(2, &video->ve.vdev,
- "dma_buf %d (%d/%d/%d) addr: %pad\n",
- buf_index, ivb->index, i, vb->index,
- &ivb->dma_addr[i]);
- }
-
- if (++video->buf_count < video->reqbufs_count)
- return;
-
- video->buf_mask = (1UL << video->buf_count) - 1;
- set_bit(ST_ISP_VID_CAP_BUF_PREP, &isp->state);
- }
-
- if (!test_bit(ST_ISP_VID_CAP_STREAMING, &isp->state))
- isp_video_capture_start_streaming(vb->vb2_queue, 0);
-}
-
-/*
- * FIMC-IS ISP input and output DMA interface interrupt handler.
- * Locking: called with is->slock spinlock held.
- */
-void fimc_isp_video_irq_handler(struct fimc_is *is)
-{
- struct fimc_is_video *video = &is->isp.video_capture;
- struct vb2_v4l2_buffer *vbuf;
- int buf_index;
-
- /* TODO: Ensure the DMA is really stopped in stop_streaming callback */
- if (!test_bit(ST_ISP_VID_CAP_STREAMING, &is->isp.state))
- return;
-
- buf_index = (is->i2h_cmd.args[1] - 1) % video->buf_count;
- vbuf = &video->buffers[buf_index]->vb;
-
- vbuf->vb2_buf.timestamp = ktime_get_ns();
- vb2_buffer_done(&vbuf->vb2_buf, VB2_BUF_STATE_DONE);
-
- video->buf_mask &= ~BIT(buf_index);
- fimc_is_hw_set_isp_buf_mask(is, video->buf_mask);
-}
-
-static const struct vb2_ops isp_video_capture_qops = {
- .queue_setup = isp_video_capture_queue_setup,
- .buf_prepare = isp_video_capture_buffer_prepare,
- .buf_queue = isp_video_capture_buffer_queue,
- .wait_prepare = vb2_ops_wait_prepare,
- .wait_finish = vb2_ops_wait_finish,
- .start_streaming = isp_video_capture_start_streaming,
- .stop_streaming = isp_video_capture_stop_streaming,
-};
-
-static int isp_video_open(struct file *file)
-{
- struct fimc_isp *isp = video_drvdata(file);
- struct exynos_video_entity *ve = &isp->video_capture.ve;
- struct media_entity *me = &ve->vdev.entity;
- int ret;
-
- if (mutex_lock_interruptible(&isp->video_lock))
- return -ERESTARTSYS;
-
- ret = v4l2_fh_open(file);
- if (ret < 0)
- goto unlock;
-
- ret = pm_runtime_resume_and_get(&isp->pdev->dev);
- if (ret < 0)
- goto rel_fh;
-
- if (v4l2_fh_is_singular_file(file)) {
- mutex_lock(&me->graph_obj.mdev->graph_mutex);
-
- ret = fimc_pipeline_call(ve, open, me, true);
-
- /* Mark the video pipeline as in use. */
- if (ret == 0)
- me->use_count++;
-
- mutex_unlock(&me->graph_obj.mdev->graph_mutex);
- }
- if (!ret)
- goto unlock;
-rel_fh:
- v4l2_fh_release(file);
-unlock:
- mutex_unlock(&isp->video_lock);
- return ret;
-}
-
-static int isp_video_release(struct file *file)
-{
- struct fimc_isp *isp = video_drvdata(file);
- struct fimc_is_video *ivc = &isp->video_capture;
- struct media_entity *entity = &ivc->ve.vdev.entity;
- struct media_device *mdev = entity->graph_obj.mdev;
- bool is_singular_file;
-
- mutex_lock(&isp->video_lock);
-
- is_singular_file = v4l2_fh_is_singular_file(file);
-
- if (is_singular_file && ivc->streaming) {
- media_pipeline_stop(entity);
- ivc->streaming = 0;
- }
-
- _vb2_fop_release(file, NULL);
-
- if (is_singular_file) {
- fimc_pipeline_call(&ivc->ve, close);
-
- mutex_lock(&mdev->graph_mutex);
- entity->use_count--;
- mutex_unlock(&mdev->graph_mutex);
- }
-
- pm_runtime_put(&isp->pdev->dev);
- mutex_unlock(&isp->video_lock);
-
- return 0;
-}
-
-static const struct v4l2_file_operations isp_video_fops = {
- .owner = THIS_MODULE,
- .open = isp_video_open,
- .release = isp_video_release,
- .poll = vb2_fop_poll,
- .unlocked_ioctl = video_ioctl2,
- .mmap = vb2_fop_mmap,
-};
-
-/*
- * Video node ioctl operations
- */
-static int isp_video_querycap(struct file *file, void *priv,
- struct v4l2_capability *cap)
-{
- struct fimc_isp *isp = video_drvdata(file);
-
- __fimc_vidioc_querycap(&isp->pdev->dev, cap);
- return 0;
-}
-
-static int isp_video_enum_fmt(struct file *file, void *priv,
- struct v4l2_fmtdesc *f)
-{
- const struct fimc_fmt *fmt;
-
- if (f->index >= FIMC_ISP_NUM_FORMATS)
- return -EINVAL;
-
- fmt = fimc_isp_find_format(NULL, NULL, f->index);
- if (WARN_ON(fmt == NULL))
- return -EINVAL;
-
- f->pixelformat = fmt->fourcc;
-
- return 0;
-}
-
-static int isp_video_g_fmt_mplane(struct file *file, void *fh,
- struct v4l2_format *f)
-{
- struct fimc_isp *isp = video_drvdata(file);
-
- f->fmt.pix_mp = isp->video_capture.pixfmt;
- return 0;
-}
-
-static void __isp_video_try_fmt(struct fimc_isp *isp,
- struct v4l2_pix_format_mplane *pixm,
- const struct fimc_fmt **fmt)
-{
- const struct fimc_fmt *__fmt;
-
- __fmt = fimc_isp_find_format(&pixm->pixelformat, NULL, 2);
-
- if (fmt)
- *fmt = __fmt;
-
- pixm->colorspace = V4L2_COLORSPACE_SRGB;
- pixm->field = V4L2_FIELD_NONE;
- pixm->num_planes = __fmt->memplanes;
- pixm->pixelformat = __fmt->fourcc;
- /*
- * TODO: double check with the docmentation these width/height
- * constraints are correct.
- */
- v4l_bound_align_image(&pixm->width, FIMC_ISP_SOURCE_WIDTH_MIN,
- FIMC_ISP_SOURCE_WIDTH_MAX, 3,
- &pixm->height, FIMC_ISP_SOURCE_HEIGHT_MIN,
- FIMC_ISP_SOURCE_HEIGHT_MAX, 0, 0);
-}
-
-static int isp_video_try_fmt_mplane(struct file *file, void *fh,
- struct v4l2_format *f)
-{
- struct fimc_isp *isp = video_drvdata(file);
-
- __isp_video_try_fmt(isp, &f->fmt.pix_mp, NULL);
- return 0;
-}
-
-static int isp_video_s_fmt_mplane(struct file *file, void *priv,
- struct v4l2_format *f)
-{
- struct fimc_isp *isp = video_drvdata(file);
- struct fimc_is *is = fimc_isp_to_is(isp);
- struct v4l2_pix_format_mplane *pixm = &f->fmt.pix_mp;
- const struct fimc_fmt *ifmt = NULL;
- struct param_dma_output *dma = __get_isp_dma2(is);
-
- __isp_video_try_fmt(isp, pixm, &ifmt);
-
- if (WARN_ON(ifmt == NULL))
- return -EINVAL;
-
- dma->format = DMA_OUTPUT_FORMAT_BAYER;
- dma->order = DMA_OUTPUT_ORDER_GB_BG;
- dma->plane = ifmt->memplanes;
- dma->bitwidth = ifmt->depth[0];
- dma->width = pixm->width;
- dma->height = pixm->height;
-
- fimc_is_mem_barrier();
-
- isp->video_capture.format = ifmt;
- isp->video_capture.pixfmt = *pixm;
-
- return 0;
-}
-
-/*
- * Check for source/sink format differences at each link.
- * Return 0 if the formats match or -EPIPE otherwise.
- */
-static int isp_video_pipeline_validate(struct fimc_isp *isp)
-{
- struct v4l2_subdev *sd = &isp->subdev;
- struct v4l2_subdev_format sink_fmt, src_fmt;
- struct media_pad *pad;
- int ret;
-
- while (1) {
- /* Retrieve format at the sink pad */
- pad = &sd->entity.pads[0];
- if (!(pad->flags & MEDIA_PAD_FL_SINK))
- break;
- sink_fmt.pad = pad->index;
- sink_fmt.which = V4L2_SUBDEV_FORMAT_ACTIVE;
- ret = v4l2_subdev_call(sd, pad, get_fmt, NULL, &sink_fmt);
- if (ret < 0 && ret != -ENOIOCTLCMD)
- return -EPIPE;
-
- /* Retrieve format at the source pad */
- pad = media_entity_remote_pad(pad);
- if (!pad || !is_media_entity_v4l2_subdev(pad->entity))
- break;
-
- sd = media_entity_to_v4l2_subdev(pad->entity);
- src_fmt.pad = pad->index;
- src_fmt.which = V4L2_SUBDEV_FORMAT_ACTIVE;
- ret = v4l2_subdev_call(sd, pad, get_fmt, NULL, &src_fmt);
- if (ret < 0 && ret != -ENOIOCTLCMD)
- return -EPIPE;
-
- if (src_fmt.format.width != sink_fmt.format.width ||
- src_fmt.format.height != sink_fmt.format.height ||
- src_fmt.format.code != sink_fmt.format.code)
- return -EPIPE;
- }
-
- return 0;
-}
-
-static int isp_video_streamon(struct file *file, void *priv,
- enum v4l2_buf_type type)
-{
- struct fimc_isp *isp = video_drvdata(file);
- struct exynos_video_entity *ve = &isp->video_capture.ve;
- struct media_entity *me = &ve->vdev.entity;
- int ret;
-
- ret = media_pipeline_start(me, &ve->pipe->mp);
- if (ret < 0)
- return ret;
-
- ret = isp_video_pipeline_validate(isp);
- if (ret < 0)
- goto p_stop;
-
- ret = vb2_ioctl_streamon(file, priv, type);
- if (ret < 0)
- goto p_stop;
-
- isp->video_capture.streaming = 1;
- return 0;
-p_stop:
- media_pipeline_stop(me);
- return ret;
-}
-
-static int isp_video_streamoff(struct file *file, void *priv,
- enum v4l2_buf_type type)
-{
- struct fimc_isp *isp = video_drvdata(file);
- struct fimc_is_video *video = &isp->video_capture;
- int ret;
-
- ret = vb2_ioctl_streamoff(file, priv, type);
- if (ret < 0)
- return ret;
-
- media_pipeline_stop(&video->ve.vdev.entity);
- video->streaming = 0;
- return 0;
-}
-
-static int isp_video_reqbufs(struct file *file, void *priv,
- struct v4l2_requestbuffers *rb)
-{
- struct fimc_isp *isp = video_drvdata(file);
- int ret;
-
- ret = vb2_ioctl_reqbufs(file, priv, rb);
- if (ret < 0)
- return ret;
-
- if (rb->count && rb->count < FIMC_ISP_REQ_BUFS_MIN) {
- rb->count = 0;
- vb2_ioctl_reqbufs(file, priv, rb);
- ret = -ENOMEM;
- }
-
- isp->video_capture.reqbufs_count = rb->count;
- return ret;
-}
-
-static const struct v4l2_ioctl_ops isp_video_ioctl_ops = {
- .vidioc_querycap = isp_video_querycap,
- .vidioc_enum_fmt_vid_cap = isp_video_enum_fmt,
- .vidioc_try_fmt_vid_cap_mplane = isp_video_try_fmt_mplane,
- .vidioc_s_fmt_vid_cap_mplane = isp_video_s_fmt_mplane,
- .vidioc_g_fmt_vid_cap_mplane = isp_video_g_fmt_mplane,
- .vidioc_reqbufs = isp_video_reqbufs,
- .vidioc_querybuf = vb2_ioctl_querybuf,
- .vidioc_prepare_buf = vb2_ioctl_prepare_buf,
- .vidioc_create_bufs = vb2_ioctl_create_bufs,
- .vidioc_qbuf = vb2_ioctl_qbuf,
- .vidioc_dqbuf = vb2_ioctl_dqbuf,
- .vidioc_streamon = isp_video_streamon,
- .vidioc_streamoff = isp_video_streamoff,
-};
-
-int fimc_isp_video_device_register(struct fimc_isp *isp,
- struct v4l2_device *v4l2_dev,
- enum v4l2_buf_type type)
-{
- struct vb2_queue *q = &isp->video_capture.vb_queue;
- struct fimc_is_video *iv;
- struct video_device *vdev;
- int ret;
-
- if (type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE)
- iv = &isp->video_capture;
- else
- return -ENOSYS;
-
- mutex_init(&isp->video_lock);
- INIT_LIST_HEAD(&iv->pending_buf_q);
- INIT_LIST_HEAD(&iv->active_buf_q);
- iv->format = fimc_isp_find_format(NULL, NULL, 0);
- iv->pixfmt.width = IS_DEFAULT_WIDTH;
- iv->pixfmt.height = IS_DEFAULT_HEIGHT;
- iv->pixfmt.pixelformat = iv->format->fourcc;
- iv->pixfmt.colorspace = V4L2_COLORSPACE_SRGB;
- iv->reqbufs_count = 0;
-
- memset(q, 0, sizeof(*q));
- q->type = type;
- q->io_modes = VB2_MMAP | VB2_USERPTR;
- q->ops = &isp_video_capture_qops;
- q->mem_ops = &vb2_dma_contig_memops;
- q->buf_struct_size = sizeof(struct isp_video_buf);
- q->drv_priv = isp;
- q->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
- q->lock = &isp->video_lock;
- q->dev = &isp->pdev->dev;
-
- ret = vb2_queue_init(q);
- if (ret < 0)
- return ret;
-
- vdev = &iv->ve.vdev;
- memset(vdev, 0, sizeof(*vdev));
- strscpy(vdev->name, "fimc-is-isp.capture", sizeof(vdev->name));
- vdev->queue = q;
- vdev->fops = &isp_video_fops;
- vdev->ioctl_ops = &isp_video_ioctl_ops;
- vdev->v4l2_dev = v4l2_dev;
- vdev->minor = -1;
- vdev->release = video_device_release_empty;
- vdev->lock = &isp->video_lock;
- vdev->device_caps = V4L2_CAP_STREAMING | V4L2_CAP_VIDEO_CAPTURE_MPLANE;
-
- iv->pad.flags = MEDIA_PAD_FL_SINK;
- ret = media_entity_pads_init(&vdev->entity, 1, &iv->pad);
- if (ret < 0)
- return ret;
-
- video_set_drvdata(vdev, isp);
-
- ret = video_register_device(vdev, VFL_TYPE_VIDEO, -1);
- if (ret < 0) {
- media_entity_cleanup(&vdev->entity);
- return ret;
- }
-
- v4l2_info(v4l2_dev, "Registered %s as /dev/%s\n",
- vdev->name, video_device_node_name(vdev));
-
- return 0;
-}
-
-void fimc_isp_video_device_unregister(struct fimc_isp *isp,
- enum v4l2_buf_type type)
-{
- struct exynos_video_entity *ve;
-
- if (type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE)
- ve = &isp->video_capture.ve;
- else
- return;
-
- mutex_lock(&isp->video_lock);
-
- if (video_is_registered(&ve->vdev)) {
- video_unregister_device(&ve->vdev);
- media_entity_cleanup(&ve->vdev.entity);
- ve->pipe = NULL;
- }
-
- mutex_unlock(&isp->video_lock);
-}
diff --git a/drivers/media/platform/exynos4-is/fimc-isp-video.h b/drivers/media/platform/exynos4-is/fimc-isp-video.h
deleted file mode 100644
index edcb3a5e3cb9..000000000000
--- a/drivers/media/platform/exynos4-is/fimc-isp-video.h
+++ /dev/null
@@ -1,41 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-only */
-/*
- * Samsung EXYNOS4x12 FIMC-IS (Imaging Subsystem) driver
- *
- * Copyright (C) 2013 Samsung Electronics Co., Ltd.
- * Sylwester Nawrocki <s.nawrocki@samsung.com>
- */
-#ifndef FIMC_ISP_VIDEO__
-#define FIMC_ISP_VIDEO__
-
-#include <media/videobuf2-v4l2.h>
-#include "fimc-isp.h"
-
-#ifdef CONFIG_VIDEO_EXYNOS4_ISP_DMA_CAPTURE
-int fimc_isp_video_device_register(struct fimc_isp *isp,
- struct v4l2_device *v4l2_dev,
- enum v4l2_buf_type type);
-
-void fimc_isp_video_device_unregister(struct fimc_isp *isp,
- enum v4l2_buf_type type);
-
-void fimc_isp_video_irq_handler(struct fimc_is *is);
-#else
-static inline void fimc_isp_video_irq_handler(struct fimc_is *is)
-{
-}
-
-static inline int fimc_isp_video_device_register(struct fimc_isp *isp,
- struct v4l2_device *v4l2_dev,
- enum v4l2_buf_type type)
-{
- return 0;
-}
-
-void fimc_isp_video_device_unregister(struct fimc_isp *isp,
- enum v4l2_buf_type type)
-{
-}
-#endif /* !CONFIG_VIDEO_EXYNOS4_ISP_DMA_CAPTURE */
-
-#endif /* FIMC_ISP_VIDEO__ */
diff --git a/drivers/media/platform/exynos4-is/fimc-isp.c b/drivers/media/platform/exynos4-is/fimc-isp.c
deleted file mode 100644
index b85986e50f46..000000000000
--- a/drivers/media/platform/exynos4-is/fimc-isp.c
+++ /dev/null
@@ -1,789 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-/*
- * Samsung EXYNOS4x12 FIMC-IS (Imaging Subsystem) driver
- *
- * Copyright (C) 2013 Samsung Electronics Co., Ltd.
- *
- * Authors: Sylwester Nawrocki <s.nawrocki@samsung.com>
- * Younghwan Joo <yhwan.joo@samsung.com>
- */
-#define pr_fmt(fmt) "%s:%d " fmt, __func__, __LINE__
-
-#include <linux/device.h>
-#include <linux/errno.h>
-#include <linux/kernel.h>
-#include <linux/list.h>
-#include <linux/module.h>
-#include <linux/platform_device.h>
-#include <linux/printk.h>
-#include <linux/pm_runtime.h>
-#include <linux/slab.h>
-#include <linux/types.h>
-#include <media/v4l2-device.h>
-
-#include "media-dev.h"
-#include "fimc-isp-video.h"
-#include "fimc-is-command.h"
-#include "fimc-is-param.h"
-#include "fimc-is-regs.h"
-#include "fimc-is.h"
-
-int fimc_isp_debug;
-module_param_named(debug_isp, fimc_isp_debug, int, S_IRUGO | S_IWUSR);
-
-static const struct fimc_fmt fimc_isp_formats[FIMC_ISP_NUM_FORMATS] = {
- {
- .fourcc = V4L2_PIX_FMT_SGRBG8,
- .depth = { 8 },
- .color = FIMC_FMT_RAW8,
- .memplanes = 1,
- .mbus_code = MEDIA_BUS_FMT_SGRBG8_1X8,
- }, {
- .fourcc = V4L2_PIX_FMT_SGRBG10,
- .depth = { 10 },
- .color = FIMC_FMT_RAW10,
- .memplanes = 1,
- .mbus_code = MEDIA_BUS_FMT_SGRBG10_1X10,
- }, {
- .fourcc = V4L2_PIX_FMT_SGRBG12,
- .depth = { 12 },
- .color = FIMC_FMT_RAW12,
- .memplanes = 1,
- .mbus_code = MEDIA_BUS_FMT_SGRBG12_1X12,
- },
-};
-
-/**
- * fimc_isp_find_format - lookup color format by fourcc or media bus code
- * @pixelformat: fourcc to match, ignored if null
- * @mbus_code: media bus code to match, ignored if null
- * @index: index to the fimc_isp_formats array, ignored if negative
- */
-const struct fimc_fmt *fimc_isp_find_format(const u32 *pixelformat,
- const u32 *mbus_code, int index)
-{
- const struct fimc_fmt *fmt, *def_fmt = NULL;
- unsigned int i;
- int id = 0;
-
- if (index >= (int)ARRAY_SIZE(fimc_isp_formats))
- return NULL;
-
- for (i = 0; i < ARRAY_SIZE(fimc_isp_formats); ++i) {
- fmt = &fimc_isp_formats[i];
- if (pixelformat && fmt->fourcc == *pixelformat)
- return fmt;
- if (mbus_code && fmt->mbus_code == *mbus_code)
- return fmt;
- if (index == id)
- def_fmt = fmt;
- id++;
- }
- return def_fmt;
-}
-
-void fimc_isp_irq_handler(struct fimc_is *is)
-{
- is->i2h_cmd.args[0] = mcuctl_read(is, MCUCTL_REG_ISSR(20));
- is->i2h_cmd.args[1] = mcuctl_read(is, MCUCTL_REG_ISSR(21));
-
- fimc_is_fw_clear_irq1(is, FIMC_IS_INT_FRAME_DONE_ISP);
- fimc_isp_video_irq_handler(is);
-
- wake_up(&is->irq_queue);
-}
-
-/* Capture subdev media entity operations */
-static int fimc_is_link_setup(struct media_entity *entity,
- const struct media_pad *local,
- const struct media_pad *remote, u32 flags)
-{
- return 0;
-}
-
-static const struct media_entity_operations fimc_is_subdev_media_ops = {
- .link_setup = fimc_is_link_setup,
-};
-
-static int fimc_is_subdev_enum_mbus_code(struct v4l2_subdev *sd,
- struct v4l2_subdev_state *sd_state,
- struct v4l2_subdev_mbus_code_enum *code)
-{
- const struct fimc_fmt *fmt;
-
- fmt = fimc_isp_find_format(NULL, NULL, code->index);
- if (!fmt)
- return -EINVAL;
- code->code = fmt->mbus_code;
- return 0;
-}
-
-static int fimc_isp_subdev_get_fmt(struct v4l2_subdev *sd,
- struct v4l2_subdev_state *sd_state,
- struct v4l2_subdev_format *fmt)
-{
- struct fimc_isp *isp = v4l2_get_subdevdata(sd);
- struct v4l2_mbus_framefmt *mf = &fmt->format;
-
- if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) {
- *mf = *v4l2_subdev_get_try_format(sd, sd_state, fmt->pad);
- return 0;
- }
-
- mf->colorspace = V4L2_COLORSPACE_SRGB;
-
- mutex_lock(&isp->subdev_lock);
-
- if (fmt->pad == FIMC_ISP_SD_PAD_SINK) {
- /* ISP OTF input image format */
- *mf = isp->sink_fmt;
- } else {
- /* ISP OTF output image format */
- *mf = isp->src_fmt;
-
- if (fmt->pad == FIMC_ISP_SD_PAD_SRC_FIFO) {
- mf->colorspace = V4L2_COLORSPACE_JPEG;
- mf->code = MEDIA_BUS_FMT_YUV10_1X30;
- }
- }
-
- mutex_unlock(&isp->subdev_lock);
-
- isp_dbg(1, sd, "%s: pad%d: fmt: 0x%x, %dx%d\n", __func__,
- fmt->pad, mf->code, mf->width, mf->height);
-
- return 0;
-}
-
-static void __isp_subdev_try_format(struct fimc_isp *isp,
- struct v4l2_subdev_state *sd_state,
- struct v4l2_subdev_format *fmt)
-{
- struct v4l2_mbus_framefmt *mf = &fmt->format;
- struct v4l2_mbus_framefmt *format;
-
- mf->colorspace = V4L2_COLORSPACE_SRGB;
-
- if (fmt->pad == FIMC_ISP_SD_PAD_SINK) {
- v4l_bound_align_image(&mf->width, FIMC_ISP_SINK_WIDTH_MIN,
- FIMC_ISP_SINK_WIDTH_MAX, 0,
- &mf->height, FIMC_ISP_SINK_HEIGHT_MIN,
- FIMC_ISP_SINK_HEIGHT_MAX, 0, 0);
- mf->code = MEDIA_BUS_FMT_SGRBG10_1X10;
- } else {
- if (fmt->which == V4L2_SUBDEV_FORMAT_TRY)
- format = v4l2_subdev_get_try_format(&isp->subdev,
- sd_state,
- FIMC_ISP_SD_PAD_SINK);
- else
- format = &isp->sink_fmt;
-
- /* Allow changing format only on sink pad */
- mf->width = format->width - FIMC_ISP_CAC_MARGIN_WIDTH;
- mf->height = format->height - FIMC_ISP_CAC_MARGIN_HEIGHT;
-
- if (fmt->pad == FIMC_ISP_SD_PAD_SRC_FIFO) {
- mf->code = MEDIA_BUS_FMT_YUV10_1X30;
- mf->colorspace = V4L2_COLORSPACE_JPEG;
- } else {
- mf->code = format->code;
- }
- }
-}
-
-static int fimc_isp_subdev_set_fmt(struct v4l2_subdev *sd,
- struct v4l2_subdev_state *sd_state,
- struct v4l2_subdev_format *fmt)
-{
- struct fimc_isp *isp = v4l2_get_subdevdata(sd);
- struct fimc_is *is = fimc_isp_to_is(isp);
- struct v4l2_mbus_framefmt *mf = &fmt->format;
- int ret = 0;
-
- isp_dbg(1, sd, "%s: pad%d: code: 0x%x, %dx%d\n",
- __func__, fmt->pad, mf->code, mf->width, mf->height);
-
- mutex_lock(&isp->subdev_lock);
- __isp_subdev_try_format(isp, sd_state, fmt);
-
- if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) {
- mf = v4l2_subdev_get_try_format(sd, sd_state, fmt->pad);
- *mf = fmt->format;
-
- /* Propagate format to the source pads */
- if (fmt->pad == FIMC_ISP_SD_PAD_SINK) {
- struct v4l2_subdev_format format = *fmt;
- unsigned int pad;
-
- for (pad = FIMC_ISP_SD_PAD_SRC_FIFO;
- pad < FIMC_ISP_SD_PADS_NUM; pad++) {
- format.pad = pad;
- __isp_subdev_try_format(isp, sd_state,
- &format);
- mf = v4l2_subdev_get_try_format(sd, sd_state,
- pad);
- *mf = format.format;
- }
- }
- } else {
- if (!media_entity_is_streaming(&sd->entity)) {
- if (fmt->pad == FIMC_ISP_SD_PAD_SINK) {
- struct v4l2_subdev_format format = *fmt;
-
- isp->sink_fmt = *mf;
-
- format.pad = FIMC_ISP_SD_PAD_SRC_DMA;
- __isp_subdev_try_format(isp, sd_state,
- &format);
-
- isp->src_fmt = format.format;
- __is_set_frame_size(is, &isp->src_fmt);
- } else {
- isp->src_fmt = *mf;
- }
- } else {
- ret = -EBUSY;
- }
- }
-
- mutex_unlock(&isp->subdev_lock);
- return ret;
-}
-
-static int fimc_isp_subdev_s_stream(struct v4l2_subdev *sd, int on)
-{
- struct fimc_isp *isp = v4l2_get_subdevdata(sd);
- struct fimc_is *is = fimc_isp_to_is(isp);
- int ret;
-
- isp_dbg(1, sd, "%s: on: %d\n", __func__, on);
-
- if (!test_bit(IS_ST_INIT_DONE, &is->state))
- return -EBUSY;
-
- fimc_is_mem_barrier();
-
- if (on) {
- if (__get_pending_param_count(is)) {
- ret = fimc_is_itf_s_param(is, true);
- if (ret < 0)
- return ret;
- }
-
- isp_dbg(1, sd, "changing mode to %d\n", is->config_index);
-
- ret = fimc_is_itf_mode_change(is);
- if (ret)
- return -EINVAL;
-
- clear_bit(IS_ST_STREAM_ON, &is->state);
- fimc_is_hw_stream_on(is);
- ret = fimc_is_wait_event(is, IS_ST_STREAM_ON, 1,
- FIMC_IS_CONFIG_TIMEOUT);
- if (ret < 0) {
- v4l2_err(sd, "stream on timeout\n");
- return ret;
- }
- } else {
- clear_bit(IS_ST_STREAM_OFF, &is->state);
- fimc_is_hw_stream_off(is);
- ret = fimc_is_wait_event(is, IS_ST_STREAM_OFF, 1,
- FIMC_IS_CONFIG_TIMEOUT);
- if (ret < 0) {
- v4l2_err(sd, "stream off timeout\n");
- return ret;
- }
- is->setfile.sub_index = 0;
- }
-
- return 0;
-}
-
-static int fimc_isp_subdev_s_power(struct v4l2_subdev *sd, int on)
-{
- struct fimc_isp *isp = v4l2_get_subdevdata(sd);
- struct fimc_is *is = fimc_isp_to_is(isp);
- int ret = 0;
-
- pr_debug("on: %d\n", on);
-
- if (on) {
- ret = pm_runtime_resume_and_get(&is->pdev->dev);
- if (ret < 0)
- return ret;
-
- set_bit(IS_ST_PWR_ON, &is->state);
-
- ret = fimc_is_start_firmware(is);
- if (ret < 0) {
- v4l2_err(sd, "firmware booting failed\n");
- pm_runtime_put(&is->pdev->dev);
- return ret;
- }
- set_bit(IS_ST_PWR_SUBIP_ON, &is->state);
-
- ret = fimc_is_hw_initialize(is);
- } else {
- /* Close sensor */
- if (!test_bit(IS_ST_PWR_ON, &is->state)) {
- fimc_is_hw_close_sensor(is, 0);
-
- ret = fimc_is_wait_event(is, IS_ST_OPEN_SENSOR, 0,
- FIMC_IS_CONFIG_TIMEOUT);
- if (ret < 0) {
- v4l2_err(sd, "sensor close timeout\n");
- return ret;
- }
- }
-
- /* SUB IP power off */
- if (test_bit(IS_ST_PWR_SUBIP_ON, &is->state)) {
- fimc_is_hw_subip_power_off(is);
- ret = fimc_is_wait_event(is, IS_ST_PWR_SUBIP_ON, 0,
- FIMC_IS_CONFIG_TIMEOUT);
- if (ret < 0) {
- v4l2_err(sd, "sub-IP power off timeout\n");
- return ret;
- }
- }
-
- fimc_is_cpu_set_power(is, 0);
- pm_runtime_put_sync(&is->pdev->dev);
-
- clear_bit(IS_ST_PWR_ON, &is->state);
- clear_bit(IS_ST_INIT_DONE, &is->state);
- is->state = 0;
- is->config[is->config_index].p_region_index[0] = 0;
- is->config[is->config_index].p_region_index[1] = 0;
- set_bit(IS_ST_IDLE, &is->state);
- wmb();
- }
-
- return ret;
-}
-
-static int fimc_isp_subdev_open(struct v4l2_subdev *sd,
- struct v4l2_subdev_fh *fh)
-{
- struct v4l2_mbus_framefmt *format;
- struct v4l2_mbus_framefmt fmt = {
- .colorspace = V4L2_COLORSPACE_SRGB,
- .code = fimc_isp_formats[0].mbus_code,
- .width = DEFAULT_PREVIEW_STILL_WIDTH + FIMC_ISP_CAC_MARGIN_WIDTH,
- .height = DEFAULT_PREVIEW_STILL_HEIGHT + FIMC_ISP_CAC_MARGIN_HEIGHT,
- .field = V4L2_FIELD_NONE,
- };
-
- format = v4l2_subdev_get_try_format(sd, fh->state,
- FIMC_ISP_SD_PAD_SINK);
- *format = fmt;
-
- format = v4l2_subdev_get_try_format(sd, fh->state,
- FIMC_ISP_SD_PAD_SRC_FIFO);
- fmt.width = DEFAULT_PREVIEW_STILL_WIDTH;
- fmt.height = DEFAULT_PREVIEW_STILL_HEIGHT;
- *format = fmt;
-
- format = v4l2_subdev_get_try_format(sd, fh->state,
- FIMC_ISP_SD_PAD_SRC_DMA);
- *format = fmt;
-
- return 0;
-}
-
-static int fimc_isp_subdev_registered(struct v4l2_subdev *sd)
-{
- struct fimc_isp *isp = v4l2_get_subdevdata(sd);
- int ret;
-
- /* Use pipeline object allocated by the media device. */
- isp->video_capture.ve.pipe = v4l2_get_subdev_hostdata(sd);
-
- ret = fimc_isp_video_device_register(isp, sd->v4l2_dev,
- V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE);
- if (ret < 0)
- isp->video_capture.ve.pipe = NULL;
-
- return ret;
-}
-
-static void fimc_isp_subdev_unregistered(struct v4l2_subdev *sd)
-{
- struct fimc_isp *isp = v4l2_get_subdevdata(sd);
-
- fimc_isp_video_device_unregister(isp,
- V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE);
-}
-
-static const struct v4l2_subdev_internal_ops fimc_is_subdev_internal_ops = {
- .registered = fimc_isp_subdev_registered,
- .unregistered = fimc_isp_subdev_unregistered,
- .open = fimc_isp_subdev_open,
-};
-
-static const struct v4l2_subdev_pad_ops fimc_is_subdev_pad_ops = {
- .enum_mbus_code = fimc_is_subdev_enum_mbus_code,
- .get_fmt = fimc_isp_subdev_get_fmt,
- .set_fmt = fimc_isp_subdev_set_fmt,
-};
-
-static const struct v4l2_subdev_video_ops fimc_is_subdev_video_ops = {
- .s_stream = fimc_isp_subdev_s_stream,
-};
-
-static const struct v4l2_subdev_core_ops fimc_is_core_ops = {
- .s_power = fimc_isp_subdev_s_power,
-};
-
-static const struct v4l2_subdev_ops fimc_is_subdev_ops = {
- .core = &fimc_is_core_ops,
- .video = &fimc_is_subdev_video_ops,
- .pad = &fimc_is_subdev_pad_ops,
-};
-
-static int __ctrl_set_white_balance(struct fimc_is *is, int value)
-{
- switch (value) {
- case V4L2_WHITE_BALANCE_AUTO:
- __is_set_isp_awb(is, ISP_AWB_COMMAND_AUTO, 0);
- break;
- case V4L2_WHITE_BALANCE_DAYLIGHT:
- __is_set_isp_awb(is, ISP_AWB_COMMAND_ILLUMINATION,
- ISP_AWB_ILLUMINATION_DAYLIGHT);
- break;
- case V4L2_WHITE_BALANCE_CLOUDY:
- __is_set_isp_awb(is, ISP_AWB_COMMAND_ILLUMINATION,
- ISP_AWB_ILLUMINATION_CLOUDY);
- break;
- case V4L2_WHITE_BALANCE_INCANDESCENT:
- __is_set_isp_awb(is, ISP_AWB_COMMAND_ILLUMINATION,
- ISP_AWB_ILLUMINATION_TUNGSTEN);
- break;
- case V4L2_WHITE_BALANCE_FLUORESCENT:
- __is_set_isp_awb(is, ISP_AWB_COMMAND_ILLUMINATION,
- ISP_AWB_ILLUMINATION_FLUORESCENT);
- break;
- default:
- return -EINVAL;
- }
-
- return 0;
-}
-
-static int __ctrl_set_aewb_lock(struct fimc_is *is,
- struct v4l2_ctrl *ctrl)
-{
- bool awb_lock = ctrl->val & V4L2_LOCK_WHITE_BALANCE;
- bool ae_lock = ctrl->val & V4L2_LOCK_EXPOSURE;
- struct isp_param *isp = &is->is_p_region->parameter.isp;
- int cmd, ret;
-
- cmd = ae_lock ? ISP_AA_COMMAND_STOP : ISP_AA_COMMAND_START;
- isp->aa.cmd = cmd;
- isp->aa.target = ISP_AA_TARGET_AE;
- fimc_is_set_param_bit(is, PARAM_ISP_AA);
- is->af.ae_lock_state = ae_lock;
- wmb();
-
- ret = fimc_is_itf_s_param(is, false);
- if (ret < 0)
- return ret;
-
- cmd = awb_lock ? ISP_AA_COMMAND_STOP : ISP_AA_COMMAND_START;
- isp->aa.cmd = cmd;
- isp->aa.target = ISP_AA_TARGET_AE;
- fimc_is_set_param_bit(is, PARAM_ISP_AA);
- is->af.awb_lock_state = awb_lock;
- wmb();
-
- return fimc_is_itf_s_param(is, false);
-}
-
-/* Supported manual ISO values */
-static const s64 iso_qmenu[] = {
- 50, 100, 200, 400, 800,
-};
-
-static int __ctrl_set_iso(struct fimc_is *is, int value)
-{
- unsigned int idx, iso;
-
- if (value == V4L2_ISO_SENSITIVITY_AUTO) {
- __is_set_isp_iso(is, ISP_ISO_COMMAND_AUTO, 0);
- return 0;
- }
- idx = is->isp.ctrls.iso->val;
- if (idx >= ARRAY_SIZE(iso_qmenu))
- return -EINVAL;
-
- iso = iso_qmenu[idx];
- __is_set_isp_iso(is, ISP_ISO_COMMAND_MANUAL, iso);
- return 0;
-}
-
-static int __ctrl_set_metering(struct fimc_is *is, unsigned int value)
-{
- unsigned int val;
-
- switch (value) {
- case V4L2_EXPOSURE_METERING_AVERAGE:
- val = ISP_METERING_COMMAND_AVERAGE;
- break;
- case V4L2_EXPOSURE_METERING_CENTER_WEIGHTED:
- val = ISP_METERING_COMMAND_CENTER;
- break;
- case V4L2_EXPOSURE_METERING_SPOT:
- val = ISP_METERING_COMMAND_SPOT;
- break;
- case V4L2_EXPOSURE_METERING_MATRIX:
- val = ISP_METERING_COMMAND_MATRIX;
- break;
- default:
- return -EINVAL;
- }
-
- __is_set_isp_metering(is, IS_METERING_CONFIG_CMD, val);
- return 0;
-}
-
-static int __ctrl_set_afc(struct fimc_is *is, int value)
-{
- switch (value) {
- case V4L2_CID_POWER_LINE_FREQUENCY_DISABLED:
- __is_set_isp_afc(is, ISP_AFC_COMMAND_DISABLE, 0);
- break;
- case V4L2_CID_POWER_LINE_FREQUENCY_50HZ:
- __is_set_isp_afc(is, ISP_AFC_COMMAND_MANUAL, 50);
- break;
- case V4L2_CID_POWER_LINE_FREQUENCY_60HZ:
- __is_set_isp_afc(is, ISP_AFC_COMMAND_MANUAL, 60);
- break;
- case V4L2_CID_POWER_LINE_FREQUENCY_AUTO:
- __is_set_isp_afc(is, ISP_AFC_COMMAND_AUTO, 0);
- break;
- default:
- return -EINVAL;
- }
-
- return 0;
-}
-
-static int __ctrl_set_image_effect(struct fimc_is *is, int value)
-{
- static const u8 effects[][2] = {
- { V4L2_COLORFX_NONE, ISP_IMAGE_EFFECT_DISABLE },
- { V4L2_COLORFX_BW, ISP_IMAGE_EFFECT_MONOCHROME },
- { V4L2_COLORFX_SEPIA, ISP_IMAGE_EFFECT_SEPIA },
- { V4L2_COLORFX_NEGATIVE, ISP_IMAGE_EFFECT_NEGATIVE_MONO },
- { 16 /* TODO */, ISP_IMAGE_EFFECT_NEGATIVE_COLOR },
- };
- int i;
-
- for (i = 0; i < ARRAY_SIZE(effects); i++) {
- if (effects[i][0] != value)
- continue;
-
- __is_set_isp_effect(is, effects[i][1]);
- return 0;
- }
-
- return -EINVAL;
-}
-
-static int fimc_is_s_ctrl(struct v4l2_ctrl *ctrl)
-{
- struct fimc_isp *isp = ctrl_to_fimc_isp(ctrl);
- struct fimc_is *is = fimc_isp_to_is(isp);
- bool set_param = true;
- int ret = 0;
-
- switch (ctrl->id) {
- case V4L2_CID_CONTRAST:
- __is_set_isp_adjust(is, ISP_ADJUST_COMMAND_MANUAL_CONTRAST,
- ctrl->val);
- break;
-
- case V4L2_CID_SATURATION:
- __is_set_isp_adjust(is, ISP_ADJUST_COMMAND_MANUAL_SATURATION,
- ctrl->val);
- break;
-
- case V4L2_CID_SHARPNESS:
- __is_set_isp_adjust(is, ISP_ADJUST_COMMAND_MANUAL_SHARPNESS,
- ctrl->val);
- break;
-
- case V4L2_CID_EXPOSURE_ABSOLUTE:
- __is_set_isp_adjust(is, ISP_ADJUST_COMMAND_MANUAL_EXPOSURE,
- ctrl->val);
- break;
-
- case V4L2_CID_BRIGHTNESS:
- __is_set_isp_adjust(is, ISP_ADJUST_COMMAND_MANUAL_BRIGHTNESS,
- ctrl->val);
- break;
-
- case V4L2_CID_HUE:
- __is_set_isp_adjust(is, ISP_ADJUST_COMMAND_MANUAL_HUE,
- ctrl->val);
- break;
-
- case V4L2_CID_EXPOSURE_METERING:
- ret = __ctrl_set_metering(is, ctrl->val);
- break;
-
- case V4L2_CID_AUTO_N_PRESET_WHITE_BALANCE:
- ret = __ctrl_set_white_balance(is, ctrl->val);
- break;
-
- case V4L2_CID_3A_LOCK:
- ret = __ctrl_set_aewb_lock(is, ctrl);
- set_param = false;
- break;
-
- case V4L2_CID_ISO_SENSITIVITY_AUTO:
- ret = __ctrl_set_iso(is, ctrl->val);
- break;
-
- case V4L2_CID_POWER_LINE_FREQUENCY:
- ret = __ctrl_set_afc(is, ctrl->val);
- break;
-
- case V4L2_CID_COLORFX:
- __ctrl_set_image_effect(is, ctrl->val);
- break;
-
- default:
- ret = -EINVAL;
- break;
- }
-
- if (ret < 0) {
- v4l2_err(&isp->subdev, "Failed to set control: %s (%d)\n",
- ctrl->name, ctrl->val);
- return ret;
- }
-
- if (set_param && test_bit(IS_ST_STREAM_ON, &is->state))
- return fimc_is_itf_s_param(is, true);
-
- return 0;
-}
-
-static const struct v4l2_ctrl_ops fimc_isp_ctrl_ops = {
- .s_ctrl = fimc_is_s_ctrl,
-};
-
-static void __isp_subdev_set_default_format(struct fimc_isp *isp)
-{
- struct fimc_is *is = fimc_isp_to_is(isp);
-
- isp->sink_fmt.width = DEFAULT_PREVIEW_STILL_WIDTH +
- FIMC_ISP_CAC_MARGIN_WIDTH;
- isp->sink_fmt.height = DEFAULT_PREVIEW_STILL_HEIGHT +
- FIMC_ISP_CAC_MARGIN_HEIGHT;
- isp->sink_fmt.code = MEDIA_BUS_FMT_SGRBG10_1X10;
-
- isp->src_fmt.width = DEFAULT_PREVIEW_STILL_WIDTH;
- isp->src_fmt.height = DEFAULT_PREVIEW_STILL_HEIGHT;
- isp->src_fmt.code = MEDIA_BUS_FMT_SGRBG10_1X10;
- __is_set_frame_size(is, &isp->src_fmt);
-}
-
-int fimc_isp_subdev_create(struct fimc_isp *isp)
-{
- const struct v4l2_ctrl_ops *ops = &fimc_isp_ctrl_ops;
- struct v4l2_ctrl_handler *handler = &isp->ctrls.handler;
- struct v4l2_subdev *sd = &isp->subdev;
- struct fimc_isp_ctrls *ctrls = &isp->ctrls;
- int ret;
-
- mutex_init(&isp->subdev_lock);
-
- v4l2_subdev_init(sd, &fimc_is_subdev_ops);
-
- sd->owner = THIS_MODULE;
- sd->grp_id = GRP_ID_FIMC_IS;
- sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
- snprintf(sd->name, sizeof(sd->name), "FIMC-IS-ISP");
-
- sd->entity.function = MEDIA_ENT_F_PROC_VIDEO_PIXEL_FORMATTER;
- isp->subdev_pads[FIMC_ISP_SD_PAD_SINK].flags = MEDIA_PAD_FL_SINK;
- isp->subdev_pads[FIMC_ISP_SD_PAD_SRC_FIFO].flags = MEDIA_PAD_FL_SOURCE;
- isp->subdev_pads[FIMC_ISP_SD_PAD_SRC_DMA].flags = MEDIA_PAD_FL_SOURCE;
- ret = media_entity_pads_init(&sd->entity, FIMC_ISP_SD_PADS_NUM,
- isp->subdev_pads);
- if (ret)
- return ret;
-
- v4l2_ctrl_handler_init(handler, 20);
-
- ctrls->saturation = v4l2_ctrl_new_std(handler, ops, V4L2_CID_SATURATION,
- -2, 2, 1, 0);
- ctrls->brightness = v4l2_ctrl_new_std(handler, ops, V4L2_CID_BRIGHTNESS,
- -4, 4, 1, 0);
- ctrls->contrast = v4l2_ctrl_new_std(handler, ops, V4L2_CID_CONTRAST,
- -2, 2, 1, 0);
- ctrls->sharpness = v4l2_ctrl_new_std(handler, ops, V4L2_CID_SHARPNESS,
- -2, 2, 1, 0);
- ctrls->hue = v4l2_ctrl_new_std(handler, ops, V4L2_CID_HUE,
- -2, 2, 1, 0);
-
- ctrls->auto_wb = v4l2_ctrl_new_std_menu(handler, ops,
- V4L2_CID_AUTO_N_PRESET_WHITE_BALANCE,
- 8, ~0x14e, V4L2_WHITE_BALANCE_AUTO);
-
- ctrls->exposure = v4l2_ctrl_new_std(handler, ops,
- V4L2_CID_EXPOSURE_ABSOLUTE,
- -4, 4, 1, 0);
-
- ctrls->exp_metering = v4l2_ctrl_new_std_menu(handler, ops,
- V4L2_CID_EXPOSURE_METERING, 3,
- ~0xf, V4L2_EXPOSURE_METERING_AVERAGE);
-
- v4l2_ctrl_new_std_menu(handler, ops, V4L2_CID_POWER_LINE_FREQUENCY,
- V4L2_CID_POWER_LINE_FREQUENCY_AUTO, 0,
- V4L2_CID_POWER_LINE_FREQUENCY_AUTO);
- /* ISO sensitivity */
- ctrls->auto_iso = v4l2_ctrl_new_std_menu(handler, ops,
- V4L2_CID_ISO_SENSITIVITY_AUTO, 1, 0,
- V4L2_ISO_SENSITIVITY_AUTO);
-
- ctrls->iso = v4l2_ctrl_new_int_menu(handler, ops,
- V4L2_CID_ISO_SENSITIVITY, ARRAY_SIZE(iso_qmenu) - 1,
- ARRAY_SIZE(iso_qmenu)/2 - 1, iso_qmenu);
-
- ctrls->aewb_lock = v4l2_ctrl_new_std(handler, ops,
- V4L2_CID_3A_LOCK, 0, 0x3, 0, 0);
-
- /* TODO: Add support for NEGATIVE_COLOR option */
- ctrls->colorfx = v4l2_ctrl_new_std_menu(handler, ops, V4L2_CID_COLORFX,
- V4L2_COLORFX_SET_CBCR + 1, ~0x1000f, V4L2_COLORFX_NONE);
-
- if (handler->error) {
- media_entity_cleanup(&sd->entity);
- return handler->error;
- }
-
- v4l2_ctrl_auto_cluster(2, &ctrls->auto_iso,
- V4L2_ISO_SENSITIVITY_MANUAL, false);
-
- sd->ctrl_handler = handler;
- sd->internal_ops = &fimc_is_subdev_internal_ops;
- sd->entity.ops = &fimc_is_subdev_media_ops;
- v4l2_set_subdevdata(sd, isp);
-
- __isp_subdev_set_default_format(isp);
-
- return 0;
-}
-
-void fimc_isp_subdev_destroy(struct fimc_isp *isp)
-{
- struct v4l2_subdev *sd = &isp->subdev;
-
- v4l2_device_unregister_subdev(sd);
- media_entity_cleanup(&sd->entity);
- v4l2_ctrl_handler_free(&isp->ctrls.handler);
- v4l2_set_subdevdata(sd, NULL);
-}
diff --git a/drivers/media/platform/exynos4-is/fimc-isp.h b/drivers/media/platform/exynos4-is/fimc-isp.h
deleted file mode 100644
index 12017cd924d9..000000000000
--- a/drivers/media/platform/exynos4-is/fimc-isp.h
+++ /dev/null
@@ -1,197 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-only */
-/*
- * Samsung EXYNOS4x12 FIMC-IS (Imaging Subsystem) driver
- *
- * Copyright (C) 2013 Samsung Electronics Co., Ltd.
- *
- * Authors: Sylwester Nawrocki <s.nawrocki@samsung.com>
- * Younghwan Joo <yhwan.joo@samsung.com>
- */
-#ifndef FIMC_ISP_H_
-#define FIMC_ISP_H_
-
-#include <linux/io.h>
-#include <linux/platform_device.h>
-#include <linux/sched.h>
-#include <linux/spinlock.h>
-#include <linux/types.h>
-#include <linux/videodev2.h>
-
-#include <media/media-entity.h>
-#include <media/videobuf2-v4l2.h>
-#include <media/v4l2-device.h>
-#include <media/v4l2-mediabus.h>
-#include <media/drv-intf/exynos-fimc.h>
-
-extern int fimc_isp_debug;
-
-#define isp_dbg(level, dev, fmt, arg...) \
- v4l2_dbg(level, fimc_isp_debug, dev, fmt, ## arg)
-
-/* FIXME: revisit these constraints */
-#define FIMC_ISP_SINK_WIDTH_MIN (16 + 8)
-#define FIMC_ISP_SINK_HEIGHT_MIN (12 + 8)
-#define FIMC_ISP_SOURCE_WIDTH_MIN 8
-#define FIMC_ISP_SOURCE_HEIGHT_MIN 8
-#define FIMC_ISP_CAC_MARGIN_WIDTH 16
-#define FIMC_ISP_CAC_MARGIN_HEIGHT 12
-
-#define FIMC_ISP_SINK_WIDTH_MAX (4000 - 16)
-#define FIMC_ISP_SINK_HEIGHT_MAX (4000 + 12)
-#define FIMC_ISP_SOURCE_WIDTH_MAX 4000
-#define FIMC_ISP_SOURCE_HEIGHT_MAX 4000
-
-#define FIMC_ISP_NUM_FORMATS 3
-#define FIMC_ISP_REQ_BUFS_MIN 2
-#define FIMC_ISP_REQ_BUFS_MAX 32
-
-#define FIMC_ISP_SD_PAD_SINK 0
-#define FIMC_ISP_SD_PAD_SRC_FIFO 1
-#define FIMC_ISP_SD_PAD_SRC_DMA 2
-#define FIMC_ISP_SD_PADS_NUM 3
-#define FIMC_ISP_MAX_PLANES 1
-
-/**
- * struct fimc_isp_frame - source/target frame properties
- * @width: full image width
- * @height: full image height
- * @rect: crop/composition rectangle
- */
-struct fimc_isp_frame {
- u16 width;
- u16 height;
- struct v4l2_rect rect;
-};
-
-struct fimc_isp_ctrls {
- struct v4l2_ctrl_handler handler;
-
- /* Auto white balance */
- struct v4l2_ctrl *auto_wb;
- /* Auto ISO control cluster */
- struct {
- struct v4l2_ctrl *auto_iso;
- struct v4l2_ctrl *iso;
- };
- /* Adjust - contrast */
- struct v4l2_ctrl *contrast;
- /* Adjust - saturation */
- struct v4l2_ctrl *saturation;
- /* Adjust - sharpness */
- struct v4l2_ctrl *sharpness;
- /* Adjust - brightness */
- struct v4l2_ctrl *brightness;
- /* Adjust - hue */
- struct v4l2_ctrl *hue;
-
- /* Auto/manual exposure */
- struct v4l2_ctrl *auto_exp;
- /* Manual exposure value */
- struct v4l2_ctrl *exposure;
- /* AE/AWB lock/unlock */
- struct v4l2_ctrl *aewb_lock;
- /* Exposure metering mode */
- struct v4l2_ctrl *exp_metering;
- /* AFC */
- struct v4l2_ctrl *afc;
- /* ISP image effect */
- struct v4l2_ctrl *colorfx;
-};
-
-struct isp_video_buf {
- struct vb2_v4l2_buffer vb;
- dma_addr_t dma_addr[FIMC_ISP_MAX_PLANES];
- unsigned int index;
-};
-
-#define to_isp_video_buf(_b) container_of(_b, struct isp_video_buf, vb)
-
-#define FIMC_ISP_MAX_BUFS 4
-
-/**
- * struct fimc_is_video - fimc-is video device structure
- * @ve: video_device structure and media pipeline
- * @type: video device type (CAPTURE/OUTPUT)
- * @pad: video device media (sink) pad
- * @pending_buf_q: pending buffers queue head
- * @active_buf_q: a queue head of buffers scheduled in hardware
- * @vb_queue: vb2 buffer queue
- * @reqbufs_count: the number of buffers requested in REQBUFS ioctl
- * @buf_count: number of video buffers scheduled in hardware
- * @buf_mask: bitmask of the queued video buffer indices
- * @frame_count: counter of frames dequeued to user space
- * @streaming: is streaming in progress?
- * @buffers: buffer info
- * @format: current fimc pixel format
- * @pixfmt: current pixel format
- */
-struct fimc_is_video {
- struct exynos_video_entity ve;
- enum v4l2_buf_type type;
- struct media_pad pad;
- struct list_head pending_buf_q;
- struct list_head active_buf_q;
- struct vb2_queue vb_queue;
- unsigned int reqbufs_count;
- unsigned int buf_count;
- unsigned int buf_mask;
- unsigned int frame_count;
- int streaming;
- struct isp_video_buf *buffers[FIMC_ISP_MAX_BUFS];
- const struct fimc_fmt *format;
- struct v4l2_pix_format_mplane pixfmt;
-};
-
-/* struct fimc_isp:state bit definitions */
-#define ST_ISP_VID_CAP_BUF_PREP 0
-#define ST_ISP_VID_CAP_STREAMING 1
-
-/**
- * struct fimc_isp - FIMC-IS ISP data structure
- * @pdev: pointer to FIMC-IS platform device
- * @subdev: ISP v4l2_subdev
- * @subdev_pads: the ISP subdev media pads
- * @src_fmt: source mediabus format
- * @sink_fmt: sink mediabus format
- * @test_pattern: test pattern controls
- * @ctrls: v4l2 controls structure
- * @video_lock: mutex serializing video device operations
- * @subdev_lock: mutex serializing subdev operations
- * @cac_margin_x: horizontal CAC margin in pixels
- * @cac_margin_y: vertical CAC margin in pixels
- * @state: driver state flags
- * @video_capture: the ISP block video capture device
- */
-struct fimc_isp {
- struct platform_device *pdev;
- struct v4l2_subdev subdev;
- struct media_pad subdev_pads[FIMC_ISP_SD_PADS_NUM];
- struct v4l2_mbus_framefmt src_fmt;
- struct v4l2_mbus_framefmt sink_fmt;
- struct v4l2_ctrl *test_pattern;
- struct fimc_isp_ctrls ctrls;
-
- struct mutex video_lock;
- struct mutex subdev_lock;
-
- unsigned int cac_margin_x;
- unsigned int cac_margin_y;
-
- unsigned long state;
-
- struct fimc_is_video video_capture;
-};
-
-#define ctrl_to_fimc_isp(_ctrl) \
- container_of(ctrl->handler, struct fimc_isp, ctrls.handler)
-
-struct fimc_is;
-
-int fimc_isp_subdev_create(struct fimc_isp *isp);
-void fimc_isp_subdev_destroy(struct fimc_isp *isp);
-void fimc_isp_irq_handler(struct fimc_is *is);
-int fimc_is_create_controls(struct fimc_isp *isp);
-int fimc_is_delete_controls(struct fimc_isp *isp);
-const struct fimc_fmt *fimc_isp_find_format(const u32 *pixelformat,
- const u32 *mbus_code, int index);
-#endif /* FIMC_ISP_H_ */
diff --git a/drivers/media/platform/exynos4-is/fimc-lite-reg.c b/drivers/media/platform/exynos4-is/fimc-lite-reg.c
deleted file mode 100644
index 57996b4104b4..000000000000
--- a/drivers/media/platform/exynos4-is/fimc-lite-reg.c
+++ /dev/null
@@ -1,346 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-/*
- * Register interface file for EXYNOS FIMC-LITE (camera interface) driver
- *
- * Copyright (C) 2012 Samsung Electronics Co., Ltd.
- * Author: Sylwester Nawrocki <s.nawrocki@samsung.com>
-*/
-
-#include <linux/bitops.h>
-#include <linux/delay.h>
-#include <linux/io.h>
-#include <media/drv-intf/exynos-fimc.h>
-
-#include "fimc-lite-reg.h"
-#include "fimc-lite.h"
-#include "fimc-core.h"
-
-#define FLITE_RESET_TIMEOUT 50 /* in ms */
-
-void flite_hw_reset(struct fimc_lite *dev)
-{
- unsigned long end = jiffies + msecs_to_jiffies(FLITE_RESET_TIMEOUT);
- u32 cfg;
-
- cfg = readl(dev->regs + FLITE_REG_CIGCTRL);
- cfg |= FLITE_REG_CIGCTRL_SWRST_REQ;
- writel(cfg, dev->regs + FLITE_REG_CIGCTRL);
-
- while (time_is_after_jiffies(end)) {
- cfg = readl(dev->regs + FLITE_REG_CIGCTRL);
- if (cfg & FLITE_REG_CIGCTRL_SWRST_RDY)
- break;
- usleep_range(1000, 5000);
- }
-
- cfg |= FLITE_REG_CIGCTRL_SWRST;
- writel(cfg, dev->regs + FLITE_REG_CIGCTRL);
-}
-
-void flite_hw_clear_pending_irq(struct fimc_lite *dev)
-{
- u32 cfg = readl(dev->regs + FLITE_REG_CISTATUS);
- cfg &= ~FLITE_REG_CISTATUS_IRQ_CAM;
- writel(cfg, dev->regs + FLITE_REG_CISTATUS);
-}
-
-u32 flite_hw_get_interrupt_source(struct fimc_lite *dev)
-{
- u32 intsrc = readl(dev->regs + FLITE_REG_CISTATUS);
- return intsrc & FLITE_REG_CISTATUS_IRQ_MASK;
-}
-
-void flite_hw_clear_last_capture_end(struct fimc_lite *dev)
-{
-
- u32 cfg = readl(dev->regs + FLITE_REG_CISTATUS2);
- cfg &= ~FLITE_REG_CISTATUS2_LASTCAPEND;
- writel(cfg, dev->regs + FLITE_REG_CISTATUS2);
-}
-
-void flite_hw_set_interrupt_mask(struct fimc_lite *dev)
-{
- u32 cfg, intsrc;
-
- /* Select interrupts to be enabled for each output mode */
- if (atomic_read(&dev->out_path) == FIMC_IO_DMA) {
- intsrc = FLITE_REG_CIGCTRL_IRQ_OVFEN |
- FLITE_REG_CIGCTRL_IRQ_LASTEN |
- FLITE_REG_CIGCTRL_IRQ_STARTEN |
- FLITE_REG_CIGCTRL_IRQ_ENDEN;
- } else {
- /* An output to the FIMC-IS */
- intsrc = FLITE_REG_CIGCTRL_IRQ_OVFEN |
- FLITE_REG_CIGCTRL_IRQ_LASTEN;
- }
-
- cfg = readl(dev->regs + FLITE_REG_CIGCTRL);
- cfg |= FLITE_REG_CIGCTRL_IRQ_DISABLE_MASK;
- cfg &= ~intsrc;
- writel(cfg, dev->regs + FLITE_REG_CIGCTRL);
-}
-
-void flite_hw_capture_start(struct fimc_lite *dev)
-{
- u32 cfg = readl(dev->regs + FLITE_REG_CIIMGCPT);
- cfg |= FLITE_REG_CIIMGCPT_IMGCPTEN;
- writel(cfg, dev->regs + FLITE_REG_CIIMGCPT);
-}
-
-void flite_hw_capture_stop(struct fimc_lite *dev)
-{
- u32 cfg = readl(dev->regs + FLITE_REG_CIIMGCPT);
- cfg &= ~FLITE_REG_CIIMGCPT_IMGCPTEN;
- writel(cfg, dev->regs + FLITE_REG_CIIMGCPT);
-}
-
-/*
- * Test pattern (color bars) enable/disable. External sensor
- * pixel clock must be active for the test pattern to work.
- */
-void flite_hw_set_test_pattern(struct fimc_lite *dev, bool on)
-{
- u32 cfg = readl(dev->regs + FLITE_REG_CIGCTRL);
- if (on)
- cfg |= FLITE_REG_CIGCTRL_TEST_PATTERN_COLORBAR;
- else
- cfg &= ~FLITE_REG_CIGCTRL_TEST_PATTERN_COLORBAR;
- writel(cfg, dev->regs + FLITE_REG_CIGCTRL);
-}
-
-static const u32 src_pixfmt_map[8][3] = {
- { MEDIA_BUS_FMT_YUYV8_2X8, FLITE_REG_CISRCSIZE_ORDER422_IN_YCBYCR,
- FLITE_REG_CIGCTRL_YUV422_1P },
- { MEDIA_BUS_FMT_YVYU8_2X8, FLITE_REG_CISRCSIZE_ORDER422_IN_YCRYCB,
- FLITE_REG_CIGCTRL_YUV422_1P },
- { MEDIA_BUS_FMT_UYVY8_2X8, FLITE_REG_CISRCSIZE_ORDER422_IN_CBYCRY,
- FLITE_REG_CIGCTRL_YUV422_1P },
- { MEDIA_BUS_FMT_VYUY8_2X8, FLITE_REG_CISRCSIZE_ORDER422_IN_CRYCBY,
- FLITE_REG_CIGCTRL_YUV422_1P },
- { MEDIA_BUS_FMT_SGRBG8_1X8, 0, FLITE_REG_CIGCTRL_RAW8 },
- { MEDIA_BUS_FMT_SGRBG10_1X10, 0, FLITE_REG_CIGCTRL_RAW10 },
- { MEDIA_BUS_FMT_SGRBG12_1X12, 0, FLITE_REG_CIGCTRL_RAW12 },
- { MEDIA_BUS_FMT_JPEG_1X8, 0, FLITE_REG_CIGCTRL_USER(1) },
-};
-
-/* Set camera input pixel format and resolution */
-void flite_hw_set_source_format(struct fimc_lite *dev, struct flite_frame *f)
-{
- u32 pixelcode = f->fmt->mbus_code;
- int i = ARRAY_SIZE(src_pixfmt_map);
- u32 cfg;
-
- while (--i) {
- if (src_pixfmt_map[i][0] == pixelcode)
- break;
- }
-
- if (i == 0 && src_pixfmt_map[i][0] != pixelcode) {
- v4l2_err(&dev->ve.vdev,
- "Unsupported pixel code, falling back to %#08x\n",
- src_pixfmt_map[i][0]);
- }
-
- cfg = readl(dev->regs + FLITE_REG_CIGCTRL);
- cfg &= ~FLITE_REG_CIGCTRL_FMT_MASK;
- cfg |= src_pixfmt_map[i][2];
- writel(cfg, dev->regs + FLITE_REG_CIGCTRL);
-
- cfg = readl(dev->regs + FLITE_REG_CISRCSIZE);
- cfg &= ~(FLITE_REG_CISRCSIZE_ORDER422_MASK |
- FLITE_REG_CISRCSIZE_SIZE_CAM_MASK);
- cfg |= (f->f_width << 16) | f->f_height;
- cfg |= src_pixfmt_map[i][1];
- writel(cfg, dev->regs + FLITE_REG_CISRCSIZE);
-}
-
-/* Set the camera host input window offsets (cropping) */
-void flite_hw_set_window_offset(struct fimc_lite *dev, struct flite_frame *f)
-{
- u32 hoff2, voff2;
- u32 cfg;
-
- cfg = readl(dev->regs + FLITE_REG_CIWDOFST);
- cfg &= ~FLITE_REG_CIWDOFST_OFST_MASK;
- cfg |= (f->rect.left << 16) | f->rect.top;
- cfg |= FLITE_REG_CIWDOFST_WINOFSEN;
- writel(cfg, dev->regs + FLITE_REG_CIWDOFST);
-
- hoff2 = f->f_width - f->rect.width - f->rect.left;
- voff2 = f->f_height - f->rect.height - f->rect.top;
-
- cfg = (hoff2 << 16) | voff2;
- writel(cfg, dev->regs + FLITE_REG_CIWDOFST2);
-}
-
-/* Select camera port (A, B) */
-static void flite_hw_set_camera_port(struct fimc_lite *dev, int id)
-{
- u32 cfg = readl(dev->regs + FLITE_REG_CIGENERAL);
- if (id == 0)
- cfg &= ~FLITE_REG_CIGENERAL_CAM_B;
- else
- cfg |= FLITE_REG_CIGENERAL_CAM_B;
- writel(cfg, dev->regs + FLITE_REG_CIGENERAL);
-}
-
-/* Select serial or parallel bus, camera port (A,B) and set signals polarity */
-void flite_hw_set_camera_bus(struct fimc_lite *dev,
- struct fimc_source_info *si)
-{
- u32 cfg = readl(dev->regs + FLITE_REG_CIGCTRL);
- unsigned int flags = si->flags;
-
- if (si->sensor_bus_type != FIMC_BUS_TYPE_MIPI_CSI2) {
- cfg &= ~(FLITE_REG_CIGCTRL_SELCAM_MIPI |
- FLITE_REG_CIGCTRL_INVPOLPCLK |
- FLITE_REG_CIGCTRL_INVPOLVSYNC |
- FLITE_REG_CIGCTRL_INVPOLHREF);
-
- if (flags & V4L2_MBUS_PCLK_SAMPLE_FALLING)
- cfg |= FLITE_REG_CIGCTRL_INVPOLPCLK;
-
- if (flags & V4L2_MBUS_VSYNC_ACTIVE_LOW)
- cfg |= FLITE_REG_CIGCTRL_INVPOLVSYNC;
-
- if (flags & V4L2_MBUS_HSYNC_ACTIVE_LOW)
- cfg |= FLITE_REG_CIGCTRL_INVPOLHREF;
- } else {
- cfg |= FLITE_REG_CIGCTRL_SELCAM_MIPI;
- }
-
- writel(cfg, dev->regs + FLITE_REG_CIGCTRL);
-
- flite_hw_set_camera_port(dev, si->mux_id);
-}
-
-static void flite_hw_set_pack12(struct fimc_lite *dev, int on)
-{
- u32 cfg = readl(dev->regs + FLITE_REG_CIODMAFMT);
-
- cfg &= ~FLITE_REG_CIODMAFMT_PACK12;
-
- if (on)
- cfg |= FLITE_REG_CIODMAFMT_PACK12;
-
- writel(cfg, dev->regs + FLITE_REG_CIODMAFMT);
-}
-
-static void flite_hw_set_out_order(struct fimc_lite *dev, struct flite_frame *f)
-{
- static const u32 pixcode[4][2] = {
- { MEDIA_BUS_FMT_YUYV8_2X8, FLITE_REG_CIODMAFMT_YCBYCR },
- { MEDIA_BUS_FMT_YVYU8_2X8, FLITE_REG_CIODMAFMT_YCRYCB },
- { MEDIA_BUS_FMT_UYVY8_2X8, FLITE_REG_CIODMAFMT_CBYCRY },
- { MEDIA_BUS_FMT_VYUY8_2X8, FLITE_REG_CIODMAFMT_CRYCBY },
- };
- u32 cfg = readl(dev->regs + FLITE_REG_CIODMAFMT);
- int i = ARRAY_SIZE(pixcode);
-
- while (--i)
- if (pixcode[i][0] == f->fmt->mbus_code)
- break;
- cfg &= ~FLITE_REG_CIODMAFMT_YCBCR_ORDER_MASK;
- writel(cfg | pixcode[i][1], dev->regs + FLITE_REG_CIODMAFMT);
-}
-
-void flite_hw_set_dma_window(struct fimc_lite *dev, struct flite_frame *f)
-{
- u32 cfg;
-
- /* Maximum output pixel size */
- cfg = readl(dev->regs + FLITE_REG_CIOCAN);
- cfg &= ~FLITE_REG_CIOCAN_MASK;
- cfg |= (f->f_height << 16) | f->f_width;
- writel(cfg, dev->regs + FLITE_REG_CIOCAN);
-
- /* DMA offsets */
- cfg = readl(dev->regs + FLITE_REG_CIOOFF);
- cfg &= ~FLITE_REG_CIOOFF_MASK;
- cfg |= (f->rect.top << 16) | f->rect.left;
- writel(cfg, dev->regs + FLITE_REG_CIOOFF);
-}
-
-void flite_hw_set_dma_buffer(struct fimc_lite *dev, struct flite_buffer *buf)
-{
- unsigned int index;
- u32 cfg;
-
- if (dev->dd->max_dma_bufs == 1)
- index = 0;
- else
- index = buf->index;
-
- if (index == 0)
- writel(buf->addr, dev->regs + FLITE_REG_CIOSA);
- else
- writel(buf->addr, dev->regs + FLITE_REG_CIOSAN(index - 1));
-
- cfg = readl(dev->regs + FLITE_REG_CIFCNTSEQ);
- cfg |= BIT(index);
- writel(cfg, dev->regs + FLITE_REG_CIFCNTSEQ);
-}
-
-void flite_hw_mask_dma_buffer(struct fimc_lite *dev, u32 index)
-{
- u32 cfg;
-
- if (dev->dd->max_dma_bufs == 1)
- index = 0;
-
- cfg = readl(dev->regs + FLITE_REG_CIFCNTSEQ);
- cfg &= ~BIT(index);
- writel(cfg, dev->regs + FLITE_REG_CIFCNTSEQ);
-}
-
-/* Enable/disable output DMA, set output pixel size and offsets (composition) */
-void flite_hw_set_output_dma(struct fimc_lite *dev, struct flite_frame *f,
- bool enable)
-{
- u32 cfg = readl(dev->regs + FLITE_REG_CIGCTRL);
-
- if (!enable) {
- cfg |= FLITE_REG_CIGCTRL_ODMA_DISABLE;
- writel(cfg, dev->regs + FLITE_REG_CIGCTRL);
- return;
- }
-
- cfg &= ~FLITE_REG_CIGCTRL_ODMA_DISABLE;
- writel(cfg, dev->regs + FLITE_REG_CIGCTRL);
-
- flite_hw_set_out_order(dev, f);
- flite_hw_set_dma_window(dev, f);
- flite_hw_set_pack12(dev, 0);
-}
-
-void flite_hw_dump_regs(struct fimc_lite *dev, const char *label)
-{
- struct {
- u32 offset;
- const char * const name;
- } registers[] = {
- { 0x00, "CISRCSIZE" },
- { 0x04, "CIGCTRL" },
- { 0x08, "CIIMGCPT" },
- { 0x0c, "CICPTSEQ" },
- { 0x10, "CIWDOFST" },
- { 0x14, "CIWDOFST2" },
- { 0x18, "CIODMAFMT" },
- { 0x20, "CIOCAN" },
- { 0x24, "CIOOFF" },
- { 0x30, "CIOSA" },
- { 0x40, "CISTATUS" },
- { 0x44, "CISTATUS2" },
- { 0xf0, "CITHOLD" },
- { 0xfc, "CIGENERAL" },
- };
- u32 i;
-
- v4l2_info(&dev->subdev, "--- %s ---\n", label);
-
- for (i = 0; i < ARRAY_SIZE(registers); i++) {
- u32 cfg = readl(dev->regs + registers[i].offset);
- v4l2_info(&dev->subdev, "%9s: 0x%08x\n",
- registers[i].name, cfg);
- }
-}
diff --git a/drivers/media/platform/exynos4-is/fimc-lite-reg.h b/drivers/media/platform/exynos4-is/fimc-lite-reg.h
deleted file mode 100644
index c5656e902750..000000000000
--- a/drivers/media/platform/exynos4-is/fimc-lite-reg.h
+++ /dev/null
@@ -1,155 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-only */
-/*
- * Copyright (C) 2012 Samsung Electronics Co., Ltd.
- */
-
-#ifndef FIMC_LITE_REG_H_
-#define FIMC_LITE_REG_H_
-
-#include <linux/bitops.h>
-
-#include "fimc-lite.h"
-
-/* Camera Source size */
-#define FLITE_REG_CISRCSIZE 0x00
-#define FLITE_REG_CISRCSIZE_ORDER422_IN_YCBYCR (0 << 14)
-#define FLITE_REG_CISRCSIZE_ORDER422_IN_YCRYCB (1 << 14)
-#define FLITE_REG_CISRCSIZE_ORDER422_IN_CBYCRY (2 << 14)
-#define FLITE_REG_CISRCSIZE_ORDER422_IN_CRYCBY (3 << 14)
-#define FLITE_REG_CISRCSIZE_ORDER422_MASK (0x3 << 14)
-#define FLITE_REG_CISRCSIZE_SIZE_CAM_MASK (0x3fff << 16 | 0x3fff)
-
-/* Global control */
-#define FLITE_REG_CIGCTRL 0x04
-#define FLITE_REG_CIGCTRL_YUV422_1P (0x1e << 24)
-#define FLITE_REG_CIGCTRL_RAW8 (0x2a << 24)
-#define FLITE_REG_CIGCTRL_RAW10 (0x2b << 24)
-#define FLITE_REG_CIGCTRL_RAW12 (0x2c << 24)
-#define FLITE_REG_CIGCTRL_RAW14 (0x2d << 24)
-/* User defined formats. x = 0...15 */
-#define FLITE_REG_CIGCTRL_USER(x) ((0x30 + x - 1) << 24)
-#define FLITE_REG_CIGCTRL_FMT_MASK (0x3f << 24)
-#define FLITE_REG_CIGCTRL_SHADOWMASK_DISABLE BIT(21)
-#define FLITE_REG_CIGCTRL_ODMA_DISABLE BIT(20)
-#define FLITE_REG_CIGCTRL_SWRST_REQ BIT(19)
-#define FLITE_REG_CIGCTRL_SWRST_RDY BIT(18)
-#define FLITE_REG_CIGCTRL_SWRST BIT(17)
-#define FLITE_REG_CIGCTRL_TEST_PATTERN_COLORBAR BIT(15)
-#define FLITE_REG_CIGCTRL_INVPOLPCLK BIT(14)
-#define FLITE_REG_CIGCTRL_INVPOLVSYNC BIT(13)
-#define FLITE_REG_CIGCTRL_INVPOLHREF BIT(12)
-/* Interrupts mask bits (1 disables an interrupt) */
-#define FLITE_REG_CIGCTRL_IRQ_LASTEN BIT(8)
-#define FLITE_REG_CIGCTRL_IRQ_ENDEN BIT(7)
-#define FLITE_REG_CIGCTRL_IRQ_STARTEN BIT(6)
-#define FLITE_REG_CIGCTRL_IRQ_OVFEN BIT(5)
-#define FLITE_REG_CIGCTRL_IRQ_DISABLE_MASK (0xf << 5)
-#define FLITE_REG_CIGCTRL_SELCAM_MIPI BIT(3)
-
-/* Image Capture Enable */
-#define FLITE_REG_CIIMGCPT 0x08
-#define FLITE_REG_CIIMGCPT_IMGCPTEN BIT(31)
-#define FLITE_REG_CIIMGCPT_CPT_FREN BIT(25)
-#define FLITE_REG_CIIMGCPT_CPT_MOD_FRCNT (1 << 18)
-#define FLITE_REG_CIIMGCPT_CPT_MOD_FREN (0 << 18)
-
-/* Capture Sequence */
-#define FLITE_REG_CICPTSEQ 0x0c
-
-/* Camera Window Offset */
-#define FLITE_REG_CIWDOFST 0x10
-#define FLITE_REG_CIWDOFST_WINOFSEN BIT(31)
-#define FLITE_REG_CIWDOFST_CLROVIY BIT(31)
-#define FLITE_REG_CIWDOFST_CLROVFICB BIT(15)
-#define FLITE_REG_CIWDOFST_CLROVFICR BIT(14)
-#define FLITE_REG_CIWDOFST_OFST_MASK ((0x1fff << 16) | 0x1fff)
-
-/* Camera Window Offset2 */
-#define FLITE_REG_CIWDOFST2 0x14
-
-/* Camera Output DMA Format */
-#define FLITE_REG_CIODMAFMT 0x18
-#define FLITE_REG_CIODMAFMT_RAW_CON BIT(15)
-#define FLITE_REG_CIODMAFMT_PACK12 BIT(14)
-#define FLITE_REG_CIODMAFMT_YCBYCR (0 << 4)
-#define FLITE_REG_CIODMAFMT_YCRYCB (1 << 4)
-#define FLITE_REG_CIODMAFMT_CBYCRY (2 << 4)
-#define FLITE_REG_CIODMAFMT_CRYCBY (3 << 4)
-#define FLITE_REG_CIODMAFMT_YCBCR_ORDER_MASK (0x3 << 4)
-
-/* Camera Output Canvas */
-#define FLITE_REG_CIOCAN 0x20
-#define FLITE_REG_CIOCAN_MASK ((0x3fff << 16) | 0x3fff)
-
-/* Camera Output DMA Offset */
-#define FLITE_REG_CIOOFF 0x24
-#define FLITE_REG_CIOOFF_MASK ((0x3fff << 16) | 0x3fff)
-
-/* Camera Output DMA Start Address */
-#define FLITE_REG_CIOSA 0x30
-
-/* Camera Status */
-#define FLITE_REG_CISTATUS 0x40
-#define FLITE_REG_CISTATUS_MIPI_VVALID BIT(22)
-#define FLITE_REG_CISTATUS_MIPI_HVALID BIT(21)
-#define FLITE_REG_CISTATUS_MIPI_DVALID BIT(20)
-#define FLITE_REG_CISTATUS_ITU_VSYNC BIT(14)
-#define FLITE_REG_CISTATUS_ITU_HREFF BIT(13)
-#define FLITE_REG_CISTATUS_OVFIY BIT(10)
-#define FLITE_REG_CISTATUS_OVFICB BIT(9)
-#define FLITE_REG_CISTATUS_OVFICR BIT(8)
-#define FLITE_REG_CISTATUS_IRQ_SRC_OVERFLOW BIT(7)
-#define FLITE_REG_CISTATUS_IRQ_SRC_LASTCAPEND BIT(6)
-#define FLITE_REG_CISTATUS_IRQ_SRC_FRMSTART BIT(5)
-#define FLITE_REG_CISTATUS_IRQ_SRC_FRMEND BIT(4)
-#define FLITE_REG_CISTATUS_IRQ_CAM BIT(0)
-#define FLITE_REG_CISTATUS_IRQ_MASK (0xf << 4)
-
-/* Camera Status2 */
-#define FLITE_REG_CISTATUS2 0x44
-#define FLITE_REG_CISTATUS2_LASTCAPEND BIT(1)
-#define FLITE_REG_CISTATUS2_FRMEND BIT(0)
-
-/* Qos Threshold */
-#define FLITE_REG_CITHOLD 0xf0
-#define FLITE_REG_CITHOLD_W_QOS_EN BIT(30)
-
-/* Camera General Purpose */
-#define FLITE_REG_CIGENERAL 0xfc
-/* b0: 1 - camera B, 0 - camera A */
-#define FLITE_REG_CIGENERAL_CAM_B BIT(0)
-
-#define FLITE_REG_CIFCNTSEQ 0x100
-#define FLITE_REG_CIOSAN(x) (0x200 + (4 * (x)))
-
-/* ----------------------------------------------------------------------------
- * Function declarations
- */
-void flite_hw_reset(struct fimc_lite *dev);
-void flite_hw_clear_pending_irq(struct fimc_lite *dev);
-u32 flite_hw_get_interrupt_source(struct fimc_lite *dev);
-void flite_hw_clear_last_capture_end(struct fimc_lite *dev);
-void flite_hw_set_interrupt_mask(struct fimc_lite *dev);
-void flite_hw_capture_start(struct fimc_lite *dev);
-void flite_hw_capture_stop(struct fimc_lite *dev);
-void flite_hw_set_camera_bus(struct fimc_lite *dev,
- struct fimc_source_info *s_info);
-void flite_hw_set_camera_polarity(struct fimc_lite *dev,
- struct fimc_source_info *cam);
-void flite_hw_set_window_offset(struct fimc_lite *dev, struct flite_frame *f);
-void flite_hw_set_source_format(struct fimc_lite *dev, struct flite_frame *f);
-
-void flite_hw_set_output_dma(struct fimc_lite *dev, struct flite_frame *f,
- bool enable);
-void flite_hw_set_dma_window(struct fimc_lite *dev, struct flite_frame *f);
-void flite_hw_set_test_pattern(struct fimc_lite *dev, bool on);
-void flite_hw_dump_regs(struct fimc_lite *dev, const char *label);
-void flite_hw_set_dma_buffer(struct fimc_lite *dev, struct flite_buffer *buf);
-void flite_hw_mask_dma_buffer(struct fimc_lite *dev, u32 index);
-
-static inline void flite_hw_set_dma_buf_mask(struct fimc_lite *dev, u32 mask)
-{
- writel(mask, dev->regs + FLITE_REG_CIFCNTSEQ);
-}
-
-#endif /* FIMC_LITE_REG_H */
diff --git a/drivers/media/platform/exynos4-is/fimc-lite.c b/drivers/media/platform/exynos4-is/fimc-lite.c
deleted file mode 100644
index 2e8f476efc5c..000000000000
--- a/drivers/media/platform/exynos4-is/fimc-lite.c
+++ /dev/null
@@ -1,1673 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-/*
- * Samsung EXYNOS FIMC-LITE (camera host interface) driver
-*
- * Copyright (C) 2012 - 2013 Samsung Electronics Co., Ltd.
- * Author: Sylwester Nawrocki <s.nawrocki@samsung.com>
- */
-#define pr_fmt(fmt) "%s:%d " fmt, __func__, __LINE__
-
-#include <linux/bug.h>
-#include <linux/clk.h>
-#include <linux/device.h>
-#include <linux/errno.h>
-#include <linux/interrupt.h>
-#include <linux/kernel.h>
-#include <linux/list.h>
-#include <linux/module.h>
-#include <linux/of.h>
-#include <linux/types.h>
-#include <linux/platform_device.h>
-#include <linux/pm_runtime.h>
-#include <linux/slab.h>
-#include <linux/videodev2.h>
-
-#include <media/v4l2-device.h>
-#include <media/v4l2-ioctl.h>
-#include <media/v4l2-mem2mem.h>
-#include <media/v4l2-rect.h>
-#include <media/videobuf2-v4l2.h>
-#include <media/videobuf2-dma-contig.h>
-#include <media/drv-intf/exynos-fimc.h>
-
-#include "common.h"
-#include "fimc-core.h"
-#include "fimc-lite.h"
-#include "fimc-lite-reg.h"
-
-static int debug;
-module_param(debug, int, 0644);
-
-static const struct fimc_fmt fimc_lite_formats[] = {
- {
- .fourcc = V4L2_PIX_FMT_YUYV,
- .colorspace = V4L2_COLORSPACE_JPEG,
- .depth = { 16 },
- .color = FIMC_FMT_YCBYCR422,
- .memplanes = 1,
- .mbus_code = MEDIA_BUS_FMT_YUYV8_2X8,
- .flags = FMT_FLAGS_YUV,
- }, {
- .fourcc = V4L2_PIX_FMT_UYVY,
- .colorspace = V4L2_COLORSPACE_JPEG,
- .depth = { 16 },
- .color = FIMC_FMT_CBYCRY422,
- .memplanes = 1,
- .mbus_code = MEDIA_BUS_FMT_UYVY8_2X8,
- .flags = FMT_FLAGS_YUV,
- }, {
- .fourcc = V4L2_PIX_FMT_VYUY,
- .colorspace = V4L2_COLORSPACE_JPEG,
- .depth = { 16 },
- .color = FIMC_FMT_CRYCBY422,
- .memplanes = 1,
- .mbus_code = MEDIA_BUS_FMT_VYUY8_2X8,
- .flags = FMT_FLAGS_YUV,
- }, {
- .fourcc = V4L2_PIX_FMT_YVYU,
- .colorspace = V4L2_COLORSPACE_JPEG,
- .depth = { 16 },
- .color = FIMC_FMT_YCRYCB422,
- .memplanes = 1,
- .mbus_code = MEDIA_BUS_FMT_YVYU8_2X8,
- .flags = FMT_FLAGS_YUV,
- }, {
- .fourcc = V4L2_PIX_FMT_SGRBG8,
- .colorspace = V4L2_COLORSPACE_SRGB,
- .depth = { 8 },
- .color = FIMC_FMT_RAW8,
- .memplanes = 1,
- .mbus_code = MEDIA_BUS_FMT_SGRBG8_1X8,
- .flags = FMT_FLAGS_RAW_BAYER,
- }, {
- .fourcc = V4L2_PIX_FMT_SGRBG10,
- .colorspace = V4L2_COLORSPACE_SRGB,
- .depth = { 16 },
- .color = FIMC_FMT_RAW10,
- .memplanes = 1,
- .mbus_code = MEDIA_BUS_FMT_SGRBG10_1X10,
- .flags = FMT_FLAGS_RAW_BAYER,
- }, {
- .fourcc = V4L2_PIX_FMT_SGRBG12,
- .colorspace = V4L2_COLORSPACE_SRGB,
- .depth = { 16 },
- .color = FIMC_FMT_RAW12,
- .memplanes = 1,
- .mbus_code = MEDIA_BUS_FMT_SGRBG12_1X12,
- .flags = FMT_FLAGS_RAW_BAYER,
- },
-};
-
-/**
- * fimc_lite_find_format - lookup fimc color format by fourcc or media bus code
- * @pixelformat: fourcc to match, ignored if null
- * @mbus_code: media bus code to match, ignored if null
- * @mask: the color format flags to match
- * @index: index to the fimc_lite_formats array, ignored if negative
- */
-static const struct fimc_fmt *fimc_lite_find_format(const u32 *pixelformat,
- const u32 *mbus_code, unsigned int mask, int index)
-{
- const struct fimc_fmt *fmt, *def_fmt = NULL;
- unsigned int i;
- int id = 0;
-
- if (index >= (int)ARRAY_SIZE(fimc_lite_formats))
- return NULL;
-
- for (i = 0; i < ARRAY_SIZE(fimc_lite_formats); ++i) {
- fmt = &fimc_lite_formats[i];
- if (mask && !(fmt->flags & mask))
- continue;
- if (pixelformat && fmt->fourcc == *pixelformat)
- return fmt;
- if (mbus_code && fmt->mbus_code == *mbus_code)
- return fmt;
- if (index == id)
- def_fmt = fmt;
- id++;
- }
- return def_fmt;
-}
-
-static int fimc_lite_hw_init(struct fimc_lite *fimc, bool isp_output)
-{
- struct fimc_source_info *si;
- unsigned long flags;
-
- if (fimc->sensor == NULL)
- return -ENXIO;
-
- if (fimc->inp_frame.fmt == NULL || fimc->out_frame.fmt == NULL)
- return -EINVAL;
-
- /* Get sensor configuration data from the sensor subdev */
- si = v4l2_get_subdev_hostdata(fimc->sensor);
- if (!si)
- return -EINVAL;
-
- spin_lock_irqsave(&fimc->slock, flags);
-
- flite_hw_set_camera_bus(fimc, si);
- flite_hw_set_source_format(fimc, &fimc->inp_frame);
- flite_hw_set_window_offset(fimc, &fimc->inp_frame);
- flite_hw_set_dma_buf_mask(fimc, 0);
- flite_hw_set_output_dma(fimc, &fimc->out_frame, !isp_output);
- flite_hw_set_interrupt_mask(fimc);
- flite_hw_set_test_pattern(fimc, fimc->test_pattern->val);
-
- if (debug > 0)
- flite_hw_dump_regs(fimc, __func__);
-
- spin_unlock_irqrestore(&fimc->slock, flags);
- return 0;
-}
-
-/*
- * Reinitialize the driver so it is ready to start the streaming again.
- * Set fimc->state to indicate stream off and the hardware shut down state.
- * If not suspending (@suspend is false), return any buffers to videobuf2.
- * Otherwise put any owned buffers onto the pending buffers queue, so they
- * can be re-spun when the device is being resumed. Also perform FIMC
- * software reset and disable streaming on the whole pipeline if required.
- */
-static int fimc_lite_reinit(struct fimc_lite *fimc, bool suspend)
-{
- struct flite_buffer *buf;
- unsigned long flags;
- bool streaming;
-
- spin_lock_irqsave(&fimc->slock, flags);
- streaming = fimc->state & (1 << ST_SENSOR_STREAM);
-
- fimc->state &= ~(1 << ST_FLITE_RUN | 1 << ST_FLITE_OFF |
- 1 << ST_FLITE_STREAM | 1 << ST_SENSOR_STREAM);
- if (suspend)
- fimc->state |= (1 << ST_FLITE_SUSPENDED);
- else
- fimc->state &= ~(1 << ST_FLITE_PENDING |
- 1 << ST_FLITE_SUSPENDED);
-
- /* Release unused buffers */
- while (!suspend && !list_empty(&fimc->pending_buf_q)) {
- buf = fimc_lite_pending_queue_pop(fimc);
- vb2_buffer_done(&buf->vb.vb2_buf, VB2_BUF_STATE_ERROR);
- }
- /* If suspending put unused buffers onto pending queue */
- while (!list_empty(&fimc->active_buf_q)) {
- buf = fimc_lite_active_queue_pop(fimc);
- if (suspend)
- fimc_lite_pending_queue_add(fimc, buf);
- else
- vb2_buffer_done(&buf->vb.vb2_buf, VB2_BUF_STATE_ERROR);
- }
-
- spin_unlock_irqrestore(&fimc->slock, flags);
-
- flite_hw_reset(fimc);
-
- if (!streaming)
- return 0;
-
- return fimc_pipeline_call(&fimc->ve, set_stream, 0);
-}
-
-static int fimc_lite_stop_capture(struct fimc_lite *fimc, bool suspend)
-{
- unsigned long flags;
-
- if (!fimc_lite_active(fimc))
- return 0;
-
- spin_lock_irqsave(&fimc->slock, flags);
- set_bit(ST_FLITE_OFF, &fimc->state);
- flite_hw_capture_stop(fimc);
- spin_unlock_irqrestore(&fimc->slock, flags);
-
- wait_event_timeout(fimc->irq_queue,
- !test_bit(ST_FLITE_OFF, &fimc->state),
- (2*HZ/10)); /* 200 ms */
-
- return fimc_lite_reinit(fimc, suspend);
-}
-
-/* Must be called with fimc.slock spinlock held. */
-static void fimc_lite_config_update(struct fimc_lite *fimc)
-{
- flite_hw_set_window_offset(fimc, &fimc->inp_frame);
- flite_hw_set_dma_window(fimc, &fimc->out_frame);
- flite_hw_set_test_pattern(fimc, fimc->test_pattern->val);
- clear_bit(ST_FLITE_CONFIG, &fimc->state);
-}
-
-static irqreturn_t flite_irq_handler(int irq, void *priv)
-{
- struct fimc_lite *fimc = priv;
- struct flite_buffer *vbuf;
- unsigned long flags;
- u32 intsrc;
-
- spin_lock_irqsave(&fimc->slock, flags);
-
- intsrc = flite_hw_get_interrupt_source(fimc);
- flite_hw_clear_pending_irq(fimc);
-
- if (test_and_clear_bit(ST_FLITE_OFF, &fimc->state)) {
- wake_up(&fimc->irq_queue);
- goto done;
- }
-
- if (intsrc & FLITE_REG_CISTATUS_IRQ_SRC_OVERFLOW) {
- clear_bit(ST_FLITE_RUN, &fimc->state);
- fimc->events.data_overflow++;
- }
-
- if (intsrc & FLITE_REG_CISTATUS_IRQ_SRC_LASTCAPEND) {
- flite_hw_clear_last_capture_end(fimc);
- clear_bit(ST_FLITE_STREAM, &fimc->state);
- wake_up(&fimc->irq_queue);
- }
-
- if (atomic_read(&fimc->out_path) != FIMC_IO_DMA)
- goto done;
-
- if ((intsrc & FLITE_REG_CISTATUS_IRQ_SRC_FRMSTART) &&
- test_bit(ST_FLITE_RUN, &fimc->state) &&
- !list_empty(&fimc->pending_buf_q)) {
- vbuf = fimc_lite_pending_queue_pop(fimc);
- flite_hw_set_dma_buffer(fimc, vbuf);
- fimc_lite_active_queue_add(fimc, vbuf);
- }
-
- if ((intsrc & FLITE_REG_CISTATUS_IRQ_SRC_FRMEND) &&
- test_bit(ST_FLITE_RUN, &fimc->state) &&
- !list_empty(&fimc->active_buf_q)) {
- vbuf = fimc_lite_active_queue_pop(fimc);
- vbuf->vb.vb2_buf.timestamp = ktime_get_ns();
- vbuf->vb.sequence = fimc->frame_count++;
- flite_hw_mask_dma_buffer(fimc, vbuf->index);
- vb2_buffer_done(&vbuf->vb.vb2_buf, VB2_BUF_STATE_DONE);
- }
-
- if (test_bit(ST_FLITE_CONFIG, &fimc->state))
- fimc_lite_config_update(fimc);
-
- if (list_empty(&fimc->pending_buf_q)) {
- flite_hw_capture_stop(fimc);
- clear_bit(ST_FLITE_STREAM, &fimc->state);
- }
-done:
- set_bit(ST_FLITE_RUN, &fimc->state);
- spin_unlock_irqrestore(&fimc->slock, flags);
- return IRQ_HANDLED;
-}
-
-static int start_streaming(struct vb2_queue *q, unsigned int count)
-{
- struct fimc_lite *fimc = q->drv_priv;
- unsigned long flags;
- int ret;
-
- spin_lock_irqsave(&fimc->slock, flags);
-
- fimc->buf_index = 0;
- fimc->frame_count = 0;
-
- spin_unlock_irqrestore(&fimc->slock, flags);
-
- ret = fimc_lite_hw_init(fimc, false);
- if (ret) {
- fimc_lite_reinit(fimc, false);
- return ret;
- }
-
- set_bit(ST_FLITE_PENDING, &fimc->state);
-
- if (!list_empty(&fimc->active_buf_q) &&
- !test_and_set_bit(ST_FLITE_STREAM, &fimc->state)) {
- flite_hw_capture_start(fimc);
-
- if (!test_and_set_bit(ST_SENSOR_STREAM, &fimc->state))
- fimc_pipeline_call(&fimc->ve, set_stream, 1);
- }
- if (debug > 0)
- flite_hw_dump_regs(fimc, __func__);
-
- return 0;
-}
-
-static void stop_streaming(struct vb2_queue *q)
-{
- struct fimc_lite *fimc = q->drv_priv;
-
- if (!fimc_lite_active(fimc))
- return;
-
- fimc_lite_stop_capture(fimc, false);
-}
-
-static int queue_setup(struct vb2_queue *vq,
- unsigned int *num_buffers, unsigned int *num_planes,
- unsigned int sizes[], struct device *alloc_devs[])
-{
- struct fimc_lite *fimc = vq->drv_priv;
- struct flite_frame *frame = &fimc->out_frame;
- const struct fimc_fmt *fmt = frame->fmt;
- unsigned long wh = frame->f_width * frame->f_height;
- int i;
-
- if (fmt == NULL)
- return -EINVAL;
-
- if (*num_planes) {
- if (*num_planes != fmt->memplanes)
- return -EINVAL;
- for (i = 0; i < *num_planes; i++)
- if (sizes[i] < (wh * fmt->depth[i]) / 8)
- return -EINVAL;
- return 0;
- }
-
- *num_planes = fmt->memplanes;
-
- for (i = 0; i < fmt->memplanes; i++)
- sizes[i] = (wh * fmt->depth[i]) / 8;
-
- return 0;
-}
-
-static int buffer_prepare(struct vb2_buffer *vb)
-{
- struct vb2_queue *vq = vb->vb2_queue;
- struct fimc_lite *fimc = vq->drv_priv;
- int i;
-
- if (fimc->out_frame.fmt == NULL)
- return -EINVAL;
-
- for (i = 0; i < fimc->out_frame.fmt->memplanes; i++) {
- unsigned long size = fimc->payload[i];
-
- if (vb2_plane_size(vb, i) < size) {
- v4l2_err(&fimc->ve.vdev,
- "User buffer too small (%ld < %ld)\n",
- vb2_plane_size(vb, i), size);
- return -EINVAL;
- }
- vb2_set_plane_payload(vb, i, size);
- }
-
- return 0;
-}
-
-static void buffer_queue(struct vb2_buffer *vb)
-{
- struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
- struct flite_buffer *buf
- = container_of(vbuf, struct flite_buffer, vb);
- struct fimc_lite *fimc = vb2_get_drv_priv(vb->vb2_queue);
- unsigned long flags;
-
- spin_lock_irqsave(&fimc->slock, flags);
- buf->addr = vb2_dma_contig_plane_dma_addr(vb, 0);
-
- buf->index = fimc->buf_index++;
- if (fimc->buf_index >= fimc->reqbufs_count)
- fimc->buf_index = 0;
-
- if (!test_bit(ST_FLITE_SUSPENDED, &fimc->state) &&
- !test_bit(ST_FLITE_STREAM, &fimc->state) &&
- list_empty(&fimc->active_buf_q)) {
- flite_hw_set_dma_buffer(fimc, buf);
- fimc_lite_active_queue_add(fimc, buf);
- } else {
- fimc_lite_pending_queue_add(fimc, buf);
- }
-
- if (vb2_is_streaming(&fimc->vb_queue) &&
- !list_empty(&fimc->pending_buf_q) &&
- !test_and_set_bit(ST_FLITE_STREAM, &fimc->state)) {
- flite_hw_capture_start(fimc);
- spin_unlock_irqrestore(&fimc->slock, flags);
-
- if (!test_and_set_bit(ST_SENSOR_STREAM, &fimc->state))
- fimc_pipeline_call(&fimc->ve, set_stream, 1);
- return;
- }
- spin_unlock_irqrestore(&fimc->slock, flags);
-}
-
-static const struct vb2_ops fimc_lite_qops = {
- .queue_setup = queue_setup,
- .buf_prepare = buffer_prepare,
- .buf_queue = buffer_queue,
- .wait_prepare = vb2_ops_wait_prepare,
- .wait_finish = vb2_ops_wait_finish,
- .start_streaming = start_streaming,
- .stop_streaming = stop_streaming,
-};
-
-static void fimc_lite_clear_event_counters(struct fimc_lite *fimc)
-{
- unsigned long flags;
-
- spin_lock_irqsave(&fimc->slock, flags);
- memset(&fimc->events, 0, sizeof(fimc->events));
- spin_unlock_irqrestore(&fimc->slock, flags);
-}
-
-static int fimc_lite_open(struct file *file)
-{
- struct fimc_lite *fimc = video_drvdata(file);
- struct media_entity *me = &fimc->ve.vdev.entity;
- int ret;
-
- mutex_lock(&fimc->lock);
- if (atomic_read(&fimc->out_path) != FIMC_IO_DMA) {
- ret = -EBUSY;
- goto unlock;
- }
-
- set_bit(ST_FLITE_IN_USE, &fimc->state);
- ret = pm_runtime_resume_and_get(&fimc->pdev->dev);
- if (ret < 0)
- goto err_in_use;
-
- ret = v4l2_fh_open(file);
- if (ret < 0)
- goto err_pm;
-
- if (!v4l2_fh_is_singular_file(file) ||
- atomic_read(&fimc->out_path) != FIMC_IO_DMA)
- goto unlock;
-
- mutex_lock(&me->graph_obj.mdev->graph_mutex);
-
- ret = fimc_pipeline_call(&fimc->ve, open, me, true);
-
- /* Mark video pipeline ending at this video node as in use. */
- if (ret == 0)
- me->use_count++;
-
- mutex_unlock(&me->graph_obj.mdev->graph_mutex);
-
- if (!ret) {
- fimc_lite_clear_event_counters(fimc);
- goto unlock;
- }
-
- v4l2_fh_release(file);
-err_pm:
- pm_runtime_put_sync(&fimc->pdev->dev);
-err_in_use:
- clear_bit(ST_FLITE_IN_USE, &fimc->state);
-unlock:
- mutex_unlock(&fimc->lock);
- return ret;
-}
-
-static int fimc_lite_release(struct file *file)
-{
- struct fimc_lite *fimc = video_drvdata(file);
- struct media_entity *entity = &fimc->ve.vdev.entity;
-
- mutex_lock(&fimc->lock);
-
- if (v4l2_fh_is_singular_file(file) &&
- atomic_read(&fimc->out_path) == FIMC_IO_DMA) {
- if (fimc->streaming) {
- media_pipeline_stop(entity);
- fimc->streaming = false;
- }
- fimc_lite_stop_capture(fimc, false);
- fimc_pipeline_call(&fimc->ve, close);
- clear_bit(ST_FLITE_IN_USE, &fimc->state);
-
- mutex_lock(&entity->graph_obj.mdev->graph_mutex);
- entity->use_count--;
- mutex_unlock(&entity->graph_obj.mdev->graph_mutex);
- }
-
- _vb2_fop_release(file, NULL);
- pm_runtime_put(&fimc->pdev->dev);
- clear_bit(ST_FLITE_SUSPENDED, &fimc->state);
-
- mutex_unlock(&fimc->lock);
- return 0;
-}
-
-static const struct v4l2_file_operations fimc_lite_fops = {
- .owner = THIS_MODULE,
- .open = fimc_lite_open,
- .release = fimc_lite_release,
- .poll = vb2_fop_poll,
- .unlocked_ioctl = video_ioctl2,
- .mmap = vb2_fop_mmap,
-};
-
-/*
- * Format and crop negotiation helpers
- */
-
-static const struct fimc_fmt *fimc_lite_subdev_try_fmt(struct fimc_lite *fimc,
- struct v4l2_subdev_state *sd_state,
- struct v4l2_subdev_format *format)
-{
- struct flite_drvdata *dd = fimc->dd;
- struct v4l2_mbus_framefmt *mf = &format->format;
- const struct fimc_fmt *fmt = NULL;
-
- if (format->pad == FLITE_SD_PAD_SINK) {
- v4l_bound_align_image(&mf->width, 8, dd->max_width,
- ffs(dd->out_width_align) - 1,
- &mf->height, 0, dd->max_height, 0, 0);
-
- fmt = fimc_lite_find_format(NULL, &mf->code, 0, 0);
- if (WARN_ON(!fmt))
- return NULL;
-
- mf->colorspace = fmt->colorspace;
- mf->code = fmt->mbus_code;
- } else {
- struct flite_frame *sink = &fimc->inp_frame;
- struct v4l2_mbus_framefmt *sink_fmt;
- struct v4l2_rect *rect;
-
- if (format->which == V4L2_SUBDEV_FORMAT_TRY) {
- sink_fmt = v4l2_subdev_get_try_format(&fimc->subdev,
- sd_state,
- FLITE_SD_PAD_SINK);
-
- mf->code = sink_fmt->code;
- mf->colorspace = sink_fmt->colorspace;
-
- rect = v4l2_subdev_get_try_crop(&fimc->subdev,
- sd_state,
- FLITE_SD_PAD_SINK);
- } else {
- mf->code = sink->fmt->mbus_code;
- mf->colorspace = sink->fmt->colorspace;
- rect = &sink->rect;
- }
-
- /* Allow changing format only on sink pad */
- mf->width = rect->width;
- mf->height = rect->height;
- }
-
- mf->field = V4L2_FIELD_NONE;
-
- v4l2_dbg(1, debug, &fimc->subdev, "code: %#x (%d), %dx%d\n",
- mf->code, mf->colorspace, mf->width, mf->height);
-
- return fmt;
-}
-
-static void fimc_lite_try_crop(struct fimc_lite *fimc, struct v4l2_rect *r)
-{
- struct flite_frame *frame = &fimc->inp_frame;
-
- v4l_bound_align_image(&r->width, 0, frame->f_width, 0,
- &r->height, 0, frame->f_height, 0, 0);
-
- /* Adjust left/top if cropping rectangle got out of bounds */
- r->left = clamp_t(u32, r->left, 0, frame->f_width - r->width);
- r->left = round_down(r->left, fimc->dd->win_hor_offs_align);
- r->top = clamp_t(u32, r->top, 0, frame->f_height - r->height);
-
- v4l2_dbg(1, debug, &fimc->subdev, "(%d,%d)/%dx%d, sink fmt: %dx%d\n",
- r->left, r->top, r->width, r->height,
- frame->f_width, frame->f_height);
-}
-
-static void fimc_lite_try_compose(struct fimc_lite *fimc, struct v4l2_rect *r)
-{
- struct flite_frame *frame = &fimc->out_frame;
- struct v4l2_rect *crop_rect = &fimc->inp_frame.rect;
-
- /* Scaling is not supported so we enforce compose rectangle size
- same as size of the sink crop rectangle. */
- r->width = crop_rect->width;
- r->height = crop_rect->height;
-
- /* Adjust left/top if the composing rectangle got out of bounds */
- r->left = clamp_t(u32, r->left, 0, frame->f_width - r->width);
- r->left = round_down(r->left, fimc->dd->out_hor_offs_align);
- r->top = clamp_t(u32, r->top, 0, fimc->out_frame.f_height - r->height);
-
- v4l2_dbg(1, debug, &fimc->subdev, "(%d,%d)/%dx%d, source fmt: %dx%d\n",
- r->left, r->top, r->width, r->height,
- frame->f_width, frame->f_height);
-}
-
-/*
- * Video node ioctl operations
- */
-static int fimc_lite_querycap(struct file *file, void *priv,
- struct v4l2_capability *cap)
-{
- struct fimc_lite *fimc = video_drvdata(file);
-
- strscpy(cap->driver, FIMC_LITE_DRV_NAME, sizeof(cap->driver));
- strscpy(cap->card, FIMC_LITE_DRV_NAME, sizeof(cap->card));
- snprintf(cap->bus_info, sizeof(cap->bus_info), "platform:%s",
- dev_name(&fimc->pdev->dev));
- return 0;
-}
-
-static int fimc_lite_enum_fmt(struct file *file, void *priv,
- struct v4l2_fmtdesc *f)
-{
- const struct fimc_fmt *fmt;
-
- if (f->index >= ARRAY_SIZE(fimc_lite_formats))
- return -EINVAL;
-
- fmt = &fimc_lite_formats[f->index];
- f->pixelformat = fmt->fourcc;
-
- return 0;
-}
-
-static int fimc_lite_g_fmt_mplane(struct file *file, void *fh,
- struct v4l2_format *f)
-{
- struct fimc_lite *fimc = video_drvdata(file);
- struct v4l2_pix_format_mplane *pixm = &f->fmt.pix_mp;
- struct v4l2_plane_pix_format *plane_fmt = &pixm->plane_fmt[0];
- struct flite_frame *frame = &fimc->out_frame;
- const struct fimc_fmt *fmt = frame->fmt;
-
- plane_fmt->bytesperline = (frame->f_width * fmt->depth[0]) / 8;
- plane_fmt->sizeimage = plane_fmt->bytesperline * frame->f_height;
-
- pixm->num_planes = fmt->memplanes;
- pixm->pixelformat = fmt->fourcc;
- pixm->width = frame->f_width;
- pixm->height = frame->f_height;
- pixm->field = V4L2_FIELD_NONE;
- pixm->colorspace = fmt->colorspace;
- return 0;
-}
-
-static int fimc_lite_try_fmt(struct fimc_lite *fimc,
- struct v4l2_pix_format_mplane *pixm,
- const struct fimc_fmt **ffmt)
-{
- u32 bpl = pixm->plane_fmt[0].bytesperline;
- struct flite_drvdata *dd = fimc->dd;
- const struct fimc_fmt *inp_fmt = fimc->inp_frame.fmt;
- const struct fimc_fmt *fmt;
-
- if (WARN_ON(inp_fmt == NULL))
- return -EINVAL;
- /*
- * We allow some flexibility only for YUV formats. In case of raw
- * raw Bayer the FIMC-LITE's output format must match its camera
- * interface input format.
- */
- if (inp_fmt->flags & FMT_FLAGS_YUV)
- fmt = fimc_lite_find_format(&pixm->pixelformat, NULL,
- inp_fmt->flags, 0);
- else
- fmt = inp_fmt;
-
- if (WARN_ON(fmt == NULL))
- return -EINVAL;
- if (ffmt)
- *ffmt = fmt;
- v4l_bound_align_image(&pixm->width, 8, dd->max_width,
- ffs(dd->out_width_align) - 1,
- &pixm->height, 0, dd->max_height, 0, 0);
-
- if ((bpl == 0 || ((bpl * 8) / fmt->depth[0]) < pixm->width))
- pixm->plane_fmt[0].bytesperline = (pixm->width *
- fmt->depth[0]) / 8;
-
- if (pixm->plane_fmt[0].sizeimage == 0)
- pixm->plane_fmt[0].sizeimage = (pixm->width * pixm->height *
- fmt->depth[0]) / 8;
- pixm->num_planes = fmt->memplanes;
- pixm->pixelformat = fmt->fourcc;
- pixm->colorspace = fmt->colorspace;
- pixm->field = V4L2_FIELD_NONE;
- return 0;
-}
-
-static int fimc_lite_try_fmt_mplane(struct file *file, void *fh,
- struct v4l2_format *f)
-{
- struct fimc_lite *fimc = video_drvdata(file);
- return fimc_lite_try_fmt(fimc, &f->fmt.pix_mp, NULL);
-}
-
-static int fimc_lite_s_fmt_mplane(struct file *file, void *priv,
- struct v4l2_format *f)
-{
- struct v4l2_pix_format_mplane *pixm = &f->fmt.pix_mp;
- struct fimc_lite *fimc = video_drvdata(file);
- struct flite_frame *frame = &fimc->out_frame;
- const struct fimc_fmt *fmt = NULL;
- int ret;
-
- if (vb2_is_busy(&fimc->vb_queue))
- return -EBUSY;
-
- ret = fimc_lite_try_fmt(fimc, &f->fmt.pix_mp, &fmt);
- if (ret < 0)
- return ret;
-
- frame->fmt = fmt;
- fimc->payload[0] = max((pixm->width * pixm->height * fmt->depth[0]) / 8,
- pixm->plane_fmt[0].sizeimage);
- frame->f_width = pixm->width;
- frame->f_height = pixm->height;
-
- return 0;
-}
-
-static int fimc_pipeline_validate(struct fimc_lite *fimc)
-{
- struct v4l2_subdev *sd = &fimc->subdev;
- struct v4l2_subdev_format sink_fmt, src_fmt;
- struct media_pad *pad;
- int ret;
-
- while (1) {
- /* Retrieve format at the sink pad */
- pad = &sd->entity.pads[0];
- if (!(pad->flags & MEDIA_PAD_FL_SINK))
- break;
- /* Don't call FIMC subdev operation to avoid nested locking */
- if (sd == &fimc->subdev) {
- struct flite_frame *ff = &fimc->out_frame;
- sink_fmt.format.width = ff->f_width;
- sink_fmt.format.height = ff->f_height;
- sink_fmt.format.code = fimc->inp_frame.fmt->mbus_code;
- } else {
- sink_fmt.pad = pad->index;
- sink_fmt.which = V4L2_SUBDEV_FORMAT_ACTIVE;
- ret = v4l2_subdev_call(sd, pad, get_fmt, NULL,
- &sink_fmt);
- if (ret < 0 && ret != -ENOIOCTLCMD)
- return -EPIPE;
- }
- /* Retrieve format at the source pad */
- pad = media_entity_remote_pad(pad);
- if (!pad || !is_media_entity_v4l2_subdev(pad->entity))
- break;
-
- sd = media_entity_to_v4l2_subdev(pad->entity);
- src_fmt.pad = pad->index;
- src_fmt.which = V4L2_SUBDEV_FORMAT_ACTIVE;
- ret = v4l2_subdev_call(sd, pad, get_fmt, NULL, &src_fmt);
- if (ret < 0 && ret != -ENOIOCTLCMD)
- return -EPIPE;
-
- if (src_fmt.format.width != sink_fmt.format.width ||
- src_fmt.format.height != sink_fmt.format.height ||
- src_fmt.format.code != sink_fmt.format.code)
- return -EPIPE;
- }
- return 0;
-}
-
-static int fimc_lite_streamon(struct file *file, void *priv,
- enum v4l2_buf_type type)
-{
- struct fimc_lite *fimc = video_drvdata(file);
- struct media_entity *entity = &fimc->ve.vdev.entity;
- int ret;
-
- if (fimc_lite_active(fimc))
- return -EBUSY;
-
- ret = media_pipeline_start(entity, &fimc->ve.pipe->mp);
- if (ret < 0)
- return ret;
-
- ret = fimc_pipeline_validate(fimc);
- if (ret < 0)
- goto err_p_stop;
-
- fimc->sensor = fimc_find_remote_sensor(&fimc->subdev.entity);
-
- ret = vb2_ioctl_streamon(file, priv, type);
- if (!ret) {
- fimc->streaming = true;
- return ret;
- }
-
-err_p_stop:
- media_pipeline_stop(entity);
- return 0;
-}
-
-static int fimc_lite_streamoff(struct file *file, void *priv,
- enum v4l2_buf_type type)
-{
- struct fimc_lite *fimc = video_drvdata(file);
- int ret;
-
- ret = vb2_ioctl_streamoff(file, priv, type);
- if (ret < 0)
- return ret;
-
- media_pipeline_stop(&fimc->ve.vdev.entity);
- fimc->streaming = false;
- return 0;
-}
-
-static int fimc_lite_reqbufs(struct file *file, void *priv,
- struct v4l2_requestbuffers *reqbufs)
-{
- struct fimc_lite *fimc = video_drvdata(file);
- int ret;
-
- reqbufs->count = max_t(u32, FLITE_REQ_BUFS_MIN, reqbufs->count);
- ret = vb2_ioctl_reqbufs(file, priv, reqbufs);
- if (!ret)
- fimc->reqbufs_count = reqbufs->count;
-
- return ret;
-}
-
-static int fimc_lite_g_selection(struct file *file, void *fh,
- struct v4l2_selection *sel)
-{
- struct fimc_lite *fimc = video_drvdata(file);
- struct flite_frame *f = &fimc->out_frame;
-
- if (sel->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
- return -EINVAL;
-
- switch (sel->target) {
- case V4L2_SEL_TGT_COMPOSE_BOUNDS:
- case V4L2_SEL_TGT_COMPOSE_DEFAULT:
- sel->r.left = 0;
- sel->r.top = 0;
- sel->r.width = f->f_width;
- sel->r.height = f->f_height;
- return 0;
-
- case V4L2_SEL_TGT_COMPOSE:
- sel->r = f->rect;
- return 0;
- }
-
- return -EINVAL;
-}
-
-static int fimc_lite_s_selection(struct file *file, void *fh,
- struct v4l2_selection *sel)
-{
- struct fimc_lite *fimc = video_drvdata(file);
- struct flite_frame *f = &fimc->out_frame;
- struct v4l2_rect rect = sel->r;
- unsigned long flags;
-
- if (sel->type != V4L2_BUF_TYPE_VIDEO_CAPTURE ||
- sel->target != V4L2_SEL_TGT_COMPOSE)
- return -EINVAL;
-
- fimc_lite_try_compose(fimc, &rect);
-
- if ((sel->flags & V4L2_SEL_FLAG_LE) &&
- !v4l2_rect_enclosed(&rect, &sel->r))
- return -ERANGE;
-
- if ((sel->flags & V4L2_SEL_FLAG_GE) &&
- !v4l2_rect_enclosed(&sel->r, &rect))
- return -ERANGE;
-
- sel->r = rect;
- spin_lock_irqsave(&fimc->slock, flags);
- f->rect = rect;
- set_bit(ST_FLITE_CONFIG, &fimc->state);
- spin_unlock_irqrestore(&fimc->slock, flags);
-
- return 0;
-}
-
-static const struct v4l2_ioctl_ops fimc_lite_ioctl_ops = {
- .vidioc_querycap = fimc_lite_querycap,
- .vidioc_enum_fmt_vid_cap = fimc_lite_enum_fmt,
- .vidioc_try_fmt_vid_cap_mplane = fimc_lite_try_fmt_mplane,
- .vidioc_s_fmt_vid_cap_mplane = fimc_lite_s_fmt_mplane,
- .vidioc_g_fmt_vid_cap_mplane = fimc_lite_g_fmt_mplane,
- .vidioc_g_selection = fimc_lite_g_selection,
- .vidioc_s_selection = fimc_lite_s_selection,
- .vidioc_reqbufs = fimc_lite_reqbufs,
- .vidioc_querybuf = vb2_ioctl_querybuf,
- .vidioc_prepare_buf = vb2_ioctl_prepare_buf,
- .vidioc_create_bufs = vb2_ioctl_create_bufs,
- .vidioc_qbuf = vb2_ioctl_qbuf,
- .vidioc_dqbuf = vb2_ioctl_dqbuf,
- .vidioc_streamon = fimc_lite_streamon,
- .vidioc_streamoff = fimc_lite_streamoff,
-};
-
-/* Capture subdev media entity operations */
-static int fimc_lite_link_setup(struct media_entity *entity,
- const struct media_pad *local,
- const struct media_pad *remote, u32 flags)
-{
- struct v4l2_subdev *sd = media_entity_to_v4l2_subdev(entity);
- struct fimc_lite *fimc = v4l2_get_subdevdata(sd);
- int ret = 0;
-
- if (WARN_ON(fimc == NULL))
- return 0;
-
- v4l2_dbg(1, debug, sd, "%s: %s --> %s, flags: 0x%x. source_id: 0x%x\n",
- __func__, remote->entity->name, local->entity->name,
- flags, fimc->source_subdev_grp_id);
-
- switch (local->index) {
- case FLITE_SD_PAD_SINK:
- if (flags & MEDIA_LNK_FL_ENABLED) {
- if (fimc->source_subdev_grp_id == 0)
- fimc->source_subdev_grp_id = sd->grp_id;
- else
- ret = -EBUSY;
- } else {
- fimc->source_subdev_grp_id = 0;
- fimc->sensor = NULL;
- }
- break;
-
- case FLITE_SD_PAD_SOURCE_DMA:
- if (!(flags & MEDIA_LNK_FL_ENABLED))
- atomic_set(&fimc->out_path, FIMC_IO_NONE);
- else
- atomic_set(&fimc->out_path, FIMC_IO_DMA);
- break;
-
- case FLITE_SD_PAD_SOURCE_ISP:
- if (!(flags & MEDIA_LNK_FL_ENABLED))
- atomic_set(&fimc->out_path, FIMC_IO_NONE);
- else
- atomic_set(&fimc->out_path, FIMC_IO_ISP);
- break;
-
- default:
- v4l2_err(sd, "Invalid pad index\n");
- ret = -EINVAL;
- }
- mb();
-
- return ret;
-}
-
-static const struct media_entity_operations fimc_lite_subdev_media_ops = {
- .link_setup = fimc_lite_link_setup,
-};
-
-static int fimc_lite_subdev_enum_mbus_code(struct v4l2_subdev *sd,
- struct v4l2_subdev_state *sd_state,
- struct v4l2_subdev_mbus_code_enum *code)
-{
- const struct fimc_fmt *fmt;
-
- fmt = fimc_lite_find_format(NULL, NULL, 0, code->index);
- if (!fmt)
- return -EINVAL;
- code->code = fmt->mbus_code;
- return 0;
-}
-
-static struct v4l2_mbus_framefmt *__fimc_lite_subdev_get_try_fmt(
- struct v4l2_subdev *sd,
- struct v4l2_subdev_state *sd_state, unsigned int pad)
-{
- if (pad != FLITE_SD_PAD_SINK)
- pad = FLITE_SD_PAD_SOURCE_DMA;
-
- return v4l2_subdev_get_try_format(sd, sd_state, pad);
-}
-
-static int fimc_lite_subdev_get_fmt(struct v4l2_subdev *sd,
- struct v4l2_subdev_state *sd_state,
- struct v4l2_subdev_format *fmt)
-{
- struct fimc_lite *fimc = v4l2_get_subdevdata(sd);
- struct v4l2_mbus_framefmt *mf = &fmt->format;
- struct flite_frame *f = &fimc->inp_frame;
-
- if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) {
- mf = __fimc_lite_subdev_get_try_fmt(sd, sd_state, fmt->pad);
- fmt->format = *mf;
- return 0;
- }
-
- mutex_lock(&fimc->lock);
- mf->colorspace = f->fmt->colorspace;
- mf->code = f->fmt->mbus_code;
-
- if (fmt->pad == FLITE_SD_PAD_SINK) {
- /* full camera input frame size */
- mf->width = f->f_width;
- mf->height = f->f_height;
- } else {
- /* crop size */
- mf->width = f->rect.width;
- mf->height = f->rect.height;
- }
- mutex_unlock(&fimc->lock);
- return 0;
-}
-
-static int fimc_lite_subdev_set_fmt(struct v4l2_subdev *sd,
- struct v4l2_subdev_state *sd_state,
- struct v4l2_subdev_format *fmt)
-{
- struct fimc_lite *fimc = v4l2_get_subdevdata(sd);
- struct v4l2_mbus_framefmt *mf = &fmt->format;
- struct flite_frame *sink = &fimc->inp_frame;
- struct flite_frame *source = &fimc->out_frame;
- const struct fimc_fmt *ffmt;
-
- v4l2_dbg(1, debug, sd, "pad%d: code: 0x%x, %dx%d\n",
- fmt->pad, mf->code, mf->width, mf->height);
-
- mutex_lock(&fimc->lock);
-
- if ((atomic_read(&fimc->out_path) == FIMC_IO_ISP &&
- media_entity_is_streaming(&sd->entity)) ||
- (atomic_read(&fimc->out_path) == FIMC_IO_DMA &&
- vb2_is_busy(&fimc->vb_queue))) {
- mutex_unlock(&fimc->lock);
- return -EBUSY;
- }
-
- ffmt = fimc_lite_subdev_try_fmt(fimc, sd_state, fmt);
-
- if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) {
- struct v4l2_mbus_framefmt *src_fmt;
-
- mf = __fimc_lite_subdev_get_try_fmt(sd, sd_state, fmt->pad);
- *mf = fmt->format;
-
- if (fmt->pad == FLITE_SD_PAD_SINK) {
- unsigned int pad = FLITE_SD_PAD_SOURCE_DMA;
- src_fmt = __fimc_lite_subdev_get_try_fmt(sd, sd_state,
- pad);
- *src_fmt = *mf;
- }
-
- mutex_unlock(&fimc->lock);
- return 0;
- }
-
- if (fmt->pad == FLITE_SD_PAD_SINK) {
- sink->f_width = mf->width;
- sink->f_height = mf->height;
- sink->fmt = ffmt;
- /* Set sink crop rectangle */
- sink->rect.width = mf->width;
- sink->rect.height = mf->height;
- sink->rect.left = 0;
- sink->rect.top = 0;
- /* Reset source format and crop rectangle */
- source->rect = sink->rect;
- source->f_width = mf->width;
- source->f_height = mf->height;
- }
-
- mutex_unlock(&fimc->lock);
- return 0;
-}
-
-static int fimc_lite_subdev_get_selection(struct v4l2_subdev *sd,
- struct v4l2_subdev_state *sd_state,
- struct v4l2_subdev_selection *sel)
-{
- struct fimc_lite *fimc = v4l2_get_subdevdata(sd);
- struct flite_frame *f = &fimc->inp_frame;
-
- if ((sel->target != V4L2_SEL_TGT_CROP &&
- sel->target != V4L2_SEL_TGT_CROP_BOUNDS) ||
- sel->pad != FLITE_SD_PAD_SINK)
- return -EINVAL;
-
- if (sel->which == V4L2_SUBDEV_FORMAT_TRY) {
- sel->r = *v4l2_subdev_get_try_crop(sd, sd_state, sel->pad);
- return 0;
- }
-
- mutex_lock(&fimc->lock);
- if (sel->target == V4L2_SEL_TGT_CROP) {
- sel->r = f->rect;
- } else {
- sel->r.left = 0;
- sel->r.top = 0;
- sel->r.width = f->f_width;
- sel->r.height = f->f_height;
- }
- mutex_unlock(&fimc->lock);
-
- v4l2_dbg(1, debug, sd, "%s: (%d,%d) %dx%d, f_w: %d, f_h: %d\n",
- __func__, f->rect.left, f->rect.top, f->rect.width,
- f->rect.height, f->f_width, f->f_height);
-
- return 0;
-}
-
-static int fimc_lite_subdev_set_selection(struct v4l2_subdev *sd,
- struct v4l2_subdev_state *sd_state,
- struct v4l2_subdev_selection *sel)
-{
- struct fimc_lite *fimc = v4l2_get_subdevdata(sd);
- struct flite_frame *f = &fimc->inp_frame;
- int ret = 0;
-
- if (sel->target != V4L2_SEL_TGT_CROP || sel->pad != FLITE_SD_PAD_SINK)
- return -EINVAL;
-
- mutex_lock(&fimc->lock);
- fimc_lite_try_crop(fimc, &sel->r);
-
- if (sel->which == V4L2_SUBDEV_FORMAT_TRY) {
- *v4l2_subdev_get_try_crop(sd, sd_state, sel->pad) = sel->r;
- } else {
- unsigned long flags;
- spin_lock_irqsave(&fimc->slock, flags);
- f->rect = sel->r;
- /* Same crop rectangle on the source pad */
- fimc->out_frame.rect = sel->r;
- set_bit(ST_FLITE_CONFIG, &fimc->state);
- spin_unlock_irqrestore(&fimc->slock, flags);
- }
- mutex_unlock(&fimc->lock);
-
- v4l2_dbg(1, debug, sd, "%s: (%d,%d) %dx%d, f_w: %d, f_h: %d\n",
- __func__, f->rect.left, f->rect.top, f->rect.width,
- f->rect.height, f->f_width, f->f_height);
-
- return ret;
-}
-
-static int fimc_lite_subdev_s_stream(struct v4l2_subdev *sd, int on)
-{
- struct fimc_lite *fimc = v4l2_get_subdevdata(sd);
- unsigned long flags;
- int ret;
-
- /*
- * Find sensor subdev linked to FIMC-LITE directly or through
- * MIPI-CSIS. This is required for configuration where FIMC-LITE
- * is used as a subdev only and feeds data internally to FIMC-IS.
- * The pipeline links are protected through entity.pipe so there is no
- * need to take the media graph mutex here.
- */
- fimc->sensor = fimc_find_remote_sensor(&sd->entity);
-
- if (atomic_read(&fimc->out_path) != FIMC_IO_ISP)
- return -ENOIOCTLCMD;
-
- mutex_lock(&fimc->lock);
- if (on) {
- flite_hw_reset(fimc);
- ret = fimc_lite_hw_init(fimc, true);
- if (!ret) {
- spin_lock_irqsave(&fimc->slock, flags);
- flite_hw_capture_start(fimc);
- spin_unlock_irqrestore(&fimc->slock, flags);
- }
- } else {
- set_bit(ST_FLITE_OFF, &fimc->state);
-
- spin_lock_irqsave(&fimc->slock, flags);
- flite_hw_capture_stop(fimc);
- spin_unlock_irqrestore(&fimc->slock, flags);
-
- ret = wait_event_timeout(fimc->irq_queue,
- !test_bit(ST_FLITE_OFF, &fimc->state),
- msecs_to_jiffies(200));
- if (ret == 0)
- v4l2_err(sd, "s_stream(0) timeout\n");
- clear_bit(ST_FLITE_RUN, &fimc->state);
- }
-
- mutex_unlock(&fimc->lock);
- return ret;
-}
-
-static int fimc_lite_log_status(struct v4l2_subdev *sd)
-{
- struct fimc_lite *fimc = v4l2_get_subdevdata(sd);
-
- flite_hw_dump_regs(fimc, __func__);
- return 0;
-}
-
-static int fimc_lite_subdev_registered(struct v4l2_subdev *sd)
-{
- struct fimc_lite *fimc = v4l2_get_subdevdata(sd);
- struct vb2_queue *q = &fimc->vb_queue;
- struct video_device *vfd = &fimc->ve.vdev;
- int ret;
-
- memset(vfd, 0, sizeof(*vfd));
- atomic_set(&fimc->out_path, FIMC_IO_DMA);
-
- snprintf(vfd->name, sizeof(vfd->name), "fimc-lite.%d.capture",
- fimc->index);
-
- vfd->fops = &fimc_lite_fops;
- vfd->ioctl_ops = &fimc_lite_ioctl_ops;
- vfd->v4l2_dev = sd->v4l2_dev;
- vfd->minor = -1;
- vfd->release = video_device_release_empty;
- vfd->queue = q;
- vfd->device_caps = V4L2_CAP_VIDEO_CAPTURE_MPLANE | V4L2_CAP_STREAMING;
- fimc->reqbufs_count = 0;
-
- INIT_LIST_HEAD(&fimc->pending_buf_q);
- INIT_LIST_HEAD(&fimc->active_buf_q);
-
- memset(q, 0, sizeof(*q));
- q->type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
- q->io_modes = VB2_MMAP | VB2_USERPTR;
- q->ops = &fimc_lite_qops;
- q->mem_ops = &vb2_dma_contig_memops;
- q->buf_struct_size = sizeof(struct flite_buffer);
- q->drv_priv = fimc;
- q->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
- q->lock = &fimc->lock;
- q->dev = &fimc->pdev->dev;
-
- ret = vb2_queue_init(q);
- if (ret < 0)
- return ret;
-
- fimc->vd_pad.flags = MEDIA_PAD_FL_SINK;
- ret = media_entity_pads_init(&vfd->entity, 1, &fimc->vd_pad);
- if (ret < 0)
- return ret;
-
- video_set_drvdata(vfd, fimc);
- fimc->ve.pipe = v4l2_get_subdev_hostdata(sd);
-
- ret = video_register_device(vfd, VFL_TYPE_VIDEO, -1);
- if (ret < 0) {
- media_entity_cleanup(&vfd->entity);
- fimc->ve.pipe = NULL;
- return ret;
- }
-
- v4l2_info(sd->v4l2_dev, "Registered %s as /dev/%s\n",
- vfd->name, video_device_node_name(vfd));
- return 0;
-}
-
-static void fimc_lite_subdev_unregistered(struct v4l2_subdev *sd)
-{
- struct fimc_lite *fimc = v4l2_get_subdevdata(sd);
-
- if (fimc == NULL)
- return;
-
- mutex_lock(&fimc->lock);
-
- if (video_is_registered(&fimc->ve.vdev)) {
- video_unregister_device(&fimc->ve.vdev);
- media_entity_cleanup(&fimc->ve.vdev.entity);
- fimc->ve.pipe = NULL;
- }
-
- mutex_unlock(&fimc->lock);
-}
-
-static const struct v4l2_subdev_internal_ops fimc_lite_subdev_internal_ops = {
- .registered = fimc_lite_subdev_registered,
- .unregistered = fimc_lite_subdev_unregistered,
-};
-
-static const struct v4l2_subdev_pad_ops fimc_lite_subdev_pad_ops = {
- .enum_mbus_code = fimc_lite_subdev_enum_mbus_code,
- .get_selection = fimc_lite_subdev_get_selection,
- .set_selection = fimc_lite_subdev_set_selection,
- .get_fmt = fimc_lite_subdev_get_fmt,
- .set_fmt = fimc_lite_subdev_set_fmt,
-};
-
-static const struct v4l2_subdev_video_ops fimc_lite_subdev_video_ops = {
- .s_stream = fimc_lite_subdev_s_stream,
-};
-
-static const struct v4l2_subdev_core_ops fimc_lite_core_ops = {
- .log_status = fimc_lite_log_status,
-};
-
-static const struct v4l2_subdev_ops fimc_lite_subdev_ops = {
- .core = &fimc_lite_core_ops,
- .video = &fimc_lite_subdev_video_ops,
- .pad = &fimc_lite_subdev_pad_ops,
-};
-
-static int fimc_lite_s_ctrl(struct v4l2_ctrl *ctrl)
-{
- struct fimc_lite *fimc = container_of(ctrl->handler, struct fimc_lite,
- ctrl_handler);
- set_bit(ST_FLITE_CONFIG, &fimc->state);
- return 0;
-}
-
-static const struct v4l2_ctrl_ops fimc_lite_ctrl_ops = {
- .s_ctrl = fimc_lite_s_ctrl,
-};
-
-static const struct v4l2_ctrl_config fimc_lite_ctrl = {
- .ops = &fimc_lite_ctrl_ops,
- .id = V4L2_CTRL_CLASS_USER | 0x1001,
- .type = V4L2_CTRL_TYPE_BOOLEAN,
- .name = "Test Pattern 640x480",
- .step = 1,
-};
-
-static void fimc_lite_set_default_config(struct fimc_lite *fimc)
-{
- struct flite_frame *sink = &fimc->inp_frame;
- struct flite_frame *source = &fimc->out_frame;
-
- sink->fmt = &fimc_lite_formats[0];
- sink->f_width = FLITE_DEFAULT_WIDTH;
- sink->f_height = FLITE_DEFAULT_HEIGHT;
-
- sink->rect.width = FLITE_DEFAULT_WIDTH;
- sink->rect.height = FLITE_DEFAULT_HEIGHT;
- sink->rect.left = 0;
- sink->rect.top = 0;
-
- *source = *sink;
-}
-
-static int fimc_lite_create_capture_subdev(struct fimc_lite *fimc)
-{
- struct v4l2_ctrl_handler *handler = &fimc->ctrl_handler;
- struct v4l2_subdev *sd = &fimc->subdev;
- int ret;
-
- v4l2_subdev_init(sd, &fimc_lite_subdev_ops);
- sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
- snprintf(sd->name, sizeof(sd->name), "FIMC-LITE.%d", fimc->index);
-
- fimc->subdev_pads[FLITE_SD_PAD_SINK].flags = MEDIA_PAD_FL_SINK;
- fimc->subdev_pads[FLITE_SD_PAD_SOURCE_DMA].flags = MEDIA_PAD_FL_SOURCE;
- fimc->subdev_pads[FLITE_SD_PAD_SOURCE_ISP].flags = MEDIA_PAD_FL_SOURCE;
- ret = media_entity_pads_init(&sd->entity, FLITE_SD_PADS_NUM,
- fimc->subdev_pads);
- if (ret)
- return ret;
-
- v4l2_ctrl_handler_init(handler, 1);
- fimc->test_pattern = v4l2_ctrl_new_custom(handler, &fimc_lite_ctrl,
- NULL);
- if (handler->error) {
- media_entity_cleanup(&sd->entity);
- return handler->error;
- }
-
- sd->ctrl_handler = handler;
- sd->internal_ops = &fimc_lite_subdev_internal_ops;
- sd->entity.function = MEDIA_ENT_F_PROC_VIDEO_SCALER;
- sd->entity.ops = &fimc_lite_subdev_media_ops;
- sd->owner = THIS_MODULE;
- v4l2_set_subdevdata(sd, fimc);
-
- return 0;
-}
-
-static void fimc_lite_unregister_capture_subdev(struct fimc_lite *fimc)
-{
- struct v4l2_subdev *sd = &fimc->subdev;
-
- v4l2_device_unregister_subdev(sd);
- media_entity_cleanup(&sd->entity);
- v4l2_ctrl_handler_free(&fimc->ctrl_handler);
- v4l2_set_subdevdata(sd, NULL);
-}
-
-static void fimc_lite_clk_put(struct fimc_lite *fimc)
-{
- if (IS_ERR(fimc->clock))
- return;
-
- clk_put(fimc->clock);
- fimc->clock = ERR_PTR(-EINVAL);
-}
-
-static int fimc_lite_clk_get(struct fimc_lite *fimc)
-{
- fimc->clock = clk_get(&fimc->pdev->dev, FLITE_CLK_NAME);
- return PTR_ERR_OR_ZERO(fimc->clock);
-}
-
-static const struct of_device_id flite_of_match[];
-
-static int fimc_lite_probe(struct platform_device *pdev)
-{
- struct flite_drvdata *drv_data = NULL;
- struct device *dev = &pdev->dev;
- const struct of_device_id *of_id;
- struct fimc_lite *fimc;
- struct resource *res;
- int ret;
- int irq;
-
- if (!dev->of_node)
- return -ENODEV;
-
- fimc = devm_kzalloc(dev, sizeof(*fimc), GFP_KERNEL);
- if (!fimc)
- return -ENOMEM;
-
- of_id = of_match_node(flite_of_match, dev->of_node);
- if (of_id)
- drv_data = (struct flite_drvdata *)of_id->data;
- fimc->index = of_alias_get_id(dev->of_node, "fimc-lite");
-
- if (!drv_data || fimc->index >= drv_data->num_instances ||
- fimc->index < 0) {
- dev_err(dev, "Wrong %pOF node alias\n", dev->of_node);
- return -EINVAL;
- }
-
- fimc->dd = drv_data;
- fimc->pdev = pdev;
-
- init_waitqueue_head(&fimc->irq_queue);
- spin_lock_init(&fimc->slock);
- mutex_init(&fimc->lock);
-
- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- fimc->regs = devm_ioremap_resource(dev, res);
- if (IS_ERR(fimc->regs))
- return PTR_ERR(fimc->regs);
-
- irq = platform_get_irq(pdev, 0);
- if (irq < 0)
- return irq;
-
- ret = fimc_lite_clk_get(fimc);
- if (ret)
- return ret;
-
- ret = devm_request_irq(dev, irq, flite_irq_handler,
- 0, dev_name(dev), fimc);
- if (ret) {
- dev_err(dev, "Failed to install irq (%d)\n", ret);
- goto err_clk_put;
- }
-
- /* The video node will be created within the subdev's registered() op */
- ret = fimc_lite_create_capture_subdev(fimc);
- if (ret)
- goto err_clk_put;
-
- platform_set_drvdata(pdev, fimc);
- pm_runtime_enable(dev);
-
- if (!pm_runtime_enabled(dev)) {
- ret = clk_prepare_enable(fimc->clock);
- if (ret < 0)
- goto err_sd;
- }
-
- vb2_dma_contig_set_max_seg_size(dev, DMA_BIT_MASK(32));
-
- fimc_lite_set_default_config(fimc);
-
- dev_dbg(dev, "FIMC-LITE.%d registered successfully\n",
- fimc->index);
- return 0;
-
-err_sd:
- fimc_lite_unregister_capture_subdev(fimc);
-err_clk_put:
- fimc_lite_clk_put(fimc);
- return ret;
-}
-
-#ifdef CONFIG_PM
-static int fimc_lite_runtime_resume(struct device *dev)
-{
- struct fimc_lite *fimc = dev_get_drvdata(dev);
-
- clk_prepare_enable(fimc->clock);
- return 0;
-}
-
-static int fimc_lite_runtime_suspend(struct device *dev)
-{
- struct fimc_lite *fimc = dev_get_drvdata(dev);
-
- clk_disable_unprepare(fimc->clock);
- return 0;
-}
-#endif
-
-#ifdef CONFIG_PM_SLEEP
-static int fimc_lite_resume(struct device *dev)
-{
- struct fimc_lite *fimc = dev_get_drvdata(dev);
- struct flite_buffer *buf;
- unsigned long flags;
- int i;
-
- spin_lock_irqsave(&fimc->slock, flags);
- if (!test_and_clear_bit(ST_LPM, &fimc->state) ||
- !test_bit(ST_FLITE_IN_USE, &fimc->state)) {
- spin_unlock_irqrestore(&fimc->slock, flags);
- return 0;
- }
- flite_hw_reset(fimc);
- spin_unlock_irqrestore(&fimc->slock, flags);
-
- if (!test_and_clear_bit(ST_FLITE_SUSPENDED, &fimc->state))
- return 0;
-
- INIT_LIST_HEAD(&fimc->active_buf_q);
- fimc_pipeline_call(&fimc->ve, open,
- &fimc->ve.vdev.entity, false);
- fimc_lite_hw_init(fimc, atomic_read(&fimc->out_path) == FIMC_IO_ISP);
- clear_bit(ST_FLITE_SUSPENDED, &fimc->state);
-
- for (i = 0; i < fimc->reqbufs_count; i++) {
- if (list_empty(&fimc->pending_buf_q))
- break;
- buf = fimc_lite_pending_queue_pop(fimc);
- buffer_queue(&buf->vb.vb2_buf);
- }
- return 0;
-}
-
-static int fimc_lite_suspend(struct device *dev)
-{
- struct fimc_lite *fimc = dev_get_drvdata(dev);
- bool suspend = test_bit(ST_FLITE_IN_USE, &fimc->state);
- int ret;
-
- if (test_and_set_bit(ST_LPM, &fimc->state))
- return 0;
-
- ret = fimc_lite_stop_capture(fimc, suspend);
- if (ret < 0 || !fimc_lite_active(fimc))
- return ret;
-
- return fimc_pipeline_call(&fimc->ve, close);
-}
-#endif /* CONFIG_PM_SLEEP */
-
-static int fimc_lite_remove(struct platform_device *pdev)
-{
- struct fimc_lite *fimc = platform_get_drvdata(pdev);
- struct device *dev = &pdev->dev;
-
- if (!pm_runtime_enabled(dev))
- clk_disable_unprepare(fimc->clock);
-
- pm_runtime_disable(dev);
- pm_runtime_set_suspended(dev);
- fimc_lite_unregister_capture_subdev(fimc);
- vb2_dma_contig_clear_max_seg_size(dev);
- fimc_lite_clk_put(fimc);
-
- dev_info(dev, "Driver unloaded\n");
- return 0;
-}
-
-static const struct dev_pm_ops fimc_lite_pm_ops = {
- SET_SYSTEM_SLEEP_PM_OPS(fimc_lite_suspend, fimc_lite_resume)
- SET_RUNTIME_PM_OPS(fimc_lite_runtime_suspend, fimc_lite_runtime_resume,
- NULL)
-};
-
-/* EXYNOS4412 */
-static struct flite_drvdata fimc_lite_drvdata_exynos4 = {
- .max_width = 8192,
- .max_height = 8192,
- .out_width_align = 8,
- .win_hor_offs_align = 2,
- .out_hor_offs_align = 8,
- .max_dma_bufs = 1,
- .num_instances = 2,
-};
-
-/* EXYNOS5250 */
-static struct flite_drvdata fimc_lite_drvdata_exynos5 = {
- .max_width = 8192,
- .max_height = 8192,
- .out_width_align = 8,
- .win_hor_offs_align = 2,
- .out_hor_offs_align = 8,
- .max_dma_bufs = 32,
- .num_instances = 3,
-};
-
-static const struct of_device_id flite_of_match[] = {
- {
- .compatible = "samsung,exynos4212-fimc-lite",
- .data = &fimc_lite_drvdata_exynos4,
- },
- {
- .compatible = "samsung,exynos5250-fimc-lite",
- .data = &fimc_lite_drvdata_exynos5,
- },
- { /* sentinel */ },
-};
-MODULE_DEVICE_TABLE(of, flite_of_match);
-
-static struct platform_driver fimc_lite_driver = {
- .probe = fimc_lite_probe,
- .remove = fimc_lite_remove,
- .driver = {
- .of_match_table = flite_of_match,
- .name = FIMC_LITE_DRV_NAME,
- .pm = &fimc_lite_pm_ops,
- }
-};
-module_platform_driver(fimc_lite_driver);
-MODULE_LICENSE("GPL");
-MODULE_ALIAS("platform:" FIMC_LITE_DRV_NAME);
diff --git a/drivers/media/platform/exynos4-is/fimc-lite.h b/drivers/media/platform/exynos4-is/fimc-lite.h
deleted file mode 100644
index ddf29e0b5b1c..000000000000
--- a/drivers/media/platform/exynos4-is/fimc-lite.h
+++ /dev/null
@@ -1,224 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-only */
-/*
- * Copyright (C) 2012 Samsung Electronics Co., Ltd.
- */
-
-#ifndef FIMC_LITE_H_
-#define FIMC_LITE_H_
-
-#include <linux/sizes.h>
-#include <linux/io.h>
-#include <linux/irqreturn.h>
-#include <linux/platform_device.h>
-#include <linux/sched.h>
-#include <linux/spinlock.h>
-#include <linux/types.h>
-#include <linux/videodev2.h>
-
-#include <media/media-entity.h>
-#include <media/videobuf2-v4l2.h>
-#include <media/v4l2-ctrls.h>
-#include <media/v4l2-device.h>
-#include <media/v4l2-mediabus.h>
-#include <media/drv-intf/exynos-fimc.h>
-
-#define FIMC_LITE_DRV_NAME "exynos-fimc-lite"
-#define FLITE_CLK_NAME "flite"
-#define FIMC_LITE_MAX_DEVS 3
-#define FLITE_REQ_BUFS_MIN 2
-#define FLITE_DEFAULT_WIDTH 640
-#define FLITE_DEFAULT_HEIGHT 480
-
-/* Bit index definitions for struct fimc_lite::state */
-enum {
- ST_FLITE_LPM,
- ST_FLITE_PENDING,
- ST_FLITE_RUN,
- ST_FLITE_STREAM,
- ST_FLITE_SUSPENDED,
- ST_FLITE_OFF,
- ST_FLITE_IN_USE,
- ST_FLITE_CONFIG,
- ST_SENSOR_STREAM,
-};
-
-#define FLITE_SD_PAD_SINK 0
-#define FLITE_SD_PAD_SOURCE_DMA 1
-#define FLITE_SD_PAD_SOURCE_ISP 2
-#define FLITE_SD_PADS_NUM 3
-
-/**
- * struct flite_drvdata - FIMC-LITE IP variant data structure
- * @max_width: maximum camera interface input width in pixels
- * @max_height: maximum camera interface input height in pixels
- * @out_width_align: minimum output width alignment in pixels
- * @win_hor_offs_align: minimum camera interface crop window horizontal
- * offset alignment in pixels
- * @out_hor_offs_align: minimum output DMA compose rectangle horizontal
- * offset alignment in pixels
- * @max_dma_bufs: number of output DMA buffer start address registers
- * @num_instances: total number of FIMC-LITE IP instances available
- */
-struct flite_drvdata {
- unsigned short max_width;
- unsigned short max_height;
- unsigned short out_width_align;
- unsigned short win_hor_offs_align;
- unsigned short out_hor_offs_align;
- unsigned short max_dma_bufs;
- unsigned short num_instances;
-};
-
-struct fimc_lite_events {
- unsigned int data_overflow;
-};
-
-#define FLITE_MAX_PLANES 1
-
-/**
- * struct flite_frame - source/target frame properties
- * @f_width: full pixel width
- * @f_height: full pixel height
- * @rect: crop/composition rectangle
- * @fmt: pointer to pixel format description data structure
- */
-struct flite_frame {
- u16 f_width;
- u16 f_height;
- struct v4l2_rect rect;
- const struct fimc_fmt *fmt;
-};
-
-/**
- * struct flite_buffer - video buffer structure
- * @vb: vb2 buffer
- * @list: list head for the buffers queue
- * @addr: DMA buffer start address
- * @index: DMA start address register's index
- */
-struct flite_buffer {
- struct vb2_v4l2_buffer vb;
- struct list_head list;
- dma_addr_t addr;
- unsigned short index;
-};
-
-/**
- * struct fimc_lite - fimc lite structure
- * @pdev: pointer to FIMC-LITE platform device
- * @dd: SoC specific driver data structure
- * @ve: exynos video device entity structure
- * @v4l2_dev: pointer to top the level v4l2_device
- * @fh: v4l2 file handle
- * @subdev: FIMC-LITE subdev
- * @vd_pad: media (sink) pad for the capture video node
- * @subdev_pads: the subdev media pads
- * @sensor: sensor subdev attached to FIMC-LITE directly or through MIPI-CSIS
- * @ctrl_handler: v4l2 control handler
- * @test_pattern: test pattern controls
- * @index: FIMC-LITE platform device index
- * @pipeline: video capture pipeline data structure
- * @pipeline_ops: media pipeline ops for the video node driver
- * @slock: spinlock protecting this data structure and the hw registers
- * @lock: mutex serializing video device and the subdev operations
- * @clock: FIMC-LITE gate clock
- * @regs: memory mapped io registers
- * @irq_queue: interrupt handler waitqueue
- * @payload: image size in bytes (w x h x bpp)
- * @inp_frame: camera input frame structure
- * @out_frame: DMA output frame structure
- * @out_path: output data path (DMA or FIFO)
- * @source_subdev_grp_id: source subdev group id
- * @state: driver state flags
- * @pending_buf_q: pending buffers queue head
- * @active_buf_q: the queue head of buffers scheduled in hardware
- * @vb_queue: vb2 buffers queue
- * @buf_index: helps to keep track of the DMA start address register index
- * @active_buf_count: number of video buffers scheduled in hardware
- * @frame_count: the captured frames counter
- * @reqbufs_count: the number of buffers requested with REQBUFS ioctl
- * @events: event info
- * @streaming: is streaming in progress?
- */
-struct fimc_lite {
- struct platform_device *pdev;
- struct flite_drvdata *dd;
- struct exynos_video_entity ve;
- struct v4l2_device *v4l2_dev;
- struct v4l2_fh fh;
- struct v4l2_subdev subdev;
- struct media_pad vd_pad;
- struct media_pad subdev_pads[FLITE_SD_PADS_NUM];
- struct v4l2_subdev *sensor;
- struct v4l2_ctrl_handler ctrl_handler;
- struct v4l2_ctrl *test_pattern;
- int index;
-
- struct mutex lock;
- spinlock_t slock;
-
- struct clk *clock;
- void __iomem *regs;
- wait_queue_head_t irq_queue;
-
- unsigned long payload[FLITE_MAX_PLANES];
- struct flite_frame inp_frame;
- struct flite_frame out_frame;
- atomic_t out_path;
- unsigned int source_subdev_grp_id;
-
- unsigned long state;
- struct list_head pending_buf_q;
- struct list_head active_buf_q;
- struct vb2_queue vb_queue;
- unsigned short buf_index;
- unsigned int frame_count;
- unsigned int reqbufs_count;
-
- struct fimc_lite_events events;
- bool streaming;
-};
-
-static inline bool fimc_lite_active(struct fimc_lite *fimc)
-{
- unsigned long flags;
- bool ret;
-
- spin_lock_irqsave(&fimc->slock, flags);
- ret = fimc->state & (1 << ST_FLITE_RUN) ||
- fimc->state & (1 << ST_FLITE_PENDING);
- spin_unlock_irqrestore(&fimc->slock, flags);
- return ret;
-}
-
-static inline void fimc_lite_active_queue_add(struct fimc_lite *dev,
- struct flite_buffer *buf)
-{
- list_add_tail(&buf->list, &dev->active_buf_q);
-}
-
-static inline struct flite_buffer *fimc_lite_active_queue_pop(
- struct fimc_lite *dev)
-{
- struct flite_buffer *buf = list_entry(dev->active_buf_q.next,
- struct flite_buffer, list);
- list_del(&buf->list);
- return buf;
-}
-
-static inline void fimc_lite_pending_queue_add(struct fimc_lite *dev,
- struct flite_buffer *buf)
-{
- list_add_tail(&buf->list, &dev->pending_buf_q);
-}
-
-static inline struct flite_buffer *fimc_lite_pending_queue_pop(
- struct fimc_lite *dev)
-{
- struct flite_buffer *buf = list_entry(dev->pending_buf_q.next,
- struct flite_buffer, list);
- list_del(&buf->list);
- return buf;
-}
-
-#endif /* FIMC_LITE_H_ */
diff --git a/drivers/media/platform/exynos4-is/fimc-m2m.c b/drivers/media/platform/exynos4-is/fimc-m2m.c
deleted file mode 100644
index df8e2aa454d8..000000000000
--- a/drivers/media/platform/exynos4-is/fimc-m2m.c
+++ /dev/null
@@ -1,773 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-or-later
-/*
- * Samsung S5P/EXYNOS4 SoC series FIMC (video postprocessor) driver
- *
- * Copyright (C) 2012 - 2013 Samsung Electronics Co., Ltd.
- * Sylwester Nawrocki <s.nawrocki@samsung.com>
- */
-
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/types.h>
-#include <linux/errno.h>
-#include <linux/bug.h>
-#include <linux/interrupt.h>
-#include <linux/device.h>
-#include <linux/platform_device.h>
-#include <linux/pm_runtime.h>
-#include <linux/list.h>
-#include <linux/io.h>
-#include <linux/slab.h>
-#include <linux/clk.h>
-#include <media/v4l2-ioctl.h>
-#include <media/videobuf2-v4l2.h>
-#include <media/videobuf2-dma-contig.h>
-
-#include "common.h"
-#include "fimc-core.h"
-#include "fimc-reg.h"
-#include "media-dev.h"
-
-static unsigned int get_m2m_fmt_flags(unsigned int stream_type)
-{
- if (stream_type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE)
- return FMT_FLAGS_M2M_IN;
- else
- return FMT_FLAGS_M2M_OUT;
-}
-
-void fimc_m2m_job_finish(struct fimc_ctx *ctx, int vb_state)
-{
- struct vb2_v4l2_buffer *src_vb, *dst_vb;
-
- if (!ctx || !ctx->fh.m2m_ctx)
- return;
-
- src_vb = v4l2_m2m_src_buf_remove(ctx->fh.m2m_ctx);
- dst_vb = v4l2_m2m_dst_buf_remove(ctx->fh.m2m_ctx);
-
- if (src_vb)
- v4l2_m2m_buf_done(src_vb, vb_state);
- if (dst_vb)
- v4l2_m2m_buf_done(dst_vb, vb_state);
- if (src_vb && dst_vb)
- v4l2_m2m_job_finish(ctx->fimc_dev->m2m.m2m_dev,
- ctx->fh.m2m_ctx);
-}
-
-/* Complete the transaction which has been scheduled for execution. */
-static void fimc_m2m_shutdown(struct fimc_ctx *ctx)
-{
- struct fimc_dev *fimc = ctx->fimc_dev;
-
- if (!fimc_m2m_pending(fimc))
- return;
-
- fimc_ctx_state_set(FIMC_CTX_SHUT, ctx);
-
- wait_event_timeout(fimc->irq_queue,
- !fimc_ctx_state_is_set(FIMC_CTX_SHUT, ctx),
- FIMC_SHUTDOWN_TIMEOUT);
-}
-
-static int start_streaming(struct vb2_queue *q, unsigned int count)
-{
- struct fimc_ctx *ctx = q->drv_priv;
-
- return pm_runtime_resume_and_get(&ctx->fimc_dev->pdev->dev);
-}
-
-static void stop_streaming(struct vb2_queue *q)
-{
- struct fimc_ctx *ctx = q->drv_priv;
-
- fimc_m2m_shutdown(ctx);
- fimc_m2m_job_finish(ctx, VB2_BUF_STATE_ERROR);
- pm_runtime_put(&ctx->fimc_dev->pdev->dev);
-}
-
-static void fimc_device_run(void *priv)
-{
- struct vb2_v4l2_buffer *src_vb, *dst_vb;
- struct fimc_ctx *ctx = priv;
- struct fimc_frame *sf, *df;
- struct fimc_dev *fimc;
- unsigned long flags;
- int ret;
-
- if (WARN(!ctx, "Null context\n"))
- return;
-
- fimc = ctx->fimc_dev;
- spin_lock_irqsave(&fimc->slock, flags);
-
- set_bit(ST_M2M_PEND, &fimc->state);
- sf = &ctx->s_frame;
- df = &ctx->d_frame;
-
- if (ctx->state & FIMC_PARAMS) {
- /* Prepare the DMA offsets for scaler */
- fimc_prepare_dma_offset(ctx, sf);
- fimc_prepare_dma_offset(ctx, df);
- }
-
- src_vb = v4l2_m2m_next_src_buf(ctx->fh.m2m_ctx);
- ret = fimc_prepare_addr(ctx, &src_vb->vb2_buf, sf, &sf->addr);
- if (ret)
- goto dma_unlock;
-
- dst_vb = v4l2_m2m_next_dst_buf(ctx->fh.m2m_ctx);
- ret = fimc_prepare_addr(ctx, &dst_vb->vb2_buf, df, &df->addr);
- if (ret)
- goto dma_unlock;
-
- dst_vb->vb2_buf.timestamp = src_vb->vb2_buf.timestamp;
- dst_vb->flags &= ~V4L2_BUF_FLAG_TSTAMP_SRC_MASK;
- dst_vb->flags |=
- src_vb->flags & V4L2_BUF_FLAG_TSTAMP_SRC_MASK;
-
- /* Reconfigure hardware if the context has changed. */
- if (fimc->m2m.ctx != ctx) {
- ctx->state |= FIMC_PARAMS;
- fimc->m2m.ctx = ctx;
- }
-
- if (ctx->state & FIMC_PARAMS) {
- fimc_set_yuv_order(ctx);
- fimc_hw_set_input_path(ctx);
- fimc_hw_set_in_dma(ctx);
- ret = fimc_set_scaler_info(ctx);
- if (ret)
- goto dma_unlock;
- fimc_hw_set_prescaler(ctx);
- fimc_hw_set_mainscaler(ctx);
- fimc_hw_set_target_format(ctx);
- fimc_hw_set_rotation(ctx);
- fimc_hw_set_effect(ctx);
- fimc_hw_set_out_dma(ctx);
- if (fimc->drv_data->alpha_color)
- fimc_hw_set_rgb_alpha(ctx);
- fimc_hw_set_output_path(ctx);
- }
- fimc_hw_set_input_addr(fimc, &sf->addr);
- fimc_hw_set_output_addr(fimc, &df->addr, -1);
-
- fimc_activate_capture(ctx);
- ctx->state &= (FIMC_CTX_M2M | FIMC_CTX_CAP);
- fimc_hw_activate_input_dma(fimc, true);
-
-dma_unlock:
- spin_unlock_irqrestore(&fimc->slock, flags);
-}
-
-static void fimc_job_abort(void *priv)
-{
- fimc_m2m_shutdown(priv);
-}
-
-static int fimc_queue_setup(struct vb2_queue *vq,
- unsigned int *num_buffers, unsigned int *num_planes,
- unsigned int sizes[], struct device *alloc_devs[])
-{
- struct fimc_ctx *ctx = vb2_get_drv_priv(vq);
- struct fimc_frame *f;
- int i;
-
- f = ctx_get_frame(ctx, vq->type);
- if (IS_ERR(f))
- return PTR_ERR(f);
- /*
- * Return number of non-contiguous planes (plane buffers)
- * depending on the configured color format.
- */
- if (!f->fmt)
- return -EINVAL;
-
- *num_planes = f->fmt->memplanes;
- for (i = 0; i < f->fmt->memplanes; i++)
- sizes[i] = f->payload[i];
- return 0;
-}
-
-static int fimc_buf_prepare(struct vb2_buffer *vb)
-{
- struct fimc_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue);
- struct fimc_frame *frame;
- int i;
-
- frame = ctx_get_frame(ctx, vb->vb2_queue->type);
- if (IS_ERR(frame))
- return PTR_ERR(frame);
-
- for (i = 0; i < frame->fmt->memplanes; i++)
- vb2_set_plane_payload(vb, i, frame->payload[i]);
-
- return 0;
-}
-
-static void fimc_buf_queue(struct vb2_buffer *vb)
-{
- struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
- struct fimc_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue);
- v4l2_m2m_buf_queue(ctx->fh.m2m_ctx, vbuf);
-}
-
-static const struct vb2_ops fimc_qops = {
- .queue_setup = fimc_queue_setup,
- .buf_prepare = fimc_buf_prepare,
- .buf_queue = fimc_buf_queue,
- .wait_prepare = vb2_ops_wait_prepare,
- .wait_finish = vb2_ops_wait_finish,
- .stop_streaming = stop_streaming,
- .start_streaming = start_streaming,
-};
-
-/*
- * V4L2 ioctl handlers
- */
-static int fimc_m2m_querycap(struct file *file, void *fh,
- struct v4l2_capability *cap)
-{
- struct fimc_dev *fimc = video_drvdata(file);
-
- __fimc_vidioc_querycap(&fimc->pdev->dev, cap);
- return 0;
-}
-
-static int fimc_m2m_enum_fmt(struct file *file, void *priv,
- struct v4l2_fmtdesc *f)
-{
- struct fimc_fmt *fmt;
-
- fmt = fimc_find_format(NULL, NULL, get_m2m_fmt_flags(f->type),
- f->index);
- if (!fmt)
- return -EINVAL;
-
- f->pixelformat = fmt->fourcc;
- return 0;
-}
-
-static int fimc_m2m_g_fmt_mplane(struct file *file, void *fh,
- struct v4l2_format *f)
-{
- struct fimc_ctx *ctx = fh_to_ctx(fh);
- struct fimc_frame *frame = ctx_get_frame(ctx, f->type);
-
- if (IS_ERR(frame))
- return PTR_ERR(frame);
-
- __fimc_get_format(frame, f);
- return 0;
-}
-
-static int fimc_try_fmt_mplane(struct fimc_ctx *ctx, struct v4l2_format *f)
-{
- struct fimc_dev *fimc = ctx->fimc_dev;
- const struct fimc_variant *variant = fimc->variant;
- struct v4l2_pix_format_mplane *pix = &f->fmt.pix_mp;
- struct fimc_fmt *fmt;
- u32 max_w, mod_x, mod_y;
-
- if (!IS_M2M(f->type))
- return -EINVAL;
-
- fmt = fimc_find_format(&pix->pixelformat, NULL,
- get_m2m_fmt_flags(f->type), 0);
- if (WARN(fmt == NULL, "Pixel format lookup failed"))
- return -EINVAL;
-
- if (pix->field == V4L2_FIELD_ANY)
- pix->field = V4L2_FIELD_NONE;
- else if (pix->field != V4L2_FIELD_NONE)
- return -EINVAL;
-
- if (f->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
- max_w = variant->pix_limit->scaler_dis_w;
- mod_x = ffs(variant->min_inp_pixsize) - 1;
- } else {
- max_w = variant->pix_limit->out_rot_dis_w;
- mod_x = ffs(variant->min_out_pixsize) - 1;
- }
-
- if (tiled_fmt(fmt)) {
- mod_x = 6; /* 64 x 32 pixels tile */
- mod_y = 5;
- } else {
- if (variant->min_vsize_align == 1)
- mod_y = fimc_fmt_is_rgb(fmt->color) ? 0 : 1;
- else
- mod_y = ffs(variant->min_vsize_align) - 1;
- }
-
- v4l_bound_align_image(&pix->width, 16, max_w, mod_x,
- &pix->height, 8, variant->pix_limit->scaler_dis_w, mod_y, 0);
-
- fimc_adjust_mplane_format(fmt, pix->width, pix->height, &f->fmt.pix_mp);
- return 0;
-}
-
-static int fimc_m2m_try_fmt_mplane(struct file *file, void *fh,
- struct v4l2_format *f)
-{
- struct fimc_ctx *ctx = fh_to_ctx(fh);
- return fimc_try_fmt_mplane(ctx, f);
-}
-
-static void __set_frame_format(struct fimc_frame *frame, struct fimc_fmt *fmt,
- struct v4l2_pix_format_mplane *pixm)
-{
- int i;
-
- for (i = 0; i < fmt->memplanes; i++) {
- frame->bytesperline[i] = pixm->plane_fmt[i].bytesperline;
- frame->payload[i] = pixm->plane_fmt[i].sizeimage;
- }
-
- frame->f_width = pixm->width;
- frame->f_height = pixm->height;
- frame->o_width = pixm->width;
- frame->o_height = pixm->height;
- frame->width = pixm->width;
- frame->height = pixm->height;
- frame->offs_h = 0;
- frame->offs_v = 0;
- frame->fmt = fmt;
-}
-
-static int fimc_m2m_s_fmt_mplane(struct file *file, void *fh,
- struct v4l2_format *f)
-{
- struct fimc_ctx *ctx = fh_to_ctx(fh);
- struct fimc_dev *fimc = ctx->fimc_dev;
- struct fimc_fmt *fmt;
- struct vb2_queue *vq;
- struct fimc_frame *frame;
- int ret;
-
- ret = fimc_try_fmt_mplane(ctx, f);
- if (ret)
- return ret;
-
- vq = v4l2_m2m_get_vq(ctx->fh.m2m_ctx, f->type);
-
- if (vb2_is_busy(vq)) {
- v4l2_err(&fimc->m2m.vfd, "queue (%d) busy\n", f->type);
- return -EBUSY;
- }
-
- if (f->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE)
- frame = &ctx->s_frame;
- else
- frame = &ctx->d_frame;
-
- fmt = fimc_find_format(&f->fmt.pix_mp.pixelformat, NULL,
- get_m2m_fmt_flags(f->type), 0);
- if (!fmt)
- return -EINVAL;
-
- __set_frame_format(frame, fmt, &f->fmt.pix_mp);
-
- /* Update RGB Alpha control state and value range */
- fimc_alpha_ctrl_update(ctx);
-
- return 0;
-}
-
-static int fimc_m2m_g_selection(struct file *file, void *fh,
- struct v4l2_selection *s)
-{
- struct fimc_ctx *ctx = fh_to_ctx(fh);
- struct fimc_frame *frame;
-
- frame = ctx_get_frame(ctx, s->type);
- if (IS_ERR(frame))
- return PTR_ERR(frame);
-
- switch (s->target) {
- case V4L2_SEL_TGT_CROP:
- case V4L2_SEL_TGT_CROP_DEFAULT:
- case V4L2_SEL_TGT_CROP_BOUNDS:
- if (s->type != V4L2_BUF_TYPE_VIDEO_OUTPUT)
- return -EINVAL;
- break;
- case V4L2_SEL_TGT_COMPOSE:
- case V4L2_SEL_TGT_COMPOSE_DEFAULT:
- case V4L2_SEL_TGT_COMPOSE_BOUNDS:
- if (s->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
- return -EINVAL;
- break;
- default:
- return -EINVAL;
- }
-
- switch (s->target) {
- case V4L2_SEL_TGT_CROP:
- case V4L2_SEL_TGT_COMPOSE:
- s->r.left = frame->offs_h;
- s->r.top = frame->offs_v;
- s->r.width = frame->width;
- s->r.height = frame->height;
- break;
- case V4L2_SEL_TGT_CROP_DEFAULT:
- case V4L2_SEL_TGT_CROP_BOUNDS:
- case V4L2_SEL_TGT_COMPOSE_DEFAULT:
- case V4L2_SEL_TGT_COMPOSE_BOUNDS:
- s->r.left = 0;
- s->r.top = 0;
- s->r.width = frame->o_width;
- s->r.height = frame->o_height;
- break;
- default:
- return -EINVAL;
- }
- return 0;
-}
-
-static int fimc_m2m_try_selection(struct fimc_ctx *ctx,
- struct v4l2_selection *s)
-{
- struct fimc_dev *fimc = ctx->fimc_dev;
- struct fimc_frame *f;
- u32 min_size, halign, depth = 0;
- int i;
-
- if (s->r.top < 0 || s->r.left < 0) {
- v4l2_err(&fimc->m2m.vfd,
- "doesn't support negative values for top & left\n");
- return -EINVAL;
- }
- if (s->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) {
- f = &ctx->d_frame;
- if (s->target != V4L2_SEL_TGT_COMPOSE)
- return -EINVAL;
- } else if (s->type == V4L2_BUF_TYPE_VIDEO_OUTPUT) {
- f = &ctx->s_frame;
- if (s->target != V4L2_SEL_TGT_CROP)
- return -EINVAL;
- } else {
- return -EINVAL;
- }
-
- min_size = (f == &ctx->s_frame) ?
- fimc->variant->min_inp_pixsize : fimc->variant->min_out_pixsize;
-
- /* Get pixel alignment constraints. */
- if (fimc->variant->min_vsize_align == 1)
- halign = fimc_fmt_is_rgb(f->fmt->color) ? 0 : 1;
- else
- halign = ffs(fimc->variant->min_vsize_align) - 1;
-
- for (i = 0; i < f->fmt->memplanes; i++)
- depth += f->fmt->depth[i];
-
- v4l_bound_align_image(&s->r.width, min_size, f->o_width,
- ffs(min_size) - 1,
- &s->r.height, min_size, f->o_height,
- halign, 64/(ALIGN(depth, 8)));
-
- /* adjust left/top if cropping rectangle is out of bounds */
- if (s->r.left + s->r.width > f->o_width)
- s->r.left = f->o_width - s->r.width;
- if (s->r.top + s->r.height > f->o_height)
- s->r.top = f->o_height - s->r.height;
-
- s->r.left = round_down(s->r.left, min_size);
- s->r.top = round_down(s->r.top, fimc->variant->hor_offs_align);
-
- dbg("l:%d, t:%d, w:%d, h:%d, f_w: %d, f_h: %d",
- s->r.left, s->r.top, s->r.width, s->r.height,
- f->f_width, f->f_height);
-
- return 0;
-}
-
-static int fimc_m2m_s_selection(struct file *file, void *fh,
- struct v4l2_selection *s)
-{
- struct fimc_ctx *ctx = fh_to_ctx(fh);
- struct fimc_dev *fimc = ctx->fimc_dev;
- struct fimc_frame *f;
- int ret;
-
- ret = fimc_m2m_try_selection(ctx, s);
- if (ret)
- return ret;
-
- f = (s->type == V4L2_BUF_TYPE_VIDEO_OUTPUT) ?
- &ctx->s_frame : &ctx->d_frame;
-
- /* Check to see if scaling ratio is within supported range */
- if (s->type == V4L2_BUF_TYPE_VIDEO_OUTPUT) {
- ret = fimc_check_scaler_ratio(ctx, s->r.width,
- s->r.height, ctx->d_frame.width,
- ctx->d_frame.height, ctx->rotation);
- } else {
- ret = fimc_check_scaler_ratio(ctx, ctx->s_frame.width,
- ctx->s_frame.height, s->r.width,
- s->r.height, ctx->rotation);
- }
- if (ret) {
- v4l2_err(&fimc->m2m.vfd, "Out of scaler range\n");
- return -EINVAL;
- }
-
- f->offs_h = s->r.left;
- f->offs_v = s->r.top;
- f->width = s->r.width;
- f->height = s->r.height;
-
- fimc_ctx_state_set(FIMC_PARAMS, ctx);
-
- return 0;
-}
-
-static const struct v4l2_ioctl_ops fimc_m2m_ioctl_ops = {
- .vidioc_querycap = fimc_m2m_querycap,
- .vidioc_enum_fmt_vid_cap = fimc_m2m_enum_fmt,
- .vidioc_enum_fmt_vid_out = fimc_m2m_enum_fmt,
- .vidioc_g_fmt_vid_cap_mplane = fimc_m2m_g_fmt_mplane,
- .vidioc_g_fmt_vid_out_mplane = fimc_m2m_g_fmt_mplane,
- .vidioc_try_fmt_vid_cap_mplane = fimc_m2m_try_fmt_mplane,
- .vidioc_try_fmt_vid_out_mplane = fimc_m2m_try_fmt_mplane,
- .vidioc_s_fmt_vid_cap_mplane = fimc_m2m_s_fmt_mplane,
- .vidioc_s_fmt_vid_out_mplane = fimc_m2m_s_fmt_mplane,
- .vidioc_reqbufs = v4l2_m2m_ioctl_reqbufs,
- .vidioc_querybuf = v4l2_m2m_ioctl_querybuf,
- .vidioc_qbuf = v4l2_m2m_ioctl_qbuf,
- .vidioc_dqbuf = v4l2_m2m_ioctl_dqbuf,
- .vidioc_expbuf = v4l2_m2m_ioctl_expbuf,
- .vidioc_streamon = v4l2_m2m_ioctl_streamon,
- .vidioc_streamoff = v4l2_m2m_ioctl_streamoff,
- .vidioc_g_selection = fimc_m2m_g_selection,
- .vidioc_s_selection = fimc_m2m_s_selection,
-
-};
-
-static int queue_init(void *priv, struct vb2_queue *src_vq,
- struct vb2_queue *dst_vq)
-{
- struct fimc_ctx *ctx = priv;
- int ret;
-
- src_vq->type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
- src_vq->io_modes = VB2_MMAP | VB2_USERPTR | VB2_DMABUF;
- src_vq->drv_priv = ctx;
- src_vq->ops = &fimc_qops;
- src_vq->mem_ops = &vb2_dma_contig_memops;
- src_vq->buf_struct_size = sizeof(struct v4l2_m2m_buffer);
- src_vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY;
- src_vq->lock = &ctx->fimc_dev->lock;
- src_vq->dev = &ctx->fimc_dev->pdev->dev;
-
- ret = vb2_queue_init(src_vq);
- if (ret)
- return ret;
-
- dst_vq->type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
- dst_vq->io_modes = VB2_MMAP | VB2_USERPTR | VB2_DMABUF;
- dst_vq->drv_priv = ctx;
- dst_vq->ops = &fimc_qops;
- dst_vq->mem_ops = &vb2_dma_contig_memops;
- dst_vq->buf_struct_size = sizeof(struct v4l2_m2m_buffer);
- dst_vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY;
- dst_vq->lock = &ctx->fimc_dev->lock;
- dst_vq->dev = &ctx->fimc_dev->pdev->dev;
-
- return vb2_queue_init(dst_vq);
-}
-
-static int fimc_m2m_set_default_format(struct fimc_ctx *ctx)
-{
- struct v4l2_pix_format_mplane pixm = {
- .pixelformat = V4L2_PIX_FMT_RGB32,
- .width = 800,
- .height = 600,
- .plane_fmt[0] = {
- .bytesperline = 800 * 4,
- .sizeimage = 800 * 4 * 600,
- },
- };
- struct fimc_fmt *fmt;
-
- fmt = fimc_find_format(&pixm.pixelformat, NULL, FMT_FLAGS_M2M, 0);
- if (!fmt)
- return -EINVAL;
-
- __set_frame_format(&ctx->s_frame, fmt, &pixm);
- __set_frame_format(&ctx->d_frame, fmt, &pixm);
-
- return 0;
-}
-
-static int fimc_m2m_open(struct file *file)
-{
- struct fimc_dev *fimc = video_drvdata(file);
- struct fimc_ctx *ctx;
- int ret = -EBUSY;
-
- pr_debug("pid: %d, state: %#lx\n", task_pid_nr(current), fimc->state);
-
- if (mutex_lock_interruptible(&fimc->lock))
- return -ERESTARTSYS;
- /*
- * Don't allow simultaneous open() of the mem-to-mem and the
- * capture video node that belong to same FIMC IP instance.
- */
- if (test_bit(ST_CAPT_BUSY, &fimc->state))
- goto unlock;
-
- ctx = kzalloc(sizeof(*ctx), GFP_KERNEL);
- if (!ctx) {
- ret = -ENOMEM;
- goto unlock;
- }
- v4l2_fh_init(&ctx->fh, &fimc->m2m.vfd);
- ctx->fimc_dev = fimc;
-
- /* Default color format */
- ctx->s_frame.fmt = fimc_get_format(0);
- ctx->d_frame.fmt = fimc_get_format(0);
-
- ret = fimc_ctrls_create(ctx);
- if (ret)
- goto error_fh;
-
- /* Use separate control handler per file handle */
- ctx->fh.ctrl_handler = &ctx->ctrls.handler;
- file->private_data = &ctx->fh;
- v4l2_fh_add(&ctx->fh);
-
- /* Setup the device context for memory-to-memory mode */
- ctx->state = FIMC_CTX_M2M;
- ctx->flags = 0;
- ctx->in_path = FIMC_IO_DMA;
- ctx->out_path = FIMC_IO_DMA;
- ctx->scaler.enabled = 1;
-
- ctx->fh.m2m_ctx = v4l2_m2m_ctx_init(fimc->m2m.m2m_dev, ctx, queue_init);
- if (IS_ERR(ctx->fh.m2m_ctx)) {
- ret = PTR_ERR(ctx->fh.m2m_ctx);
- goto error_c;
- }
-
- if (fimc->m2m.refcnt++ == 0)
- set_bit(ST_M2M_RUN, &fimc->state);
-
- ret = fimc_m2m_set_default_format(ctx);
- if (ret < 0)
- goto error_m2m_ctx;
-
- mutex_unlock(&fimc->lock);
- return 0;
-
-error_m2m_ctx:
- v4l2_m2m_ctx_release(ctx->fh.m2m_ctx);
-error_c:
- fimc_ctrls_delete(ctx);
- v4l2_fh_del(&ctx->fh);
-error_fh:
- v4l2_fh_exit(&ctx->fh);
- kfree(ctx);
-unlock:
- mutex_unlock(&fimc->lock);
- return ret;
-}
-
-static int fimc_m2m_release(struct file *file)
-{
- struct fimc_ctx *ctx = fh_to_ctx(file->private_data);
- struct fimc_dev *fimc = ctx->fimc_dev;
-
- dbg("pid: %d, state: 0x%lx, refcnt= %d",
- task_pid_nr(current), fimc->state, fimc->m2m.refcnt);
-
- mutex_lock(&fimc->lock);
-
- v4l2_m2m_ctx_release(ctx->fh.m2m_ctx);
- fimc_ctrls_delete(ctx);
- v4l2_fh_del(&ctx->fh);
- v4l2_fh_exit(&ctx->fh);
-
- if (--fimc->m2m.refcnt <= 0)
- clear_bit(ST_M2M_RUN, &fimc->state);
- kfree(ctx);
-
- mutex_unlock(&fimc->lock);
- return 0;
-}
-
-static const struct v4l2_file_operations fimc_m2m_fops = {
- .owner = THIS_MODULE,
- .open = fimc_m2m_open,
- .release = fimc_m2m_release,
- .poll = v4l2_m2m_fop_poll,
- .unlocked_ioctl = video_ioctl2,
- .mmap = v4l2_m2m_fop_mmap,
-};
-
-static const struct v4l2_m2m_ops m2m_ops = {
- .device_run = fimc_device_run,
- .job_abort = fimc_job_abort,
-};
-
-int fimc_register_m2m_device(struct fimc_dev *fimc,
- struct v4l2_device *v4l2_dev)
-{
- struct video_device *vfd = &fimc->m2m.vfd;
- int ret;
-
- fimc->v4l2_dev = v4l2_dev;
-
- memset(vfd, 0, sizeof(*vfd));
- vfd->fops = &fimc_m2m_fops;
- vfd->ioctl_ops = &fimc_m2m_ioctl_ops;
- vfd->v4l2_dev = v4l2_dev;
- vfd->minor = -1;
- vfd->release = video_device_release_empty;
- vfd->lock = &fimc->lock;
- vfd->vfl_dir = VFL_DIR_M2M;
- vfd->device_caps = V4L2_CAP_STREAMING | V4L2_CAP_VIDEO_M2M_MPLANE;
- set_bit(V4L2_FL_QUIRK_INVERTED_CROP, &vfd->flags);
-
- snprintf(vfd->name, sizeof(vfd->name), "fimc.%d.m2m", fimc->id);
- video_set_drvdata(vfd, fimc);
-
- fimc->m2m.m2m_dev = v4l2_m2m_init(&m2m_ops);
- if (IS_ERR(fimc->m2m.m2m_dev)) {
- v4l2_err(v4l2_dev, "failed to initialize v4l2-m2m device\n");
- return PTR_ERR(fimc->m2m.m2m_dev);
- }
-
- ret = media_entity_pads_init(&vfd->entity, 0, NULL);
- if (ret)
- goto err_me;
-
- ret = video_register_device(vfd, VFL_TYPE_VIDEO, -1);
- if (ret)
- goto err_vd;
-
- v4l2_info(v4l2_dev, "Registered %s as /dev/%s\n",
- vfd->name, video_device_node_name(vfd));
- return 0;
-
-err_vd:
- media_entity_cleanup(&vfd->entity);
-err_me:
- v4l2_m2m_release(fimc->m2m.m2m_dev);
- return ret;
-}
-
-void fimc_unregister_m2m_device(struct fimc_dev *fimc)
-{
- if (!fimc)
- return;
-
- if (fimc->m2m.m2m_dev)
- v4l2_m2m_release(fimc->m2m.m2m_dev);
-
- if (video_is_registered(&fimc->m2m.vfd)) {
- video_unregister_device(&fimc->m2m.vfd);
- media_entity_cleanup(&fimc->m2m.vfd.entity);
- }
-}
diff --git a/drivers/media/platform/exynos4-is/fimc-reg.c b/drivers/media/platform/exynos4-is/fimc-reg.c
deleted file mode 100644
index 95165a2cc7d1..000000000000
--- a/drivers/media/platform/exynos4-is/fimc-reg.c
+++ /dev/null
@@ -1,846 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-/*
- * Register interface file for Samsung Camera Interface (FIMC) driver
- *
- * Copyright (C) 2010 - 2013 Samsung Electronics Co., Ltd.
- * Sylwester Nawrocki <s.nawrocki@samsung.com>
-*/
-
-#include <linux/delay.h>
-#include <linux/io.h>
-#include <linux/regmap.h>
-
-#include <media/drv-intf/exynos-fimc.h>
-#include "media-dev.h"
-
-#include "fimc-reg.h"
-#include "fimc-core.h"
-
-void fimc_hw_reset(struct fimc_dev *dev)
-{
- u32 cfg;
-
- cfg = readl(dev->regs + FIMC_REG_CISRCFMT);
- cfg |= FIMC_REG_CISRCFMT_ITU601_8BIT;
- writel(cfg, dev->regs + FIMC_REG_CISRCFMT);
-
- /* Software reset. */
- cfg = readl(dev->regs + FIMC_REG_CIGCTRL);
- cfg |= (FIMC_REG_CIGCTRL_SWRST | FIMC_REG_CIGCTRL_IRQ_LEVEL);
- writel(cfg, dev->regs + FIMC_REG_CIGCTRL);
- udelay(10);
-
- cfg = readl(dev->regs + FIMC_REG_CIGCTRL);
- cfg &= ~FIMC_REG_CIGCTRL_SWRST;
- writel(cfg, dev->regs + FIMC_REG_CIGCTRL);
-
- if (dev->drv_data->out_buf_count > 4)
- fimc_hw_set_dma_seq(dev, 0xF);
-}
-
-static u32 fimc_hw_get_in_flip(struct fimc_ctx *ctx)
-{
- u32 flip = FIMC_REG_MSCTRL_FLIP_NORMAL;
-
- if (ctx->hflip)
- flip = FIMC_REG_MSCTRL_FLIP_Y_MIRROR;
- if (ctx->vflip)
- flip = FIMC_REG_MSCTRL_FLIP_X_MIRROR;
-
- if (ctx->rotation <= 90)
- return flip;
-
- return (flip ^ FIMC_REG_MSCTRL_FLIP_180) & FIMC_REG_MSCTRL_FLIP_180;
-}
-
-static u32 fimc_hw_get_target_flip(struct fimc_ctx *ctx)
-{
- u32 flip = FIMC_REG_CITRGFMT_FLIP_NORMAL;
-
- if (ctx->hflip)
- flip |= FIMC_REG_CITRGFMT_FLIP_Y_MIRROR;
- if (ctx->vflip)
- flip |= FIMC_REG_CITRGFMT_FLIP_X_MIRROR;
-
- if (ctx->rotation <= 90)
- return flip;
-
- return (flip ^ FIMC_REG_CITRGFMT_FLIP_180) & FIMC_REG_CITRGFMT_FLIP_180;
-}
-
-void fimc_hw_set_rotation(struct fimc_ctx *ctx)
-{
- u32 cfg, flip;
- struct fimc_dev *dev = ctx->fimc_dev;
-
- cfg = readl(dev->regs + FIMC_REG_CITRGFMT);
- cfg &= ~(FIMC_REG_CITRGFMT_INROT90 | FIMC_REG_CITRGFMT_OUTROT90 |
- FIMC_REG_CITRGFMT_FLIP_180);
-
- /*
- * The input and output rotator cannot work simultaneously.
- * Use the output rotator in output DMA mode or the input rotator
- * in direct fifo output mode.
- */
- if (ctx->rotation == 90 || ctx->rotation == 270) {
- if (ctx->out_path == FIMC_IO_LCDFIFO)
- cfg |= FIMC_REG_CITRGFMT_INROT90;
- else
- cfg |= FIMC_REG_CITRGFMT_OUTROT90;
- }
-
- if (ctx->out_path == FIMC_IO_DMA) {
- cfg |= fimc_hw_get_target_flip(ctx);
- writel(cfg, dev->regs + FIMC_REG_CITRGFMT);
- } else {
- /* LCD FIFO path */
- flip = readl(dev->regs + FIMC_REG_MSCTRL);
- flip &= ~FIMC_REG_MSCTRL_FLIP_MASK;
- flip |= fimc_hw_get_in_flip(ctx);
- writel(flip, dev->regs + FIMC_REG_MSCTRL);
- }
-}
-
-void fimc_hw_set_target_format(struct fimc_ctx *ctx)
-{
- u32 cfg;
- struct fimc_dev *dev = ctx->fimc_dev;
- struct fimc_frame *frame = &ctx->d_frame;
-
- dbg("w= %d, h= %d color: %d", frame->width,
- frame->height, frame->fmt->color);
-
- cfg = readl(dev->regs + FIMC_REG_CITRGFMT);
- cfg &= ~(FIMC_REG_CITRGFMT_FMT_MASK | FIMC_REG_CITRGFMT_HSIZE_MASK |
- FIMC_REG_CITRGFMT_VSIZE_MASK);
-
- switch (frame->fmt->color) {
- case FIMC_FMT_RGB444...FIMC_FMT_RGB888:
- cfg |= FIMC_REG_CITRGFMT_RGB;
- break;
- case FIMC_FMT_YCBCR420:
- cfg |= FIMC_REG_CITRGFMT_YCBCR420;
- break;
- case FIMC_FMT_YCBYCR422...FIMC_FMT_CRYCBY422:
- if (frame->fmt->colplanes == 1)
- cfg |= FIMC_REG_CITRGFMT_YCBCR422_1P;
- else
- cfg |= FIMC_REG_CITRGFMT_YCBCR422;
- break;
- default:
- break;
- }
-
- if (ctx->rotation == 90 || ctx->rotation == 270)
- cfg |= (frame->height << 16) | frame->width;
- else
- cfg |= (frame->width << 16) | frame->height;
-
- writel(cfg, dev->regs + FIMC_REG_CITRGFMT);
-
- cfg = readl(dev->regs + FIMC_REG_CITAREA);
- cfg &= ~FIMC_REG_CITAREA_MASK;
- cfg |= (frame->width * frame->height);
- writel(cfg, dev->regs + FIMC_REG_CITAREA);
-}
-
-static void fimc_hw_set_out_dma_size(struct fimc_ctx *ctx)
-{
- struct fimc_dev *dev = ctx->fimc_dev;
- struct fimc_frame *frame = &ctx->d_frame;
- u32 cfg;
-
- cfg = (frame->f_height << 16) | frame->f_width;
- writel(cfg, dev->regs + FIMC_REG_ORGOSIZE);
-
- /* Select color space conversion equation (HD/SD size).*/
- cfg = readl(dev->regs + FIMC_REG_CIGCTRL);
- if (frame->f_width >= 1280) /* HD */
- cfg |= FIMC_REG_CIGCTRL_CSC_ITU601_709;
- else /* SD */
- cfg &= ~FIMC_REG_CIGCTRL_CSC_ITU601_709;
- writel(cfg, dev->regs + FIMC_REG_CIGCTRL);
-
-}
-
-void fimc_hw_set_out_dma(struct fimc_ctx *ctx)
-{
- struct fimc_dev *dev = ctx->fimc_dev;
- struct fimc_frame *frame = &ctx->d_frame;
- struct fimc_dma_offset *offset = &frame->dma_offset;
- struct fimc_fmt *fmt = frame->fmt;
- u32 cfg;
-
- /* Set the input dma offsets. */
- cfg = (offset->y_v << 16) | offset->y_h;
- writel(cfg, dev->regs + FIMC_REG_CIOYOFF);
-
- cfg = (offset->cb_v << 16) | offset->cb_h;
- writel(cfg, dev->regs + FIMC_REG_CIOCBOFF);
-
- cfg = (offset->cr_v << 16) | offset->cr_h;
- writel(cfg, dev->regs + FIMC_REG_CIOCROFF);
-
- fimc_hw_set_out_dma_size(ctx);
-
- /* Configure chroma components order. */
- cfg = readl(dev->regs + FIMC_REG_CIOCTRL);
-
- cfg &= ~(FIMC_REG_CIOCTRL_ORDER2P_MASK |
- FIMC_REG_CIOCTRL_ORDER422_MASK |
- FIMC_REG_CIOCTRL_YCBCR_PLANE_MASK |
- FIMC_REG_CIOCTRL_RGB16FMT_MASK);
-
- if (fmt->colplanes == 1)
- cfg |= ctx->out_order_1p;
- else if (fmt->colplanes == 2)
- cfg |= ctx->out_order_2p | FIMC_REG_CIOCTRL_YCBCR_2PLANE;
- else if (fmt->colplanes == 3)
- cfg |= FIMC_REG_CIOCTRL_YCBCR_3PLANE;
-
- if (fmt->color == FIMC_FMT_RGB565)
- cfg |= FIMC_REG_CIOCTRL_RGB565;
- else if (fmt->color == FIMC_FMT_RGB555)
- cfg |= FIMC_REG_CIOCTRL_ARGB1555;
- else if (fmt->color == FIMC_FMT_RGB444)
- cfg |= FIMC_REG_CIOCTRL_ARGB4444;
-
- writel(cfg, dev->regs + FIMC_REG_CIOCTRL);
-}
-
-static void fimc_hw_en_autoload(struct fimc_dev *dev, int enable)
-{
- u32 cfg = readl(dev->regs + FIMC_REG_ORGISIZE);
- if (enable)
- cfg |= FIMC_REG_CIREAL_ISIZE_AUTOLOAD_EN;
- else
- cfg &= ~FIMC_REG_CIREAL_ISIZE_AUTOLOAD_EN;
- writel(cfg, dev->regs + FIMC_REG_ORGISIZE);
-}
-
-void fimc_hw_en_lastirq(struct fimc_dev *dev, int enable)
-{
- u32 cfg = readl(dev->regs + FIMC_REG_CIOCTRL);
- if (enable)
- cfg |= FIMC_REG_CIOCTRL_LASTIRQ_ENABLE;
- else
- cfg &= ~FIMC_REG_CIOCTRL_LASTIRQ_ENABLE;
- writel(cfg, dev->regs + FIMC_REG_CIOCTRL);
-}
-
-void fimc_hw_set_prescaler(struct fimc_ctx *ctx)
-{
- struct fimc_dev *dev = ctx->fimc_dev;
- struct fimc_scaler *sc = &ctx->scaler;
- u32 cfg, shfactor;
-
- shfactor = 10 - (sc->hfactor + sc->vfactor);
- cfg = shfactor << 28;
-
- cfg |= (sc->pre_hratio << 16) | sc->pre_vratio;
- writel(cfg, dev->regs + FIMC_REG_CISCPRERATIO);
-
- cfg = (sc->pre_dst_width << 16) | sc->pre_dst_height;
- writel(cfg, dev->regs + FIMC_REG_CISCPREDST);
-}
-
-static void fimc_hw_set_scaler(struct fimc_ctx *ctx)
-{
- struct fimc_dev *dev = ctx->fimc_dev;
- struct fimc_scaler *sc = &ctx->scaler;
- struct fimc_frame *src_frame = &ctx->s_frame;
- struct fimc_frame *dst_frame = &ctx->d_frame;
-
- u32 cfg = readl(dev->regs + FIMC_REG_CISCCTRL);
-
- cfg &= ~(FIMC_REG_CISCCTRL_CSCR2Y_WIDE | FIMC_REG_CISCCTRL_CSCY2R_WIDE |
- FIMC_REG_CISCCTRL_SCALEUP_H | FIMC_REG_CISCCTRL_SCALEUP_V |
- FIMC_REG_CISCCTRL_SCALERBYPASS | FIMC_REG_CISCCTRL_ONE2ONE |
- FIMC_REG_CISCCTRL_INRGB_FMT_MASK | FIMC_REG_CISCCTRL_OUTRGB_FMT_MASK |
- FIMC_REG_CISCCTRL_INTERLACE | FIMC_REG_CISCCTRL_RGB_EXT);
-
- if (!(ctx->flags & FIMC_COLOR_RANGE_NARROW))
- cfg |= (FIMC_REG_CISCCTRL_CSCR2Y_WIDE |
- FIMC_REG_CISCCTRL_CSCY2R_WIDE);
-
- if (!sc->enabled)
- cfg |= FIMC_REG_CISCCTRL_SCALERBYPASS;
-
- if (sc->scaleup_h)
- cfg |= FIMC_REG_CISCCTRL_SCALEUP_H;
-
- if (sc->scaleup_v)
- cfg |= FIMC_REG_CISCCTRL_SCALEUP_V;
-
- if (sc->copy_mode)
- cfg |= FIMC_REG_CISCCTRL_ONE2ONE;
-
- if (ctx->in_path == FIMC_IO_DMA) {
- switch (src_frame->fmt->color) {
- case FIMC_FMT_RGB565:
- cfg |= FIMC_REG_CISCCTRL_INRGB_FMT_RGB565;
- break;
- case FIMC_FMT_RGB666:
- cfg |= FIMC_REG_CISCCTRL_INRGB_FMT_RGB666;
- break;
- case FIMC_FMT_RGB888:
- cfg |= FIMC_REG_CISCCTRL_INRGB_FMT_RGB888;
- break;
- }
- }
-
- if (ctx->out_path == FIMC_IO_DMA) {
- u32 color = dst_frame->fmt->color;
-
- if (color >= FIMC_FMT_RGB444 && color <= FIMC_FMT_RGB565)
- cfg |= FIMC_REG_CISCCTRL_OUTRGB_FMT_RGB565;
- else if (color == FIMC_FMT_RGB666)
- cfg |= FIMC_REG_CISCCTRL_OUTRGB_FMT_RGB666;
- else if (color == FIMC_FMT_RGB888)
- cfg |= FIMC_REG_CISCCTRL_OUTRGB_FMT_RGB888;
- } else {
- cfg |= FIMC_REG_CISCCTRL_OUTRGB_FMT_RGB888;
-
- if (ctx->flags & FIMC_SCAN_MODE_INTERLACED)
- cfg |= FIMC_REG_CISCCTRL_INTERLACE;
- }
-
- writel(cfg, dev->regs + FIMC_REG_CISCCTRL);
-}
-
-void fimc_hw_set_mainscaler(struct fimc_ctx *ctx)
-{
- struct fimc_dev *dev = ctx->fimc_dev;
- const struct fimc_variant *variant = dev->variant;
- struct fimc_scaler *sc = &ctx->scaler;
- u32 cfg;
-
- dbg("main_hratio= 0x%X main_vratio= 0x%X",
- sc->main_hratio, sc->main_vratio);
-
- fimc_hw_set_scaler(ctx);
-
- cfg = readl(dev->regs + FIMC_REG_CISCCTRL);
- cfg &= ~(FIMC_REG_CISCCTRL_MHRATIO_MASK |
- FIMC_REG_CISCCTRL_MVRATIO_MASK);
-
- if (variant->has_mainscaler_ext) {
- cfg |= FIMC_REG_CISCCTRL_MHRATIO_EXT(sc->main_hratio);
- cfg |= FIMC_REG_CISCCTRL_MVRATIO_EXT(sc->main_vratio);
- writel(cfg, dev->regs + FIMC_REG_CISCCTRL);
-
- cfg = readl(dev->regs + FIMC_REG_CIEXTEN);
-
- cfg &= ~(FIMC_REG_CIEXTEN_MVRATIO_EXT_MASK |
- FIMC_REG_CIEXTEN_MHRATIO_EXT_MASK);
- cfg |= FIMC_REG_CIEXTEN_MHRATIO_EXT(sc->main_hratio);
- cfg |= FIMC_REG_CIEXTEN_MVRATIO_EXT(sc->main_vratio);
- writel(cfg, dev->regs + FIMC_REG_CIEXTEN);
- } else {
- cfg |= FIMC_REG_CISCCTRL_MHRATIO(sc->main_hratio);
- cfg |= FIMC_REG_CISCCTRL_MVRATIO(sc->main_vratio);
- writel(cfg, dev->regs + FIMC_REG_CISCCTRL);
- }
-}
-
-void fimc_hw_enable_capture(struct fimc_ctx *ctx)
-{
- struct fimc_dev *dev = ctx->fimc_dev;
- u32 cfg;
-
- cfg = readl(dev->regs + FIMC_REG_CIIMGCPT);
- cfg |= FIMC_REG_CIIMGCPT_CPT_FREN_ENABLE;
-
- if (ctx->scaler.enabled)
- cfg |= FIMC_REG_CIIMGCPT_IMGCPTEN_SC;
- else
- cfg &= FIMC_REG_CIIMGCPT_IMGCPTEN_SC;
-
- cfg |= FIMC_REG_CIIMGCPT_IMGCPTEN;
- writel(cfg, dev->regs + FIMC_REG_CIIMGCPT);
-}
-
-void fimc_hw_disable_capture(struct fimc_dev *dev)
-{
- u32 cfg = readl(dev->regs + FIMC_REG_CIIMGCPT);
- cfg &= ~(FIMC_REG_CIIMGCPT_IMGCPTEN |
- FIMC_REG_CIIMGCPT_IMGCPTEN_SC);
- writel(cfg, dev->regs + FIMC_REG_CIIMGCPT);
-}
-
-void fimc_hw_set_effect(struct fimc_ctx *ctx)
-{
- struct fimc_dev *dev = ctx->fimc_dev;
- struct fimc_effect *effect = &ctx->effect;
- u32 cfg = 0;
-
- if (effect->type != FIMC_REG_CIIMGEFF_FIN_BYPASS) {
- cfg |= FIMC_REG_CIIMGEFF_IE_SC_AFTER |
- FIMC_REG_CIIMGEFF_IE_ENABLE;
- cfg |= effect->type;
- if (effect->type == FIMC_REG_CIIMGEFF_FIN_ARBITRARY)
- cfg |= (effect->pat_cb << 13) | effect->pat_cr;
- }
-
- writel(cfg, dev->regs + FIMC_REG_CIIMGEFF);
-}
-
-void fimc_hw_set_rgb_alpha(struct fimc_ctx *ctx)
-{
- struct fimc_dev *dev = ctx->fimc_dev;
- struct fimc_frame *frame = &ctx->d_frame;
- u32 cfg;
-
- if (!(frame->fmt->flags & FMT_HAS_ALPHA))
- return;
-
- cfg = readl(dev->regs + FIMC_REG_CIOCTRL);
- cfg &= ~FIMC_REG_CIOCTRL_ALPHA_OUT_MASK;
- cfg |= (frame->alpha << 4);
- writel(cfg, dev->regs + FIMC_REG_CIOCTRL);
-}
-
-static void fimc_hw_set_in_dma_size(struct fimc_ctx *ctx)
-{
- struct fimc_dev *dev = ctx->fimc_dev;
- struct fimc_frame *frame = &ctx->s_frame;
- u32 cfg_o = 0;
- u32 cfg_r = 0;
-
- if (FIMC_IO_LCDFIFO == ctx->out_path)
- cfg_r |= FIMC_REG_CIREAL_ISIZE_AUTOLOAD_EN;
-
- cfg_o |= (frame->f_height << 16) | frame->f_width;
- cfg_r |= (frame->height << 16) | frame->width;
-
- writel(cfg_o, dev->regs + FIMC_REG_ORGISIZE);
- writel(cfg_r, dev->regs + FIMC_REG_CIREAL_ISIZE);
-}
-
-void fimc_hw_set_in_dma(struct fimc_ctx *ctx)
-{
- struct fimc_dev *dev = ctx->fimc_dev;
- struct fimc_frame *frame = &ctx->s_frame;
- struct fimc_dma_offset *offset = &frame->dma_offset;
- u32 cfg;
-
- /* Set the pixel offsets. */
- cfg = (offset->y_v << 16) | offset->y_h;
- writel(cfg, dev->regs + FIMC_REG_CIIYOFF);
-
- cfg = (offset->cb_v << 16) | offset->cb_h;
- writel(cfg, dev->regs + FIMC_REG_CIICBOFF);
-
- cfg = (offset->cr_v << 16) | offset->cr_h;
- writel(cfg, dev->regs + FIMC_REG_CIICROFF);
-
- /* Input original and real size. */
- fimc_hw_set_in_dma_size(ctx);
-
- /* Use DMA autoload only in FIFO mode. */
- fimc_hw_en_autoload(dev, ctx->out_path == FIMC_IO_LCDFIFO);
-
- /* Set the input DMA to process single frame only. */
- cfg = readl(dev->regs + FIMC_REG_MSCTRL);
- cfg &= ~(FIMC_REG_MSCTRL_INFORMAT_MASK
- | FIMC_REG_MSCTRL_IN_BURST_COUNT_MASK
- | FIMC_REG_MSCTRL_INPUT_MASK
- | FIMC_REG_MSCTRL_C_INT_IN_MASK
- | FIMC_REG_MSCTRL_2P_IN_ORDER_MASK
- | FIMC_REG_MSCTRL_ORDER422_MASK);
-
- cfg |= (FIMC_REG_MSCTRL_IN_BURST_COUNT(4)
- | FIMC_REG_MSCTRL_INPUT_MEMORY
- | FIMC_REG_MSCTRL_FIFO_CTRL_FULL);
-
- switch (frame->fmt->color) {
- case FIMC_FMT_RGB565...FIMC_FMT_RGB888:
- cfg |= FIMC_REG_MSCTRL_INFORMAT_RGB;
- break;
- case FIMC_FMT_YCBCR420:
- cfg |= FIMC_REG_MSCTRL_INFORMAT_YCBCR420;
-
- if (frame->fmt->colplanes == 2)
- cfg |= ctx->in_order_2p | FIMC_REG_MSCTRL_C_INT_IN_2PLANE;
- else
- cfg |= FIMC_REG_MSCTRL_C_INT_IN_3PLANE;
-
- break;
- case FIMC_FMT_YCBYCR422...FIMC_FMT_CRYCBY422:
- if (frame->fmt->colplanes == 1) {
- cfg |= ctx->in_order_1p
- | FIMC_REG_MSCTRL_INFORMAT_YCBCR422_1P;
- } else {
- cfg |= FIMC_REG_MSCTRL_INFORMAT_YCBCR422;
-
- if (frame->fmt->colplanes == 2)
- cfg |= ctx->in_order_2p
- | FIMC_REG_MSCTRL_C_INT_IN_2PLANE;
- else
- cfg |= FIMC_REG_MSCTRL_C_INT_IN_3PLANE;
- }
- break;
- default:
- break;
- }
-
- writel(cfg, dev->regs + FIMC_REG_MSCTRL);
-
- /* Input/output DMA linear/tiled mode. */
- cfg = readl(dev->regs + FIMC_REG_CIDMAPARAM);
- cfg &= ~FIMC_REG_CIDMAPARAM_TILE_MASK;
-
- if (tiled_fmt(ctx->s_frame.fmt))
- cfg |= FIMC_REG_CIDMAPARAM_R_64X32;
-
- if (tiled_fmt(ctx->d_frame.fmt))
- cfg |= FIMC_REG_CIDMAPARAM_W_64X32;
-
- writel(cfg, dev->regs + FIMC_REG_CIDMAPARAM);
-}
-
-
-void fimc_hw_set_input_path(struct fimc_ctx *ctx)
-{
- struct fimc_dev *dev = ctx->fimc_dev;
-
- u32 cfg = readl(dev->regs + FIMC_REG_MSCTRL);
- cfg &= ~FIMC_REG_MSCTRL_INPUT_MASK;
-
- if (ctx->in_path == FIMC_IO_DMA)
- cfg |= FIMC_REG_MSCTRL_INPUT_MEMORY;
- else
- cfg |= FIMC_REG_MSCTRL_INPUT_EXTCAM;
-
- writel(cfg, dev->regs + FIMC_REG_MSCTRL);
-}
-
-void fimc_hw_set_output_path(struct fimc_ctx *ctx)
-{
- struct fimc_dev *dev = ctx->fimc_dev;
-
- u32 cfg = readl(dev->regs + FIMC_REG_CISCCTRL);
- cfg &= ~FIMC_REG_CISCCTRL_LCDPATHEN_FIFO;
- if (ctx->out_path == FIMC_IO_LCDFIFO)
- cfg |= FIMC_REG_CISCCTRL_LCDPATHEN_FIFO;
- writel(cfg, dev->regs + FIMC_REG_CISCCTRL);
-}
-
-void fimc_hw_set_input_addr(struct fimc_dev *dev, struct fimc_addr *addr)
-{
- u32 cfg = readl(dev->regs + FIMC_REG_CIREAL_ISIZE);
- cfg |= FIMC_REG_CIREAL_ISIZE_ADDR_CH_DIS;
- writel(cfg, dev->regs + FIMC_REG_CIREAL_ISIZE);
-
- writel(addr->y, dev->regs + FIMC_REG_CIIYSA(0));
- writel(addr->cb, dev->regs + FIMC_REG_CIICBSA(0));
- writel(addr->cr, dev->regs + FIMC_REG_CIICRSA(0));
-
- cfg &= ~FIMC_REG_CIREAL_ISIZE_ADDR_CH_DIS;
- writel(cfg, dev->regs + FIMC_REG_CIREAL_ISIZE);
-}
-
-void fimc_hw_set_output_addr(struct fimc_dev *dev,
- struct fimc_addr *addr, int index)
-{
- int i = (index == -1) ? 0 : index;
- do {
- writel(addr->y, dev->regs + FIMC_REG_CIOYSA(i));
- writel(addr->cb, dev->regs + FIMC_REG_CIOCBSA(i));
- writel(addr->cr, dev->regs + FIMC_REG_CIOCRSA(i));
- dbg("dst_buf[%d]: 0x%X, cb: 0x%X, cr: 0x%X",
- i, addr->y, addr->cb, addr->cr);
- } while (index == -1 && ++i < FIMC_MAX_OUT_BUFS);
-}
-
-int fimc_hw_set_camera_polarity(struct fimc_dev *fimc,
- struct fimc_source_info *cam)
-{
- u32 cfg = readl(fimc->regs + FIMC_REG_CIGCTRL);
-
- cfg &= ~(FIMC_REG_CIGCTRL_INVPOLPCLK | FIMC_REG_CIGCTRL_INVPOLVSYNC |
- FIMC_REG_CIGCTRL_INVPOLHREF | FIMC_REG_CIGCTRL_INVPOLHSYNC |
- FIMC_REG_CIGCTRL_INVPOLFIELD);
-
- if (cam->flags & V4L2_MBUS_PCLK_SAMPLE_FALLING)
- cfg |= FIMC_REG_CIGCTRL_INVPOLPCLK;
-
- if (cam->flags & V4L2_MBUS_VSYNC_ACTIVE_LOW)
- cfg |= FIMC_REG_CIGCTRL_INVPOLVSYNC;
-
- if (cam->flags & V4L2_MBUS_HSYNC_ACTIVE_LOW)
- cfg |= FIMC_REG_CIGCTRL_INVPOLHREF;
-
- if (cam->flags & V4L2_MBUS_HSYNC_ACTIVE_LOW)
- cfg |= FIMC_REG_CIGCTRL_INVPOLHSYNC;
-
- if (cam->flags & V4L2_MBUS_FIELD_EVEN_LOW)
- cfg |= FIMC_REG_CIGCTRL_INVPOLFIELD;
-
- writel(cfg, fimc->regs + FIMC_REG_CIGCTRL);
-
- return 0;
-}
-
-struct mbus_pixfmt_desc {
- u32 pixelcode;
- u32 cisrcfmt;
- u16 bus_width;
-};
-
-static const struct mbus_pixfmt_desc pix_desc[] = {
- { MEDIA_BUS_FMT_YUYV8_2X8, FIMC_REG_CISRCFMT_ORDER422_YCBYCR, 8 },
- { MEDIA_BUS_FMT_YVYU8_2X8, FIMC_REG_CISRCFMT_ORDER422_YCRYCB, 8 },
- { MEDIA_BUS_FMT_VYUY8_2X8, FIMC_REG_CISRCFMT_ORDER422_CRYCBY, 8 },
- { MEDIA_BUS_FMT_UYVY8_2X8, FIMC_REG_CISRCFMT_ORDER422_CBYCRY, 8 },
-};
-
-int fimc_hw_set_camera_source(struct fimc_dev *fimc,
- struct fimc_source_info *source)
-{
- struct fimc_vid_cap *vc = &fimc->vid_cap;
- struct fimc_frame *f = &vc->ctx->s_frame;
- u32 bus_width, cfg = 0;
- int i;
-
- switch (source->fimc_bus_type) {
- case FIMC_BUS_TYPE_ITU_601:
- case FIMC_BUS_TYPE_ITU_656:
- if (fimc_fmt_is_user_defined(f->fmt->color)) {
- cfg |= FIMC_REG_CISRCFMT_ITU601_8BIT;
- break;
- }
-
- for (i = 0; i < ARRAY_SIZE(pix_desc); i++) {
- if (vc->ci_fmt.code == pix_desc[i].pixelcode) {
- cfg = pix_desc[i].cisrcfmt;
- bus_width = pix_desc[i].bus_width;
- break;
- }
- }
-
- if (i == ARRAY_SIZE(pix_desc)) {
- v4l2_err(&vc->ve.vdev,
- "Camera color format not supported: %d\n",
- vc->ci_fmt.code);
- return -EINVAL;
- }
-
- if (source->fimc_bus_type == FIMC_BUS_TYPE_ITU_601) {
- if (bus_width == 8)
- cfg |= FIMC_REG_CISRCFMT_ITU601_8BIT;
- else if (bus_width == 16)
- cfg |= FIMC_REG_CISRCFMT_ITU601_16BIT;
- } /* else defaults to ITU-R BT.656 8-bit */
- break;
- case FIMC_BUS_TYPE_MIPI_CSI2:
- if (fimc_fmt_is_user_defined(f->fmt->color))
- cfg |= FIMC_REG_CISRCFMT_ITU601_8BIT;
- break;
- default:
- case FIMC_BUS_TYPE_ISP_WRITEBACK:
- /* Anything to do here ? */
- break;
- }
-
- cfg |= (f->o_width << 16) | f->o_height;
- writel(cfg, fimc->regs + FIMC_REG_CISRCFMT);
- return 0;
-}
-
-void fimc_hw_set_camera_offset(struct fimc_dev *fimc, struct fimc_frame *f)
-{
- u32 hoff2, voff2;
-
- u32 cfg = readl(fimc->regs + FIMC_REG_CIWDOFST);
-
- cfg &= ~(FIMC_REG_CIWDOFST_HOROFF_MASK | FIMC_REG_CIWDOFST_VEROFF_MASK);
- cfg |= FIMC_REG_CIWDOFST_OFF_EN |
- (f->offs_h << 16) | f->offs_v;
-
- writel(cfg, fimc->regs + FIMC_REG_CIWDOFST);
-
- /* See CIWDOFSTn register description in the datasheet for details. */
- hoff2 = f->o_width - f->width - f->offs_h;
- voff2 = f->o_height - f->height - f->offs_v;
- cfg = (hoff2 << 16) | voff2;
- writel(cfg, fimc->regs + FIMC_REG_CIWDOFST2);
-}
-
-int fimc_hw_set_camera_type(struct fimc_dev *fimc,
- struct fimc_source_info *source)
-{
- struct fimc_vid_cap *vid_cap = &fimc->vid_cap;
- u32 csis_data_alignment = 32;
- u32 cfg, tmp;
-
- cfg = readl(fimc->regs + FIMC_REG_CIGCTRL);
-
- /* Select ITU B interface, disable Writeback path and test pattern. */
- cfg &= ~(FIMC_REG_CIGCTRL_TESTPAT_MASK | FIMC_REG_CIGCTRL_SELCAM_ITU_A |
- FIMC_REG_CIGCTRL_SELCAM_MIPI | FIMC_REG_CIGCTRL_CAMIF_SELWB |
- FIMC_REG_CIGCTRL_SELCAM_MIPI_A | FIMC_REG_CIGCTRL_CAM_JPEG |
- FIMC_REG_CIGCTRL_SELWB_A);
-
- switch (source->fimc_bus_type) {
- case FIMC_BUS_TYPE_MIPI_CSI2:
- cfg |= FIMC_REG_CIGCTRL_SELCAM_MIPI;
-
- if (source->mux_id == 0)
- cfg |= FIMC_REG_CIGCTRL_SELCAM_MIPI_A;
-
- /* TODO: add remaining supported formats. */
- switch (vid_cap->ci_fmt.code) {
- case MEDIA_BUS_FMT_VYUY8_2X8:
- tmp = FIMC_REG_CSIIMGFMT_YCBCR422_8BIT;
- break;
- case MEDIA_BUS_FMT_JPEG_1X8:
- case MEDIA_BUS_FMT_S5C_UYVY_JPEG_1X8:
- tmp = FIMC_REG_CSIIMGFMT_USER(1);
- cfg |= FIMC_REG_CIGCTRL_CAM_JPEG;
- break;
- default:
- v4l2_err(&vid_cap->ve.vdev,
- "Not supported camera pixel format: %#x\n",
- vid_cap->ci_fmt.code);
- return -EINVAL;
- }
- tmp |= (csis_data_alignment == 32) << 8;
-
- writel(tmp, fimc->regs + FIMC_REG_CSIIMGFMT);
- break;
- case FIMC_BUS_TYPE_ITU_601...FIMC_BUS_TYPE_ITU_656:
- if (source->mux_id == 0) /* ITU-A, ITU-B: 0, 1 */
- cfg |= FIMC_REG_CIGCTRL_SELCAM_ITU_A;
- if (vid_cap->ci_fmt.code == MEDIA_BUS_FMT_JPEG_1X8)
- cfg |= FIMC_REG_CIGCTRL_CAM_JPEG;
- break;
- case FIMC_BUS_TYPE_LCD_WRITEBACK_A:
- cfg |= FIMC_REG_CIGCTRL_CAMIF_SELWB;
- fallthrough;
- case FIMC_BUS_TYPE_ISP_WRITEBACK:
- if (fimc->variant->has_isp_wb)
- cfg |= FIMC_REG_CIGCTRL_CAMIF_SELWB;
- else
- WARN_ONCE(1, "ISP Writeback input is not supported\n");
- break;
- default:
- v4l2_err(&vid_cap->ve.vdev,
- "Invalid FIMC bus type selected: %d\n",
- source->fimc_bus_type);
- return -EINVAL;
- }
- writel(cfg, fimc->regs + FIMC_REG_CIGCTRL);
-
- return 0;
-}
-
-void fimc_hw_clear_irq(struct fimc_dev *dev)
-{
- u32 cfg = readl(dev->regs + FIMC_REG_CIGCTRL);
- cfg |= FIMC_REG_CIGCTRL_IRQ_CLR;
- writel(cfg, dev->regs + FIMC_REG_CIGCTRL);
-}
-
-void fimc_hw_enable_scaler(struct fimc_dev *dev, bool on)
-{
- u32 cfg = readl(dev->regs + FIMC_REG_CISCCTRL);
- if (on)
- cfg |= FIMC_REG_CISCCTRL_SCALERSTART;
- else
- cfg &= ~FIMC_REG_CISCCTRL_SCALERSTART;
- writel(cfg, dev->regs + FIMC_REG_CISCCTRL);
-}
-
-void fimc_hw_activate_input_dma(struct fimc_dev *dev, bool on)
-{
- u32 cfg = readl(dev->regs + FIMC_REG_MSCTRL);
- if (on)
- cfg |= FIMC_REG_MSCTRL_ENVID;
- else
- cfg &= ~FIMC_REG_MSCTRL_ENVID;
- writel(cfg, dev->regs + FIMC_REG_MSCTRL);
-}
-
-/* Return an index to the buffer actually being written. */
-s32 fimc_hw_get_frame_index(struct fimc_dev *dev)
-{
- s32 reg;
-
- if (dev->drv_data->cistatus2) {
- reg = readl(dev->regs + FIMC_REG_CISTATUS2) & 0x3f;
- return reg - 1;
- }
-
- reg = readl(dev->regs + FIMC_REG_CISTATUS);
-
- return (reg & FIMC_REG_CISTATUS_FRAMECNT_MASK) >>
- FIMC_REG_CISTATUS_FRAMECNT_SHIFT;
-}
-
-/* Return an index to the buffer being written previously. */
-s32 fimc_hw_get_prev_frame_index(struct fimc_dev *dev)
-{
- s32 reg;
-
- if (!dev->drv_data->cistatus2)
- return -1;
-
- reg = readl(dev->regs + FIMC_REG_CISTATUS2);
- return ((reg >> 7) & 0x3f) - 1;
-}
-
-/* Locking: the caller holds fimc->slock */
-void fimc_activate_capture(struct fimc_ctx *ctx)
-{
- fimc_hw_enable_scaler(ctx->fimc_dev, ctx->scaler.enabled);
- fimc_hw_enable_capture(ctx);
-}
-
-void fimc_deactivate_capture(struct fimc_dev *fimc)
-{
- fimc_hw_en_lastirq(fimc, true);
- fimc_hw_disable_capture(fimc);
- fimc_hw_enable_scaler(fimc, false);
- fimc_hw_en_lastirq(fimc, false);
-}
-
-int fimc_hw_camblk_cfg_writeback(struct fimc_dev *fimc)
-{
- struct regmap *map = fimc->sysreg;
- unsigned int mask, val, camblk_cfg;
- int ret;
-
- if (map == NULL)
- return 0;
-
- ret = regmap_read(map, SYSREG_CAMBLK, &camblk_cfg);
- if (ret < 0 || ((camblk_cfg & 0x00700000) >> 20 != 0x3))
- return ret;
-
- if (!WARN(fimc->id >= 3, "not supported id: %d\n", fimc->id))
- val = 0x1 << (fimc->id + 20);
- else
- val = 0;
-
- mask = SYSREG_CAMBLK_FIFORST_ISP | SYSREG_CAMBLK_ISPWB_FULL_EN;
- ret = regmap_update_bits(map, SYSREG_CAMBLK, mask, val);
- if (ret < 0)
- return ret;
-
- usleep_range(1000, 2000);
-
- val |= SYSREG_CAMBLK_FIFORST_ISP;
- ret = regmap_update_bits(map, SYSREG_CAMBLK, mask, val);
- if (ret < 0)
- return ret;
-
- mask = SYSREG_ISPBLK_FIFORST_CAM_BLK;
- ret = regmap_update_bits(map, SYSREG_ISPBLK, mask, ~mask);
- if (ret < 0)
- return ret;
-
- usleep_range(1000, 2000);
-
- return regmap_update_bits(map, SYSREG_ISPBLK, mask, mask);
-}
diff --git a/drivers/media/platform/exynos4-is/fimc-reg.h b/drivers/media/platform/exynos4-is/fimc-reg.h
deleted file mode 100644
index b9b33aa1f12f..000000000000
--- a/drivers/media/platform/exynos4-is/fimc-reg.h
+++ /dev/null
@@ -1,338 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-only */
-/*
- * Samsung camera host interface (FIMC) registers definition
- *
- * Copyright (C) 2010 - 2012 Samsung Electronics Co., Ltd.
- */
-
-#ifndef FIMC_REG_H_
-#define FIMC_REG_H_
-
-#include <linux/bitops.h>
-
-#include "fimc-core.h"
-
-/* Input source format */
-#define FIMC_REG_CISRCFMT 0x00
-#define FIMC_REG_CISRCFMT_ITU601_8BIT BIT(31)
-#define FIMC_REG_CISRCFMT_ITU601_16BIT BIT(29)
-#define FIMC_REG_CISRCFMT_ORDER422_YCBYCR (0 << 14)
-#define FIMC_REG_CISRCFMT_ORDER422_YCRYCB (1 << 14)
-#define FIMC_REG_CISRCFMT_ORDER422_CBYCRY (2 << 14)
-#define FIMC_REG_CISRCFMT_ORDER422_CRYCBY (3 << 14)
-
-/* Window offset */
-#define FIMC_REG_CIWDOFST 0x04
-#define FIMC_REG_CIWDOFST_OFF_EN BIT(31)
-#define FIMC_REG_CIWDOFST_CLROVFIY BIT(30)
-#define FIMC_REG_CIWDOFST_CLROVRLB BIT(29)
-#define FIMC_REG_CIWDOFST_HOROFF_MASK (0x7ff << 16)
-#define FIMC_REG_CIWDOFST_CLROVFICB BIT(15)
-#define FIMC_REG_CIWDOFST_CLROVFICR BIT(14)
-#define FIMC_REG_CIWDOFST_VEROFF_MASK (0xfff << 0)
-
-/* Global control */
-#define FIMC_REG_CIGCTRL 0x08
-#define FIMC_REG_CIGCTRL_SWRST BIT(31)
-#define FIMC_REG_CIGCTRL_CAMRST_A BIT(30)
-#define FIMC_REG_CIGCTRL_SELCAM_ITU_A BIT(29)
-#define FIMC_REG_CIGCTRL_TESTPAT_NORMAL (0 << 27)
-#define FIMC_REG_CIGCTRL_TESTPAT_COLOR_BAR (1 << 27)
-#define FIMC_REG_CIGCTRL_TESTPAT_HOR_INC (2 << 27)
-#define FIMC_REG_CIGCTRL_TESTPAT_VER_INC (3 << 27)
-#define FIMC_REG_CIGCTRL_TESTPAT_MASK (3 << 27)
-#define FIMC_REG_CIGCTRL_TESTPAT_SHIFT 27
-#define FIMC_REG_CIGCTRL_INVPOLPCLK BIT(26)
-#define FIMC_REG_CIGCTRL_INVPOLVSYNC BIT(25)
-#define FIMC_REG_CIGCTRL_INVPOLHREF BIT(24)
-#define FIMC_REG_CIGCTRL_IRQ_OVFEN BIT(22)
-#define FIMC_REG_CIGCTRL_HREF_MASK BIT(21)
-#define FIMC_REG_CIGCTRL_IRQ_LEVEL BIT(20)
-#define FIMC_REG_CIGCTRL_IRQ_CLR BIT(19)
-#define FIMC_REG_CIGCTRL_IRQ_ENABLE BIT(16)
-#define FIMC_REG_CIGCTRL_SHDW_DISABLE BIT(12)
-/* 0 - selects Writeback A (LCD), 1 - selects Writeback B (LCD/ISP) */
-#define FIMC_REG_CIGCTRL_SELWB_A BIT(10)
-#define FIMC_REG_CIGCTRL_CAM_JPEG BIT(8)
-#define FIMC_REG_CIGCTRL_SELCAM_MIPI_A BIT(7)
-#define FIMC_REG_CIGCTRL_CAMIF_SELWB BIT(6)
-/* 0 - ITU601; 1 - ITU709 */
-#define FIMC_REG_CIGCTRL_CSC_ITU601_709 BIT(5)
-#define FIMC_REG_CIGCTRL_INVPOLHSYNC BIT(4)
-#define FIMC_REG_CIGCTRL_SELCAM_MIPI BIT(3)
-#define FIMC_REG_CIGCTRL_INVPOLFIELD BIT(1)
-#define FIMC_REG_CIGCTRL_INTERLACE BIT(0)
-
-/* Window offset 2 */
-#define FIMC_REG_CIWDOFST2 0x14
-#define FIMC_REG_CIWDOFST2_HOROFF_MASK (0xfff << 16)
-#define FIMC_REG_CIWDOFST2_VEROFF_MASK (0xfff << 0)
-
-/* Output DMA Y/Cb/Cr plane start addresses */
-#define FIMC_REG_CIOYSA(n) (0x18 + (n) * 4)
-#define FIMC_REG_CIOCBSA(n) (0x28 + (n) * 4)
-#define FIMC_REG_CIOCRSA(n) (0x38 + (n) * 4)
-
-/* Target image format */
-#define FIMC_REG_CITRGFMT 0x48
-#define FIMC_REG_CITRGFMT_INROT90 BIT(31)
-#define FIMC_REG_CITRGFMT_YCBCR420 (0 << 29)
-#define FIMC_REG_CITRGFMT_YCBCR422 (1 << 29)
-#define FIMC_REG_CITRGFMT_YCBCR422_1P (2 << 29)
-#define FIMC_REG_CITRGFMT_RGB (3 << 29)
-#define FIMC_REG_CITRGFMT_FMT_MASK (3 << 29)
-#define FIMC_REG_CITRGFMT_HSIZE_MASK (0xfff << 16)
-#define FIMC_REG_CITRGFMT_FLIP_SHIFT 14
-#define FIMC_REG_CITRGFMT_FLIP_NORMAL (0 << 14)
-#define FIMC_REG_CITRGFMT_FLIP_X_MIRROR (1 << 14)
-#define FIMC_REG_CITRGFMT_FLIP_Y_MIRROR (2 << 14)
-#define FIMC_REG_CITRGFMT_FLIP_180 (3 << 14)
-#define FIMC_REG_CITRGFMT_FLIP_MASK (3 << 14)
-#define FIMC_REG_CITRGFMT_OUTROT90 BIT(13)
-#define FIMC_REG_CITRGFMT_VSIZE_MASK (0xfff << 0)
-
-/* Output DMA control */
-#define FIMC_REG_CIOCTRL 0x4c
-#define FIMC_REG_CIOCTRL_ORDER422_MASK (3 << 0)
-#define FIMC_REG_CIOCTRL_ORDER422_YCBYCR (0 << 0)
-#define FIMC_REG_CIOCTRL_ORDER422_YCRYCB (1 << 0)
-#define FIMC_REG_CIOCTRL_ORDER422_CBYCRY (2 << 0)
-#define FIMC_REG_CIOCTRL_ORDER422_CRYCBY (3 << 0)
-#define FIMC_REG_CIOCTRL_LASTIRQ_ENABLE BIT(2)
-#define FIMC_REG_CIOCTRL_YCBCR_3PLANE (0 << 3)
-#define FIMC_REG_CIOCTRL_YCBCR_2PLANE (1 << 3)
-#define FIMC_REG_CIOCTRL_YCBCR_PLANE_MASK (1 << 3)
-#define FIMC_REG_CIOCTRL_ALPHA_OUT_MASK (0xff << 4)
-#define FIMC_REG_CIOCTRL_RGB16FMT_MASK (3 << 16)
-#define FIMC_REG_CIOCTRL_RGB565 (0 << 16)
-#define FIMC_REG_CIOCTRL_ARGB1555 (1 << 16)
-#define FIMC_REG_CIOCTRL_ARGB4444 (2 << 16)
-#define FIMC_REG_CIOCTRL_ORDER2P_SHIFT 24
-#define FIMC_REG_CIOCTRL_ORDER2P_MASK (3 << 24)
-#define FIMC_REG_CIOCTRL_ORDER422_2P_LSB_CRCB (0 << 24)
-
-/* Pre-scaler control 1 */
-#define FIMC_REG_CISCPRERATIO 0x50
-
-#define FIMC_REG_CISCPREDST 0x54
-
-/* Main scaler control */
-#define FIMC_REG_CISCCTRL 0x58
-#define FIMC_REG_CISCCTRL_SCALERBYPASS BIT(31)
-#define FIMC_REG_CISCCTRL_SCALEUP_H BIT(30)
-#define FIMC_REG_CISCCTRL_SCALEUP_V BIT(29)
-#define FIMC_REG_CISCCTRL_CSCR2Y_WIDE BIT(28)
-#define FIMC_REG_CISCCTRL_CSCY2R_WIDE BIT(27)
-#define FIMC_REG_CISCCTRL_LCDPATHEN_FIFO BIT(26)
-#define FIMC_REG_CISCCTRL_INTERLACE BIT(25)
-#define FIMC_REG_CISCCTRL_SCALERSTART BIT(15)
-#define FIMC_REG_CISCCTRL_INRGB_FMT_RGB565 (0 << 13)
-#define FIMC_REG_CISCCTRL_INRGB_FMT_RGB666 (1 << 13)
-#define FIMC_REG_CISCCTRL_INRGB_FMT_RGB888 (2 << 13)
-#define FIMC_REG_CISCCTRL_INRGB_FMT_MASK (3 << 13)
-#define FIMC_REG_CISCCTRL_OUTRGB_FMT_RGB565 (0 << 11)
-#define FIMC_REG_CISCCTRL_OUTRGB_FMT_RGB666 (1 << 11)
-#define FIMC_REG_CISCCTRL_OUTRGB_FMT_RGB888 (2 << 11)
-#define FIMC_REG_CISCCTRL_OUTRGB_FMT_MASK (3 << 11)
-#define FIMC_REG_CISCCTRL_RGB_EXT BIT(10)
-#define FIMC_REG_CISCCTRL_ONE2ONE BIT(9)
-#define FIMC_REG_CISCCTRL_MHRATIO(x) ((x) << 16)
-#define FIMC_REG_CISCCTRL_MVRATIO(x) ((x) << 0)
-#define FIMC_REG_CISCCTRL_MHRATIO_MASK (0x1ff << 16)
-#define FIMC_REG_CISCCTRL_MVRATIO_MASK (0x1ff << 0)
-#define FIMC_REG_CISCCTRL_MHRATIO_EXT(x) (((x) >> 6) << 16)
-#define FIMC_REG_CISCCTRL_MVRATIO_EXT(x) (((x) >> 6) << 0)
-
-/* Target area */
-#define FIMC_REG_CITAREA 0x5c
-#define FIMC_REG_CITAREA_MASK 0x0fffffff
-
-/* General status */
-#define FIMC_REG_CISTATUS 0x64
-#define FIMC_REG_CISTATUS_OVFIY BIT(31)
-#define FIMC_REG_CISTATUS_OVFICB BIT(30)
-#define FIMC_REG_CISTATUS_OVFICR BIT(29)
-#define FIMC_REG_CISTATUS_VSYNC BIT(28)
-#define FIMC_REG_CISTATUS_FRAMECNT_MASK (3 << 26)
-#define FIMC_REG_CISTATUS_FRAMECNT_SHIFT 26
-#define FIMC_REG_CISTATUS_WINOFF_EN BIT(25)
-#define FIMC_REG_CISTATUS_IMGCPT_EN BIT(22)
-#define FIMC_REG_CISTATUS_IMGCPT_SCEN BIT(21)
-#define FIMC_REG_CISTATUS_VSYNC_A BIT(20)
-#define FIMC_REG_CISTATUS_VSYNC_B BIT(19)
-#define FIMC_REG_CISTATUS_OVRLB BIT(18)
-#define FIMC_REG_CISTATUS_FRAME_END BIT(17)
-#define FIMC_REG_CISTATUS_LASTCAPT_END BIT(16)
-#define FIMC_REG_CISTATUS_VVALID_A BIT(15)
-#define FIMC_REG_CISTATUS_VVALID_B BIT(14)
-
-/* Indexes to the last and the currently processed buffer. */
-#define FIMC_REG_CISTATUS2 0x68
-
-/* Image capture control */
-#define FIMC_REG_CIIMGCPT 0xc0
-#define FIMC_REG_CIIMGCPT_IMGCPTEN BIT(31)
-#define FIMC_REG_CIIMGCPT_IMGCPTEN_SC BIT(30)
-#define FIMC_REG_CIIMGCPT_CPT_FREN_ENABLE BIT(25)
-#define FIMC_REG_CIIMGCPT_CPT_FRMOD_CNT BIT(18)
-
-/* Frame capture sequence */
-#define FIMC_REG_CICPTSEQ 0xc4
-
-/* Image effect */
-#define FIMC_REG_CIIMGEFF 0xd0
-#define FIMC_REG_CIIMGEFF_IE_ENABLE BIT(30)
-#define FIMC_REG_CIIMGEFF_IE_SC_BEFORE (0 << 29)
-#define FIMC_REG_CIIMGEFF_IE_SC_AFTER (1 << 29)
-#define FIMC_REG_CIIMGEFF_FIN_BYPASS (0 << 26)
-#define FIMC_REG_CIIMGEFF_FIN_ARBITRARY (1 << 26)
-#define FIMC_REG_CIIMGEFF_FIN_NEGATIVE (2 << 26)
-#define FIMC_REG_CIIMGEFF_FIN_ARTFREEZE (3 << 26)
-#define FIMC_REG_CIIMGEFF_FIN_EMBOSSING (4 << 26)
-#define FIMC_REG_CIIMGEFF_FIN_SILHOUETTE (5 << 26)
-#define FIMC_REG_CIIMGEFF_FIN_MASK (7 << 26)
-#define FIMC_REG_CIIMGEFF_PAT_CBCR_MASK ((0xff << 13) | 0xff)
-
-/* Input DMA Y/Cb/Cr plane start address 0/1 */
-#define FIMC_REG_CIIYSA(n) (0xd4 + (n) * 0x70)
-#define FIMC_REG_CIICBSA(n) (0xd8 + (n) * 0x70)
-#define FIMC_REG_CIICRSA(n) (0xdc + (n) * 0x70)
-
-/* Real input DMA image size */
-#define FIMC_REG_CIREAL_ISIZE 0xf8
-#define FIMC_REG_CIREAL_ISIZE_AUTOLOAD_EN BIT(31)
-#define FIMC_REG_CIREAL_ISIZE_ADDR_CH_DIS BIT(30)
-
-/* Input DMA control */
-#define FIMC_REG_MSCTRL 0xfc
-#define FIMC_REG_MSCTRL_IN_BURST_COUNT_MASK (0xf << 24)
-#define FIMC_REG_MSCTRL_2P_IN_ORDER_MASK (3 << 16)
-#define FIMC_REG_MSCTRL_2P_IN_ORDER_SHIFT 16
-#define FIMC_REG_MSCTRL_C_INT_IN_3PLANE (0 << 15)
-#define FIMC_REG_MSCTRL_C_INT_IN_2PLANE (1 << 15)
-#define FIMC_REG_MSCTRL_C_INT_IN_MASK (1 << 15)
-#define FIMC_REG_MSCTRL_FLIP_SHIFT 13
-#define FIMC_REG_MSCTRL_FLIP_MASK (3 << 13)
-#define FIMC_REG_MSCTRL_FLIP_NORMAL (0 << 13)
-#define FIMC_REG_MSCTRL_FLIP_X_MIRROR (1 << 13)
-#define FIMC_REG_MSCTRL_FLIP_Y_MIRROR (2 << 13)
-#define FIMC_REG_MSCTRL_FLIP_180 (3 << 13)
-#define FIMC_REG_MSCTRL_FIFO_CTRL_FULL BIT(12)
-#define FIMC_REG_MSCTRL_ORDER422_SHIFT 4
-#define FIMC_REG_MSCTRL_ORDER422_CRYCBY (0 << 4)
-#define FIMC_REG_MSCTRL_ORDER422_YCRYCB (1 << 4)
-#define FIMC_REG_MSCTRL_ORDER422_CBYCRY (2 << 4)
-#define FIMC_REG_MSCTRL_ORDER422_YCBYCR (3 << 4)
-#define FIMC_REG_MSCTRL_ORDER422_MASK (3 << 4)
-#define FIMC_REG_MSCTRL_INPUT_EXTCAM (0 << 3)
-#define FIMC_REG_MSCTRL_INPUT_MEMORY BIT(3)
-#define FIMC_REG_MSCTRL_INPUT_MASK BIT(3)
-#define FIMC_REG_MSCTRL_INFORMAT_YCBCR420 (0 << 1)
-#define FIMC_REG_MSCTRL_INFORMAT_YCBCR422 (1 << 1)
-#define FIMC_REG_MSCTRL_INFORMAT_YCBCR422_1P (2 << 1)
-#define FIMC_REG_MSCTRL_INFORMAT_RGB (3 << 1)
-#define FIMC_REG_MSCTRL_INFORMAT_MASK (3 << 1)
-#define FIMC_REG_MSCTRL_ENVID BIT(0)
-#define FIMC_REG_MSCTRL_IN_BURST_COUNT(x) ((x) << 24)
-
-/* Output DMA Y/Cb/Cr offset */
-#define FIMC_REG_CIOYOFF 0x168
-#define FIMC_REG_CIOCBOFF 0x16c
-#define FIMC_REG_CIOCROFF 0x170
-
-/* Input DMA Y/Cb/Cr offset */
-#define FIMC_REG_CIIYOFF 0x174
-#define FIMC_REG_CIICBOFF 0x178
-#define FIMC_REG_CIICROFF 0x17c
-
-/* Input DMA original image size */
-#define FIMC_REG_ORGISIZE 0x180
-
-/* Output DMA original image size */
-#define FIMC_REG_ORGOSIZE 0x184
-
-/* Real output DMA image size (extension register) */
-#define FIMC_REG_CIEXTEN 0x188
-#define FIMC_REG_CIEXTEN_MHRATIO_EXT(x) (((x) & 0x3f) << 10)
-#define FIMC_REG_CIEXTEN_MVRATIO_EXT(x) ((x) & 0x3f)
-#define FIMC_REG_CIEXTEN_MHRATIO_EXT_MASK (0x3f << 10)
-#define FIMC_REG_CIEXTEN_MVRATIO_EXT_MASK 0x3f
-
-#define FIMC_REG_CIDMAPARAM 0x18c
-#define FIMC_REG_CIDMAPARAM_R_LINEAR (0 << 29)
-#define FIMC_REG_CIDMAPARAM_R_64X32 (3 << 29)
-#define FIMC_REG_CIDMAPARAM_W_LINEAR (0 << 13)
-#define FIMC_REG_CIDMAPARAM_W_64X32 (3 << 13)
-#define FIMC_REG_CIDMAPARAM_TILE_MASK ((3 << 29) | (3 << 13))
-
-/* MIPI CSI image format */
-#define FIMC_REG_CSIIMGFMT 0x194
-#define FIMC_REG_CSIIMGFMT_YCBCR422_8BIT 0x1e
-#define FIMC_REG_CSIIMGFMT_RAW8 0x2a
-#define FIMC_REG_CSIIMGFMT_RAW10 0x2b
-#define FIMC_REG_CSIIMGFMT_RAW12 0x2c
-/* User defined formats. x = 0...16. */
-#define FIMC_REG_CSIIMGFMT_USER(x) (0x30 + x - 1)
-
-/* Output frame buffer sequence mask */
-#define FIMC_REG_CIFCNTSEQ 0x1fc
-
-/* SYSREG ISP Writeback register address offsets */
-#define SYSREG_ISPBLK 0x020c
-#define SYSREG_ISPBLK_FIFORST_CAM_BLK BIT(7)
-
-#define SYSREG_CAMBLK 0x0218
-#define SYSREG_CAMBLK_FIFORST_ISP BIT(15)
-#define SYSREG_CAMBLK_ISPWB_FULL_EN (7 << 20)
-
-/*
- * Function declarations
- */
-void fimc_hw_reset(struct fimc_dev *fimc);
-void fimc_hw_set_rotation(struct fimc_ctx *ctx);
-void fimc_hw_set_target_format(struct fimc_ctx *ctx);
-void fimc_hw_set_out_dma(struct fimc_ctx *ctx);
-void fimc_hw_en_lastirq(struct fimc_dev *fimc, int enable);
-void fimc_hw_en_irq(struct fimc_dev *fimc, int enable);
-void fimc_hw_set_prescaler(struct fimc_ctx *ctx);
-void fimc_hw_set_mainscaler(struct fimc_ctx *ctx);
-void fimc_hw_enable_capture(struct fimc_ctx *ctx);
-void fimc_hw_set_effect(struct fimc_ctx *ctx);
-void fimc_hw_set_rgb_alpha(struct fimc_ctx *ctx);
-void fimc_hw_set_in_dma(struct fimc_ctx *ctx);
-void fimc_hw_set_input_path(struct fimc_ctx *ctx);
-void fimc_hw_set_output_path(struct fimc_ctx *ctx);
-void fimc_hw_set_input_addr(struct fimc_dev *fimc, struct fimc_addr *addr);
-void fimc_hw_set_output_addr(struct fimc_dev *fimc, struct fimc_addr *addr,
- int index);
-int fimc_hw_set_camera_source(struct fimc_dev *fimc,
- struct fimc_source_info *cam);
-void fimc_hw_set_camera_offset(struct fimc_dev *fimc, struct fimc_frame *f);
-int fimc_hw_set_camera_polarity(struct fimc_dev *fimc,
- struct fimc_source_info *cam);
-int fimc_hw_set_camera_type(struct fimc_dev *fimc,
- struct fimc_source_info *cam);
-void fimc_hw_clear_irq(struct fimc_dev *dev);
-void fimc_hw_enable_scaler(struct fimc_dev *dev, bool on);
-void fimc_hw_activate_input_dma(struct fimc_dev *dev, bool on);
-void fimc_hw_disable_capture(struct fimc_dev *dev);
-s32 fimc_hw_get_frame_index(struct fimc_dev *dev);
-s32 fimc_hw_get_prev_frame_index(struct fimc_dev *dev);
-int fimc_hw_camblk_cfg_writeback(struct fimc_dev *fimc);
-void fimc_activate_capture(struct fimc_ctx *ctx);
-void fimc_deactivate_capture(struct fimc_dev *fimc);
-
-/**
- * fimc_hw_set_dma_seq - configure output DMA buffer sequence
- * @dev: fimc device
- * @mask: bitmask for the DMA output buffer registers, set to 0 to skip buffer
- * This function masks output DMA ring buffers, it allows to select which of
- * the 32 available output buffer address registers will be used by the DMA
- * engine.
- */
-static inline void fimc_hw_set_dma_seq(struct fimc_dev *dev, u32 mask)
-{
- writel(mask, dev->regs + FIMC_REG_CIFCNTSEQ);
-}
-
-#endif /* FIMC_REG_H_ */
diff --git a/drivers/media/platform/exynos4-is/media-dev.c b/drivers/media/platform/exynos4-is/media-dev.c
deleted file mode 100644
index 544b54e428c9..000000000000
--- a/drivers/media/platform/exynos4-is/media-dev.c
+++ /dev/null
@@ -1,1604 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-or-later
-/*
- * S5P/EXYNOS4 SoC series camera host interface media device driver
- *
- * Copyright (C) 2011 - 2013 Samsung Electronics Co., Ltd.
- * Author: Sylwester Nawrocki <s.nawrocki@samsung.com>
- */
-
-#include <linux/bug.h>
-#include <linux/clk.h>
-#include <linux/clk-provider.h>
-#include <linux/device.h>
-#include <linux/errno.h>
-#include <linux/i2c.h>
-#include <linux/kernel.h>
-#include <linux/list.h>
-#include <linux/module.h>
-#include <linux/of.h>
-#include <linux/of_platform.h>
-#include <linux/of_device.h>
-#include <linux/of_graph.h>
-#include <linux/pinctrl/consumer.h>
-#include <linux/platform_device.h>
-#include <linux/pm_runtime.h>
-#include <linux/types.h>
-#include <linux/slab.h>
-#include <media/v4l2-async.h>
-#include <media/v4l2-ctrls.h>
-#include <media/v4l2-fwnode.h>
-#include <media/media-device.h>
-#include <media/drv-intf/exynos-fimc.h>
-
-#include "media-dev.h"
-#include "fimc-core.h"
-#include "fimc-is.h"
-#include "fimc-lite.h"
-#include "mipi-csis.h"
-
-/* Set up image sensor subdev -> FIMC capture node notifications. */
-static void __setup_sensor_notification(struct fimc_md *fmd,
- struct v4l2_subdev *sensor,
- struct v4l2_subdev *fimc_sd)
-{
- struct fimc_source_info *src_inf;
- struct fimc_sensor_info *md_si;
- unsigned long flags;
-
- src_inf = v4l2_get_subdev_hostdata(sensor);
- if (!src_inf || WARN_ON(fmd == NULL))
- return;
-
- md_si = source_to_sensor_info(src_inf);
- spin_lock_irqsave(&fmd->slock, flags);
- md_si->host = v4l2_get_subdevdata(fimc_sd);
- spin_unlock_irqrestore(&fmd->slock, flags);
-}
-
-/**
- * fimc_pipeline_prepare - update pipeline information with subdevice pointers
- * @p: fimc pipeline
- * @me: media entity terminating the pipeline
- *
- * Caller holds the graph mutex.
- */
-static void fimc_pipeline_prepare(struct fimc_pipeline *p,
- struct media_entity *me)
-{
- struct fimc_md *fmd = entity_to_fimc_mdev(me);
- struct v4l2_subdev *sd;
- struct v4l2_subdev *sensor = NULL;
- int i;
-
- for (i = 0; i < IDX_MAX; i++)
- p->subdevs[i] = NULL;
-
- while (1) {
- struct media_pad *pad = NULL;
-
- /* Find remote source pad */
- for (i = 0; i < me->num_pads; i++) {
- struct media_pad *spad = &me->pads[i];
- if (!(spad->flags & MEDIA_PAD_FL_SINK))
- continue;
- pad = media_entity_remote_pad(spad);
- if (pad)
- break;
- }
-
- if (!pad || !is_media_entity_v4l2_subdev(pad->entity))
- break;
- sd = media_entity_to_v4l2_subdev(pad->entity);
-
- switch (sd->grp_id) {
- case GRP_ID_SENSOR:
- sensor = sd;
- fallthrough;
- case GRP_ID_FIMC_IS_SENSOR:
- p->subdevs[IDX_SENSOR] = sd;
- break;
- case GRP_ID_CSIS:
- p->subdevs[IDX_CSIS] = sd;
- break;
- case GRP_ID_FLITE:
- p->subdevs[IDX_FLITE] = sd;
- break;
- case GRP_ID_FIMC:
- p->subdevs[IDX_FIMC] = sd;
- break;
- case GRP_ID_FIMC_IS:
- p->subdevs[IDX_IS_ISP] = sd;
- break;
- default:
- break;
- }
- me = &sd->entity;
- if (me->num_pads == 1)
- break;
- }
-
- if (sensor && p->subdevs[IDX_FIMC])
- __setup_sensor_notification(fmd, sensor, p->subdevs[IDX_FIMC]);
-}
-
-/**
- * __subdev_set_power - change power state of a single subdev
- * @sd: subdevice to change power state for
- * @on: 1 to enable power or 0 to disable
- *
- * Return result of s_power subdev operation or -ENXIO if sd argument
- * is NULL. Return 0 if the subdevice does not implement s_power.
- */
-static int __subdev_set_power(struct v4l2_subdev *sd, int on)
-{
- int *use_count;
- int ret;
-
- if (sd == NULL)
- return -ENXIO;
-
- use_count = &sd->entity.use_count;
- if (on && (*use_count)++ > 0)
- return 0;
- else if (!on && (*use_count == 0 || --(*use_count) > 0))
- return 0;
- ret = v4l2_subdev_call(sd, core, s_power, on);
-
- return ret != -ENOIOCTLCMD ? ret : 0;
-}
-
-/**
- * fimc_pipeline_s_power - change power state of all pipeline subdevs
- * @p: fimc device terminating the pipeline
- * @on: true to power on, false to power off
- *
- * Needs to be called with the graph mutex held.
- */
-static int fimc_pipeline_s_power(struct fimc_pipeline *p, bool on)
-{
- static const u8 seq[2][IDX_MAX - 1] = {
- { IDX_IS_ISP, IDX_SENSOR, IDX_CSIS, IDX_FLITE },
- { IDX_CSIS, IDX_FLITE, IDX_SENSOR, IDX_IS_ISP },
- };
- int i, ret = 0;
-
- if (p->subdevs[IDX_SENSOR] == NULL)
- return -ENXIO;
-
- for (i = 0; i < IDX_MAX - 1; i++) {
- unsigned int idx = seq[on][i];
-
- ret = __subdev_set_power(p->subdevs[idx], on);
-
-
- if (ret < 0 && ret != -ENXIO)
- goto error;
- }
- return 0;
-error:
- for (; i >= 0; i--) {
- unsigned int idx = seq[on][i];
- __subdev_set_power(p->subdevs[idx], !on);
- }
- return ret;
-}
-
-/**
- * __fimc_pipeline_enable - enable power of all pipeline subdevs
- * and the sensor clock
- * @ep: video pipeline structure
- * @fmd: fimc media device
- *
- * Called with the graph mutex held.
- */
-static int __fimc_pipeline_enable(struct exynos_media_pipeline *ep,
- struct fimc_md *fmd)
-{
- struct fimc_pipeline *p = to_fimc_pipeline(ep);
- int ret;
-
- /* Enable PXLASYNC clock if this pipeline includes FIMC-IS */
- if (!IS_ERR(fmd->wbclk[CLK_IDX_WB_B]) && p->subdevs[IDX_IS_ISP]) {
- ret = clk_prepare_enable(fmd->wbclk[CLK_IDX_WB_B]);
- if (ret < 0)
- return ret;
- }
-
- ret = fimc_pipeline_s_power(p, 1);
- if (!ret)
- return 0;
-
- if (!IS_ERR(fmd->wbclk[CLK_IDX_WB_B]) && p->subdevs[IDX_IS_ISP])
- clk_disable_unprepare(fmd->wbclk[CLK_IDX_WB_B]);
-
- return ret;
-}
-
-/**
- * __fimc_pipeline_open - update the pipeline information, enable power
- * of all pipeline subdevs and the sensor clock
- * @ep: fimc device terminating the pipeline
- * @me: media entity to start graph walk with
- * @prepare: true to walk the current pipeline and acquire all subdevs
- *
- * Called with the graph mutex held.
- */
-static int __fimc_pipeline_open(struct exynos_media_pipeline *ep,
- struct media_entity *me, bool prepare)
-{
- struct fimc_md *fmd = entity_to_fimc_mdev(me);
- struct fimc_pipeline *p = to_fimc_pipeline(ep);
- struct v4l2_subdev *sd;
-
- if (WARN_ON(p == NULL || me == NULL))
- return -EINVAL;
-
- if (prepare)
- fimc_pipeline_prepare(p, me);
-
- sd = p->subdevs[IDX_SENSOR];
- if (sd == NULL) {
- pr_warn("%s(): No sensor subdev\n", __func__);
- /*
- * Pipeline open cannot fail so as to make it possible
- * for the user space to configure the pipeline.
- */
- return 0;
- }
-
- return __fimc_pipeline_enable(ep, fmd);
-}
-
-/**
- * __fimc_pipeline_close - disable the sensor clock and pipeline power
- * @ep: fimc device terminating the pipeline
- *
- * Disable power of all subdevs and turn the external sensor clock off.
- */
-static int __fimc_pipeline_close(struct exynos_media_pipeline *ep)
-{
- struct fimc_pipeline *p = to_fimc_pipeline(ep);
- struct v4l2_subdev *sd = p ? p->subdevs[IDX_SENSOR] : NULL;
- struct fimc_md *fmd;
- int ret;
-
- if (sd == NULL) {
- pr_warn("%s(): No sensor subdev\n", __func__);
- return 0;
- }
-
- ret = fimc_pipeline_s_power(p, 0);
-
- fmd = entity_to_fimc_mdev(&sd->entity);
-
- /* Disable PXLASYNC clock if this pipeline includes FIMC-IS */
- if (!IS_ERR(fmd->wbclk[CLK_IDX_WB_B]) && p->subdevs[IDX_IS_ISP])
- clk_disable_unprepare(fmd->wbclk[CLK_IDX_WB_B]);
-
- return ret == -ENXIO ? 0 : ret;
-}
-
-/**
- * __fimc_pipeline_s_stream - call s_stream() on pipeline subdevs
- * @ep: video pipeline structure
- * @on: passed as the s_stream() callback argument
- */
-static int __fimc_pipeline_s_stream(struct exynos_media_pipeline *ep, bool on)
-{
- static const u8 seq[2][IDX_MAX] = {
- { IDX_FIMC, IDX_SENSOR, IDX_IS_ISP, IDX_CSIS, IDX_FLITE },
- { IDX_CSIS, IDX_FLITE, IDX_FIMC, IDX_SENSOR, IDX_IS_ISP },
- };
- struct fimc_pipeline *p = to_fimc_pipeline(ep);
- enum fimc_subdev_index sd_id;
- int i, ret = 0;
-
- if (p->subdevs[IDX_SENSOR] == NULL) {
- struct fimc_md *fmd;
- struct v4l2_subdev *sd = p->subdevs[IDX_CSIS];
-
- if (!sd)
- sd = p->subdevs[IDX_FIMC];
-
- if (!sd) {
- /*
- * If neither CSIS nor FIMC was set up,
- * it's impossible to have any sensors
- */
- return -ENODEV;
- }
-
- fmd = entity_to_fimc_mdev(&sd->entity);
-
- if (!fmd->user_subdev_api) {
- /*
- * Sensor must be already discovered if we
- * aren't in the user_subdev_api mode
- */
- return -ENODEV;
- }
-
- /* Get pipeline sink entity */
- if (p->subdevs[IDX_FIMC])
- sd_id = IDX_FIMC;
- else if (p->subdevs[IDX_IS_ISP])
- sd_id = IDX_IS_ISP;
- else if (p->subdevs[IDX_FLITE])
- sd_id = IDX_FLITE;
- else
- return -ENODEV;
-
- /*
- * Sensor could have been linked between open and STREAMON -
- * check if this is the case.
- */
- fimc_pipeline_prepare(p, &p->subdevs[sd_id]->entity);
-
- if (p->subdevs[IDX_SENSOR] == NULL)
- return -ENODEV;
-
- ret = __fimc_pipeline_enable(ep, fmd);
- if (ret < 0)
- return ret;
-
- }
-
- for (i = 0; i < IDX_MAX; i++) {
- unsigned int idx = seq[on][i];
-
- ret = v4l2_subdev_call(p->subdevs[idx], video, s_stream, on);
-
- if (ret < 0 && ret != -ENOIOCTLCMD && ret != -ENODEV)
- goto error;
- }
-
- return 0;
-error:
- fimc_pipeline_s_power(p, !on);
- for (; i >= 0; i--) {
- unsigned int idx = seq[on][i];
- v4l2_subdev_call(p->subdevs[idx], video, s_stream, !on);
- }
- return ret;
-}
-
-/* Media pipeline operations for the FIMC/FIMC-LITE video device driver */
-static const struct exynos_media_pipeline_ops fimc_pipeline_ops = {
- .open = __fimc_pipeline_open,
- .close = __fimc_pipeline_close,
- .set_stream = __fimc_pipeline_s_stream,
-};
-
-static struct exynos_media_pipeline *fimc_md_pipeline_create(
- struct fimc_md *fmd)
-{
- struct fimc_pipeline *p;
-
- p = kzalloc(sizeof(*p), GFP_KERNEL);
- if (!p)
- return NULL;
-
- list_add_tail(&p->list, &fmd->pipelines);
-
- p->ep.ops = &fimc_pipeline_ops;
- return &p->ep;
-}
-
-static void fimc_md_pipelines_free(struct fimc_md *fmd)
-{
- while (!list_empty(&fmd->pipelines)) {
- struct fimc_pipeline *p;
-
- p = list_entry(fmd->pipelines.next, typeof(*p), list);
- list_del(&p->list);
- kfree(p);
- }
-}
-
-static int fimc_md_parse_one_endpoint(struct fimc_md *fmd,
- struct device_node *ep)
-{
- int index = fmd->num_sensors;
- struct fimc_source_info *pd = &fmd->sensor[index].pdata;
- struct device_node *rem, *np;
- struct v4l2_async_subdev *asd;
- struct v4l2_fwnode_endpoint endpoint = { .bus_type = 0 };
- int ret;
-
- ret = v4l2_fwnode_endpoint_parse(of_fwnode_handle(ep), &endpoint);
- if (ret) {
- of_node_put(ep);
- return ret;
- }
-
- if (WARN_ON(endpoint.base.port == 0) || index >= FIMC_MAX_SENSORS) {
- of_node_put(ep);
- return -EINVAL;
- }
-
- pd->mux_id = (endpoint.base.port - 1) & 0x1;
-
- rem = of_graph_get_remote_port_parent(ep);
- if (rem == NULL) {
- v4l2_info(&fmd->v4l2_dev, "Remote device at %pOF not found\n",
- ep);
- of_node_put(ep);
- return 0;
- }
-
- if (fimc_input_is_parallel(endpoint.base.port)) {
- if (endpoint.bus_type == V4L2_MBUS_PARALLEL)
- pd->sensor_bus_type = FIMC_BUS_TYPE_ITU_601;
- else
- pd->sensor_bus_type = FIMC_BUS_TYPE_ITU_656;
- pd->flags = endpoint.bus.parallel.flags;
- } else if (fimc_input_is_mipi_csi(endpoint.base.port)) {
- /*
- * MIPI CSI-2: only input mux selection and
- * the sensor's clock frequency is needed.
- */
- pd->sensor_bus_type = FIMC_BUS_TYPE_MIPI_CSI2;
- } else {
- v4l2_err(&fmd->v4l2_dev, "Wrong port id (%u) at node %pOF\n",
- endpoint.base.port, rem);
- }
- /*
- * For FIMC-IS handled sensors, that are placed under i2c-isp device
- * node, FIMC is connected to the FIMC-IS through its ISP Writeback
- * input. Sensors are attached to the FIMC-LITE hostdata interface
- * directly or through MIPI-CSIS, depending on the external media bus
- * used. This needs to be handled in a more reliable way, not by just
- * checking parent's node name.
- */
- np = of_get_parent(rem);
- of_node_put(rem);
-
- if (of_node_name_eq(np, "i2c-isp"))
- pd->fimc_bus_type = FIMC_BUS_TYPE_ISP_WRITEBACK;
- else
- pd->fimc_bus_type = pd->sensor_bus_type;
- of_node_put(np);
-
- if (WARN_ON(index >= ARRAY_SIZE(fmd->sensor))) {
- of_node_put(ep);
- return -EINVAL;
- }
-
- asd = v4l2_async_nf_add_fwnode_remote(&fmd->subdev_notifier,
- of_fwnode_handle(ep),
- struct v4l2_async_subdev);
-
- of_node_put(ep);
-
- if (IS_ERR(asd))
- return PTR_ERR(asd);
-
- fmd->sensor[index].asd = asd;
- fmd->num_sensors++;
-
- return 0;
-}
-
-/* Parse port node and register as a sub-device any sensor specified there. */
-static int fimc_md_parse_port_node(struct fimc_md *fmd,
- struct device_node *port)
-{
- struct device_node *ep;
- int ret;
-
- for_each_child_of_node(port, ep) {
- ret = fimc_md_parse_one_endpoint(fmd, ep);
- if (ret < 0) {
- of_node_put(ep);
- return ret;
- }
- }
-
- return 0;
-}
-
-/* Register all SoC external sub-devices */
-static int fimc_md_register_sensor_entities(struct fimc_md *fmd)
-{
- struct device_node *parent = fmd->pdev->dev.of_node;
- struct device_node *ports = NULL;
- struct device_node *node;
- int ret;
-
- /*
- * Runtime resume one of the FIMC entities to make sure
- * the sclk_cam clocks are not globally disabled.
- */
- if (!fmd->pmf)
- return -ENXIO;
-
- ret = pm_runtime_resume_and_get(fmd->pmf);
- if (ret < 0)
- return ret;
-
- fmd->num_sensors = 0;
-
- /* Attach sensors linked to MIPI CSI-2 receivers */
- for_each_available_child_of_node(parent, node) {
- struct device_node *port;
-
- if (!of_node_name_eq(node, "csis"))
- continue;
- /* The csis node can have only port subnode. */
- port = of_get_next_child(node, NULL);
- if (!port)
- continue;
-
- ret = fimc_md_parse_port_node(fmd, port);
- of_node_put(port);
- if (ret < 0) {
- of_node_put(node);
- goto cleanup;
- }
- }
-
- /* Attach sensors listed in the parallel-ports node */
- ports = of_get_child_by_name(parent, "parallel-ports");
- if (!ports)
- goto rpm_put;
-
- for_each_child_of_node(ports, node) {
- ret = fimc_md_parse_port_node(fmd, node);
- if (ret < 0) {
- of_node_put(node);
- goto cleanup;
- }
- }
- of_node_put(ports);
-
-rpm_put:
- pm_runtime_put(fmd->pmf);
- return 0;
-
-cleanup:
- of_node_put(ports);
- v4l2_async_nf_cleanup(&fmd->subdev_notifier);
- pm_runtime_put(fmd->pmf);
- return ret;
-}
-
-static int __of_get_csis_id(struct device_node *np)
-{
- u32 reg = 0;
-
- np = of_get_child_by_name(np, "port");
- if (!np)
- return -EINVAL;
- of_property_read_u32(np, "reg", &reg);
- of_node_put(np);
- return reg - FIMC_INPUT_MIPI_CSI2_0;
-}
-
-/*
- * MIPI-CSIS, FIMC and FIMC-LITE platform devices registration.
- */
-static int register_fimc_lite_entity(struct fimc_md *fmd,
- struct fimc_lite *fimc_lite)
-{
- struct v4l2_subdev *sd;
- struct exynos_media_pipeline *ep;
- int ret;
-
- if (WARN_ON(fimc_lite->index >= FIMC_LITE_MAX_DEVS ||
- fmd->fimc_lite[fimc_lite->index]))
- return -EBUSY;
-
- sd = &fimc_lite->subdev;
- sd->grp_id = GRP_ID_FLITE;
-
- ep = fimc_md_pipeline_create(fmd);
- if (!ep)
- return -ENOMEM;
-
- v4l2_set_subdev_hostdata(sd, ep);
-
- ret = v4l2_device_register_subdev(&fmd->v4l2_dev, sd);
- if (!ret)
- fmd->fimc_lite[fimc_lite->index] = fimc_lite;
- else
- v4l2_err(&fmd->v4l2_dev, "Failed to register FIMC.LITE%d\n",
- fimc_lite->index);
- return ret;
-}
-
-static int register_fimc_entity(struct fimc_md *fmd, struct fimc_dev *fimc)
-{
- struct v4l2_subdev *sd;
- struct exynos_media_pipeline *ep;
- int ret;
-
- if (WARN_ON(fimc->id >= FIMC_MAX_DEVS || fmd->fimc[fimc->id]))
- return -EBUSY;
-
- sd = &fimc->vid_cap.subdev;
- sd->grp_id = GRP_ID_FIMC;
-
- ep = fimc_md_pipeline_create(fmd);
- if (!ep)
- return -ENOMEM;
-
- v4l2_set_subdev_hostdata(sd, ep);
-
- ret = v4l2_device_register_subdev(&fmd->v4l2_dev, sd);
- if (!ret) {
- if (!fmd->pmf && fimc->pdev)
- fmd->pmf = &fimc->pdev->dev;
- fmd->fimc[fimc->id] = fimc;
- fimc->vid_cap.user_subdev_api = fmd->user_subdev_api;
- } else {
- v4l2_err(&fmd->v4l2_dev, "Failed to register FIMC.%d (%d)\n",
- fimc->id, ret);
- }
- return ret;
-}
-
-static int register_csis_entity(struct fimc_md *fmd,
- struct platform_device *pdev,
- struct v4l2_subdev *sd)
-{
- struct device_node *node = pdev->dev.of_node;
- int id, ret;
-
- id = node ? __of_get_csis_id(node) : max(0, pdev->id);
-
- if (WARN_ON(id < 0 || id >= CSIS_MAX_ENTITIES))
- return -ENOENT;
-
- if (WARN_ON(fmd->csis[id].sd))
- return -EBUSY;
-
- sd->grp_id = GRP_ID_CSIS;
- ret = v4l2_device_register_subdev(&fmd->v4l2_dev, sd);
- if (!ret)
- fmd->csis[id].sd = sd;
- else
- v4l2_err(&fmd->v4l2_dev,
- "Failed to register MIPI-CSIS.%d (%d)\n", id, ret);
- return ret;
-}
-
-static int register_fimc_is_entity(struct fimc_md *fmd, struct fimc_is *is)
-{
- struct v4l2_subdev *sd = &is->isp.subdev;
- struct exynos_media_pipeline *ep;
- int ret;
-
- /* Allocate pipeline object for the ISP capture video node. */
- ep = fimc_md_pipeline_create(fmd);
- if (!ep)
- return -ENOMEM;
-
- v4l2_set_subdev_hostdata(sd, ep);
-
- ret = v4l2_device_register_subdev(&fmd->v4l2_dev, sd);
- if (ret) {
- v4l2_err(&fmd->v4l2_dev,
- "Failed to register FIMC-ISP (%d)\n", ret);
- return ret;
- }
-
- fmd->fimc_is = is;
- return 0;
-}
-
-static int fimc_md_register_platform_entity(struct fimc_md *fmd,
- struct platform_device *pdev,
- int plat_entity)
-{
- struct device *dev = &pdev->dev;
- int ret = -EPROBE_DEFER;
- void *drvdata;
-
- /* Lock to ensure dev->driver won't change. */
- device_lock(dev);
-
- if (!dev->driver || !try_module_get(dev->driver->owner))
- goto dev_unlock;
-
- drvdata = dev_get_drvdata(dev);
- /* Some subdev didn't probe successfully id drvdata is NULL */
- if (drvdata) {
- switch (plat_entity) {
- case IDX_FIMC:
- ret = register_fimc_entity(fmd, drvdata);
- break;
- case IDX_FLITE:
- ret = register_fimc_lite_entity(fmd, drvdata);
- break;
- case IDX_CSIS:
- ret = register_csis_entity(fmd, pdev, drvdata);
- break;
- case IDX_IS_ISP:
- ret = register_fimc_is_entity(fmd, drvdata);
- break;
- default:
- ret = -ENODEV;
- }
- }
-
- module_put(dev->driver->owner);
-dev_unlock:
- device_unlock(dev);
- if (ret == -EPROBE_DEFER)
- dev_info(&fmd->pdev->dev, "deferring %s device registration\n",
- dev_name(dev));
- else if (ret < 0)
- dev_err(&fmd->pdev->dev, "%s device registration failed (%d)\n",
- dev_name(dev), ret);
- return ret;
-}
-
-/* Register FIMC, FIMC-LITE and CSIS media entities */
-static int fimc_md_register_platform_entities(struct fimc_md *fmd,
- struct device_node *parent)
-{
- struct device_node *node;
- int ret = 0;
-
- for_each_available_child_of_node(parent, node) {
- struct platform_device *pdev;
- int plat_entity = -1;
-
- pdev = of_find_device_by_node(node);
- if (!pdev)
- continue;
-
- /* If driver of any entity isn't ready try all again later. */
- if (of_node_name_eq(node, CSIS_OF_NODE_NAME))
- plat_entity = IDX_CSIS;
- else if (of_node_name_eq(node, FIMC_IS_OF_NODE_NAME))
- plat_entity = IDX_IS_ISP;
- else if (of_node_name_eq(node, FIMC_LITE_OF_NODE_NAME))
- plat_entity = IDX_FLITE;
- else if (of_node_name_eq(node, FIMC_OF_NODE_NAME) &&
- !of_property_read_bool(node, "samsung,lcd-wb"))
- plat_entity = IDX_FIMC;
-
- if (plat_entity >= 0)
- ret = fimc_md_register_platform_entity(fmd, pdev,
- plat_entity);
- put_device(&pdev->dev);
- if (ret < 0) {
- of_node_put(node);
- break;
- }
- }
-
- return ret;
-}
-
-static void fimc_md_unregister_entities(struct fimc_md *fmd)
-{
- int i;
-
- for (i = 0; i < FIMC_MAX_DEVS; i++) {
- struct fimc_dev *dev = fmd->fimc[i];
- if (dev == NULL)
- continue;
- v4l2_device_unregister_subdev(&dev->vid_cap.subdev);
- dev->vid_cap.ve.pipe = NULL;
- fmd->fimc[i] = NULL;
- }
- for (i = 0; i < FIMC_LITE_MAX_DEVS; i++) {
- struct fimc_lite *dev = fmd->fimc_lite[i];
- if (dev == NULL)
- continue;
- v4l2_device_unregister_subdev(&dev->subdev);
- dev->ve.pipe = NULL;
- fmd->fimc_lite[i] = NULL;
- }
- for (i = 0; i < CSIS_MAX_ENTITIES; i++) {
- if (fmd->csis[i].sd == NULL)
- continue;
- v4l2_device_unregister_subdev(fmd->csis[i].sd);
- fmd->csis[i].sd = NULL;
- }
-
- if (fmd->fimc_is)
- v4l2_device_unregister_subdev(&fmd->fimc_is->isp.subdev);
-
- v4l2_info(&fmd->v4l2_dev, "Unregistered all entities\n");
-}
-
-/**
- * __fimc_md_create_fimc_sink_links - create links to all FIMC entities
- * @fmd: fimc media device
- * @source: the source entity to create links to all fimc entities from
- * @sensor: sensor subdev linked to FIMC[fimc_id] entity, may be null
- * @pad: the source entity pad index
- * @link_mask: bitmask of the fimc devices for which link should be enabled
- */
-static int __fimc_md_create_fimc_sink_links(struct fimc_md *fmd,
- struct media_entity *source,
- struct v4l2_subdev *sensor,
- int pad, int link_mask)
-{
- struct fimc_source_info *si = NULL;
- struct media_entity *sink;
- unsigned int flags = 0;
- int i, ret = 0;
-
- if (sensor) {
- si = v4l2_get_subdev_hostdata(sensor);
- /* Skip direct FIMC links in the logical FIMC-IS sensor path */
- if (si && si->fimc_bus_type == FIMC_BUS_TYPE_ISP_WRITEBACK)
- ret = 1;
- }
-
- for (i = 0; !ret && i < FIMC_MAX_DEVS; i++) {
- if (!fmd->fimc[i])
- continue;
- /*
- * Some FIMC variants are not fitted with camera capture
- * interface. Skip creating a link from sensor for those.
- */
- if (!fmd->fimc[i]->variant->has_cam_if)
- continue;
-
- flags = ((1 << i) & link_mask) ? MEDIA_LNK_FL_ENABLED : 0;
-
- sink = &fmd->fimc[i]->vid_cap.subdev.entity;
- ret = media_create_pad_link(source, pad, sink,
- FIMC_SD_PAD_SINK_CAM, flags);
- if (ret)
- return ret;
-
- /* Notify FIMC capture subdev entity */
- ret = media_entity_call(sink, link_setup, &sink->pads[0],
- &source->pads[pad], flags);
- if (ret)
- break;
-
- v4l2_info(&fmd->v4l2_dev, "created link [%s] %c> [%s]\n",
- source->name, flags ? '=' : '-', sink->name);
- }
-
- for (i = 0; i < FIMC_LITE_MAX_DEVS; i++) {
- if (!fmd->fimc_lite[i])
- continue;
-
- sink = &fmd->fimc_lite[i]->subdev.entity;
- ret = media_create_pad_link(source, pad, sink,
- FLITE_SD_PAD_SINK, 0);
- if (ret)
- return ret;
-
- /* Notify FIMC-LITE subdev entity */
- ret = media_entity_call(sink, link_setup, &sink->pads[0],
- &source->pads[pad], 0);
- if (ret)
- break;
-
- v4l2_info(&fmd->v4l2_dev, "created link [%s] -> [%s]\n",
- source->name, sink->name);
- }
- return 0;
-}
-
-/* Create links from FIMC-LITE source pads to other entities */
-static int __fimc_md_create_flite_source_links(struct fimc_md *fmd)
-{
- struct media_entity *source, *sink;
- int i, ret = 0;
-
- for (i = 0; i < FIMC_LITE_MAX_DEVS; i++) {
- struct fimc_lite *fimc = fmd->fimc_lite[i];
-
- if (fimc == NULL)
- continue;
-
- source = &fimc->subdev.entity;
- sink = &fimc->ve.vdev.entity;
- /* FIMC-LITE's subdev and video node */
- ret = media_create_pad_link(source, FLITE_SD_PAD_SOURCE_DMA,
- sink, 0, 0);
- if (ret)
- break;
- /* Link from FIMC-LITE to IS-ISP subdev */
- sink = &fmd->fimc_is->isp.subdev.entity;
- ret = media_create_pad_link(source, FLITE_SD_PAD_SOURCE_ISP,
- sink, 0, 0);
- if (ret)
- break;
- }
-
- return ret;
-}
-
-/* Create FIMC-IS links */
-static int __fimc_md_create_fimc_is_links(struct fimc_md *fmd)
-{
- struct fimc_isp *isp = &fmd->fimc_is->isp;
- struct media_entity *source, *sink;
- int i, ret;
-
- source = &isp->subdev.entity;
-
- for (i = 0; i < FIMC_MAX_DEVS; i++) {
- if (fmd->fimc[i] == NULL)
- continue;
-
- /* Link from FIMC-IS-ISP subdev to FIMC */
- sink = &fmd->fimc[i]->vid_cap.subdev.entity;
- ret = media_create_pad_link(source, FIMC_ISP_SD_PAD_SRC_FIFO,
- sink, FIMC_SD_PAD_SINK_FIFO, 0);
- if (ret)
- return ret;
- }
-
- /* Link from FIMC-IS-ISP subdev to fimc-is-isp.capture video node */
- sink = &isp->video_capture.ve.vdev.entity;
-
- /* Skip this link if the fimc-is-isp video node driver isn't built-in */
- if (sink->num_pads == 0)
- return 0;
-
- return media_create_pad_link(source, FIMC_ISP_SD_PAD_SRC_DMA,
- sink, 0, 0);
-}
-
-/**
- * fimc_md_create_links - create default links between registered entities
- * @fmd: fimc media device
- *
- * Parallel interface sensor entities are connected directly to FIMC capture
- * entities. The sensors using MIPI CSIS bus are connected through immutable
- * link with CSI receiver entity specified by mux_id. Any registered CSIS
- * entity has a link to each registered FIMC capture entity. Enabled links
- * are created by default between each subsequent registered sensor and
- * subsequent FIMC capture entity. The number of default active links is
- * determined by the number of available sensors or FIMC entities,
- * whichever is less.
- */
-static int fimc_md_create_links(struct fimc_md *fmd)
-{
- struct v4l2_subdev *csi_sensors[CSIS_MAX_ENTITIES] = { NULL };
- struct v4l2_subdev *sensor, *csis;
- struct fimc_source_info *pdata;
- struct media_entity *source, *sink;
- int i, pad, fimc_id = 0, ret = 0;
- u32 flags, link_mask = 0;
-
- for (i = 0; i < fmd->num_sensors; i++) {
- if (fmd->sensor[i].subdev == NULL)
- continue;
-
- sensor = fmd->sensor[i].subdev;
- pdata = v4l2_get_subdev_hostdata(sensor);
- if (!pdata)
- continue;
-
- source = NULL;
-
- switch (pdata->sensor_bus_type) {
- case FIMC_BUS_TYPE_MIPI_CSI2:
- if (WARN(pdata->mux_id >= CSIS_MAX_ENTITIES,
- "Wrong CSI channel id: %d\n", pdata->mux_id))
- return -EINVAL;
-
- csis = fmd->csis[pdata->mux_id].sd;
- if (WARN(csis == NULL,
- "MIPI-CSI interface specified but s5p-csis module is not loaded!\n"))
- return -EINVAL;
-
- pad = sensor->entity.num_pads - 1;
- ret = media_create_pad_link(&sensor->entity, pad,
- &csis->entity, CSIS_PAD_SINK,
- MEDIA_LNK_FL_IMMUTABLE |
- MEDIA_LNK_FL_ENABLED);
- if (ret)
- return ret;
-
- v4l2_info(&fmd->v4l2_dev, "created link [%s] => [%s]\n",
- sensor->entity.name, csis->entity.name);
-
- source = NULL;
- csi_sensors[pdata->mux_id] = sensor;
- break;
-
- case FIMC_BUS_TYPE_ITU_601...FIMC_BUS_TYPE_ITU_656:
- source = &sensor->entity;
- pad = 0;
- break;
-
- default:
- v4l2_err(&fmd->v4l2_dev, "Wrong bus_type: %x\n",
- pdata->sensor_bus_type);
- return -EINVAL;
- }
- if (source == NULL)
- continue;
-
- link_mask = 1 << fimc_id++;
- ret = __fimc_md_create_fimc_sink_links(fmd, source, sensor,
- pad, link_mask);
- }
-
- for (i = 0; i < CSIS_MAX_ENTITIES; i++) {
- if (fmd->csis[i].sd == NULL)
- continue;
-
- source = &fmd->csis[i].sd->entity;
- pad = CSIS_PAD_SOURCE;
- sensor = csi_sensors[i];
-
- link_mask = 1 << fimc_id++;
- ret = __fimc_md_create_fimc_sink_links(fmd, source, sensor,
- pad, link_mask);
- }
-
- /* Create immutable links between each FIMC's subdev and video node */
- flags = MEDIA_LNK_FL_IMMUTABLE | MEDIA_LNK_FL_ENABLED;
- for (i = 0; i < FIMC_MAX_DEVS; i++) {
- if (!fmd->fimc[i])
- continue;
-
- source = &fmd->fimc[i]->vid_cap.subdev.entity;
- sink = &fmd->fimc[i]->vid_cap.ve.vdev.entity;
-
- ret = media_create_pad_link(source, FIMC_SD_PAD_SOURCE,
- sink, 0, flags);
- if (ret)
- break;
- }
-
- ret = __fimc_md_create_flite_source_links(fmd);
- if (ret < 0)
- return ret;
-
- if (fmd->use_isp)
- ret = __fimc_md_create_fimc_is_links(fmd);
-
- return ret;
-}
-
-/*
- * The peripheral sensor and CAM_BLK (PIXELASYNCMx) clocks management.
- */
-static void fimc_md_put_clocks(struct fimc_md *fmd)
-{
- int i = FIMC_MAX_CAMCLKS;
-
- while (--i >= 0) {
- if (IS_ERR(fmd->camclk[i].clock))
- continue;
- clk_put(fmd->camclk[i].clock);
- fmd->camclk[i].clock = ERR_PTR(-EINVAL);
- }
-
- /* Writeback (PIXELASYNCMx) clocks */
- for (i = 0; i < FIMC_MAX_WBCLKS; i++) {
- if (IS_ERR(fmd->wbclk[i]))
- continue;
- clk_put(fmd->wbclk[i]);
- fmd->wbclk[i] = ERR_PTR(-EINVAL);
- }
-}
-
-static int fimc_md_get_clocks(struct fimc_md *fmd)
-{
- struct device *dev = &fmd->pdev->dev;
- char clk_name[32];
- struct clk *clock;
- int i, ret = 0;
-
- for (i = 0; i < FIMC_MAX_CAMCLKS; i++)
- fmd->camclk[i].clock = ERR_PTR(-EINVAL);
-
- for (i = 0; i < FIMC_MAX_CAMCLKS; i++) {
- snprintf(clk_name, sizeof(clk_name), "sclk_cam%u", i);
- clock = clk_get(dev, clk_name);
-
- if (IS_ERR(clock)) {
- dev_err(dev, "Failed to get clock: %s\n", clk_name);
- ret = PTR_ERR(clock);
- break;
- }
- fmd->camclk[i].clock = clock;
- }
- if (ret)
- fimc_md_put_clocks(fmd);
-
- if (!fmd->use_isp)
- return 0;
- /*
- * For now get only PIXELASYNCM1 clock (Writeback B/ISP),
- * leave PIXELASYNCM0 out for the LCD Writeback driver.
- */
- fmd->wbclk[CLK_IDX_WB_A] = ERR_PTR(-EINVAL);
-
- for (i = CLK_IDX_WB_B; i < FIMC_MAX_WBCLKS; i++) {
- snprintf(clk_name, sizeof(clk_name), "pxl_async%u", i);
- clock = clk_get(dev, clk_name);
- if (IS_ERR(clock)) {
- v4l2_err(&fmd->v4l2_dev, "Failed to get clock: %s\n",
- clk_name);
- ret = PTR_ERR(clock);
- break;
- }
- fmd->wbclk[i] = clock;
- }
- if (ret)
- fimc_md_put_clocks(fmd);
-
- return ret;
-}
-
-static int __fimc_md_modify_pipeline(struct media_entity *entity, bool enable)
-{
- struct exynos_video_entity *ve;
- struct fimc_pipeline *p;
- struct video_device *vdev;
- int ret;
-
- vdev = media_entity_to_video_device(entity);
- if (vdev->entity.use_count == 0)
- return 0;
-
- ve = vdev_to_exynos_video_entity(vdev);
- p = to_fimc_pipeline(ve->pipe);
- /*
- * Nothing to do if we are disabling the pipeline, some link
- * has been disconnected and p->subdevs array is cleared now.
- */
- if (!enable && p->subdevs[IDX_SENSOR] == NULL)
- return 0;
-
- if (enable)
- ret = __fimc_pipeline_open(ve->pipe, entity, true);
- else
- ret = __fimc_pipeline_close(ve->pipe);
-
- if (ret == 0 && !enable)
- memset(p->subdevs, 0, sizeof(p->subdevs));
-
- return ret;
-}
-
-/* Locking: called with entity->graph_obj.mdev->graph_mutex mutex held. */
-static int __fimc_md_modify_pipelines(struct media_entity *entity, bool enable,
- struct media_graph *graph)
-{
- struct media_entity *entity_err = entity;
- int ret;
-
- /*
- * Walk current graph and call the pipeline open/close routine for each
- * opened video node that belongs to the graph of entities connected
- * through active links. This is needed as we cannot power on/off the
- * subdevs in random order.
- */
- media_graph_walk_start(graph, entity);
-
- while ((entity = media_graph_walk_next(graph))) {
- if (!is_media_entity_v4l2_video_device(entity))
- continue;
-
- ret = __fimc_md_modify_pipeline(entity, enable);
-
- if (ret < 0)
- goto err;
- }
-
- return 0;
-
-err:
- media_graph_walk_start(graph, entity_err);
-
- while ((entity_err = media_graph_walk_next(graph))) {
- if (!is_media_entity_v4l2_video_device(entity_err))
- continue;
-
- __fimc_md_modify_pipeline(entity_err, !enable);
-
- if (entity_err == entity)
- break;
- }
-
- return ret;
-}
-
-static int fimc_md_link_notify(struct media_link *link, unsigned int flags,
- unsigned int notification)
-{
- struct media_graph *graph =
- &container_of(link->graph_obj.mdev, struct fimc_md,
- media_dev)->link_setup_graph;
- struct media_entity *sink = link->sink->entity;
- int ret = 0;
-
- /* Before link disconnection */
- if (notification == MEDIA_DEV_NOTIFY_PRE_LINK_CH) {
- ret = media_graph_walk_init(graph,
- link->graph_obj.mdev);
- if (ret)
- return ret;
- if (!(flags & MEDIA_LNK_FL_ENABLED))
- ret = __fimc_md_modify_pipelines(sink, false, graph);
-#if 0
- else
- /* TODO: Link state change validation */
-#endif
- /* After link activation */
- } else if (notification == MEDIA_DEV_NOTIFY_POST_LINK_CH) {
- if (link->flags & MEDIA_LNK_FL_ENABLED)
- ret = __fimc_md_modify_pipelines(sink, true, graph);
- media_graph_walk_cleanup(graph);
- }
-
- return ret ? -EPIPE : 0;
-}
-
-static const struct media_device_ops fimc_md_ops = {
- .link_notify = fimc_md_link_notify,
-};
-
-static ssize_t subdev_conf_mode_show(struct device *dev,
- struct device_attribute *attr, char *buf)
-{
- struct fimc_md *fmd = dev_get_drvdata(dev);
-
- if (fmd->user_subdev_api)
- return strscpy(buf, "Sub-device API (sub-dev)\n", PAGE_SIZE);
-
- return strscpy(buf, "V4L2 video node only API (vid-dev)\n", PAGE_SIZE);
-}
-
-static ssize_t subdev_conf_mode_store(struct device *dev,
- struct device_attribute *attr,
- const char *buf, size_t count)
-{
- struct fimc_md *fmd = dev_get_drvdata(dev);
- bool subdev_api;
- int i;
-
- if (!strcmp(buf, "vid-dev\n"))
- subdev_api = false;
- else if (!strcmp(buf, "sub-dev\n"))
- subdev_api = true;
- else
- return count;
-
- fmd->user_subdev_api = subdev_api;
- for (i = 0; i < FIMC_MAX_DEVS; i++)
- if (fmd->fimc[i])
- fmd->fimc[i]->vid_cap.user_subdev_api = subdev_api;
- return count;
-}
-/*
- * This device attribute is to select video pipeline configuration method.
- * There are following valid values:
- * vid-dev - for V4L2 video node API only, subdevice will be configured
- * by the host driver.
- * sub-dev - for media controller API, subdevs must be configured in user
- * space before starting streaming.
- */
-static DEVICE_ATTR_RW(subdev_conf_mode);
-
-static int cam_clk_prepare(struct clk_hw *hw)
-{
- struct cam_clk *camclk = to_cam_clk(hw);
-
- if (camclk->fmd->pmf == NULL)
- return -ENODEV;
-
- return pm_runtime_resume_and_get(camclk->fmd->pmf);
-}
-
-static void cam_clk_unprepare(struct clk_hw *hw)
-{
- struct cam_clk *camclk = to_cam_clk(hw);
-
- if (camclk->fmd->pmf == NULL)
- return;
-
- pm_runtime_put_sync(camclk->fmd->pmf);
-}
-
-static const struct clk_ops cam_clk_ops = {
- .prepare = cam_clk_prepare,
- .unprepare = cam_clk_unprepare,
-};
-
-static void fimc_md_unregister_clk_provider(struct fimc_md *fmd)
-{
- struct cam_clk_provider *cp = &fmd->clk_provider;
- unsigned int i;
-
- if (cp->of_node)
- of_clk_del_provider(cp->of_node);
-
- for (i = 0; i < cp->num_clocks; i++)
- clk_unregister(cp->clks[i]);
-}
-
-static int fimc_md_register_clk_provider(struct fimc_md *fmd)
-{
- struct cam_clk_provider *cp = &fmd->clk_provider;
- struct device *dev = &fmd->pdev->dev;
- int i, ret;
-
- for (i = 0; i < FIMC_MAX_CAMCLKS; i++) {
- struct cam_clk *camclk = &cp->camclk[i];
- struct clk_init_data init;
- const char *p_name;
-
- ret = of_property_read_string_index(dev->of_node,
- "clock-output-names", i, &init.name);
- if (ret < 0)
- break;
-
- p_name = __clk_get_name(fmd->camclk[i].clock);
-
- /* It's safe since clk_register() will duplicate the string. */
- init.parent_names = &p_name;
- init.num_parents = 1;
- init.ops = &cam_clk_ops;
- init.flags = CLK_SET_RATE_PARENT;
- camclk->hw.init = &init;
- camclk->fmd = fmd;
-
- cp->clks[i] = clk_register(NULL, &camclk->hw);
- if (IS_ERR(cp->clks[i])) {
- dev_err(dev, "failed to register clock: %s (%ld)\n",
- init.name, PTR_ERR(cp->clks[i]));
- ret = PTR_ERR(cp->clks[i]);
- goto err;
- }
- cp->num_clocks++;
- }
-
- if (cp->num_clocks == 0) {
- dev_warn(dev, "clk provider not registered\n");
- return 0;
- }
-
- cp->clk_data.clks = cp->clks;
- cp->clk_data.clk_num = cp->num_clocks;
- cp->of_node = dev->of_node;
- ret = of_clk_add_provider(dev->of_node, of_clk_src_onecell_get,
- &cp->clk_data);
- if (ret == 0)
- return 0;
-err:
- fimc_md_unregister_clk_provider(fmd);
- return ret;
-}
-
-static int subdev_notifier_bound(struct v4l2_async_notifier *notifier,
- struct v4l2_subdev *subdev,
- struct v4l2_async_subdev *asd)
-{
- struct fimc_md *fmd = notifier_to_fimc_md(notifier);
- struct fimc_sensor_info *si = NULL;
- int i;
-
- /* Find platform data for this sensor subdev */
- for (i = 0; i < ARRAY_SIZE(fmd->sensor); i++)
- if (fmd->sensor[i].asd &&
- fmd->sensor[i].asd->match.fwnode ==
- of_fwnode_handle(subdev->dev->of_node))
- si = &fmd->sensor[i];
-
- if (si == NULL)
- return -EINVAL;
-
- v4l2_set_subdev_hostdata(subdev, &si->pdata);
-
- if (si->pdata.fimc_bus_type == FIMC_BUS_TYPE_ISP_WRITEBACK)
- subdev->grp_id = GRP_ID_FIMC_IS_SENSOR;
- else
- subdev->grp_id = GRP_ID_SENSOR;
-
- si->subdev = subdev;
-
- v4l2_info(&fmd->v4l2_dev, "Registered sensor subdevice: %s (%d)\n",
- subdev->name, fmd->num_sensors);
-
- fmd->num_sensors++;
-
- return 0;
-}
-
-static int subdev_notifier_complete(struct v4l2_async_notifier *notifier)
-{
- struct fimc_md *fmd = notifier_to_fimc_md(notifier);
- int ret;
-
- mutex_lock(&fmd->media_dev.graph_mutex);
-
- ret = fimc_md_create_links(fmd);
- if (ret < 0)
- goto unlock;
-
- ret = v4l2_device_register_subdev_nodes(&fmd->v4l2_dev);
-unlock:
- mutex_unlock(&fmd->media_dev.graph_mutex);
- if (ret < 0)
- return ret;
-
- return media_device_register(&fmd->media_dev);
-}
-
-static const struct v4l2_async_notifier_operations subdev_notifier_ops = {
- .bound = subdev_notifier_bound,
- .complete = subdev_notifier_complete,
-};
-
-static int fimc_md_probe(struct platform_device *pdev)
-{
- struct device *dev = &pdev->dev;
- struct v4l2_device *v4l2_dev;
- struct pinctrl *pinctrl;
- struct fimc_md *fmd;
- int ret;
-
- fmd = devm_kzalloc(dev, sizeof(*fmd), GFP_KERNEL);
- if (!fmd)
- return -ENOMEM;
-
- spin_lock_init(&fmd->slock);
- INIT_LIST_HEAD(&fmd->pipelines);
- fmd->pdev = pdev;
-
- strscpy(fmd->media_dev.model, "Samsung S5P FIMC",
- sizeof(fmd->media_dev.model));
- fmd->media_dev.ops = &fimc_md_ops;
- fmd->media_dev.dev = dev;
-
- v4l2_dev = &fmd->v4l2_dev;
- v4l2_dev->mdev = &fmd->media_dev;
- v4l2_dev->notify = fimc_sensor_notify;
- strscpy(v4l2_dev->name, "s5p-fimc-md", sizeof(v4l2_dev->name));
-
- fmd->use_isp = fimc_md_is_isp_available(dev->of_node);
- fmd->user_subdev_api = true;
-
- media_device_init(&fmd->media_dev);
-
- ret = v4l2_device_register(dev, &fmd->v4l2_dev);
- if (ret < 0) {
- v4l2_err(v4l2_dev, "Failed to register v4l2_device: %d\n", ret);
- goto err_md;
- }
-
- ret = fimc_md_get_clocks(fmd);
- if (ret)
- goto err_v4l2dev;
-
- pinctrl = devm_pinctrl_get(dev);
- if (IS_ERR(pinctrl)) {
- ret = PTR_ERR(pinctrl);
- if (ret != EPROBE_DEFER)
- dev_err(dev, "Failed to get pinctrl: %d\n", ret);
- goto err_clk;
- }
-
- platform_set_drvdata(pdev, fmd);
-
- v4l2_async_nf_init(&fmd->subdev_notifier);
-
- ret = fimc_md_register_platform_entities(fmd, dev->of_node);
- if (ret)
- goto err_clk;
-
- ret = fimc_md_register_sensor_entities(fmd);
- if (ret)
- goto err_m_ent;
-
- ret = device_create_file(&pdev->dev, &dev_attr_subdev_conf_mode);
- if (ret)
- goto err_cleanup;
- /*
- * FIMC platform devices need to be registered before the sclk_cam
- * clocks provider, as one of these devices needs to be activated
- * to enable the clock.
- */
- ret = fimc_md_register_clk_provider(fmd);
- if (ret < 0) {
- v4l2_err(v4l2_dev, "clock provider registration failed\n");
- goto err_attr;
- }
-
- if (fmd->num_sensors > 0) {
- fmd->subdev_notifier.ops = &subdev_notifier_ops;
- fmd->num_sensors = 0;
-
- ret = v4l2_async_nf_register(&fmd->v4l2_dev,
- &fmd->subdev_notifier);
- if (ret)
- goto err_clk_p;
- }
-
- return 0;
-
-err_clk_p:
- fimc_md_unregister_clk_provider(fmd);
-err_attr:
- device_remove_file(&pdev->dev, &dev_attr_subdev_conf_mode);
-err_cleanup:
- v4l2_async_nf_cleanup(&fmd->subdev_notifier);
-err_m_ent:
- fimc_md_unregister_entities(fmd);
-err_clk:
- fimc_md_put_clocks(fmd);
-err_v4l2dev:
- v4l2_device_unregister(&fmd->v4l2_dev);
-err_md:
- media_device_cleanup(&fmd->media_dev);
- return ret;
-}
-
-static int fimc_md_remove(struct platform_device *pdev)
-{
- struct fimc_md *fmd = platform_get_drvdata(pdev);
-
- if (!fmd)
- return 0;
-
- fimc_md_unregister_clk_provider(fmd);
- v4l2_async_nf_unregister(&fmd->subdev_notifier);
- v4l2_async_nf_cleanup(&fmd->subdev_notifier);
-
- v4l2_device_unregister(&fmd->v4l2_dev);
- device_remove_file(&pdev->dev, &dev_attr_subdev_conf_mode);
- fimc_md_unregister_entities(fmd);
- fimc_md_pipelines_free(fmd);
- media_device_unregister(&fmd->media_dev);
- media_device_cleanup(&fmd->media_dev);
- fimc_md_put_clocks(fmd);
-
- return 0;
-}
-
-static const struct platform_device_id fimc_driver_ids[] __always_unused = {
- { .name = "s5p-fimc-md" },
- { },
-};
-MODULE_DEVICE_TABLE(platform, fimc_driver_ids);
-
-static const struct of_device_id fimc_md_of_match[] = {
- { .compatible = "samsung,fimc" },
- { },
-};
-MODULE_DEVICE_TABLE(of, fimc_md_of_match);
-
-static struct platform_driver fimc_md_driver = {
- .probe = fimc_md_probe,
- .remove = fimc_md_remove,
- .driver = {
- .of_match_table = of_match_ptr(fimc_md_of_match),
- .name = "s5p-fimc-md",
- }
-};
-
-static int __init fimc_md_init(void)
-{
- int ret;
-
- request_module("s5p-csis");
- ret = fimc_register_driver();
- if (ret)
- return ret;
-
- return platform_driver_register(&fimc_md_driver);
-}
-
-static void __exit fimc_md_exit(void)
-{
- platform_driver_unregister(&fimc_md_driver);
- fimc_unregister_driver();
-}
-
-module_init(fimc_md_init);
-module_exit(fimc_md_exit);
-
-MODULE_AUTHOR("Sylwester Nawrocki <s.nawrocki@samsung.com>");
-MODULE_DESCRIPTION("S5P FIMC camera host interface/video postprocessor driver");
-MODULE_LICENSE("GPL");
-MODULE_VERSION("2.0.1");
diff --git a/drivers/media/platform/exynos4-is/media-dev.h b/drivers/media/platform/exynos4-is/media-dev.h
deleted file mode 100644
index 62ad5d7e035a..000000000000
--- a/drivers/media/platform/exynos4-is/media-dev.h
+++ /dev/null
@@ -1,201 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-only */
-/*
- * Copyright (C) 2011 - 2012 Samsung Electronics Co., Ltd.
- */
-
-#ifndef FIMC_MDEVICE_H_
-#define FIMC_MDEVICE_H_
-
-#include <linux/clk.h>
-#include <linux/clk-provider.h>
-#include <linux/platform_device.h>
-#include <linux/mutex.h>
-#include <linux/of.h>
-#include <linux/pinctrl/consumer.h>
-#include <media/media-device.h>
-#include <media/media-entity.h>
-#include <media/v4l2-device.h>
-#include <media/v4l2-subdev.h>
-#include <media/drv-intf/exynos-fimc.h>
-
-#include "fimc-core.h"
-#include "fimc-lite.h"
-#include "mipi-csis.h"
-
-#define FIMC_OF_NODE_NAME "fimc"
-#define FIMC_LITE_OF_NODE_NAME "fimc-lite"
-#define FIMC_IS_OF_NODE_NAME "fimc-is"
-#define CSIS_OF_NODE_NAME "csis"
-
-#define FIMC_MAX_SENSORS 4
-#define FIMC_MAX_CAMCLKS 2
-#define DEFAULT_SENSOR_CLK_FREQ 24000000U
-
-/* LCD/ISP Writeback clocks (PIXELASYNCMx) */
-enum {
- CLK_IDX_WB_A,
- CLK_IDX_WB_B,
- FIMC_MAX_WBCLKS
-};
-
-enum fimc_subdev_index {
- IDX_SENSOR,
- IDX_CSIS,
- IDX_FLITE,
- IDX_IS_ISP,
- IDX_FIMC,
- IDX_MAX,
-};
-
-/*
- * This structure represents a chain of media entities, including a data
- * source entity (e.g. an image sensor subdevice), a data capture entity
- * - a video capture device node and any remaining entities.
- */
-struct fimc_pipeline {
- struct exynos_media_pipeline ep;
- struct list_head list;
- struct media_entity *vdev_entity;
- struct v4l2_subdev *subdevs[IDX_MAX];
-};
-
-#define to_fimc_pipeline(_ep) container_of(_ep, struct fimc_pipeline, ep)
-
-struct fimc_csis_info {
- struct v4l2_subdev *sd;
- int id;
-};
-
-struct fimc_camclk_info {
- struct clk *clock;
- int use_count;
- unsigned long frequency;
-};
-
-/**
- * struct fimc_sensor_info - image data source subdev information
- * @pdata: sensor's attributes passed as media device's platform data
- * @asd: asynchronous subdev registration data structure
- * @subdev: image sensor v4l2 subdev
- * @host: fimc device the sensor is currently linked to
- *
- * This data structure applies to image sensor and the writeback subdevs.
- */
-struct fimc_sensor_info {
- struct fimc_source_info pdata;
- struct v4l2_async_subdev *asd;
- struct v4l2_subdev *subdev;
- struct fimc_dev *host;
-};
-
-struct cam_clk {
- struct clk_hw hw;
- struct fimc_md *fmd;
-};
-#define to_cam_clk(_hw) container_of(_hw, struct cam_clk, hw)
-
-/**
- * struct fimc_md - fimc media device information
- * @csis: MIPI CSIS subdevs data
- * @sensor: array of registered sensor subdevs
- * @num_sensors: actual number of registered sensors
- * @camclk: external sensor clock information
- * @wbclk: external writeback clock information
- * @fimc_lite: array of registered fimc-lite devices
- * @fimc: array of registered fimc devices
- * @fimc_is: fimc-is data structure
- * @use_isp: set to true when FIMC-IS subsystem is used
- * @pmf: handle to the CAMCLK clock control FIMC helper device
- * @media_dev: top level media device
- * @v4l2_dev: top level v4l2_device holding up the subdevs
- * @pdev: platform device this media device is hooked up into
- * @clk_provider: CAMCLK clock provider structure
- * @subdev_notifier: notifier for the subdevs
- * @user_subdev_api: true if subdevs are not configured by the host driver
- * @slock: spinlock protecting @sensor array
- * @pipelines: list of pipelines
- * @link_setup_graph: graph iterator
- */
-struct fimc_md {
- struct fimc_csis_info csis[CSIS_MAX_ENTITIES];
- struct fimc_sensor_info sensor[FIMC_MAX_SENSORS];
- int num_sensors;
- struct fimc_camclk_info camclk[FIMC_MAX_CAMCLKS];
- struct clk *wbclk[FIMC_MAX_WBCLKS];
- struct fimc_lite *fimc_lite[FIMC_LITE_MAX_DEVS];
- struct fimc_dev *fimc[FIMC_MAX_DEVS];
- struct fimc_is *fimc_is;
- bool use_isp;
- struct device *pmf;
- struct media_device media_dev;
- struct v4l2_device v4l2_dev;
- struct platform_device *pdev;
-
- struct cam_clk_provider {
- struct clk *clks[FIMC_MAX_CAMCLKS];
- struct clk_onecell_data clk_data;
- struct device_node *of_node;
- struct cam_clk camclk[FIMC_MAX_CAMCLKS];
- int num_clocks;
- } clk_provider;
-
- struct v4l2_async_notifier subdev_notifier;
-
- bool user_subdev_api;
- spinlock_t slock;
- struct list_head pipelines;
- struct media_graph link_setup_graph;
-};
-
-static inline
-struct fimc_sensor_info *source_to_sensor_info(struct fimc_source_info *si)
-{
- return container_of(si, struct fimc_sensor_info, pdata);
-}
-
-static inline struct fimc_md *entity_to_fimc_mdev(struct media_entity *me)
-{
- return me->graph_obj.mdev == NULL ? NULL :
- container_of(me->graph_obj.mdev, struct fimc_md, media_dev);
-}
-
-static inline struct fimc_md *notifier_to_fimc_md(struct v4l2_async_notifier *n)
-{
- return container_of(n, struct fimc_md, subdev_notifier);
-}
-
-static inline void fimc_md_graph_lock(struct exynos_video_entity *ve)
-{
- mutex_lock(&ve->vdev.entity.graph_obj.mdev->graph_mutex);
-}
-
-static inline void fimc_md_graph_unlock(struct exynos_video_entity *ve)
-{
- mutex_unlock(&ve->vdev.entity.graph_obj.mdev->graph_mutex);
-}
-
-int fimc_md_set_camclk(struct v4l2_subdev *sd, bool on);
-
-#ifdef CONFIG_OF
-static inline bool fimc_md_is_isp_available(struct device_node *node)
-{
- node = of_get_child_by_name(node, FIMC_IS_OF_NODE_NAME);
- return node ? of_device_is_available(node) : false;
-}
-#else
-#define fimc_md_is_isp_available(node) (false)
-#endif /* CONFIG_OF */
-
-static inline struct v4l2_subdev *__fimc_md_get_subdev(
- struct exynos_media_pipeline *ep,
- unsigned int index)
-{
- struct fimc_pipeline *p = to_fimc_pipeline(ep);
-
- if (!p || index >= IDX_MAX)
- return NULL;
- else
- return p->subdevs[index];
-}
-
-#endif
diff --git a/drivers/media/platform/exynos4-is/mipi-csis.c b/drivers/media/platform/exynos4-is/mipi-csis.c
deleted file mode 100644
index 27a214936cb0..000000000000
--- a/drivers/media/platform/exynos4-is/mipi-csis.c
+++ /dev/null
@@ -1,1037 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-/*
- * Samsung S5P/EXYNOS SoC series MIPI-CSI receiver driver
- *
- * Copyright (C) 2011 - 2013 Samsung Electronics Co., Ltd.
- * Author: Sylwester Nawrocki <s.nawrocki@samsung.com>
- */
-
-#include <linux/clk.h>
-#include <linux/delay.h>
-#include <linux/device.h>
-#include <linux/errno.h>
-#include <linux/interrupt.h>
-#include <linux/io.h>
-#include <linux/irq.h>
-#include <linux/kernel.h>
-#include <linux/memory.h>
-#include <linux/module.h>
-#include <linux/of.h>
-#include <linux/of_graph.h>
-#include <linux/phy/phy.h>
-#include <linux/platform_device.h>
-#include <linux/pm_runtime.h>
-#include <linux/regulator/consumer.h>
-#include <linux/sizes.h>
-#include <linux/slab.h>
-#include <linux/spinlock.h>
-#include <linux/videodev2.h>
-#include <media/drv-intf/exynos-fimc.h>
-#include <media/v4l2-fwnode.h>
-#include <media/v4l2-subdev.h>
-
-#include "mipi-csis.h"
-
-static int debug;
-module_param(debug, int, 0644);
-MODULE_PARM_DESC(debug, "Debug level (0-2)");
-
-/* Register map definition */
-
-/* CSIS global control */
-#define S5PCSIS_CTRL 0x00
-#define S5PCSIS_CTRL_DPDN_DEFAULT (0 << 31)
-#define S5PCSIS_CTRL_DPDN_SWAP (1UL << 31)
-#define S5PCSIS_CTRL_ALIGN_32BIT (1 << 20)
-#define S5PCSIS_CTRL_UPDATE_SHADOW (1 << 16)
-#define S5PCSIS_CTRL_WCLK_EXTCLK (1 << 8)
-#define S5PCSIS_CTRL_RESET (1 << 4)
-#define S5PCSIS_CTRL_ENABLE (1 << 0)
-
-/* D-PHY control */
-#define S5PCSIS_DPHYCTRL 0x04
-#define S5PCSIS_DPHYCTRL_HSS_MASK (0x1f << 27)
-#define S5PCSIS_DPHYCTRL_ENABLE (0x1f << 0)
-
-#define S5PCSIS_CONFIG 0x08
-#define S5PCSIS_CFG_FMT_YCBCR422_8BIT (0x1e << 2)
-#define S5PCSIS_CFG_FMT_RAW8 (0x2a << 2)
-#define S5PCSIS_CFG_FMT_RAW10 (0x2b << 2)
-#define S5PCSIS_CFG_FMT_RAW12 (0x2c << 2)
-/* User defined formats, x = 1...4 */
-#define S5PCSIS_CFG_FMT_USER(x) ((0x30 + x - 1) << 2)
-#define S5PCSIS_CFG_FMT_MASK (0x3f << 2)
-#define S5PCSIS_CFG_NR_LANE_MASK 3
-
-/* Interrupt mask */
-#define S5PCSIS_INTMSK 0x10
-#define S5PCSIS_INTMSK_EVEN_BEFORE (1UL << 31)
-#define S5PCSIS_INTMSK_EVEN_AFTER (1 << 30)
-#define S5PCSIS_INTMSK_ODD_BEFORE (1 << 29)
-#define S5PCSIS_INTMSK_ODD_AFTER (1 << 28)
-#define S5PCSIS_INTMSK_FRAME_START (1 << 27)
-#define S5PCSIS_INTMSK_FRAME_END (1 << 26)
-#define S5PCSIS_INTMSK_ERR_SOT_HS (1 << 12)
-#define S5PCSIS_INTMSK_ERR_LOST_FS (1 << 5)
-#define S5PCSIS_INTMSK_ERR_LOST_FE (1 << 4)
-#define S5PCSIS_INTMSK_ERR_OVER (1 << 3)
-#define S5PCSIS_INTMSK_ERR_ECC (1 << 2)
-#define S5PCSIS_INTMSK_ERR_CRC (1 << 1)
-#define S5PCSIS_INTMSK_ERR_UNKNOWN (1 << 0)
-#define S5PCSIS_INTMSK_EXYNOS4_EN_ALL 0xf000103f
-#define S5PCSIS_INTMSK_EXYNOS5_EN_ALL 0xfc00103f
-
-/* Interrupt source */
-#define S5PCSIS_INTSRC 0x14
-#define S5PCSIS_INTSRC_EVEN_BEFORE (1UL << 31)
-#define S5PCSIS_INTSRC_EVEN_AFTER (1 << 30)
-#define S5PCSIS_INTSRC_EVEN (0x3 << 30)
-#define S5PCSIS_INTSRC_ODD_BEFORE (1 << 29)
-#define S5PCSIS_INTSRC_ODD_AFTER (1 << 28)
-#define S5PCSIS_INTSRC_ODD (0x3 << 28)
-#define S5PCSIS_INTSRC_NON_IMAGE_DATA (0xf << 28)
-#define S5PCSIS_INTSRC_FRAME_START (1 << 27)
-#define S5PCSIS_INTSRC_FRAME_END (1 << 26)
-#define S5PCSIS_INTSRC_ERR_SOT_HS (0xf << 12)
-#define S5PCSIS_INTSRC_ERR_LOST_FS (1 << 5)
-#define S5PCSIS_INTSRC_ERR_LOST_FE (1 << 4)
-#define S5PCSIS_INTSRC_ERR_OVER (1 << 3)
-#define S5PCSIS_INTSRC_ERR_ECC (1 << 2)
-#define S5PCSIS_INTSRC_ERR_CRC (1 << 1)
-#define S5PCSIS_INTSRC_ERR_UNKNOWN (1 << 0)
-#define S5PCSIS_INTSRC_ERRORS 0xf03f
-
-/* Pixel resolution */
-#define S5PCSIS_RESOL 0x2c
-#define CSIS_MAX_PIX_WIDTH 0xffff
-#define CSIS_MAX_PIX_HEIGHT 0xffff
-
-/* Non-image packet data buffers */
-#define S5PCSIS_PKTDATA_ODD 0x2000
-#define S5PCSIS_PKTDATA_EVEN 0x3000
-#define S5PCSIS_PKTDATA_SIZE SZ_4K
-
-enum {
- CSIS_CLK_MUX,
- CSIS_CLK_GATE,
-};
-
-static char *csi_clock_name[] = {
- [CSIS_CLK_MUX] = "sclk_csis",
- [CSIS_CLK_GATE] = "csis",
-};
-#define NUM_CSIS_CLOCKS ARRAY_SIZE(csi_clock_name)
-#define DEFAULT_SCLK_CSIS_FREQ 166000000UL
-
-static const char * const csis_supply_name[] = {
- "vddcore", /* CSIS Core (1.0V, 1.1V or 1.2V) suppply */
- "vddio", /* CSIS I/O and PLL (1.8V) supply */
-};
-#define CSIS_NUM_SUPPLIES ARRAY_SIZE(csis_supply_name)
-
-enum {
- ST_POWERED = 1,
- ST_STREAMING = 2,
- ST_SUSPENDED = 4,
-};
-
-struct s5pcsis_event {
- u32 mask;
- const char * const name;
- unsigned int counter;
-};
-
-static const struct s5pcsis_event s5pcsis_events[] = {
- /* Errors */
- { S5PCSIS_INTSRC_ERR_SOT_HS, "SOT Error" },
- { S5PCSIS_INTSRC_ERR_LOST_FS, "Lost Frame Start Error" },
- { S5PCSIS_INTSRC_ERR_LOST_FE, "Lost Frame End Error" },
- { S5PCSIS_INTSRC_ERR_OVER, "FIFO Overflow Error" },
- { S5PCSIS_INTSRC_ERR_ECC, "ECC Error" },
- { S5PCSIS_INTSRC_ERR_CRC, "CRC Error" },
- { S5PCSIS_INTSRC_ERR_UNKNOWN, "Unknown Error" },
- /* Non-image data receive events */
- { S5PCSIS_INTSRC_EVEN_BEFORE, "Non-image data before even frame" },
- { S5PCSIS_INTSRC_EVEN_AFTER, "Non-image data after even frame" },
- { S5PCSIS_INTSRC_ODD_BEFORE, "Non-image data before odd frame" },
- { S5PCSIS_INTSRC_ODD_AFTER, "Non-image data after odd frame" },
- /* Frame start/end */
- { S5PCSIS_INTSRC_FRAME_START, "Frame Start" },
- { S5PCSIS_INTSRC_FRAME_END, "Frame End" },
-};
-#define S5PCSIS_NUM_EVENTS ARRAY_SIZE(s5pcsis_events)
-
-struct csis_pktbuf {
- u32 *data;
- unsigned int len;
-};
-
-struct csis_drvdata {
- /* Mask of all used interrupts in S5PCSIS_INTMSK register */
- u32 interrupt_mask;
-};
-
-/**
- * struct csis_state - the driver's internal state data structure
- * @lock: mutex serializing the subdev and power management operations,
- * protecting @format and @flags members
- * @pads: CSIS pads array
- * @sd: v4l2_subdev associated with CSIS device instance
- * @index: the hardware instance index
- * @pdev: CSIS platform device
- * @phy: pointer to the CSIS generic PHY
- * @regs: mmapped I/O registers memory
- * @supplies: CSIS regulator supplies
- * @clock: CSIS clocks
- * @irq: requested s5p-mipi-csis irq number
- * @interrupt_mask: interrupt mask of the all used interrupts
- * @flags: the state variable for power and streaming control
- * @clk_frequency: device bus clock frequency
- * @hs_settle: HS-RX settle time
- * @num_lanes: number of MIPI-CSI data lanes used
- * @max_num_lanes: maximum number of MIPI-CSI data lanes supported
- * @wclk_ext: CSI wrapper clock: 0 - bus clock, 1 - external SCLK_CAM
- * @csis_fmt: current CSIS pixel format
- * @format: common media bus format for the source and sink pad
- * @slock: spinlock protecting structure members below
- * @pkt_buf: the frame embedded (non-image) data buffer
- * @events: MIPI-CSIS event (error) counters
- */
-struct csis_state {
- struct mutex lock;
- struct media_pad pads[CSIS_PADS_NUM];
- struct v4l2_subdev sd;
- u8 index;
- struct platform_device *pdev;
- struct phy *phy;
- void __iomem *regs;
- struct regulator_bulk_data supplies[CSIS_NUM_SUPPLIES];
- struct clk *clock[NUM_CSIS_CLOCKS];
- int irq;
- u32 interrupt_mask;
- u32 flags;
-
- u32 clk_frequency;
- u32 hs_settle;
- u32 num_lanes;
- u32 max_num_lanes;
- u8 wclk_ext;
-
- const struct csis_pix_format *csis_fmt;
- struct v4l2_mbus_framefmt format;
-
- spinlock_t slock;
- struct csis_pktbuf pkt_buf;
- struct s5pcsis_event events[S5PCSIS_NUM_EVENTS];
-};
-
-/**
- * struct csis_pix_format - CSIS pixel format description
- * @pix_width_alignment: horizontal pixel alignment, width will be
- * multiple of 2^pix_width_alignment
- * @code: corresponding media bus code
- * @fmt_reg: S5PCSIS_CONFIG register value
- * @data_alignment: MIPI-CSI data alignment in bits
- */
-struct csis_pix_format {
- unsigned int pix_width_alignment;
- u32 code;
- u32 fmt_reg;
- u8 data_alignment;
-};
-
-static const struct csis_pix_format s5pcsis_formats[] = {
- {
- .code = MEDIA_BUS_FMT_VYUY8_2X8,
- .fmt_reg = S5PCSIS_CFG_FMT_YCBCR422_8BIT,
- .data_alignment = 32,
- }, {
- .code = MEDIA_BUS_FMT_JPEG_1X8,
- .fmt_reg = S5PCSIS_CFG_FMT_USER(1),
- .data_alignment = 32,
- }, {
- .code = MEDIA_BUS_FMT_S5C_UYVY_JPEG_1X8,
- .fmt_reg = S5PCSIS_CFG_FMT_USER(1),
- .data_alignment = 32,
- }, {
- .code = MEDIA_BUS_FMT_SGRBG8_1X8,
- .fmt_reg = S5PCSIS_CFG_FMT_RAW8,
- .data_alignment = 24,
- }, {
- .code = MEDIA_BUS_FMT_SGRBG10_1X10,
- .fmt_reg = S5PCSIS_CFG_FMT_RAW10,
- .data_alignment = 24,
- }, {
- .code = MEDIA_BUS_FMT_SGRBG12_1X12,
- .fmt_reg = S5PCSIS_CFG_FMT_RAW12,
- .data_alignment = 24,
- }
-};
-
-#define s5pcsis_write(__csis, __r, __v) writel(__v, __csis->regs + __r)
-#define s5pcsis_read(__csis, __r) readl(__csis->regs + __r)
-
-static struct csis_state *sd_to_csis_state(struct v4l2_subdev *sdev)
-{
- return container_of(sdev, struct csis_state, sd);
-}
-
-static const struct csis_pix_format *find_csis_format(
- struct v4l2_mbus_framefmt *mf)
-{
- int i;
-
- for (i = 0; i < ARRAY_SIZE(s5pcsis_formats); i++)
- if (mf->code == s5pcsis_formats[i].code)
- return &s5pcsis_formats[i];
- return NULL;
-}
-
-static void s5pcsis_enable_interrupts(struct csis_state *state, bool on)
-{
- u32 val = s5pcsis_read(state, S5PCSIS_INTMSK);
- if (on)
- val |= state->interrupt_mask;
- else
- val &= ~state->interrupt_mask;
- s5pcsis_write(state, S5PCSIS_INTMSK, val);
-}
-
-static void s5pcsis_reset(struct csis_state *state)
-{
- u32 val = s5pcsis_read(state, S5PCSIS_CTRL);
-
- s5pcsis_write(state, S5PCSIS_CTRL, val | S5PCSIS_CTRL_RESET);
- udelay(10);
-}
-
-static void s5pcsis_system_enable(struct csis_state *state, int on)
-{
- u32 val, mask;
-
- val = s5pcsis_read(state, S5PCSIS_CTRL);
- if (on)
- val |= S5PCSIS_CTRL_ENABLE;
- else
- val &= ~S5PCSIS_CTRL_ENABLE;
- s5pcsis_write(state, S5PCSIS_CTRL, val);
-
- val = s5pcsis_read(state, S5PCSIS_DPHYCTRL);
- val &= ~S5PCSIS_DPHYCTRL_ENABLE;
- if (on) {
- mask = (1 << (state->num_lanes + 1)) - 1;
- val |= (mask & S5PCSIS_DPHYCTRL_ENABLE);
- }
- s5pcsis_write(state, S5PCSIS_DPHYCTRL, val);
-}
-
-/* Called with the state.lock mutex held */
-static void __s5pcsis_set_format(struct csis_state *state)
-{
- struct v4l2_mbus_framefmt *mf = &state->format;
- u32 val;
-
- v4l2_dbg(1, debug, &state->sd, "fmt: %#x, %d x %d\n",
- mf->code, mf->width, mf->height);
-
- /* Color format */
- val = s5pcsis_read(state, S5PCSIS_CONFIG);
- val = (val & ~S5PCSIS_CFG_FMT_MASK) | state->csis_fmt->fmt_reg;
- s5pcsis_write(state, S5PCSIS_CONFIG, val);
-
- /* Pixel resolution */
- val = (mf->width << 16) | mf->height;
- s5pcsis_write(state, S5PCSIS_RESOL, val);
-}
-
-static void s5pcsis_set_hsync_settle(struct csis_state *state, int settle)
-{
- u32 val = s5pcsis_read(state, S5PCSIS_DPHYCTRL);
-
- val = (val & ~S5PCSIS_DPHYCTRL_HSS_MASK) | (settle << 27);
- s5pcsis_write(state, S5PCSIS_DPHYCTRL, val);
-}
-
-static void s5pcsis_set_params(struct csis_state *state)
-{
- u32 val;
-
- val = s5pcsis_read(state, S5PCSIS_CONFIG);
- val = (val & ~S5PCSIS_CFG_NR_LANE_MASK) | (state->num_lanes - 1);
- s5pcsis_write(state, S5PCSIS_CONFIG, val);
-
- __s5pcsis_set_format(state);
- s5pcsis_set_hsync_settle(state, state->hs_settle);
-
- val = s5pcsis_read(state, S5PCSIS_CTRL);
- if (state->csis_fmt->data_alignment == 32)
- val |= S5PCSIS_CTRL_ALIGN_32BIT;
- else /* 24-bits */
- val &= ~S5PCSIS_CTRL_ALIGN_32BIT;
-
- val &= ~S5PCSIS_CTRL_WCLK_EXTCLK;
- if (state->wclk_ext)
- val |= S5PCSIS_CTRL_WCLK_EXTCLK;
- s5pcsis_write(state, S5PCSIS_CTRL, val);
-
- /* Update the shadow register. */
- val = s5pcsis_read(state, S5PCSIS_CTRL);
- s5pcsis_write(state, S5PCSIS_CTRL, val | S5PCSIS_CTRL_UPDATE_SHADOW);
-}
-
-static void s5pcsis_clk_put(struct csis_state *state)
-{
- int i;
-
- for (i = 0; i < NUM_CSIS_CLOCKS; i++) {
- if (IS_ERR(state->clock[i]))
- continue;
- clk_unprepare(state->clock[i]);
- clk_put(state->clock[i]);
- state->clock[i] = ERR_PTR(-EINVAL);
- }
-}
-
-static int s5pcsis_clk_get(struct csis_state *state)
-{
- struct device *dev = &state->pdev->dev;
- int i, ret;
-
- for (i = 0; i < NUM_CSIS_CLOCKS; i++)
- state->clock[i] = ERR_PTR(-EINVAL);
-
- for (i = 0; i < NUM_CSIS_CLOCKS; i++) {
- state->clock[i] = clk_get(dev, csi_clock_name[i]);
- if (IS_ERR(state->clock[i])) {
- ret = PTR_ERR(state->clock[i]);
- goto err;
- }
- ret = clk_prepare(state->clock[i]);
- if (ret < 0) {
- clk_put(state->clock[i]);
- state->clock[i] = ERR_PTR(-EINVAL);
- goto err;
- }
- }
- return 0;
-err:
- s5pcsis_clk_put(state);
- dev_err(dev, "failed to get clock: %s\n", csi_clock_name[i]);
- return ret;
-}
-
-static void dump_regs(struct csis_state *state, const char *label)
-{
- struct {
- u32 offset;
- const char * const name;
- } registers[] = {
- { 0x00, "CTRL" },
- { 0x04, "DPHYCTRL" },
- { 0x08, "CONFIG" },
- { 0x0c, "DPHYSTS" },
- { 0x10, "INTMSK" },
- { 0x2c, "RESOL" },
- { 0x38, "SDW_CONFIG" },
- };
- u32 i;
-
- v4l2_info(&state->sd, "--- %s ---\n", label);
-
- for (i = 0; i < ARRAY_SIZE(registers); i++) {
- u32 cfg = s5pcsis_read(state, registers[i].offset);
- v4l2_info(&state->sd, "%10s: 0x%08x\n", registers[i].name, cfg);
- }
-}
-
-static void s5pcsis_start_stream(struct csis_state *state)
-{
- s5pcsis_reset(state);
- s5pcsis_set_params(state);
- s5pcsis_system_enable(state, true);
- s5pcsis_enable_interrupts(state, true);
-}
-
-static void s5pcsis_stop_stream(struct csis_state *state)
-{
- s5pcsis_enable_interrupts(state, false);
- s5pcsis_system_enable(state, false);
-}
-
-static void s5pcsis_clear_counters(struct csis_state *state)
-{
- unsigned long flags;
- int i;
-
- spin_lock_irqsave(&state->slock, flags);
- for (i = 0; i < S5PCSIS_NUM_EVENTS; i++)
- state->events[i].counter = 0;
- spin_unlock_irqrestore(&state->slock, flags);
-}
-
-static void s5pcsis_log_counters(struct csis_state *state, bool non_errors)
-{
- int i = non_errors ? S5PCSIS_NUM_EVENTS : S5PCSIS_NUM_EVENTS - 4;
- unsigned long flags;
-
- spin_lock_irqsave(&state->slock, flags);
-
- for (i--; i >= 0; i--) {
- if (state->events[i].counter > 0 || debug)
- v4l2_info(&state->sd, "%s events: %d\n",
- state->events[i].name,
- state->events[i].counter);
- }
- spin_unlock_irqrestore(&state->slock, flags);
-}
-
-/*
- * V4L2 subdev operations
- */
-static int s5pcsis_s_power(struct v4l2_subdev *sd, int on)
-{
- struct csis_state *state = sd_to_csis_state(sd);
- struct device *dev = &state->pdev->dev;
-
- if (on)
- return pm_runtime_resume_and_get(dev);
-
- return pm_runtime_put_sync(dev);
-}
-
-static int s5pcsis_s_stream(struct v4l2_subdev *sd, int enable)
-{
- struct csis_state *state = sd_to_csis_state(sd);
- int ret = 0;
-
- v4l2_dbg(1, debug, sd, "%s: %d, state: 0x%x\n",
- __func__, enable, state->flags);
-
- if (enable) {
- s5pcsis_clear_counters(state);
- ret = pm_runtime_resume_and_get(&state->pdev->dev);
- if (ret < 0)
- return ret;
- }
-
- mutex_lock(&state->lock);
- if (enable) {
- if (state->flags & ST_SUSPENDED) {
- ret = -EBUSY;
- goto unlock;
- }
- s5pcsis_start_stream(state);
- state->flags |= ST_STREAMING;
- } else {
- s5pcsis_stop_stream(state);
- state->flags &= ~ST_STREAMING;
- if (debug > 0)
- s5pcsis_log_counters(state, true);
- }
-unlock:
- mutex_unlock(&state->lock);
- if (!enable)
- pm_runtime_put(&state->pdev->dev);
-
- return ret;
-}
-
-static int s5pcsis_enum_mbus_code(struct v4l2_subdev *sd,
- struct v4l2_subdev_state *sd_state,
- struct v4l2_subdev_mbus_code_enum *code)
-{
- if (code->index >= ARRAY_SIZE(s5pcsis_formats))
- return -EINVAL;
-
- code->code = s5pcsis_formats[code->index].code;
- return 0;
-}
-
-static struct csis_pix_format const *s5pcsis_try_format(
- struct v4l2_mbus_framefmt *mf)
-{
- struct csis_pix_format const *csis_fmt;
-
- csis_fmt = find_csis_format(mf);
- if (csis_fmt == NULL)
- csis_fmt = &s5pcsis_formats[0];
-
- mf->code = csis_fmt->code;
- v4l_bound_align_image(&mf->width, 1, CSIS_MAX_PIX_WIDTH,
- csis_fmt->pix_width_alignment,
- &mf->height, 1, CSIS_MAX_PIX_HEIGHT, 1,
- 0);
- return csis_fmt;
-}
-
-static struct v4l2_mbus_framefmt *__s5pcsis_get_format(
- struct csis_state *state, struct v4l2_subdev_state *sd_state,
- enum v4l2_subdev_format_whence which)
-{
- if (which == V4L2_SUBDEV_FORMAT_TRY)
- return sd_state ? v4l2_subdev_get_try_format(&state->sd,
- sd_state, 0) : NULL;
-
- return &state->format;
-}
-
-static int s5pcsis_set_fmt(struct v4l2_subdev *sd,
- struct v4l2_subdev_state *sd_state,
- struct v4l2_subdev_format *fmt)
-{
- struct csis_state *state = sd_to_csis_state(sd);
- struct csis_pix_format const *csis_fmt;
- struct v4l2_mbus_framefmt *mf;
-
- mf = __s5pcsis_get_format(state, sd_state, fmt->which);
-
- if (fmt->pad == CSIS_PAD_SOURCE) {
- if (mf) {
- mutex_lock(&state->lock);
- fmt->format = *mf;
- mutex_unlock(&state->lock);
- }
- return 0;
- }
- csis_fmt = s5pcsis_try_format(&fmt->format);
- if (mf) {
- mutex_lock(&state->lock);
- *mf = fmt->format;
- if (fmt->which == V4L2_SUBDEV_FORMAT_ACTIVE)
- state->csis_fmt = csis_fmt;
- mutex_unlock(&state->lock);
- }
- return 0;
-}
-
-static int s5pcsis_get_fmt(struct v4l2_subdev *sd,
- struct v4l2_subdev_state *sd_state,
- struct v4l2_subdev_format *fmt)
-{
- struct csis_state *state = sd_to_csis_state(sd);
- struct v4l2_mbus_framefmt *mf;
-
- mf = __s5pcsis_get_format(state, sd_state, fmt->which);
- if (!mf)
- return -EINVAL;
-
- mutex_lock(&state->lock);
- fmt->format = *mf;
- mutex_unlock(&state->lock);
- return 0;
-}
-
-static int s5pcsis_s_rx_buffer(struct v4l2_subdev *sd, void *buf,
- unsigned int *size)
-{
- struct csis_state *state = sd_to_csis_state(sd);
- unsigned long flags;
-
- *size = min_t(unsigned int, *size, S5PCSIS_PKTDATA_SIZE);
-
- spin_lock_irqsave(&state->slock, flags);
- state->pkt_buf.data = buf;
- state->pkt_buf.len = *size;
- spin_unlock_irqrestore(&state->slock, flags);
-
- return 0;
-}
-
-static int s5pcsis_log_status(struct v4l2_subdev *sd)
-{
- struct csis_state *state = sd_to_csis_state(sd);
-
- mutex_lock(&state->lock);
- s5pcsis_log_counters(state, true);
- if (debug && (state->flags & ST_POWERED))
- dump_regs(state, __func__);
- mutex_unlock(&state->lock);
- return 0;
-}
-
-static const struct v4l2_subdev_core_ops s5pcsis_core_ops = {
- .s_power = s5pcsis_s_power,
- .log_status = s5pcsis_log_status,
-};
-
-static const struct v4l2_subdev_pad_ops s5pcsis_pad_ops = {
- .enum_mbus_code = s5pcsis_enum_mbus_code,
- .get_fmt = s5pcsis_get_fmt,
- .set_fmt = s5pcsis_set_fmt,
-};
-
-static const struct v4l2_subdev_video_ops s5pcsis_video_ops = {
- .s_rx_buffer = s5pcsis_s_rx_buffer,
- .s_stream = s5pcsis_s_stream,
-};
-
-static const struct v4l2_subdev_ops s5pcsis_subdev_ops = {
- .core = &s5pcsis_core_ops,
- .pad = &s5pcsis_pad_ops,
- .video = &s5pcsis_video_ops,
-};
-
-static irqreturn_t s5pcsis_irq_handler(int irq, void *dev_id)
-{
- struct csis_state *state = dev_id;
- struct csis_pktbuf *pktbuf = &state->pkt_buf;
- unsigned long flags;
- u32 status;
-
- status = s5pcsis_read(state, S5PCSIS_INTSRC);
- spin_lock_irqsave(&state->slock, flags);
-
- if ((status & S5PCSIS_INTSRC_NON_IMAGE_DATA) && pktbuf->data) {
- u32 offset;
-
- if (status & S5PCSIS_INTSRC_EVEN)
- offset = S5PCSIS_PKTDATA_EVEN;
- else
- offset = S5PCSIS_PKTDATA_ODD;
-
- memcpy(pktbuf->data, (u8 __force *)state->regs + offset,
- pktbuf->len);
- pktbuf->data = NULL;
- rmb();
- }
-
- /* Update the event/error counters */
- if ((status & S5PCSIS_INTSRC_ERRORS) || debug) {
- int i;
- for (i = 0; i < S5PCSIS_NUM_EVENTS; i++) {
- if (!(status & state->events[i].mask))
- continue;
- state->events[i].counter++;
- v4l2_dbg(2, debug, &state->sd, "%s: %d\n",
- state->events[i].name,
- state->events[i].counter);
- }
- v4l2_dbg(2, debug, &state->sd, "status: %08x\n", status);
- }
- spin_unlock_irqrestore(&state->slock, flags);
-
- s5pcsis_write(state, S5PCSIS_INTSRC, status);
- return IRQ_HANDLED;
-}
-
-static int s5pcsis_parse_dt(struct platform_device *pdev,
- struct csis_state *state)
-{
- struct device_node *node = pdev->dev.of_node;
- struct v4l2_fwnode_endpoint endpoint = { .bus_type = 0 };
- int ret;
-
- if (of_property_read_u32(node, "clock-frequency",
- &state->clk_frequency))
- state->clk_frequency = DEFAULT_SCLK_CSIS_FREQ;
- if (of_property_read_u32(node, "bus-width",
- &state->max_num_lanes))
- return -EINVAL;
-
- node = of_graph_get_next_endpoint(node, NULL);
- if (!node) {
- dev_err(&pdev->dev, "No port node at %pOF\n",
- pdev->dev.of_node);
- return -EINVAL;
- }
- /* Get port node and validate MIPI-CSI channel id. */
- ret = v4l2_fwnode_endpoint_parse(of_fwnode_handle(node), &endpoint);
- if (ret)
- goto err;
-
- state->index = endpoint.base.port - FIMC_INPUT_MIPI_CSI2_0;
- if (state->index >= CSIS_MAX_ENTITIES) {
- ret = -ENXIO;
- goto err;
- }
-
- /* Get MIPI CSI-2 bus configuration from the endpoint node. */
- of_property_read_u32(node, "samsung,csis-hs-settle",
- &state->hs_settle);
- state->wclk_ext = of_property_read_bool(node,
- "samsung,csis-wclk");
-
- state->num_lanes = endpoint.bus.mipi_csi2.num_data_lanes;
-
-err:
- of_node_put(node);
- return ret;
-}
-
-static int s5pcsis_pm_resume(struct device *dev, bool runtime);
-static const struct of_device_id s5pcsis_of_match[];
-
-static int s5pcsis_probe(struct platform_device *pdev)
-{
- const struct of_device_id *of_id;
- const struct csis_drvdata *drv_data;
- struct device *dev = &pdev->dev;
- struct csis_state *state;
- int ret = -ENOMEM;
- int i;
-
- state = devm_kzalloc(dev, sizeof(*state), GFP_KERNEL);
- if (!state)
- return -ENOMEM;
-
- mutex_init(&state->lock);
- spin_lock_init(&state->slock);
- state->pdev = pdev;
-
- of_id = of_match_node(s5pcsis_of_match, dev->of_node);
- if (WARN_ON(of_id == NULL))
- return -EINVAL;
-
- drv_data = of_id->data;
- state->interrupt_mask = drv_data->interrupt_mask;
-
- ret = s5pcsis_parse_dt(pdev, state);
- if (ret < 0)
- return ret;
-
- if (state->num_lanes == 0 || state->num_lanes > state->max_num_lanes) {
- dev_err(dev, "Unsupported number of data lanes: %d (max. %d)\n",
- state->num_lanes, state->max_num_lanes);
- return -EINVAL;
- }
-
- state->phy = devm_phy_get(dev, "csis");
- if (IS_ERR(state->phy))
- return PTR_ERR(state->phy);
-
- state->regs = devm_platform_ioremap_resource(pdev, 0);
- if (IS_ERR(state->regs))
- return PTR_ERR(state->regs);
-
- state->irq = platform_get_irq(pdev, 0);
- if (state->irq < 0)
- return state->irq;
-
- for (i = 0; i < CSIS_NUM_SUPPLIES; i++)
- state->supplies[i].supply = csis_supply_name[i];
-
- ret = devm_regulator_bulk_get(dev, CSIS_NUM_SUPPLIES,
- state->supplies);
- if (ret)
- return ret;
-
- ret = s5pcsis_clk_get(state);
- if (ret < 0)
- return ret;
-
- if (state->clk_frequency)
- ret = clk_set_rate(state->clock[CSIS_CLK_MUX],
- state->clk_frequency);
- else
- dev_WARN(dev, "No clock frequency specified!\n");
- if (ret < 0)
- goto e_clkput;
-
- ret = clk_enable(state->clock[CSIS_CLK_MUX]);
- if (ret < 0)
- goto e_clkput;
-
- ret = devm_request_irq(dev, state->irq, s5pcsis_irq_handler,
- 0, dev_name(dev), state);
- if (ret) {
- dev_err(dev, "Interrupt request failed\n");
- goto e_clkdis;
- }
-
- v4l2_subdev_init(&state->sd, &s5pcsis_subdev_ops);
- state->sd.owner = THIS_MODULE;
- snprintf(state->sd.name, sizeof(state->sd.name), "%s.%d",
- CSIS_SUBDEV_NAME, state->index);
- state->sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
- state->csis_fmt = &s5pcsis_formats[0];
-
- state->format.code = s5pcsis_formats[0].code;
- state->format.width = S5PCSIS_DEF_PIX_WIDTH;
- state->format.height = S5PCSIS_DEF_PIX_HEIGHT;
-
- state->sd.entity.function = MEDIA_ENT_F_IO_V4L;
- state->pads[CSIS_PAD_SINK].flags = MEDIA_PAD_FL_SINK;
- state->pads[CSIS_PAD_SOURCE].flags = MEDIA_PAD_FL_SOURCE;
- ret = media_entity_pads_init(&state->sd.entity,
- CSIS_PADS_NUM, state->pads);
- if (ret < 0)
- goto e_clkdis;
-
- /* This allows to retrieve the platform device id by the host driver */
- v4l2_set_subdevdata(&state->sd, pdev);
-
- /* .. and a pointer to the subdev. */
- platform_set_drvdata(pdev, &state->sd);
- memcpy(state->events, s5pcsis_events, sizeof(state->events));
-
- pm_runtime_enable(dev);
- if (!pm_runtime_enabled(dev)) {
- ret = s5pcsis_pm_resume(dev, true);
- if (ret < 0)
- goto e_m_ent;
- }
-
- dev_info(&pdev->dev, "lanes: %d, hs_settle: %d, wclk: %d, freq: %u\n",
- state->num_lanes, state->hs_settle, state->wclk_ext,
- state->clk_frequency);
- return 0;
-
-e_m_ent:
- media_entity_cleanup(&state->sd.entity);
-e_clkdis:
- clk_disable(state->clock[CSIS_CLK_MUX]);
-e_clkput:
- s5pcsis_clk_put(state);
- return ret;
-}
-
-static int s5pcsis_pm_suspend(struct device *dev, bool runtime)
-{
- struct v4l2_subdev *sd = dev_get_drvdata(dev);
- struct csis_state *state = sd_to_csis_state(sd);
- int ret = 0;
-
- v4l2_dbg(1, debug, sd, "%s: flags: 0x%x\n",
- __func__, state->flags);
-
- mutex_lock(&state->lock);
- if (state->flags & ST_POWERED) {
- s5pcsis_stop_stream(state);
- ret = phy_power_off(state->phy);
- if (ret)
- goto unlock;
- ret = regulator_bulk_disable(CSIS_NUM_SUPPLIES,
- state->supplies);
- if (ret)
- goto unlock;
- clk_disable(state->clock[CSIS_CLK_GATE]);
- state->flags &= ~ST_POWERED;
- if (!runtime)
- state->flags |= ST_SUSPENDED;
- }
- unlock:
- mutex_unlock(&state->lock);
- return ret ? -EAGAIN : 0;
-}
-
-static int s5pcsis_pm_resume(struct device *dev, bool runtime)
-{
- struct v4l2_subdev *sd = dev_get_drvdata(dev);
- struct csis_state *state = sd_to_csis_state(sd);
- int ret = 0;
-
- v4l2_dbg(1, debug, sd, "%s: flags: 0x%x\n",
- __func__, state->flags);
-
- mutex_lock(&state->lock);
- if (!runtime && !(state->flags & ST_SUSPENDED))
- goto unlock;
-
- if (!(state->flags & ST_POWERED)) {
- ret = regulator_bulk_enable(CSIS_NUM_SUPPLIES,
- state->supplies);
- if (ret)
- goto unlock;
- ret = phy_power_on(state->phy);
- if (!ret) {
- state->flags |= ST_POWERED;
- } else {
- regulator_bulk_disable(CSIS_NUM_SUPPLIES,
- state->supplies);
- goto unlock;
- }
- clk_enable(state->clock[CSIS_CLK_GATE]);
- }
- if (state->flags & ST_STREAMING)
- s5pcsis_start_stream(state);
-
- state->flags &= ~ST_SUSPENDED;
- unlock:
- mutex_unlock(&state->lock);
- return ret ? -EAGAIN : 0;
-}
-
-#ifdef CONFIG_PM_SLEEP
-static int s5pcsis_suspend(struct device *dev)
-{
- return s5pcsis_pm_suspend(dev, false);
-}
-
-static int s5pcsis_resume(struct device *dev)
-{
- return s5pcsis_pm_resume(dev, false);
-}
-#endif
-
-#ifdef CONFIG_PM
-static int s5pcsis_runtime_suspend(struct device *dev)
-{
- return s5pcsis_pm_suspend(dev, true);
-}
-
-static int s5pcsis_runtime_resume(struct device *dev)
-{
- return s5pcsis_pm_resume(dev, true);
-}
-#endif
-
-static int s5pcsis_remove(struct platform_device *pdev)
-{
- struct v4l2_subdev *sd = platform_get_drvdata(pdev);
- struct csis_state *state = sd_to_csis_state(sd);
-
- pm_runtime_disable(&pdev->dev);
- s5pcsis_pm_suspend(&pdev->dev, true);
- clk_disable(state->clock[CSIS_CLK_MUX]);
- pm_runtime_set_suspended(&pdev->dev);
- s5pcsis_clk_put(state);
-
- media_entity_cleanup(&state->sd.entity);
-
- return 0;
-}
-
-static const struct dev_pm_ops s5pcsis_pm_ops = {
- SET_RUNTIME_PM_OPS(s5pcsis_runtime_suspend, s5pcsis_runtime_resume,
- NULL)
- SET_SYSTEM_SLEEP_PM_OPS(s5pcsis_suspend, s5pcsis_resume)
-};
-
-static const struct csis_drvdata exynos4_csis_drvdata = {
- .interrupt_mask = S5PCSIS_INTMSK_EXYNOS4_EN_ALL,
-};
-
-static const struct csis_drvdata exynos5_csis_drvdata = {
- .interrupt_mask = S5PCSIS_INTMSK_EXYNOS5_EN_ALL,
-};
-
-static const struct of_device_id s5pcsis_of_match[] = {
- {
- .compatible = "samsung,s5pv210-csis",
- .data = &exynos4_csis_drvdata,
- }, {
- .compatible = "samsung,exynos4210-csis",
- .data = &exynos4_csis_drvdata,
- }, {
- .compatible = "samsung,exynos5250-csis",
- .data = &exynos5_csis_drvdata,
- },
- { /* sentinel */ },
-};
-MODULE_DEVICE_TABLE(of, s5pcsis_of_match);
-
-static struct platform_driver s5pcsis_driver = {
- .probe = s5pcsis_probe,
- .remove = s5pcsis_remove,
- .driver = {
- .of_match_table = s5pcsis_of_match,
- .name = CSIS_DRIVER_NAME,
- .pm = &s5pcsis_pm_ops,
- },
-};
-
-module_platform_driver(s5pcsis_driver);
-
-MODULE_AUTHOR("Sylwester Nawrocki <s.nawrocki@samsung.com>");
-MODULE_DESCRIPTION("Samsung S5P/EXYNOS SoC MIPI-CSI2 receiver driver");
-MODULE_LICENSE("GPL");
diff --git a/drivers/media/platform/exynos4-is/mipi-csis.h b/drivers/media/platform/exynos4-is/mipi-csis.h
deleted file mode 100644
index 193f253c7907..000000000000
--- a/drivers/media/platform/exynos4-is/mipi-csis.h
+++ /dev/null
@@ -1,23 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-only */
-/*
- * Samsung S5P/EXYNOS4 SoC series MIPI-CSI receiver driver
- *
- * Copyright (C) 2011 Samsung Electronics Co., Ltd.
- */
-#ifndef S5P_MIPI_CSIS_H_
-#define S5P_MIPI_CSIS_H_
-
-#define CSIS_DRIVER_NAME "s5p-mipi-csis"
-#define CSIS_SUBDEV_NAME CSIS_DRIVER_NAME
-#define CSIS_MAX_ENTITIES 2
-#define CSIS0_MAX_LANES 4
-#define CSIS1_MAX_LANES 2
-
-#define CSIS_PAD_SINK 0
-#define CSIS_PAD_SOURCE 1
-#define CSIS_PADS_NUM 2
-
-#define S5PCSIS_DEF_PIX_WIDTH 640
-#define S5PCSIS_DEF_PIX_HEIGHT 480
-
-#endif