diff options
Diffstat (limited to 'drivers/media')
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); |