imx8mq-mipi-csi2.c (25558B)
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/of_device.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 66enum { 67 ST_POWERED = 1, 68 ST_STREAMING = 2, 69 ST_SUSPENDED = 4, 70}; 71 72enum imx8mq_mipi_csi_clk { 73 CSI2_CLK_CORE, 74 CSI2_CLK_ESC, 75 CSI2_CLK_UI, 76 CSI2_NUM_CLKS, 77}; 78 79static const char * const imx8mq_mipi_csi_clk_id[CSI2_NUM_CLKS] = { 80 [CSI2_CLK_CORE] = "core", 81 [CSI2_CLK_ESC] = "esc", 82 [CSI2_CLK_UI] = "ui", 83}; 84 85#define CSI2_NUM_CLKS ARRAY_SIZE(imx8mq_mipi_csi_clk_id) 86 87#define GPR_CSI2_1_RX_ENABLE BIT(13) 88#define GPR_CSI2_1_VID_INTFC_ENB BIT(12) 89#define GPR_CSI2_1_HSEL BIT(10) 90#define GPR_CSI2_1_CONT_CLK_MODE BIT(8) 91#define GPR_CSI2_1_S_PRG_RXHS_SETTLE(x) (((x) & 0x3f) << 2) 92 93/* 94 * The send level configures the number of entries that must accumulate in 95 * the Pixel FIFO before the data will be transferred to the video output. 96 * The exact value needed for this configuration is dependent on the rate at 97 * which the sensor transfers data to the CSI-2 Controller and the user 98 * video clock. 99 * 100 * The calculation is the classical rate-in rate-out type of problem: If the 101 * video bandwidth is 10% faster than the incoming mipi data and the video 102 * line length is 500 pixels, then the fifo should be allowed to fill 103 * 10% of the line length or 50 pixels. If the gap data is ok, then the level 104 * can be set to 16 and ignored. 105 */ 106#define CSI2RX_SEND_LEVEL 64 107 108struct csi_state { 109 struct device *dev; 110 void __iomem *regs; 111 struct clk_bulk_data clks[CSI2_NUM_CLKS]; 112 struct reset_control *rst; 113 struct regulator *mipi_phy_regulator; 114 115 struct v4l2_subdev sd; 116 struct media_pad pads[MIPI_CSI2_PADS_NUM]; 117 struct v4l2_async_notifier notifier; 118 struct v4l2_subdev *src_sd; 119 120 struct v4l2_mbus_config_mipi_csi2 bus; 121 122 struct mutex lock; /* Protect csi2_fmt, format_mbus, state, hs_settle */ 123 const struct csi2_pix_format *csi2_fmt; 124 struct v4l2_mbus_framefmt format_mbus[MIPI_CSI2_PADS_NUM]; 125 u32 state; 126 u32 hs_settle; 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 144static const struct csi2_pix_format imx8mq_mipi_csi_formats[] = { 145 /* RAW (Bayer and greyscale) formats. */ 146 { 147 .code = MEDIA_BUS_FMT_SBGGR8_1X8, 148 .width = 8, 149 }, { 150 .code = MEDIA_BUS_FMT_SGBRG8_1X8, 151 .width = 8, 152 }, { 153 .code = MEDIA_BUS_FMT_SGRBG8_1X8, 154 .width = 8, 155 }, { 156 .code = MEDIA_BUS_FMT_SRGGB8_1X8, 157 .width = 8, 158 }, { 159 .code = MEDIA_BUS_FMT_Y8_1X8, 160 .width = 8, 161 }, { 162 .code = MEDIA_BUS_FMT_SBGGR10_1X10, 163 .width = 10, 164 }, { 165 .code = MEDIA_BUS_FMT_SGBRG10_1X10, 166 .width = 10, 167 }, { 168 .code = MEDIA_BUS_FMT_SGRBG10_1X10, 169 .width = 10, 170 }, { 171 .code = MEDIA_BUS_FMT_SRGGB10_1X10, 172 .width = 10, 173 }, { 174 .code = MEDIA_BUS_FMT_Y10_1X10, 175 .width = 10, 176 }, { 177 .code = MEDIA_BUS_FMT_SBGGR12_1X12, 178 .width = 12, 179 }, { 180 .code = MEDIA_BUS_FMT_SGBRG12_1X12, 181 .width = 12, 182 }, { 183 .code = MEDIA_BUS_FMT_SGRBG12_1X12, 184 .width = 12, 185 }, { 186 .code = MEDIA_BUS_FMT_SRGGB12_1X12, 187 .width = 12, 188 }, { 189 .code = MEDIA_BUS_FMT_Y12_1X12, 190 .width = 12, 191 }, { 192 .code = MEDIA_BUS_FMT_SBGGR14_1X14, 193 .width = 14, 194 }, { 195 .code = MEDIA_BUS_FMT_SGBRG14_1X14, 196 .width = 14, 197 }, { 198 .code = MEDIA_BUS_FMT_SGRBG14_1X14, 199 .width = 14, 200 }, { 201 .code = MEDIA_BUS_FMT_SRGGB14_1X14, 202 .width = 14, 203 }, 204 /* YUV formats */ 205 { 206 .code = MEDIA_BUS_FMT_YUYV8_1X16, 207 .width = 16, 208 }, { 209 .code = MEDIA_BUS_FMT_UYVY8_1X16, 210 .width = 16, 211 } 212}; 213 214static const struct csi2_pix_format *find_csi2_format(u32 code) 215{ 216 unsigned int i; 217 218 for (i = 0; i < ARRAY_SIZE(imx8mq_mipi_csi_formats); i++) 219 if (code == imx8mq_mipi_csi_formats[i].code) 220 return &imx8mq_mipi_csi_formats[i]; 221 return NULL; 222} 223 224/* ----------------------------------------------------------------------------- 225 * Hardware configuration 226 */ 227 228static inline void imx8mq_mipi_csi_write(struct csi_state *state, u32 reg, u32 val) 229{ 230 writel(val, state->regs + reg); 231} 232 233static int imx8mq_mipi_csi_sw_reset(struct csi_state *state) 234{ 235 int ret; 236 237 /* 238 * these are most likely self-clearing reset bits. to make it 239 * more clear, the reset-imx7 driver should implement the 240 * .reset() operation. 241 */ 242 ret = reset_control_assert(state->rst); 243 if (ret < 0) { 244 dev_err(state->dev, "Failed to assert resets: %d\n", ret); 245 return ret; 246 } 247 248 return 0; 249} 250 251static void imx8mq_mipi_csi_system_enable(struct csi_state *state, int on) 252{ 253 if (!on) { 254 imx8mq_mipi_csi_write(state, CSI2RX_CFG_DISABLE_DATA_LANES, 0xf); 255 return; 256 } 257 258 regmap_update_bits(state->phy_gpr, 259 state->phy_gpr_reg, 260 0x3fff, 261 GPR_CSI2_1_RX_ENABLE | 262 GPR_CSI2_1_VID_INTFC_ENB | 263 GPR_CSI2_1_HSEL | 264 GPR_CSI2_1_CONT_CLK_MODE | 265 GPR_CSI2_1_S_PRG_RXHS_SETTLE(state->hs_settle)); 266} 267 268static void imx8mq_mipi_csi_set_params(struct csi_state *state) 269{ 270 int lanes = state->bus.num_data_lanes; 271 272 imx8mq_mipi_csi_write(state, CSI2RX_CFG_NUM_LANES, lanes - 1); 273 imx8mq_mipi_csi_write(state, CSI2RX_CFG_DISABLE_DATA_LANES, 274 (0xf << lanes) & 0xf); 275 imx8mq_mipi_csi_write(state, CSI2RX_IRQ_MASK, CSI2RX_IRQ_MASK_ALL); 276 /* 277 * 0x180 bit 0 controls the Virtual Channel behaviour: when set the 278 * interface ignores the Virtual Channel (VC) field in received packets; 279 * when cleared it causes the interface to only accept packets whose VC 280 * matches the value to which VC is set at offset 0x184. 281 */ 282 imx8mq_mipi_csi_write(state, CSI2RX_CFG_VID_VC_IGNORE, 1); 283 imx8mq_mipi_csi_write(state, CSI2RX_CFG_VID_P_FIFO_SEND_LEVEL, 284 CSI2RX_SEND_LEVEL); 285} 286 287static int imx8mq_mipi_csi_clk_enable(struct csi_state *state) 288{ 289 return clk_bulk_prepare_enable(CSI2_NUM_CLKS, state->clks); 290} 291 292static void imx8mq_mipi_csi_clk_disable(struct csi_state *state) 293{ 294 clk_bulk_disable_unprepare(CSI2_NUM_CLKS, state->clks); 295} 296 297static int imx8mq_mipi_csi_clk_get(struct csi_state *state) 298{ 299 unsigned int i; 300 301 for (i = 0; i < CSI2_NUM_CLKS; i++) 302 state->clks[i].id = imx8mq_mipi_csi_clk_id[i]; 303 304 return devm_clk_bulk_get(state->dev, CSI2_NUM_CLKS, state->clks); 305} 306 307static int imx8mq_mipi_csi_calc_hs_settle(struct csi_state *state) 308{ 309 s64 link_freq; 310 u32 lane_rate; 311 unsigned long esc_clk_rate; 312 u32 min_ths_settle, max_ths_settle, ths_settle_ns, esc_clk_period_ns; 313 314 /* Calculate the line rate from the pixel rate. */ 315 link_freq = v4l2_get_link_freq(state->src_sd->ctrl_handler, 316 state->csi2_fmt->width, 317 state->bus.num_data_lanes * 2); 318 if (link_freq < 0) { 319 dev_err(state->dev, "Unable to obtain link frequency: %d\n", 320 (int)link_freq); 321 return link_freq; 322 } 323 324 lane_rate = link_freq * 2; 325 if (lane_rate < 80000000 || lane_rate > 1500000000) { 326 dev_dbg(state->dev, "Out-of-bound lane rate %u\n", lane_rate); 327 return -EINVAL; 328 } 329 330 /* 331 * The D-PHY specification requires Ths-settle to be in the range 332 * 85ns + 6*UI to 140ns + 10*UI, with the unit interval UI being half 333 * the clock period. 334 * 335 * The Ths-settle value is expressed in the hardware as a multiple of 336 * the Esc clock period: 337 * 338 * Ths-settle = (PRG_RXHS_SETTLE + 1) * Tperiod of RxClkInEsc 339 * 340 * Due to the one cycle inaccuracy introduced by rounding, the 341 * documentation recommends picking a value away from the boundaries. 342 * Let's pick the average. 343 */ 344 esc_clk_rate = clk_get_rate(state->clks[CSI2_CLK_ESC].clk); 345 if (!esc_clk_rate) { 346 dev_err(state->dev, "Could not get esc clock rate.\n"); 347 return -EINVAL; 348 } 349 350 dev_dbg(state->dev, "esc clk rate: %lu\n", esc_clk_rate); 351 esc_clk_period_ns = 1000000000 / esc_clk_rate; 352 353 min_ths_settle = 85 + 6 * 1000000 / (lane_rate / 1000); 354 max_ths_settle = 140 + 10 * 1000000 / (lane_rate / 1000); 355 ths_settle_ns = (min_ths_settle + max_ths_settle) / 2; 356 357 state->hs_settle = ths_settle_ns / esc_clk_period_ns - 1; 358 359 dev_dbg(state->dev, "lane rate %u Ths_settle %u hs_settle %u\n", 360 lane_rate, ths_settle_ns, state->hs_settle); 361 362 return 0; 363} 364 365static int imx8mq_mipi_csi_start_stream(struct csi_state *state) 366{ 367 int ret; 368 369 ret = imx8mq_mipi_csi_sw_reset(state); 370 if (ret) 371 return ret; 372 373 imx8mq_mipi_csi_set_params(state); 374 ret = imx8mq_mipi_csi_calc_hs_settle(state); 375 if (ret) 376 return ret; 377 378 imx8mq_mipi_csi_system_enable(state, true); 379 380 return 0; 381} 382 383static void imx8mq_mipi_csi_stop_stream(struct csi_state *state) 384{ 385 imx8mq_mipi_csi_system_enable(state, false); 386} 387 388/* ----------------------------------------------------------------------------- 389 * V4L2 subdev operations 390 */ 391 392static struct csi_state *mipi_sd_to_csi2_state(struct v4l2_subdev *sdev) 393{ 394 return container_of(sdev, struct csi_state, sd); 395} 396 397static int imx8mq_mipi_csi_s_stream(struct v4l2_subdev *sd, int enable) 398{ 399 struct csi_state *state = mipi_sd_to_csi2_state(sd); 400 int ret = 0; 401 402 if (enable) { 403 ret = pm_runtime_resume_and_get(state->dev); 404 if (ret < 0) 405 return ret; 406 } 407 408 mutex_lock(&state->lock); 409 410 if (enable) { 411 if (state->state & ST_SUSPENDED) { 412 ret = -EBUSY; 413 goto unlock; 414 } 415 416 ret = imx8mq_mipi_csi_start_stream(state); 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 struct v4l2_mbus_framefmt * 441imx8mq_mipi_csi_get_format(struct csi_state *state, 442 struct v4l2_subdev_state *sd_state, 443 enum v4l2_subdev_format_whence which, 444 unsigned int pad) 445{ 446 if (which == V4L2_SUBDEV_FORMAT_TRY) 447 return v4l2_subdev_get_try_format(&state->sd, sd_state, pad); 448 449 return &state->format_mbus[pad]; 450} 451 452static int imx8mq_mipi_csi_init_cfg(struct v4l2_subdev *sd, 453 struct v4l2_subdev_state *sd_state) 454{ 455 struct csi_state *state = mipi_sd_to_csi2_state(sd); 456 struct v4l2_mbus_framefmt *fmt_sink; 457 struct v4l2_mbus_framefmt *fmt_source; 458 enum v4l2_subdev_format_whence which; 459 460 which = sd_state ? V4L2_SUBDEV_FORMAT_TRY : V4L2_SUBDEV_FORMAT_ACTIVE; 461 fmt_sink = imx8mq_mipi_csi_get_format(state, sd_state, which, 462 MIPI_CSI2_PAD_SINK); 463 464 fmt_sink->code = MEDIA_BUS_FMT_SGBRG10_1X10; 465 fmt_sink->width = MIPI_CSI2_DEF_PIX_WIDTH; 466 fmt_sink->height = MIPI_CSI2_DEF_PIX_HEIGHT; 467 fmt_sink->field = V4L2_FIELD_NONE; 468 469 fmt_sink->colorspace = V4L2_COLORSPACE_RAW; 470 fmt_sink->xfer_func = V4L2_MAP_XFER_FUNC_DEFAULT(fmt_sink->colorspace); 471 fmt_sink->ycbcr_enc = V4L2_MAP_YCBCR_ENC_DEFAULT(fmt_sink->colorspace); 472 fmt_sink->quantization = 473 V4L2_MAP_QUANTIZATION_DEFAULT(false, fmt_sink->colorspace, 474 fmt_sink->ycbcr_enc); 475 476 fmt_source = imx8mq_mipi_csi_get_format(state, sd_state, which, 477 MIPI_CSI2_PAD_SOURCE); 478 *fmt_source = *fmt_sink; 479 480 return 0; 481} 482 483static int imx8mq_mipi_csi_get_fmt(struct v4l2_subdev *sd, 484 struct v4l2_subdev_state *sd_state, 485 struct v4l2_subdev_format *sdformat) 486{ 487 struct csi_state *state = mipi_sd_to_csi2_state(sd); 488 struct v4l2_mbus_framefmt *fmt; 489 490 fmt = imx8mq_mipi_csi_get_format(state, sd_state, sdformat->which, 491 sdformat->pad); 492 493 mutex_lock(&state->lock); 494 495 sdformat->format = *fmt; 496 497 mutex_unlock(&state->lock); 498 499 return 0; 500} 501 502static int imx8mq_mipi_csi_enum_mbus_code(struct v4l2_subdev *sd, 503 struct v4l2_subdev_state *sd_state, 504 struct v4l2_subdev_mbus_code_enum *code) 505{ 506 struct csi_state *state = mipi_sd_to_csi2_state(sd); 507 508 /* 509 * We can't transcode in any way, the source format is identical 510 * to the sink format. 511 */ 512 if (code->pad == MIPI_CSI2_PAD_SOURCE) { 513 struct v4l2_mbus_framefmt *fmt; 514 515 if (code->index > 0) 516 return -EINVAL; 517 518 fmt = imx8mq_mipi_csi_get_format(state, sd_state, code->which, 519 code->pad); 520 code->code = fmt->code; 521 return 0; 522 } 523 524 if (code->pad != MIPI_CSI2_PAD_SINK) 525 return -EINVAL; 526 527 if (code->index >= ARRAY_SIZE(imx8mq_mipi_csi_formats)) 528 return -EINVAL; 529 530 code->code = imx8mq_mipi_csi_formats[code->index].code; 531 532 return 0; 533} 534 535static int imx8mq_mipi_csi_set_fmt(struct v4l2_subdev *sd, 536 struct v4l2_subdev_state *sd_state, 537 struct v4l2_subdev_format *sdformat) 538{ 539 struct csi_state *state = mipi_sd_to_csi2_state(sd); 540 struct csi2_pix_format const *csi2_fmt; 541 struct v4l2_mbus_framefmt *fmt; 542 543 /* 544 * The device can't transcode in any way, the source format can't be 545 * modified. 546 */ 547 if (sdformat->pad == MIPI_CSI2_PAD_SOURCE) 548 return imx8mq_mipi_csi_get_fmt(sd, sd_state, sdformat); 549 550 if (sdformat->pad != MIPI_CSI2_PAD_SINK) 551 return -EINVAL; 552 553 csi2_fmt = find_csi2_format(sdformat->format.code); 554 if (!csi2_fmt) 555 csi2_fmt = &imx8mq_mipi_csi_formats[0]; 556 557 fmt = imx8mq_mipi_csi_get_format(state, sd_state, sdformat->which, 558 sdformat->pad); 559 560 mutex_lock(&state->lock); 561 562 fmt->code = csi2_fmt->code; 563 fmt->width = sdformat->format.width; 564 fmt->height = sdformat->format.height; 565 566 sdformat->format = *fmt; 567 568 /* Propagate the format from sink to source. */ 569 fmt = imx8mq_mipi_csi_get_format(state, sd_state, sdformat->which, 570 MIPI_CSI2_PAD_SOURCE); 571 *fmt = sdformat->format; 572 573 /* Store the CSI2 format descriptor for active formats. */ 574 if (sdformat->which == V4L2_SUBDEV_FORMAT_ACTIVE) 575 state->csi2_fmt = csi2_fmt; 576 577 mutex_unlock(&state->lock); 578 579 return 0; 580} 581 582static const struct v4l2_subdev_video_ops imx8mq_mipi_csi_video_ops = { 583 .s_stream = imx8mq_mipi_csi_s_stream, 584}; 585 586static const struct v4l2_subdev_pad_ops imx8mq_mipi_csi_pad_ops = { 587 .init_cfg = imx8mq_mipi_csi_init_cfg, 588 .enum_mbus_code = imx8mq_mipi_csi_enum_mbus_code, 589 .get_fmt = imx8mq_mipi_csi_get_fmt, 590 .set_fmt = imx8mq_mipi_csi_set_fmt, 591}; 592 593static const struct v4l2_subdev_ops imx8mq_mipi_csi_subdev_ops = { 594 .video = &imx8mq_mipi_csi_video_ops, 595 .pad = &imx8mq_mipi_csi_pad_ops, 596}; 597 598/* ----------------------------------------------------------------------------- 599 * Media entity operations 600 */ 601 602static const struct media_entity_operations imx8mq_mipi_csi_entity_ops = { 603 .link_validate = v4l2_subdev_link_validate, 604 .get_fwnode_pad = v4l2_subdev_get_fwnode_pad_1_to_1, 605}; 606 607/* ----------------------------------------------------------------------------- 608 * Async subdev notifier 609 */ 610 611static struct csi_state * 612mipi_notifier_to_csi2_state(struct v4l2_async_notifier *n) 613{ 614 return container_of(n, struct csi_state, notifier); 615} 616 617static int imx8mq_mipi_csi_notify_bound(struct v4l2_async_notifier *notifier, 618 struct v4l2_subdev *sd, 619 struct v4l2_async_subdev *asd) 620{ 621 struct csi_state *state = mipi_notifier_to_csi2_state(notifier); 622 struct media_pad *sink = &state->sd.entity.pads[MIPI_CSI2_PAD_SINK]; 623 624 state->src_sd = sd; 625 626 return v4l2_create_fwnode_links_to_pad(sd, sink, MEDIA_LNK_FL_ENABLED | 627 MEDIA_LNK_FL_IMMUTABLE); 628} 629 630static const struct v4l2_async_notifier_operations imx8mq_mipi_csi_notify_ops = { 631 .bound = imx8mq_mipi_csi_notify_bound, 632}; 633 634static int imx8mq_mipi_csi_async_register(struct csi_state *state) 635{ 636 struct v4l2_fwnode_endpoint vep = { 637 .bus_type = V4L2_MBUS_CSI2_DPHY, 638 }; 639 struct v4l2_async_subdev *asd; 640 struct fwnode_handle *ep; 641 unsigned int i; 642 int ret; 643 644 v4l2_async_nf_init(&state->notifier); 645 646 ep = fwnode_graph_get_endpoint_by_id(dev_fwnode(state->dev), 0, 0, 647 FWNODE_GRAPH_ENDPOINT_NEXT); 648 if (!ep) 649 return -ENOTCONN; 650 651 ret = v4l2_fwnode_endpoint_parse(ep, &vep); 652 if (ret) 653 goto err_parse; 654 655 for (i = 0; i < vep.bus.mipi_csi2.num_data_lanes; ++i) { 656 if (vep.bus.mipi_csi2.data_lanes[i] != i + 1) { 657 dev_err(state->dev, 658 "data lanes reordering is not supported"); 659 ret = -EINVAL; 660 goto err_parse; 661 } 662 } 663 664 state->bus = vep.bus.mipi_csi2; 665 666 dev_dbg(state->dev, "data lanes: %d flags: 0x%08x\n", 667 state->bus.num_data_lanes, 668 state->bus.flags); 669 670 asd = v4l2_async_nf_add_fwnode_remote(&state->notifier, ep, 671 struct v4l2_async_subdev); 672 if (IS_ERR(asd)) { 673 ret = PTR_ERR(asd); 674 goto err_parse; 675 } 676 677 fwnode_handle_put(ep); 678 679 state->notifier.ops = &imx8mq_mipi_csi_notify_ops; 680 681 ret = v4l2_async_subdev_nf_register(&state->sd, &state->notifier); 682 if (ret) 683 return ret; 684 685 return v4l2_async_register_subdev(&state->sd); 686 687err_parse: 688 fwnode_handle_put(ep); 689 690 return ret; 691} 692 693/* ----------------------------------------------------------------------------- 694 * Suspend/resume 695 */ 696 697static void imx8mq_mipi_csi_pm_suspend(struct device *dev) 698{ 699 struct v4l2_subdev *sd = dev_get_drvdata(dev); 700 struct csi_state *state = mipi_sd_to_csi2_state(sd); 701 702 mutex_lock(&state->lock); 703 704 if (state->state & ST_POWERED) { 705 imx8mq_mipi_csi_stop_stream(state); 706 imx8mq_mipi_csi_clk_disable(state); 707 state->state &= ~ST_POWERED; 708 } 709 710 mutex_unlock(&state->lock); 711} 712 713static int imx8mq_mipi_csi_pm_resume(struct device *dev) 714{ 715 struct v4l2_subdev *sd = dev_get_drvdata(dev); 716 struct csi_state *state = mipi_sd_to_csi2_state(sd); 717 int ret = 0; 718 719 mutex_lock(&state->lock); 720 721 if (!(state->state & ST_POWERED)) { 722 state->state |= ST_POWERED; 723 ret = imx8mq_mipi_csi_clk_enable(state); 724 } 725 if (state->state & ST_STREAMING) { 726 ret = imx8mq_mipi_csi_start_stream(state); 727 if (ret) 728 goto unlock; 729 } 730 731 state->state &= ~ST_SUSPENDED; 732 733unlock: 734 mutex_unlock(&state->lock); 735 736 return ret ? -EAGAIN : 0; 737} 738 739static int __maybe_unused imx8mq_mipi_csi_suspend(struct device *dev) 740{ 741 struct v4l2_subdev *sd = dev_get_drvdata(dev); 742 struct csi_state *state = mipi_sd_to_csi2_state(sd); 743 744 imx8mq_mipi_csi_pm_suspend(dev); 745 746 state->state |= ST_SUSPENDED; 747 748 return 0; 749} 750 751static int __maybe_unused imx8mq_mipi_csi_resume(struct device *dev) 752{ 753 struct v4l2_subdev *sd = dev_get_drvdata(dev); 754 struct csi_state *state = mipi_sd_to_csi2_state(sd); 755 756 if (!(state->state & ST_SUSPENDED)) 757 return 0; 758 759 return imx8mq_mipi_csi_pm_resume(dev); 760} 761 762static int __maybe_unused imx8mq_mipi_csi_runtime_suspend(struct device *dev) 763{ 764 struct v4l2_subdev *sd = dev_get_drvdata(dev); 765 struct csi_state *state = mipi_sd_to_csi2_state(sd); 766 int ret; 767 768 imx8mq_mipi_csi_pm_suspend(dev); 769 770 ret = icc_set_bw(state->icc_path, 0, 0); 771 if (ret) 772 dev_err(dev, "icc_set_bw failed with %d\n", ret); 773 774 return ret; 775} 776 777static int __maybe_unused imx8mq_mipi_csi_runtime_resume(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 int ret; 782 783 ret = icc_set_bw(state->icc_path, 0, state->icc_path_bw); 784 if (ret) { 785 dev_err(dev, "icc_set_bw failed with %d\n", ret); 786 return ret; 787 } 788 789 return imx8mq_mipi_csi_pm_resume(dev); 790} 791 792static const struct dev_pm_ops imx8mq_mipi_csi_pm_ops = { 793 SET_RUNTIME_PM_OPS(imx8mq_mipi_csi_runtime_suspend, 794 imx8mq_mipi_csi_runtime_resume, 795 NULL) 796 SET_SYSTEM_SLEEP_PM_OPS(imx8mq_mipi_csi_suspend, imx8mq_mipi_csi_resume) 797}; 798 799/* ----------------------------------------------------------------------------- 800 * Probe/remove & platform driver 801 */ 802 803static int imx8mq_mipi_csi_subdev_init(struct csi_state *state) 804{ 805 struct v4l2_subdev *sd = &state->sd; 806 807 v4l2_subdev_init(sd, &imx8mq_mipi_csi_subdev_ops); 808 sd->owner = THIS_MODULE; 809 snprintf(sd->name, sizeof(sd->name), "%s %s", 810 MIPI_CSI2_SUBDEV_NAME, dev_name(state->dev)); 811 812 sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE; 813 814 sd->entity.function = MEDIA_ENT_F_VID_IF_BRIDGE; 815 sd->entity.ops = &imx8mq_mipi_csi_entity_ops; 816 817 sd->dev = state->dev; 818 819 state->csi2_fmt = &imx8mq_mipi_csi_formats[0]; 820 imx8mq_mipi_csi_init_cfg(sd, NULL); 821 822 state->pads[MIPI_CSI2_PAD_SINK].flags = MEDIA_PAD_FL_SINK 823 | MEDIA_PAD_FL_MUST_CONNECT; 824 state->pads[MIPI_CSI2_PAD_SOURCE].flags = MEDIA_PAD_FL_SOURCE 825 | MEDIA_PAD_FL_MUST_CONNECT; 826 return media_entity_pads_init(&sd->entity, MIPI_CSI2_PADS_NUM, 827 state->pads); 828} 829 830static void imx8mq_mipi_csi_release_icc(struct platform_device *pdev) 831{ 832 struct v4l2_subdev *sd = dev_get_drvdata(&pdev->dev); 833 struct csi_state *state = mipi_sd_to_csi2_state(sd); 834 835 icc_put(state->icc_path); 836} 837 838static int imx8mq_mipi_csi_init_icc(struct platform_device *pdev) 839{ 840 struct v4l2_subdev *sd = dev_get_drvdata(&pdev->dev); 841 struct csi_state *state = mipi_sd_to_csi2_state(sd); 842 843 /* Optional interconnect request */ 844 state->icc_path = of_icc_get(&pdev->dev, "dram"); 845 if (IS_ERR_OR_NULL(state->icc_path)) 846 return PTR_ERR_OR_ZERO(state->icc_path); 847 848 state->icc_path_bw = MBps_to_icc(700); 849 850 return 0; 851} 852 853static int imx8mq_mipi_csi_parse_dt(struct csi_state *state) 854{ 855 struct device *dev = state->dev; 856 struct device_node *np = state->dev->of_node; 857 struct device_node *node; 858 phandle ph; 859 u32 out_val[2]; 860 int ret = 0; 861 862 state->rst = devm_reset_control_array_get_exclusive(dev); 863 if (IS_ERR(state->rst)) { 864 dev_err(dev, "Failed to get reset: %pe\n", state->rst); 865 return PTR_ERR(state->rst); 866 } 867 868 ret = of_property_read_u32_array(np, "fsl,mipi-phy-gpr", out_val, 869 ARRAY_SIZE(out_val)); 870 if (ret) { 871 dev_err(dev, "no fsl,mipi-phy-gpr property found: %d\n", ret); 872 return ret; 873 } 874 875 ph = *out_val; 876 877 node = of_find_node_by_phandle(ph); 878 if (!node) { 879 dev_err(dev, "Error finding node by phandle\n"); 880 return -ENODEV; 881 } 882 state->phy_gpr = syscon_node_to_regmap(node); 883 of_node_put(node); 884 if (IS_ERR(state->phy_gpr)) { 885 dev_err(dev, "failed to get gpr regmap: %pe\n", state->phy_gpr); 886 return PTR_ERR(state->phy_gpr); 887 } 888 889 state->phy_gpr_reg = out_val[1]; 890 dev_dbg(dev, "phy gpr register set to 0x%x\n", state->phy_gpr_reg); 891 892 return ret; 893} 894 895static int imx8mq_mipi_csi_probe(struct platform_device *pdev) 896{ 897 struct device *dev = &pdev->dev; 898 struct csi_state *state; 899 int ret; 900 901 state = devm_kzalloc(dev, sizeof(*state), GFP_KERNEL); 902 if (!state) 903 return -ENOMEM; 904 905 state->dev = dev; 906 907 ret = imx8mq_mipi_csi_parse_dt(state); 908 if (ret < 0) { 909 dev_err(dev, "Failed to parse device tree: %d\n", ret); 910 return ret; 911 } 912 913 /* Acquire resources. */ 914 state->regs = devm_platform_ioremap_resource(pdev, 0); 915 if (IS_ERR(state->regs)) 916 return PTR_ERR(state->regs); 917 918 ret = imx8mq_mipi_csi_clk_get(state); 919 if (ret < 0) 920 return ret; 921 922 platform_set_drvdata(pdev, &state->sd); 923 924 mutex_init(&state->lock); 925 926 ret = imx8mq_mipi_csi_subdev_init(state); 927 if (ret < 0) 928 goto mutex; 929 930 ret = imx8mq_mipi_csi_init_icc(pdev); 931 if (ret) 932 goto mutex; 933 934 /* Enable runtime PM. */ 935 pm_runtime_enable(dev); 936 if (!pm_runtime_enabled(dev)) { 937 ret = imx8mq_mipi_csi_runtime_resume(dev); 938 if (ret < 0) 939 goto icc; 940 } 941 942 ret = imx8mq_mipi_csi_async_register(state); 943 if (ret < 0) 944 goto cleanup; 945 946 return 0; 947 948cleanup: 949 pm_runtime_disable(&pdev->dev); 950 imx8mq_mipi_csi_runtime_suspend(&pdev->dev); 951 952 media_entity_cleanup(&state->sd.entity); 953 v4l2_async_nf_unregister(&state->notifier); 954 v4l2_async_nf_cleanup(&state->notifier); 955 v4l2_async_unregister_subdev(&state->sd); 956icc: 957 imx8mq_mipi_csi_release_icc(pdev); 958mutex: 959 mutex_destroy(&state->lock); 960 961 return ret; 962} 963 964static int imx8mq_mipi_csi_remove(struct platform_device *pdev) 965{ 966 struct v4l2_subdev *sd = platform_get_drvdata(pdev); 967 struct csi_state *state = mipi_sd_to_csi2_state(sd); 968 969 v4l2_async_nf_unregister(&state->notifier); 970 v4l2_async_nf_cleanup(&state->notifier); 971 v4l2_async_unregister_subdev(&state->sd); 972 973 pm_runtime_disable(&pdev->dev); 974 imx8mq_mipi_csi_runtime_suspend(&pdev->dev); 975 media_entity_cleanup(&state->sd.entity); 976 mutex_destroy(&state->lock); 977 pm_runtime_set_suspended(&pdev->dev); 978 imx8mq_mipi_csi_release_icc(pdev); 979 980 return 0; 981} 982 983static const struct of_device_id imx8mq_mipi_csi_of_match[] = { 984 { .compatible = "fsl,imx8mq-mipi-csi2", }, 985 { /* sentinel */ }, 986}; 987MODULE_DEVICE_TABLE(of, imx8mq_mipi_csi_of_match); 988 989static struct platform_driver imx8mq_mipi_csi_driver = { 990 .probe = imx8mq_mipi_csi_probe, 991 .remove = imx8mq_mipi_csi_remove, 992 .driver = { 993 .of_match_table = imx8mq_mipi_csi_of_match, 994 .name = MIPI_CSI2_DRIVER_NAME, 995 .pm = &imx8mq_mipi_csi_pm_ops, 996 }, 997}; 998 999module_platform_driver(imx8mq_mipi_csi_driver); 1000 1001MODULE_DESCRIPTION("i.MX8MQ MIPI CSI-2 receiver driver"); 1002MODULE_AUTHOR("Martin Kepplinger <martin.kepplinger@puri.sm>"); 1003MODULE_LICENSE("GPL v2"); 1004MODULE_ALIAS("platform:imx8mq-mipi-csi2");