bcm27xx: import latest patches from the RPi foundation
[openwrt/staging/ynezz.git] / target / linux / bcm27xx / patches-5.4 / 950-0820-media-i2c-imx290-Add-support-for-2-data-lanes.patch
1 From 78d867300b5026ab31c9a3fbd37b6590b7940f66 Mon Sep 17 00:00:00 2001
2 From: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
3 Date: Fri, 12 Jun 2020 15:53:49 +0200
4 Subject: [PATCH] media: i2c: imx290: Add support for 2 data lanes
5
6 Commit 97589ad61c730e0f486635c6c19fa25ab8e8f29d upstream.
7
8 The IMX290 sensor can output frames with 2/4 CSI2 data lanes. This commit
9 adds support for 2 lane mode in addition to the 4 lane and also
10 configuring the data lane settings in the driver based on system
11 configuration.
12
13 Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
14 Signed-off-by: Andrey Konovalov <andrey.konovalov@linaro.org>
15 Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com>
16 Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
17 ---
18 drivers/media/i2c/imx290.c | 147 +++++++++++++++++++++++++++++++++----
19 1 file changed, 133 insertions(+), 14 deletions(-)
20
21 --- a/drivers/media/i2c/imx290.c
22 +++ b/drivers/media/i2c/imx290.c
23 @@ -25,7 +25,12 @@
24 #define IMX290_STANDBY 0x3000
25 #define IMX290_REGHOLD 0x3001
26 #define IMX290_XMSTA 0x3002
27 +#define IMX290_FR_FDG_SEL 0x3009
28 #define IMX290_GAIN 0x3014
29 +#define IMX290_HMAX_LOW 0x301c
30 +#define IMX290_HMAX_HIGH 0x301d
31 +#define IMX290_PHY_LANE_NUM 0x3407
32 +#define IMX290_CSI_LANE_MODE 0x3443
33
34 #define IMX290_DEFAULT_LINK_FREQ 445500000
35
36 @@ -45,6 +50,7 @@ struct imx290_regval {
37 struct imx290_mode {
38 u32 width;
39 u32 height;
40 + u32 hmax;
41 u32 pixel_rate;
42 u32 link_freq_index;
43
44 @@ -56,6 +62,7 @@ struct imx290 {
45 struct device *dev;
46 struct clk *xclk;
47 struct regmap *regmap;
48 + u8 nlanes;
49
50 struct v4l2_subdev sd;
51 struct v4l2_fwnode_endpoint ep;
52 @@ -89,14 +96,11 @@ static const struct regmap_config imx290
53
54 static const struct imx290_regval imx290_global_init_settings[] = {
55 { 0x3007, 0x00 },
56 - { 0x3009, 0x00 },
57 { 0x3018, 0x65 },
58 { 0x3019, 0x04 },
59 { 0x301a, 0x00 },
60 - { 0x3443, 0x03 },
61 { 0x3444, 0x20 },
62 { 0x3445, 0x25 },
63 - { 0x3407, 0x03 },
64 { 0x303a, 0x0c },
65 { 0x3040, 0x00 },
66 { 0x3041, 0x00 },
67 @@ -169,7 +173,6 @@ static const struct imx290_regval imx290
68 { 0x3164, 0x1a },
69 { 0x3480, 0x49 },
70 /* data rate settings */
71 - { 0x3009, 0x01 },
72 { 0x3405, 0x10 },
73 { 0x3446, 0x57 },
74 { 0x3447, 0x00 },
75 @@ -187,8 +190,6 @@ static const struct imx290_regval imx290
76 { 0x3453, 0x00 },
77 { 0x3454, 0x17 },
78 { 0x3455, 0x00 },
79 - { 0x301c, 0x98 },
80 - { 0x301d, 0x08 },
81 };
82
83 static const struct imx290_regval imx290_720p_settings[] = {
84 @@ -210,7 +211,6 @@ static const struct imx290_regval imx290
85 { 0x3164, 0x1a },
86 { 0x3480, 0x49 },
87 /* data rate settings */
88 - { 0x3009, 0x01 },
89 { 0x3405, 0x10 },
90 { 0x3446, 0x4f },
91 { 0x3447, 0x00 },
92 @@ -228,8 +228,6 @@ static const struct imx290_regval imx290
93 { 0x3453, 0x00 },
94 { 0x3454, 0x17 },
95 { 0x3455, 0x00 },
96 - { 0x301c, 0xe4 },
97 - { 0x301d, 0x0c },
98 };
99
100 static const struct imx290_regval imx290_10bit_settings[] = {
101 @@ -250,10 +248,11 @@ static const s64 imx290_link_freq[] = {
102 };
103
104 /* Mode configs */
105 -static const struct imx290_mode imx290_modes[] = {
106 +static const struct imx290_mode imx290_modes_2lanes[] = {
107 {
108 .width = 1920,
109 .height = 1080,
110 + .hmax = 0x1130,
111 .data = imx290_1080p_settings,
112 .data_size = ARRAY_SIZE(imx290_1080p_settings),
113 .pixel_rate = 178200000,
114 @@ -262,6 +261,7 @@ static const struct imx290_mode imx290_m
115 {
116 .width = 1280,
117 .height = 720,
118 + .hmax = 0x19c8,
119 .data = imx290_720p_settings,
120 .data_size = ARRAY_SIZE(imx290_720p_settings),
121 .pixel_rate = 178200000,
122 @@ -269,6 +269,44 @@ static const struct imx290_mode imx290_m
123 },
124 };
125
126 +static const struct imx290_mode imx290_modes_4lanes[] = {
127 + {
128 + .width = 1920,
129 + .height = 1080,
130 + .hmax = 0x0898,
131 + .data = imx290_1080p_settings,
132 + .data_size = ARRAY_SIZE(imx290_1080p_settings),
133 + .pixel_rate = 178200000,
134 + .link_freq_index = 0,
135 + },
136 + {
137 + .width = 1280,
138 + .height = 720,
139 + .hmax = 0x0ce4,
140 + .data = imx290_720p_settings,
141 + .data_size = ARRAY_SIZE(imx290_720p_settings),
142 + .pixel_rate = 178200000,
143 + .link_freq_index = 0,
144 + },
145 +};
146 +
147 +static inline const struct imx290_mode *imx290_modes_ptr(const struct imx290 *imx290)
148 +{
149 + /* We rely on imx290_probe() to ensure that nlanes is either 2 or 4 */
150 + if (imx290->nlanes == 2)
151 + return imx290_modes_2lanes;
152 + else
153 + return imx290_modes_4lanes;
154 +}
155 +
156 +static inline int imx290_modes_num(const struct imx290 *imx290)
157 +{
158 + if (imx290->nlanes == 2)
159 + return ARRAY_SIZE(imx290_modes_2lanes);
160 + else
161 + return ARRAY_SIZE(imx290_modes_4lanes);
162 +}
163 +
164 static inline struct imx290 *to_imx290(struct v4l2_subdev *_sd)
165 {
166 return container_of(_sd, struct imx290, sd);
167 @@ -450,9 +488,8 @@ static int imx290_set_fmt(struct v4l2_su
168
169 mutex_lock(&imx290->lock);
170
171 - mode = v4l2_find_nearest_size(imx290_modes,
172 - ARRAY_SIZE(imx290_modes),
173 - width, height,
174 + mode = v4l2_find_nearest_size(imx290_modes_ptr(imx290),
175 + imx290_modes_num(imx290), width, height,
176 fmt->format.width, fmt->format.height);
177
178 fmt->format.width = mode->width;
179 @@ -522,6 +559,25 @@ static int imx290_write_current_format(s
180 return 0;
181 }
182
183 +static int imx290_set_hmax(struct imx290 *imx290, u32 val)
184 +{
185 + int ret;
186 +
187 + ret = imx290_write_reg(imx290, IMX290_HMAX_LOW, (val & 0xff));
188 + if (ret) {
189 + dev_err(imx290->dev, "Error setting HMAX register\n");
190 + return ret;
191 + }
192 +
193 + ret = imx290_write_reg(imx290, IMX290_HMAX_HIGH, ((val >> 8) & 0xff));
194 + if (ret) {
195 + dev_err(imx290->dev, "Error setting HMAX register\n");
196 + return ret;
197 + }
198 +
199 + return 0;
200 +}
201 +
202 /* Start streaming */
203 static int imx290_start_streaming(struct imx290 *imx290)
204 {
205 @@ -550,6 +606,9 @@ static int imx290_start_streaming(struct
206 dev_err(imx290->dev, "Could not set current mode\n");
207 return ret;
208 }
209 + ret = imx290_set_hmax(imx290, imx290->current_mode->hmax);
210 + if (ret < 0)
211 + return ret;
212
213 /* Apply customized values from user */
214 ret = v4l2_ctrl_handler_setup(imx290->sd.ctrl_handler);
215 @@ -607,6 +666,49 @@ static int imx290_get_regulators(struct
216 imx290->supplies);
217 }
218
219 +static int imx290_set_data_lanes(struct imx290 *imx290)
220 +{
221 + int ret = 0, laneval, frsel;
222 +
223 + switch (imx290->nlanes) {
224 + case 2:
225 + laneval = 0x01;
226 + frsel = 0x02;
227 + break;
228 + case 4:
229 + laneval = 0x03;
230 + frsel = 0x01;
231 + break;
232 + default:
233 + /*
234 + * We should never hit this since the data lane count is
235 + * validated in probe itself
236 + */
237 + dev_err(imx290->dev, "Lane configuration not supported\n");
238 + ret = -EINVAL;
239 + goto exit;
240 + }
241 +
242 + ret = imx290_write_reg(imx290, IMX290_PHY_LANE_NUM, laneval);
243 + if (ret) {
244 + dev_err(imx290->dev, "Error setting Physical Lane number register\n");
245 + goto exit;
246 + }
247 +
248 + ret = imx290_write_reg(imx290, IMX290_CSI_LANE_MODE, laneval);
249 + if (ret) {
250 + dev_err(imx290->dev, "Error setting CSI Lane mode register\n");
251 + goto exit;
252 + }
253 +
254 + ret = imx290_write_reg(imx290, IMX290_FR_FDG_SEL, frsel);
255 + if (ret)
256 + dev_err(imx290->dev, "Error setting FR/FDG SEL register\n");
257 +
258 +exit:
259 + return ret;
260 +}
261 +
262 static int imx290_power_on(struct device *dev)
263 {
264 struct i2c_client *client = to_i2c_client(dev);
265 @@ -631,6 +733,9 @@ static int imx290_power_on(struct device
266 gpiod_set_value_cansleep(imx290->rst_gpio, 0);
267 usleep_range(30000, 31000);
268
269 + /* Set data lane count */
270 + imx290_set_data_lanes(imx290);
271 +
272 return 0;
273 }
274
275 @@ -677,6 +782,7 @@ static int imx290_probe(struct i2c_clien
276 struct fwnode_handle *endpoint;
277 struct imx290 *imx290;
278 u32 xclk_freq;
279 + u32 default_pixel_rate;
280 int ret;
281
282 imx290 = devm_kzalloc(dev, sizeof(*imx290), GFP_KERNEL);
283 @@ -703,6 +809,16 @@ static int imx290_probe(struct i2c_clien
284 goto free_err;
285 }
286
287 + /* Get number of data lanes */
288 + imx290->nlanes = imx290->ep.bus.mipi_csi2.num_data_lanes;
289 + if (imx290->nlanes != 2 && imx290->nlanes != 4) {
290 + dev_err(dev, "Invalid data lanes: %d\n", imx290->nlanes);
291 + ret = -EINVAL;
292 + goto free_err;
293 + }
294 +
295 + dev_dbg(dev, "Using %u data lanes\n", imx290->nlanes);
296 +
297 if (!imx290->ep.nr_of_link_frequencies) {
298 dev_err(dev, "link-frequency property not found in DT\n");
299 ret = -EINVAL;
300 @@ -780,10 +896,13 @@ static int imx290_probe(struct i2c_clien
301 if (imx290->link_freq)
302 imx290->link_freq->flags |= V4L2_CTRL_FLAG_READ_ONLY;
303
304 + default_pixel_rate = imx290->nlanes == 2 ?
305 + imx290_modes_2lanes[0].pixel_rate :
306 + imx290_modes_4lanes[0].pixel_rate;
307 imx290->pixel_rate = v4l2_ctrl_new_std(&imx290->ctrls, &imx290_ctrl_ops,
308 V4L2_CID_PIXEL_RATE, 1,
309 INT_MAX, 1,
310 - imx290_modes[0].pixel_rate);
311 + default_pixel_rate);
312
313 imx290->sd.ctrl_handler = &imx290->ctrls;
314