1 // SPDX-License-Identifier: GPL-2.0
5 * Qualcomm MSM Camera Subsystem - CSID (CSI Decoder) Module
7 * Copyright (c) 2011-2015, The Linux Foundation. All rights reserved.
8 * Copyright (C) 2015-2018 Linaro Ltd.
10 #include <linux/clk.h>
11 #include <linux/completion.h>
12 #include <linux/interrupt.h>
14 #include <linux/kernel.h>
16 #include <linux/platform_device.h>
17 #include <linux/pm_runtime.h>
18 #include <linux/regulator/consumer.h>
19 #include <media/media-entity.h>
20 #include <media/v4l2-device.h>
21 #include <media/v4l2-event.h>
22 #include <media/v4l2-subdev.h>
24 #include "camss-csid.h"
25 #include "camss-csid-gen1.h"
28 /* offset of CSID registers in VFE region for VFE 480 */
29 #define VFE_480_CSID_OFFSET 0x1200
30 #define VFE_480_LITE_CSID_OFFSET 0x200
32 #define MSM_CSID_NAME "msm_csid"
34 const char * const csid_testgen_modes
[] = {
37 "Alternating 0x55/0xAA",
48 static const struct csid_format_info formats_4_1
[] = {
50 MEDIA_BUS_FMT_UYVY8_1X16
,
51 DATA_TYPE_YUV422_8BIT
,
52 DECODE_FORMAT_UNCOMPRESSED_8_BIT
,
57 MEDIA_BUS_FMT_VYUY8_1X16
,
58 DATA_TYPE_YUV422_8BIT
,
59 DECODE_FORMAT_UNCOMPRESSED_8_BIT
,
64 MEDIA_BUS_FMT_YUYV8_1X16
,
65 DATA_TYPE_YUV422_8BIT
,
66 DECODE_FORMAT_UNCOMPRESSED_8_BIT
,
71 MEDIA_BUS_FMT_YVYU8_1X16
,
72 DATA_TYPE_YUV422_8BIT
,
73 DECODE_FORMAT_UNCOMPRESSED_8_BIT
,
78 MEDIA_BUS_FMT_SBGGR8_1X8
,
80 DECODE_FORMAT_UNCOMPRESSED_8_BIT
,
85 MEDIA_BUS_FMT_SGBRG8_1X8
,
87 DECODE_FORMAT_UNCOMPRESSED_8_BIT
,
92 MEDIA_BUS_FMT_SGRBG8_1X8
,
94 DECODE_FORMAT_UNCOMPRESSED_8_BIT
,
99 MEDIA_BUS_FMT_SRGGB8_1X8
,
101 DECODE_FORMAT_UNCOMPRESSED_8_BIT
,
106 MEDIA_BUS_FMT_SBGGR10_1X10
,
108 DECODE_FORMAT_UNCOMPRESSED_10_BIT
,
113 MEDIA_BUS_FMT_SGBRG10_1X10
,
115 DECODE_FORMAT_UNCOMPRESSED_10_BIT
,
120 MEDIA_BUS_FMT_SGRBG10_1X10
,
122 DECODE_FORMAT_UNCOMPRESSED_10_BIT
,
127 MEDIA_BUS_FMT_SRGGB10_1X10
,
129 DECODE_FORMAT_UNCOMPRESSED_10_BIT
,
134 MEDIA_BUS_FMT_SBGGR12_1X12
,
136 DECODE_FORMAT_UNCOMPRESSED_12_BIT
,
141 MEDIA_BUS_FMT_SGBRG12_1X12
,
143 DECODE_FORMAT_UNCOMPRESSED_12_BIT
,
148 MEDIA_BUS_FMT_SGRBG12_1X12
,
150 DECODE_FORMAT_UNCOMPRESSED_12_BIT
,
155 MEDIA_BUS_FMT_SRGGB12_1X12
,
157 DECODE_FORMAT_UNCOMPRESSED_12_BIT
,
162 MEDIA_BUS_FMT_Y10_1X10
,
164 DECODE_FORMAT_UNCOMPRESSED_10_BIT
,
170 static const struct csid_format_info formats_4_7
[] = {
172 MEDIA_BUS_FMT_UYVY8_1X16
,
173 DATA_TYPE_YUV422_8BIT
,
174 DECODE_FORMAT_UNCOMPRESSED_8_BIT
,
179 MEDIA_BUS_FMT_VYUY8_1X16
,
180 DATA_TYPE_YUV422_8BIT
,
181 DECODE_FORMAT_UNCOMPRESSED_8_BIT
,
186 MEDIA_BUS_FMT_YUYV8_1X16
,
187 DATA_TYPE_YUV422_8BIT
,
188 DECODE_FORMAT_UNCOMPRESSED_8_BIT
,
193 MEDIA_BUS_FMT_YVYU8_1X16
,
194 DATA_TYPE_YUV422_8BIT
,
195 DECODE_FORMAT_UNCOMPRESSED_8_BIT
,
200 MEDIA_BUS_FMT_SBGGR8_1X8
,
202 DECODE_FORMAT_UNCOMPRESSED_8_BIT
,
207 MEDIA_BUS_FMT_SGBRG8_1X8
,
209 DECODE_FORMAT_UNCOMPRESSED_8_BIT
,
214 MEDIA_BUS_FMT_SGRBG8_1X8
,
216 DECODE_FORMAT_UNCOMPRESSED_8_BIT
,
221 MEDIA_BUS_FMT_SRGGB8_1X8
,
223 DECODE_FORMAT_UNCOMPRESSED_8_BIT
,
228 MEDIA_BUS_FMT_SBGGR10_1X10
,
230 DECODE_FORMAT_UNCOMPRESSED_10_BIT
,
235 MEDIA_BUS_FMT_SGBRG10_1X10
,
237 DECODE_FORMAT_UNCOMPRESSED_10_BIT
,
242 MEDIA_BUS_FMT_SGRBG10_1X10
,
244 DECODE_FORMAT_UNCOMPRESSED_10_BIT
,
249 MEDIA_BUS_FMT_SRGGB10_1X10
,
251 DECODE_FORMAT_UNCOMPRESSED_10_BIT
,
256 MEDIA_BUS_FMT_SBGGR12_1X12
,
258 DECODE_FORMAT_UNCOMPRESSED_12_BIT
,
263 MEDIA_BUS_FMT_SGBRG12_1X12
,
265 DECODE_FORMAT_UNCOMPRESSED_12_BIT
,
270 MEDIA_BUS_FMT_SGRBG12_1X12
,
272 DECODE_FORMAT_UNCOMPRESSED_12_BIT
,
277 MEDIA_BUS_FMT_SRGGB12_1X12
,
279 DECODE_FORMAT_UNCOMPRESSED_12_BIT
,
284 MEDIA_BUS_FMT_SBGGR14_1X14
,
286 DECODE_FORMAT_UNCOMPRESSED_14_BIT
,
291 MEDIA_BUS_FMT_SGBRG14_1X14
,
293 DECODE_FORMAT_UNCOMPRESSED_14_BIT
,
298 MEDIA_BUS_FMT_SGRBG14_1X14
,
300 DECODE_FORMAT_UNCOMPRESSED_14_BIT
,
305 MEDIA_BUS_FMT_SRGGB14_1X14
,
307 DECODE_FORMAT_UNCOMPRESSED_14_BIT
,
312 MEDIA_BUS_FMT_Y10_1X10
,
314 DECODE_FORMAT_UNCOMPRESSED_10_BIT
,
320 static const struct csid_format_info formats_gen2
[] = {
322 MEDIA_BUS_FMT_UYVY8_1X16
,
323 DATA_TYPE_YUV422_8BIT
,
324 DECODE_FORMAT_UNCOMPRESSED_8_BIT
,
329 MEDIA_BUS_FMT_VYUY8_1X16
,
330 DATA_TYPE_YUV422_8BIT
,
331 DECODE_FORMAT_UNCOMPRESSED_8_BIT
,
336 MEDIA_BUS_FMT_YUYV8_1X16
,
337 DATA_TYPE_YUV422_8BIT
,
338 DECODE_FORMAT_UNCOMPRESSED_8_BIT
,
343 MEDIA_BUS_FMT_YVYU8_1X16
,
344 DATA_TYPE_YUV422_8BIT
,
345 DECODE_FORMAT_UNCOMPRESSED_8_BIT
,
350 MEDIA_BUS_FMT_SBGGR8_1X8
,
352 DECODE_FORMAT_UNCOMPRESSED_8_BIT
,
357 MEDIA_BUS_FMT_SGBRG8_1X8
,
359 DECODE_FORMAT_UNCOMPRESSED_8_BIT
,
364 MEDIA_BUS_FMT_SGRBG8_1X8
,
366 DECODE_FORMAT_UNCOMPRESSED_8_BIT
,
371 MEDIA_BUS_FMT_SRGGB8_1X8
,
373 DECODE_FORMAT_UNCOMPRESSED_8_BIT
,
378 MEDIA_BUS_FMT_SBGGR10_1X10
,
380 DECODE_FORMAT_UNCOMPRESSED_10_BIT
,
385 MEDIA_BUS_FMT_SGBRG10_1X10
,
387 DECODE_FORMAT_UNCOMPRESSED_10_BIT
,
392 MEDIA_BUS_FMT_SGRBG10_1X10
,
394 DECODE_FORMAT_UNCOMPRESSED_10_BIT
,
399 MEDIA_BUS_FMT_SRGGB10_1X10
,
401 DECODE_FORMAT_UNCOMPRESSED_10_BIT
,
406 MEDIA_BUS_FMT_Y8_1X8
,
408 DECODE_FORMAT_UNCOMPRESSED_8_BIT
,
413 MEDIA_BUS_FMT_Y10_1X10
,
415 DECODE_FORMAT_UNCOMPRESSED_10_BIT
,
420 MEDIA_BUS_FMT_SBGGR12_1X12
,
422 DECODE_FORMAT_UNCOMPRESSED_12_BIT
,
427 MEDIA_BUS_FMT_SGBRG12_1X12
,
429 DECODE_FORMAT_UNCOMPRESSED_12_BIT
,
434 MEDIA_BUS_FMT_SGRBG12_1X12
,
436 DECODE_FORMAT_UNCOMPRESSED_12_BIT
,
441 MEDIA_BUS_FMT_SRGGB12_1X12
,
443 DECODE_FORMAT_UNCOMPRESSED_12_BIT
,
448 MEDIA_BUS_FMT_SBGGR14_1X14
,
450 DECODE_FORMAT_UNCOMPRESSED_14_BIT
,
455 MEDIA_BUS_FMT_SGBRG14_1X14
,
457 DECODE_FORMAT_UNCOMPRESSED_14_BIT
,
462 MEDIA_BUS_FMT_SGRBG14_1X14
,
464 DECODE_FORMAT_UNCOMPRESSED_14_BIT
,
469 MEDIA_BUS_FMT_SRGGB14_1X14
,
471 DECODE_FORMAT_UNCOMPRESSED_14_BIT
,
477 const struct csid_formats csid_formats_4_1
= {
478 .nformats
= ARRAY_SIZE(formats_4_1
),
479 .formats
= formats_4_1
482 const struct csid_formats csid_formats_4_7
= {
483 .nformats
= ARRAY_SIZE(formats_4_7
),
484 .formats
= formats_4_7
487 const struct csid_formats csid_formats_gen2
= {
488 .nformats
= ARRAY_SIZE(formats_gen2
),
489 .formats
= formats_gen2
492 u32
csid_find_code(u32
*codes
, unsigned int ncodes
,
493 unsigned int match_format_idx
, u32 match_code
)
497 if (!match_code
&& (match_format_idx
>= ncodes
))
500 for (i
= 0; i
< ncodes
; i
++)
502 if (codes
[i
] == match_code
)
505 if (i
== match_format_idx
)
512 const struct csid_format_info
*csid_get_fmt_entry(const struct csid_format_info
*formats
,
513 unsigned int nformats
,
518 for (i
= 0; i
< nformats
; i
++)
519 if (code
== formats
[i
].code
)
522 WARN(1, "Unknown format\n");
528 * csid_set_clock_rates - Calculate and set clock rates on CSID module
529 * @csiphy: CSID device
531 static int csid_set_clock_rates(struct csid_device
*csid
)
533 struct device
*dev
= csid
->camss
->dev
;
534 const struct csid_format_info
*fmt
;
539 fmt
= csid_get_fmt_entry(csid
->res
->formats
->formats
, csid
->res
->formats
->nformats
,
540 csid
->fmt
[MSM_CSIPHY_PAD_SINK
].code
);
541 link_freq
= camss_get_link_freq(&csid
->subdev
.entity
, fmt
->bpp
,
546 for (i
= 0; i
< csid
->nclocks
; i
++) {
547 struct camss_clock
*clock
= &csid
->clock
[i
];
549 if (!strcmp(clock
->name
, "csi0") ||
550 !strcmp(clock
->name
, "csi1") ||
551 !strcmp(clock
->name
, "csi2") ||
552 !strcmp(clock
->name
, "csi3")) {
553 u64 min_rate
= link_freq
/ 4;
556 camss_add_clock_margin(&min_rate
);
558 for (j
= 0; j
< clock
->nfreqs
; j
++)
559 if (min_rate
< clock
->freq
[j
])
562 if (j
== clock
->nfreqs
) {
564 "Pixel clock is too high for CSID\n");
568 /* if sensor pixel clock is not available */
569 /* set highest possible CSID clock rate */
571 j
= clock
->nfreqs
- 1;
573 rate
= clk_round_rate(clock
->clk
, clock
->freq
[j
]);
575 dev_err(dev
, "clk round rate failed: %ld\n",
580 ret
= clk_set_rate(clock
->clk
, rate
);
582 dev_err(dev
, "clk set rate failed: %d\n", ret
);
585 } else if (clock
->nfreqs
) {
586 clk_set_rate(clock
->clk
, clock
->freq
[0]);
594 * csid_set_power - Power on/off CSID module
595 * @sd: CSID V4L2 subdevice
596 * @on: Requested power state
598 * Return 0 on success or a negative error code otherwise
600 static int csid_set_power(struct v4l2_subdev
*sd
, int on
)
602 struct csid_device
*csid
= v4l2_get_subdevdata(sd
);
603 struct camss
*camss
= csid
->camss
;
604 struct device
*dev
= camss
->dev
;
609 * From SDM845 onwards, the VFE needs to be powered on before
610 * switching on the CSID. Do so unconditionally, as there is no
611 * drawback in following the same powering order on older SoCs.
613 ret
= csid
->res
->parent_dev_ops
->get(camss
, csid
->id
);
617 ret
= pm_runtime_resume_and_get(dev
);
621 ret
= regulator_bulk_enable(csid
->num_supplies
,
624 pm_runtime_put_sync(dev
);
628 ret
= csid_set_clock_rates(csid
);
630 regulator_bulk_disable(csid
->num_supplies
,
632 pm_runtime_put_sync(dev
);
636 ret
= camss_enable_clocks(csid
->nclocks
, csid
->clock
, dev
);
638 regulator_bulk_disable(csid
->num_supplies
,
640 pm_runtime_put_sync(dev
);
644 csid
->phy
.need_vc_update
= true;
646 enable_irq(csid
->irq
);
648 ret
= csid
->res
->hw_ops
->reset(csid
);
650 disable_irq(csid
->irq
);
651 camss_disable_clocks(csid
->nclocks
, csid
->clock
);
652 regulator_bulk_disable(csid
->num_supplies
,
654 pm_runtime_put_sync(dev
);
658 csid
->res
->hw_ops
->hw_version(csid
);
660 disable_irq(csid
->irq
);
661 camss_disable_clocks(csid
->nclocks
, csid
->clock
);
662 regulator_bulk_disable(csid
->num_supplies
,
664 pm_runtime_put_sync(dev
);
665 csid
->res
->parent_dev_ops
->put(camss
, csid
->id
);
672 * csid_set_stream - Enable/disable streaming on CSID module
673 * @sd: CSID V4L2 subdevice
674 * @enable: Requested streaming state
676 * Main configuration of CSID module is also done here.
678 * Return 0 on success or a negative error code otherwise
680 static int csid_set_stream(struct v4l2_subdev
*sd
, int enable
)
682 struct csid_device
*csid
= v4l2_get_subdevdata(sd
);
686 ret
= v4l2_ctrl_handler_setup(&csid
->ctrls
);
688 dev_err(csid
->camss
->dev
,
689 "could not sync v4l2 controls: %d\n", ret
);
693 if (!csid
->testgen
.enabled
&&
694 !media_pad_remote_pad_first(&csid
->pads
[MSM_CSID_PAD_SINK
]))
698 if (csid
->phy
.need_vc_update
) {
699 csid
->res
->hw_ops
->configure_stream(csid
, enable
);
700 csid
->phy
.need_vc_update
= false;
707 * __csid_get_format - Get pointer to format structure
709 * @sd_state: V4L2 subdev state
710 * @pad: pad from which format is requested
711 * @which: TRY or ACTIVE format
713 * Return pointer to TRY or ACTIVE format structure
715 static struct v4l2_mbus_framefmt
*
716 __csid_get_format(struct csid_device
*csid
,
717 struct v4l2_subdev_state
*sd_state
,
719 enum v4l2_subdev_format_whence which
)
721 if (which
== V4L2_SUBDEV_FORMAT_TRY
)
722 return v4l2_subdev_state_get_format(sd_state
, pad
);
724 return &csid
->fmt
[pad
];
728 * csid_try_format - Handle try format by pad subdev method
730 * @sd_state: V4L2 subdev state
731 * @pad: pad on which format is requested
732 * @fmt: pointer to v4l2 format structure
733 * @which: wanted subdev format
735 static void csid_try_format(struct csid_device
*csid
,
736 struct v4l2_subdev_state
*sd_state
,
738 struct v4l2_mbus_framefmt
*fmt
,
739 enum v4l2_subdev_format_whence which
)
744 case MSM_CSID_PAD_SINK
:
745 /* Set format on sink pad */
747 for (i
= 0; i
< csid
->res
->formats
->nformats
; i
++)
748 if (fmt
->code
== csid
->res
->formats
->formats
[i
].code
)
751 /* If not found, use UYVY as default */
752 if (i
>= csid
->res
->formats
->nformats
)
753 fmt
->code
= MEDIA_BUS_FMT_UYVY8_1X16
;
755 fmt
->width
= clamp_t(u32
, fmt
->width
, 1, 8191);
756 fmt
->height
= clamp_t(u32
, fmt
->height
, 1, 8191);
758 fmt
->field
= V4L2_FIELD_NONE
;
759 fmt
->colorspace
= V4L2_COLORSPACE_SRGB
;
763 case MSM_CSID_PAD_SRC
:
764 if (csid
->testgen_mode
->cur
.val
== 0) {
765 /* Test generator is disabled, */
766 /* keep pad formats in sync */
767 u32 code
= fmt
->code
;
769 *fmt
= *__csid_get_format(csid
, sd_state
,
770 MSM_CSID_PAD_SINK
, which
);
771 fmt
->code
= csid
->res
->hw_ops
->src_pad_code(csid
, fmt
->code
, 0, code
);
773 /* Test generator is enabled, set format on source */
774 /* pad to allow test generator usage */
776 for (i
= 0; i
< csid
->res
->formats
->nformats
; i
++)
777 if (csid
->res
->formats
->formats
[i
].code
== fmt
->code
)
780 /* If not found, use UYVY as default */
781 if (i
>= csid
->res
->formats
->nformats
)
782 fmt
->code
= MEDIA_BUS_FMT_UYVY8_1X16
;
784 fmt
->width
= clamp_t(u32
, fmt
->width
, 1, 8191);
785 fmt
->height
= clamp_t(u32
, fmt
->height
, 1, 8191);
787 fmt
->field
= V4L2_FIELD_NONE
;
792 fmt
->colorspace
= V4L2_COLORSPACE_SRGB
;
796 * csid_enum_mbus_code - Handle pixel format enumeration
797 * @sd: CSID V4L2 subdevice
798 * @sd_state: V4L2 subdev state
799 * @code: pointer to v4l2_subdev_mbus_code_enum structure
800 * return -EINVAL or zero on success
802 static int csid_enum_mbus_code(struct v4l2_subdev
*sd
,
803 struct v4l2_subdev_state
*sd_state
,
804 struct v4l2_subdev_mbus_code_enum
*code
)
806 struct csid_device
*csid
= v4l2_get_subdevdata(sd
);
808 if (code
->pad
== MSM_CSID_PAD_SINK
) {
809 if (code
->index
>= csid
->res
->formats
->nformats
)
812 code
->code
= csid
->res
->formats
->formats
[code
->index
].code
;
814 if (csid
->testgen_mode
->cur
.val
== 0) {
815 struct v4l2_mbus_framefmt
*sink_fmt
;
817 sink_fmt
= __csid_get_format(csid
, sd_state
,
821 code
->code
= csid
->res
->hw_ops
->src_pad_code(csid
, sink_fmt
->code
,
826 if (code
->index
>= csid
->res
->formats
->nformats
)
829 code
->code
= csid
->res
->formats
->formats
[code
->index
].code
;
837 * csid_enum_frame_size - Handle frame size enumeration
838 * @sd: CSID V4L2 subdevice
839 * @sd_state: V4L2 subdev state
840 * @fse: pointer to v4l2_subdev_frame_size_enum structure
841 * return -EINVAL or zero on success
843 static int csid_enum_frame_size(struct v4l2_subdev
*sd
,
844 struct v4l2_subdev_state
*sd_state
,
845 struct v4l2_subdev_frame_size_enum
*fse
)
847 struct csid_device
*csid
= v4l2_get_subdevdata(sd
);
848 struct v4l2_mbus_framefmt format
;
853 format
.code
= fse
->code
;
856 csid_try_format(csid
, sd_state
, fse
->pad
, &format
, fse
->which
);
857 fse
->min_width
= format
.width
;
858 fse
->min_height
= format
.height
;
860 if (format
.code
!= fse
->code
)
863 format
.code
= fse
->code
;
866 csid_try_format(csid
, sd_state
, fse
->pad
, &format
, fse
->which
);
867 fse
->max_width
= format
.width
;
868 fse
->max_height
= format
.height
;
874 * csid_get_format - Handle get format by pads subdev method
875 * @sd: CSID V4L2 subdevice
876 * @sd_state: V4L2 subdev state
877 * @fmt: pointer to v4l2 subdev format structure
879 * Return -EINVAL or zero on success
881 static int csid_get_format(struct v4l2_subdev
*sd
,
882 struct v4l2_subdev_state
*sd_state
,
883 struct v4l2_subdev_format
*fmt
)
885 struct csid_device
*csid
= v4l2_get_subdevdata(sd
);
886 struct v4l2_mbus_framefmt
*format
;
888 format
= __csid_get_format(csid
, sd_state
, fmt
->pad
, fmt
->which
);
892 fmt
->format
= *format
;
898 * csid_set_format - Handle set format by pads subdev method
899 * @sd: CSID V4L2 subdevice
900 * @sd_state: V4L2 subdev state
901 * @fmt: pointer to v4l2 subdev format structure
903 * Return -EINVAL or zero on success
905 static int csid_set_format(struct v4l2_subdev
*sd
,
906 struct v4l2_subdev_state
*sd_state
,
907 struct v4l2_subdev_format
*fmt
)
909 struct csid_device
*csid
= v4l2_get_subdevdata(sd
);
910 struct v4l2_mbus_framefmt
*format
;
913 format
= __csid_get_format(csid
, sd_state
, fmt
->pad
, fmt
->which
);
917 csid_try_format(csid
, sd_state
, fmt
->pad
, &fmt
->format
, fmt
->which
);
918 *format
= fmt
->format
;
920 /* Propagate the format from sink to source pads */
921 if (fmt
->pad
== MSM_CSID_PAD_SINK
) {
922 for (i
= MSM_CSID_PAD_FIRST_SRC
; i
< MSM_CSID_PADS_NUM
; ++i
) {
923 format
= __csid_get_format(csid
, sd_state
, i
, fmt
->which
);
925 *format
= fmt
->format
;
926 csid_try_format(csid
, sd_state
, i
, format
, fmt
->which
);
934 * csid_init_formats - Initialize formats on all pads
935 * @sd: CSID V4L2 subdevice
936 * @fh: V4L2 subdev file handle
938 * Initialize all pad formats with default values.
940 * Return 0 on success or a negative error code otherwise
942 static int csid_init_formats(struct v4l2_subdev
*sd
, struct v4l2_subdev_fh
*fh
)
944 struct v4l2_subdev_format format
= {
945 .pad
= MSM_CSID_PAD_SINK
,
946 .which
= fh
? V4L2_SUBDEV_FORMAT_TRY
:
947 V4L2_SUBDEV_FORMAT_ACTIVE
,
949 .code
= MEDIA_BUS_FMT_UYVY8_1X16
,
955 return csid_set_format(sd
, fh
? fh
->state
: NULL
, &format
);
959 * csid_set_test_pattern - Set test generator's pattern mode
961 * @value: desired test pattern mode
963 * Return 0 on success or a negative error code otherwise
965 static int csid_set_test_pattern(struct csid_device
*csid
, s32 value
)
967 struct csid_testgen_config
*tg
= &csid
->testgen
;
969 /* If CSID is linked to CSIPHY, do not allow to enable test generator */
970 if (value
&& media_pad_remote_pad_first(&csid
->pads
[MSM_CSID_PAD_SINK
]))
973 tg
->enabled
= !!value
;
975 return csid
->res
->hw_ops
->configure_testgen_pattern(csid
, value
);
979 * csid_s_ctrl - Handle set control subdev method
980 * @ctrl: pointer to v4l2 control structure
982 * Return 0 on success or a negative error code otherwise
984 static int csid_s_ctrl(struct v4l2_ctrl
*ctrl
)
986 struct csid_device
*csid
= container_of(ctrl
->handler
,
987 struct csid_device
, ctrls
);
991 case V4L2_CID_TEST_PATTERN
:
992 ret
= csid_set_test_pattern(csid
, ctrl
->val
);
999 static const struct v4l2_ctrl_ops csid_ctrl_ops
= {
1000 .s_ctrl
= csid_s_ctrl
,
1004 * msm_csid_subdev_init - Initialize CSID device structure and resources
1005 * @csid: CSID device
1006 * @res: CSID module resources table
1007 * @id: CSID module id
1009 * Return 0 on success or a negative error code otherwise
1011 int msm_csid_subdev_init(struct camss
*camss
, struct csid_device
*csid
,
1012 const struct camss_subdev_resources
*res
, u8 id
)
1014 struct device
*dev
= camss
->dev
;
1015 struct platform_device
*pdev
= to_platform_device(dev
);
1019 csid
->camss
= camss
;
1021 csid
->res
= &res
->csid
;
1023 if (dev_WARN_ONCE(dev
, !csid
->res
->parent_dev_ops
,
1024 "Error: CSID depends on VFE/IFE device ops!\n")) {
1028 csid
->res
->hw_ops
->subdev_init(csid
);
1032 if (camss
->res
->version
== CAMSS_8250
) {
1033 /* for titan 480, CSID registers are inside the VFE region,
1034 * between the VFE "top" and "bus" registers. this requires
1035 * VFE to be initialized before CSID
1037 if (id
>= 2) /* VFE/CSID lite */
1038 csid
->base
= csid
->res
->parent_dev_ops
->get_base_address(camss
, id
)
1039 + VFE_480_LITE_CSID_OFFSET
;
1041 csid
->base
= csid
->res
->parent_dev_ops
->get_base_address(camss
, id
)
1042 + VFE_480_CSID_OFFSET
;
1044 csid
->base
= devm_platform_ioremap_resource_byname(pdev
, res
->reg
[0]);
1045 if (IS_ERR(csid
->base
))
1046 return PTR_ERR(csid
->base
);
1051 ret
= platform_get_irq_byname(pdev
, res
->interrupt
[0]);
1056 snprintf(csid
->irq_name
, sizeof(csid
->irq_name
), "%s_%s%d",
1057 dev_name(dev
), MSM_CSID_NAME
, csid
->id
);
1058 ret
= devm_request_irq(dev
, csid
->irq
, csid
->res
->hw_ops
->isr
,
1059 IRQF_TRIGGER_RISING
| IRQF_NO_AUTOEN
,
1060 csid
->irq_name
, csid
);
1062 dev_err(dev
, "request_irq failed: %d\n", ret
);
1069 while (res
->clock
[csid
->nclocks
])
1072 csid
->clock
= devm_kcalloc(dev
, csid
->nclocks
, sizeof(*csid
->clock
),
1077 for (i
= 0; i
< csid
->nclocks
; i
++) {
1078 struct camss_clock
*clock
= &csid
->clock
[i
];
1080 clock
->clk
= devm_clk_get(dev
, res
->clock
[i
]);
1081 if (IS_ERR(clock
->clk
))
1082 return PTR_ERR(clock
->clk
);
1084 clock
->name
= res
->clock
[i
];
1087 while (res
->clock_rate
[i
][clock
->nfreqs
])
1090 if (!clock
->nfreqs
) {
1095 clock
->freq
= devm_kcalloc(dev
,
1097 sizeof(*clock
->freq
),
1102 for (j
= 0; j
< clock
->nfreqs
; j
++)
1103 clock
->freq
[j
] = res
->clock_rate
[i
][j
];
1107 for (i
= 0; i
< ARRAY_SIZE(res
->regulators
); i
++) {
1108 if (res
->regulators
[i
])
1109 csid
->num_supplies
++;
1112 if (csid
->num_supplies
) {
1113 csid
->supplies
= devm_kmalloc_array(camss
->dev
,
1115 sizeof(*csid
->supplies
),
1117 if (!csid
->supplies
)
1121 for (i
= 0; i
< csid
->num_supplies
; i
++)
1122 csid
->supplies
[i
].supply
= res
->regulators
[i
];
1124 ret
= devm_regulator_bulk_get(camss
->dev
, csid
->num_supplies
,
1129 init_completion(&csid
->reset_complete
);
1135 * msm_csid_get_csid_id - Get CSID HW module id
1136 * @entity: Pointer to CSID media entity structure
1137 * @id: Return CSID HW module id here
1139 void msm_csid_get_csid_id(struct media_entity
*entity
, u8
*id
)
1141 struct v4l2_subdev
*sd
= media_entity_to_v4l2_subdev(entity
);
1142 struct csid_device
*csid
= v4l2_get_subdevdata(sd
);
1148 * csid_get_lane_assign - Calculate CSI2 lane assign configuration parameter
1149 * @lane_cfg - CSI2 lane configuration
1151 * Return lane assign
1153 static u32
csid_get_lane_assign(struct csiphy_lanes_cfg
*lane_cfg
)
1155 u32 lane_assign
= 0;
1158 for (i
= 0; i
< lane_cfg
->num_data
; i
++)
1159 lane_assign
|= lane_cfg
->data
[i
].pos
<< (i
* 4);
1165 * csid_link_setup - Setup CSID connections
1166 * @entity: Pointer to media entity structure
1167 * @local: Pointer to local pad
1168 * @remote: Pointer to remote pad
1169 * @flags: Link flags
1171 * Return 0 on success
1173 static int csid_link_setup(struct media_entity
*entity
,
1174 const struct media_pad
*local
,
1175 const struct media_pad
*remote
, u32 flags
)
1177 if (flags
& MEDIA_LNK_FL_ENABLED
)
1178 if (media_pad_remote_pad_first(local
))
1181 if ((local
->flags
& MEDIA_PAD_FL_SINK
) &&
1182 (flags
& MEDIA_LNK_FL_ENABLED
)) {
1183 struct v4l2_subdev
*sd
;
1184 struct csid_device
*csid
;
1185 struct csiphy_device
*csiphy
;
1186 struct csiphy_lanes_cfg
*lane_cfg
;
1188 sd
= media_entity_to_v4l2_subdev(entity
);
1189 csid
= v4l2_get_subdevdata(sd
);
1191 /* If test generator is enabled */
1192 /* do not allow a link from CSIPHY to CSID */
1193 if (csid
->testgen_mode
->cur
.val
!= 0)
1196 sd
= media_entity_to_v4l2_subdev(remote
->entity
);
1197 csiphy
= v4l2_get_subdevdata(sd
);
1199 /* If a sensor is not linked to CSIPHY */
1200 /* do no allow a link from CSIPHY to CSID */
1201 if (!csiphy
->cfg
.csi2
)
1204 csid
->phy
.csiphy_id
= csiphy
->id
;
1206 lane_cfg
= &csiphy
->cfg
.csi2
->lane_cfg
;
1207 csid
->phy
.lane_cnt
= lane_cfg
->num_data
;
1208 csid
->phy
.lane_assign
= csid_get_lane_assign(lane_cfg
);
1210 /* Decide which virtual channels to enable based on which source pads are enabled */
1211 if (local
->flags
& MEDIA_PAD_FL_SOURCE
) {
1212 struct v4l2_subdev
*sd
= media_entity_to_v4l2_subdev(entity
);
1213 struct csid_device
*csid
= v4l2_get_subdevdata(sd
);
1214 struct device
*dev
= csid
->camss
->dev
;
1216 if (flags
& MEDIA_LNK_FL_ENABLED
)
1217 csid
->phy
.en_vc
|= BIT(local
->index
- 1);
1219 csid
->phy
.en_vc
&= ~BIT(local
->index
- 1);
1221 csid
->phy
.need_vc_update
= true;
1223 dev_dbg(dev
, "%s: Enabled CSID virtual channels mask 0x%x\n",
1224 __func__
, csid
->phy
.en_vc
);
1230 static const struct v4l2_subdev_core_ops csid_core_ops
= {
1231 .s_power
= csid_set_power
,
1232 .subscribe_event
= v4l2_ctrl_subdev_subscribe_event
,
1233 .unsubscribe_event
= v4l2_event_subdev_unsubscribe
,
1236 static const struct v4l2_subdev_video_ops csid_video_ops
= {
1237 .s_stream
= csid_set_stream
,
1240 static const struct v4l2_subdev_pad_ops csid_pad_ops
= {
1241 .enum_mbus_code
= csid_enum_mbus_code
,
1242 .enum_frame_size
= csid_enum_frame_size
,
1243 .get_fmt
= csid_get_format
,
1244 .set_fmt
= csid_set_format
,
1247 static const struct v4l2_subdev_ops csid_v4l2_ops
= {
1248 .core
= &csid_core_ops
,
1249 .video
= &csid_video_ops
,
1250 .pad
= &csid_pad_ops
,
1253 static const struct v4l2_subdev_internal_ops csid_v4l2_internal_ops
= {
1254 .open
= csid_init_formats
,
1257 static const struct media_entity_operations csid_media_ops
= {
1258 .link_setup
= csid_link_setup
,
1259 .link_validate
= v4l2_subdev_link_validate
,
1263 * msm_csid_register_entity - Register subdev node for CSID module
1264 * @csid: CSID device
1265 * @v4l2_dev: V4L2 device
1267 * Return 0 on success or a negative error code otherwise
1269 int msm_csid_register_entity(struct csid_device
*csid
,
1270 struct v4l2_device
*v4l2_dev
)
1272 struct v4l2_subdev
*sd
= &csid
->subdev
;
1273 struct media_pad
*pads
= csid
->pads
;
1274 struct device
*dev
= csid
->camss
->dev
;
1278 v4l2_subdev_init(sd
, &csid_v4l2_ops
);
1279 sd
->internal_ops
= &csid_v4l2_internal_ops
;
1280 sd
->flags
|= V4L2_SUBDEV_FL_HAS_DEVNODE
|
1281 V4L2_SUBDEV_FL_HAS_EVENTS
;
1282 snprintf(sd
->name
, ARRAY_SIZE(sd
->name
), "%s%d",
1283 MSM_CSID_NAME
, csid
->id
);
1284 v4l2_set_subdevdata(sd
, csid
);
1286 ret
= v4l2_ctrl_handler_init(&csid
->ctrls
, 1);
1288 dev_err(dev
, "Failed to init ctrl handler: %d\n", ret
);
1292 csid
->testgen_mode
= v4l2_ctrl_new_std_menu_items(&csid
->ctrls
,
1293 &csid_ctrl_ops
, V4L2_CID_TEST_PATTERN
,
1294 csid
->testgen
.nmodes
, 0, 0,
1295 csid
->testgen
.modes
);
1297 if (csid
->ctrls
.error
) {
1298 dev_err(dev
, "Failed to init ctrl: %d\n", csid
->ctrls
.error
);
1299 ret
= csid
->ctrls
.error
;
1303 csid
->subdev
.ctrl_handler
= &csid
->ctrls
;
1305 ret
= csid_init_formats(sd
, NULL
);
1307 dev_err(dev
, "Failed to init format: %d\n", ret
);
1311 pads
[MSM_CSID_PAD_SINK
].flags
= MEDIA_PAD_FL_SINK
;
1312 for (i
= MSM_CSID_PAD_FIRST_SRC
; i
< MSM_CSID_PADS_NUM
; ++i
)
1313 pads
[i
].flags
= MEDIA_PAD_FL_SOURCE
;
1315 sd
->entity
.function
= MEDIA_ENT_F_PROC_VIDEO_PIXEL_FORMATTER
;
1316 sd
->entity
.ops
= &csid_media_ops
;
1317 ret
= media_entity_pads_init(&sd
->entity
, MSM_CSID_PADS_NUM
, pads
);
1319 dev_err(dev
, "Failed to init media entity: %d\n", ret
);
1323 ret
= v4l2_device_register_subdev(v4l2_dev
, sd
);
1325 dev_err(dev
, "Failed to register subdev: %d\n", ret
);
1332 media_entity_cleanup(&sd
->entity
);
1334 v4l2_ctrl_handler_free(&csid
->ctrls
);
1340 * msm_csid_unregister_entity - Unregister CSID module subdev node
1341 * @csid: CSID device
1343 void msm_csid_unregister_entity(struct csid_device
*csid
)
1345 v4l2_device_unregister_subdev(&csid
->subdev
);
1346 media_entity_cleanup(&csid
->subdev
.entity
);
1347 v4l2_ctrl_handler_free(&csid
->ctrls
);
1350 inline bool csid_is_lite(struct csid_device
*csid
)
1352 return csid
->camss
->res
->csid_res
[csid
->id
].csid
.is_lite
;