34
34
#define PCI_VENDOR_ID_OROLIA 0x1ad7
35
35
#define PCI_DEVICE_ID_OROLIA_ARTCARD 0xa000
36
36
37
+ #define PCI_VENDOR_ID_ADVA 0xad5a
38
+ #define PCI_DEVICE_ID_ADVA_TIMECARD 0x0400
39
+
37
40
static struct class timecard_class = {
38
41
.name = "timecard" ,
39
42
};
@@ -63,6 +66,13 @@ struct ocp_reg {
63
66
u32 status_drift ;
64
67
};
65
68
69
+ struct ptp_ocp_servo_conf {
70
+ u32 servo_offset_p ;
71
+ u32 servo_offset_i ;
72
+ u32 servo_drift_p ;
73
+ u32 servo_drift_i ;
74
+ };
75
+
66
76
#define OCP_CTRL_ENABLE BIT(0)
67
77
#define OCP_CTRL_ADJUST_TIME BIT(1)
68
78
#define OCP_CTRL_ADJUST_OFFSET BIT(2)
@@ -397,10 +407,14 @@ static int ptp_ocp_sma_store(struct ptp_ocp *bp, const char *buf, int sma_nr);
397
407
398
408
static int ptp_ocp_art_board_init (struct ptp_ocp * bp , struct ocp_resource * r );
399
409
410
+ static int ptp_ocp_adva_board_init (struct ptp_ocp * bp , struct ocp_resource * r );
411
+
400
412
static const struct ocp_attr_group fb_timecard_groups [];
401
413
402
414
static const struct ocp_attr_group art_timecard_groups [];
403
415
416
+ static const struct ocp_attr_group adva_timecard_groups [];
417
+
404
418
struct ptp_ocp_eeprom_map {
405
419
u16 off ;
406
420
u16 len ;
@@ -700,6 +714,12 @@ static struct ocp_resource ocp_fb_resource[] = {
700
714
},
701
715
{
702
716
.setup = ptp_ocp_fb_board_init ,
717
+ .extra = & (struct ptp_ocp_servo_conf ) {
718
+ .servo_offset_p = 0x2000 ,
719
+ .servo_offset_i = 0x1000 ,
720
+ .servo_drift_p = 0 ,
721
+ .servo_drift_i = 0 ,
722
+ },
703
723
},
704
724
{ }
705
725
};
@@ -831,6 +851,170 @@ static struct ocp_resource ocp_art_resource[] = {
831
851
},
832
852
{
833
853
.setup = ptp_ocp_art_board_init ,
854
+ .extra = & (struct ptp_ocp_servo_conf ) {
855
+ .servo_offset_p = 0x2000 ,
856
+ .servo_offset_i = 0x1000 ,
857
+ .servo_drift_p = 0 ,
858
+ .servo_drift_i = 0 ,
859
+ },
860
+ },
861
+ { }
862
+ };
863
+
864
+ static struct ocp_resource ocp_adva_resource [] = {
865
+ {
866
+ OCP_MEM_RESOURCE (reg ),
867
+ .offset = 0x01000000 , .size = 0x10000 ,
868
+ },
869
+ {
870
+ OCP_EXT_RESOURCE (ts0 ),
871
+ .offset = 0x01010000 , .size = 0x10000 , .irq_vec = 1 ,
872
+ .extra = & (struct ptp_ocp_ext_info ) {
873
+ .index = 0 ,
874
+ .irq_fcn = ptp_ocp_ts_irq ,
875
+ .enable = ptp_ocp_ts_enable ,
876
+ },
877
+ },
878
+ {
879
+ OCP_EXT_RESOURCE (ts1 ),
880
+ .offset = 0x01020000 , .size = 0x10000 , .irq_vec = 2 ,
881
+ .extra = & (struct ptp_ocp_ext_info ) {
882
+ .index = 1 ,
883
+ .irq_fcn = ptp_ocp_ts_irq ,
884
+ .enable = ptp_ocp_ts_enable ,
885
+ },
886
+ },
887
+ {
888
+ OCP_EXT_RESOURCE (ts2 ),
889
+ .offset = 0x01060000 , .size = 0x10000 , .irq_vec = 6 ,
890
+ .extra = & (struct ptp_ocp_ext_info ) {
891
+ .index = 2 ,
892
+ .irq_fcn = ptp_ocp_ts_irq ,
893
+ .enable = ptp_ocp_ts_enable ,
894
+ },
895
+ },
896
+ /* Timestamp for PHC and/or PPS generator */
897
+ {
898
+ OCP_EXT_RESOURCE (pps ),
899
+ .offset = 0x010C0000 , .size = 0x10000 , .irq_vec = 0 ,
900
+ .extra = & (struct ptp_ocp_ext_info ) {
901
+ .index = 5 ,
902
+ .irq_fcn = ptp_ocp_ts_irq ,
903
+ .enable = ptp_ocp_ts_enable ,
904
+ },
905
+ },
906
+ {
907
+ OCP_EXT_RESOURCE (signal_out [0 ]),
908
+ .offset = 0x010D0000 , .size = 0x10000 , .irq_vec = 11 ,
909
+ .extra = & (struct ptp_ocp_ext_info ) {
910
+ .index = 1 ,
911
+ .irq_fcn = ptp_ocp_signal_irq ,
912
+ .enable = ptp_ocp_signal_enable ,
913
+ },
914
+ },
915
+ {
916
+ OCP_EXT_RESOURCE (signal_out [1 ]),
917
+ .offset = 0x010E0000 , .size = 0x10000 , .irq_vec = 12 ,
918
+ .extra = & (struct ptp_ocp_ext_info ) {
919
+ .index = 2 ,
920
+ .irq_fcn = ptp_ocp_signal_irq ,
921
+ .enable = ptp_ocp_signal_enable ,
922
+ },
923
+ },
924
+ {
925
+ OCP_MEM_RESOURCE (pps_to_ext ),
926
+ .offset = 0x01030000 , .size = 0x10000 ,
927
+ },
928
+ {
929
+ OCP_MEM_RESOURCE (pps_to_clk ),
930
+ .offset = 0x01040000 , .size = 0x10000 ,
931
+ },
932
+ {
933
+ OCP_MEM_RESOURCE (tod ),
934
+ .offset = 0x01050000 , .size = 0x10000 ,
935
+ },
936
+ {
937
+ OCP_MEM_RESOURCE (image ),
938
+ .offset = 0x00020000 , .size = 0x1000 ,
939
+ },
940
+ {
941
+ OCP_MEM_RESOURCE (pps_select ),
942
+ .offset = 0x00130000 , .size = 0x1000 ,
943
+ },
944
+ {
945
+ OCP_MEM_RESOURCE (sma_map1 ),
946
+ .offset = 0x00140000 , .size = 0x1000 ,
947
+ },
948
+ {
949
+ OCP_MEM_RESOURCE (sma_map2 ),
950
+ .offset = 0x00220000 , .size = 0x1000 ,
951
+ },
952
+ {
953
+ OCP_SERIAL_RESOURCE (gnss_port ),
954
+ .offset = 0x00160000 + 0x1000 , .irq_vec = 3 ,
955
+ .extra = & (struct ptp_ocp_serial_port ) {
956
+ .baud = 9600 ,
957
+ },
958
+ },
959
+ {
960
+ OCP_SERIAL_RESOURCE (mac_port ),
961
+ .offset = 0x00180000 + 0x1000 , .irq_vec = 5 ,
962
+ .extra = & (struct ptp_ocp_serial_port ) {
963
+ .baud = 115200 ,
964
+ },
965
+ },
966
+ {
967
+ OCP_MEM_RESOURCE (freq_in [0 ]),
968
+ .offset = 0x01200000 , .size = 0x10000 ,
969
+ },
970
+ {
971
+ OCP_MEM_RESOURCE (freq_in [1 ]),
972
+ .offset = 0x01210000 , .size = 0x10000 ,
973
+ },
974
+ {
975
+ OCP_SPI_RESOURCE (spi_flash ),
976
+ .offset = 0x00310400 , .size = 0x10000 , .irq_vec = 9 ,
977
+ .extra = & (struct ptp_ocp_flash_info ) {
978
+ .name = "spi_altera" , .pci_offset = 0 ,
979
+ .data_size = sizeof (struct altera_spi_platform_data ),
980
+ .data = & (struct altera_spi_platform_data ) {
981
+ .num_chipselect = 1 ,
982
+ .num_devices = 1 ,
983
+ .devices = & (struct spi_board_info ) {
984
+ .modalias = "spi-nor" ,
985
+ },
986
+ },
987
+ },
988
+ },
989
+ {
990
+ OCP_I2C_RESOURCE (i2c_ctrl ),
991
+ .offset = 0x150000 , .size = 0x100 , .irq_vec = 7 ,
992
+ .extra = & (struct ptp_ocp_i2c_info ) {
993
+ .name = "ocores-i2c" ,
994
+ .fixed_rate = 50000000 ,
995
+ .data_size = sizeof (struct ocores_i2c_platform_data ),
996
+ .data = & (struct ocores_i2c_platform_data ) {
997
+ .clock_khz = 50000 ,
998
+ .bus_khz = 100 ,
999
+ .reg_io_width = 4 , // 32-bit/4-byte
1000
+ .reg_shift = 2 , // 32-bit addressing
1001
+ .num_devices = 2 ,
1002
+ .devices = (struct i2c_board_info []) {
1003
+ { I2C_BOARD_INFO ("24c02" , 0x50 ) },
1004
+ { I2C_BOARD_INFO ("24mac402" , 0x58 ),
1005
+ .platform_data = "mac" },
1006
+ },
1007
+ },
1008
+ },
1009
+ },
1010
+ {
1011
+ .setup = ptp_ocp_adva_board_init ,
1012
+ .extra = & (struct ptp_ocp_servo_conf ) {
1013
+ .servo_offset_p = 0xc000 ,
1014
+ .servo_offset_i = 0x1000 ,
1015
+ .servo_drift_p = 0 ,
1016
+ .servo_drift_i = 0 ,
1017
+ },
834
1018
},
835
1019
{ }
836
1020
};
@@ -839,6 +1023,7 @@ static const struct pci_device_id ptp_ocp_pcidev_id[] = {
839
1023
{ PCI_DEVICE_DATA (FACEBOOK , TIMECARD , & ocp_fb_resource ) },
840
1024
{ PCI_DEVICE_DATA (CELESTICA , TIMECARD , & ocp_fb_resource ) },
841
1025
{ PCI_DEVICE_DATA (OROLIA , ARTCARD , & ocp_art_resource ) },
1026
+ { PCI_DEVICE_DATA (ADVA , TIMECARD , & ocp_adva_resource ) },
842
1027
{ }
843
1028
};
844
1029
MODULE_DEVICE_TABLE (pci , ptp_ocp_pcidev_id );
@@ -917,6 +1102,30 @@ static const struct ocp_selector ptp_ocp_art_sma_out[] = {
917
1102
{ }
918
1103
};
919
1104
1105
+ static const struct ocp_selector ptp_ocp_adva_sma_in [] = {
1106
+ { .name = "10Mhz" , .value = 0x0000 , .frequency = 10000000 },
1107
+ { .name = "PPS1" , .value = 0x0001 , .frequency = 1 },
1108
+ { .name = "PPS2" , .value = 0x0002 , .frequency = 1 },
1109
+ { .name = "TS1" , .value = 0x0004 , .frequency = 0 },
1110
+ { .name = "TS2" , .value = 0x0008 , .frequency = 0 },
1111
+ { .name = "FREQ1" , .value = 0x0100 , .frequency = 0 },
1112
+ { .name = "FREQ2" , .value = 0x0200 , .frequency = 0 },
1113
+ { .name = "None" , .value = SMA_DISABLE , .frequency = 0 },
1114
+ { }
1115
+ };
1116
+
1117
+ static const struct ocp_selector ptp_ocp_adva_sma_out [] = {
1118
+ { .name = "10Mhz" , .value = 0x0000 , .frequency = 10000000 },
1119
+ { .name = "PHC" , .value = 0x0001 , .frequency = 1 },
1120
+ { .name = "MAC" , .value = 0x0002 , .frequency = 1 },
1121
+ { .name = "GNSS1" , .value = 0x0004 , .frequency = 1 },
1122
+ { .name = "GEN1" , .value = 0x0040 },
1123
+ { .name = "GEN2" , .value = 0x0080 },
1124
+ { .name = "GND" , .value = 0x2000 },
1125
+ { .name = "VCC" , .value = 0x4000 },
1126
+ { }
1127
+ };
1128
+
920
1129
struct ocp_sma_op {
921
1130
const struct ocp_selector * tbl [2 ];
922
1131
void (* init )(struct ptp_ocp * bp );
@@ -1363,20 +1572,19 @@ ptp_ocp_estimate_pci_timing(struct ptp_ocp *bp)
1363
1572
}
1364
1573
1365
1574
static int
1366
- ptp_ocp_init_clock (struct ptp_ocp * bp )
1575
+ ptp_ocp_init_clock (struct ptp_ocp * bp , struct ptp_ocp_servo_conf * servo_conf )
1367
1576
{
1368
1577
struct timespec64 ts ;
1369
1578
u32 ctrl ;
1370
1579
1371
1580
ctrl = OCP_CTRL_ENABLE ;
1372
1581
iowrite32 (ctrl , & bp -> reg -> ctrl );
1373
1582
1374
- /* NO DRIFT Correction */
1375
- /* offset_p:i 1/8, offset_i: 1/16, drift_p: 0, drift_i: 0 */
1376
- iowrite32 (0x2000 , & bp -> reg -> servo_offset_p );
1377
- iowrite32 (0x1000 , & bp -> reg -> servo_offset_i );
1378
- iowrite32 (0 , & bp -> reg -> servo_drift_p );
1379
- iowrite32 (0 , & bp -> reg -> servo_drift_i );
1583
+ /* servo configuration */
1584
+ iowrite32 (servo_conf -> servo_offset_p , & bp -> reg -> servo_offset_p );
1585
+ iowrite32 (servo_conf -> servo_offset_i , & bp -> reg -> servo_offset_i );
1586
+ iowrite32 (servo_conf -> servo_drift_p , & bp -> reg -> servo_drift_p );
1587
+ iowrite32 (servo_conf -> servo_drift_p , & bp -> reg -> servo_drift_i );
1380
1588
1381
1589
/* latch servo values */
1382
1590
ctrl |= OCP_CTRL_ADJUST_SERVO ;
@@ -2348,6 +2556,14 @@ static const struct ocp_sma_op ocp_fb_sma_op = {
2348
2556
.set_output = ptp_ocp_sma_fb_set_output ,
2349
2557
};
2350
2558
2559
+ static const struct ocp_sma_op ocp_adva_sma_op = {
2560
+ .tbl = { ptp_ocp_adva_sma_in , ptp_ocp_adva_sma_out },
2561
+ .init = ptp_ocp_sma_fb_init ,
2562
+ .get = ptp_ocp_sma_fb_get ,
2563
+ .set_inputs = ptp_ocp_sma_fb_set_inputs ,
2564
+ .set_output = ptp_ocp_sma_fb_set_output ,
2565
+ };
2566
+
2351
2567
static int
2352
2568
ptp_ocp_set_pins (struct ptp_ocp * bp )
2353
2569
{
@@ -2427,7 +2643,7 @@ ptp_ocp_fb_board_init(struct ptp_ocp *bp, struct ocp_resource *r)
2427
2643
return err ;
2428
2644
ptp_ocp_sma_init (bp );
2429
2645
2430
- return ptp_ocp_init_clock (bp );
2646
+ return ptp_ocp_init_clock (bp , r -> extra );
2431
2647
}
2432
2648
2433
2649
static bool
@@ -2589,7 +2805,44 @@ ptp_ocp_art_board_init(struct ptp_ocp *bp, struct ocp_resource *r)
2589
2805
if (err )
2590
2806
return err ;
2591
2807
2592
- return ptp_ocp_init_clock (bp );
2808
+ return ptp_ocp_init_clock (bp , r -> extra );
2809
+ }
2810
+
2811
+ /* ADVA specific board initializers; last "resource" registered. */
2812
+ static int
2813
+ ptp_ocp_adva_board_init (struct ptp_ocp * bp , struct ocp_resource * r )
2814
+ {
2815
+ int err ;
2816
+ u32 version ;
2817
+
2818
+ bp -> flash_start = 0xA00000 ;
2819
+ bp -> eeprom_map = fb_eeprom_map ;
2820
+ bp -> sma_op = & ocp_adva_sma_op ;
2821
+
2822
+ version = ioread32 (& bp -> image -> version );
2823
+ /* if lower 16 bits are empty, this is the fw loader. */
2824
+ if ((version & 0xffff ) == 0 ) {
2825
+ version = version >> 16 ;
2826
+ bp -> fw_loader = true;
2827
+ }
2828
+ bp -> fw_tag = 3 ;
2829
+ bp -> fw_version = version & 0xffff ;
2830
+ bp -> fw_cap = OCP_CAP_BASIC | OCP_CAP_SIGNAL | OCP_CAP_FREQ ;
2831
+
2832
+ ptp_ocp_tod_init (bp );
2833
+ ptp_ocp_nmea_out_init (bp );
2834
+ ptp_ocp_signal_init (bp );
2835
+
2836
+ err = ptp_ocp_attr_group_add (bp , adva_timecard_groups );
2837
+ if (err )
2838
+ return err ;
2839
+
2840
+ err = ptp_ocp_set_pins (bp );
2841
+ if (err )
2842
+ return err ;
2843
+ ptp_ocp_sma_init (bp );
2844
+
2845
+ return ptp_ocp_init_clock (bp , r -> extra );
2593
2846
}
2594
2847
2595
2848
static ssize_t
@@ -3564,6 +3817,37 @@ static const struct ocp_attr_group art_timecard_groups[] = {
3564
3817
{ },
3565
3818
};
3566
3819
3820
+ static struct attribute * adva_timecard_attrs [] = {
3821
+ & dev_attr_serialnum .attr ,
3822
+ & dev_attr_gnss_sync .attr ,
3823
+ & dev_attr_clock_source .attr ,
3824
+ & dev_attr_available_clock_sources .attr ,
3825
+ & dev_attr_sma1 .attr ,
3826
+ & dev_attr_sma2 .attr ,
3827
+ & dev_attr_sma3 .attr ,
3828
+ & dev_attr_sma4 .attr ,
3829
+ & dev_attr_available_sma_inputs .attr ,
3830
+ & dev_attr_available_sma_outputs .attr ,
3831
+ & dev_attr_clock_status_drift .attr ,
3832
+ & dev_attr_clock_status_offset .attr ,
3833
+ & dev_attr_ts_window_adjust .attr ,
3834
+ & dev_attr_tod_correction .attr ,
3835
+ NULL ,
3836
+ };
3837
+
3838
+ static const struct attribute_group adva_timecard_group = {
3839
+ .attrs = adva_timecard_attrs ,
3840
+ };
3841
+
3842
+ static const struct ocp_attr_group adva_timecard_groups [] = {
3843
+ { .cap = OCP_CAP_BASIC , .group = & adva_timecard_group },
3844
+ { .cap = OCP_CAP_SIGNAL , .group = & fb_timecard_signal0_group },
3845
+ { .cap = OCP_CAP_SIGNAL , .group = & fb_timecard_signal1_group },
3846
+ { .cap = OCP_CAP_FREQ , .group = & fb_timecard_freq0_group },
3847
+ { .cap = OCP_CAP_FREQ , .group = & fb_timecard_freq1_group },
3848
+ { },
3849
+ };
3850
+
3567
3851
static void
3568
3852
gpio_input_map (char * buf , struct ptp_ocp * bp , u16 map [][2 ], u16 bit ,
3569
3853
const char * def )
0 commit comments