xref: /linux/drivers/media/platform/qcom/camss/camss-tpg.c (revision b2128290c29902315e632ea59e0504d6bc9e9b42)
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  *
4  * Qualcomm MSM Camera Subsystem - TPG Module
5  *
6  * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
7  */
8 #include <linux/clk.h>
9 #include <linux/io.h>
10 #include <linux/kernel.h>
11 #include <linux/of.h>
12 #include <linux/platform_device.h>
13 #include <linux/pm_runtime.h>
14 #include <media/media-entity.h>
15 #include <media/v4l2-device.h>
16 #include <media/v4l2-subdev.h>
17 #include <media/mipi-csi2.h>
18 
19 #include "camss-tpg.h"
20 #include "camss.h"
21 
22 static const struct tpg_format_info formats_gen1[] = {
23 	{
24 		MEDIA_BUS_FMT_SBGGR8_1X8,
25 		MIPI_CSI2_DT_RAW8,
26 		ENCODE_FORMAT_UNCOMPRESSED_8_BIT,
27 		8,
28 	},
29 	{
30 		MEDIA_BUS_FMT_SGBRG8_1X8,
31 		MIPI_CSI2_DT_RAW8,
32 		ENCODE_FORMAT_UNCOMPRESSED_8_BIT,
33 		8,
34 	},
35 	{
36 		MEDIA_BUS_FMT_SGRBG8_1X8,
37 		MIPI_CSI2_DT_RAW8,
38 		ENCODE_FORMAT_UNCOMPRESSED_8_BIT,
39 		8,
40 	},
41 	{
42 		MEDIA_BUS_FMT_SRGGB8_1X8,
43 		MIPI_CSI2_DT_RAW8,
44 		ENCODE_FORMAT_UNCOMPRESSED_8_BIT,
45 		8,
46 	},
47 	{
48 		MEDIA_BUS_FMT_SBGGR10_1X10,
49 		MIPI_CSI2_DT_RAW10,
50 		ENCODE_FORMAT_UNCOMPRESSED_10_BIT,
51 		10,
52 	},
53 	{
54 		MEDIA_BUS_FMT_SGBRG10_1X10,
55 		MIPI_CSI2_DT_RAW10,
56 		ENCODE_FORMAT_UNCOMPRESSED_10_BIT,
57 		10,
58 	},
59 	{
60 		MEDIA_BUS_FMT_SGRBG10_1X10,
61 		MIPI_CSI2_DT_RAW10,
62 		ENCODE_FORMAT_UNCOMPRESSED_10_BIT,
63 		10,
64 	},
65 	{
66 		MEDIA_BUS_FMT_SRGGB10_1X10,
67 		MIPI_CSI2_DT_RAW10,
68 		ENCODE_FORMAT_UNCOMPRESSED_10_BIT,
69 		10,
70 	},
71 	{
72 		MEDIA_BUS_FMT_SBGGR12_1X12,
73 		MIPI_CSI2_DT_RAW12,
74 		ENCODE_FORMAT_UNCOMPRESSED_12_BIT,
75 		12,
76 	},
77 	{
78 		MEDIA_BUS_FMT_SGBRG12_1X12,
79 		MIPI_CSI2_DT_RAW12,
80 		ENCODE_FORMAT_UNCOMPRESSED_12_BIT,
81 		12,
82 	},
83 	{
84 		MEDIA_BUS_FMT_SGRBG12_1X12,
85 		MIPI_CSI2_DT_RAW12,
86 		ENCODE_FORMAT_UNCOMPRESSED_12_BIT,
87 		12,
88 	},
89 	{
90 		MEDIA_BUS_FMT_SRGGB12_1X12,
91 		MIPI_CSI2_DT_RAW12,
92 		ENCODE_FORMAT_UNCOMPRESSED_12_BIT,
93 		12,
94 	},
95 	{
96 		MEDIA_BUS_FMT_Y8_1X8,
97 		MIPI_CSI2_DT_RAW8,
98 		ENCODE_FORMAT_UNCOMPRESSED_8_BIT,
99 		8,
100 	},
101 	{
102 		MEDIA_BUS_FMT_Y10_1X10,
103 		MIPI_CSI2_DT_RAW10,
104 		ENCODE_FORMAT_UNCOMPRESSED_10_BIT,
105 		10,
106 	},
107 };
108 
109 const struct tpg_formats tpg_formats_gen1 = {
110 	.nformats = ARRAY_SIZE(formats_gen1),
111 	.formats = formats_gen1
112 };
113 
114 const struct tpg_format_info *tpg_get_fmt_entry(const struct tpg_format_info *formats,
115 						unsigned int nformats,
116 						u32 code)
117 {
118 	unsigned int i;
119 
120 	for (i = 0; i < nformats; i++)
121 		if (code == formats[i].code)
122 			return &formats[i];
123 
124 	return ERR_PTR(-EINVAL);
125 }
126 
127 static int tpg_set_clock_rates(struct tpg_device *tpg)
128 {
129 	struct device *dev = tpg->camss->dev;
130 	int i, ret;
131 
132 	for (i = 0; i < tpg->nclocks; i++) {
133 		struct camss_clock *clock = &tpg->clock[i];
134 		long round_rate;
135 
136 		if (clock->freq) {
137 			round_rate = clk_round_rate(clock->clk, clock->freq[0]);
138 			if (round_rate < 0) {
139 				dev_err(dev, "clk round rate failed: %ld\n",
140 					round_rate);
141 				return -EINVAL;
142 			}
143 
144 			ret = clk_set_rate(clock->clk, round_rate);
145 			if (ret < 0) {
146 				dev_err(dev, "clk set rate failed: %d\n", ret);
147 				return ret;
148 			}
149 		}
150 	}
151 
152 	return 0;
153 }
154 
155 static int tpg_set_power(struct v4l2_subdev *sd, int on)
156 {
157 	struct tpg_device *tpg = v4l2_get_subdevdata(sd);
158 	struct device *dev = tpg->camss->dev;
159 
160 	if (on) {
161 		int ret;
162 
163 		ret = pm_runtime_resume_and_get(dev);
164 		if (ret < 0)
165 			return ret;
166 
167 		ret = tpg_set_clock_rates(tpg);
168 		if (ret < 0) {
169 			pm_runtime_put_sync(dev);
170 			return ret;
171 		}
172 
173 		ret = camss_enable_clocks(tpg->nclocks, tpg->clock, dev);
174 		if (ret < 0) {
175 			pm_runtime_put_sync(dev);
176 			return ret;
177 		}
178 
179 		tpg->res->hw_ops->reset(tpg);
180 
181 		tpg->res->hw_ops->hw_version(tpg);
182 	} else {
183 		camss_disable_clocks(tpg->nclocks, tpg->clock);
184 
185 		pm_runtime_put_sync(dev);
186 	}
187 
188 	return 0;
189 }
190 
191 static int tpg_set_stream(struct v4l2_subdev *sd, int enable)
192 {
193 	struct tpg_device *tpg = v4l2_get_subdevdata(sd);
194 	int ret;
195 
196 	if (enable) {
197 		ret = v4l2_ctrl_handler_setup(&tpg->ctrls);
198 		if (ret < 0) {
199 			dev_err(tpg->camss->dev,
200 				"could not sync v4l2 controls: %d\n", ret);
201 			return ret;
202 		}
203 	}
204 
205 	return tpg->res->hw_ops->configure_stream(tpg, enable);
206 }
207 
208 static struct v4l2_mbus_framefmt *
209 __tpg_get_format(struct tpg_device *tpg,
210 		 struct v4l2_subdev_state *sd_state,
211 		 unsigned int pad,
212 		 enum v4l2_subdev_format_whence which)
213 {
214 	if (which == V4L2_SUBDEV_FORMAT_TRY)
215 		return v4l2_subdev_state_get_format(sd_state,
216 						    pad);
217 
218 	return &tpg->fmt;
219 }
220 
221 static void tpg_try_format(struct tpg_device *tpg,
222 			   struct v4l2_mbus_framefmt *fmt)
223 {
224 	unsigned int i;
225 
226 	for (i = 0; i < tpg->res->formats->nformats; i++)
227 		if (tpg->res->formats->formats[i].code == fmt->code)
228 			break;
229 
230 	if (i >= tpg->res->formats->nformats)
231 		fmt->code = MEDIA_BUS_FMT_SBGGR8_1X8;
232 
233 	fmt->width = clamp_t(u32, fmt->width, TPG_MIN_WIDTH, TPG_MAX_WIDTH);
234 	fmt->height = clamp_t(u32, fmt->height, TPG_MIN_HEIGHT, TPG_MAX_HEIGHT);
235 	fmt->field = V4L2_FIELD_NONE;
236 	fmt->colorspace = V4L2_COLORSPACE_SRGB;
237 }
238 
239 static int tpg_enum_mbus_code(struct v4l2_subdev *sd,
240 			      struct v4l2_subdev_state *sd_state,
241 			      struct v4l2_subdev_mbus_code_enum *code)
242 {
243 	struct tpg_device *tpg = v4l2_get_subdevdata(sd);
244 
245 	if (code->index >= tpg->res->formats->nformats)
246 		return -EINVAL;
247 
248 	code->code = tpg->res->formats->formats[code->index].code;
249 
250 	return 0;
251 }
252 
253 static int tpg_enum_frame_size(struct v4l2_subdev *sd,
254 			       struct v4l2_subdev_state *sd_state,
255 			       struct v4l2_subdev_frame_size_enum *fse)
256 {
257 	struct tpg_device *tpg = v4l2_get_subdevdata(sd);
258 	unsigned int i;
259 
260 	if (fse->index != 0)
261 		return -EINVAL;
262 
263 	for (i = 0; i < tpg->res->formats->nformats; i++)
264 		if (tpg->res->formats->formats[i].code == fse->code)
265 			break;
266 
267 	if (i >= tpg->res->formats->nformats)
268 		return -EINVAL;
269 
270 	fse->min_width = TPG_MIN_WIDTH;
271 	fse->min_height = TPG_MIN_HEIGHT;
272 	fse->max_width = TPG_MAX_WIDTH;
273 	fse->max_height = TPG_MAX_HEIGHT;
274 
275 	return 0;
276 }
277 
278 static int tpg_get_format(struct v4l2_subdev *sd,
279 			  struct v4l2_subdev_state *sd_state,
280 			  struct v4l2_subdev_format *fmt)
281 {
282 	struct tpg_device *tpg = v4l2_get_subdevdata(sd);
283 	struct v4l2_mbus_framefmt *format;
284 
285 	format = __tpg_get_format(tpg, sd_state, fmt->pad, fmt->which);
286 	if (!format)
287 		return -EINVAL;
288 
289 	fmt->format = *format;
290 
291 	return 0;
292 }
293 
294 static int tpg_set_format(struct v4l2_subdev *sd,
295 			  struct v4l2_subdev_state *sd_state,
296 			  struct v4l2_subdev_format *fmt)
297 {
298 	struct tpg_device *tpg = v4l2_get_subdevdata(sd);
299 	struct v4l2_mbus_framefmt *format;
300 
301 	format = __tpg_get_format(tpg, sd_state, fmt->pad, fmt->which);
302 	if (!format)
303 		return -EINVAL;
304 
305 	tpg_try_format(tpg, &fmt->format);
306 	*format = fmt->format;
307 
308 	return 0;
309 }
310 
311 static int tpg_init_formats(struct v4l2_subdev *sd,
312 			    struct v4l2_subdev_fh *fh)
313 {
314 	struct v4l2_subdev_format format = {
315 		.pad = MSM_TPG_PAD_SRC,
316 		.which = fh ? V4L2_SUBDEV_FORMAT_TRY :
317 			      V4L2_SUBDEV_FORMAT_ACTIVE,
318 		.format = {
319 			.code = MEDIA_BUS_FMT_SBGGR8_1X8,
320 			.width = 1920,
321 			.height = 1080,
322 		}
323 	};
324 
325 	return tpg_set_format(sd, fh ? fh->state : NULL, &format);
326 }
327 
328 static int tpg_s_ctrl(struct v4l2_ctrl *ctrl)
329 {
330 	struct tpg_device *tpg = container_of(ctrl->handler,
331 					      struct tpg_device, ctrls);
332 	int ret = -EINVAL;
333 
334 	switch (ctrl->id) {
335 	case V4L2_CID_TEST_PATTERN:
336 		ret = tpg->res->hw_ops->configure_testgen_pattern(tpg, ctrl->val);
337 		break;
338 	}
339 
340 	return ret;
341 }
342 
343 static const struct v4l2_ctrl_ops tpg_ctrl_ops = {
344 	.s_ctrl = tpg_s_ctrl,
345 };
346 
347 int msm_tpg_subdev_init(struct camss *camss,
348 			struct tpg_device *tpg,
349 			const struct camss_subdev_resources *res, u8 id)
350 {
351 	struct platform_device *pdev;
352 	struct device *dev;
353 	int i, j;
354 
355 	dev  = camss->dev;
356 	pdev = to_platform_device(dev);
357 
358 	tpg->camss = camss;
359 	tpg->id = id;
360 	tpg->res = &res->tpg;
361 	tpg->res->hw_ops->subdev_init(tpg);
362 
363 	tpg->base = devm_platform_ioremap_resource_byname(pdev, res->reg[0]);
364 	if (IS_ERR(tpg->base))
365 		return PTR_ERR(tpg->base);
366 
367 	tpg->nclocks = 0;
368 	while (res->clock[tpg->nclocks])
369 		tpg->nclocks++;
370 
371 	if (!tpg->nclocks)
372 		return 0;
373 
374 	tpg->clock = devm_kcalloc(dev, tpg->nclocks,
375 				  sizeof(*tpg->clock), GFP_KERNEL);
376 	if (!tpg->clock)
377 		return -ENOMEM;
378 
379 	for (i = 0; i < tpg->nclocks; i++) {
380 		struct camss_clock *clock = &tpg->clock[i];
381 
382 		clock->clk = devm_clk_get(dev, res->clock[i]);
383 		if (IS_ERR(clock->clk))
384 			return PTR_ERR(clock->clk);
385 
386 		clock->name = res->clock[i];
387 
388 		clock->nfreqs = 0;
389 		while (res->clock_rate[i][clock->nfreqs])
390 			clock->nfreqs++;
391 
392 		if (!clock->nfreqs) {
393 			clock->freq = NULL;
394 			continue;
395 		}
396 
397 		clock->freq = devm_kcalloc(dev, clock->nfreqs,
398 					   sizeof(*clock->freq), GFP_KERNEL);
399 		if (!clock->freq)
400 			return -ENOMEM;
401 
402 		for (j = 0; j < clock->nfreqs; j++)
403 			clock->freq[j] = res->clock_rate[i][j];
404 	}
405 
406 	return 0;
407 }
408 
409 static int tpg_link_setup(struct media_entity *entity,
410 			  const struct media_pad *local,
411 			  const struct media_pad *remote, u32 flags)
412 {
413 	if (flags & MEDIA_LNK_FL_ENABLED)
414 		if (media_pad_remote_pad_first(local))
415 			return -EBUSY;
416 
417 	return 0;
418 }
419 
420 static const struct v4l2_subdev_core_ops tpg_core_ops = {
421 	.s_power = tpg_set_power,
422 };
423 
424 static const struct v4l2_subdev_video_ops tpg_video_ops = {
425 	.s_stream = tpg_set_stream,
426 };
427 
428 static const struct v4l2_subdev_pad_ops tpg_pad_ops = {
429 	.enum_mbus_code = tpg_enum_mbus_code,
430 	.enum_frame_size = tpg_enum_frame_size,
431 	.get_fmt = tpg_get_format,
432 	.set_fmt = tpg_set_format,
433 };
434 
435 static const struct v4l2_subdev_ops tpg_v4l2_ops = {
436 	.core = &tpg_core_ops,
437 	.video = &tpg_video_ops,
438 	.pad = &tpg_pad_ops,
439 };
440 
441 static const struct v4l2_subdev_internal_ops tpg_v4l2_internal_ops = {
442 	.open = tpg_init_formats,
443 };
444 
445 static const struct media_entity_operations tpg_media_ops = {
446 	.link_setup = tpg_link_setup,
447 	.link_validate = v4l2_subdev_link_validate,
448 };
449 
450 int msm_tpg_register_entity(struct tpg_device *tpg,
451 			    struct v4l2_device *v4l2_dev)
452 {
453 	struct v4l2_subdev *sd = &tpg->subdev;
454 	struct device *dev = tpg->camss->dev;
455 	int ret;
456 
457 	v4l2_subdev_init(sd, &tpg_v4l2_ops);
458 	sd->internal_ops = &tpg_v4l2_internal_ops;
459 	sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE |
460 		     V4L2_SUBDEV_FL_HAS_EVENTS;
461 	snprintf(sd->name, ARRAY_SIZE(sd->name), "%s%d",
462 		 "msm_tpg", tpg->id);
463 	sd->grp_id = TPG_GRP_ID;
464 	v4l2_set_subdevdata(sd, tpg);
465 
466 	ret = v4l2_ctrl_handler_init(&tpg->ctrls, 1);
467 	if (ret < 0) {
468 		dev_err(dev, "Failed to init ctrl handler: %d\n", ret);
469 		return ret;
470 	}
471 
472 	tpg->testgen_mode = v4l2_ctrl_new_std_menu_items(&tpg->ctrls,
473 							 &tpg_ctrl_ops, V4L2_CID_TEST_PATTERN,
474 							 tpg->testgen.nmodes, 0, 0,
475 							 tpg->testgen.modes);
476 	if (tpg->ctrls.error) {
477 		dev_err(dev, "Failed to init ctrl: %d\n", tpg->ctrls.error);
478 		ret = tpg->ctrls.error;
479 		goto free_ctrl;
480 	}
481 
482 	tpg->subdev.ctrl_handler = &tpg->ctrls;
483 
484 	ret = tpg_init_formats(sd, NULL);
485 	if (ret < 0) {
486 		dev_err(dev, "Failed to init format: %d\n", ret);
487 		goto free_ctrl;
488 	}
489 
490 	tpg->pad.flags = MEDIA_PAD_FL_SOURCE;
491 
492 	sd->entity.ops = &tpg_media_ops;
493 	ret = media_entity_pads_init(&sd->entity, 1, &tpg->pad);
494 	if (ret < 0) {
495 		dev_err(dev, "Failed to init media entity: %d\n", ret);
496 		goto free_ctrl;
497 	}
498 
499 	ret = v4l2_device_register_subdev(v4l2_dev, sd);
500 	if (ret < 0) {
501 		dev_err(dev, "Failed to register subdev: %d\n", ret);
502 		media_entity_cleanup(&sd->entity);
503 		goto free_ctrl;
504 	}
505 
506 	return 0;
507 
508 free_ctrl:
509 	v4l2_ctrl_handler_free(&tpg->ctrls);
510 
511 	return ret;
512 }
513 
514 void msm_tpg_unregister_entity(struct tpg_device *tpg)
515 {
516 	v4l2_device_unregister_subdev(&tpg->subdev);
517 	media_entity_cleanup(&tpg->subdev.entity);
518 	v4l2_ctrl_handler_free(&tpg->ctrls);
519 }
520