diff options
Diffstat (limited to 'drivers/media/platform/rcar-vin')
-rw-r--r-- | drivers/media/platform/rcar-vin/rcar-core.c | 52 | ||||
-rw-r--r-- | drivers/media/platform/rcar-vin/rcar-csi2.c | 97 | ||||
-rw-r--r-- | drivers/media/platform/rcar-vin/rcar-v4l2.c | 10 |
3 files changed, 120 insertions, 39 deletions
diff --git a/drivers/media/platform/rcar-vin/rcar-core.c b/drivers/media/platform/rcar-vin/rcar-core.c index f476b2f1eb35..f0719ce24b97 100644 --- a/drivers/media/platform/rcar-vin/rcar-core.c +++ b/drivers/media/platform/rcar-vin/rcar-core.c @@ -1088,6 +1088,50 @@ static const struct rvin_info rcar_info_r8a77970 = { .routes = rcar_info_r8a77970_routes, }; +static const struct rvin_group_route rcar_info_r8a77980_routes[] = { + { .csi = RVIN_CSI40, .channel = 0, .vin = 0, .mask = BIT(0) | BIT(3) }, + { .csi = RVIN_CSI40, .channel = 1, .vin = 0, .mask = BIT(2) }, + { .csi = RVIN_CSI40, .channel = 0, .vin = 1, .mask = BIT(2) }, + { .csi = RVIN_CSI40, .channel = 1, .vin = 1, .mask = BIT(1) | BIT(3) }, + { .csi = RVIN_CSI40, .channel = 0, .vin = 2, .mask = BIT(1) }, + { .csi = RVIN_CSI40, .channel = 2, .vin = 2, .mask = BIT(3) }, + { .csi = RVIN_CSI40, .channel = 1, .vin = 3, .mask = BIT(0) }, + { .csi = RVIN_CSI40, .channel = 3, .vin = 3, .mask = BIT(3) }, + { .csi = RVIN_CSI41, .channel = 0, .vin = 4, .mask = BIT(0) | BIT(3) }, + { .csi = RVIN_CSI41, .channel = 1, .vin = 4, .mask = BIT(2) }, + { .csi = RVIN_CSI41, .channel = 0, .vin = 5, .mask = BIT(2) }, + { .csi = RVIN_CSI41, .channel = 1, .vin = 5, .mask = BIT(1) | BIT(3) }, + { .csi = RVIN_CSI41, .channel = 0, .vin = 6, .mask = BIT(1) }, + { .csi = RVIN_CSI41, .channel = 2, .vin = 6, .mask = BIT(3) }, + { .csi = RVIN_CSI41, .channel = 1, .vin = 7, .mask = BIT(0) }, + { .csi = RVIN_CSI41, .channel = 3, .vin = 7, .mask = BIT(3) }, + { /* Sentinel */ } +}; + +static const struct rvin_info rcar_info_r8a77980 = { + .model = RCAR_GEN3, + .use_mc = true, + .max_width = 4096, + .max_height = 4096, + .routes = rcar_info_r8a77980_routes, +}; + +static const struct rvin_group_route rcar_info_r8a77990_routes[] = { + { .csi = RVIN_CSI40, .channel = 0, .vin = 4, .mask = BIT(0) | BIT(3) }, + { .csi = RVIN_CSI40, .channel = 0, .vin = 5, .mask = BIT(2) }, + { .csi = RVIN_CSI40, .channel = 1, .vin = 4, .mask = BIT(2) }, + { .csi = RVIN_CSI40, .channel = 1, .vin = 5, .mask = BIT(1) | BIT(3) }, + { /* Sentinel */ } +}; + +static const struct rvin_info rcar_info_r8a77990 = { + .model = RCAR_GEN3, + .use_mc = true, + .max_width = 4096, + .max_height = 4096, + .routes = rcar_info_r8a77990_routes, +}; + static const struct rvin_group_route rcar_info_r8a77995_routes[] = { { /* Sentinel */ } }; @@ -1146,6 +1190,14 @@ static const struct of_device_id rvin_of_id_table[] = { .data = &rcar_info_r8a77970, }, { + .compatible = "renesas,vin-r8a77980", + .data = &rcar_info_r8a77980, + }, + { + .compatible = "renesas,vin-r8a77990", + .data = &rcar_info_r8a77990, + }, + { .compatible = "renesas,vin-r8a77995", .data = &rcar_info_r8a77995, }, diff --git a/drivers/media/platform/rcar-vin/rcar-csi2.c b/drivers/media/platform/rcar-vin/rcar-csi2.c index b0044a08e71e..6d356f5a9456 100644 --- a/drivers/media/platform/rcar-vin/rcar-csi2.c +++ b/drivers/media/platform/rcar-vin/rcar-csi2.c @@ -152,37 +152,37 @@ static const struct rcsi2_mbps_reg phtw_mbps_h3_v3h_m3n[] = { }; static const struct rcsi2_mbps_reg phtw_mbps_v3m_e3[] = { - { .mbps = 80, .reg = 0x00 }, - { .mbps = 90, .reg = 0x20 }, - { .mbps = 100, .reg = 0x40 }, - { .mbps = 110, .reg = 0x02 }, - { .mbps = 130, .reg = 0x22 }, - { .mbps = 140, .reg = 0x42 }, - { .mbps = 150, .reg = 0x04 }, - { .mbps = 170, .reg = 0x24 }, - { .mbps = 180, .reg = 0x44 }, - { .mbps = 200, .reg = 0x06 }, - { .mbps = 220, .reg = 0x26 }, - { .mbps = 240, .reg = 0x46 }, - { .mbps = 250, .reg = 0x08 }, - { .mbps = 270, .reg = 0x28 }, - { .mbps = 300, .reg = 0x0a }, - { .mbps = 330, .reg = 0x2a }, - { .mbps = 360, .reg = 0x4a }, - { .mbps = 400, .reg = 0x0c }, - { .mbps = 450, .reg = 0x2c }, - { .mbps = 500, .reg = 0x0e }, - { .mbps = 550, .reg = 0x2e }, - { .mbps = 600, .reg = 0x10 }, - { .mbps = 650, .reg = 0x30 }, - { .mbps = 700, .reg = 0x12 }, - { .mbps = 750, .reg = 0x32 }, - { .mbps = 800, .reg = 0x52 }, - { .mbps = 850, .reg = 0x72 }, - { .mbps = 900, .reg = 0x14 }, - { .mbps = 950, .reg = 0x34 }, - { .mbps = 1000, .reg = 0x54 }, - { .mbps = 1050, .reg = 0x74 }, + { .mbps = 89, .reg = 0x00 }, + { .mbps = 99, .reg = 0x20 }, + { .mbps = 109, .reg = 0x40 }, + { .mbps = 129, .reg = 0x02 }, + { .mbps = 139, .reg = 0x22 }, + { .mbps = 149, .reg = 0x42 }, + { .mbps = 169, .reg = 0x04 }, + { .mbps = 179, .reg = 0x24 }, + { .mbps = 199, .reg = 0x44 }, + { .mbps = 219, .reg = 0x06 }, + { .mbps = 239, .reg = 0x26 }, + { .mbps = 249, .reg = 0x46 }, + { .mbps = 269, .reg = 0x08 }, + { .mbps = 299, .reg = 0x28 }, + { .mbps = 329, .reg = 0x0a }, + { .mbps = 359, .reg = 0x2a }, + { .mbps = 399, .reg = 0x4a }, + { .mbps = 449, .reg = 0x0c }, + { .mbps = 499, .reg = 0x2c }, + { .mbps = 549, .reg = 0x0e }, + { .mbps = 599, .reg = 0x2e }, + { .mbps = 649, .reg = 0x10 }, + { .mbps = 699, .reg = 0x30 }, + { .mbps = 749, .reg = 0x12 }, + { .mbps = 799, .reg = 0x32 }, + { .mbps = 849, .reg = 0x52 }, + { .mbps = 899, .reg = 0x72 }, + { .mbps = 949, .reg = 0x14 }, + { .mbps = 999, .reg = 0x34 }, + { .mbps = 1049, .reg = 0x54 }, + { .mbps = 1099, .reg = 0x74 }, { .mbps = 1125, .reg = 0x16 }, { /* sentinel */ }, }; @@ -342,6 +342,7 @@ struct rcar_csi2_info { int (*confirm_start)(struct rcar_csi2 *priv); const struct rcsi2_mbps_reg *hsfreqrange; unsigned int csi0clkfreqrange; + unsigned int num_channels; bool clear_ulps; }; @@ -476,13 +477,14 @@ static int rcsi2_start(struct rcar_csi2 *priv) format = rcsi2_code_to_fmt(priv->mf.code); /* - * Enable all Virtual Channels. + * Enable all supported CSI-2 channels with virtual channel and + * data type matching. * * NOTE: It's not possible to get individual datatype for each * source virtual channel. Once this is possible in V4L2 * it should be used here. */ - for (i = 0; i < 4; i++) { + for (i = 0; i < priv->info->num_channels; i++) { u32 vcdt_part; vcdt_part = VCDT_SEL_VC(i) | VCDT_VCDTN_EN | VCDT_SEL_DTN_ON | @@ -511,7 +513,8 @@ static int rcsi2_start(struct rcar_csi2 *priv) rcsi2_write(priv, FLD_REG, FLD_FLD_NUM(2) | FLD_FLD_EN4 | FLD_FLD_EN3 | FLD_FLD_EN2 | FLD_FLD_EN); rcsi2_write(priv, VCDT_REG, vcdt); - rcsi2_write(priv, VCDT2_REG, vcdt2); + if (vcdt2) + rcsi2_write(priv, VCDT2_REG, vcdt2); /* Lanes are zero indexed. */ rcsi2_write(priv, LSWAP_REG, LSWAP_L0SEL(priv->lane_swap[0] - 1) | @@ -940,27 +943,45 @@ static const struct rcar_csi2_info rcar_csi2_info_r8a7795 = { .init_phtw = rcsi2_init_phtw_h3_v3h_m3n, .hsfreqrange = hsfreqrange_h3_v3h_m3n, .csi0clkfreqrange = 0x20, + .num_channels = 4, .clear_ulps = true, }; static const struct rcar_csi2_info rcar_csi2_info_r8a7795es1 = { .hsfreqrange = hsfreqrange_m3w_h3es1, + .num_channels = 4, }; static const struct rcar_csi2_info rcar_csi2_info_r8a7796 = { .hsfreqrange = hsfreqrange_m3w_h3es1, + .num_channels = 4, }; static const struct rcar_csi2_info rcar_csi2_info_r8a77965 = { .init_phtw = rcsi2_init_phtw_h3_v3h_m3n, .hsfreqrange = hsfreqrange_h3_v3h_m3n, .csi0clkfreqrange = 0x20, + .num_channels = 4, .clear_ulps = true, }; static const struct rcar_csi2_info rcar_csi2_info_r8a77970 = { .init_phtw = rcsi2_init_phtw_v3m_e3, .confirm_start = rcsi2_confirm_start_v3m_e3, + .num_channels = 4, +}; + +static const struct rcar_csi2_info rcar_csi2_info_r8a77980 = { + .init_phtw = rcsi2_init_phtw_h3_v3h_m3n, + .hsfreqrange = hsfreqrange_h3_v3h_m3n, + .csi0clkfreqrange = 0x20, + .clear_ulps = true, +}; + +static const struct rcar_csi2_info rcar_csi2_info_r8a77990 = { + .init_phtw = rcsi2_init_phtw_v3m_e3, + .confirm_start = rcsi2_confirm_start_v3m_e3, + .num_channels = 2, }; static const struct of_device_id rcar_csi2_of_table[] = { @@ -980,6 +1001,14 @@ static const struct of_device_id rcar_csi2_of_table[] = { .compatible = "renesas,r8a77970-csi2", .data = &rcar_csi2_info_r8a77970, }, + { + .compatible = "renesas,r8a77980-csi2", + .data = &rcar_csi2_info_r8a77980, + }, + { + .compatible = "renesas,r8a77990-csi2", + .data = &rcar_csi2_info_r8a77990, + }, { /* sentinel */ }, }; MODULE_DEVICE_TABLE(of, rcar_csi2_of_table); diff --git a/drivers/media/platform/rcar-vin/rcar-v4l2.c b/drivers/media/platform/rcar-vin/rcar-v4l2.c index dc77682b4785..7a2851790b91 100644 --- a/drivers/media/platform/rcar-vin/rcar-v4l2.c +++ b/drivers/media/platform/rcar-vin/rcar-v4l2.c @@ -404,16 +404,16 @@ static int rvin_s_selection(struct file *file, void *fh, return 0; } -static int rvin_cropcap(struct file *file, void *priv, - struct v4l2_cropcap *crop) +static int rvin_g_pixelaspect(struct file *file, void *priv, + int type, struct v4l2_fract *f) { struct rvin_dev *vin = video_drvdata(file); struct v4l2_subdev *sd = vin_to_source(vin); - if (crop->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) + if (type != V4L2_BUF_TYPE_VIDEO_CAPTURE) return -EINVAL; - return v4l2_subdev_call(sd, video, g_pixelaspect, &crop->pixelaspect); + return v4l2_subdev_call(sd, video, g_pixelaspect, f); } static int rvin_enum_input(struct file *file, void *priv, @@ -620,7 +620,7 @@ static const struct v4l2_ioctl_ops rvin_ioctl_ops = { .vidioc_g_selection = rvin_g_selection, .vidioc_s_selection = rvin_s_selection, - .vidioc_cropcap = rvin_cropcap, + .vidioc_g_pixelaspect = rvin_g_pixelaspect, .vidioc_enum_input = rvin_enum_input, .vidioc_g_input = rvin_g_input, |