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"
27 #define MSM_CSID_NAME "msm_csid"
29 #define CAMSS_CSID_HW_VERSION 0x0
30 #define CAMSS_CSID_CORE_CTRL_0 0x004
31 #define CAMSS_CSID_CORE_CTRL_1 0x008
32 #define CAMSS_CSID_RST_CMD(v) ((v) == CAMSS_8x16 ? 0x00c : 0x010)
33 #define CAMSS_CSID_CID_LUT_VC_n(v, n) \
34 (((v) == CAMSS_8x16 ? 0x010 : 0x014) + 0x4 * (n))
35 #define CAMSS_CSID_CID_n_CFG(v, n) \
36 (((v) == CAMSS_8x16 ? 0x020 : 0x024) + 0x4 * (n))
37 #define CAMSS_CSID_CID_n_CFG_ISPIF_EN BIT(0)
38 #define CAMSS_CSID_CID_n_CFG_RDI_EN BIT(1)
39 #define CAMSS_CSID_CID_n_CFG_DECODE_FORMAT_SHIFT 4
40 #define CAMSS_CSID_CID_n_CFG_PLAIN_FORMAT_8 (0 << 8)
41 #define CAMSS_CSID_CID_n_CFG_PLAIN_FORMAT_16 (1 << 8)
42 #define CAMSS_CSID_CID_n_CFG_PLAIN_ALIGNMENT_LSB (0 << 9)
43 #define CAMSS_CSID_CID_n_CFG_PLAIN_ALIGNMENT_MSB (1 << 9)
44 #define CAMSS_CSID_CID_n_CFG_RDI_MODE_RAW_DUMP (0 << 10)
45 #define CAMSS_CSID_CID_n_CFG_RDI_MODE_PLAIN_PACKING (1 << 10)
46 #define CAMSS_CSID_IRQ_CLEAR_CMD(v) ((v) == CAMSS_8x16 ? 0x060 : 0x064)
47 #define CAMSS_CSID_IRQ_MASK(v) ((v) == CAMSS_8x16 ? 0x064 : 0x068)
48 #define CAMSS_CSID_IRQ_STATUS(v) ((v) == CAMSS_8x16 ? 0x068 : 0x06c)
49 #define CAMSS_CSID_TG_CTRL(v) ((v) == CAMSS_8x16 ? 0x0a0 : 0x0a8)
50 #define CAMSS_CSID_TG_CTRL_DISABLE 0xa06436
51 #define CAMSS_CSID_TG_CTRL_ENABLE 0xa06437
52 #define CAMSS_CSID_TG_VC_CFG(v) ((v) == CAMSS_8x16 ? 0x0a4 : 0x0ac)
53 #define CAMSS_CSID_TG_VC_CFG_H_BLANKING 0x3ff
54 #define CAMSS_CSID_TG_VC_CFG_V_BLANKING 0x7f
55 #define CAMSS_CSID_TG_DT_n_CGG_0(v, n) \
56 (((v) == CAMSS_8x16 ? 0x0ac : 0x0b4) + 0xc * (n))
57 #define CAMSS_CSID_TG_DT_n_CGG_1(v, n) \
58 (((v) == CAMSS_8x16 ? 0x0b0 : 0x0b8) + 0xc * (n))
59 #define CAMSS_CSID_TG_DT_n_CGG_2(v, n) \
60 (((v) == CAMSS_8x16 ? 0x0b4 : 0x0bc) + 0xc * (n))
62 #define DATA_TYPE_EMBEDDED_DATA_8BIT 0x12
63 #define DATA_TYPE_YUV422_8BIT 0x1e
64 #define DATA_TYPE_RAW_6BIT 0x28
65 #define DATA_TYPE_RAW_8BIT 0x2a
66 #define DATA_TYPE_RAW_10BIT 0x2b
67 #define DATA_TYPE_RAW_12BIT 0x2c
68 #define DATA_TYPE_RAW_14BIT 0x2d
70 #define DECODE_FORMAT_UNCOMPRESSED_6_BIT 0x0
71 #define DECODE_FORMAT_UNCOMPRESSED_8_BIT 0x1
72 #define DECODE_FORMAT_UNCOMPRESSED_10_BIT 0x2
73 #define DECODE_FORMAT_UNCOMPRESSED_12_BIT 0x3
74 #define DECODE_FORMAT_UNCOMPRESSED_14_BIT 0x8
76 #define CSID_RESET_TIMEOUT_MS 500
83 u8 spp; /* bus samples per pixel */
86 static const struct csid_format csid_formats_8x16[] = {
88 MEDIA_BUS_FMT_UYVY8_2X8,
89 DATA_TYPE_YUV422_8BIT,
90 DECODE_FORMAT_UNCOMPRESSED_8_BIT,
95 MEDIA_BUS_FMT_VYUY8_2X8,
96 DATA_TYPE_YUV422_8BIT,
97 DECODE_FORMAT_UNCOMPRESSED_8_BIT,
102 MEDIA_BUS_FMT_YUYV8_2X8,
103 DATA_TYPE_YUV422_8BIT,
104 DECODE_FORMAT_UNCOMPRESSED_8_BIT,
109 MEDIA_BUS_FMT_YVYU8_2X8,
110 DATA_TYPE_YUV422_8BIT,
111 DECODE_FORMAT_UNCOMPRESSED_8_BIT,
116 MEDIA_BUS_FMT_SBGGR8_1X8,
118 DECODE_FORMAT_UNCOMPRESSED_8_BIT,
123 MEDIA_BUS_FMT_SGBRG8_1X8,
125 DECODE_FORMAT_UNCOMPRESSED_8_BIT,
130 MEDIA_BUS_FMT_SGRBG8_1X8,
132 DECODE_FORMAT_UNCOMPRESSED_8_BIT,
137 MEDIA_BUS_FMT_SRGGB8_1X8,
139 DECODE_FORMAT_UNCOMPRESSED_8_BIT,
144 MEDIA_BUS_FMT_SBGGR10_1X10,
146 DECODE_FORMAT_UNCOMPRESSED_10_BIT,
151 MEDIA_BUS_FMT_SGBRG10_1X10,
153 DECODE_FORMAT_UNCOMPRESSED_10_BIT,
158 MEDIA_BUS_FMT_SGRBG10_1X10,
160 DECODE_FORMAT_UNCOMPRESSED_10_BIT,
165 MEDIA_BUS_FMT_SRGGB10_1X10,
167 DECODE_FORMAT_UNCOMPRESSED_10_BIT,
172 MEDIA_BUS_FMT_SBGGR12_1X12,
174 DECODE_FORMAT_UNCOMPRESSED_12_BIT,
179 MEDIA_BUS_FMT_SGBRG12_1X12,
181 DECODE_FORMAT_UNCOMPRESSED_12_BIT,
186 MEDIA_BUS_FMT_SGRBG12_1X12,
188 DECODE_FORMAT_UNCOMPRESSED_12_BIT,
193 MEDIA_BUS_FMT_SRGGB12_1X12,
195 DECODE_FORMAT_UNCOMPRESSED_12_BIT,
200 MEDIA_BUS_FMT_Y10_1X10,
202 DECODE_FORMAT_UNCOMPRESSED_10_BIT,
208 static const struct csid_format csid_formats_8x96[] = {
210 MEDIA_BUS_FMT_UYVY8_2X8,
211 DATA_TYPE_YUV422_8BIT,
212 DECODE_FORMAT_UNCOMPRESSED_8_BIT,
217 MEDIA_BUS_FMT_VYUY8_2X8,
218 DATA_TYPE_YUV422_8BIT,
219 DECODE_FORMAT_UNCOMPRESSED_8_BIT,
224 MEDIA_BUS_FMT_YUYV8_2X8,
225 DATA_TYPE_YUV422_8BIT,
226 DECODE_FORMAT_UNCOMPRESSED_8_BIT,
231 MEDIA_BUS_FMT_YVYU8_2X8,
232 DATA_TYPE_YUV422_8BIT,
233 DECODE_FORMAT_UNCOMPRESSED_8_BIT,
238 MEDIA_BUS_FMT_SBGGR8_1X8,
240 DECODE_FORMAT_UNCOMPRESSED_8_BIT,
245 MEDIA_BUS_FMT_SGBRG8_1X8,
247 DECODE_FORMAT_UNCOMPRESSED_8_BIT,
252 MEDIA_BUS_FMT_SGRBG8_1X8,
254 DECODE_FORMAT_UNCOMPRESSED_8_BIT,
259 MEDIA_BUS_FMT_SRGGB8_1X8,
261 DECODE_FORMAT_UNCOMPRESSED_8_BIT,
266 MEDIA_BUS_FMT_SBGGR10_1X10,
268 DECODE_FORMAT_UNCOMPRESSED_10_BIT,
273 MEDIA_BUS_FMT_SGBRG10_1X10,
275 DECODE_FORMAT_UNCOMPRESSED_10_BIT,
280 MEDIA_BUS_FMT_SGRBG10_1X10,
282 DECODE_FORMAT_UNCOMPRESSED_10_BIT,
287 MEDIA_BUS_FMT_SRGGB10_1X10,
289 DECODE_FORMAT_UNCOMPRESSED_10_BIT,
294 MEDIA_BUS_FMT_SBGGR12_1X12,
296 DECODE_FORMAT_UNCOMPRESSED_12_BIT,
301 MEDIA_BUS_FMT_SGBRG12_1X12,
303 DECODE_FORMAT_UNCOMPRESSED_12_BIT,
308 MEDIA_BUS_FMT_SGRBG12_1X12,
310 DECODE_FORMAT_UNCOMPRESSED_12_BIT,
315 MEDIA_BUS_FMT_SRGGB12_1X12,
317 DECODE_FORMAT_UNCOMPRESSED_12_BIT,
322 MEDIA_BUS_FMT_SBGGR14_1X14,
324 DECODE_FORMAT_UNCOMPRESSED_14_BIT,
329 MEDIA_BUS_FMT_SGBRG14_1X14,
331 DECODE_FORMAT_UNCOMPRESSED_14_BIT,
336 MEDIA_BUS_FMT_SGRBG14_1X14,
338 DECODE_FORMAT_UNCOMPRESSED_14_BIT,
343 MEDIA_BUS_FMT_SRGGB14_1X14,
345 DECODE_FORMAT_UNCOMPRESSED_14_BIT,
350 MEDIA_BUS_FMT_Y10_1X10,
352 DECODE_FORMAT_UNCOMPRESSED_10_BIT,
358 static u32 csid_find_code(u32 *code, unsigned int n_code,
359 unsigned int index, u32 req_code)
363 if (!req_code && (index >= n_code))
366 for (i = 0; i < n_code; i++)
368 if (req_code == code[i])
378 static u32 csid_src_pad_code(struct csid_device *csid, u32 sink_code,
379 unsigned int index, u32 src_req_code)
381 if (csid->camss->version == CAMSS_8x16) {
386 } else if (csid->camss->version == CAMSS_8x96 ||
387 csid->camss->version == CAMSS_660) {
389 case MEDIA_BUS_FMT_SBGGR10_1X10:
392 MEDIA_BUS_FMT_SBGGR10_1X10,
393 MEDIA_BUS_FMT_SBGGR10_2X8_PADHI_LE,
396 return csid_find_code(src_code, ARRAY_SIZE(src_code),
397 index, src_req_code);
399 case MEDIA_BUS_FMT_Y10_1X10:
402 MEDIA_BUS_FMT_Y10_1X10,
403 MEDIA_BUS_FMT_Y10_2X8_PADHI_LE,
406 return csid_find_code(src_code, ARRAY_SIZE(src_code),
407 index, src_req_code);
420 static const struct csid_format *csid_get_fmt_entry(
421 const struct csid_format *formats,
422 unsigned int nformat,
427 for (i = 0; i < nformat; i++)
428 if (code == formats[i].code)
431 WARN(1, "Unknown format\n");
437 * csid_isr - CSID module interrupt handler
438 * @irq: Interrupt line
441 * Return IRQ_HANDLED on success
443 static irqreturn_t csid_isr(int irq, void *dev)
445 struct csid_device *csid = dev;
446 enum camss_version ver = csid->camss->version;
449 value = readl_relaxed(csid->base + CAMSS_CSID_IRQ_STATUS(ver));
450 writel_relaxed(value, csid->base + CAMSS_CSID_IRQ_CLEAR_CMD(ver));
452 if ((value >> 11) & 0x1)
453 complete(&csid->reset_complete);
459 * csid_set_clock_rates - Calculate and set clock rates on CSID module
460 * @csiphy: CSID device
462 static int csid_set_clock_rates(struct csid_device *csid)
464 struct device *dev = csid->camss->dev;
469 ret = camss_get_pixel_clock(&csid->subdev.entity, &pixel_clock);
473 for (i = 0; i < csid->nclocks; i++) {
474 struct camss_clock *clock = &csid->clock[i];
476 if (!strcmp(clock->name, "csi0") ||
477 !strcmp(clock->name, "csi1") ||
478 !strcmp(clock->name, "csi2") ||
479 !strcmp(clock->name, "csi3")) {
480 const struct csid_format *f = csid_get_fmt_entry(
483 csid->fmt[MSM_CSIPHY_PAD_SINK].code);
484 u8 num_lanes = csid->phy.lane_cnt;
485 u64 min_rate = pixel_clock * f->bpp /
489 camss_add_clock_margin(&min_rate);
491 for (j = 0; j < clock->nfreqs; j++)
492 if (min_rate < clock->freq[j])
495 if (j == clock->nfreqs) {
497 "Pixel clock is too high for CSID\n");
501 /* if sensor pixel clock is not available */
502 /* set highest possible CSID clock rate */
504 j = clock->nfreqs - 1;
506 rate = clk_round_rate(clock->clk, clock->freq[j]);
508 dev_err(dev, "clk round rate failed: %ld\n",
513 ret = clk_set_rate(clock->clk, rate);
515 dev_err(dev, "clk set rate failed: %d\n", ret);
525 * csid_reset - Trigger reset on CSID module and wait to complete
528 * Return 0 on success or a negative error code otherwise
530 static int csid_reset(struct csid_device *csid)
534 reinit_completion(&csid->reset_complete);
536 writel_relaxed(0x7fff, csid->base +
537 CAMSS_CSID_RST_CMD(csid->camss->version));
539 time = wait_for_completion_timeout(&csid->reset_complete,
540 msecs_to_jiffies(CSID_RESET_TIMEOUT_MS));
542 dev_err(csid->camss->dev, "CSID reset timeout\n");
550 * csid_set_power - Power on/off CSID module
551 * @sd: CSID V4L2 subdevice
552 * @on: Requested power state
554 * Return 0 on success or a negative error code otherwise
556 static int csid_set_power(struct v4l2_subdev *sd, int on)
558 struct csid_device *csid = v4l2_get_subdevdata(sd);
559 struct device *dev = csid->camss->dev;
565 ret = pm_runtime_get_sync(dev);
567 pm_runtime_put_sync(dev);
571 ret = regulator_enable(csid->vdda);
573 pm_runtime_put_sync(dev);
577 ret = csid_set_clock_rates(csid);
579 regulator_disable(csid->vdda);
580 pm_runtime_put_sync(dev);
584 ret = camss_enable_clocks(csid->nclocks, csid->clock, dev);
586 regulator_disable(csid->vdda);
587 pm_runtime_put_sync(dev);
591 enable_irq(csid->irq);
593 ret = csid_reset(csid);
595 disable_irq(csid->irq);
596 camss_disable_clocks(csid->nclocks, csid->clock);
597 regulator_disable(csid->vdda);
598 pm_runtime_put_sync(dev);
602 hw_version = readl_relaxed(csid->base + CAMSS_CSID_HW_VERSION);
603 dev_dbg(dev, "CSID HW Version = 0x%08x\n", hw_version);
605 disable_irq(csid->irq);
606 camss_disable_clocks(csid->nclocks, csid->clock);
607 ret = regulator_disable(csid->vdda);
608 pm_runtime_put_sync(dev);
615 * csid_set_stream - Enable/disable streaming on CSID module
616 * @sd: CSID V4L2 subdevice
617 * @enable: Requested streaming state
619 * Main configuration of CSID module is also done here.
621 * Return 0 on success or a negative error code otherwise
623 static int csid_set_stream(struct v4l2_subdev *sd, int enable)
625 struct csid_device *csid = v4l2_get_subdevdata(sd);
626 struct csid_testgen_config *tg = &csid->testgen;
627 enum camss_version ver = csid->camss->version;
631 u8 vc = 0; /* Virtual Channel 0 */
632 u8 cid = vc * 4; /* id of Virtual Channel and Data Type set */
636 ret = v4l2_ctrl_handler_setup(&csid->ctrls);
638 dev_err(csid->camss->dev,
639 "could not sync v4l2 controls: %d\n", ret);
644 !media_entity_remote_pad(&csid->pads[MSM_CSID_PAD_SINK]))
648 /* Config Test Generator */
649 struct v4l2_mbus_framefmt *f =
650 &csid->fmt[MSM_CSID_PAD_SRC];
651 const struct csid_format *format = csid_get_fmt_entry(
652 csid->formats, csid->nformats, f->code);
653 u32 num_bytes_per_line =
654 f->width * format->bpp * format->spp / 8;
655 u32 num_lines = f->height;
657 /* 31:24 V blank, 23:13 H blank, 3:2 num of active DT */
659 val = ((CAMSS_CSID_TG_VC_CFG_V_BLANKING & 0xff) << 24) |
660 ((CAMSS_CSID_TG_VC_CFG_H_BLANKING & 0x7ff) << 13);
661 writel_relaxed(val, csid->base +
662 CAMSS_CSID_TG_VC_CFG(ver));
664 /* 28:16 bytes per lines, 12:0 num of lines */
665 val = ((num_bytes_per_line & 0x1fff) << 16) |
666 (num_lines & 0x1fff);
667 writel_relaxed(val, csid->base +
668 CAMSS_CSID_TG_DT_n_CGG_0(ver, 0));
670 dt = format->data_type;
674 writel_relaxed(val, csid->base +
675 CAMSS_CSID_TG_DT_n_CGG_1(ver, 0));
677 /* 2:0 output test pattern */
678 val = tg->payload_mode;
679 writel_relaxed(val, csid->base +
680 CAMSS_CSID_TG_DT_n_CGG_2(ver, 0));
682 df = format->decode_format;
684 struct v4l2_mbus_framefmt *f =
685 &csid->fmt[MSM_CSID_PAD_SINK];
686 const struct csid_format *format = csid_get_fmt_entry(
687 csid->formats, csid->nformats, f->code);
688 struct csid_phy_config *phy = &csid->phy;
690 val = phy->lane_cnt - 1;
691 val |= phy->lane_assign << 4;
694 csid->base + CAMSS_CSID_CORE_CTRL_0);
696 val = phy->csiphy_id << 17;
700 csid->base + CAMSS_CSID_CORE_CTRL_1);
702 dt = format->data_type;
703 df = format->decode_format;
708 dt_shift = (cid % 4) * 8;
710 val = readl_relaxed(csid->base +
711 CAMSS_CSID_CID_LUT_VC_n(ver, vc));
712 val &= ~(0xff << dt_shift);
713 val |= dt << dt_shift;
714 writel_relaxed(val, csid->base +
715 CAMSS_CSID_CID_LUT_VC_n(ver, vc));
717 val = CAMSS_CSID_CID_n_CFG_ISPIF_EN;
718 val |= CAMSS_CSID_CID_n_CFG_RDI_EN;
719 val |= df << CAMSS_CSID_CID_n_CFG_DECODE_FORMAT_SHIFT;
720 val |= CAMSS_CSID_CID_n_CFG_RDI_MODE_RAW_DUMP;
722 if (csid->camss->version == CAMSS_8x96 ||
723 csid->camss->version == CAMSS_660) {
724 u32 sink_code = csid->fmt[MSM_CSID_PAD_SINK].code;
725 u32 src_code = csid->fmt[MSM_CSID_PAD_SRC].code;
727 if ((sink_code == MEDIA_BUS_FMT_SBGGR10_1X10 &&
728 src_code == MEDIA_BUS_FMT_SBGGR10_2X8_PADHI_LE) ||
729 (sink_code == MEDIA_BUS_FMT_Y10_1X10 &&
730 src_code == MEDIA_BUS_FMT_Y10_2X8_PADHI_LE)) {
731 val |= CAMSS_CSID_CID_n_CFG_RDI_MODE_PLAIN_PACKING;
732 val |= CAMSS_CSID_CID_n_CFG_PLAIN_FORMAT_16;
733 val |= CAMSS_CSID_CID_n_CFG_PLAIN_ALIGNMENT_LSB;
737 writel_relaxed(val, csid->base +
738 CAMSS_CSID_CID_n_CFG(ver, cid));
741 val = CAMSS_CSID_TG_CTRL_ENABLE;
742 writel_relaxed(val, csid->base +
743 CAMSS_CSID_TG_CTRL(ver));
747 val = CAMSS_CSID_TG_CTRL_DISABLE;
748 writel_relaxed(val, csid->base +
749 CAMSS_CSID_TG_CTRL(ver));
757 * __csid_get_format - Get pointer to format structure
759 * @cfg: V4L2 subdev pad configuration
760 * @pad: pad from which format is requested
761 * @which: TRY or ACTIVE format
763 * Return pointer to TRY or ACTIVE format structure
765 static struct v4l2_mbus_framefmt *
766 __csid_get_format(struct csid_device *csid,
767 struct v4l2_subdev_pad_config *cfg,
769 enum v4l2_subdev_format_whence which)
771 if (which == V4L2_SUBDEV_FORMAT_TRY)
772 return v4l2_subdev_get_try_format(&csid->subdev, cfg, pad);
774 return &csid->fmt[pad];
778 * csid_try_format - Handle try format by pad subdev method
780 * @cfg: V4L2 subdev pad configuration
781 * @pad: pad on which format is requested
782 * @fmt: pointer to v4l2 format structure
783 * @which: wanted subdev format
785 static void csid_try_format(struct csid_device *csid,
786 struct v4l2_subdev_pad_config *cfg,
788 struct v4l2_mbus_framefmt *fmt,
789 enum v4l2_subdev_format_whence which)
794 case MSM_CSID_PAD_SINK:
795 /* Set format on sink pad */
797 for (i = 0; i < csid->nformats; i++)
798 if (fmt->code == csid->formats[i].code)
801 /* If not found, use UYVY as default */
802 if (i >= csid->nformats)
803 fmt->code = MEDIA_BUS_FMT_UYVY8_2X8;
805 fmt->width = clamp_t(u32, fmt->width, 1, 8191);
806 fmt->height = clamp_t(u32, fmt->height, 1, 8191);
808 fmt->field = V4L2_FIELD_NONE;
809 fmt->colorspace = V4L2_COLORSPACE_SRGB;
813 case MSM_CSID_PAD_SRC:
814 if (csid->testgen_mode->cur.val == 0) {
815 /* Test generator is disabled, */
816 /* keep pad formats in sync */
817 u32 code = fmt->code;
819 *fmt = *__csid_get_format(csid, cfg,
820 MSM_CSID_PAD_SINK, which);
821 fmt->code = csid_src_pad_code(csid, fmt->code, 0, code);
823 /* Test generator is enabled, set format on source */
824 /* pad to allow test generator usage */
826 for (i = 0; i < csid->nformats; i++)
827 if (csid->formats[i].code == fmt->code)
830 /* If not found, use UYVY as default */
831 if (i >= csid->nformats)
832 fmt->code = MEDIA_BUS_FMT_UYVY8_2X8;
834 fmt->width = clamp_t(u32, fmt->width, 1, 8191);
835 fmt->height = clamp_t(u32, fmt->height, 1, 8191);
837 fmt->field = V4L2_FIELD_NONE;
842 fmt->colorspace = V4L2_COLORSPACE_SRGB;
846 * csid_enum_mbus_code - Handle pixel format enumeration
847 * @sd: CSID V4L2 subdevice
848 * @cfg: V4L2 subdev pad configuration
849 * @code: pointer to v4l2_subdev_mbus_code_enum structure
850 * return -EINVAL or zero on success
852 static int csid_enum_mbus_code(struct v4l2_subdev *sd,
853 struct v4l2_subdev_pad_config *cfg,
854 struct v4l2_subdev_mbus_code_enum *code)
856 struct csid_device *csid = v4l2_get_subdevdata(sd);
858 if (code->pad == MSM_CSID_PAD_SINK) {
859 if (code->index >= csid->nformats)
862 code->code = csid->formats[code->index].code;
864 if (csid->testgen_mode->cur.val == 0) {
865 struct v4l2_mbus_framefmt *sink_fmt;
867 sink_fmt = __csid_get_format(csid, cfg,
871 code->code = csid_src_pad_code(csid, sink_fmt->code,
876 if (code->index >= csid->nformats)
879 code->code = csid->formats[code->index].code;
887 * csid_enum_frame_size - Handle frame size enumeration
888 * @sd: CSID V4L2 subdevice
889 * @cfg: V4L2 subdev pad configuration
890 * @fse: pointer to v4l2_subdev_frame_size_enum structure
891 * return -EINVAL or zero on success
893 static int csid_enum_frame_size(struct v4l2_subdev *sd,
894 struct v4l2_subdev_pad_config *cfg,
895 struct v4l2_subdev_frame_size_enum *fse)
897 struct csid_device *csid = v4l2_get_subdevdata(sd);
898 struct v4l2_mbus_framefmt format;
903 format.code = fse->code;
906 csid_try_format(csid, cfg, fse->pad, &format, fse->which);
907 fse->min_width = format.width;
908 fse->min_height = format.height;
910 if (format.code != fse->code)
913 format.code = fse->code;
916 csid_try_format(csid, cfg, fse->pad, &format, fse->which);
917 fse->max_width = format.width;
918 fse->max_height = format.height;
924 * csid_get_format - Handle get format by pads subdev method
925 * @sd: CSID V4L2 subdevice
926 * @cfg: V4L2 subdev pad configuration
927 * @fmt: pointer to v4l2 subdev format structure
929 * Return -EINVAL or zero on success
931 static int csid_get_format(struct v4l2_subdev *sd,
932 struct v4l2_subdev_pad_config *cfg,
933 struct v4l2_subdev_format *fmt)
935 struct csid_device *csid = v4l2_get_subdevdata(sd);
936 struct v4l2_mbus_framefmt *format;
938 format = __csid_get_format(csid, cfg, fmt->pad, fmt->which);
942 fmt->format = *format;
948 * csid_set_format - Handle set format by pads subdev method
949 * @sd: CSID V4L2 subdevice
950 * @cfg: V4L2 subdev pad configuration
951 * @fmt: pointer to v4l2 subdev format structure
953 * Return -EINVAL or zero on success
955 static int csid_set_format(struct v4l2_subdev *sd,
956 struct v4l2_subdev_pad_config *cfg,
957 struct v4l2_subdev_format *fmt)
959 struct csid_device *csid = v4l2_get_subdevdata(sd);
960 struct v4l2_mbus_framefmt *format;
962 format = __csid_get_format(csid, cfg, fmt->pad, fmt->which);
966 csid_try_format(csid, cfg, fmt->pad, &fmt->format, fmt->which);
967 *format = fmt->format;
969 /* Propagate the format from sink to source */
970 if (fmt->pad == MSM_CSID_PAD_SINK) {
971 format = __csid_get_format(csid, cfg, MSM_CSID_PAD_SRC,
974 *format = fmt->format;
975 csid_try_format(csid, cfg, MSM_CSID_PAD_SRC, format,
983 * csid_init_formats - Initialize formats on all pads
984 * @sd: CSID V4L2 subdevice
985 * @fh: V4L2 subdev file handle
987 * Initialize all pad formats with default values.
989 * Return 0 on success or a negative error code otherwise
991 static int csid_init_formats(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh)
993 struct v4l2_subdev_format format = {
994 .pad = MSM_CSID_PAD_SINK,
995 .which = fh ? V4L2_SUBDEV_FORMAT_TRY :
996 V4L2_SUBDEV_FORMAT_ACTIVE,
998 .code = MEDIA_BUS_FMT_UYVY8_2X8,
1004 return csid_set_format(sd, fh ? fh->pad : NULL, &format);
1007 static const char * const csid_test_pattern_menu[] = {
1010 "Alternating 0x55/0xAA",
1013 "Pseudo-random Data",
1017 * csid_set_test_pattern - Set test generator's pattern mode
1018 * @csid: CSID device
1019 * @value: desired test pattern mode
1021 * Return 0 on success or a negative error code otherwise
1023 static int csid_set_test_pattern(struct csid_device *csid, s32 value)
1025 struct csid_testgen_config *tg = &csid->testgen;
1027 /* If CSID is linked to CSIPHY, do not allow to enable test generator */
1028 if (value && media_entity_remote_pad(&csid->pads[MSM_CSID_PAD_SINK]))
1031 tg->enabled = !!value;
1035 tg->payload_mode = CSID_PAYLOAD_MODE_INCREMENTING;
1038 tg->payload_mode = CSID_PAYLOAD_MODE_ALTERNATING_55_AA;
1041 tg->payload_mode = CSID_PAYLOAD_MODE_ALL_ZEROES;
1044 tg->payload_mode = CSID_PAYLOAD_MODE_ALL_ONES;
1047 tg->payload_mode = CSID_PAYLOAD_MODE_RANDOM;
1055 * csid_s_ctrl - Handle set control subdev method
1056 * @ctrl: pointer to v4l2 control structure
1058 * Return 0 on success or a negative error code otherwise
1060 static int csid_s_ctrl(struct v4l2_ctrl *ctrl)
1062 struct csid_device *csid = container_of(ctrl->handler,
1063 struct csid_device, ctrls);
1067 case V4L2_CID_TEST_PATTERN:
1068 ret = csid_set_test_pattern(csid, ctrl->val);
1075 static const struct v4l2_ctrl_ops csid_ctrl_ops = {
1076 .s_ctrl = csid_s_ctrl,
1080 * msm_csid_subdev_init - Initialize CSID device structure and resources
1081 * @csid: CSID device
1082 * @res: CSID module resources table
1083 * @id: CSID module id
1085 * Return 0 on success or a negative error code otherwise
1087 int msm_csid_subdev_init(struct camss *camss, struct csid_device *csid,
1088 const struct resources *res, u8 id)
1090 struct device *dev = camss->dev;
1091 struct platform_device *pdev = to_platform_device(dev);
1096 csid->camss = camss;
1099 if (camss->version == CAMSS_8x16) {
1100 csid->formats = csid_formats_8x16;
1102 ARRAY_SIZE(csid_formats_8x16);
1103 } else if (camss->version == CAMSS_8x96 ||
1104 camss->version == CAMSS_660) {
1105 csid->formats = csid_formats_8x96;
1107 ARRAY_SIZE(csid_formats_8x96);
1114 r = platform_get_resource_byname(pdev, IORESOURCE_MEM, res->reg[0]);
1115 csid->base = devm_ioremap_resource(dev, r);
1116 if (IS_ERR(csid->base)) {
1117 dev_err(dev, "could not map memory\n");
1118 return PTR_ERR(csid->base);
1123 r = platform_get_resource_byname(pdev, IORESOURCE_IRQ,
1126 dev_err(dev, "missing IRQ\n");
1130 csid->irq = r->start;
1131 snprintf(csid->irq_name, sizeof(csid->irq_name), "%s_%s%d",
1132 dev_name(dev), MSM_CSID_NAME, csid->id);
1133 ret = devm_request_irq(dev, csid->irq, csid_isr,
1134 IRQF_TRIGGER_RISING, csid->irq_name, csid);
1136 dev_err(dev, "request_irq failed: %d\n", ret);
1140 disable_irq(csid->irq);
1145 while (res->clock[csid->nclocks])
1148 csid->clock = devm_kcalloc(dev, csid->nclocks, sizeof(*csid->clock),
1153 for (i = 0; i < csid->nclocks; i++) {
1154 struct camss_clock *clock = &csid->clock[i];
1156 clock->clk = devm_clk_get(dev, res->clock[i]);
1157 if (IS_ERR(clock->clk))
1158 return PTR_ERR(clock->clk);
1160 clock->name = res->clock[i];
1163 while (res->clock_rate[i][clock->nfreqs])
1166 if (!clock->nfreqs) {
1171 clock->freq = devm_kcalloc(dev,
1173 sizeof(*clock->freq),
1178 for (j = 0; j < clock->nfreqs; j++)
1179 clock->freq[j] = res->clock_rate[i][j];
1184 csid->vdda = devm_regulator_get(dev, res->regulator[0]);
1185 if (IS_ERR(csid->vdda)) {
1186 dev_err(dev, "could not get regulator\n");
1187 return PTR_ERR(csid->vdda);
1190 init_completion(&csid->reset_complete);
1196 * msm_csid_get_csid_id - Get CSID HW module id
1197 * @entity: Pointer to CSID media entity structure
1198 * @id: Return CSID HW module id here
1200 void msm_csid_get_csid_id(struct media_entity *entity, u8 *id)
1202 struct v4l2_subdev *sd = media_entity_to_v4l2_subdev(entity);
1203 struct csid_device *csid = v4l2_get_subdevdata(sd);
1209 * csid_get_lane_assign - Calculate CSI2 lane assign configuration parameter
1210 * @lane_cfg - CSI2 lane configuration
1212 * Return lane assign
1214 static u32 csid_get_lane_assign(struct csiphy_lanes_cfg *lane_cfg)
1216 u32 lane_assign = 0;
1219 for (i = 0; i < lane_cfg->num_data; i++)
1220 lane_assign |= lane_cfg->data[i].pos << (i * 4);
1226 * csid_link_setup - Setup CSID connections
1227 * @entity: Pointer to media entity structure
1228 * @local: Pointer to local pad
1229 * @remote: Pointer to remote pad
1230 * @flags: Link flags
1232 * Return 0 on success
1234 static int csid_link_setup(struct media_entity *entity,
1235 const struct media_pad *local,
1236 const struct media_pad *remote, u32 flags)
1238 if (flags & MEDIA_LNK_FL_ENABLED)
1239 if (media_entity_remote_pad(local))
1242 if ((local->flags & MEDIA_PAD_FL_SINK) &&
1243 (flags & MEDIA_LNK_FL_ENABLED)) {
1244 struct v4l2_subdev *sd;
1245 struct csid_device *csid;
1246 struct csiphy_device *csiphy;
1247 struct csiphy_lanes_cfg *lane_cfg;
1248 struct v4l2_subdev_format format = { 0 };
1250 sd = media_entity_to_v4l2_subdev(entity);
1251 csid = v4l2_get_subdevdata(sd);
1253 /* If test generator is enabled */
1254 /* do not allow a link from CSIPHY to CSID */
1255 if (csid->testgen_mode->cur.val != 0)
1258 sd = media_entity_to_v4l2_subdev(remote->entity);
1259 csiphy = v4l2_get_subdevdata(sd);
1261 /* If a sensor is not linked to CSIPHY */
1262 /* do no allow a link from CSIPHY to CSID */
1263 if (!csiphy->cfg.csi2)
1266 csid->phy.csiphy_id = csiphy->id;
1268 lane_cfg = &csiphy->cfg.csi2->lane_cfg;
1269 csid->phy.lane_cnt = lane_cfg->num_data;
1270 csid->phy.lane_assign = csid_get_lane_assign(lane_cfg);
1272 /* Reset format on source pad to sink pad format */
1273 format.pad = MSM_CSID_PAD_SRC;
1274 format.which = V4L2_SUBDEV_FORMAT_ACTIVE;
1275 csid_set_format(&csid->subdev, NULL, &format);
1281 static const struct v4l2_subdev_core_ops csid_core_ops = {
1282 .s_power = csid_set_power,
1283 .subscribe_event = v4l2_ctrl_subdev_subscribe_event,
1284 .unsubscribe_event = v4l2_event_subdev_unsubscribe,
1287 static const struct v4l2_subdev_video_ops csid_video_ops = {
1288 .s_stream = csid_set_stream,
1291 static const struct v4l2_subdev_pad_ops csid_pad_ops = {
1292 .enum_mbus_code = csid_enum_mbus_code,
1293 .enum_frame_size = csid_enum_frame_size,
1294 .get_fmt = csid_get_format,
1295 .set_fmt = csid_set_format,
1298 static const struct v4l2_subdev_ops csid_v4l2_ops = {
1299 .core = &csid_core_ops,
1300 .video = &csid_video_ops,
1301 .pad = &csid_pad_ops,
1304 static const struct v4l2_subdev_internal_ops csid_v4l2_internal_ops = {
1305 .open = csid_init_formats,
1308 static const struct media_entity_operations csid_media_ops = {
1309 .link_setup = csid_link_setup,
1310 .link_validate = v4l2_subdev_link_validate,
1314 * msm_csid_register_entity - Register subdev node for CSID module
1315 * @csid: CSID device
1316 * @v4l2_dev: V4L2 device
1318 * Return 0 on success or a negative error code otherwise
1320 int msm_csid_register_entity(struct csid_device *csid,
1321 struct v4l2_device *v4l2_dev)
1323 struct v4l2_subdev *sd = &csid->subdev;
1324 struct media_pad *pads = csid->pads;
1325 struct device *dev = csid->camss->dev;
1328 v4l2_subdev_init(sd, &csid_v4l2_ops);
1329 sd->internal_ops = &csid_v4l2_internal_ops;
1330 sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE |
1331 V4L2_SUBDEV_FL_HAS_EVENTS;
1332 snprintf(sd->name, ARRAY_SIZE(sd->name), "%s%d",
1333 MSM_CSID_NAME, csid->id);
1334 v4l2_set_subdevdata(sd, csid);
1336 ret = v4l2_ctrl_handler_init(&csid->ctrls, 1);
1338 dev_err(dev, "Failed to init ctrl handler: %d\n", ret);
1342 csid->testgen_mode = v4l2_ctrl_new_std_menu_items(&csid->ctrls,
1343 &csid_ctrl_ops, V4L2_CID_TEST_PATTERN,
1344 ARRAY_SIZE(csid_test_pattern_menu) - 1, 0, 0,
1345 csid_test_pattern_menu);
1347 if (csid->ctrls.error) {
1348 dev_err(dev, "Failed to init ctrl: %d\n", csid->ctrls.error);
1349 ret = csid->ctrls.error;
1353 csid->subdev.ctrl_handler = &csid->ctrls;
1355 ret = csid_init_formats(sd, NULL);
1357 dev_err(dev, "Failed to init format: %d\n", ret);
1361 pads[MSM_CSID_PAD_SINK].flags = MEDIA_PAD_FL_SINK;
1362 pads[MSM_CSID_PAD_SRC].flags = MEDIA_PAD_FL_SOURCE;
1364 sd->entity.function = MEDIA_ENT_F_PROC_VIDEO_PIXEL_FORMATTER;
1365 sd->entity.ops = &csid_media_ops;
1366 ret = media_entity_pads_init(&sd->entity, MSM_CSID_PADS_NUM, pads);
1368 dev_err(dev, "Failed to init media entity: %d\n", ret);
1372 ret = v4l2_device_register_subdev(v4l2_dev, sd);
1374 dev_err(dev, "Failed to register subdev: %d\n", ret);
1381 media_entity_cleanup(&sd->entity);
1383 v4l2_ctrl_handler_free(&csid->ctrls);
1389 * msm_csid_unregister_entity - Unregister CSID module subdev node
1390 * @csid: CSID device
1392 void msm_csid_unregister_entity(struct csid_device *csid)
1394 v4l2_device_unregister_subdev(&csid->subdev);
1395 media_entity_cleanup(&csid->subdev.entity);
1396 v4l2_ctrl_handler_free(&csid->ctrls);