@@ -364,6 +364,7 @@ struct rcar_csi2 {
364
364
struct v4l2_async_notifier notifier ;
365
365
struct v4l2_async_subdev asd ;
366
366
struct v4l2_subdev * remote ;
367
+ unsigned int remote_pad ;
367
368
368
369
struct v4l2_mbus_framefmt mf ;
369
370
@@ -409,13 +410,14 @@ static void rcsi2_exit_standby(struct rcar_csi2 *priv)
409
410
reset_control_deassert (priv -> rstc );
410
411
}
411
412
412
- static int rcsi2_wait_phy_start (struct rcar_csi2 * priv )
413
+ static int rcsi2_wait_phy_start (struct rcar_csi2 * priv ,
414
+ unsigned int lanes )
413
415
{
414
416
unsigned int timeout ;
415
417
416
418
/* Wait for the clock and data lanes to enter LP-11 state. */
417
419
for (timeout = 0 ; timeout <= 20 ; timeout ++ ) {
418
- const u32 lane_mask = (1 << priv -> lanes ) - 1 ;
420
+ const u32 lane_mask = (1 << lanes ) - 1 ;
419
421
420
422
if ((rcsi2_read (priv , PHCLM_REG ) & PHCLM_STOPSTATECKL ) &&
421
423
(rcsi2_read (priv , PHDLM_REG ) & lane_mask ) == lane_mask )
@@ -447,7 +449,8 @@ static int rcsi2_set_phypll(struct rcar_csi2 *priv, unsigned int mbps)
447
449
return 0 ;
448
450
}
449
451
450
- static int rcsi2_calc_mbps (struct rcar_csi2 * priv , unsigned int bpp )
452
+ static int rcsi2_calc_mbps (struct rcar_csi2 * priv , unsigned int bpp ,
453
+ unsigned int lanes )
451
454
{
452
455
struct v4l2_subdev * source ;
453
456
struct v4l2_ctrl * ctrl ;
@@ -472,15 +475,64 @@ static int rcsi2_calc_mbps(struct rcar_csi2 *priv, unsigned int bpp)
472
475
* bps = link_freq * 2
473
476
*/
474
477
mbps = v4l2_ctrl_g_ctrl_int64 (ctrl ) * bpp ;
475
- do_div (mbps , priv -> lanes * 1000000 );
478
+ do_div (mbps , lanes * 1000000 );
476
479
477
480
return mbps ;
478
481
}
479
482
483
+ static int rcsi2_get_active_lanes (struct rcar_csi2 * priv ,
484
+ unsigned int * lanes )
485
+ {
486
+ struct v4l2_mbus_config mbus_config = { 0 };
487
+ unsigned int num_lanes = UINT_MAX ;
488
+ int ret ;
489
+
490
+ * lanes = priv -> lanes ;
491
+
492
+ ret = v4l2_subdev_call (priv -> remote , pad , get_mbus_config ,
493
+ priv -> remote_pad , & mbus_config );
494
+ if (ret == - ENOIOCTLCMD ) {
495
+ dev_dbg (priv -> dev , "No remote mbus configuration available\n" );
496
+ return 0 ;
497
+ }
498
+
499
+ if (ret ) {
500
+ dev_err (priv -> dev , "Failed to get remote mbus configuration\n" );
501
+ return ret ;
502
+ }
503
+
504
+ if (mbus_config .type != V4L2_MBUS_CSI2_DPHY ) {
505
+ dev_err (priv -> dev , "Unsupported media bus type %u\n" ,
506
+ mbus_config .type );
507
+ return - EINVAL ;
508
+ }
509
+
510
+ if (mbus_config .flags & V4L2_MBUS_CSI2_1_LANE )
511
+ num_lanes = 1 ;
512
+ else if (mbus_config .flags & V4L2_MBUS_CSI2_2_LANE )
513
+ num_lanes = 2 ;
514
+ else if (mbus_config .flags & V4L2_MBUS_CSI2_3_LANE )
515
+ num_lanes = 3 ;
516
+ else if (mbus_config .flags & V4L2_MBUS_CSI2_4_LANE )
517
+ num_lanes = 4 ;
518
+
519
+ if (num_lanes > priv -> lanes ) {
520
+ dev_err (priv -> dev ,
521
+ "Unsupported mbus config: too many data lanes %u\n" ,
522
+ num_lanes );
523
+ return - EINVAL ;
524
+ }
525
+
526
+ * lanes = num_lanes ;
527
+
528
+ return 0 ;
529
+ }
530
+
480
531
static int rcsi2_start_receiver (struct rcar_csi2 * priv )
481
532
{
482
533
const struct rcar_csi2_format * format ;
483
534
u32 phycnt , vcdt = 0 , vcdt2 = 0 , fld = 0 ;
535
+ unsigned int lanes ;
484
536
unsigned int i ;
485
537
int mbps , ret ;
486
538
@@ -522,10 +574,18 @@ static int rcsi2_start_receiver(struct rcar_csi2 *priv)
522
574
fld |= FLD_FLD_NUM (1 );
523
575
}
524
576
577
+ /*
578
+ * Get the number of active data lanes inspecting the remote mbus
579
+ * configuration.
580
+ */
581
+ ret = rcsi2_get_active_lanes (priv , & lanes );
582
+ if (ret )
583
+ return ret ;
584
+
525
585
phycnt = PHYCNT_ENABLECLK ;
526
- phycnt |= (1 << priv -> lanes ) - 1 ;
586
+ phycnt |= (1 << lanes ) - 1 ;
527
587
528
- mbps = rcsi2_calc_mbps (priv , format -> bpp );
588
+ mbps = rcsi2_calc_mbps (priv , format -> bpp , lanes );
529
589
if (mbps < 0 )
530
590
return mbps ;
531
591
@@ -572,7 +632,7 @@ static int rcsi2_start_receiver(struct rcar_csi2 *priv)
572
632
rcsi2_write (priv , PHYCNT_REG , phycnt | PHYCNT_SHUTDOWNZ );
573
633
rcsi2_write (priv , PHYCNT_REG , phycnt | PHYCNT_SHUTDOWNZ | PHYCNT_RSTZ );
574
634
575
- ret = rcsi2_wait_phy_start (priv );
635
+ ret = rcsi2_wait_phy_start (priv , lanes );
576
636
if (ret )
577
637
return ret ;
578
638
@@ -749,6 +809,7 @@ static int rcsi2_notify_bound(struct v4l2_async_notifier *notifier,
749
809
}
750
810
751
811
priv -> remote = subdev ;
812
+ priv -> remote_pad = pad ;
752
813
753
814
dev_dbg (priv -> dev , "Bound %s pad: %d\n" , subdev -> name , pad );
754
815
0 commit comments