1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * Synopsys DesignWare MIPI CSI-2 Receiver Driver 4 * 5 * Copyright (C) 2019 Rockchip Electronics Co., Ltd. 6 * Copyright (C) 2025 Michael Riesch <michael.riesch@wolfvision.net> 7 * Copyright (C) 2026 Collabora, Ltd. 8 */ 9 10 #include <linux/clk.h> 11 #include <linux/delay.h> 12 #include <linux/io.h> 13 #include <linux/module.h> 14 #include <linux/of.h> 15 #include <linux/phy/phy.h> 16 #include <linux/platform_device.h> 17 #include <linux/pm_runtime.h> 18 #include <linux/property.h> 19 #include <linux/reset.h> 20 21 #include <media/mipi-csi2.h> 22 #include <media/v4l2-ctrls.h> 23 #include <media/v4l2-fwnode.h> 24 #include <media/v4l2-mc.h> 25 #include <media/v4l2-subdev.h> 26 27 #define DW_MIPI_CSI2RX_N_LANES 0x04 28 #define DW_MIPI_CSI2RX_RESETN 0x10 29 #define DW_MIPI_CSI2RX_PHY_STATE 0x14 30 #define DW_MIPI_CSI2RX_ERR1 0x20 31 #define DW_MIPI_CSI2RX_ERR2 0x24 32 #define DW_MIPI_CSI2RX_MSK1 0x28 33 #define DW_MIPI_CSI2RX_MSK2 0x2c 34 #define DW_MIPI_CSI2RX_CONTROL 0x40 35 36 #define SW_CPHY_EN(x) ((x) << 0) 37 #define SW_DSI_EN(x) ((x) << 4) 38 #define SW_DATATYPE_FS(x) ((x) << 8) 39 #define SW_DATATYPE_FE(x) ((x) << 14) 40 #define SW_DATATYPE_LS(x) ((x) << 20) 41 #define SW_DATATYPE_LE(x) ((x) << 26) 42 43 #define DW_MIPI_CSI2RX_CLKS_MAX 1 44 45 enum { 46 DW_MIPI_CSI2RX_PAD_SINK, 47 DW_MIPI_CSI2RX_PAD_SRC, 48 DW_MIPI_CSI2RX_PAD_MAX, 49 }; 50 51 struct dw_mipi_csi2rx_format { 52 u32 code; 53 u8 depth; 54 u8 csi_dt; 55 }; 56 57 struct dw_mipi_csi2rx_device { 58 struct device *dev; 59 60 void __iomem *base_addr; 61 struct clk_bulk_data *clks; 62 unsigned int clks_num; 63 struct phy *phy; 64 struct reset_control *reset; 65 66 const struct dw_mipi_csi2rx_format *formats; 67 unsigned int formats_num; 68 69 struct media_pad pads[DW_MIPI_CSI2RX_PAD_MAX]; 70 struct v4l2_async_notifier notifier; 71 struct v4l2_subdev sd; 72 73 enum v4l2_mbus_type bus_type; 74 u32 lanes_num; 75 }; 76 77 static const struct v4l2_mbus_framefmt default_format = { 78 .width = 3840, 79 .height = 2160, 80 .code = MEDIA_BUS_FMT_SRGGB10_1X10, 81 .field = V4L2_FIELD_NONE, 82 .colorspace = V4L2_COLORSPACE_RAW, 83 .ycbcr_enc = V4L2_YCBCR_ENC_601, 84 .quantization = V4L2_QUANTIZATION_FULL_RANGE, 85 .xfer_func = V4L2_XFER_FUNC_NONE, 86 }; 87 88 static const struct dw_mipi_csi2rx_format formats[] = { 89 /* YUV formats */ 90 { 91 .code = MEDIA_BUS_FMT_YUYV8_1X16, 92 .depth = 16, 93 .csi_dt = MIPI_CSI2_DT_YUV422_8B, 94 }, 95 { 96 .code = MEDIA_BUS_FMT_UYVY8_1X16, 97 .depth = 16, 98 .csi_dt = MIPI_CSI2_DT_YUV422_8B, 99 }, 100 { 101 .code = MEDIA_BUS_FMT_YVYU8_1X16, 102 .depth = 16, 103 .csi_dt = MIPI_CSI2_DT_YUV422_8B, 104 }, 105 { 106 .code = MEDIA_BUS_FMT_VYUY8_1X16, 107 .depth = 16, 108 .csi_dt = MIPI_CSI2_DT_YUV422_8B, 109 }, 110 /* RGB formats */ 111 { 112 .code = MEDIA_BUS_FMT_RGB888_1X24, 113 .depth = 24, 114 .csi_dt = MIPI_CSI2_DT_RGB888, 115 }, 116 { 117 .code = MEDIA_BUS_FMT_BGR888_1X24, 118 .depth = 24, 119 .csi_dt = MIPI_CSI2_DT_RGB888, 120 }, 121 /* Bayer formats */ 122 { 123 .code = MEDIA_BUS_FMT_SBGGR8_1X8, 124 .depth = 8, 125 .csi_dt = MIPI_CSI2_DT_RAW8, 126 }, 127 { 128 .code = MEDIA_BUS_FMT_SGBRG8_1X8, 129 .depth = 8, 130 .csi_dt = MIPI_CSI2_DT_RAW8, 131 }, 132 { 133 .code = MEDIA_BUS_FMT_SGRBG8_1X8, 134 .depth = 8, 135 .csi_dt = MIPI_CSI2_DT_RAW8, 136 }, 137 { 138 .code = MEDIA_BUS_FMT_SRGGB8_1X8, 139 .depth = 8, 140 .csi_dt = MIPI_CSI2_DT_RAW8, 141 }, 142 { 143 .code = MEDIA_BUS_FMT_SBGGR10_1X10, 144 .depth = 10, 145 .csi_dt = MIPI_CSI2_DT_RAW10, 146 }, 147 { 148 .code = MEDIA_BUS_FMT_SGBRG10_1X10, 149 .depth = 10, 150 .csi_dt = MIPI_CSI2_DT_RAW10, 151 }, 152 { 153 .code = MEDIA_BUS_FMT_SGRBG10_1X10, 154 .depth = 10, 155 .csi_dt = MIPI_CSI2_DT_RAW10, 156 }, 157 { 158 .code = MEDIA_BUS_FMT_SRGGB10_1X10, 159 .depth = 10, 160 .csi_dt = MIPI_CSI2_DT_RAW10, 161 }, 162 { 163 .code = MEDIA_BUS_FMT_SBGGR12_1X12, 164 .depth = 12, 165 .csi_dt = MIPI_CSI2_DT_RAW12, 166 }, 167 { 168 .code = MEDIA_BUS_FMT_SGBRG12_1X12, 169 .depth = 12, 170 .csi_dt = MIPI_CSI2_DT_RAW12, 171 }, 172 { 173 .code = MEDIA_BUS_FMT_SGRBG12_1X12, 174 .depth = 12, 175 .csi_dt = MIPI_CSI2_DT_RAW12, 176 }, 177 { 178 .code = MEDIA_BUS_FMT_SRGGB12_1X12, 179 .depth = 12, 180 .csi_dt = MIPI_CSI2_DT_RAW12, 181 }, 182 }; 183 184 static inline struct dw_mipi_csi2rx_device *to_csi2(struct v4l2_subdev *sd) 185 { 186 return container_of(sd, struct dw_mipi_csi2rx_device, sd); 187 } 188 189 static inline void dw_mipi_csi2rx_write(struct dw_mipi_csi2rx_device *csi2, 190 unsigned int addr, u32 val) 191 { 192 writel(val, csi2->base_addr + addr); 193 } 194 195 static inline u32 dw_mipi_csi2rx_read(struct dw_mipi_csi2rx_device *csi2, 196 unsigned int addr) 197 { 198 return readl(csi2->base_addr + addr); 199 } 200 201 static const struct dw_mipi_csi2rx_format * 202 dw_mipi_csi2rx_find_format(struct dw_mipi_csi2rx_device *csi2, u32 mbus_code) 203 { 204 WARN_ON(csi2->formats_num == 0); 205 206 for (unsigned int i = 0; i < csi2->formats_num; i++) { 207 const struct dw_mipi_csi2rx_format *format = &csi2->formats[i]; 208 209 if (format->code == mbus_code) 210 return format; 211 } 212 213 return NULL; 214 } 215 216 static int dw_mipi_csi2rx_start(struct dw_mipi_csi2rx_device *csi2) 217 { 218 struct media_pad *source_pad; 219 union phy_configure_opts opts; 220 u32 lanes = csi2->lanes_num; 221 u32 control = 0; 222 s64 link_freq; 223 int ret; 224 225 if (lanes < 1 || lanes > 4) 226 return -EINVAL; 227 228 source_pad = media_pad_remote_pad_unique( 229 &csi2->pads[DW_MIPI_CSI2RX_PAD_SINK]); 230 if (IS_ERR(source_pad)) 231 return PTR_ERR(source_pad); 232 233 /* set mult and div to 0, thus completely rely on V4L2_CID_LINK_FREQ */ 234 link_freq = v4l2_get_link_freq(source_pad, 0, 0); 235 if (link_freq < 0) 236 return link_freq; 237 238 switch (csi2->bus_type) { 239 case V4L2_MBUS_CSI2_DPHY: 240 ret = phy_mipi_dphy_get_default_config_for_hsclk(link_freq * 2, 241 lanes, &opts.mipi_dphy); 242 if (ret) 243 return ret; 244 245 ret = phy_set_mode(csi2->phy, PHY_MODE_MIPI_DPHY); 246 if (ret) 247 return ret; 248 249 ret = phy_configure(csi2->phy, &opts); 250 if (ret) 251 return ret; 252 253 control |= SW_CPHY_EN(0); 254 break; 255 256 case V4L2_MBUS_CSI2_CPHY: 257 /* TODO: implement CPHY configuration */ 258 return -EOPNOTSUPP; 259 default: 260 return -EINVAL; 261 } 262 263 control |= SW_DATATYPE_FS(0x00) | SW_DATATYPE_FE(0x01) | 264 SW_DATATYPE_LS(0x02) | SW_DATATYPE_LE(0x03); 265 266 dw_mipi_csi2rx_write(csi2, DW_MIPI_CSI2RX_N_LANES, lanes - 1); 267 dw_mipi_csi2rx_write(csi2, DW_MIPI_CSI2RX_CONTROL, control); 268 dw_mipi_csi2rx_write(csi2, DW_MIPI_CSI2RX_RESETN, 1); 269 270 return phy_power_on(csi2->phy); 271 } 272 273 static void dw_mipi_csi2rx_stop(struct dw_mipi_csi2rx_device *csi2) 274 { 275 phy_power_off(csi2->phy); 276 277 dw_mipi_csi2rx_write(csi2, DW_MIPI_CSI2RX_RESETN, 0); 278 dw_mipi_csi2rx_write(csi2, DW_MIPI_CSI2RX_MSK1, ~0); 279 dw_mipi_csi2rx_write(csi2, DW_MIPI_CSI2RX_MSK2, ~0); 280 } 281 282 static const struct media_entity_operations dw_mipi_csi2rx_media_ops = { 283 .link_validate = v4l2_subdev_link_validate, 284 }; 285 286 static int 287 dw_mipi_csi2rx_enum_mbus_code(struct v4l2_subdev *sd, 288 struct v4l2_subdev_state *sd_state, 289 struct v4l2_subdev_mbus_code_enum *code) 290 { 291 struct dw_mipi_csi2rx_device *csi2 = to_csi2(sd); 292 293 switch (code->pad) { 294 case DW_MIPI_CSI2RX_PAD_SRC: 295 if (code->index) 296 return -EINVAL; 297 298 code->code = 299 v4l2_subdev_state_get_format(sd_state, 300 DW_MIPI_CSI2RX_PAD_SINK)->code; 301 302 return 0; 303 case DW_MIPI_CSI2RX_PAD_SINK: 304 if (code->index > csi2->formats_num) 305 return -EINVAL; 306 307 code->code = csi2->formats[code->index].code; 308 return 0; 309 default: 310 return -EINVAL; 311 } 312 } 313 314 static int dw_mipi_csi2rx_set_fmt(struct v4l2_subdev *sd, 315 struct v4l2_subdev_state *state, 316 struct v4l2_subdev_format *format) 317 { 318 struct dw_mipi_csi2rx_device *csi2 = to_csi2(sd); 319 const struct dw_mipi_csi2rx_format *fmt; 320 struct v4l2_mbus_framefmt *sink, *src; 321 322 /* the format on the source pad always matches the sink pad */ 323 if (format->pad == DW_MIPI_CSI2RX_PAD_SRC) 324 return v4l2_subdev_get_fmt(sd, state, format); 325 326 sink = v4l2_subdev_state_get_format(state, format->pad, format->stream); 327 if (!sink) 328 return -EINVAL; 329 330 fmt = dw_mipi_csi2rx_find_format(csi2, format->format.code); 331 if (!fmt) 332 format->format = default_format; 333 334 *sink = format->format; 335 336 /* propagate the format to the source pad */ 337 src = v4l2_subdev_state_get_opposite_stream_format(state, format->pad, 338 format->stream); 339 if (!src) 340 return -EINVAL; 341 342 *src = *sink; 343 344 return 0; 345 } 346 347 static int dw_mipi_csi2rx_set_routing(struct v4l2_subdev *sd, 348 struct v4l2_subdev_state *state, 349 enum v4l2_subdev_format_whence which, 350 struct v4l2_subdev_krouting *routing) 351 { 352 int ret; 353 354 ret = v4l2_subdev_routing_validate(sd, routing, 355 V4L2_SUBDEV_ROUTING_ONLY_1_TO_1); 356 if (ret) 357 return ret; 358 359 return v4l2_subdev_set_routing_with_fmt(sd, state, routing, 360 &default_format); 361 } 362 363 static int dw_mipi_csi2rx_enable_streams(struct v4l2_subdev *sd, 364 struct v4l2_subdev_state *state, 365 u32 pad, u64 streams_mask) 366 { 367 struct dw_mipi_csi2rx_device *csi2 = to_csi2(sd); 368 struct v4l2_subdev *remote_sd; 369 struct media_pad *sink_pad, *remote_pad; 370 struct device *dev = csi2->dev; 371 u64 mask; 372 int ret; 373 374 sink_pad = &sd->entity.pads[DW_MIPI_CSI2RX_PAD_SINK]; 375 remote_pad = media_pad_remote_pad_first(sink_pad); 376 remote_sd = media_entity_to_v4l2_subdev(remote_pad->entity); 377 378 mask = v4l2_subdev_state_xlate_streams(state, DW_MIPI_CSI2RX_PAD_SINK, 379 DW_MIPI_CSI2RX_PAD_SRC, 380 &streams_mask); 381 382 ret = pm_runtime_resume_and_get(dev); 383 if (ret) 384 goto err; 385 386 ret = dw_mipi_csi2rx_start(csi2); 387 if (ret) { 388 dev_err(dev, "failed to enable CSI hardware\n"); 389 goto err_pm_runtime_put; 390 } 391 392 ret = v4l2_subdev_enable_streams(remote_sd, remote_pad->index, mask); 393 if (ret) 394 goto err_csi_stop; 395 396 return 0; 397 398 err_csi_stop: 399 dw_mipi_csi2rx_stop(csi2); 400 err_pm_runtime_put: 401 pm_runtime_put(dev); 402 err: 403 return ret; 404 } 405 406 static int dw_mipi_csi2rx_disable_streams(struct v4l2_subdev *sd, 407 struct v4l2_subdev_state *state, 408 u32 pad, u64 streams_mask) 409 { 410 struct dw_mipi_csi2rx_device *csi2 = to_csi2(sd); 411 struct v4l2_subdev *remote_sd; 412 struct media_pad *sink_pad, *remote_pad; 413 struct device *dev = csi2->dev; 414 u64 mask; 415 int ret; 416 417 sink_pad = &sd->entity.pads[DW_MIPI_CSI2RX_PAD_SINK]; 418 remote_pad = media_pad_remote_pad_first(sink_pad); 419 remote_sd = media_entity_to_v4l2_subdev(remote_pad->entity); 420 421 mask = v4l2_subdev_state_xlate_streams(state, DW_MIPI_CSI2RX_PAD_SINK, 422 DW_MIPI_CSI2RX_PAD_SRC, 423 &streams_mask); 424 425 ret = v4l2_subdev_disable_streams(remote_sd, remote_pad->index, mask); 426 427 dw_mipi_csi2rx_stop(csi2); 428 429 pm_runtime_put(dev); 430 431 return ret; 432 } 433 434 static const struct v4l2_subdev_pad_ops dw_mipi_csi2rx_pad_ops = { 435 .enum_mbus_code = dw_mipi_csi2rx_enum_mbus_code, 436 .get_fmt = v4l2_subdev_get_fmt, 437 .set_fmt = dw_mipi_csi2rx_set_fmt, 438 .set_routing = dw_mipi_csi2rx_set_routing, 439 .enable_streams = dw_mipi_csi2rx_enable_streams, 440 .disable_streams = dw_mipi_csi2rx_disable_streams, 441 }; 442 443 static const struct v4l2_subdev_ops dw_mipi_csi2rx_ops = { 444 .pad = &dw_mipi_csi2rx_pad_ops, 445 }; 446 447 static int dw_mipi_csi2rx_init_state(struct v4l2_subdev *sd, 448 struct v4l2_subdev_state *state) 449 { 450 struct v4l2_subdev_route routes[] = { 451 { 452 .sink_pad = DW_MIPI_CSI2RX_PAD_SINK, 453 .sink_stream = 0, 454 .source_pad = DW_MIPI_CSI2RX_PAD_SRC, 455 .source_stream = 0, 456 .flags = V4L2_SUBDEV_ROUTE_FL_ACTIVE, 457 }, 458 }; 459 struct v4l2_subdev_krouting routing = { 460 .len_routes = ARRAY_SIZE(routes), 461 .num_routes = ARRAY_SIZE(routes), 462 .routes = routes, 463 }; 464 465 return v4l2_subdev_set_routing_with_fmt(sd, state, &routing, 466 &default_format); 467 } 468 469 static const struct v4l2_subdev_internal_ops dw_mipi_csi2rx_internal_ops = { 470 .init_state = dw_mipi_csi2rx_init_state, 471 }; 472 473 static int dw_mipi_csi2rx_notifier_bound(struct v4l2_async_notifier *notifier, 474 struct v4l2_subdev *sd, 475 struct v4l2_async_connection *asd) 476 { 477 struct dw_mipi_csi2rx_device *csi2 = 478 container_of(notifier, struct dw_mipi_csi2rx_device, notifier); 479 struct media_pad *sink_pad = &csi2->pads[DW_MIPI_CSI2RX_PAD_SINK]; 480 int ret; 481 482 ret = v4l2_create_fwnode_links_to_pad(sd, sink_pad, 483 MEDIA_LNK_FL_ENABLED); 484 if (ret) { 485 dev_err(csi2->dev, "failed to link source pad of %s\n", 486 sd->name); 487 return ret; 488 } 489 490 return 0; 491 } 492 493 static const struct v4l2_async_notifier_operations dw_mipi_csi2rx_notifier_ops = { 494 .bound = dw_mipi_csi2rx_notifier_bound, 495 }; 496 497 static int dw_mipi_csi2rx_register_notifier(struct dw_mipi_csi2rx_device *csi2) 498 { 499 struct v4l2_async_connection *asd; 500 struct v4l2_async_notifier *ntf = &csi2->notifier; 501 struct v4l2_fwnode_endpoint vep; 502 struct v4l2_subdev *sd = &csi2->sd; 503 struct device *dev = csi2->dev; 504 int ret; 505 506 struct fwnode_handle *ep __free(fwnode_handle) = 507 fwnode_graph_get_endpoint_by_id(dev_fwnode(dev), 0, 0, 0); 508 if (!ep) 509 return dev_err_probe(dev, -ENODEV, "failed to get endpoint\n"); 510 511 vep.bus_type = V4L2_MBUS_UNKNOWN; 512 ret = v4l2_fwnode_endpoint_parse(ep, &vep); 513 if (ret) 514 return dev_err_probe(dev, ret, "failed to parse endpoint\n"); 515 516 if (vep.bus_type != V4L2_MBUS_CSI2_DPHY && 517 vep.bus_type != V4L2_MBUS_CSI2_CPHY) 518 return dev_err_probe(dev, -EINVAL, 519 "invalid bus type of endpoint\n"); 520 521 csi2->bus_type = vep.bus_type; 522 csi2->lanes_num = vep.bus.mipi_csi2.num_data_lanes; 523 524 v4l2_async_subdev_nf_init(ntf, sd); 525 ntf->ops = &dw_mipi_csi2rx_notifier_ops; 526 527 asd = v4l2_async_nf_add_fwnode_remote(ntf, ep, 528 struct v4l2_async_connection); 529 if (IS_ERR(asd)) { 530 ret = PTR_ERR(asd); 531 goto err_nf_cleanup; 532 } 533 534 ret = v4l2_async_nf_register(ntf); 535 if (ret) { 536 ret = dev_err_probe(dev, ret, "failed to register notifier\n"); 537 goto err_nf_cleanup; 538 } 539 540 return 0; 541 542 err_nf_cleanup: 543 v4l2_async_nf_cleanup(ntf); 544 545 return ret; 546 } 547 548 static int dw_mipi_csi2rx_register(struct dw_mipi_csi2rx_device *csi2) 549 { 550 struct media_pad *pads = csi2->pads; 551 struct v4l2_subdev *sd = &csi2->sd; 552 int ret; 553 554 ret = dw_mipi_csi2rx_register_notifier(csi2); 555 if (ret) 556 goto err; 557 558 v4l2_subdev_init(sd, &dw_mipi_csi2rx_ops); 559 sd->dev = csi2->dev; 560 sd->entity.ops = &dw_mipi_csi2rx_media_ops; 561 sd->entity.function = MEDIA_ENT_F_VID_IF_BRIDGE; 562 sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE | V4L2_SUBDEV_FL_STREAMS; 563 sd->internal_ops = &dw_mipi_csi2rx_internal_ops; 564 snprintf(sd->name, sizeof(sd->name), "dw-mipi-csi2rx %s", 565 dev_name(csi2->dev)); 566 567 pads[DW_MIPI_CSI2RX_PAD_SINK].flags = MEDIA_PAD_FL_SINK | 568 MEDIA_PAD_FL_MUST_CONNECT; 569 pads[DW_MIPI_CSI2RX_PAD_SRC].flags = MEDIA_PAD_FL_SOURCE; 570 ret = media_entity_pads_init(&sd->entity, DW_MIPI_CSI2RX_PAD_MAX, pads); 571 if (ret) 572 goto err_notifier_unregister; 573 574 ret = v4l2_subdev_init_finalize(sd); 575 if (ret) 576 goto err_entity_cleanup; 577 578 ret = v4l2_async_register_subdev(sd); 579 if (ret) { 580 dev_err(sd->dev, "failed to register CSI-2 subdev\n"); 581 goto err_subdev_cleanup; 582 } 583 584 return 0; 585 586 err_subdev_cleanup: 587 v4l2_subdev_cleanup(sd); 588 err_entity_cleanup: 589 media_entity_cleanup(&sd->entity); 590 err_notifier_unregister: 591 v4l2_async_nf_unregister(&csi2->notifier); 592 v4l2_async_nf_cleanup(&csi2->notifier); 593 err: 594 return ret; 595 } 596 597 static void dw_mipi_csi2rx_unregister(struct dw_mipi_csi2rx_device *csi2) 598 { 599 struct v4l2_subdev *sd = &csi2->sd; 600 601 v4l2_async_unregister_subdev(sd); 602 v4l2_subdev_cleanup(sd); 603 media_entity_cleanup(&sd->entity); 604 v4l2_async_nf_unregister(&csi2->notifier); 605 v4l2_async_nf_cleanup(&csi2->notifier); 606 } 607 608 static const struct of_device_id dw_mipi_csi2rx_of_match[] = { 609 { 610 .compatible = "rockchip,rk3568-mipi-csi2", 611 }, 612 {} 613 }; 614 MODULE_DEVICE_TABLE(of, dw_mipi_csi2rx_of_match); 615 616 static int dw_mipi_csi2rx_probe(struct platform_device *pdev) 617 { 618 struct device *dev = &pdev->dev; 619 struct dw_mipi_csi2rx_device *csi2; 620 int ret; 621 622 csi2 = devm_kzalloc(dev, sizeof(*csi2), GFP_KERNEL); 623 if (!csi2) 624 return -ENOMEM; 625 csi2->dev = dev; 626 dev_set_drvdata(dev, csi2); 627 628 csi2->base_addr = devm_platform_ioremap_resource(pdev, 0); 629 if (IS_ERR(csi2->base_addr)) 630 return PTR_ERR(csi2->base_addr); 631 632 ret = devm_clk_bulk_get_all(dev, &csi2->clks); 633 if (ret != DW_MIPI_CSI2RX_CLKS_MAX) 634 return dev_err_probe(dev, -ENODEV, "failed to get clocks\n"); 635 csi2->clks_num = ret; 636 637 csi2->phy = devm_phy_get(dev, NULL); 638 if (IS_ERR(csi2->phy)) 639 return dev_err_probe(dev, PTR_ERR(csi2->phy), 640 "failed to get MIPI CSI-2 PHY\n"); 641 642 csi2->reset = devm_reset_control_get_exclusive(dev, NULL); 643 if (IS_ERR(csi2->reset)) 644 return dev_err_probe(dev, PTR_ERR(csi2->reset), 645 "failed to get reset\n"); 646 647 csi2->formats = formats; 648 csi2->formats_num = ARRAY_SIZE(formats); 649 650 ret = devm_pm_runtime_enable(dev); 651 if (ret) 652 return dev_err_probe(dev, ret, "failed to enable pm runtime\n"); 653 654 ret = phy_init(csi2->phy); 655 if (ret) 656 return dev_err_probe(dev, ret, 657 "failed to initialize MIPI CSI-2 PHY\n"); 658 659 ret = dw_mipi_csi2rx_register(csi2); 660 if (ret) 661 goto err_phy_exit; 662 663 return 0; 664 665 err_phy_exit: 666 phy_exit(csi2->phy); 667 668 return ret; 669 } 670 671 static void dw_mipi_csi2rx_remove(struct platform_device *pdev) 672 { 673 struct dw_mipi_csi2rx_device *csi2 = platform_get_drvdata(pdev); 674 675 dw_mipi_csi2rx_unregister(csi2); 676 phy_exit(csi2->phy); 677 } 678 679 static int dw_mipi_csi2rx_runtime_suspend(struct device *dev) 680 { 681 struct dw_mipi_csi2rx_device *csi2 = dev_get_drvdata(dev); 682 683 clk_bulk_disable_unprepare(csi2->clks_num, csi2->clks); 684 685 return 0; 686 } 687 688 static int dw_mipi_csi2rx_runtime_resume(struct device *dev) 689 { 690 struct dw_mipi_csi2rx_device *csi2 = dev_get_drvdata(dev); 691 int ret; 692 693 reset_control_assert(csi2->reset); 694 udelay(5); 695 reset_control_deassert(csi2->reset); 696 697 ret = clk_bulk_prepare_enable(csi2->clks_num, csi2->clks); 698 if (ret) { 699 dev_err(dev, "failed to enable clocks\n"); 700 return ret; 701 } 702 703 return 0; 704 } 705 706 static DEFINE_RUNTIME_DEV_PM_OPS(dw_mipi_csi2rx_pm_ops, 707 dw_mipi_csi2rx_runtime_suspend, 708 dw_mipi_csi2rx_runtime_resume, NULL); 709 710 static struct platform_driver dw_mipi_csi2rx_drv = { 711 .driver = { 712 .name = "dw-mipi-csi2rx", 713 .of_match_table = dw_mipi_csi2rx_of_match, 714 .pm = pm_ptr(&dw_mipi_csi2rx_pm_ops), 715 }, 716 .probe = dw_mipi_csi2rx_probe, 717 .remove = dw_mipi_csi2rx_remove, 718 }; 719 module_platform_driver(dw_mipi_csi2rx_drv); 720 721 MODULE_DESCRIPTION("Synopsys DesignWare MIPI CSI-2 Receiver platform driver"); 722 MODULE_LICENSE("GPL"); 723