0001
0002
0003
0004
0005
0006
0007
0008 #include <linux/clk.h>
0009 #include <linux/clk-provider.h>
0010 #include <linux/delay.h>
0011 #include <linux/errno.h>
0012 #include <linux/interconnect.h>
0013 #include <linux/interrupt.h>
0014 #include <linux/io.h>
0015 #include <linux/kernel.h>
0016 #include <linux/mfd/syscon.h>
0017 #include <linux/module.h>
0018 #include <linux/mutex.h>
0019 #include <linux/of.h>
0020 #include <linux/of_device.h>
0021 #include <linux/platform_device.h>
0022 #include <linux/pm_runtime.h>
0023 #include <linux/regmap.h>
0024 #include <linux/regulator/consumer.h>
0025 #include <linux/reset.h>
0026 #include <linux/spinlock.h>
0027
0028 #include <media/v4l2-common.h>
0029 #include <media/v4l2-device.h>
0030 #include <media/v4l2-fwnode.h>
0031 #include <media/v4l2-mc.h>
0032 #include <media/v4l2-subdev.h>
0033
0034 #define MIPI_CSI2_DRIVER_NAME "imx8mq-mipi-csi2"
0035 #define MIPI_CSI2_SUBDEV_NAME MIPI_CSI2_DRIVER_NAME
0036
0037 #define MIPI_CSI2_PAD_SINK 0
0038 #define MIPI_CSI2_PAD_SOURCE 1
0039 #define MIPI_CSI2_PADS_NUM 2
0040
0041 #define MIPI_CSI2_DEF_PIX_WIDTH 640
0042 #define MIPI_CSI2_DEF_PIX_HEIGHT 480
0043
0044
0045
0046
0047 #define CSI2RX_CFG_NUM_LANES 0x100
0048 #define CSI2RX_CFG_DISABLE_DATA_LANES 0x104
0049 #define CSI2RX_BIT_ERR 0x108
0050 #define CSI2RX_IRQ_STATUS 0x10c
0051 #define CSI2RX_IRQ_MASK 0x110
0052 #define CSI2RX_IRQ_MASK_ALL 0x1ff
0053 #define CSI2RX_IRQ_MASK_ULPS_STATUS_CHANGE 0x8
0054 #define CSI2RX_ULPS_STATUS 0x114
0055 #define CSI2RX_PPI_ERRSOT_HS 0x118
0056 #define CSI2RX_PPI_ERRSOTSYNC_HS 0x11c
0057 #define CSI2RX_PPI_ERRESC 0x120
0058 #define CSI2RX_PPI_ERRSYNCESC 0x124
0059 #define CSI2RX_PPI_ERRCONTROL 0x128
0060 #define CSI2RX_CFG_DISABLE_PAYLOAD_0 0x12c
0061 #define CSI2RX_CFG_VID_VC_IGNORE 0x180
0062 #define CSI2RX_CFG_VID_VC 0x184
0063 #define CSI2RX_CFG_VID_P_FIFO_SEND_LEVEL 0x188
0064 #define CSI2RX_CFG_DISABLE_PAYLOAD_1 0x130
0065
0066 enum {
0067 ST_POWERED = 1,
0068 ST_STREAMING = 2,
0069 ST_SUSPENDED = 4,
0070 };
0071
0072 enum imx8mq_mipi_csi_clk {
0073 CSI2_CLK_CORE,
0074 CSI2_CLK_ESC,
0075 CSI2_CLK_UI,
0076 CSI2_NUM_CLKS,
0077 };
0078
0079 static const char * const imx8mq_mipi_csi_clk_id[CSI2_NUM_CLKS] = {
0080 [CSI2_CLK_CORE] = "core",
0081 [CSI2_CLK_ESC] = "esc",
0082 [CSI2_CLK_UI] = "ui",
0083 };
0084
0085 #define CSI2_NUM_CLKS ARRAY_SIZE(imx8mq_mipi_csi_clk_id)
0086
0087 #define GPR_CSI2_1_RX_ENABLE BIT(13)
0088 #define GPR_CSI2_1_VID_INTFC_ENB BIT(12)
0089 #define GPR_CSI2_1_HSEL BIT(10)
0090 #define GPR_CSI2_1_CONT_CLK_MODE BIT(8)
0091 #define GPR_CSI2_1_S_PRG_RXHS_SETTLE(x) (((x) & 0x3f) << 2)
0092
0093
0094
0095
0096
0097
0098
0099
0100
0101
0102
0103
0104
0105
0106 #define CSI2RX_SEND_LEVEL 64
0107
0108 struct csi_state {
0109 struct device *dev;
0110 void __iomem *regs;
0111 struct clk_bulk_data clks[CSI2_NUM_CLKS];
0112 struct reset_control *rst;
0113 struct regulator *mipi_phy_regulator;
0114
0115 struct v4l2_subdev sd;
0116 struct media_pad pads[MIPI_CSI2_PADS_NUM];
0117 struct v4l2_async_notifier notifier;
0118 struct v4l2_subdev *src_sd;
0119
0120 struct v4l2_mbus_config_mipi_csi2 bus;
0121
0122 struct mutex lock;
0123 const struct csi2_pix_format *csi2_fmt;
0124 struct v4l2_mbus_framefmt format_mbus[MIPI_CSI2_PADS_NUM];
0125 u32 state;
0126 u32 hs_settle;
0127
0128 struct regmap *phy_gpr;
0129 u8 phy_gpr_reg;
0130
0131 struct icc_path *icc_path;
0132 s32 icc_path_bw;
0133 };
0134
0135
0136
0137
0138
0139 struct csi2_pix_format {
0140 u32 code;
0141 u8 width;
0142 };
0143
0144 static const struct csi2_pix_format imx8mq_mipi_csi_formats[] = {
0145
0146 {
0147 .code = MEDIA_BUS_FMT_SBGGR8_1X8,
0148 .width = 8,
0149 }, {
0150 .code = MEDIA_BUS_FMT_SGBRG8_1X8,
0151 .width = 8,
0152 }, {
0153 .code = MEDIA_BUS_FMT_SGRBG8_1X8,
0154 .width = 8,
0155 }, {
0156 .code = MEDIA_BUS_FMT_SRGGB8_1X8,
0157 .width = 8,
0158 }, {
0159 .code = MEDIA_BUS_FMT_Y8_1X8,
0160 .width = 8,
0161 }, {
0162 .code = MEDIA_BUS_FMT_SBGGR10_1X10,
0163 .width = 10,
0164 }, {
0165 .code = MEDIA_BUS_FMT_SGBRG10_1X10,
0166 .width = 10,
0167 }, {
0168 .code = MEDIA_BUS_FMT_SGRBG10_1X10,
0169 .width = 10,
0170 }, {
0171 .code = MEDIA_BUS_FMT_SRGGB10_1X10,
0172 .width = 10,
0173 }, {
0174 .code = MEDIA_BUS_FMT_Y10_1X10,
0175 .width = 10,
0176 }, {
0177 .code = MEDIA_BUS_FMT_SBGGR12_1X12,
0178 .width = 12,
0179 }, {
0180 .code = MEDIA_BUS_FMT_SGBRG12_1X12,
0181 .width = 12,
0182 }, {
0183 .code = MEDIA_BUS_FMT_SGRBG12_1X12,
0184 .width = 12,
0185 }, {
0186 .code = MEDIA_BUS_FMT_SRGGB12_1X12,
0187 .width = 12,
0188 }, {
0189 .code = MEDIA_BUS_FMT_Y12_1X12,
0190 .width = 12,
0191 }, {
0192 .code = MEDIA_BUS_FMT_SBGGR14_1X14,
0193 .width = 14,
0194 }, {
0195 .code = MEDIA_BUS_FMT_SGBRG14_1X14,
0196 .width = 14,
0197 }, {
0198 .code = MEDIA_BUS_FMT_SGRBG14_1X14,
0199 .width = 14,
0200 }, {
0201 .code = MEDIA_BUS_FMT_SRGGB14_1X14,
0202 .width = 14,
0203 },
0204
0205 {
0206 .code = MEDIA_BUS_FMT_YUYV8_1X16,
0207 .width = 16,
0208 }, {
0209 .code = MEDIA_BUS_FMT_UYVY8_1X16,
0210 .width = 16,
0211 }
0212 };
0213
0214 static const struct csi2_pix_format *find_csi2_format(u32 code)
0215 {
0216 unsigned int i;
0217
0218 for (i = 0; i < ARRAY_SIZE(imx8mq_mipi_csi_formats); i++)
0219 if (code == imx8mq_mipi_csi_formats[i].code)
0220 return &imx8mq_mipi_csi_formats[i];
0221 return NULL;
0222 }
0223
0224
0225
0226
0227
0228 static inline void imx8mq_mipi_csi_write(struct csi_state *state, u32 reg, u32 val)
0229 {
0230 writel(val, state->regs + reg);
0231 }
0232
0233 static int imx8mq_mipi_csi_sw_reset(struct csi_state *state)
0234 {
0235 int ret;
0236
0237
0238
0239
0240
0241
0242 ret = reset_control_assert(state->rst);
0243 if (ret < 0) {
0244 dev_err(state->dev, "Failed to assert resets: %d\n", ret);
0245 return ret;
0246 }
0247
0248 return 0;
0249 }
0250
0251 static void imx8mq_mipi_csi_system_enable(struct csi_state *state, int on)
0252 {
0253 if (!on) {
0254 imx8mq_mipi_csi_write(state, CSI2RX_CFG_DISABLE_DATA_LANES, 0xf);
0255 return;
0256 }
0257
0258 regmap_update_bits(state->phy_gpr,
0259 state->phy_gpr_reg,
0260 0x3fff,
0261 GPR_CSI2_1_RX_ENABLE |
0262 GPR_CSI2_1_VID_INTFC_ENB |
0263 GPR_CSI2_1_HSEL |
0264 GPR_CSI2_1_CONT_CLK_MODE |
0265 GPR_CSI2_1_S_PRG_RXHS_SETTLE(state->hs_settle));
0266 }
0267
0268 static void imx8mq_mipi_csi_set_params(struct csi_state *state)
0269 {
0270 int lanes = state->bus.num_data_lanes;
0271
0272 imx8mq_mipi_csi_write(state, CSI2RX_CFG_NUM_LANES, lanes - 1);
0273 imx8mq_mipi_csi_write(state, CSI2RX_CFG_DISABLE_DATA_LANES,
0274 (0xf << lanes) & 0xf);
0275 imx8mq_mipi_csi_write(state, CSI2RX_IRQ_MASK, CSI2RX_IRQ_MASK_ALL);
0276
0277
0278
0279
0280
0281
0282 imx8mq_mipi_csi_write(state, CSI2RX_CFG_VID_VC_IGNORE, 1);
0283 imx8mq_mipi_csi_write(state, CSI2RX_CFG_VID_P_FIFO_SEND_LEVEL,
0284 CSI2RX_SEND_LEVEL);
0285 }
0286
0287 static int imx8mq_mipi_csi_clk_enable(struct csi_state *state)
0288 {
0289 return clk_bulk_prepare_enable(CSI2_NUM_CLKS, state->clks);
0290 }
0291
0292 static void imx8mq_mipi_csi_clk_disable(struct csi_state *state)
0293 {
0294 clk_bulk_disable_unprepare(CSI2_NUM_CLKS, state->clks);
0295 }
0296
0297 static int imx8mq_mipi_csi_clk_get(struct csi_state *state)
0298 {
0299 unsigned int i;
0300
0301 for (i = 0; i < CSI2_NUM_CLKS; i++)
0302 state->clks[i].id = imx8mq_mipi_csi_clk_id[i];
0303
0304 return devm_clk_bulk_get(state->dev, CSI2_NUM_CLKS, state->clks);
0305 }
0306
0307 static int imx8mq_mipi_csi_calc_hs_settle(struct csi_state *state)
0308 {
0309 s64 link_freq;
0310 u32 lane_rate;
0311 unsigned long esc_clk_rate;
0312 u32 min_ths_settle, max_ths_settle, ths_settle_ns, esc_clk_period_ns;
0313
0314
0315 link_freq = v4l2_get_link_freq(state->src_sd->ctrl_handler,
0316 state->csi2_fmt->width,
0317 state->bus.num_data_lanes * 2);
0318 if (link_freq < 0) {
0319 dev_err(state->dev, "Unable to obtain link frequency: %d\n",
0320 (int)link_freq);
0321 return link_freq;
0322 }
0323
0324 lane_rate = link_freq * 2;
0325 if (lane_rate < 80000000 || lane_rate > 1500000000) {
0326 dev_dbg(state->dev, "Out-of-bound lane rate %u\n", lane_rate);
0327 return -EINVAL;
0328 }
0329
0330
0331
0332
0333
0334
0335
0336
0337
0338
0339
0340
0341
0342
0343
0344 esc_clk_rate = clk_get_rate(state->clks[CSI2_CLK_ESC].clk);
0345 if (!esc_clk_rate) {
0346 dev_err(state->dev, "Could not get esc clock rate.\n");
0347 return -EINVAL;
0348 }
0349
0350 dev_dbg(state->dev, "esc clk rate: %lu\n", esc_clk_rate);
0351 esc_clk_period_ns = 1000000000 / esc_clk_rate;
0352
0353 min_ths_settle = 85 + 6 * 1000000 / (lane_rate / 1000);
0354 max_ths_settle = 140 + 10 * 1000000 / (lane_rate / 1000);
0355 ths_settle_ns = (min_ths_settle + max_ths_settle) / 2;
0356
0357 state->hs_settle = ths_settle_ns / esc_clk_period_ns - 1;
0358
0359 dev_dbg(state->dev, "lane rate %u Ths_settle %u hs_settle %u\n",
0360 lane_rate, ths_settle_ns, state->hs_settle);
0361
0362 return 0;
0363 }
0364
0365 static int imx8mq_mipi_csi_start_stream(struct csi_state *state)
0366 {
0367 int ret;
0368
0369 ret = imx8mq_mipi_csi_sw_reset(state);
0370 if (ret)
0371 return ret;
0372
0373 imx8mq_mipi_csi_set_params(state);
0374 ret = imx8mq_mipi_csi_calc_hs_settle(state);
0375 if (ret)
0376 return ret;
0377
0378 imx8mq_mipi_csi_system_enable(state, true);
0379
0380 return 0;
0381 }
0382
0383 static void imx8mq_mipi_csi_stop_stream(struct csi_state *state)
0384 {
0385 imx8mq_mipi_csi_system_enable(state, false);
0386 }
0387
0388
0389
0390
0391
0392 static struct csi_state *mipi_sd_to_csi2_state(struct v4l2_subdev *sdev)
0393 {
0394 return container_of(sdev, struct csi_state, sd);
0395 }
0396
0397 static int imx8mq_mipi_csi_s_stream(struct v4l2_subdev *sd, int enable)
0398 {
0399 struct csi_state *state = mipi_sd_to_csi2_state(sd);
0400 int ret = 0;
0401
0402 if (enable) {
0403 ret = pm_runtime_resume_and_get(state->dev);
0404 if (ret < 0)
0405 return ret;
0406 }
0407
0408 mutex_lock(&state->lock);
0409
0410 if (enable) {
0411 if (state->state & ST_SUSPENDED) {
0412 ret = -EBUSY;
0413 goto unlock;
0414 }
0415
0416 ret = imx8mq_mipi_csi_start_stream(state);
0417 if (ret < 0)
0418 goto unlock;
0419
0420 ret = v4l2_subdev_call(state->src_sd, video, s_stream, 1);
0421 if (ret < 0)
0422 goto unlock;
0423
0424 state->state |= ST_STREAMING;
0425 } else {
0426 v4l2_subdev_call(state->src_sd, video, s_stream, 0);
0427 imx8mq_mipi_csi_stop_stream(state);
0428 state->state &= ~ST_STREAMING;
0429 }
0430
0431 unlock:
0432 mutex_unlock(&state->lock);
0433
0434 if (!enable || ret < 0)
0435 pm_runtime_put(state->dev);
0436
0437 return ret;
0438 }
0439
0440 static struct v4l2_mbus_framefmt *
0441 imx8mq_mipi_csi_get_format(struct csi_state *state,
0442 struct v4l2_subdev_state *sd_state,
0443 enum v4l2_subdev_format_whence which,
0444 unsigned int pad)
0445 {
0446 if (which == V4L2_SUBDEV_FORMAT_TRY)
0447 return v4l2_subdev_get_try_format(&state->sd, sd_state, pad);
0448
0449 return &state->format_mbus[pad];
0450 }
0451
0452 static int imx8mq_mipi_csi_init_cfg(struct v4l2_subdev *sd,
0453 struct v4l2_subdev_state *sd_state)
0454 {
0455 struct csi_state *state = mipi_sd_to_csi2_state(sd);
0456 struct v4l2_mbus_framefmt *fmt_sink;
0457 struct v4l2_mbus_framefmt *fmt_source;
0458 enum v4l2_subdev_format_whence which;
0459
0460 which = sd_state ? V4L2_SUBDEV_FORMAT_TRY : V4L2_SUBDEV_FORMAT_ACTIVE;
0461 fmt_sink = imx8mq_mipi_csi_get_format(state, sd_state, which,
0462 MIPI_CSI2_PAD_SINK);
0463
0464 fmt_sink->code = MEDIA_BUS_FMT_SGBRG10_1X10;
0465 fmt_sink->width = MIPI_CSI2_DEF_PIX_WIDTH;
0466 fmt_sink->height = MIPI_CSI2_DEF_PIX_HEIGHT;
0467 fmt_sink->field = V4L2_FIELD_NONE;
0468
0469 fmt_sink->colorspace = V4L2_COLORSPACE_RAW;
0470 fmt_sink->xfer_func = V4L2_MAP_XFER_FUNC_DEFAULT(fmt_sink->colorspace);
0471 fmt_sink->ycbcr_enc = V4L2_MAP_YCBCR_ENC_DEFAULT(fmt_sink->colorspace);
0472 fmt_sink->quantization =
0473 V4L2_MAP_QUANTIZATION_DEFAULT(false, fmt_sink->colorspace,
0474 fmt_sink->ycbcr_enc);
0475
0476 fmt_source = imx8mq_mipi_csi_get_format(state, sd_state, which,
0477 MIPI_CSI2_PAD_SOURCE);
0478 *fmt_source = *fmt_sink;
0479
0480 return 0;
0481 }
0482
0483 static int imx8mq_mipi_csi_get_fmt(struct v4l2_subdev *sd,
0484 struct v4l2_subdev_state *sd_state,
0485 struct v4l2_subdev_format *sdformat)
0486 {
0487 struct csi_state *state = mipi_sd_to_csi2_state(sd);
0488 struct v4l2_mbus_framefmt *fmt;
0489
0490 fmt = imx8mq_mipi_csi_get_format(state, sd_state, sdformat->which,
0491 sdformat->pad);
0492
0493 mutex_lock(&state->lock);
0494
0495 sdformat->format = *fmt;
0496
0497 mutex_unlock(&state->lock);
0498
0499 return 0;
0500 }
0501
0502 static int imx8mq_mipi_csi_enum_mbus_code(struct v4l2_subdev *sd,
0503 struct v4l2_subdev_state *sd_state,
0504 struct v4l2_subdev_mbus_code_enum *code)
0505 {
0506 struct csi_state *state = mipi_sd_to_csi2_state(sd);
0507
0508
0509
0510
0511
0512 if (code->pad == MIPI_CSI2_PAD_SOURCE) {
0513 struct v4l2_mbus_framefmt *fmt;
0514
0515 if (code->index > 0)
0516 return -EINVAL;
0517
0518 fmt = imx8mq_mipi_csi_get_format(state, sd_state, code->which,
0519 code->pad);
0520 code->code = fmt->code;
0521 return 0;
0522 }
0523
0524 if (code->pad != MIPI_CSI2_PAD_SINK)
0525 return -EINVAL;
0526
0527 if (code->index >= ARRAY_SIZE(imx8mq_mipi_csi_formats))
0528 return -EINVAL;
0529
0530 code->code = imx8mq_mipi_csi_formats[code->index].code;
0531
0532 return 0;
0533 }
0534
0535 static int imx8mq_mipi_csi_set_fmt(struct v4l2_subdev *sd,
0536 struct v4l2_subdev_state *sd_state,
0537 struct v4l2_subdev_format *sdformat)
0538 {
0539 struct csi_state *state = mipi_sd_to_csi2_state(sd);
0540 struct csi2_pix_format const *csi2_fmt;
0541 struct v4l2_mbus_framefmt *fmt;
0542
0543
0544
0545
0546
0547 if (sdformat->pad == MIPI_CSI2_PAD_SOURCE)
0548 return imx8mq_mipi_csi_get_fmt(sd, sd_state, sdformat);
0549
0550 if (sdformat->pad != MIPI_CSI2_PAD_SINK)
0551 return -EINVAL;
0552
0553 csi2_fmt = find_csi2_format(sdformat->format.code);
0554 if (!csi2_fmt)
0555 csi2_fmt = &imx8mq_mipi_csi_formats[0];
0556
0557 fmt = imx8mq_mipi_csi_get_format(state, sd_state, sdformat->which,
0558 sdformat->pad);
0559
0560 mutex_lock(&state->lock);
0561
0562 fmt->code = csi2_fmt->code;
0563 fmt->width = sdformat->format.width;
0564 fmt->height = sdformat->format.height;
0565
0566 sdformat->format = *fmt;
0567
0568
0569 fmt = imx8mq_mipi_csi_get_format(state, sd_state, sdformat->which,
0570 MIPI_CSI2_PAD_SOURCE);
0571 *fmt = sdformat->format;
0572
0573
0574 if (sdformat->which == V4L2_SUBDEV_FORMAT_ACTIVE)
0575 state->csi2_fmt = csi2_fmt;
0576
0577 mutex_unlock(&state->lock);
0578
0579 return 0;
0580 }
0581
0582 static const struct v4l2_subdev_video_ops imx8mq_mipi_csi_video_ops = {
0583 .s_stream = imx8mq_mipi_csi_s_stream,
0584 };
0585
0586 static const struct v4l2_subdev_pad_ops imx8mq_mipi_csi_pad_ops = {
0587 .init_cfg = imx8mq_mipi_csi_init_cfg,
0588 .enum_mbus_code = imx8mq_mipi_csi_enum_mbus_code,
0589 .get_fmt = imx8mq_mipi_csi_get_fmt,
0590 .set_fmt = imx8mq_mipi_csi_set_fmt,
0591 };
0592
0593 static const struct v4l2_subdev_ops imx8mq_mipi_csi_subdev_ops = {
0594 .video = &imx8mq_mipi_csi_video_ops,
0595 .pad = &imx8mq_mipi_csi_pad_ops,
0596 };
0597
0598
0599
0600
0601
0602 static const struct media_entity_operations imx8mq_mipi_csi_entity_ops = {
0603 .link_validate = v4l2_subdev_link_validate,
0604 .get_fwnode_pad = v4l2_subdev_get_fwnode_pad_1_to_1,
0605 };
0606
0607
0608
0609
0610
0611 static struct csi_state *
0612 mipi_notifier_to_csi2_state(struct v4l2_async_notifier *n)
0613 {
0614 return container_of(n, struct csi_state, notifier);
0615 }
0616
0617 static int imx8mq_mipi_csi_notify_bound(struct v4l2_async_notifier *notifier,
0618 struct v4l2_subdev *sd,
0619 struct v4l2_async_subdev *asd)
0620 {
0621 struct csi_state *state = mipi_notifier_to_csi2_state(notifier);
0622 struct media_pad *sink = &state->sd.entity.pads[MIPI_CSI2_PAD_SINK];
0623
0624 state->src_sd = sd;
0625
0626 return v4l2_create_fwnode_links_to_pad(sd, sink, MEDIA_LNK_FL_ENABLED |
0627 MEDIA_LNK_FL_IMMUTABLE);
0628 }
0629
0630 static const struct v4l2_async_notifier_operations imx8mq_mipi_csi_notify_ops = {
0631 .bound = imx8mq_mipi_csi_notify_bound,
0632 };
0633
0634 static int imx8mq_mipi_csi_async_register(struct csi_state *state)
0635 {
0636 struct v4l2_fwnode_endpoint vep = {
0637 .bus_type = V4L2_MBUS_CSI2_DPHY,
0638 };
0639 struct v4l2_async_subdev *asd;
0640 struct fwnode_handle *ep;
0641 unsigned int i;
0642 int ret;
0643
0644 v4l2_async_nf_init(&state->notifier);
0645
0646 ep = fwnode_graph_get_endpoint_by_id(dev_fwnode(state->dev), 0, 0,
0647 FWNODE_GRAPH_ENDPOINT_NEXT);
0648 if (!ep)
0649 return -ENOTCONN;
0650
0651 ret = v4l2_fwnode_endpoint_parse(ep, &vep);
0652 if (ret)
0653 goto err_parse;
0654
0655 for (i = 0; i < vep.bus.mipi_csi2.num_data_lanes; ++i) {
0656 if (vep.bus.mipi_csi2.data_lanes[i] != i + 1) {
0657 dev_err(state->dev,
0658 "data lanes reordering is not supported");
0659 ret = -EINVAL;
0660 goto err_parse;
0661 }
0662 }
0663
0664 state->bus = vep.bus.mipi_csi2;
0665
0666 dev_dbg(state->dev, "data lanes: %d flags: 0x%08x\n",
0667 state->bus.num_data_lanes,
0668 state->bus.flags);
0669
0670 asd = v4l2_async_nf_add_fwnode_remote(&state->notifier, ep,
0671 struct v4l2_async_subdev);
0672 if (IS_ERR(asd)) {
0673 ret = PTR_ERR(asd);
0674 goto err_parse;
0675 }
0676
0677 fwnode_handle_put(ep);
0678
0679 state->notifier.ops = &imx8mq_mipi_csi_notify_ops;
0680
0681 ret = v4l2_async_subdev_nf_register(&state->sd, &state->notifier);
0682 if (ret)
0683 return ret;
0684
0685 return v4l2_async_register_subdev(&state->sd);
0686
0687 err_parse:
0688 fwnode_handle_put(ep);
0689
0690 return ret;
0691 }
0692
0693
0694
0695
0696
0697 static void imx8mq_mipi_csi_pm_suspend(struct device *dev)
0698 {
0699 struct v4l2_subdev *sd = dev_get_drvdata(dev);
0700 struct csi_state *state = mipi_sd_to_csi2_state(sd);
0701
0702 mutex_lock(&state->lock);
0703
0704 if (state->state & ST_POWERED) {
0705 imx8mq_mipi_csi_stop_stream(state);
0706 imx8mq_mipi_csi_clk_disable(state);
0707 state->state &= ~ST_POWERED;
0708 }
0709
0710 mutex_unlock(&state->lock);
0711 }
0712
0713 static int imx8mq_mipi_csi_pm_resume(struct device *dev)
0714 {
0715 struct v4l2_subdev *sd = dev_get_drvdata(dev);
0716 struct csi_state *state = mipi_sd_to_csi2_state(sd);
0717 int ret = 0;
0718
0719 mutex_lock(&state->lock);
0720
0721 if (!(state->state & ST_POWERED)) {
0722 state->state |= ST_POWERED;
0723 ret = imx8mq_mipi_csi_clk_enable(state);
0724 }
0725 if (state->state & ST_STREAMING) {
0726 ret = imx8mq_mipi_csi_start_stream(state);
0727 if (ret)
0728 goto unlock;
0729 }
0730
0731 state->state &= ~ST_SUSPENDED;
0732
0733 unlock:
0734 mutex_unlock(&state->lock);
0735
0736 return ret ? -EAGAIN : 0;
0737 }
0738
0739 static int __maybe_unused imx8mq_mipi_csi_suspend(struct device *dev)
0740 {
0741 struct v4l2_subdev *sd = dev_get_drvdata(dev);
0742 struct csi_state *state = mipi_sd_to_csi2_state(sd);
0743
0744 imx8mq_mipi_csi_pm_suspend(dev);
0745
0746 state->state |= ST_SUSPENDED;
0747
0748 return 0;
0749 }
0750
0751 static int __maybe_unused imx8mq_mipi_csi_resume(struct device *dev)
0752 {
0753 struct v4l2_subdev *sd = dev_get_drvdata(dev);
0754 struct csi_state *state = mipi_sd_to_csi2_state(sd);
0755
0756 if (!(state->state & ST_SUSPENDED))
0757 return 0;
0758
0759 return imx8mq_mipi_csi_pm_resume(dev);
0760 }
0761
0762 static int __maybe_unused imx8mq_mipi_csi_runtime_suspend(struct device *dev)
0763 {
0764 struct v4l2_subdev *sd = dev_get_drvdata(dev);
0765 struct csi_state *state = mipi_sd_to_csi2_state(sd);
0766 int ret;
0767
0768 imx8mq_mipi_csi_pm_suspend(dev);
0769
0770 ret = icc_set_bw(state->icc_path, 0, 0);
0771 if (ret)
0772 dev_err(dev, "icc_set_bw failed with %d\n", ret);
0773
0774 return ret;
0775 }
0776
0777 static int __maybe_unused imx8mq_mipi_csi_runtime_resume(struct device *dev)
0778 {
0779 struct v4l2_subdev *sd = dev_get_drvdata(dev);
0780 struct csi_state *state = mipi_sd_to_csi2_state(sd);
0781 int ret;
0782
0783 ret = icc_set_bw(state->icc_path, 0, state->icc_path_bw);
0784 if (ret) {
0785 dev_err(dev, "icc_set_bw failed with %d\n", ret);
0786 return ret;
0787 }
0788
0789 return imx8mq_mipi_csi_pm_resume(dev);
0790 }
0791
0792 static const struct dev_pm_ops imx8mq_mipi_csi_pm_ops = {
0793 SET_RUNTIME_PM_OPS(imx8mq_mipi_csi_runtime_suspend,
0794 imx8mq_mipi_csi_runtime_resume,
0795 NULL)
0796 SET_SYSTEM_SLEEP_PM_OPS(imx8mq_mipi_csi_suspend, imx8mq_mipi_csi_resume)
0797 };
0798
0799
0800
0801
0802
0803 static int imx8mq_mipi_csi_subdev_init(struct csi_state *state)
0804 {
0805 struct v4l2_subdev *sd = &state->sd;
0806
0807 v4l2_subdev_init(sd, &imx8mq_mipi_csi_subdev_ops);
0808 sd->owner = THIS_MODULE;
0809 snprintf(sd->name, sizeof(sd->name), "%s %s",
0810 MIPI_CSI2_SUBDEV_NAME, dev_name(state->dev));
0811
0812 sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
0813
0814 sd->entity.function = MEDIA_ENT_F_VID_IF_BRIDGE;
0815 sd->entity.ops = &imx8mq_mipi_csi_entity_ops;
0816
0817 sd->dev = state->dev;
0818
0819 state->csi2_fmt = &imx8mq_mipi_csi_formats[0];
0820 imx8mq_mipi_csi_init_cfg(sd, NULL);
0821
0822 state->pads[MIPI_CSI2_PAD_SINK].flags = MEDIA_PAD_FL_SINK
0823 | MEDIA_PAD_FL_MUST_CONNECT;
0824 state->pads[MIPI_CSI2_PAD_SOURCE].flags = MEDIA_PAD_FL_SOURCE
0825 | MEDIA_PAD_FL_MUST_CONNECT;
0826 return media_entity_pads_init(&sd->entity, MIPI_CSI2_PADS_NUM,
0827 state->pads);
0828 }
0829
0830 static void imx8mq_mipi_csi_release_icc(struct platform_device *pdev)
0831 {
0832 struct v4l2_subdev *sd = dev_get_drvdata(&pdev->dev);
0833 struct csi_state *state = mipi_sd_to_csi2_state(sd);
0834
0835 icc_put(state->icc_path);
0836 }
0837
0838 static int imx8mq_mipi_csi_init_icc(struct platform_device *pdev)
0839 {
0840 struct v4l2_subdev *sd = dev_get_drvdata(&pdev->dev);
0841 struct csi_state *state = mipi_sd_to_csi2_state(sd);
0842
0843
0844 state->icc_path = of_icc_get(&pdev->dev, "dram");
0845 if (IS_ERR_OR_NULL(state->icc_path))
0846 return PTR_ERR_OR_ZERO(state->icc_path);
0847
0848 state->icc_path_bw = MBps_to_icc(700);
0849
0850 return 0;
0851 }
0852
0853 static int imx8mq_mipi_csi_parse_dt(struct csi_state *state)
0854 {
0855 struct device *dev = state->dev;
0856 struct device_node *np = state->dev->of_node;
0857 struct device_node *node;
0858 phandle ph;
0859 u32 out_val[2];
0860 int ret = 0;
0861
0862 state->rst = devm_reset_control_array_get_exclusive(dev);
0863 if (IS_ERR(state->rst)) {
0864 dev_err(dev, "Failed to get reset: %pe\n", state->rst);
0865 return PTR_ERR(state->rst);
0866 }
0867
0868 ret = of_property_read_u32_array(np, "fsl,mipi-phy-gpr", out_val,
0869 ARRAY_SIZE(out_val));
0870 if (ret) {
0871 dev_err(dev, "no fsl,mipi-phy-gpr property found: %d\n", ret);
0872 return ret;
0873 }
0874
0875 ph = *out_val;
0876
0877 node = of_find_node_by_phandle(ph);
0878 if (!node) {
0879 dev_err(dev, "Error finding node by phandle\n");
0880 return -ENODEV;
0881 }
0882 state->phy_gpr = syscon_node_to_regmap(node);
0883 of_node_put(node);
0884 if (IS_ERR(state->phy_gpr)) {
0885 dev_err(dev, "failed to get gpr regmap: %pe\n", state->phy_gpr);
0886 return PTR_ERR(state->phy_gpr);
0887 }
0888
0889 state->phy_gpr_reg = out_val[1];
0890 dev_dbg(dev, "phy gpr register set to 0x%x\n", state->phy_gpr_reg);
0891
0892 return ret;
0893 }
0894
0895 static int imx8mq_mipi_csi_probe(struct platform_device *pdev)
0896 {
0897 struct device *dev = &pdev->dev;
0898 struct csi_state *state;
0899 int ret;
0900
0901 state = devm_kzalloc(dev, sizeof(*state), GFP_KERNEL);
0902 if (!state)
0903 return -ENOMEM;
0904
0905 state->dev = dev;
0906
0907 ret = imx8mq_mipi_csi_parse_dt(state);
0908 if (ret < 0) {
0909 dev_err(dev, "Failed to parse device tree: %d\n", ret);
0910 return ret;
0911 }
0912
0913
0914 state->regs = devm_platform_ioremap_resource(pdev, 0);
0915 if (IS_ERR(state->regs))
0916 return PTR_ERR(state->regs);
0917
0918 ret = imx8mq_mipi_csi_clk_get(state);
0919 if (ret < 0)
0920 return ret;
0921
0922 platform_set_drvdata(pdev, &state->sd);
0923
0924 mutex_init(&state->lock);
0925
0926 ret = imx8mq_mipi_csi_subdev_init(state);
0927 if (ret < 0)
0928 goto mutex;
0929
0930 ret = imx8mq_mipi_csi_init_icc(pdev);
0931 if (ret)
0932 goto mutex;
0933
0934
0935 pm_runtime_enable(dev);
0936 if (!pm_runtime_enabled(dev)) {
0937 ret = imx8mq_mipi_csi_runtime_resume(dev);
0938 if (ret < 0)
0939 goto icc;
0940 }
0941
0942 ret = imx8mq_mipi_csi_async_register(state);
0943 if (ret < 0)
0944 goto cleanup;
0945
0946 return 0;
0947
0948 cleanup:
0949 pm_runtime_disable(&pdev->dev);
0950 imx8mq_mipi_csi_runtime_suspend(&pdev->dev);
0951
0952 media_entity_cleanup(&state->sd.entity);
0953 v4l2_async_nf_unregister(&state->notifier);
0954 v4l2_async_nf_cleanup(&state->notifier);
0955 v4l2_async_unregister_subdev(&state->sd);
0956 icc:
0957 imx8mq_mipi_csi_release_icc(pdev);
0958 mutex:
0959 mutex_destroy(&state->lock);
0960
0961 return ret;
0962 }
0963
0964 static int imx8mq_mipi_csi_remove(struct platform_device *pdev)
0965 {
0966 struct v4l2_subdev *sd = platform_get_drvdata(pdev);
0967 struct csi_state *state = mipi_sd_to_csi2_state(sd);
0968
0969 v4l2_async_nf_unregister(&state->notifier);
0970 v4l2_async_nf_cleanup(&state->notifier);
0971 v4l2_async_unregister_subdev(&state->sd);
0972
0973 pm_runtime_disable(&pdev->dev);
0974 imx8mq_mipi_csi_runtime_suspend(&pdev->dev);
0975 media_entity_cleanup(&state->sd.entity);
0976 mutex_destroy(&state->lock);
0977 pm_runtime_set_suspended(&pdev->dev);
0978 imx8mq_mipi_csi_release_icc(pdev);
0979
0980 return 0;
0981 }
0982
0983 static const struct of_device_id imx8mq_mipi_csi_of_match[] = {
0984 { .compatible = "fsl,imx8mq-mipi-csi2", },
0985 { },
0986 };
0987 MODULE_DEVICE_TABLE(of, imx8mq_mipi_csi_of_match);
0988
0989 static struct platform_driver imx8mq_mipi_csi_driver = {
0990 .probe = imx8mq_mipi_csi_probe,
0991 .remove = imx8mq_mipi_csi_remove,
0992 .driver = {
0993 .of_match_table = imx8mq_mipi_csi_of_match,
0994 .name = MIPI_CSI2_DRIVER_NAME,
0995 .pm = &imx8mq_mipi_csi_pm_ops,
0996 },
0997 };
0998
0999 module_platform_driver(imx8mq_mipi_csi_driver);
1000
1001 MODULE_DESCRIPTION("i.MX8MQ MIPI CSI-2 receiver driver");
1002 MODULE_AUTHOR("Martin Kepplinger <martin.kepplinger@puri.sm>");
1003 MODULE_LICENSE("GPL v2");
1004 MODULE_ALIAS("platform:imx8mq-mipi-csi2");