summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/media/platform/renesas/rcar-vin/rcar-core.c13
-rw-r--r--drivers/media/platform/renesas/rcar-vin/rcar-dma.c34
-rw-r--r--drivers/media/platform/renesas/rcar-vin/rcar-v4l2.c6
-rw-r--r--drivers/media/platform/renesas/rcar-vin/rcar-vin.h6
4 files changed, 46 insertions, 13 deletions
diff --git a/drivers/media/platform/renesas/rcar-vin/rcar-core.c b/drivers/media/platform/renesas/rcar-vin/rcar-core.c
index 2f7daa853ed8..fca2176672c5 100644
--- a/drivers/media/platform/renesas/rcar-vin/rcar-core.c
+++ b/drivers/media/platform/renesas/rcar-vin/rcar-core.c
@@ -1131,6 +1131,7 @@ static const struct rvin_info rcar_info_h1 = {
.use_mc = false,
.max_width = 2048,
.max_height = 2048,
+ .scaler = rvin_scaler_gen2,
};
static const struct rvin_info rcar_info_m1 = {
@@ -1138,6 +1139,7 @@ static const struct rvin_info rcar_info_m1 = {
.use_mc = false,
.max_width = 2048,
.max_height = 2048,
+ .scaler = rvin_scaler_gen2,
};
static const struct rvin_info rcar_info_gen2 = {
@@ -1145,6 +1147,7 @@ static const struct rvin_info rcar_info_gen2 = {
.use_mc = false,
.max_width = 2048,
.max_height = 2048,
+ .scaler = rvin_scaler_gen2,
};
static const struct rvin_group_route rcar_info_r8a774e1_routes[] = {
@@ -1408,13 +1411,17 @@ static int rcar_vin_probe(struct platform_device *pdev)
platform_set_drvdata(pdev, vin);
- if (vin->info->use_isp)
+ if (vin->info->use_isp) {
ret = rvin_isp_init(vin);
- else if (vin->info->use_mc)
+ } else if (vin->info->use_mc) {
ret = rvin_csi2_init(vin);
- else
+ } else {
ret = rvin_parallel_init(vin);
+ if (vin->info->scaler)
+ vin->scaler = vin->info->scaler;
+ }
+
if (ret) {
rvin_dma_unregister(vin);
return ret;
diff --git a/drivers/media/platform/renesas/rcar-vin/rcar-dma.c b/drivers/media/platform/renesas/rcar-vin/rcar-dma.c
index 3aea96d85165..48241bf6fb1b 100644
--- a/drivers/media/platform/renesas/rcar-vin/rcar-dma.c
+++ b/drivers/media/platform/renesas/rcar-vin/rcar-dma.c
@@ -160,9 +160,17 @@ static u32 rvin_read(struct rvin_dev *vin, u32 offset)
}
/* -----------------------------------------------------------------------------
- * Crop and Scaling Gen2
+ * Crop and Scaling
*/
+static bool rvin_scaler_needed(const struct rvin_dev *vin)
+{
+ return !(vin->crop.width == vin->format.width &&
+ vin->compose.width == vin->format.width &&
+ vin->crop.height == vin->format.height &&
+ vin->compose.height == vin->format.height);
+}
+
struct vin_coeff {
unsigned short xs_value;
u32 coeff_set[24];
@@ -535,7 +543,7 @@ static void rvin_set_coeff(struct rvin_dev *vin, unsigned short xs)
rvin_write(vin, p_set->coeff_set[23], VNC8C_REG);
}
-static void rvin_crop_scale_comp_gen2(struct rvin_dev *vin)
+void rvin_scaler_gen2(struct rvin_dev *vin)
{
unsigned int crop_height;
u32 xs, ys;
@@ -594,9 +602,8 @@ void rvin_crop_scale_comp(struct rvin_dev *vin)
rvin_write(vin, vin->crop.top, VNSLPRC_REG);
rvin_write(vin, vin->crop.top + vin->crop.height - 1, VNELPRC_REG);
- /* TODO: Add support for the UDS scaler. */
- if (vin->info->model != RCAR_GEN3)
- rvin_crop_scale_comp_gen2(vin);
+ if (vin->scaler)
+ vin->scaler(vin);
fmt = rvin_format_from_pixel(vin, vin->format.pixelformat);
stride = vin->format.bytesperline / fmt->bpp;
@@ -984,12 +991,12 @@ static int rvin_capture_start(struct rvin_dev *vin)
for (slot = 0; slot < HW_BUFFER_NUM; slot++)
rvin_fill_hw_slot(vin, slot);
- rvin_crop_scale_comp(vin);
-
ret = rvin_setup(vin);
if (ret)
return ret;
+ rvin_crop_scale_comp(vin);
+
vin_dbg(vin, "Starting to capture\n");
/* Continuous Frame Capture Mode */
@@ -1234,9 +1241,16 @@ static int rvin_mc_validate_format(struct rvin_dev *vin, struct v4l2_subdev *sd,
return -EPIPE;
}
- if (fmt.format.width != vin->format.width ||
- fmt.format.height != vin->format.height ||
- fmt.format.code != vin->mbus_code)
+ if (rvin_scaler_needed(vin)) {
+ if (!vin->scaler)
+ return -EPIPE;
+ } else {
+ if (fmt.format.width != vin->format.width ||
+ fmt.format.height != vin->format.height)
+ return -EPIPE;
+ }
+
+ if (fmt.format.code != vin->mbus_code)
return -EPIPE;
return 0;
diff --git a/drivers/media/platform/renesas/rcar-vin/rcar-v4l2.c b/drivers/media/platform/renesas/rcar-vin/rcar-v4l2.c
index a0b398aa2596..07564e05ed8c 100644
--- a/drivers/media/platform/renesas/rcar-vin/rcar-v4l2.c
+++ b/drivers/media/platform/renesas/rcar-vin/rcar-v4l2.c
@@ -477,6 +477,9 @@ static int rvin_g_selection(struct file *file, void *fh,
struct rvin_dev *vin = video_drvdata(file);
int ret;
+ if (!vin->scaler)
+ return -ENOIOCTLCMD;
+
if (s->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
return -EINVAL;
@@ -520,6 +523,9 @@ static int rvin_s_selection(struct file *file, void *fh,
};
int ret;
+ if (!vin->scaler)
+ return -ENOIOCTLCMD;
+
if (s->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
return -EINVAL;
diff --git a/drivers/media/platform/renesas/rcar-vin/rcar-vin.h b/drivers/media/platform/renesas/rcar-vin/rcar-vin.h
index 469c4aaf90e2..334c327889a0 100644
--- a/drivers/media/platform/renesas/rcar-vin/rcar-vin.h
+++ b/drivers/media/platform/renesas/rcar-vin/rcar-vin.h
@@ -31,6 +31,7 @@
/* Max number on VIN instances that can be in a system */
#define RCAR_VIN_NUM 32
+struct rvin_dev;
struct rvin_group;
enum model_id {
@@ -155,6 +156,7 @@ struct rvin_group_route {
* @max_height: max input height the VIN supports
* @routes: list of possible routes from the CSI-2 recivers to
* all VINs. The list mush be NULL terminated.
+ * @scaler: Optional scaler
*/
struct rvin_info {
enum model_id model;
@@ -165,6 +167,7 @@ struct rvin_info {
unsigned int max_width;
unsigned int max_height;
const struct rvin_group_route *routes;
+ void (*scaler)(struct rvin_dev *vin);
};
/**
@@ -203,6 +206,7 @@ struct rvin_info {
*
* @crop: active cropping
* @compose: active composing
+ * @scaler: Optional scaler
* @std: active video standard of the video source
*
* @alpha: Alpha component to fill in for supported pixel formats
@@ -246,6 +250,7 @@ struct rvin_dev {
struct v4l2_rect crop;
struct v4l2_rect compose;
+ void (*scaler)(struct rvin_dev *vin);
v4l2_std_id std;
unsigned int alpha;
@@ -302,6 +307,7 @@ const struct rvin_video_format *rvin_format_from_pixel(struct rvin_dev *vin,
/* Cropping, composing and scaling */
+void rvin_scaler_gen2(struct rvin_dev *vin);
void rvin_crop_scale_comp(struct rvin_dev *vin);
int rvin_set_channel_routing(struct rvin_dev *vin, u8 chsel);