@@ -398,6 +398,190 @@ static int bcm7xxx_28nm_ephy_config_init(struct phy_device *phydev)
398
398
return bcm7xxx_28nm_ephy_apd_enable (phydev );
399
399
}
400
400
401
+ static int bcm7xxx_16nm_ephy_afe_config (struct phy_device * phydev )
402
+ {
403
+ int tmp , rcalcode , rcalnewcodelp , rcalnewcode11 , rcalnewcode11d2 ;
404
+
405
+ /* Reset PHY */
406
+ tmp = genphy_soft_reset (phydev );
407
+ if (tmp )
408
+ return tmp ;
409
+
410
+ /* Reset AFE and PLL */
411
+ bcm_phy_write_exp_sel (phydev , 0x0003 , 0x0006 );
412
+ /* Clear reset */
413
+ bcm_phy_write_exp_sel (phydev , 0x0003 , 0x0000 );
414
+
415
+ /* Write PLL/AFE control register to select 54MHz crystal */
416
+ bcm_phy_write_misc (phydev , 0x0030 , 0x0001 , 0x0000 );
417
+ bcm_phy_write_misc (phydev , 0x0031 , 0x0000 , 0x044a );
418
+
419
+ /* Change Ka,Kp,Ki to pdiv=1 */
420
+ bcm_phy_write_misc (phydev , 0x0033 , 0x0002 , 0x71a1 );
421
+ /* Configuration override */
422
+ bcm_phy_write_misc (phydev , 0x0033 , 0x0001 , 0x8000 );
423
+
424
+ /* Change PLL_NDIV and PLL_NUDGE */
425
+ bcm_phy_write_misc (phydev , 0x0031 , 0x0001 , 0x2f68 );
426
+ bcm_phy_write_misc (phydev , 0x0031 , 0x0002 , 0x0000 );
427
+
428
+ /* Reference frequency is 54Mhz, config_mode[15:14] = 3 (low
429
+ * phase)
430
+ */
431
+ bcm_phy_write_misc (phydev , 0x0030 , 0x0003 , 0xc036 );
432
+
433
+ /* Initialize bypass mode */
434
+ bcm_phy_write_misc (phydev , 0x0032 , 0x0003 , 0x0000 );
435
+ /* Bypass code, default: VCOCLK enabled */
436
+ bcm_phy_write_misc (phydev , 0x0033 , 0x0000 , 0x0002 );
437
+ /* LDOs at default setting */
438
+ bcm_phy_write_misc (phydev , 0x0030 , 0x0002 , 0x01c0 );
439
+ /* Release PLL reset */
440
+ bcm_phy_write_misc (phydev , 0x0030 , 0x0001 , 0x0001 );
441
+
442
+ /* Bandgap curvature correction to correct default */
443
+ bcm_phy_write_misc (phydev , 0x0038 , 0x0000 , 0x0010 );
444
+
445
+ /* Run RCAL */
446
+ bcm_phy_write_misc (phydev , 0x0039 , 0x0003 , 0x0038 );
447
+ bcm_phy_write_misc (phydev , 0x0039 , 0x0003 , 0x003b );
448
+ udelay (2 );
449
+ bcm_phy_write_misc (phydev , 0x0039 , 0x0003 , 0x003f );
450
+ mdelay (5 );
451
+
452
+ /* AFE_CAL_CONFIG_0, Vref=1000, Target=10, averaging enabled */
453
+ bcm_phy_write_misc (phydev , 0x0039 , 0x0001 , 0x1c82 );
454
+ /* AFE_CAL_CONFIG_0, no reset and analog powerup */
455
+ bcm_phy_write_misc (phydev , 0x0039 , 0x0001 , 0x9e82 );
456
+ udelay (2 );
457
+ /* AFE_CAL_CONFIG_0, start calibration */
458
+ bcm_phy_write_misc (phydev , 0x0039 , 0x0001 , 0x9f82 );
459
+ udelay (100 );
460
+ /* AFE_CAL_CONFIG_0, clear start calibration, set HiBW */
461
+ bcm_phy_write_misc (phydev , 0x0039 , 0x0001 , 0x9e86 );
462
+ udelay (2 );
463
+ /* AFE_CAL_CONFIG_0, start calibration with hi BW mode set */
464
+ bcm_phy_write_misc (phydev , 0x0039 , 0x0001 , 0x9f86 );
465
+ udelay (100 );
466
+
467
+ /* Adjust 10BT amplitude additional +7% and 100BT +2% */
468
+ bcm_phy_write_misc (phydev , 0x0038 , 0x0001 , 0xe7ea );
469
+ /* Adjust 1G mode amplitude and 1G testmode1 */
470
+ bcm_phy_write_misc (phydev , 0x0038 , 0x0002 , 0xede0 );
471
+
472
+ /* Read CORE_EXPA9 */
473
+ tmp = bcm_phy_read_exp (phydev , 0x00a9 );
474
+ /* CORE_EXPA9[6:1] is rcalcode[5:0] */
475
+ rcalcode = (tmp & 0x7e ) / 2 ;
476
+ /* Correct RCAL code + 1 is -1% rprogr, LP: +16 */
477
+ rcalnewcodelp = rcalcode + 16 ;
478
+ /* Correct RCAL code + 1 is -15 rprogr, 11: +10 */
479
+ rcalnewcode11 = rcalcode + 10 ;
480
+ /* Saturate if necessary */
481
+ if (rcalnewcodelp > 0x3f )
482
+ rcalnewcodelp = 0x3f ;
483
+ if (rcalnewcode11 > 0x3f )
484
+ rcalnewcode11 = 0x3f ;
485
+ /* REXT=1 BYP=1 RCAL_st1<5:0>=new rcal code */
486
+ tmp = 0x00f8 + rcalnewcodelp * 256 ;
487
+ /* Program into AFE_CAL_CONFIG_2 */
488
+ bcm_phy_write_misc (phydev , 0x0039 , 0x0003 , tmp );
489
+ /* AFE_BIAS_CONFIG_0 10BT bias code (Bias: E4) */
490
+ bcm_phy_write_misc (phydev , 0x0038 , 0x0001 , 0xe7e4 );
491
+ /* invert adc clock output and 'adc refp ldo current To correct
492
+ * default
493
+ */
494
+ bcm_phy_write_misc (phydev , 0x003b , 0x0000 , 0x8002 );
495
+ /* 100BT stair case, high BW, 1G stair case, alternate encode */
496
+ bcm_phy_write_misc (phydev , 0x003c , 0x0003 , 0xf882 );
497
+ /* 1000BT DAC transition method per Erol, bits[32], DAC Shuffle
498
+ * sequence 1 + 10BT imp adjust bits
499
+ */
500
+ bcm_phy_write_misc (phydev , 0x003d , 0x0000 , 0x3201 );
501
+ /* Non-overlap fix */
502
+ bcm_phy_write_misc (phydev , 0x003a , 0x0002 , 0x0c00 );
503
+
504
+ /* pwdb override (rxconfig<5>) to turn on RX LDO indpendent of
505
+ * pwdb controls from DSP_TAP10
506
+ */
507
+ bcm_phy_write_misc (phydev , 0x003a , 0x0001 , 0x0020 );
508
+
509
+ /* Remove references to channel 2 and 3 */
510
+ bcm_phy_write_misc (phydev , 0x003b , 0x0002 , 0x0000 );
511
+ bcm_phy_write_misc (phydev , 0x003b , 0x0003 , 0x0000 );
512
+
513
+ /* Set cal_bypassb bit rxconfig<43> */
514
+ bcm_phy_write_misc (phydev , 0x003a , 0x0003 , 0x0800 );
515
+ udelay (2 );
516
+
517
+ /* Revert pwdb_override (rxconfig<5>) to 0 so that the RX pwr
518
+ * is controlled by DSP.
519
+ */
520
+ bcm_phy_write_misc (phydev , 0x003a , 0x0001 , 0x0000 );
521
+
522
+ /* Drop LSB */
523
+ rcalnewcode11d2 = (rcalnewcode11 & 0xfffe ) / 2 ;
524
+ tmp = bcm_phy_read_misc (phydev , 0x003d , 0x0001 );
525
+ /* Clear bits [11:5] */
526
+ tmp &= ~0xfe0 ;
527
+ /* set txcfg_ch0<5>=1 (enable + set local rcal) */
528
+ tmp |= 0x0020 | (rcalnewcode11d2 * 64 );
529
+ bcm_phy_write_misc (phydev , 0x003d , 0x0001 , tmp );
530
+ bcm_phy_write_misc (phydev , 0x003d , 0x0002 , tmp );
531
+
532
+ tmp = bcm_phy_read_misc (phydev , 0x003d , 0x0000 );
533
+ /* set txcfg<45:44>=11 (enable Rextra + invert fullscaledetect)
534
+ */
535
+ tmp &= ~0x3000 ;
536
+ tmp |= 0x3000 ;
537
+ bcm_phy_write_misc (phydev , 0x003d , 0x0000 , tmp );
538
+
539
+ return 0 ;
540
+ }
541
+
542
+ static int bcm7xxx_16nm_ephy_config_init (struct phy_device * phydev )
543
+ {
544
+ int ret , val ;
545
+
546
+ ret = bcm7xxx_16nm_ephy_afe_config (phydev );
547
+ if (ret )
548
+ return ret ;
549
+
550
+ ret = bcm_phy_set_eee (phydev , true);
551
+ if (ret )
552
+ return ret ;
553
+
554
+ ret = bcm_phy_read_shadow (phydev , BCM54XX_SHD_SCR3 );
555
+ if (ret < 0 )
556
+ return ret ;
557
+
558
+ val = ret ;
559
+
560
+ /* Auto power down of DLL enabled,
561
+ * TXC/RXC disabled during auto power down.
562
+ */
563
+ val &= ~BCM54XX_SHD_SCR3_DLLAPD_DIS ;
564
+ val |= BIT (8 );
565
+
566
+ ret = bcm_phy_write_shadow (phydev , BCM54XX_SHD_SCR3 , val );
567
+ if (ret < 0 )
568
+ return ret ;
569
+
570
+ return bcm_phy_enable_apd (phydev , true);
571
+ }
572
+
573
+ static int bcm7xxx_16nm_ephy_resume (struct phy_device * phydev )
574
+ {
575
+ int ret ;
576
+
577
+ /* Re-apply workarounds coming out suspend/resume */
578
+ ret = bcm7xxx_16nm_ephy_config_init (phydev );
579
+ if (ret )
580
+ return ret ;
581
+
582
+ return genphy_config_aneg (phydev );
583
+ }
584
+
401
585
static int bcm7xxx_28nm_ephy_resume (struct phy_device * phydev )
402
586
{
403
587
int ret ;
@@ -610,9 +794,25 @@ static void bcm7xxx_28nm_remove(struct phy_device *phydev)
610
794
.resume = bcm7xxx_config_init, \
611
795
}
612
796
797
+ #define BCM7XXX_16NM_EPHY (_oui , _name ) \
798
+ { \
799
+ .phy_id = (_oui), \
800
+ .phy_id_mask = 0xfffffff0, \
801
+ .name = _name, \
802
+ /* PHY_BASIC_FEATURES */ \
803
+ .flags = PHY_IS_INTERNAL, \
804
+ .probe = bcm7xxx_28nm_probe, \
805
+ .remove = bcm7xxx_28nm_remove, \
806
+ .config_init = bcm7xxx_16nm_ephy_config_init, \
807
+ .config_aneg = genphy_config_aneg, \
808
+ .read_status = genphy_read_status, \
809
+ .resume = bcm7xxx_16nm_ephy_resume, \
810
+ }
811
+
613
812
static struct phy_driver bcm7xxx_driver [] = {
614
813
BCM7XXX_28NM_EPHY (PHY_ID_BCM72113 , "Broadcom BCM72113" ),
615
814
BCM7XXX_28NM_EPHY (PHY_ID_BCM72116 , "Broadcom BCM72116" ),
815
+ BCM7XXX_16NM_EPHY (PHY_ID_BCM72165 , "Broadcom BCM72165" ),
616
816
BCM7XXX_28NM_GPHY (PHY_ID_BCM7250 , "Broadcom BCM7250" ),
617
817
BCM7XXX_28NM_EPHY (PHY_ID_BCM7255 , "Broadcom BCM7255" ),
618
818
BCM7XXX_28NM_EPHY (PHY_ID_BCM7260 , "Broadcom BCM7260" ),
@@ -635,6 +835,7 @@ static struct phy_driver bcm7xxx_driver[] = {
635
835
static struct mdio_device_id __maybe_unused bcm7xxx_tbl [] = {
636
836
{ PHY_ID_BCM72113 , 0xfffffff0 },
637
837
{ PHY_ID_BCM72116 , 0xfffffff0 , },
838
+ { PHY_ID_BCM72165 , 0xfffffff0 , },
638
839
{ PHY_ID_BCM7250 , 0xfffffff0 , },
639
840
{ PHY_ID_BCM7255 , 0xfffffff0 , },
640
841
{ PHY_ID_BCM7260 , 0xfffffff0 , },
0 commit comments