1// SPDX-License-Identifier: GPL-2.0
2/*
3 * NXP i.MX8MQ SoC series MIPI-CSI2 receiver driver
4 *
5 * Copyright (C) 2021 Purism SPC
6 */
7
8#include <linux/clk.h>
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>
14#include <linux/io.h>
15#include <linux/kernel.h>
16#include <linux/mfd/syscon.h>
17#include <linux/module.h>
18#include <linux/mutex.h>
19#include <linux/of.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>
26
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>
32
33#define MIPI_CSI2_DRIVER_NAME			"imx8mq-mipi-csi2"
34#define MIPI_CSI2_SUBDEV_NAME			MIPI_CSI2_DRIVER_NAME
35
36#define MIPI_CSI2_PAD_SINK			0
37#define MIPI_CSI2_PAD_SOURCE			1
38#define MIPI_CSI2_PADS_NUM			2
39
40#define MIPI_CSI2_DEF_PIX_WIDTH			640
41#define MIPI_CSI2_DEF_PIX_HEIGHT		480
42
43/* Register map definition */
44
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
64
65enum {
66	ST_POWERED	= 1,
67	ST_STREAMING	= 2,
68	ST_SUSPENDED	= 4,
69};
70
71enum imx8mq_mipi_csi_clk {
72	CSI2_CLK_CORE,
73	CSI2_CLK_ESC,
74	CSI2_CLK_UI,
75	CSI2_NUM_CLKS,
76};
77
78static const char * const imx8mq_mipi_csi_clk_id[CSI2_NUM_CLKS] = {
79	[CSI2_CLK_CORE] = "core",
80	[CSI2_CLK_ESC] = "esc",
81	[CSI2_CLK_UI] = "ui",
82};
83
84#define CSI2_NUM_CLKS	ARRAY_SIZE(imx8mq_mipi_csi_clk_id)
85
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)
91
92/*
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
97 * video clock.
98 *
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.
104 */
105#define CSI2RX_SEND_LEVEL			64
106
107struct csi_state {
108	struct device *dev;
109	void __iomem *regs;
110	struct clk_bulk_data clks[CSI2_NUM_CLKS];
111	struct reset_control *rst;
112	struct regulator *mipi_phy_regulator;
113
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;
118
119	struct v4l2_mbus_config_mipi_csi2 bus;
120
121	struct mutex lock; /* Protect state */
122	u32 state;
123
124	struct regmap *phy_gpr;
125	u8 phy_gpr_reg;
126
127	struct icc_path			*icc_path;
128	s32				icc_path_bw;
129};
130
131/* -----------------------------------------------------------------------------
132 * Format helpers
133 */
134
135struct csi2_pix_format {
136	u32 code;
137	u8 width;
138};
139
140static const struct csi2_pix_format imx8mq_mipi_csi_formats[] = {
141	/* RAW (Bayer and greyscale) formats. */
142	{
143		.code = MEDIA_BUS_FMT_SBGGR8_1X8,
144		.width = 8,
145	}, {
146		.code = MEDIA_BUS_FMT_SGBRG8_1X8,
147		.width = 8,
148	}, {
149		.code = MEDIA_BUS_FMT_SGRBG8_1X8,
150		.width = 8,
151	}, {
152		.code = MEDIA_BUS_FMT_SRGGB8_1X8,
153		.width = 8,
154	}, {
155		.code = MEDIA_BUS_FMT_Y8_1X8,
156		.width = 8,
157	}, {
158		.code = MEDIA_BUS_FMT_SBGGR10_1X10,
159		.width = 10,
160	}, {
161		.code = MEDIA_BUS_FMT_SGBRG10_1X10,
162		.width = 10,
163	}, {
164		.code = MEDIA_BUS_FMT_SGRBG10_1X10,
165		.width = 10,
166	}, {
167		.code = MEDIA_BUS_FMT_SRGGB10_1X10,
168		.width = 10,
169	}, {
170		.code = MEDIA_BUS_FMT_Y10_1X10,
171		.width = 10,
172	}, {
173		.code = MEDIA_BUS_FMT_SBGGR12_1X12,
174		.width = 12,
175	}, {
176		.code = MEDIA_BUS_FMT_SGBRG12_1X12,
177		.width = 12,
178	}, {
179		.code = MEDIA_BUS_FMT_SGRBG12_1X12,
180		.width = 12,
181	}, {
182		.code = MEDIA_BUS_FMT_SRGGB12_1X12,
183		.width = 12,
184	}, {
185		.code = MEDIA_BUS_FMT_Y12_1X12,
186		.width = 12,
187	}, {
188		.code = MEDIA_BUS_FMT_SBGGR14_1X14,
189		.width = 14,
190	}, {
191		.code = MEDIA_BUS_FMT_SGBRG14_1X14,
192		.width = 14,
193	}, {
194		.code = MEDIA_BUS_FMT_SGRBG14_1X14,
195		.width = 14,
196	}, {
197		.code = MEDIA_BUS_FMT_SRGGB14_1X14,
198		.width = 14,
199	},
200	/* YUV formats */
201	{
202		.code = MEDIA_BUS_FMT_YUYV8_1X16,
203		.width = 16,
204	}, {
205		.code = MEDIA_BUS_FMT_UYVY8_1X16,
206		.width = 16,
207	}
208};
209
210static const struct csi2_pix_format *find_csi2_format(u32 code)
211{
212	unsigned int i;
213
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];
217	return NULL;
218}
219
220/* -----------------------------------------------------------------------------
221 * Hardware configuration
222 */
223
224static inline void imx8mq_mipi_csi_write(struct csi_state *state, u32 reg, u32 val)
225{
226	writel(val, state->regs + reg);
227}
228
229static int imx8mq_mipi_csi_sw_reset(struct csi_state *state)
230{
231	int ret;
232
233	/*
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.
237	 */
238	ret = reset_control_assert(state->rst);
239	if (ret < 0) {
240		dev_err(state->dev, "Failed to assert resets: %d\n", ret);
241		return ret;
242	}
243
244	return 0;
245}
246
247static void imx8mq_mipi_csi_set_params(struct csi_state *state)
248{
249	int lanes = state->bus.num_data_lanes;
250
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);
255	/*
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.
260	 */
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,
263			      CSI2RX_SEND_LEVEL);
264}
265
266static int imx8mq_mipi_csi_clk_enable(struct csi_state *state)
267{
268	return clk_bulk_prepare_enable(CSI2_NUM_CLKS, state->clks);
269}
270
271static void imx8mq_mipi_csi_clk_disable(struct csi_state *state)
272{
273	clk_bulk_disable_unprepare(CSI2_NUM_CLKS, state->clks);
274}
275
276static int imx8mq_mipi_csi_clk_get(struct csi_state *state)
277{
278	unsigned int i;
279
280	for (i = 0; i < CSI2_NUM_CLKS; i++)
281		state->clks[i].id = imx8mq_mipi_csi_clk_id[i];
282
283	return devm_clk_bulk_get(state->dev, CSI2_NUM_CLKS, state->clks);
284}
285
286static int imx8mq_mipi_csi_calc_hs_settle(struct csi_state *state,
287					  struct v4l2_subdev_state *sd_state,
288					  u32 *hs_settle)
289{
290	s64 link_freq;
291	u32 lane_rate;
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;
296
297	/* Calculate the line rate from the pixel rate. */
298
299	fmt = v4l2_subdev_get_pad_format(&state->sd, sd_state, MIPI_CSI2_PAD_SINK);
300	csi2_fmt = find_csi2_format(fmt->code);
301
302	link_freq = v4l2_get_link_freq(state->src_sd->ctrl_handler,
303				       csi2_fmt->width,
304				       state->bus.num_data_lanes * 2);
305	if (link_freq < 0) {
306		dev_err(state->dev, "Unable to obtain link frequency: %d\n",
307			(int)link_freq);
308		return link_freq;
309	}
310
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);
314		return -EINVAL;
315	}
316
317	/*
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
320	 * the clock period.
321	 *
322	 * The Ths-settle value is expressed in the hardware as a multiple of
323	 * the Esc clock period:
324	 *
325	 * Ths-settle = (PRG_RXHS_SETTLE + 1) * Tperiod of RxClkInEsc
326	 *
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.
330	 */
331	esc_clk_rate = clk_get_rate(state->clks[CSI2_CLK_ESC].clk);
332	if (!esc_clk_rate) {
333		dev_err(state->dev, "Could not get esc clock rate.\n");
334		return -EINVAL;
335	}
336
337	dev_dbg(state->dev, "esc clk rate: %lu\n", esc_clk_rate);
338	esc_clk_period_ns = 1000000000 / esc_clk_rate;
339
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;
343
344	*hs_settle = ths_settle_ns / esc_clk_period_ns - 1;
345
346	dev_dbg(state->dev, "lane rate %u Ths_settle %u hs_settle %u\n",
347		lane_rate, ths_settle_ns, *hs_settle);
348
349	return 0;
350}
351
352static int imx8mq_mipi_csi_start_stream(struct csi_state *state,
353					struct v4l2_subdev_state *sd_state)
354{
355	int ret;
356	u32 hs_settle = 0;
357
358	ret = imx8mq_mipi_csi_sw_reset(state);
359	if (ret)
360		return ret;
361
362	imx8mq_mipi_csi_set_params(state);
363	ret = imx8mq_mipi_csi_calc_hs_settle(state, sd_state, &hs_settle);
364	if (ret)
365		return ret;
366
367	regmap_update_bits(state->phy_gpr,
368			   state->phy_gpr_reg,
369			   0x3fff,
370			   GPR_CSI2_1_RX_ENABLE |
371			   GPR_CSI2_1_VID_INTFC_ENB |
372			   GPR_CSI2_1_HSEL |
373			   GPR_CSI2_1_CONT_CLK_MODE |
374			   GPR_CSI2_1_S_PRG_RXHS_SETTLE(hs_settle));
375
376	return 0;
377}
378
379static void imx8mq_mipi_csi_stop_stream(struct csi_state *state)
380{
381	imx8mq_mipi_csi_write(state, CSI2RX_CFG_DISABLE_DATA_LANES, 0xf);
382}
383
384/* -----------------------------------------------------------------------------
385 * V4L2 subdev operations
386 */
387
388static struct csi_state *mipi_sd_to_csi2_state(struct v4l2_subdev *sdev)
389{
390	return container_of(sdev, struct csi_state, sd);
391}
392
393static int imx8mq_mipi_csi_s_stream(struct v4l2_subdev *sd, int enable)
394{
395	struct csi_state *state = mipi_sd_to_csi2_state(sd);
396	struct v4l2_subdev_state *sd_state;
397	int ret = 0;
398
399	if (enable) {
400		ret = pm_runtime_resume_and_get(state->dev);
401		if (ret < 0)
402			return ret;
403	}
404
405	mutex_lock(&state->lock);
406
407	if (enable) {
408		if (state->state & ST_SUSPENDED) {
409			ret = -EBUSY;
410			goto unlock;
411		}
412
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);
416
417		if (ret < 0)
418			goto unlock;
419
420		ret = v4l2_subdev_call(state->src_sd, video, s_stream, 1);
421		if (ret < 0)
422			goto unlock;
423
424		state->state |= ST_STREAMING;
425	} else {
426		v4l2_subdev_call(state->src_sd, video, s_stream, 0);
427		imx8mq_mipi_csi_stop_stream(state);
428		state->state &= ~ST_STREAMING;
429	}
430
431unlock:
432	mutex_unlock(&state->lock);
433
434	if (!enable || ret < 0)
435		pm_runtime_put(state->dev);
436
437	return ret;
438}
439
440static int imx8mq_mipi_csi_init_cfg(struct v4l2_subdev *sd,
441				    struct v4l2_subdev_state *sd_state)
442{
443	struct v4l2_mbus_framefmt *fmt_sink;
444	struct v4l2_mbus_framefmt *fmt_source;
445
446	fmt_sink = v4l2_subdev_get_pad_format(sd, sd_state, MIPI_CSI2_PAD_SINK);
447	fmt_source = v4l2_subdev_get_pad_format(sd, sd_state, MIPI_CSI2_PAD_SOURCE);
448
449	fmt_sink->code = MEDIA_BUS_FMT_SGBRG10_1X10;
450	fmt_sink->width = MIPI_CSI2_DEF_PIX_WIDTH;
451	fmt_sink->height = MIPI_CSI2_DEF_PIX_HEIGHT;
452	fmt_sink->field = V4L2_FIELD_NONE;
453
454	fmt_sink->colorspace = V4L2_COLORSPACE_RAW;
455	fmt_sink->xfer_func = V4L2_MAP_XFER_FUNC_DEFAULT(fmt_sink->colorspace);
456	fmt_sink->ycbcr_enc = V4L2_MAP_YCBCR_ENC_DEFAULT(fmt_sink->colorspace);
457	fmt_sink->quantization =
458		V4L2_MAP_QUANTIZATION_DEFAULT(false, fmt_sink->colorspace,
459					      fmt_sink->ycbcr_enc);
460
461	*fmt_source = *fmt_sink;
462
463	return 0;
464}
465
466static int imx8mq_mipi_csi_enum_mbus_code(struct v4l2_subdev *sd,
467					  struct v4l2_subdev_state *sd_state,
468					  struct v4l2_subdev_mbus_code_enum *code)
469{
470	/*
471	 * We can't transcode in any way, the source format is identical
472	 * to the sink format.
473	 */
474	if (code->pad == MIPI_CSI2_PAD_SOURCE) {
475		struct v4l2_mbus_framefmt *fmt;
476
477		if (code->index > 0)
478			return -EINVAL;
479
480		fmt = v4l2_subdev_get_pad_format(sd, sd_state, code->pad);
481		code->code = fmt->code;
482		return 0;
483	}
484
485	if (code->pad != MIPI_CSI2_PAD_SINK)
486		return -EINVAL;
487
488	if (code->index >= ARRAY_SIZE(imx8mq_mipi_csi_formats))
489		return -EINVAL;
490
491	code->code = imx8mq_mipi_csi_formats[code->index].code;
492
493	return 0;
494}
495
496static int imx8mq_mipi_csi_set_fmt(struct v4l2_subdev *sd,
497				   struct v4l2_subdev_state *sd_state,
498				   struct v4l2_subdev_format *sdformat)
499{
500	const struct csi2_pix_format *csi2_fmt;
501	struct v4l2_mbus_framefmt *fmt;
502
503	/*
504	 * The device can't transcode in any way, the source format can't be
505	 * modified.
506	 */
507	if (sdformat->pad == MIPI_CSI2_PAD_SOURCE)
508		return v4l2_subdev_get_fmt(sd, sd_state, sdformat);
509
510	if (sdformat->pad != MIPI_CSI2_PAD_SINK)
511		return -EINVAL;
512
513	csi2_fmt = find_csi2_format(sdformat->format.code);
514	if (!csi2_fmt)
515		csi2_fmt = &imx8mq_mipi_csi_formats[0];
516
517	fmt = v4l2_subdev_get_pad_format(sd, sd_state, sdformat->pad);
518
519	fmt->code = csi2_fmt->code;
520	fmt->width = sdformat->format.width;
521	fmt->height = sdformat->format.height;
522
523	sdformat->format = *fmt;
524
525	/* Propagate the format from sink to source. */
526	fmt = v4l2_subdev_get_pad_format(sd, sd_state, MIPI_CSI2_PAD_SOURCE);
527	*fmt = sdformat->format;
528
529	return 0;
530}
531
532static const struct v4l2_subdev_video_ops imx8mq_mipi_csi_video_ops = {
533	.s_stream	= imx8mq_mipi_csi_s_stream,
534};
535
536static const struct v4l2_subdev_pad_ops imx8mq_mipi_csi_pad_ops = {
537	.init_cfg		= imx8mq_mipi_csi_init_cfg,
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,
541};
542
543static const struct v4l2_subdev_ops imx8mq_mipi_csi_subdev_ops = {
544	.video	= &imx8mq_mipi_csi_video_ops,
545	.pad	= &imx8mq_mipi_csi_pad_ops,
546};
547
548/* -----------------------------------------------------------------------------
549 * Media entity operations
550 */
551
552static const struct media_entity_operations imx8mq_mipi_csi_entity_ops = {
553	.link_validate	= v4l2_subdev_link_validate,
554	.get_fwnode_pad = v4l2_subdev_get_fwnode_pad_1_to_1,
555};
556
557/* -----------------------------------------------------------------------------
558 * Async subdev notifier
559 */
560
561static struct csi_state *
562mipi_notifier_to_csi2_state(struct v4l2_async_notifier *n)
563{
564	return container_of(n, struct csi_state, notifier);
565}
566
567static int imx8mq_mipi_csi_notify_bound(struct v4l2_async_notifier *notifier,
568					struct v4l2_subdev *sd,
569					struct v4l2_async_connection *asd)
570{
571	struct csi_state *state = mipi_notifier_to_csi2_state(notifier);
572	struct media_pad *sink = &state->sd.entity.pads[MIPI_CSI2_PAD_SINK];
573
574	state->src_sd = sd;
575
576	return v4l2_create_fwnode_links_to_pad(sd, sink, MEDIA_LNK_FL_ENABLED |
577					       MEDIA_LNK_FL_IMMUTABLE);
578}
579
580static const struct v4l2_async_notifier_operations imx8mq_mipi_csi_notify_ops = {
581	.bound = imx8mq_mipi_csi_notify_bound,
582};
583
584static int imx8mq_mipi_csi_async_register(struct csi_state *state)
585{
586	struct v4l2_fwnode_endpoint vep = {
587		.bus_type = V4L2_MBUS_CSI2_DPHY,
588	};
589	struct v4l2_async_connection *asd;
590	struct fwnode_handle *ep;
591	unsigned int i;
592	int ret;
593
594	v4l2_async_subdev_nf_init(&state->notifier, &state->sd);
595
596	ep = fwnode_graph_get_endpoint_by_id(dev_fwnode(state->dev), 0, 0,
597					     FWNODE_GRAPH_ENDPOINT_NEXT);
598	if (!ep)
599		return -ENOTCONN;
600
601	ret = v4l2_fwnode_endpoint_parse(ep, &vep);
602	if (ret)
603		goto err_parse;
604
605	for (i = 0; i < vep.bus.mipi_csi2.num_data_lanes; ++i) {
606		if (vep.bus.mipi_csi2.data_lanes[i] != i + 1) {
607			dev_err(state->dev,
608				"data lanes reordering is not supported");
609			ret = -EINVAL;
610			goto err_parse;
611		}
612	}
613
614	state->bus = vep.bus.mipi_csi2;
615
616	dev_dbg(state->dev, "data lanes: %d flags: 0x%08x\n",
617		state->bus.num_data_lanes,
618		state->bus.flags);
619
620	asd = v4l2_async_nf_add_fwnode_remote(&state->notifier, ep,
621					      struct v4l2_async_connection);
622	if (IS_ERR(asd)) {
623		ret = PTR_ERR(asd);
624		goto err_parse;
625	}
626
627	fwnode_handle_put(ep);
628
629	state->notifier.ops = &imx8mq_mipi_csi_notify_ops;
630
631	ret = v4l2_async_nf_register(&state->notifier);
632	if (ret)
633		return ret;
634
635	return v4l2_async_register_subdev(&state->sd);
636
637err_parse:
638	fwnode_handle_put(ep);
639
640	return ret;
641}
642
643/* -----------------------------------------------------------------------------
644 * Suspend/resume
645 */
646
647static void imx8mq_mipi_csi_pm_suspend(struct device *dev)
648{
649	struct v4l2_subdev *sd = dev_get_drvdata(dev);
650	struct csi_state *state = mipi_sd_to_csi2_state(sd);
651
652	mutex_lock(&state->lock);
653
654	if (state->state & ST_POWERED) {
655		imx8mq_mipi_csi_stop_stream(state);
656		imx8mq_mipi_csi_clk_disable(state);
657		state->state &= ~ST_POWERED;
658	}
659
660	mutex_unlock(&state->lock);
661}
662
663static int imx8mq_mipi_csi_pm_resume(struct device *dev)
664{
665	struct v4l2_subdev *sd = dev_get_drvdata(dev);
666	struct csi_state *state = mipi_sd_to_csi2_state(sd);
667	struct v4l2_subdev_state *sd_state;
668	int ret = 0;
669
670	mutex_lock(&state->lock);
671
672	if (!(state->state & ST_POWERED)) {
673		state->state |= ST_POWERED;
674		ret = imx8mq_mipi_csi_clk_enable(state);
675	}
676	if (state->state & ST_STREAMING) {
677		sd_state = v4l2_subdev_lock_and_get_active_state(sd);
678		ret = imx8mq_mipi_csi_start_stream(state, sd_state);
679		v4l2_subdev_unlock_state(sd_state);
680		if (ret)
681			goto unlock;
682	}
683
684	state->state &= ~ST_SUSPENDED;
685
686unlock:
687	mutex_unlock(&state->lock);
688
689	return ret ? -EAGAIN : 0;
690}
691
692static int __maybe_unused imx8mq_mipi_csi_suspend(struct device *dev)
693{
694	struct v4l2_subdev *sd = dev_get_drvdata(dev);
695	struct csi_state *state = mipi_sd_to_csi2_state(sd);
696
697	imx8mq_mipi_csi_pm_suspend(dev);
698
699	state->state |= ST_SUSPENDED;
700
701	return 0;
702}
703
704static int __maybe_unused imx8mq_mipi_csi_resume(struct device *dev)
705{
706	struct v4l2_subdev *sd = dev_get_drvdata(dev);
707	struct csi_state *state = mipi_sd_to_csi2_state(sd);
708
709	if (!(state->state & ST_SUSPENDED))
710		return 0;
711
712	return imx8mq_mipi_csi_pm_resume(dev);
713}
714
715static int __maybe_unused imx8mq_mipi_csi_runtime_suspend(struct device *dev)
716{
717	struct v4l2_subdev *sd = dev_get_drvdata(dev);
718	struct csi_state *state = mipi_sd_to_csi2_state(sd);
719	int ret;
720
721	imx8mq_mipi_csi_pm_suspend(dev);
722
723	ret = icc_set_bw(state->icc_path, 0, 0);
724	if (ret)
725		dev_err(dev, "icc_set_bw failed with %d\n", ret);
726
727	return ret;
728}
729
730static int __maybe_unused imx8mq_mipi_csi_runtime_resume(struct device *dev)
731{
732	struct v4l2_subdev *sd = dev_get_drvdata(dev);
733	struct csi_state *state = mipi_sd_to_csi2_state(sd);
734	int ret;
735
736	ret = icc_set_bw(state->icc_path, 0, state->icc_path_bw);
737	if (ret) {
738		dev_err(dev, "icc_set_bw failed with %d\n", ret);
739		return ret;
740	}
741
742	return imx8mq_mipi_csi_pm_resume(dev);
743}
744
745static const struct dev_pm_ops imx8mq_mipi_csi_pm_ops = {
746	SET_RUNTIME_PM_OPS(imx8mq_mipi_csi_runtime_suspend,
747			   imx8mq_mipi_csi_runtime_resume,
748			   NULL)
749	SET_SYSTEM_SLEEP_PM_OPS(imx8mq_mipi_csi_suspend, imx8mq_mipi_csi_resume)
750};
751
752/* -----------------------------------------------------------------------------
753 * Probe/remove & platform driver
754 */
755
756static int imx8mq_mipi_csi_subdev_init(struct csi_state *state)
757{
758	struct v4l2_subdev *sd = &state->sd;
759	int ret;
760
761	v4l2_subdev_init(sd, &imx8mq_mipi_csi_subdev_ops);
762	sd->owner = THIS_MODULE;
763	snprintf(sd->name, sizeof(sd->name), "%s %s",
764		 MIPI_CSI2_SUBDEV_NAME, dev_name(state->dev));
765
766	sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
767
768	sd->entity.function = MEDIA_ENT_F_VID_IF_BRIDGE;
769	sd->entity.ops = &imx8mq_mipi_csi_entity_ops;
770
771	sd->dev = state->dev;
772
773	state->pads[MIPI_CSI2_PAD_SINK].flags = MEDIA_PAD_FL_SINK
774					 | MEDIA_PAD_FL_MUST_CONNECT;
775	state->pads[MIPI_CSI2_PAD_SOURCE].flags = MEDIA_PAD_FL_SOURCE
776					   | MEDIA_PAD_FL_MUST_CONNECT;
777	ret = media_entity_pads_init(&sd->entity, MIPI_CSI2_PADS_NUM,
778				     state->pads);
779	if (ret)
780		return ret;
781
782	ret = v4l2_subdev_init_finalize(sd);
783	if (ret) {
784		media_entity_cleanup(&sd->entity);
785		return ret;
786	}
787
788	return 0;
789}
790
791static void imx8mq_mipi_csi_release_icc(struct platform_device *pdev)
792{
793	struct v4l2_subdev *sd = dev_get_drvdata(&pdev->dev);
794	struct csi_state *state = mipi_sd_to_csi2_state(sd);
795
796	icc_put(state->icc_path);
797}
798
799static int imx8mq_mipi_csi_init_icc(struct platform_device *pdev)
800{
801	struct v4l2_subdev *sd = dev_get_drvdata(&pdev->dev);
802	struct csi_state *state = mipi_sd_to_csi2_state(sd);
803
804	/* Optional interconnect request */
805	state->icc_path = of_icc_get(&pdev->dev, "dram");
806	if (IS_ERR_OR_NULL(state->icc_path))
807		return PTR_ERR_OR_ZERO(state->icc_path);
808
809	state->icc_path_bw = MBps_to_icc(700);
810
811	return 0;
812}
813
814static int imx8mq_mipi_csi_parse_dt(struct csi_state *state)
815{
816	struct device *dev = state->dev;
817	struct device_node *np = state->dev->of_node;
818	struct device_node *node;
819	phandle ph;
820	u32 out_val[2];
821	int ret = 0;
822
823	state->rst = devm_reset_control_array_get_exclusive(dev);
824	if (IS_ERR(state->rst)) {
825		dev_err(dev, "Failed to get reset: %pe\n", state->rst);
826		return PTR_ERR(state->rst);
827	}
828
829	ret = of_property_read_u32_array(np, "fsl,mipi-phy-gpr", out_val,
830					 ARRAY_SIZE(out_val));
831	if (ret) {
832		dev_err(dev, "no fsl,mipi-phy-gpr property found: %d\n", ret);
833		return ret;
834	}
835
836	ph = *out_val;
837
838	node = of_find_node_by_phandle(ph);
839	if (!node) {
840		dev_err(dev, "Error finding node by phandle\n");
841		return -ENODEV;
842	}
843	state->phy_gpr = syscon_node_to_regmap(node);
844	of_node_put(node);
845	if (IS_ERR(state->phy_gpr)) {
846		dev_err(dev, "failed to get gpr regmap: %pe\n", state->phy_gpr);
847		return PTR_ERR(state->phy_gpr);
848	}
849
850	state->phy_gpr_reg = out_val[1];
851	dev_dbg(dev, "phy gpr register set to 0x%x\n", state->phy_gpr_reg);
852
853	return ret;
854}
855
856static int imx8mq_mipi_csi_probe(struct platform_device *pdev)
857{
858	struct device *dev = &pdev->dev;
859	struct csi_state *state;
860	int ret;
861
862	state = devm_kzalloc(dev, sizeof(*state), GFP_KERNEL);
863	if (!state)
864		return -ENOMEM;
865
866	state->dev = dev;
867
868	ret = imx8mq_mipi_csi_parse_dt(state);
869	if (ret < 0) {
870		dev_err(dev, "Failed to parse device tree: %d\n", ret);
871		return ret;
872	}
873
874	/* Acquire resources. */
875	state->regs = devm_platform_ioremap_resource(pdev, 0);
876	if (IS_ERR(state->regs))
877		return PTR_ERR(state->regs);
878
879	ret = imx8mq_mipi_csi_clk_get(state);
880	if (ret < 0)
881		return ret;
882
883	platform_set_drvdata(pdev, &state->sd);
884
885	mutex_init(&state->lock);
886
887	ret = imx8mq_mipi_csi_subdev_init(state);
888	if (ret < 0)
889		goto mutex;
890
891	ret = imx8mq_mipi_csi_init_icc(pdev);
892	if (ret)
893		goto mutex;
894
895	/* Enable runtime PM. */
896	pm_runtime_enable(dev);
897	if (!pm_runtime_enabled(dev)) {
898		ret = imx8mq_mipi_csi_runtime_resume(dev);
899		if (ret < 0)
900			goto icc;
901	}
902
903	ret = imx8mq_mipi_csi_async_register(state);
904	if (ret < 0)
905		goto cleanup;
906
907	return 0;
908
909cleanup:
910	pm_runtime_disable(&pdev->dev);
911	imx8mq_mipi_csi_runtime_suspend(&pdev->dev);
912
913	media_entity_cleanup(&state->sd.entity);
914	v4l2_subdev_cleanup(&state->sd);
915	v4l2_async_nf_unregister(&state->notifier);
916	v4l2_async_nf_cleanup(&state->notifier);
917	v4l2_async_unregister_subdev(&state->sd);
918icc:
919	imx8mq_mipi_csi_release_icc(pdev);
920mutex:
921	mutex_destroy(&state->lock);
922
923	return ret;
924}
925
926static void imx8mq_mipi_csi_remove(struct platform_device *pdev)
927{
928	struct v4l2_subdev *sd = platform_get_drvdata(pdev);
929	struct csi_state *state = mipi_sd_to_csi2_state(sd);
930
931	v4l2_async_nf_unregister(&state->notifier);
932	v4l2_async_nf_cleanup(&state->notifier);
933	v4l2_async_unregister_subdev(&state->sd);
934
935	pm_runtime_disable(&pdev->dev);
936	imx8mq_mipi_csi_runtime_suspend(&pdev->dev);
937	media_entity_cleanup(&state->sd.entity);
938	v4l2_subdev_cleanup(&state->sd);
939	mutex_destroy(&state->lock);
940	pm_runtime_set_suspended(&pdev->dev);
941	imx8mq_mipi_csi_release_icc(pdev);
942}
943
944static const struct of_device_id imx8mq_mipi_csi_of_match[] = {
945	{ .compatible = "fsl,imx8mq-mipi-csi2", },
946	{ /* sentinel */ },
947};
948MODULE_DEVICE_TABLE(of, imx8mq_mipi_csi_of_match);
949
950static struct platform_driver imx8mq_mipi_csi_driver = {
951	.probe		= imx8mq_mipi_csi_probe,
952	.remove_new	= imx8mq_mipi_csi_remove,
953	.driver		= {
954		.of_match_table = imx8mq_mipi_csi_of_match,
955		.name		= MIPI_CSI2_DRIVER_NAME,
956		.pm		= &imx8mq_mipi_csi_pm_ops,
957	},
958};
959
960module_platform_driver(imx8mq_mipi_csi_driver);
961
962MODULE_DESCRIPTION("i.MX8MQ MIPI CSI-2 receiver driver");
963MODULE_AUTHOR("Martin Kepplinger <martin.kepplinger@puri.sm>");
964MODULE_LICENSE("GPL v2");
965MODULE_ALIAS("platform:imx8mq-mipi-csi2");
966