1 // SPDX-License-Identifier: GPL-2.0
3 * NXP i.MX8MQ SoC series MIPI-CSI2 receiver driver
5 * Copyright (C) 2021 Purism SPC
9 #include <linux/clk-provider.h>
10 #include <linux/delay.h>
11 #include <linux/errno.h>
12 #include <linux/interconnect.h>
13 #include <linux/interrupt.h>
15 #include <linux/kernel.h>
16 #include <linux/mfd/syscon.h>
17 #include <linux/module.h>
18 #include <linux/mutex.h>
20 #include <linux/platform_device.h>
21 #include <linux/pm_runtime.h>
22 #include <linux/regmap.h>
23 #include <linux/regulator/consumer.h>
24 #include <linux/reset.h>
25 #include <linux/spinlock.h>
27 #include <media/v4l2-common.h>
28 #include <media/v4l2-device.h>
29 #include <media/v4l2-fwnode.h>
30 #include <media/v4l2-mc.h>
31 #include <media/v4l2-subdev.h>
33 #define MIPI_CSI2_DRIVER_NAME "imx8mq-mipi-csi2"
34 #define MIPI_CSI2_SUBDEV_NAME MIPI_CSI2_DRIVER_NAME
36 #define MIPI_CSI2_PAD_SINK 0
37 #define MIPI_CSI2_PAD_SOURCE 1
38 #define MIPI_CSI2_PADS_NUM 2
40 #define MIPI_CSI2_DEF_PIX_WIDTH 640
41 #define MIPI_CSI2_DEF_PIX_HEIGHT 480
43 /* Register map definition */
45 /* i.MX8MQ CSI-2 controller CSR */
46 #define CSI2RX_CFG_NUM_LANES 0x100
47 #define CSI2RX_CFG_DISABLE_DATA_LANES 0x104
48 #define CSI2RX_BIT_ERR 0x108
49 #define CSI2RX_IRQ_STATUS 0x10c
50 #define CSI2RX_IRQ_MASK 0x110
51 #define CSI2RX_IRQ_MASK_ALL 0x1ff
52 #define CSI2RX_IRQ_MASK_ULPS_STATUS_CHANGE 0x8
53 #define CSI2RX_ULPS_STATUS 0x114
54 #define CSI2RX_PPI_ERRSOT_HS 0x118
55 #define CSI2RX_PPI_ERRSOTSYNC_HS 0x11c
56 #define CSI2RX_PPI_ERRESC 0x120
57 #define CSI2RX_PPI_ERRSYNCESC 0x124
58 #define CSI2RX_PPI_ERRCONTROL 0x128
59 #define CSI2RX_CFG_DISABLE_PAYLOAD_0 0x12c
60 #define CSI2RX_CFG_VID_VC_IGNORE 0x180
61 #define CSI2RX_CFG_VID_VC 0x184
62 #define CSI2RX_CFG_VID_P_FIFO_SEND_LEVEL 0x188
63 #define CSI2RX_CFG_DISABLE_PAYLOAD_1 0x130
71 enum imx8mq_mipi_csi_clk
{
78 static const char * const imx8mq_mipi_csi_clk_id
[CSI2_NUM_CLKS
] = {
79 [CSI2_CLK_CORE
] = "core",
80 [CSI2_CLK_ESC
] = "esc",
84 #define CSI2_NUM_CLKS ARRAY_SIZE(imx8mq_mipi_csi_clk_id)
86 #define GPR_CSI2_1_RX_ENABLE BIT(13)
87 #define GPR_CSI2_1_VID_INTFC_ENB BIT(12)
88 #define GPR_CSI2_1_HSEL BIT(10)
89 #define GPR_CSI2_1_CONT_CLK_MODE BIT(8)
90 #define GPR_CSI2_1_S_PRG_RXHS_SETTLE(x) (((x) & 0x3f) << 2)
93 * The send level configures the number of entries that must accumulate in
94 * the Pixel FIFO before the data will be transferred to the video output.
95 * The exact value needed for this configuration is dependent on the rate at
96 * which the sensor transfers data to the CSI-2 Controller and the user
99 * The calculation is the classical rate-in rate-out type of problem: If the
100 * video bandwidth is 10% faster than the incoming mipi data and the video
101 * line length is 500 pixels, then the fifo should be allowed to fill
102 * 10% of the line length or 50 pixels. If the gap data is ok, then the level
103 * can be set to 16 and ignored.
105 #define CSI2RX_SEND_LEVEL 64
110 struct clk_bulk_data clks
[CSI2_NUM_CLKS
];
111 struct reset_control
*rst
;
112 struct regulator
*mipi_phy_regulator
;
114 struct v4l2_subdev sd
;
115 struct media_pad pads
[MIPI_CSI2_PADS_NUM
];
116 struct v4l2_async_notifier notifier
;
117 struct v4l2_subdev
*src_sd
;
119 struct v4l2_mbus_config_mipi_csi2 bus
;
121 struct mutex lock
; /* Protect state */
124 struct regmap
*phy_gpr
;
127 struct icc_path
*icc_path
;
131 /* -----------------------------------------------------------------------------
135 struct csi2_pix_format
{
140 static const struct csi2_pix_format imx8mq_mipi_csi_formats
[] = {
141 /* RAW (Bayer and greyscale) formats. */
143 .code
= MEDIA_BUS_FMT_SBGGR8_1X8
,
146 .code
= MEDIA_BUS_FMT_SGBRG8_1X8
,
149 .code
= MEDIA_BUS_FMT_SGRBG8_1X8
,
152 .code
= MEDIA_BUS_FMT_SRGGB8_1X8
,
155 .code
= MEDIA_BUS_FMT_Y8_1X8
,
158 .code
= MEDIA_BUS_FMT_SBGGR10_1X10
,
161 .code
= MEDIA_BUS_FMT_SGBRG10_1X10
,
164 .code
= MEDIA_BUS_FMT_SGRBG10_1X10
,
167 .code
= MEDIA_BUS_FMT_SRGGB10_1X10
,
170 .code
= MEDIA_BUS_FMT_Y10_1X10
,
173 .code
= MEDIA_BUS_FMT_SBGGR12_1X12
,
176 .code
= MEDIA_BUS_FMT_SGBRG12_1X12
,
179 .code
= MEDIA_BUS_FMT_SGRBG12_1X12
,
182 .code
= MEDIA_BUS_FMT_SRGGB12_1X12
,
185 .code
= MEDIA_BUS_FMT_Y12_1X12
,
188 .code
= MEDIA_BUS_FMT_SBGGR14_1X14
,
191 .code
= MEDIA_BUS_FMT_SGBRG14_1X14
,
194 .code
= MEDIA_BUS_FMT_SGRBG14_1X14
,
197 .code
= MEDIA_BUS_FMT_SRGGB14_1X14
,
202 .code
= MEDIA_BUS_FMT_YUYV8_1X16
,
205 .code
= MEDIA_BUS_FMT_UYVY8_1X16
,
210 static const struct csi2_pix_format
*find_csi2_format(u32 code
)
214 for (i
= 0; i
< ARRAY_SIZE(imx8mq_mipi_csi_formats
); i
++)
215 if (code
== imx8mq_mipi_csi_formats
[i
].code
)
216 return &imx8mq_mipi_csi_formats
[i
];
220 /* -----------------------------------------------------------------------------
221 * Hardware configuration
224 static inline void imx8mq_mipi_csi_write(struct csi_state
*state
, u32 reg
, u32 val
)
226 writel(val
, state
->regs
+ reg
);
229 static int imx8mq_mipi_csi_sw_reset(struct csi_state
*state
)
234 * these are most likely self-clearing reset bits. to make it
235 * more clear, the reset-imx7 driver should implement the
236 * .reset() operation.
238 ret
= reset_control_assert(state
->rst
);
240 dev_err(state
->dev
, "Failed to assert resets: %d\n", ret
);
247 static void imx8mq_mipi_csi_set_params(struct csi_state
*state
)
249 int lanes
= state
->bus
.num_data_lanes
;
251 imx8mq_mipi_csi_write(state
, CSI2RX_CFG_NUM_LANES
, lanes
- 1);
252 imx8mq_mipi_csi_write(state
, CSI2RX_CFG_DISABLE_DATA_LANES
,
253 (0xf << lanes
) & 0xf);
254 imx8mq_mipi_csi_write(state
, CSI2RX_IRQ_MASK
, CSI2RX_IRQ_MASK_ALL
);
256 * 0x180 bit 0 controls the Virtual Channel behaviour: when set the
257 * interface ignores the Virtual Channel (VC) field in received packets;
258 * when cleared it causes the interface to only accept packets whose VC
259 * matches the value to which VC is set at offset 0x184.
261 imx8mq_mipi_csi_write(state
, CSI2RX_CFG_VID_VC_IGNORE
, 1);
262 imx8mq_mipi_csi_write(state
, CSI2RX_CFG_VID_P_FIFO_SEND_LEVEL
,
266 static int imx8mq_mipi_csi_clk_enable(struct csi_state
*state
)
268 return clk_bulk_prepare_enable(CSI2_NUM_CLKS
, state
->clks
);
271 static void imx8mq_mipi_csi_clk_disable(struct csi_state
*state
)
273 clk_bulk_disable_unprepare(CSI2_NUM_CLKS
, state
->clks
);
276 static int imx8mq_mipi_csi_clk_get(struct csi_state
*state
)
280 for (i
= 0; i
< CSI2_NUM_CLKS
; i
++)
281 state
->clks
[i
].id
= imx8mq_mipi_csi_clk_id
[i
];
283 return devm_clk_bulk_get(state
->dev
, CSI2_NUM_CLKS
, state
->clks
);
286 static int imx8mq_mipi_csi_calc_hs_settle(struct csi_state
*state
,
287 struct v4l2_subdev_state
*sd_state
,
292 unsigned long esc_clk_rate
;
293 u32 min_ths_settle
, max_ths_settle
, ths_settle_ns
, esc_clk_period_ns
;
294 const struct v4l2_mbus_framefmt
*fmt
;
295 const struct csi2_pix_format
*csi2_fmt
;
297 /* Calculate the line rate from the pixel rate. */
299 fmt
= v4l2_subdev_state_get_format(sd_state
, MIPI_CSI2_PAD_SINK
);
300 csi2_fmt
= find_csi2_format(fmt
->code
);
302 link_freq
= v4l2_get_link_freq(state
->src_sd
->ctrl_handler
,
304 state
->bus
.num_data_lanes
* 2);
306 dev_err(state
->dev
, "Unable to obtain link frequency: %d\n",
311 lane_rate
= link_freq
* 2;
312 if (lane_rate
< 80000000 || lane_rate
> 1500000000) {
313 dev_dbg(state
->dev
, "Out-of-bound lane rate %u\n", lane_rate
);
318 * The D-PHY specification requires Ths-settle to be in the range
319 * 85ns + 6*UI to 140ns + 10*UI, with the unit interval UI being half
322 * The Ths-settle value is expressed in the hardware as a multiple of
323 * the Esc clock period:
325 * Ths-settle = (PRG_RXHS_SETTLE + 1) * Tperiod of RxClkInEsc
327 * Due to the one cycle inaccuracy introduced by rounding, the
328 * documentation recommends picking a value away from the boundaries.
329 * Let's pick the average.
331 esc_clk_rate
= clk_get_rate(state
->clks
[CSI2_CLK_ESC
].clk
);
333 dev_err(state
->dev
, "Could not get esc clock rate.\n");
337 dev_dbg(state
->dev
, "esc clk rate: %lu\n", esc_clk_rate
);
338 esc_clk_period_ns
= 1000000000 / esc_clk_rate
;
340 min_ths_settle
= 85 + 6 * 1000000 / (lane_rate
/ 1000);
341 max_ths_settle
= 140 + 10 * 1000000 / (lane_rate
/ 1000);
342 ths_settle_ns
= (min_ths_settle
+ max_ths_settle
) / 2;
344 *hs_settle
= ths_settle_ns
/ esc_clk_period_ns
- 1;
346 dev_dbg(state
->dev
, "lane rate %u Ths_settle %u hs_settle %u\n",
347 lane_rate
, ths_settle_ns
, *hs_settle
);
352 static int imx8mq_mipi_csi_start_stream(struct csi_state
*state
,
353 struct v4l2_subdev_state
*sd_state
)
358 ret
= imx8mq_mipi_csi_sw_reset(state
);
362 imx8mq_mipi_csi_set_params(state
);
363 ret
= imx8mq_mipi_csi_calc_hs_settle(state
, sd_state
, &hs_settle
);
367 regmap_update_bits(state
->phy_gpr
,
370 GPR_CSI2_1_RX_ENABLE
|
371 GPR_CSI2_1_VID_INTFC_ENB
|
373 GPR_CSI2_1_CONT_CLK_MODE
|
374 GPR_CSI2_1_S_PRG_RXHS_SETTLE(hs_settle
));
379 static void imx8mq_mipi_csi_stop_stream(struct csi_state
*state
)
381 imx8mq_mipi_csi_write(state
, CSI2RX_CFG_DISABLE_DATA_LANES
, 0xf);
384 /* -----------------------------------------------------------------------------
385 * V4L2 subdev operations
388 static struct csi_state
*mipi_sd_to_csi2_state(struct v4l2_subdev
*sdev
)
390 return container_of(sdev
, struct csi_state
, sd
);
393 static int imx8mq_mipi_csi_s_stream(struct v4l2_subdev
*sd
, int enable
)
395 struct csi_state
*state
= mipi_sd_to_csi2_state(sd
);
396 struct v4l2_subdev_state
*sd_state
;
400 ret
= pm_runtime_resume_and_get(state
->dev
);
405 mutex_lock(&state
->lock
);
408 if (state
->state
& ST_SUSPENDED
) {
413 sd_state
= v4l2_subdev_lock_and_get_active_state(sd
);
414 ret
= imx8mq_mipi_csi_start_stream(state
, sd_state
);
415 v4l2_subdev_unlock_state(sd_state
);
420 ret
= v4l2_subdev_call(state
->src_sd
, video
, s_stream
, 1);
424 state
->state
|= ST_STREAMING
;
426 v4l2_subdev_call(state
->src_sd
, video
, s_stream
, 0);
427 imx8mq_mipi_csi_stop_stream(state
);
428 state
->state
&= ~ST_STREAMING
;
432 mutex_unlock(&state
->lock
);
434 if (!enable
|| ret
< 0)
435 pm_runtime_put(state
->dev
);
440 static int imx8mq_mipi_csi_init_state(struct v4l2_subdev
*sd
,
441 struct v4l2_subdev_state
*sd_state
)
443 struct v4l2_mbus_framefmt
*fmt_sink
;
444 struct v4l2_mbus_framefmt
*fmt_source
;
446 fmt_sink
= v4l2_subdev_state_get_format(sd_state
, MIPI_CSI2_PAD_SINK
);
447 fmt_source
= v4l2_subdev_state_get_format(sd_state
,
448 MIPI_CSI2_PAD_SOURCE
);
450 fmt_sink
->code
= MEDIA_BUS_FMT_SGBRG10_1X10
;
451 fmt_sink
->width
= MIPI_CSI2_DEF_PIX_WIDTH
;
452 fmt_sink
->height
= MIPI_CSI2_DEF_PIX_HEIGHT
;
453 fmt_sink
->field
= V4L2_FIELD_NONE
;
455 fmt_sink
->colorspace
= V4L2_COLORSPACE_RAW
;
456 fmt_sink
->xfer_func
= V4L2_MAP_XFER_FUNC_DEFAULT(fmt_sink
->colorspace
);
457 fmt_sink
->ycbcr_enc
= V4L2_MAP_YCBCR_ENC_DEFAULT(fmt_sink
->colorspace
);
458 fmt_sink
->quantization
=
459 V4L2_MAP_QUANTIZATION_DEFAULT(false, fmt_sink
->colorspace
,
460 fmt_sink
->ycbcr_enc
);
462 *fmt_source
= *fmt_sink
;
467 static int imx8mq_mipi_csi_enum_mbus_code(struct v4l2_subdev
*sd
,
468 struct v4l2_subdev_state
*sd_state
,
469 struct v4l2_subdev_mbus_code_enum
*code
)
472 * We can't transcode in any way, the source format is identical
473 * to the sink format.
475 if (code
->pad
== MIPI_CSI2_PAD_SOURCE
) {
476 struct v4l2_mbus_framefmt
*fmt
;
481 fmt
= v4l2_subdev_state_get_format(sd_state
, code
->pad
);
482 code
->code
= fmt
->code
;
486 if (code
->pad
!= MIPI_CSI2_PAD_SINK
)
489 if (code
->index
>= ARRAY_SIZE(imx8mq_mipi_csi_formats
))
492 code
->code
= imx8mq_mipi_csi_formats
[code
->index
].code
;
497 static int imx8mq_mipi_csi_set_fmt(struct v4l2_subdev
*sd
,
498 struct v4l2_subdev_state
*sd_state
,
499 struct v4l2_subdev_format
*sdformat
)
501 const struct csi2_pix_format
*csi2_fmt
;
502 struct v4l2_mbus_framefmt
*fmt
;
505 * The device can't transcode in any way, the source format can't be
508 if (sdformat
->pad
== MIPI_CSI2_PAD_SOURCE
)
509 return v4l2_subdev_get_fmt(sd
, sd_state
, sdformat
);
511 if (sdformat
->pad
!= MIPI_CSI2_PAD_SINK
)
514 csi2_fmt
= find_csi2_format(sdformat
->format
.code
);
516 csi2_fmt
= &imx8mq_mipi_csi_formats
[0];
518 fmt
= v4l2_subdev_state_get_format(sd_state
, sdformat
->pad
);
520 fmt
->code
= csi2_fmt
->code
;
521 fmt
->width
= sdformat
->format
.width
;
522 fmt
->height
= sdformat
->format
.height
;
524 sdformat
->format
= *fmt
;
526 /* Propagate the format from sink to source. */
527 fmt
= v4l2_subdev_state_get_format(sd_state
, MIPI_CSI2_PAD_SOURCE
);
528 *fmt
= sdformat
->format
;
533 static const struct v4l2_subdev_video_ops imx8mq_mipi_csi_video_ops
= {
534 .s_stream
= imx8mq_mipi_csi_s_stream
,
537 static const struct v4l2_subdev_pad_ops imx8mq_mipi_csi_pad_ops
= {
538 .enum_mbus_code
= imx8mq_mipi_csi_enum_mbus_code
,
539 .get_fmt
= v4l2_subdev_get_fmt
,
540 .set_fmt
= imx8mq_mipi_csi_set_fmt
,
543 static const struct v4l2_subdev_ops imx8mq_mipi_csi_subdev_ops
= {
544 .video
= &imx8mq_mipi_csi_video_ops
,
545 .pad
= &imx8mq_mipi_csi_pad_ops
,
548 static const struct v4l2_subdev_internal_ops imx8mq_mipi_csi_internal_ops
= {
549 .init_state
= imx8mq_mipi_csi_init_state
,
552 /* -----------------------------------------------------------------------------
553 * Media entity operations
556 static const struct media_entity_operations imx8mq_mipi_csi_entity_ops
= {
557 .link_validate
= v4l2_subdev_link_validate
,
558 .get_fwnode_pad
= v4l2_subdev_get_fwnode_pad_1_to_1
,
561 /* -----------------------------------------------------------------------------
562 * Async subdev notifier
565 static struct csi_state
*
566 mipi_notifier_to_csi2_state(struct v4l2_async_notifier
*n
)
568 return container_of(n
, struct csi_state
, notifier
);
571 static int imx8mq_mipi_csi_notify_bound(struct v4l2_async_notifier
*notifier
,
572 struct v4l2_subdev
*sd
,
573 struct v4l2_async_connection
*asd
)
575 struct csi_state
*state
= mipi_notifier_to_csi2_state(notifier
);
576 struct media_pad
*sink
= &state
->sd
.entity
.pads
[MIPI_CSI2_PAD_SINK
];
580 return v4l2_create_fwnode_links_to_pad(sd
, sink
, MEDIA_LNK_FL_ENABLED
|
581 MEDIA_LNK_FL_IMMUTABLE
);
584 static const struct v4l2_async_notifier_operations imx8mq_mipi_csi_notify_ops
= {
585 .bound
= imx8mq_mipi_csi_notify_bound
,
588 static int imx8mq_mipi_csi_async_register(struct csi_state
*state
)
590 struct v4l2_fwnode_endpoint vep
= {
591 .bus_type
= V4L2_MBUS_CSI2_DPHY
,
593 struct v4l2_async_connection
*asd
;
594 struct fwnode_handle
*ep
;
598 v4l2_async_subdev_nf_init(&state
->notifier
, &state
->sd
);
600 ep
= fwnode_graph_get_endpoint_by_id(dev_fwnode(state
->dev
), 0, 0,
601 FWNODE_GRAPH_ENDPOINT_NEXT
);
605 ret
= v4l2_fwnode_endpoint_parse(ep
, &vep
);
609 for (i
= 0; i
< vep
.bus
.mipi_csi2
.num_data_lanes
; ++i
) {
610 if (vep
.bus
.mipi_csi2
.data_lanes
[i
] != i
+ 1) {
612 "data lanes reordering is not supported");
618 state
->bus
= vep
.bus
.mipi_csi2
;
620 dev_dbg(state
->dev
, "data lanes: %d flags: 0x%08x\n",
621 state
->bus
.num_data_lanes
,
624 asd
= v4l2_async_nf_add_fwnode_remote(&state
->notifier
, ep
,
625 struct v4l2_async_connection
);
631 fwnode_handle_put(ep
);
633 state
->notifier
.ops
= &imx8mq_mipi_csi_notify_ops
;
635 ret
= v4l2_async_nf_register(&state
->notifier
);
639 return v4l2_async_register_subdev(&state
->sd
);
642 fwnode_handle_put(ep
);
647 /* -----------------------------------------------------------------------------
651 static void imx8mq_mipi_csi_pm_suspend(struct device
*dev
)
653 struct v4l2_subdev
*sd
= dev_get_drvdata(dev
);
654 struct csi_state
*state
= mipi_sd_to_csi2_state(sd
);
656 mutex_lock(&state
->lock
);
658 if (state
->state
& ST_POWERED
) {
659 imx8mq_mipi_csi_stop_stream(state
);
660 imx8mq_mipi_csi_clk_disable(state
);
661 state
->state
&= ~ST_POWERED
;
664 mutex_unlock(&state
->lock
);
667 static int imx8mq_mipi_csi_pm_resume(struct device
*dev
)
669 struct v4l2_subdev
*sd
= dev_get_drvdata(dev
);
670 struct csi_state
*state
= mipi_sd_to_csi2_state(sd
);
671 struct v4l2_subdev_state
*sd_state
;
674 mutex_lock(&state
->lock
);
676 if (!(state
->state
& ST_POWERED
)) {
677 state
->state
|= ST_POWERED
;
678 ret
= imx8mq_mipi_csi_clk_enable(state
);
680 if (state
->state
& ST_STREAMING
) {
681 sd_state
= v4l2_subdev_lock_and_get_active_state(sd
);
682 ret
= imx8mq_mipi_csi_start_stream(state
, sd_state
);
683 v4l2_subdev_unlock_state(sd_state
);
688 state
->state
&= ~ST_SUSPENDED
;
691 mutex_unlock(&state
->lock
);
693 return ret
? -EAGAIN
: 0;
696 static int imx8mq_mipi_csi_suspend(struct device
*dev
)
698 struct v4l2_subdev
*sd
= dev_get_drvdata(dev
);
699 struct csi_state
*state
= mipi_sd_to_csi2_state(sd
);
701 imx8mq_mipi_csi_pm_suspend(dev
);
703 state
->state
|= ST_SUSPENDED
;
708 static int imx8mq_mipi_csi_resume(struct device
*dev
)
710 struct v4l2_subdev
*sd
= dev_get_drvdata(dev
);
711 struct csi_state
*state
= mipi_sd_to_csi2_state(sd
);
713 if (!(state
->state
& ST_SUSPENDED
))
716 return imx8mq_mipi_csi_pm_resume(dev
);
719 static int imx8mq_mipi_csi_runtime_suspend(struct device
*dev
)
721 struct v4l2_subdev
*sd
= dev_get_drvdata(dev
);
722 struct csi_state
*state
= mipi_sd_to_csi2_state(sd
);
725 imx8mq_mipi_csi_pm_suspend(dev
);
727 ret
= icc_set_bw(state
->icc_path
, 0, 0);
729 dev_err(dev
, "icc_set_bw failed with %d\n", ret
);
734 static int imx8mq_mipi_csi_runtime_resume(struct device
*dev
)
736 struct v4l2_subdev
*sd
= dev_get_drvdata(dev
);
737 struct csi_state
*state
= mipi_sd_to_csi2_state(sd
);
740 ret
= icc_set_bw(state
->icc_path
, 0, state
->icc_path_bw
);
742 dev_err(dev
, "icc_set_bw failed with %d\n", ret
);
746 return imx8mq_mipi_csi_pm_resume(dev
);
749 static const struct dev_pm_ops imx8mq_mipi_csi_pm_ops
= {
750 RUNTIME_PM_OPS(imx8mq_mipi_csi_runtime_suspend
,
751 imx8mq_mipi_csi_runtime_resume
, NULL
)
752 SYSTEM_SLEEP_PM_OPS(imx8mq_mipi_csi_suspend
, imx8mq_mipi_csi_resume
)
755 /* -----------------------------------------------------------------------------
756 * Probe/remove & platform driver
759 static int imx8mq_mipi_csi_subdev_init(struct csi_state
*state
)
761 struct v4l2_subdev
*sd
= &state
->sd
;
764 v4l2_subdev_init(sd
, &imx8mq_mipi_csi_subdev_ops
);
765 sd
->internal_ops
= &imx8mq_mipi_csi_internal_ops
;
766 sd
->owner
= THIS_MODULE
;
767 snprintf(sd
->name
, sizeof(sd
->name
), "%s %s",
768 MIPI_CSI2_SUBDEV_NAME
, dev_name(state
->dev
));
770 sd
->flags
|= V4L2_SUBDEV_FL_HAS_DEVNODE
;
772 sd
->entity
.function
= MEDIA_ENT_F_VID_IF_BRIDGE
;
773 sd
->entity
.ops
= &imx8mq_mipi_csi_entity_ops
;
775 sd
->dev
= state
->dev
;
777 state
->pads
[MIPI_CSI2_PAD_SINK
].flags
= MEDIA_PAD_FL_SINK
778 | MEDIA_PAD_FL_MUST_CONNECT
;
779 state
->pads
[MIPI_CSI2_PAD_SOURCE
].flags
= MEDIA_PAD_FL_SOURCE
780 | MEDIA_PAD_FL_MUST_CONNECT
;
781 ret
= media_entity_pads_init(&sd
->entity
, MIPI_CSI2_PADS_NUM
,
786 ret
= v4l2_subdev_init_finalize(sd
);
788 media_entity_cleanup(&sd
->entity
);
795 static void imx8mq_mipi_csi_release_icc(struct platform_device
*pdev
)
797 struct v4l2_subdev
*sd
= dev_get_drvdata(&pdev
->dev
);
798 struct csi_state
*state
= mipi_sd_to_csi2_state(sd
);
800 icc_put(state
->icc_path
);
803 static int imx8mq_mipi_csi_init_icc(struct platform_device
*pdev
)
805 struct v4l2_subdev
*sd
= dev_get_drvdata(&pdev
->dev
);
806 struct csi_state
*state
= mipi_sd_to_csi2_state(sd
);
808 /* Optional interconnect request */
809 state
->icc_path
= of_icc_get(&pdev
->dev
, "dram");
810 if (IS_ERR_OR_NULL(state
->icc_path
))
811 return PTR_ERR_OR_ZERO(state
->icc_path
);
813 state
->icc_path_bw
= MBps_to_icc(700);
818 static int imx8mq_mipi_csi_parse_dt(struct csi_state
*state
)
820 struct device
*dev
= state
->dev
;
821 struct device_node
*np
= state
->dev
->of_node
;
822 struct device_node
*node
;
827 state
->rst
= devm_reset_control_array_get_exclusive(dev
);
828 if (IS_ERR(state
->rst
)) {
829 dev_err(dev
, "Failed to get reset: %pe\n", state
->rst
);
830 return PTR_ERR(state
->rst
);
833 ret
= of_property_read_u32_array(np
, "fsl,mipi-phy-gpr", out_val
,
834 ARRAY_SIZE(out_val
));
836 dev_err(dev
, "no fsl,mipi-phy-gpr property found: %d\n", ret
);
842 node
= of_find_node_by_phandle(ph
);
844 dev_err(dev
, "Error finding node by phandle\n");
847 state
->phy_gpr
= syscon_node_to_regmap(node
);
849 if (IS_ERR(state
->phy_gpr
)) {
850 dev_err(dev
, "failed to get gpr regmap: %pe\n", state
->phy_gpr
);
851 return PTR_ERR(state
->phy_gpr
);
854 state
->phy_gpr_reg
= out_val
[1];
855 dev_dbg(dev
, "phy gpr register set to 0x%x\n", state
->phy_gpr_reg
);
860 static int imx8mq_mipi_csi_probe(struct platform_device
*pdev
)
862 struct device
*dev
= &pdev
->dev
;
863 struct csi_state
*state
;
866 state
= devm_kzalloc(dev
, sizeof(*state
), GFP_KERNEL
);
872 ret
= imx8mq_mipi_csi_parse_dt(state
);
874 dev_err(dev
, "Failed to parse device tree: %d\n", ret
);
878 /* Acquire resources. */
879 state
->regs
= devm_platform_ioremap_resource(pdev
, 0);
880 if (IS_ERR(state
->regs
))
881 return PTR_ERR(state
->regs
);
883 ret
= imx8mq_mipi_csi_clk_get(state
);
887 platform_set_drvdata(pdev
, &state
->sd
);
889 mutex_init(&state
->lock
);
891 ret
= imx8mq_mipi_csi_subdev_init(state
);
895 ret
= imx8mq_mipi_csi_init_icc(pdev
);
899 /* Enable runtime PM. */
900 pm_runtime_enable(dev
);
901 if (!pm_runtime_enabled(dev
)) {
902 ret
= imx8mq_mipi_csi_runtime_resume(dev
);
907 ret
= imx8mq_mipi_csi_async_register(state
);
914 pm_runtime_disable(&pdev
->dev
);
915 imx8mq_mipi_csi_runtime_suspend(&pdev
->dev
);
917 media_entity_cleanup(&state
->sd
.entity
);
918 v4l2_subdev_cleanup(&state
->sd
);
919 v4l2_async_nf_unregister(&state
->notifier
);
920 v4l2_async_nf_cleanup(&state
->notifier
);
921 v4l2_async_unregister_subdev(&state
->sd
);
923 imx8mq_mipi_csi_release_icc(pdev
);
925 mutex_destroy(&state
->lock
);
930 static void imx8mq_mipi_csi_remove(struct platform_device
*pdev
)
932 struct v4l2_subdev
*sd
= platform_get_drvdata(pdev
);
933 struct csi_state
*state
= mipi_sd_to_csi2_state(sd
);
935 v4l2_async_nf_unregister(&state
->notifier
);
936 v4l2_async_nf_cleanup(&state
->notifier
);
937 v4l2_async_unregister_subdev(&state
->sd
);
939 pm_runtime_disable(&pdev
->dev
);
940 imx8mq_mipi_csi_runtime_suspend(&pdev
->dev
);
941 media_entity_cleanup(&state
->sd
.entity
);
942 v4l2_subdev_cleanup(&state
->sd
);
943 mutex_destroy(&state
->lock
);
944 pm_runtime_set_suspended(&pdev
->dev
);
945 imx8mq_mipi_csi_release_icc(pdev
);
948 static const struct of_device_id imx8mq_mipi_csi_of_match
[] = {
949 { .compatible
= "fsl,imx8mq-mipi-csi2", },
952 MODULE_DEVICE_TABLE(of
, imx8mq_mipi_csi_of_match
);
954 static struct platform_driver imx8mq_mipi_csi_driver
= {
955 .probe
= imx8mq_mipi_csi_probe
,
956 .remove_new
= imx8mq_mipi_csi_remove
,
958 .of_match_table
= imx8mq_mipi_csi_of_match
,
959 .name
= MIPI_CSI2_DRIVER_NAME
,
960 .pm
= pm_ptr(&imx8mq_mipi_csi_pm_ops
),
964 module_platform_driver(imx8mq_mipi_csi_driver
);
966 MODULE_DESCRIPTION("i.MX8MQ MIPI CSI-2 receiver driver");
967 MODULE_AUTHOR("Martin Kepplinger <martin.kepplinger@puri.sm>");
968 MODULE_LICENSE("GPL v2");
969 MODULE_ALIAS("platform:imx8mq-mipi-csi2");