1 // SPDX-License-Identifier: GPL-2.0+ 2 /* 3 * Driver for Cadence MIPI-CSI2 TX Controller 4 * 5 * Copyright (C) 2017-2018 Cadence Design Systems Inc. 6 */ 7 8 #include <linux/clk.h> 9 #include <linux/delay.h> 10 #include <linux/io.h> 11 #include <linux/module.h> 12 #include <linux/mutex.h> 13 #include <linux/of.h> 14 #include <linux/of_graph.h> 15 #include <linux/platform_device.h> 16 17 #include <media/v4l2-ctrls.h> 18 #include <media/v4l2-device.h> 19 #include <media/v4l2-fwnode.h> 20 #include <media/v4l2-subdev.h> 21 22 #define CSI2TX_DEVICE_CONFIG_REG 0x00 23 #define CSI2TX_DEVICE_CONFIG_STREAMS_MASK GENMASK(6, 4) 24 #define CSI2TX_DEVICE_CONFIG_HAS_DPHY BIT(3) 25 #define CSI2TX_DEVICE_CONFIG_LANES_MASK GENMASK(2, 0) 26 27 #define CSI2TX_CONFIG_REG 0x20 28 #define CSI2TX_CONFIG_CFG_REQ BIT(2) 29 #define CSI2TX_CONFIG_SRST_REQ BIT(1) 30 31 #define CSI2TX_DPHY_CFG_REG 0x28 32 #define CSI2TX_DPHY_CFG_CLK_RESET BIT(16) 33 #define CSI2TX_DPHY_CFG_LANE_RESET(n) BIT((n) + 12) 34 #define CSI2TX_DPHY_CFG_MODE_MASK GENMASK(9, 8) 35 #define CSI2TX_DPHY_CFG_MODE_LPDT (2 << 8) 36 #define CSI2TX_DPHY_CFG_MODE_HS (1 << 8) 37 #define CSI2TX_DPHY_CFG_MODE_ULPS (0 << 8) 38 #define CSI2TX_DPHY_CFG_CLK_ENABLE BIT(4) 39 #define CSI2TX_DPHY_CFG_LANE_ENABLE(n) BIT(n) 40 41 #define CSI2TX_DPHY_CLK_WAKEUP_REG 0x2c 42 #define CSI2TX_DPHY_CLK_WAKEUP_ULPS_CYCLES(n) ((n) & 0xffff) 43 44 #define CSI2TX_DT_CFG_REG(n) (0x80 + (n) * 8) 45 #define CSI2TX_DT_CFG_DT(n) (((n) & 0x3f) << 2) 46 47 #define CSI2TX_DT_FORMAT_REG(n) (0x84 + (n) * 8) 48 #define CSI2TX_DT_FORMAT_BYTES_PER_LINE(n) (((n) & 0xffff) << 16) 49 #define CSI2TX_DT_FORMAT_MAX_LINE_NUM(n) ((n) & 0xffff) 50 51 #define CSI2TX_STREAM_IF_CFG_REG(n) (0x100 + (n) * 4) 52 #define CSI2TX_STREAM_IF_CFG_FILL_LEVEL(n) ((n) & 0x1f) 53 54 #define CSI2TX_LANES_MAX 4 55 #define CSI2TX_STREAMS_MAX 4 56 57 enum csi2tx_pads { 58 CSI2TX_PAD_SOURCE, 59 CSI2TX_PAD_SINK_STREAM0, 60 CSI2TX_PAD_SINK_STREAM1, 61 CSI2TX_PAD_SINK_STREAM2, 62 CSI2TX_PAD_SINK_STREAM3, 63 CSI2TX_PAD_MAX, 64 }; 65 66 struct csi2tx_fmt { 67 u32 mbus; 68 u32 dt; 69 u32 bpp; 70 }; 71 72 struct csi2tx_priv { 73 struct device *dev; 74 unsigned int count; 75 76 /* 77 * Used to prevent race conditions between multiple, 78 * concurrent calls to start and stop. 79 */ 80 struct mutex lock; 81 82 void __iomem *base; 83 84 struct clk *esc_clk; 85 struct clk *p_clk; 86 struct clk *pixel_clk[CSI2TX_STREAMS_MAX]; 87 88 struct v4l2_subdev subdev; 89 struct media_pad pads[CSI2TX_PAD_MAX]; 90 struct v4l2_mbus_framefmt pad_fmts[CSI2TX_PAD_MAX]; 91 92 bool has_internal_dphy; 93 u8 lanes[CSI2TX_LANES_MAX]; 94 unsigned int num_lanes; 95 unsigned int max_lanes; 96 unsigned int max_streams; 97 }; 98 99 static const struct csi2tx_fmt csi2tx_formats[] = { 100 { 101 .mbus = MEDIA_BUS_FMT_UYVY8_1X16, 102 .bpp = 2, 103 .dt = 0x1e, 104 }, 105 { 106 .mbus = MEDIA_BUS_FMT_RGB888_1X24, 107 .bpp = 3, 108 .dt = 0x24, 109 }, 110 }; 111 112 static const struct v4l2_mbus_framefmt fmt_default = { 113 .width = 1280, 114 .height = 720, 115 .code = MEDIA_BUS_FMT_RGB888_1X24, 116 .field = V4L2_FIELD_NONE, 117 .colorspace = V4L2_COLORSPACE_DEFAULT, 118 }; 119 120 static inline 121 struct csi2tx_priv *v4l2_subdev_to_csi2tx(struct v4l2_subdev *subdev) 122 { 123 return container_of(subdev, struct csi2tx_priv, subdev); 124 } 125 126 static const struct csi2tx_fmt *csi2tx_get_fmt_from_mbus(u32 mbus) 127 { 128 unsigned int i; 129 130 for (i = 0; i < ARRAY_SIZE(csi2tx_formats); i++) 131 if (csi2tx_formats[i].mbus == mbus) 132 return &csi2tx_formats[i]; 133 134 return NULL; 135 } 136 137 static int csi2tx_enum_mbus_code(struct v4l2_subdev *subdev, 138 struct v4l2_subdev_pad_config *cfg, 139 struct v4l2_subdev_mbus_code_enum *code) 140 { 141 if (code->pad || code->index >= ARRAY_SIZE(csi2tx_formats)) 142 return -EINVAL; 143 144 code->code = csi2tx_formats[code->index].mbus; 145 146 return 0; 147 } 148 149 static struct v4l2_mbus_framefmt * 150 __csi2tx_get_pad_format(struct v4l2_subdev *subdev, 151 struct v4l2_subdev_pad_config *cfg, 152 struct v4l2_subdev_format *fmt) 153 { 154 struct csi2tx_priv *csi2tx = v4l2_subdev_to_csi2tx(subdev); 155 156 if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) 157 return v4l2_subdev_get_try_format(subdev, cfg, 158 fmt->pad); 159 160 return &csi2tx->pad_fmts[fmt->pad]; 161 } 162 163 static int csi2tx_get_pad_format(struct v4l2_subdev *subdev, 164 struct v4l2_subdev_pad_config *cfg, 165 struct v4l2_subdev_format *fmt) 166 { 167 const struct v4l2_mbus_framefmt *format; 168 169 /* Multiplexed pad? */ 170 if (fmt->pad == CSI2TX_PAD_SOURCE) 171 return -EINVAL; 172 173 format = __csi2tx_get_pad_format(subdev, cfg, fmt); 174 if (!format) 175 return -EINVAL; 176 177 fmt->format = *format; 178 179 return 0; 180 } 181 182 static int csi2tx_set_pad_format(struct v4l2_subdev *subdev, 183 struct v4l2_subdev_pad_config *cfg, 184 struct v4l2_subdev_format *fmt) 185 { 186 const struct v4l2_mbus_framefmt *src_format = &fmt->format; 187 struct v4l2_mbus_framefmt *dst_format; 188 189 /* Multiplexed pad? */ 190 if (fmt->pad == CSI2TX_PAD_SOURCE) 191 return -EINVAL; 192 193 if (!csi2tx_get_fmt_from_mbus(fmt->format.code)) 194 src_format = &fmt_default; 195 196 dst_format = __csi2tx_get_pad_format(subdev, cfg, fmt); 197 if (!dst_format) 198 return -EINVAL; 199 200 *dst_format = *src_format; 201 202 return 0; 203 } 204 205 static const struct v4l2_subdev_pad_ops csi2tx_pad_ops = { 206 .enum_mbus_code = csi2tx_enum_mbus_code, 207 .get_fmt = csi2tx_get_pad_format, 208 .set_fmt = csi2tx_set_pad_format, 209 }; 210 211 static void csi2tx_reset(struct csi2tx_priv *csi2tx) 212 { 213 writel(CSI2TX_CONFIG_SRST_REQ, csi2tx->base + CSI2TX_CONFIG_REG); 214 215 udelay(10); 216 } 217 218 static int csi2tx_start(struct csi2tx_priv *csi2tx) 219 { 220 struct media_entity *entity = &csi2tx->subdev.entity; 221 struct media_link *link; 222 unsigned int i; 223 u32 reg; 224 225 csi2tx_reset(csi2tx); 226 227 writel(CSI2TX_CONFIG_CFG_REQ, csi2tx->base + CSI2TX_CONFIG_REG); 228 229 udelay(10); 230 231 /* Configure our PPI interface with the D-PHY */ 232 writel(CSI2TX_DPHY_CLK_WAKEUP_ULPS_CYCLES(32), 233 csi2tx->base + CSI2TX_DPHY_CLK_WAKEUP_REG); 234 235 /* Put our lanes (clock and data) out of reset */ 236 reg = CSI2TX_DPHY_CFG_CLK_RESET | CSI2TX_DPHY_CFG_MODE_LPDT; 237 for (i = 0; i < csi2tx->num_lanes; i++) 238 reg |= CSI2TX_DPHY_CFG_LANE_RESET(csi2tx->lanes[i]); 239 writel(reg, csi2tx->base + CSI2TX_DPHY_CFG_REG); 240 241 udelay(10); 242 243 /* Enable our (clock and data) lanes */ 244 reg |= CSI2TX_DPHY_CFG_CLK_ENABLE; 245 for (i = 0; i < csi2tx->num_lanes; i++) 246 reg |= CSI2TX_DPHY_CFG_LANE_ENABLE(csi2tx->lanes[i]); 247 writel(reg, csi2tx->base + CSI2TX_DPHY_CFG_REG); 248 249 udelay(10); 250 251 /* Switch to HS mode */ 252 reg &= ~CSI2TX_DPHY_CFG_MODE_MASK; 253 writel(reg | CSI2TX_DPHY_CFG_MODE_HS, 254 csi2tx->base + CSI2TX_DPHY_CFG_REG); 255 256 udelay(10); 257 258 /* 259 * Create a static mapping between the CSI virtual channels 260 * and the input streams. 261 * 262 * This should be enhanced, but v4l2 lacks the support for 263 * changing that mapping dynamically at the moment. 264 * 265 * We're protected from the userspace setting up links at the 266 * same time by the upper layer having called 267 * media_pipeline_start(). 268 */ 269 list_for_each_entry(link, &entity->links, list) { 270 struct v4l2_mbus_framefmt *mfmt; 271 const struct csi2tx_fmt *fmt; 272 unsigned int stream; 273 int pad_idx = -1; 274 275 /* Only consider our enabled input pads */ 276 for (i = CSI2TX_PAD_SINK_STREAM0; i < CSI2TX_PAD_MAX; i++) { 277 struct media_pad *pad = &csi2tx->pads[i]; 278 279 if ((pad == link->sink) && 280 (link->flags & MEDIA_LNK_FL_ENABLED)) { 281 pad_idx = i; 282 break; 283 } 284 } 285 286 if (pad_idx < 0) 287 continue; 288 289 mfmt = &csi2tx->pad_fmts[pad_idx]; 290 fmt = csi2tx_get_fmt_from_mbus(mfmt->code); 291 if (!fmt) 292 continue; 293 294 stream = pad_idx - CSI2TX_PAD_SINK_STREAM0; 295 296 /* 297 * We use the stream ID there, but it's wrong. 298 * 299 * A stream could very well send a data type that is 300 * not equal to its stream ID. We need to find a 301 * proper way to address it. 302 */ 303 writel(CSI2TX_DT_CFG_DT(fmt->dt), 304 csi2tx->base + CSI2TX_DT_CFG_REG(stream)); 305 306 writel(CSI2TX_DT_FORMAT_BYTES_PER_LINE(mfmt->width * fmt->bpp) | 307 CSI2TX_DT_FORMAT_MAX_LINE_NUM(mfmt->height + 1), 308 csi2tx->base + CSI2TX_DT_FORMAT_REG(stream)); 309 310 /* 311 * TODO: This needs to be calculated based on the 312 * output CSI2 clock rate. 313 */ 314 writel(CSI2TX_STREAM_IF_CFG_FILL_LEVEL(4), 315 csi2tx->base + CSI2TX_STREAM_IF_CFG_REG(stream)); 316 } 317 318 /* Disable the configuration mode */ 319 writel(0, csi2tx->base + CSI2TX_CONFIG_REG); 320 321 return 0; 322 } 323 324 static void csi2tx_stop(struct csi2tx_priv *csi2tx) 325 { 326 writel(CSI2TX_CONFIG_CFG_REQ | CSI2TX_CONFIG_SRST_REQ, 327 csi2tx->base + CSI2TX_CONFIG_REG); 328 } 329 330 static int csi2tx_s_stream(struct v4l2_subdev *subdev, int enable) 331 { 332 struct csi2tx_priv *csi2tx = v4l2_subdev_to_csi2tx(subdev); 333 int ret = 0; 334 335 mutex_lock(&csi2tx->lock); 336 337 if (enable) { 338 /* 339 * If we're not the first users, there's no need to 340 * enable the whole controller. 341 */ 342 if (!csi2tx->count) { 343 ret = csi2tx_start(csi2tx); 344 if (ret) 345 goto out; 346 } 347 348 csi2tx->count++; 349 } else { 350 csi2tx->count--; 351 352 /* 353 * Let the last user turn off the lights. 354 */ 355 if (!csi2tx->count) 356 csi2tx_stop(csi2tx); 357 } 358 359 out: 360 mutex_unlock(&csi2tx->lock); 361 return ret; 362 } 363 364 static const struct v4l2_subdev_video_ops csi2tx_video_ops = { 365 .s_stream = csi2tx_s_stream, 366 }; 367 368 static const struct v4l2_subdev_ops csi2tx_subdev_ops = { 369 .pad = &csi2tx_pad_ops, 370 .video = &csi2tx_video_ops, 371 }; 372 373 static int csi2tx_get_resources(struct csi2tx_priv *csi2tx, 374 struct platform_device *pdev) 375 { 376 struct resource *res; 377 unsigned int i; 378 u32 dev_cfg; 379 380 res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 381 csi2tx->base = devm_ioremap_resource(&pdev->dev, res); 382 if (IS_ERR(csi2tx->base)) 383 return PTR_ERR(csi2tx->base); 384 385 csi2tx->p_clk = devm_clk_get(&pdev->dev, "p_clk"); 386 if (IS_ERR(csi2tx->p_clk)) { 387 dev_err(&pdev->dev, "Couldn't get p_clk\n"); 388 return PTR_ERR(csi2tx->p_clk); 389 } 390 391 csi2tx->esc_clk = devm_clk_get(&pdev->dev, "esc_clk"); 392 if (IS_ERR(csi2tx->esc_clk)) { 393 dev_err(&pdev->dev, "Couldn't get the esc_clk\n"); 394 return PTR_ERR(csi2tx->esc_clk); 395 } 396 397 clk_prepare_enable(csi2tx->p_clk); 398 dev_cfg = readl(csi2tx->base + CSI2TX_DEVICE_CONFIG_REG); 399 clk_disable_unprepare(csi2tx->p_clk); 400 401 csi2tx->max_lanes = dev_cfg & CSI2TX_DEVICE_CONFIG_LANES_MASK; 402 if (csi2tx->max_lanes > CSI2TX_LANES_MAX) { 403 dev_err(&pdev->dev, "Invalid number of lanes: %u\n", 404 csi2tx->max_lanes); 405 return -EINVAL; 406 } 407 408 csi2tx->max_streams = (dev_cfg & CSI2TX_DEVICE_CONFIG_STREAMS_MASK) >> 4; 409 if (csi2tx->max_streams > CSI2TX_STREAMS_MAX) { 410 dev_err(&pdev->dev, "Invalid number of streams: %u\n", 411 csi2tx->max_streams); 412 return -EINVAL; 413 } 414 415 csi2tx->has_internal_dphy = !!(dev_cfg & CSI2TX_DEVICE_CONFIG_HAS_DPHY); 416 417 for (i = 0; i < csi2tx->max_streams; i++) { 418 char clk_name[16]; 419 420 snprintf(clk_name, sizeof(clk_name), "pixel_if%u_clk", i); 421 csi2tx->pixel_clk[i] = devm_clk_get(&pdev->dev, clk_name); 422 if (IS_ERR(csi2tx->pixel_clk[i])) { 423 dev_err(&pdev->dev, "Couldn't get clock %s\n", 424 clk_name); 425 return PTR_ERR(csi2tx->pixel_clk[i]); 426 } 427 } 428 429 return 0; 430 } 431 432 static int csi2tx_check_lanes(struct csi2tx_priv *csi2tx) 433 { 434 struct v4l2_fwnode_endpoint v4l2_ep; 435 struct device_node *ep; 436 int ret; 437 438 ep = of_graph_get_endpoint_by_regs(csi2tx->dev->of_node, 0, 0); 439 if (!ep) 440 return -EINVAL; 441 442 ret = v4l2_fwnode_endpoint_parse(of_fwnode_handle(ep), &v4l2_ep); 443 if (ret) { 444 dev_err(csi2tx->dev, "Could not parse v4l2 endpoint\n"); 445 goto out; 446 } 447 448 if (v4l2_ep.bus_type != V4L2_MBUS_CSI2) { 449 dev_err(csi2tx->dev, "Unsupported media bus type: 0x%x\n", 450 v4l2_ep.bus_type); 451 ret = -EINVAL; 452 goto out; 453 } 454 455 csi2tx->num_lanes = v4l2_ep.bus.mipi_csi2.num_data_lanes; 456 if (csi2tx->num_lanes > csi2tx->max_lanes) { 457 dev_err(csi2tx->dev, 458 "Current configuration uses more lanes than supported\n"); 459 ret = -EINVAL; 460 goto out; 461 } 462 463 memcpy(csi2tx->lanes, v4l2_ep.bus.mipi_csi2.data_lanes, 464 sizeof(csi2tx->lanes)); 465 466 out: 467 of_node_put(ep); 468 return ret; 469 } 470 471 static int csi2tx_probe(struct platform_device *pdev) 472 { 473 struct csi2tx_priv *csi2tx; 474 unsigned int i; 475 int ret; 476 477 csi2tx = kzalloc(sizeof(*csi2tx), GFP_KERNEL); 478 if (!csi2tx) 479 return -ENOMEM; 480 platform_set_drvdata(pdev, csi2tx); 481 mutex_init(&csi2tx->lock); 482 csi2tx->dev = &pdev->dev; 483 484 ret = csi2tx_get_resources(csi2tx, pdev); 485 if (ret) 486 goto err_free_priv; 487 488 v4l2_subdev_init(&csi2tx->subdev, &csi2tx_subdev_ops); 489 csi2tx->subdev.owner = THIS_MODULE; 490 csi2tx->subdev.dev = &pdev->dev; 491 csi2tx->subdev.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE; 492 snprintf(csi2tx->subdev.name, V4L2_SUBDEV_NAME_SIZE, "%s.%s", 493 KBUILD_MODNAME, dev_name(&pdev->dev)); 494 495 ret = csi2tx_check_lanes(csi2tx); 496 if (ret) 497 goto err_free_priv; 498 499 /* Create our media pads */ 500 csi2tx->subdev.entity.function = MEDIA_ENT_F_VID_IF_BRIDGE; 501 csi2tx->pads[CSI2TX_PAD_SOURCE].flags = MEDIA_PAD_FL_SOURCE; 502 for (i = CSI2TX_PAD_SINK_STREAM0; i < CSI2TX_PAD_MAX; i++) 503 csi2tx->pads[i].flags = MEDIA_PAD_FL_SINK; 504 505 /* 506 * Only the input pads are considered to have a format at the 507 * moment. The CSI link can multiplex various streams with 508 * different formats, and we can't expose this in v4l2 right 509 * now. 510 */ 511 for (i = CSI2TX_PAD_SINK_STREAM0; i < CSI2TX_PAD_MAX; i++) 512 csi2tx->pad_fmts[i] = fmt_default; 513 514 ret = media_entity_pads_init(&csi2tx->subdev.entity, CSI2TX_PAD_MAX, 515 csi2tx->pads); 516 if (ret) 517 goto err_free_priv; 518 519 ret = v4l2_async_register_subdev(&csi2tx->subdev); 520 if (ret < 0) 521 goto err_free_priv; 522 523 dev_info(&pdev->dev, 524 "Probed CSI2TX with %u/%u lanes, %u streams, %s D-PHY\n", 525 csi2tx->num_lanes, csi2tx->max_lanes, csi2tx->max_streams, 526 csi2tx->has_internal_dphy ? "internal" : "no"); 527 528 return 0; 529 530 err_free_priv: 531 kfree(csi2tx); 532 return ret; 533 } 534 535 static int csi2tx_remove(struct platform_device *pdev) 536 { 537 struct csi2tx_priv *csi2tx = platform_get_drvdata(pdev); 538 539 v4l2_async_unregister_subdev(&csi2tx->subdev); 540 kfree(csi2tx); 541 542 return 0; 543 } 544 545 static const struct of_device_id csi2tx_of_table[] = { 546 { .compatible = "cdns,csi2tx" }, 547 { }, 548 }; 549 MODULE_DEVICE_TABLE(of, csi2tx_of_table); 550 551 static struct platform_driver csi2tx_driver = { 552 .probe = csi2tx_probe, 553 .remove = csi2tx_remove, 554 555 .driver = { 556 .name = "cdns-csi2tx", 557 .of_match_table = csi2tx_of_table, 558 }, 559 }; 560 module_platform_driver(csi2tx_driver); 561 MODULE_AUTHOR("Maxime Ripard <maxime.ripard@bootlin.com>"); 562 MODULE_DESCRIPTION("Cadence CSI2-TX controller"); 563 MODULE_LICENSE("GPL"); 564