Linux kernel mirror (for testing)
git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel
os
linux
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/bitfield.h>
9#include <linux/clk.h>
10#include <linux/clk-provider.h>
11#include <linux/delay.h>
12#include <linux/errno.h>
13#include <linux/interconnect.h>
14#include <linux/interrupt.h>
15#include <linux/io.h>
16#include <linux/kernel.h>
17#include <linux/mfd/syscon.h>
18#include <linux/module.h>
19#include <linux/mutex.h>
20#include <linux/of.h>
21#include <linux/platform_device.h>
22#include <linux/pm_runtime.h>
23#include <linux/regmap.h>
24#include <linux/regulator/consumer.h>
25#include <linux/reset.h>
26#include <linux/spinlock.h>
27
28#include <media/v4l2-common.h>
29#include <media/v4l2-device.h>
30#include <media/v4l2-fwnode.h>
31#include <media/v4l2-mc.h>
32#include <media/v4l2-subdev.h>
33
34#define MIPI_CSI2_DRIVER_NAME "imx8mq-mipi-csi2"
35#define MIPI_CSI2_SUBDEV_NAME MIPI_CSI2_DRIVER_NAME
36
37#define MIPI_CSI2_PAD_SINK 0
38#define MIPI_CSI2_PAD_SOURCE 1
39#define MIPI_CSI2_PADS_NUM 2
40
41#define MIPI_CSI2_DEF_PIX_WIDTH 640
42#define MIPI_CSI2_DEF_PIX_HEIGHT 480
43
44/* Register map definition */
45
46/* i.MX8MQ CSI-2 controller CSR */
47#define CSI2RX_CFG_NUM_LANES 0x100
48#define CSI2RX_CFG_DISABLE_DATA_LANES 0x104
49#define CSI2RX_BIT_ERR 0x108
50#define CSI2RX_IRQ_STATUS 0x10c
51#define CSI2RX_IRQ_MASK 0x110
52#define CSI2RX_IRQ_MASK_ALL 0x1ff
53#define CSI2RX_IRQ_MASK_ULPS_STATUS_CHANGE 0x8
54#define CSI2RX_ULPS_STATUS 0x114
55#define CSI2RX_PPI_ERRSOT_HS 0x118
56#define CSI2RX_PPI_ERRSOTSYNC_HS 0x11c
57#define CSI2RX_PPI_ERRESC 0x120
58#define CSI2RX_PPI_ERRSYNCESC 0x124
59#define CSI2RX_PPI_ERRCONTROL 0x128
60#define CSI2RX_CFG_DISABLE_PAYLOAD_0 0x12c
61#define CSI2RX_CFG_VID_VC_IGNORE 0x180
62#define CSI2RX_CFG_VID_VC 0x184
63#define CSI2RX_CFG_VID_P_FIFO_SEND_LEVEL 0x188
64#define CSI2RX_CFG_DISABLE_PAYLOAD_1 0x130
65
66struct csi_state;
67
68enum {
69 ST_POWERED = 1,
70 ST_STREAMING = 2,
71 ST_SUSPENDED = 4,
72};
73
74enum imx8mq_mipi_csi_clk {
75 CSI2_CLK_CORE,
76 CSI2_CLK_ESC,
77 CSI2_CLK_UI,
78 CSI2_NUM_CLKS,
79};
80
81static const char * const imx8mq_mipi_csi_clk_id[CSI2_NUM_CLKS] = {
82 [CSI2_CLK_CORE] = "core",
83 [CSI2_CLK_ESC] = "esc",
84 [CSI2_CLK_UI] = "ui",
85};
86
87#define CSI2_NUM_CLKS ARRAY_SIZE(imx8mq_mipi_csi_clk_id)
88
89struct imx8mq_plat_data {
90 int (*enable)(struct csi_state *state, u32 hs_settle);
91 void (*disable)(struct csi_state *state);
92 bool use_reg_csr;
93};
94
95/*
96 * The send level configures the number of entries that must accumulate in
97 * the Pixel FIFO before the data will be transferred to the video output.
98 * The exact value needed for this configuration is dependent on the rate at
99 * which the sensor transfers data to the CSI-2 Controller and the user
100 * video clock.
101 *
102 * The calculation is the classical rate-in rate-out type of problem: If the
103 * video bandwidth is 10% faster than the incoming mipi data and the video
104 * line length is 500 pixels, then the fifo should be allowed to fill
105 * 10% of the line length or 50 pixels. If the gap data is ok, then the level
106 * can be set to 16 and ignored.
107 */
108#define CSI2RX_SEND_LEVEL 64
109
110struct csi_state {
111 struct device *dev;
112 const struct imx8mq_plat_data *pdata;
113 void __iomem *regs;
114 struct clk_bulk_data clks[CSI2_NUM_CLKS];
115 struct reset_control *rst;
116 struct regulator *mipi_phy_regulator;
117
118 struct v4l2_subdev sd;
119 struct media_pad pads[MIPI_CSI2_PADS_NUM];
120 struct v4l2_async_notifier notifier;
121 struct v4l2_subdev *src_sd;
122
123 struct v4l2_mbus_config_mipi_csi2 bus;
124
125 struct mutex lock; /* Protect state */
126 u32 state;
127
128 struct regmap *phy_gpr;
129 u8 phy_gpr_reg;
130
131 struct icc_path *icc_path;
132 s32 icc_path_bw;
133};
134
135/* -----------------------------------------------------------------------------
136 * Format helpers
137 */
138
139struct csi2_pix_format {
140 u32 code;
141 u8 width;
142};
143
144/* -----------------------------------------------------------------------------
145 * i.MX8MQ GPR
146 */
147
148#define GPR_CSI2_1_RX_ENABLE BIT(13)
149#define GPR_CSI2_1_VID_INTFC_ENB BIT(12)
150#define GPR_CSI2_1_HSEL BIT(10)
151#define GPR_CSI2_1_CONT_CLK_MODE BIT(8)
152#define GPR_CSI2_1_S_PRG_RXHS_SETTLE(x) (((x) & 0x3f) << 2)
153
154static int imx8mq_gpr_enable(struct csi_state *state, u32 hs_settle)
155{
156 regmap_update_bits(state->phy_gpr,
157 state->phy_gpr_reg,
158 0x3fff,
159 GPR_CSI2_1_RX_ENABLE |
160 GPR_CSI2_1_VID_INTFC_ENB |
161 GPR_CSI2_1_HSEL |
162 GPR_CSI2_1_CONT_CLK_MODE |
163 GPR_CSI2_1_S_PRG_RXHS_SETTLE(hs_settle));
164
165 return 0;
166}
167
168static const struct imx8mq_plat_data imx8mq_data = {
169 .enable = imx8mq_gpr_enable,
170};
171
172/* -----------------------------------------------------------------------------
173 * i.MX8QXP
174 */
175
176#define CSI2SS_PL_CLK_INTERVAL_US 100
177#define CSI2SS_PL_CLK_TIMEOUT_US 100000
178
179#define CSI2SS_PLM_CTRL 0x0
180#define CSI2SS_PLM_CTRL_ENABLE_PL BIT(0)
181#define CSI2SS_PLM_CTRL_VSYNC_OVERRIDE BIT(9)
182#define CSI2SS_PLM_CTRL_HSYNC_OVERRIDE BIT(10)
183#define CSI2SS_PLM_CTRL_VALID_OVERRIDE BIT(11)
184#define CSI2SS_PLM_CTRL_POLARITY_HIGH BIT(12)
185#define CSI2SS_PLM_CTRL_PL_CLK_RUN BIT(31)
186
187#define CSI2SS_PHY_CTRL 0x4
188#define CSI2SS_PHY_CTRL_RX_ENABLE BIT(0)
189#define CSI2SS_PHY_CTRL_AUTO_PD_EN BIT(1)
190#define CSI2SS_PHY_CTRL_DDRCLK_EN BIT(2)
191#define CSI2SS_PHY_CTRL_CONT_CLK_MODE BIT(3)
192#define CSI2SS_PHY_CTRL_RX_HS_SETTLE_MASK GENMASK(9, 4)
193#define CSI2SS_PHY_CTRL_RTERM_SEL BIT(21)
194#define CSI2SS_PHY_CTRL_PD BIT(22)
195
196#define CSI2SS_DATA_TYPE_DISABLE_BF 0x38
197#define CSI2SS_DATA_TYPE_DISABLE_BF_MASK GENMASK(23, 0)
198
199#define CSI2SS_CTRL_CLK_RESET 0x44
200#define CSI2SS_CTRL_CLK_RESET_EN BIT(0)
201
202static int imx8qxp_gpr_enable(struct csi_state *state, u32 hs_settle)
203{
204 int ret;
205 u32 val;
206
207 /* Clear format */
208 regmap_clear_bits(state->phy_gpr, CSI2SS_DATA_TYPE_DISABLE_BF,
209 CSI2SS_DATA_TYPE_DISABLE_BF_MASK);
210
211 regmap_write(state->phy_gpr, CSI2SS_PLM_CTRL, 0x0);
212
213 regmap_write(state->phy_gpr, CSI2SS_PHY_CTRL,
214 FIELD_PREP(CSI2SS_PHY_CTRL_RX_HS_SETTLE_MASK, hs_settle) |
215 CSI2SS_PHY_CTRL_RX_ENABLE | CSI2SS_PHY_CTRL_DDRCLK_EN |
216 CSI2SS_PHY_CTRL_CONT_CLK_MODE | CSI2SS_PHY_CTRL_PD |
217 CSI2SS_PHY_CTRL_RTERM_SEL | CSI2SS_PHY_CTRL_AUTO_PD_EN);
218
219 ret = regmap_read_poll_timeout(state->phy_gpr, CSI2SS_PLM_CTRL,
220 val, !(val & CSI2SS_PLM_CTRL_PL_CLK_RUN),
221 CSI2SS_PL_CLK_INTERVAL_US,
222 CSI2SS_PL_CLK_TIMEOUT_US);
223
224 if (ret) {
225 dev_err(state->dev, "Timeout waiting for Pixel-Link clock\n");
226 return ret;
227 }
228
229 /* Enable Pixel link Master */
230 regmap_set_bits(state->phy_gpr, CSI2SS_PLM_CTRL,
231 CSI2SS_PLM_CTRL_ENABLE_PL | CSI2SS_PLM_CTRL_VALID_OVERRIDE);
232
233 /* PHY Enable */
234 regmap_clear_bits(state->phy_gpr, CSI2SS_PHY_CTRL,
235 CSI2SS_PHY_CTRL_PD | CSI2SS_PLM_CTRL_POLARITY_HIGH);
236
237 /* Release Reset */
238 regmap_set_bits(state->phy_gpr, CSI2SS_CTRL_CLK_RESET, CSI2SS_CTRL_CLK_RESET_EN);
239
240 return ret;
241}
242
243static void imx8qxp_gpr_disable(struct csi_state *state)
244{
245 /* Disable Pixel Link */
246 regmap_write(state->phy_gpr, CSI2SS_PLM_CTRL, 0x0);
247
248 /* Disable PHY */
249 regmap_write(state->phy_gpr, CSI2SS_PHY_CTRL, 0x0);
250
251 regmap_clear_bits(state->phy_gpr, CSI2SS_CTRL_CLK_RESET,
252 CSI2SS_CTRL_CLK_RESET_EN);
253};
254
255static const struct imx8mq_plat_data imx8qxp_data = {
256 .enable = imx8qxp_gpr_enable,
257 .disable = imx8qxp_gpr_disable,
258 .use_reg_csr = true,
259};
260
261static const struct csi2_pix_format imx8mq_mipi_csi_formats[] = {
262 /* RAW (Bayer and greyscale) formats. */
263 {
264 .code = MEDIA_BUS_FMT_SBGGR8_1X8,
265 .width = 8,
266 }, {
267 .code = MEDIA_BUS_FMT_SGBRG8_1X8,
268 .width = 8,
269 }, {
270 .code = MEDIA_BUS_FMT_SGRBG8_1X8,
271 .width = 8,
272 }, {
273 .code = MEDIA_BUS_FMT_SRGGB8_1X8,
274 .width = 8,
275 }, {
276 .code = MEDIA_BUS_FMT_Y8_1X8,
277 .width = 8,
278 }, {
279 .code = MEDIA_BUS_FMT_SBGGR10_1X10,
280 .width = 10,
281 }, {
282 .code = MEDIA_BUS_FMT_SGBRG10_1X10,
283 .width = 10,
284 }, {
285 .code = MEDIA_BUS_FMT_SGRBG10_1X10,
286 .width = 10,
287 }, {
288 .code = MEDIA_BUS_FMT_SRGGB10_1X10,
289 .width = 10,
290 }, {
291 .code = MEDIA_BUS_FMT_Y10_1X10,
292 .width = 10,
293 }, {
294 .code = MEDIA_BUS_FMT_SBGGR12_1X12,
295 .width = 12,
296 }, {
297 .code = MEDIA_BUS_FMT_SGBRG12_1X12,
298 .width = 12,
299 }, {
300 .code = MEDIA_BUS_FMT_SGRBG12_1X12,
301 .width = 12,
302 }, {
303 .code = MEDIA_BUS_FMT_SRGGB12_1X12,
304 .width = 12,
305 }, {
306 .code = MEDIA_BUS_FMT_Y12_1X12,
307 .width = 12,
308 }, {
309 .code = MEDIA_BUS_FMT_SBGGR14_1X14,
310 .width = 14,
311 }, {
312 .code = MEDIA_BUS_FMT_SGBRG14_1X14,
313 .width = 14,
314 }, {
315 .code = MEDIA_BUS_FMT_SGRBG14_1X14,
316 .width = 14,
317 }, {
318 .code = MEDIA_BUS_FMT_SRGGB14_1X14,
319 .width = 14,
320 },
321 /* YUV formats */
322 {
323 .code = MEDIA_BUS_FMT_YUYV8_1X16,
324 .width = 16,
325 }, {
326 .code = MEDIA_BUS_FMT_UYVY8_1X16,
327 .width = 16,
328 }
329};
330
331static const struct csi2_pix_format *find_csi2_format(u32 code)
332{
333 unsigned int i;
334
335 for (i = 0; i < ARRAY_SIZE(imx8mq_mipi_csi_formats); i++)
336 if (code == imx8mq_mipi_csi_formats[i].code)
337 return &imx8mq_mipi_csi_formats[i];
338 return NULL;
339}
340
341/* -----------------------------------------------------------------------------
342 * Hardware configuration
343 */
344
345static inline void imx8mq_mipi_csi_write(struct csi_state *state, u32 reg, u32 val)
346{
347 writel(val, state->regs + reg);
348}
349
350static int imx8mq_mipi_csi_sw_reset(struct csi_state *state)
351{
352 int ret;
353
354 /*
355 * these are most likely self-clearing reset bits. to make it
356 * more clear, the reset-imx7 driver should implement the
357 * .reset() operation.
358 */
359 ret = reset_control_assert(state->rst);
360 if (ret < 0) {
361 dev_err(state->dev, "Failed to assert resets: %d\n", ret);
362 return ret;
363 }
364
365 return 0;
366}
367
368static void imx8mq_mipi_csi_set_params(struct csi_state *state)
369{
370 int lanes = state->bus.num_data_lanes;
371
372 imx8mq_mipi_csi_write(state, CSI2RX_CFG_NUM_LANES, lanes - 1);
373 imx8mq_mipi_csi_write(state, CSI2RX_CFG_DISABLE_DATA_LANES,
374 (0xf << lanes) & 0xf);
375 imx8mq_mipi_csi_write(state, CSI2RX_IRQ_MASK, CSI2RX_IRQ_MASK_ALL);
376 /*
377 * 0x180 bit 0 controls the Virtual Channel behaviour: when set the
378 * interface ignores the Virtual Channel (VC) field in received packets;
379 * when cleared it causes the interface to only accept packets whose VC
380 * matches the value to which VC is set at offset 0x184.
381 */
382 imx8mq_mipi_csi_write(state, CSI2RX_CFG_VID_VC_IGNORE, 1);
383 imx8mq_mipi_csi_write(state, CSI2RX_CFG_VID_P_FIFO_SEND_LEVEL,
384 CSI2RX_SEND_LEVEL);
385}
386
387static int imx8mq_mipi_csi_clk_enable(struct csi_state *state)
388{
389 return clk_bulk_prepare_enable(CSI2_NUM_CLKS, state->clks);
390}
391
392static void imx8mq_mipi_csi_clk_disable(struct csi_state *state)
393{
394 clk_bulk_disable_unprepare(CSI2_NUM_CLKS, state->clks);
395}
396
397static int imx8mq_mipi_csi_clk_get(struct csi_state *state)
398{
399 unsigned int i;
400
401 for (i = 0; i < CSI2_NUM_CLKS; i++)
402 state->clks[i].id = imx8mq_mipi_csi_clk_id[i];
403
404 return devm_clk_bulk_get(state->dev, CSI2_NUM_CLKS, state->clks);
405}
406
407static int imx8mq_mipi_csi_calc_hs_settle(struct csi_state *state,
408 struct v4l2_subdev_state *sd_state,
409 u32 *hs_settle)
410{
411 struct media_pad *src_pad;
412 s64 link_freq;
413 u32 lane_rate;
414 unsigned long esc_clk_rate;
415 u32 min_ths_settle, max_ths_settle, ths_settle_ns, esc_clk_period_ns;
416 const struct v4l2_mbus_framefmt *fmt;
417 const struct csi2_pix_format *csi2_fmt;
418
419 src_pad = media_entity_remote_source_pad_unique(&sd_state->sd->entity);
420 if (IS_ERR(src_pad)) {
421 dev_err(state->dev, "can't get source pad of %s (%pe)\n",
422 sd_state->sd->name, src_pad);
423 return PTR_ERR(src_pad);
424 }
425
426 /* Calculate the line rate from the pixel rate. */
427
428 fmt = v4l2_subdev_state_get_format(sd_state, MIPI_CSI2_PAD_SINK);
429 csi2_fmt = find_csi2_format(fmt->code);
430
431 link_freq = v4l2_get_link_freq(src_pad, csi2_fmt->width,
432 state->bus.num_data_lanes * 2);
433 if (link_freq < 0) {
434 dev_err(state->dev, "Unable to obtain link frequency: %d\n",
435 (int)link_freq);
436 return link_freq;
437 }
438
439 lane_rate = link_freq * 2;
440 if (lane_rate < 80000000 || lane_rate > 1500000000) {
441 dev_dbg(state->dev, "Out-of-bound lane rate %u\n", lane_rate);
442 return -EINVAL;
443 }
444
445 /*
446 * The D-PHY specification requires Ths-settle to be in the range
447 * 85ns + 6*UI to 140ns + 10*UI, with the unit interval UI being half
448 * the clock period.
449 *
450 * The Ths-settle value is expressed in the hardware as a multiple of
451 * the Esc clock period:
452 *
453 * Ths-settle = (PRG_RXHS_SETTLE + 1) * Tperiod of RxClkInEsc
454 *
455 * Due to the one cycle inaccuracy introduced by rounding, the
456 * documentation recommends picking a value away from the boundaries.
457 * Let's pick the average.
458 */
459 esc_clk_rate = clk_get_rate(state->clks[CSI2_CLK_ESC].clk);
460 if (!esc_clk_rate) {
461 dev_err(state->dev, "Could not get esc clock rate.\n");
462 return -EINVAL;
463 }
464
465 dev_dbg(state->dev, "esc clk rate: %lu\n", esc_clk_rate);
466 esc_clk_period_ns = 1000000000 / esc_clk_rate;
467
468 min_ths_settle = 85 + 6 * 1000000 / (lane_rate / 1000);
469 max_ths_settle = 140 + 10 * 1000000 / (lane_rate / 1000);
470 ths_settle_ns = (min_ths_settle + max_ths_settle) / 2;
471
472 *hs_settle = ths_settle_ns / esc_clk_period_ns - 1;
473
474 dev_dbg(state->dev, "lane rate %u Ths_settle %u hs_settle %u\n",
475 lane_rate, ths_settle_ns, *hs_settle);
476
477 return 0;
478}
479
480static int imx8mq_mipi_csi_start_stream(struct csi_state *state,
481 struct v4l2_subdev_state *sd_state)
482{
483 int ret;
484 u32 hs_settle = 0;
485
486 ret = imx8mq_mipi_csi_sw_reset(state);
487 if (ret)
488 return ret;
489
490 imx8mq_mipi_csi_set_params(state);
491 ret = imx8mq_mipi_csi_calc_hs_settle(state, sd_state, &hs_settle);
492 if (ret)
493 return ret;
494
495 ret = state->pdata->enable(state, hs_settle);
496 if (ret)
497 return ret;
498
499 return 0;
500}
501
502static void imx8mq_mipi_csi_stop_stream(struct csi_state *state)
503{
504 imx8mq_mipi_csi_write(state, CSI2RX_CFG_DISABLE_DATA_LANES, 0xf);
505
506 if (state->pdata->disable)
507 state->pdata->disable(state);
508}
509
510/* -----------------------------------------------------------------------------
511 * V4L2 subdev operations
512 */
513
514static struct csi_state *mipi_sd_to_csi2_state(struct v4l2_subdev *sdev)
515{
516 return container_of(sdev, struct csi_state, sd);
517}
518
519static int imx8mq_mipi_csi_s_stream(struct v4l2_subdev *sd, int enable)
520{
521 struct csi_state *state = mipi_sd_to_csi2_state(sd);
522 struct v4l2_subdev_state *sd_state;
523 int ret = 0;
524
525 if (enable) {
526 ret = pm_runtime_resume_and_get(state->dev);
527 if (ret < 0)
528 return ret;
529 }
530
531 mutex_lock(&state->lock);
532
533 if (enable) {
534 if (state->state & ST_SUSPENDED) {
535 ret = -EBUSY;
536 goto unlock;
537 }
538
539 sd_state = v4l2_subdev_lock_and_get_active_state(sd);
540 ret = imx8mq_mipi_csi_start_stream(state, sd_state);
541 v4l2_subdev_unlock_state(sd_state);
542
543 if (ret < 0)
544 goto unlock;
545
546 ret = v4l2_subdev_call(state->src_sd, video, s_stream, 1);
547 if (ret < 0)
548 goto unlock;
549
550 state->state |= ST_STREAMING;
551 } else {
552 v4l2_subdev_call(state->src_sd, video, s_stream, 0);
553 imx8mq_mipi_csi_stop_stream(state);
554 state->state &= ~ST_STREAMING;
555 }
556
557unlock:
558 mutex_unlock(&state->lock);
559
560 if (!enable || ret < 0)
561 pm_runtime_put(state->dev);
562
563 return ret;
564}
565
566static int imx8mq_mipi_csi_init_state(struct v4l2_subdev *sd,
567 struct v4l2_subdev_state *sd_state)
568{
569 struct v4l2_mbus_framefmt *fmt_sink;
570 struct v4l2_mbus_framefmt *fmt_source;
571
572 fmt_sink = v4l2_subdev_state_get_format(sd_state, MIPI_CSI2_PAD_SINK);
573 fmt_source = v4l2_subdev_state_get_format(sd_state,
574 MIPI_CSI2_PAD_SOURCE);
575
576 fmt_sink->code = MEDIA_BUS_FMT_SGBRG10_1X10;
577 fmt_sink->width = MIPI_CSI2_DEF_PIX_WIDTH;
578 fmt_sink->height = MIPI_CSI2_DEF_PIX_HEIGHT;
579 fmt_sink->field = V4L2_FIELD_NONE;
580
581 fmt_sink->colorspace = V4L2_COLORSPACE_RAW;
582 fmt_sink->xfer_func = V4L2_MAP_XFER_FUNC_DEFAULT(fmt_sink->colorspace);
583 fmt_sink->ycbcr_enc = V4L2_MAP_YCBCR_ENC_DEFAULT(fmt_sink->colorspace);
584 fmt_sink->quantization =
585 V4L2_MAP_QUANTIZATION_DEFAULT(false, fmt_sink->colorspace,
586 fmt_sink->ycbcr_enc);
587
588 *fmt_source = *fmt_sink;
589
590 return 0;
591}
592
593static int imx8mq_mipi_csi_enum_mbus_code(struct v4l2_subdev *sd,
594 struct v4l2_subdev_state *sd_state,
595 struct v4l2_subdev_mbus_code_enum *code)
596{
597 /*
598 * We can't transcode in any way, the source format is identical
599 * to the sink format.
600 */
601 if (code->pad == MIPI_CSI2_PAD_SOURCE) {
602 struct v4l2_mbus_framefmt *fmt;
603
604 if (code->index > 0)
605 return -EINVAL;
606
607 fmt = v4l2_subdev_state_get_format(sd_state, code->pad);
608 code->code = fmt->code;
609 return 0;
610 }
611
612 if (code->pad != MIPI_CSI2_PAD_SINK)
613 return -EINVAL;
614
615 if (code->index >= ARRAY_SIZE(imx8mq_mipi_csi_formats))
616 return -EINVAL;
617
618 code->code = imx8mq_mipi_csi_formats[code->index].code;
619
620 return 0;
621}
622
623static int imx8mq_mipi_csi_set_fmt(struct v4l2_subdev *sd,
624 struct v4l2_subdev_state *sd_state,
625 struct v4l2_subdev_format *sdformat)
626{
627 const struct csi2_pix_format *csi2_fmt;
628 struct v4l2_mbus_framefmt *fmt;
629
630 /*
631 * The device can't transcode in any way, the source format can't be
632 * modified.
633 */
634 if (sdformat->pad == MIPI_CSI2_PAD_SOURCE)
635 return v4l2_subdev_get_fmt(sd, sd_state, sdformat);
636
637 if (sdformat->pad != MIPI_CSI2_PAD_SINK)
638 return -EINVAL;
639
640 csi2_fmt = find_csi2_format(sdformat->format.code);
641 if (!csi2_fmt)
642 csi2_fmt = &imx8mq_mipi_csi_formats[0];
643
644 fmt = v4l2_subdev_state_get_format(sd_state, sdformat->pad);
645
646 fmt->code = csi2_fmt->code;
647 fmt->width = sdformat->format.width;
648 fmt->height = sdformat->format.height;
649
650 sdformat->format = *fmt;
651
652 /* Propagate the format from sink to source. */
653 fmt = v4l2_subdev_state_get_format(sd_state, MIPI_CSI2_PAD_SOURCE);
654 *fmt = sdformat->format;
655
656 return 0;
657}
658
659static const struct v4l2_subdev_video_ops imx8mq_mipi_csi_video_ops = {
660 .s_stream = imx8mq_mipi_csi_s_stream,
661};
662
663static const struct v4l2_subdev_pad_ops imx8mq_mipi_csi_pad_ops = {
664 .enum_mbus_code = imx8mq_mipi_csi_enum_mbus_code,
665 .get_fmt = v4l2_subdev_get_fmt,
666 .set_fmt = imx8mq_mipi_csi_set_fmt,
667};
668
669static const struct v4l2_subdev_ops imx8mq_mipi_csi_subdev_ops = {
670 .video = &imx8mq_mipi_csi_video_ops,
671 .pad = &imx8mq_mipi_csi_pad_ops,
672};
673
674static const struct v4l2_subdev_internal_ops imx8mq_mipi_csi_internal_ops = {
675 .init_state = imx8mq_mipi_csi_init_state,
676};
677
678/* -----------------------------------------------------------------------------
679 * Media entity operations
680 */
681
682static const struct media_entity_operations imx8mq_mipi_csi_entity_ops = {
683 .link_validate = v4l2_subdev_link_validate,
684 .get_fwnode_pad = v4l2_subdev_get_fwnode_pad_1_to_1,
685};
686
687/* -----------------------------------------------------------------------------
688 * Async subdev notifier
689 */
690
691static struct csi_state *
692mipi_notifier_to_csi2_state(struct v4l2_async_notifier *n)
693{
694 return container_of(n, struct csi_state, notifier);
695}
696
697static int imx8mq_mipi_csi_notify_bound(struct v4l2_async_notifier *notifier,
698 struct v4l2_subdev *sd,
699 struct v4l2_async_connection *asd)
700{
701 struct csi_state *state = mipi_notifier_to_csi2_state(notifier);
702 struct media_pad *sink = &state->sd.entity.pads[MIPI_CSI2_PAD_SINK];
703
704 state->src_sd = sd;
705
706 return v4l2_create_fwnode_links_to_pad(sd, sink, MEDIA_LNK_FL_ENABLED |
707 MEDIA_LNK_FL_IMMUTABLE);
708}
709
710static const struct v4l2_async_notifier_operations imx8mq_mipi_csi_notify_ops = {
711 .bound = imx8mq_mipi_csi_notify_bound,
712};
713
714static int imx8mq_mipi_csi_async_register(struct csi_state *state)
715{
716 struct v4l2_fwnode_endpoint vep = {
717 .bus_type = V4L2_MBUS_CSI2_DPHY,
718 };
719 struct v4l2_async_connection *asd;
720 struct fwnode_handle *ep;
721 unsigned int i;
722 int ret;
723
724 v4l2_async_subdev_nf_init(&state->notifier, &state->sd);
725
726 ep = fwnode_graph_get_endpoint_by_id(dev_fwnode(state->dev), 0, 0,
727 FWNODE_GRAPH_ENDPOINT_NEXT);
728 if (!ep)
729 return -ENOTCONN;
730
731 ret = v4l2_fwnode_endpoint_parse(ep, &vep);
732 if (ret)
733 goto err_parse;
734
735 for (i = 0; i < vep.bus.mipi_csi2.num_data_lanes; ++i) {
736 if (vep.bus.mipi_csi2.data_lanes[i] != i + 1) {
737 dev_err(state->dev,
738 "data lanes reordering is not supported");
739 ret = -EINVAL;
740 goto err_parse;
741 }
742 }
743
744 state->bus = vep.bus.mipi_csi2;
745
746 dev_dbg(state->dev, "data lanes: %d flags: 0x%08x\n",
747 state->bus.num_data_lanes,
748 state->bus.flags);
749
750 asd = v4l2_async_nf_add_fwnode_remote(&state->notifier, ep,
751 struct v4l2_async_connection);
752 if (IS_ERR(asd)) {
753 ret = PTR_ERR(asd);
754 goto err_parse;
755 }
756
757 fwnode_handle_put(ep);
758
759 state->notifier.ops = &imx8mq_mipi_csi_notify_ops;
760
761 ret = v4l2_async_nf_register(&state->notifier);
762 if (ret)
763 return ret;
764
765 return v4l2_async_register_subdev(&state->sd);
766
767err_parse:
768 fwnode_handle_put(ep);
769
770 return ret;
771}
772
773/* -----------------------------------------------------------------------------
774 * Suspend/resume
775 */
776
777static void imx8mq_mipi_csi_pm_suspend(struct device *dev)
778{
779 struct v4l2_subdev *sd = dev_get_drvdata(dev);
780 struct csi_state *state = mipi_sd_to_csi2_state(sd);
781
782 mutex_lock(&state->lock);
783
784 if (state->state & ST_POWERED) {
785 imx8mq_mipi_csi_stop_stream(state);
786 imx8mq_mipi_csi_clk_disable(state);
787 state->state &= ~ST_POWERED;
788 }
789
790 mutex_unlock(&state->lock);
791}
792
793static int imx8mq_mipi_csi_pm_resume(struct device *dev)
794{
795 struct v4l2_subdev *sd = dev_get_drvdata(dev);
796 struct csi_state *state = mipi_sd_to_csi2_state(sd);
797 struct v4l2_subdev_state *sd_state;
798 int ret = 0;
799
800 mutex_lock(&state->lock);
801
802 if (!(state->state & ST_POWERED)) {
803 state->state |= ST_POWERED;
804 ret = imx8mq_mipi_csi_clk_enable(state);
805 }
806 if (state->state & ST_STREAMING) {
807 sd_state = v4l2_subdev_lock_and_get_active_state(sd);
808 ret = imx8mq_mipi_csi_start_stream(state, sd_state);
809 v4l2_subdev_unlock_state(sd_state);
810 if (ret)
811 goto unlock;
812 }
813
814 state->state &= ~ST_SUSPENDED;
815
816unlock:
817 mutex_unlock(&state->lock);
818
819 return ret ? -EAGAIN : 0;
820}
821
822static int imx8mq_mipi_csi_suspend(struct device *dev)
823{
824 struct v4l2_subdev *sd = dev_get_drvdata(dev);
825 struct csi_state *state = mipi_sd_to_csi2_state(sd);
826
827 imx8mq_mipi_csi_pm_suspend(dev);
828
829 state->state |= ST_SUSPENDED;
830
831 return 0;
832}
833
834static int imx8mq_mipi_csi_resume(struct device *dev)
835{
836 struct v4l2_subdev *sd = dev_get_drvdata(dev);
837 struct csi_state *state = mipi_sd_to_csi2_state(sd);
838
839 if (!(state->state & ST_SUSPENDED))
840 return 0;
841
842 return imx8mq_mipi_csi_pm_resume(dev);
843}
844
845static int imx8mq_mipi_csi_runtime_suspend(struct device *dev)
846{
847 struct v4l2_subdev *sd = dev_get_drvdata(dev);
848 struct csi_state *state = mipi_sd_to_csi2_state(sd);
849 int ret;
850
851 imx8mq_mipi_csi_pm_suspend(dev);
852
853 ret = icc_set_bw(state->icc_path, 0, 0);
854 if (ret)
855 dev_err(dev, "icc_set_bw failed with %d\n", ret);
856
857 return ret;
858}
859
860static int imx8mq_mipi_csi_runtime_resume(struct device *dev)
861{
862 struct v4l2_subdev *sd = dev_get_drvdata(dev);
863 struct csi_state *state = mipi_sd_to_csi2_state(sd);
864 int ret;
865
866 ret = icc_set_bw(state->icc_path, 0, state->icc_path_bw);
867 if (ret) {
868 dev_err(dev, "icc_set_bw failed with %d\n", ret);
869 return ret;
870 }
871
872 return imx8mq_mipi_csi_pm_resume(dev);
873}
874
875static const struct dev_pm_ops imx8mq_mipi_csi_pm_ops = {
876 RUNTIME_PM_OPS(imx8mq_mipi_csi_runtime_suspend,
877 imx8mq_mipi_csi_runtime_resume, NULL)
878 SYSTEM_SLEEP_PM_OPS(imx8mq_mipi_csi_suspend, imx8mq_mipi_csi_resume)
879};
880
881/* -----------------------------------------------------------------------------
882 * Probe/remove & platform driver
883 */
884
885static int imx8mq_mipi_csi_subdev_init(struct csi_state *state)
886{
887 struct v4l2_subdev *sd = &state->sd;
888 int ret;
889
890 v4l2_subdev_init(sd, &imx8mq_mipi_csi_subdev_ops);
891 sd->internal_ops = &imx8mq_mipi_csi_internal_ops;
892 sd->owner = THIS_MODULE;
893 snprintf(sd->name, sizeof(sd->name), "%s %s",
894 MIPI_CSI2_SUBDEV_NAME, dev_name(state->dev));
895
896 sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
897
898 sd->entity.function = MEDIA_ENT_F_VID_IF_BRIDGE;
899 sd->entity.ops = &imx8mq_mipi_csi_entity_ops;
900
901 sd->dev = state->dev;
902
903 state->pads[MIPI_CSI2_PAD_SINK].flags = MEDIA_PAD_FL_SINK
904 | MEDIA_PAD_FL_MUST_CONNECT;
905 state->pads[MIPI_CSI2_PAD_SOURCE].flags = MEDIA_PAD_FL_SOURCE
906 | MEDIA_PAD_FL_MUST_CONNECT;
907 ret = media_entity_pads_init(&sd->entity, MIPI_CSI2_PADS_NUM,
908 state->pads);
909 if (ret)
910 return ret;
911
912 ret = v4l2_subdev_init_finalize(sd);
913 if (ret) {
914 media_entity_cleanup(&sd->entity);
915 return ret;
916 }
917
918 return 0;
919}
920
921static void imx8mq_mipi_csi_release_icc(struct platform_device *pdev)
922{
923 struct v4l2_subdev *sd = dev_get_drvdata(&pdev->dev);
924 struct csi_state *state = mipi_sd_to_csi2_state(sd);
925
926 icc_put(state->icc_path);
927}
928
929static int imx8mq_mipi_csi_init_icc(struct platform_device *pdev)
930{
931 struct v4l2_subdev *sd = dev_get_drvdata(&pdev->dev);
932 struct csi_state *state = mipi_sd_to_csi2_state(sd);
933
934 /* Optional interconnect request */
935 state->icc_path = of_icc_get(&pdev->dev, "dram");
936 if (IS_ERR_OR_NULL(state->icc_path))
937 return PTR_ERR_OR_ZERO(state->icc_path);
938
939 state->icc_path_bw = MBps_to_icc(700);
940
941 return 0;
942}
943
944static int imx8mq_mipi_csi_parse_dt(struct csi_state *state)
945{
946 struct device *dev = state->dev;
947 struct device_node *np = state->dev->of_node;
948 struct device_node *node;
949 phandle ph;
950 u32 out_val[2];
951 int ret = 0;
952
953 state->rst = devm_reset_control_array_get_exclusive(dev);
954 if (IS_ERR(state->rst)) {
955 dev_err(dev, "Failed to get reset: %pe\n", state->rst);
956 return PTR_ERR(state->rst);
957 }
958
959 if (state->pdata->use_reg_csr) {
960 const struct regmap_config regmap_config = {
961 .reg_bits = 32,
962 .val_bits = 32,
963 .reg_stride = 4,
964 };
965 void __iomem *base;
966
967 base = devm_platform_ioremap_resource(to_platform_device(dev), 1);
968 if (IS_ERR(base))
969 return dev_err_probe(dev, PTR_ERR(base), "Missing CSR register\n");
970
971 state->phy_gpr = devm_regmap_init_mmio(dev, base, ®map_config);
972 if (IS_ERR(state->phy_gpr))
973 return dev_err_probe(dev, PTR_ERR(state->phy_gpr),
974 "Failed to init CSI MMIO regmap\n");
975 return 0;
976 }
977
978 ret = of_property_read_u32_array(np, "fsl,mipi-phy-gpr", out_val,
979 ARRAY_SIZE(out_val));
980 if (ret) {
981 dev_err(dev, "no fsl,mipi-phy-gpr property found: %d\n", ret);
982 return ret;
983 }
984
985 ph = *out_val;
986
987 node = of_find_node_by_phandle(ph);
988 if (!node) {
989 dev_err(dev, "Error finding node by phandle\n");
990 return -ENODEV;
991 }
992 state->phy_gpr = syscon_node_to_regmap(node);
993 of_node_put(node);
994 if (IS_ERR(state->phy_gpr)) {
995 dev_err(dev, "failed to get gpr regmap: %pe\n", state->phy_gpr);
996 return PTR_ERR(state->phy_gpr);
997 }
998
999 state->phy_gpr_reg = out_val[1];
1000 dev_dbg(dev, "phy gpr register set to 0x%x\n", state->phy_gpr_reg);
1001
1002 return ret;
1003}
1004
1005static int imx8mq_mipi_csi_probe(struct platform_device *pdev)
1006{
1007 struct device *dev = &pdev->dev;
1008 struct csi_state *state;
1009 int ret;
1010
1011 state = devm_kzalloc(dev, sizeof(*state), GFP_KERNEL);
1012 if (!state)
1013 return -ENOMEM;
1014
1015 state->dev = dev;
1016
1017 state->pdata = of_device_get_match_data(dev);
1018
1019 ret = imx8mq_mipi_csi_parse_dt(state);
1020 if (ret < 0) {
1021 dev_err(dev, "Failed to parse device tree: %d\n", ret);
1022 return ret;
1023 }
1024
1025 /* Acquire resources. */
1026 state->regs = devm_platform_ioremap_resource(pdev, 0);
1027 if (IS_ERR(state->regs))
1028 return PTR_ERR(state->regs);
1029
1030 ret = imx8mq_mipi_csi_clk_get(state);
1031 if (ret < 0)
1032 return ret;
1033
1034 platform_set_drvdata(pdev, &state->sd);
1035
1036 mutex_init(&state->lock);
1037
1038 ret = imx8mq_mipi_csi_subdev_init(state);
1039 if (ret < 0)
1040 goto mutex;
1041
1042 ret = imx8mq_mipi_csi_init_icc(pdev);
1043 if (ret)
1044 goto mutex;
1045
1046 /* Enable runtime PM. */
1047 pm_runtime_enable(dev);
1048 if (!pm_runtime_enabled(dev)) {
1049 ret = imx8mq_mipi_csi_runtime_resume(dev);
1050 if (ret < 0)
1051 goto icc;
1052 }
1053
1054 ret = imx8mq_mipi_csi_async_register(state);
1055 if (ret < 0)
1056 goto cleanup;
1057
1058 return 0;
1059
1060cleanup:
1061 pm_runtime_disable(&pdev->dev);
1062 imx8mq_mipi_csi_runtime_suspend(&pdev->dev);
1063
1064 media_entity_cleanup(&state->sd.entity);
1065 v4l2_subdev_cleanup(&state->sd);
1066 v4l2_async_nf_unregister(&state->notifier);
1067 v4l2_async_nf_cleanup(&state->notifier);
1068 v4l2_async_unregister_subdev(&state->sd);
1069icc:
1070 imx8mq_mipi_csi_release_icc(pdev);
1071mutex:
1072 mutex_destroy(&state->lock);
1073
1074 return ret;
1075}
1076
1077static void imx8mq_mipi_csi_remove(struct platform_device *pdev)
1078{
1079 struct v4l2_subdev *sd = platform_get_drvdata(pdev);
1080 struct csi_state *state = mipi_sd_to_csi2_state(sd);
1081
1082 v4l2_async_nf_unregister(&state->notifier);
1083 v4l2_async_nf_cleanup(&state->notifier);
1084 v4l2_async_unregister_subdev(&state->sd);
1085
1086 pm_runtime_disable(&pdev->dev);
1087 imx8mq_mipi_csi_runtime_suspend(&pdev->dev);
1088 media_entity_cleanup(&state->sd.entity);
1089 v4l2_subdev_cleanup(&state->sd);
1090 mutex_destroy(&state->lock);
1091 pm_runtime_set_suspended(&pdev->dev);
1092 imx8mq_mipi_csi_release_icc(pdev);
1093}
1094
1095static const struct of_device_id imx8mq_mipi_csi_of_match[] = {
1096 { .compatible = "fsl,imx8mq-mipi-csi2", .data = &imx8mq_data },
1097 { .compatible = "fsl,imx8qxp-mipi-csi2", .data = &imx8qxp_data },
1098 { /* sentinel */ },
1099};
1100MODULE_DEVICE_TABLE(of, imx8mq_mipi_csi_of_match);
1101
1102static struct platform_driver imx8mq_mipi_csi_driver = {
1103 .probe = imx8mq_mipi_csi_probe,
1104 .remove = imx8mq_mipi_csi_remove,
1105 .driver = {
1106 .of_match_table = imx8mq_mipi_csi_of_match,
1107 .name = MIPI_CSI2_DRIVER_NAME,
1108 .pm = pm_ptr(&imx8mq_mipi_csi_pm_ops),
1109 },
1110};
1111
1112module_platform_driver(imx8mq_mipi_csi_driver);
1113
1114MODULE_DESCRIPTION("i.MX8MQ MIPI CSI-2 receiver driver");
1115MODULE_AUTHOR("Martin Kepplinger <martin.kepplinger@puri.sm>");
1116MODULE_LICENSE("GPL v2");