781f11de1eed2b1b173e3ae07dab95aecb4ecb9b
[openwrt/staging/linusw.git] /
1 From c33277b632fa724dd1a53da87539088c5567fc6d Mon Sep 17 00:00:00 2001
2 From: Naushir Patuck <naush@raspberrypi.com>
3 Date: Wed, 1 Nov 2023 13:25:54 +0000
4 Subject: [PATCH 0702/1085] drivers: media: cfe: Set the CSI-2 link frequency
5 correctly
6
7 Use the sensor provided link frequency to set the DPHY timing parameters
8 on stream_on. This replaces the hard-coded 999 MHz value currently being
9 used. As a fallback, revert to the original 999 Mhz link frequency.
10
11 As a drive-by, fix a 80-character line formatting error.
12
13 Signed-off-by: Naushir Patuck <naush@raspberrypi.com>
14 ---
15 .../media/platform/raspberrypi/rp1_cfe/cfe.c | 63 +++++++++++++++++--
16 1 file changed, 58 insertions(+), 5 deletions(-)
17
18 --- a/drivers/media/platform/raspberrypi/rp1_cfe/cfe.c
19 +++ b/drivers/media/platform/raspberrypi/rp1_cfe/cfe.c
20 @@ -780,7 +780,8 @@ static void cfe_start_channel(struct cfe
21 __func__, node_desc[FE_OUT0].name,
22 cfe->fe_csi2_channel);
23
24 - source_fmt = v4l2_subdev_get_pad_format(&cfe->csi2.sd, state, cfe->fe_csi2_channel);
25 + source_fmt = v4l2_subdev_get_pad_format(&cfe->csi2.sd, state,
26 + cfe->fe_csi2_channel);
27 fmt = find_format_by_code(source_fmt->code);
28
29 width = source_fmt->width;
30 @@ -982,6 +983,59 @@ static void cfe_buffer_queue(struct vb2_
31 spin_unlock_irqrestore(&cfe->state_lock, flags);
32 }
33
34 +static u64 sensor_link_frequency(struct cfe_device *cfe)
35 +{
36 + struct v4l2_mbus_framefmt *source_fmt;
37 + struct v4l2_subdev_state *state;
38 + struct media_entity *entity;
39 + struct v4l2_subdev *subdev;
40 + const struct cfe_fmt *fmt;
41 + struct media_pad *pad;
42 + s64 link_freq;
43 +
44 + state = v4l2_subdev_lock_and_get_active_state(&cfe->csi2.sd);
45 + source_fmt = v4l2_subdev_get_pad_format(&cfe->csi2.sd, state, 0);
46 + fmt = find_format_by_code(source_fmt->code);
47 + v4l2_subdev_unlock_state(state);
48 +
49 + /*
50 + * Walk up the media graph to find either the sensor entity, or another
51 + * entity that advertises the V4L2_CID_LINK_FREQ or V4L2_CID_PIXEL_RATE
52 + * control through the subdev.
53 + */
54 + entity = &cfe->csi2.sd.entity;
55 + while (1) {
56 + pad = &entity->pads[0];
57 + if (!(pad->flags & MEDIA_PAD_FL_SINK))
58 + goto err;
59 +
60 + pad = media_pad_remote_pad_first(pad);
61 + if (!pad || !is_media_entity_v4l2_subdev(pad->entity))
62 + goto err;
63 +
64 + entity = pad->entity;
65 + subdev = media_entity_to_v4l2_subdev(entity);
66 + if (entity->function == MEDIA_ENT_F_CAM_SENSOR ||
67 + v4l2_ctrl_find(subdev->ctrl_handler, V4L2_CID_LINK_FREQ) ||
68 + v4l2_ctrl_find(subdev->ctrl_handler, V4L2_CID_PIXEL_RATE))
69 + break;
70 + }
71 +
72 + link_freq = v4l2_get_link_freq(subdev->ctrl_handler, fmt->depth,
73 + cfe->csi2.active_data_lanes * 2);
74 + if (link_freq < 0)
75 + goto err;
76 +
77 + /* x2 for DDR. */
78 + link_freq *= 2;
79 + cfe_info("Using a link frequency of %lld Hz\n", link_freq);
80 + return link_freq;
81 +
82 +err:
83 + cfe_err("Unable to determine sensor link frequency, using 999 MHz\n");
84 + return 999 * 1000000UL;
85 +}
86 +
87 static int cfe_start_streaming(struct vb2_queue *vq, unsigned int count)
88 {
89 struct v4l2_mbus_config mbus_config = { 0 };
90 @@ -1049,10 +1103,11 @@ static int cfe_start_streaming(struct vb
91 goto err_disable_cfe;
92 }
93
94 - cfe_dbg("Starting sensor streaming\n");
95 -
96 + cfe_dbg("Configuring CSI-2 block\n");
97 + cfe->csi2.dphy.dphy_freq = sensor_link_frequency(cfe) / 1000000UL;
98 csi2_open_rx(&cfe->csi2);
99
100 + cfe_dbg("Starting sensor streaming\n");
101 cfe->sequence = 0;
102 ret = v4l2_subdev_call(cfe->sensor, video, s_stream, 1);
103 if (ret < 0) {
104 @@ -1945,8 +2000,6 @@ static int of_cfe_connect_subdevs(struct
105 }
106 }
107
108 - /* TODO: Get the frequency from devicetree */
109 - cfe->csi2.dphy.dphy_freq = 999;
110 cfe->csi2.dphy.num_lanes = ep.bus.mipi_csi2.num_data_lanes;
111 cfe->csi2.bus_flags = ep.bus.mipi_csi2.flags;
112