33
33
#define CTRL_IO_ADDRESS_4B BIT(13) /* AST2400 SPI only */
34
34
#define CTRL_IO_DUMMY_SET (dummy ) \
35
35
(((((dummy) >> 2) & 0x1) << 14) | (((dummy) & 0x3) << 6))
36
+ #define CTRL_FREQ_SEL_SHIFT 8
37
+ #define CTRL_FREQ_SEL_MASK GENMASK(11, CTRL_FREQ_SEL_SHIFT)
36
38
#define CTRL_CE_STOP_ACTIVE BIT(2)
37
39
#define CTRL_IO_MODE_CMD_MASK GENMASK(1, 0)
38
40
#define CTRL_IO_MODE_NORMAL 0x0
45
47
/* CEx Address Decoding Range Register */
46
48
#define CE0_SEGMENT_ADDR_REG 0x30
47
49
50
+ /* CEx Read timing compensation register */
51
+ #define CE0_TIMING_COMPENSATION_REG 0x94
52
+
48
53
enum aspeed_spi_ctl_reg_value {
49
54
ASPEED_SPI_BASE ,
50
55
ASPEED_SPI_READ ,
@@ -70,10 +75,15 @@ struct aspeed_spi_data {
70
75
bool hastype ;
71
76
u32 mode_bits ;
72
77
u32 we0 ;
78
+ u32 timing ;
79
+ u32 hclk_mask ;
80
+ u32 hdiv_max ;
73
81
74
82
u32 (* segment_start )(struct aspeed_spi * aspi , u32 reg );
75
83
u32 (* segment_end )(struct aspeed_spi * aspi , u32 reg );
76
84
u32 (* segment_reg )(struct aspeed_spi * aspi , u32 start , u32 end );
85
+ int (* calibrate )(struct aspeed_spi_chip * chip , u32 hdiv ,
86
+ const u8 * golden_buf , u8 * test_buf );
77
87
};
78
88
79
89
#define ASPEED_SPI_MAX_NUM_CS 5
@@ -525,6 +535,8 @@ static int aspeed_spi_chip_adjust_window(struct aspeed_spi_chip *chip,
525
535
return 0 ;
526
536
}
527
537
538
+ static int aspeed_spi_do_calibration (struct aspeed_spi_chip * chip );
539
+
528
540
static int aspeed_spi_dirmap_create (struct spi_mem_dirmap_desc * desc )
529
541
{
530
542
struct aspeed_spi * aspi = spi_controller_get_devdata (desc -> mem -> spi -> master );
@@ -573,6 +585,8 @@ static int aspeed_spi_dirmap_create(struct spi_mem_dirmap_desc *desc)
573
585
chip -> ctl_val [ASPEED_SPI_READ ] = ctl_val ;
574
586
writel (chip -> ctl_val [ASPEED_SPI_READ ], chip -> ctl );
575
587
588
+ ret = aspeed_spi_do_calibration (chip );
589
+
576
590
dev_info (aspi -> dev , "CE%d read buswidth:%d [0x%08x]\n" ,
577
591
chip -> cs , op -> data .buswidth , chip -> ctl_val [ASPEED_SPI_READ ]);
578
592
@@ -825,6 +839,249 @@ static u32 aspeed_spi_segment_ast2600_reg(struct aspeed_spi *aspi,
825
839
((end - 1 ) & AST2600_SEG_ADDR_MASK );
826
840
}
827
841
842
+ /*
843
+ * Read timing compensation sequences
844
+ */
845
+
846
+ #define CALIBRATE_BUF_SIZE SZ_16K
847
+
848
+ static bool aspeed_spi_check_reads (struct aspeed_spi_chip * chip ,
849
+ const u8 * golden_buf , u8 * test_buf )
850
+ {
851
+ int i ;
852
+
853
+ for (i = 0 ; i < 10 ; i ++ ) {
854
+ memcpy_fromio (test_buf , chip -> ahb_base , CALIBRATE_BUF_SIZE );
855
+ if (memcmp (test_buf , golden_buf , CALIBRATE_BUF_SIZE ) != 0 ) {
856
+ #if defined(VERBOSE_DEBUG )
857
+ print_hex_dump_bytes (DEVICE_NAME " fail: " , DUMP_PREFIX_NONE ,
858
+ test_buf , 0x100 );
859
+ #endif
860
+ return false;
861
+ }
862
+ }
863
+ return true;
864
+ }
865
+
866
+ #define FREAD_TPASS (i ) (((i) / 2) | (((i) & 1) ? 0 : 8))
867
+
868
+ /*
869
+ * The timing register is shared by all devices. Only update for CE0.
870
+ */
871
+ static int aspeed_spi_calibrate (struct aspeed_spi_chip * chip , u32 hdiv ,
872
+ const u8 * golden_buf , u8 * test_buf )
873
+ {
874
+ struct aspeed_spi * aspi = chip -> aspi ;
875
+ const struct aspeed_spi_data * data = aspi -> data ;
876
+ int i ;
877
+ int good_pass = -1 , pass_count = 0 ;
878
+ u32 shift = (hdiv - 1 ) << 2 ;
879
+ u32 mask = ~(0xfu << shift );
880
+ u32 fread_timing_val = 0 ;
881
+
882
+ /* Try HCLK delay 0..5, each one with/without delay and look for a
883
+ * good pair.
884
+ */
885
+ for (i = 0 ; i < 12 ; i ++ ) {
886
+ bool pass ;
887
+
888
+ if (chip -> cs == 0 ) {
889
+ fread_timing_val &= mask ;
890
+ fread_timing_val |= FREAD_TPASS (i ) << shift ;
891
+ writel (fread_timing_val , aspi -> regs + data -> timing );
892
+ }
893
+ pass = aspeed_spi_check_reads (chip , golden_buf , test_buf );
894
+ dev_dbg (aspi -> dev ,
895
+ " * [%08x] %d HCLK delay, %dns DI delay : %s" ,
896
+ fread_timing_val , i / 2 , (i & 1 ) ? 0 : 4 ,
897
+ pass ? "PASS" : "FAIL" );
898
+ if (pass ) {
899
+ pass_count ++ ;
900
+ if (pass_count == 3 ) {
901
+ good_pass = i - 1 ;
902
+ break ;
903
+ }
904
+ } else {
905
+ pass_count = 0 ;
906
+ }
907
+ }
908
+
909
+ /* No good setting for this frequency */
910
+ if (good_pass < 0 )
911
+ return -1 ;
912
+
913
+ /* We have at least one pass of margin, let's use first pass */
914
+ if (chip -> cs == 0 ) {
915
+ fread_timing_val &= mask ;
916
+ fread_timing_val |= FREAD_TPASS (good_pass ) << shift ;
917
+ writel (fread_timing_val , aspi -> regs + data -> timing );
918
+ }
919
+ dev_dbg (aspi -> dev , " * -> good is pass %d [0x%08x]" ,
920
+ good_pass , fread_timing_val );
921
+ return 0 ;
922
+ }
923
+
924
+ static bool aspeed_spi_check_calib_data (const u8 * test_buf , u32 size )
925
+ {
926
+ const u32 * tb32 = (const u32 * )test_buf ;
927
+ u32 i , cnt = 0 ;
928
+
929
+ /* We check if we have enough words that are neither all 0
930
+ * nor all 1's so the calibration can be considered valid.
931
+ *
932
+ * I use an arbitrary threshold for now of 64
933
+ */
934
+ size >>= 2 ;
935
+ for (i = 0 ; i < size ; i ++ ) {
936
+ if (tb32 [i ] != 0 && tb32 [i ] != 0xffffffff )
937
+ cnt ++ ;
938
+ }
939
+ return cnt >= 64 ;
940
+ }
941
+
942
+ static const u32 aspeed_spi_hclk_divs [] = {
943
+ 0xf , /* HCLK */
944
+ 0x7 , /* HCLK/2 */
945
+ 0xe , /* HCLK/3 */
946
+ 0x6 , /* HCLK/4 */
947
+ 0xd , /* HCLK/5 */
948
+ };
949
+
950
+ #define ASPEED_SPI_HCLK_DIV (i ) \
951
+ (aspeed_spi_hclk_divs[(i) - 1] << CTRL_FREQ_SEL_SHIFT)
952
+
953
+ static int aspeed_spi_do_calibration (struct aspeed_spi_chip * chip )
954
+ {
955
+ struct aspeed_spi * aspi = chip -> aspi ;
956
+ const struct aspeed_spi_data * data = aspi -> data ;
957
+ u32 ahb_freq = aspi -> clk_freq ;
958
+ u32 max_freq = chip -> clk_freq ;
959
+ u32 ctl_val ;
960
+ u8 * golden_buf = NULL ;
961
+ u8 * test_buf = NULL ;
962
+ int i , rc , best_div = -1 ;
963
+
964
+ dev_dbg (aspi -> dev , "calculate timing compensation - AHB freq: %d MHz" ,
965
+ ahb_freq / 1000000 );
966
+
967
+ /*
968
+ * use the related low frequency to get check calibration data
969
+ * and get golden data.
970
+ */
971
+ ctl_val = chip -> ctl_val [ASPEED_SPI_READ ] & data -> hclk_mask ;
972
+ writel (ctl_val , chip -> ctl );
973
+
974
+ test_buf = kzalloc (CALIBRATE_BUF_SIZE * 2 , GFP_KERNEL );
975
+ if (!test_buf )
976
+ return - ENOMEM ;
977
+
978
+ golden_buf = test_buf + CALIBRATE_BUF_SIZE ;
979
+
980
+ memcpy_fromio (golden_buf , chip -> ahb_base , CALIBRATE_BUF_SIZE );
981
+ if (!aspeed_spi_check_calib_data (golden_buf , CALIBRATE_BUF_SIZE )) {
982
+ dev_info (aspi -> dev , "Calibration area too uniform, using low speed" );
983
+ goto no_calib ;
984
+ }
985
+
986
+ #if defined(VERBOSE_DEBUG )
987
+ print_hex_dump_bytes (DEVICE_NAME " good: " , DUMP_PREFIX_NONE ,
988
+ golden_buf , 0x100 );
989
+ #endif
990
+
991
+ /* Now we iterate the HCLK dividers until we find our breaking point */
992
+ for (i = ARRAY_SIZE (aspeed_spi_hclk_divs ); i > data -> hdiv_max - 1 ; i -- ) {
993
+ u32 tv , freq ;
994
+
995
+ freq = ahb_freq / i ;
996
+ if (freq > max_freq )
997
+ continue ;
998
+
999
+ /* Set the timing */
1000
+ tv = chip -> ctl_val [ASPEED_SPI_READ ] | ASPEED_SPI_HCLK_DIV (i );
1001
+ writel (tv , chip -> ctl );
1002
+ dev_dbg (aspi -> dev , "Trying HCLK/%d [%08x] ..." , i , tv );
1003
+ rc = data -> calibrate (chip , i , golden_buf , test_buf );
1004
+ if (rc == 0 )
1005
+ best_div = i ;
1006
+ }
1007
+
1008
+ /* Nothing found ? */
1009
+ if (best_div < 0 ) {
1010
+ dev_warn (aspi -> dev , "No good frequency, using dumb slow" );
1011
+ } else {
1012
+ dev_dbg (aspi -> dev , "Found good read timings at HCLK/%d" , best_div );
1013
+
1014
+ /* Record the freq */
1015
+ for (i = 0 ; i < ASPEED_SPI_MAX ; i ++ )
1016
+ chip -> ctl_val [i ] = (chip -> ctl_val [i ] & data -> hclk_mask ) |
1017
+ ASPEED_SPI_HCLK_DIV (best_div );
1018
+ }
1019
+
1020
+ no_calib :
1021
+ writel (chip -> ctl_val [ASPEED_SPI_READ ], chip -> ctl );
1022
+ kfree (test_buf );
1023
+ return 0 ;
1024
+ }
1025
+
1026
+ #define TIMING_DELAY_DI BIT(3)
1027
+ #define TIMING_DELAY_HCYCLE_MAX 5
1028
+ #define TIMING_REG_AST2600 (chip ) \
1029
+ ((chip)->aspi->regs + (chip)->aspi->data->timing + \
1030
+ (chip)->cs * 4)
1031
+
1032
+ static int aspeed_spi_ast2600_calibrate (struct aspeed_spi_chip * chip , u32 hdiv ,
1033
+ const u8 * golden_buf , u8 * test_buf )
1034
+ {
1035
+ struct aspeed_spi * aspi = chip -> aspi ;
1036
+ int hcycle ;
1037
+ u32 shift = (hdiv - 2 ) << 3 ;
1038
+ u32 mask = ~(0xfu << shift );
1039
+ u32 fread_timing_val = 0 ;
1040
+
1041
+ for (hcycle = 0 ; hcycle <= TIMING_DELAY_HCYCLE_MAX ; hcycle ++ ) {
1042
+ int delay_ns ;
1043
+ bool pass = false;
1044
+
1045
+ fread_timing_val &= mask ;
1046
+ fread_timing_val |= hcycle << shift ;
1047
+
1048
+ /* no DI input delay first */
1049
+ writel (fread_timing_val , TIMING_REG_AST2600 (chip ));
1050
+ pass = aspeed_spi_check_reads (chip , golden_buf , test_buf );
1051
+ dev_dbg (aspi -> dev ,
1052
+ " * [%08x] %d HCLK delay, DI delay none : %s" ,
1053
+ fread_timing_val , hcycle , pass ? "PASS" : "FAIL" );
1054
+ if (pass )
1055
+ return 0 ;
1056
+
1057
+ /* Add DI input delays */
1058
+ fread_timing_val &= mask ;
1059
+ fread_timing_val |= (TIMING_DELAY_DI | hcycle ) << shift ;
1060
+
1061
+ for (delay_ns = 0 ; delay_ns < 0x10 ; delay_ns ++ ) {
1062
+ fread_timing_val &= ~(0xf << (4 + shift ));
1063
+ fread_timing_val |= delay_ns << (4 + shift );
1064
+
1065
+ writel (fread_timing_val , TIMING_REG_AST2600 (chip ));
1066
+ pass = aspeed_spi_check_reads (chip , golden_buf , test_buf );
1067
+ dev_dbg (aspi -> dev ,
1068
+ " * [%08x] %d HCLK delay, DI delay %d.%dns : %s" ,
1069
+ fread_timing_val , hcycle , (delay_ns + 1 ) / 2 ,
1070
+ (delay_ns + 1 ) & 1 ? 5 : 5 , pass ? "PASS" : "FAIL" );
1071
+ /*
1072
+ * TODO: This is optimistic. We should look
1073
+ * for a working interval and save the middle
1074
+ * value in the read timing register.
1075
+ */
1076
+ if (pass )
1077
+ return 0 ;
1078
+ }
1079
+ }
1080
+
1081
+ /* No good setting for this frequency */
1082
+ return -1 ;
1083
+ }
1084
+
828
1085
/*
829
1086
* Platform definitions
830
1087
*/
@@ -833,6 +1090,10 @@ static const struct aspeed_spi_data ast2400_fmc_data = {
833
1090
.hastype = true,
834
1091
.we0 = 16 ,
835
1092
.ctl0 = CE0_CTRL_REG ,
1093
+ .timing = CE0_TIMING_COMPENSATION_REG ,
1094
+ .hclk_mask = 0xfffff0ff ,
1095
+ .hdiv_max = 1 ,
1096
+ .calibrate = aspeed_spi_calibrate ,
836
1097
.segment_start = aspeed_spi_segment_start ,
837
1098
.segment_end = aspeed_spi_segment_end ,
838
1099
.segment_reg = aspeed_spi_segment_reg ,
@@ -843,6 +1104,10 @@ static const struct aspeed_spi_data ast2400_spi_data = {
843
1104
.hastype = false,
844
1105
.we0 = 0 ,
845
1106
.ctl0 = 0x04 ,
1107
+ .timing = 0x14 ,
1108
+ .hclk_mask = 0xfffff0ff ,
1109
+ .hdiv_max = 1 ,
1110
+ .calibrate = aspeed_spi_calibrate ,
846
1111
/* No segment registers */
847
1112
};
848
1113
@@ -851,6 +1116,10 @@ static const struct aspeed_spi_data ast2500_fmc_data = {
851
1116
.hastype = true,
852
1117
.we0 = 16 ,
853
1118
.ctl0 = CE0_CTRL_REG ,
1119
+ .timing = CE0_TIMING_COMPENSATION_REG ,
1120
+ .hclk_mask = 0xffffd0ff ,
1121
+ .hdiv_max = 1 ,
1122
+ .calibrate = aspeed_spi_calibrate ,
854
1123
.segment_start = aspeed_spi_segment_start ,
855
1124
.segment_end = aspeed_spi_segment_end ,
856
1125
.segment_reg = aspeed_spi_segment_reg ,
@@ -861,6 +1130,10 @@ static const struct aspeed_spi_data ast2500_spi_data = {
861
1130
.hastype = false,
862
1131
.we0 = 16 ,
863
1132
.ctl0 = CE0_CTRL_REG ,
1133
+ .timing = CE0_TIMING_COMPENSATION_REG ,
1134
+ .hclk_mask = 0xffffd0ff ,
1135
+ .hdiv_max = 1 ,
1136
+ .calibrate = aspeed_spi_calibrate ,
864
1137
.segment_start = aspeed_spi_segment_start ,
865
1138
.segment_end = aspeed_spi_segment_end ,
866
1139
.segment_reg = aspeed_spi_segment_reg ,
@@ -872,6 +1145,10 @@ static const struct aspeed_spi_data ast2600_fmc_data = {
872
1145
.mode_bits = SPI_RX_QUAD | SPI_RX_QUAD ,
873
1146
.we0 = 16 ,
874
1147
.ctl0 = CE0_CTRL_REG ,
1148
+ .timing = CE0_TIMING_COMPENSATION_REG ,
1149
+ .hclk_mask = 0xf0fff0ff ,
1150
+ .hdiv_max = 2 ,
1151
+ .calibrate = aspeed_spi_ast2600_calibrate ,
875
1152
.segment_start = aspeed_spi_segment_ast2600_start ,
876
1153
.segment_end = aspeed_spi_segment_ast2600_end ,
877
1154
.segment_reg = aspeed_spi_segment_ast2600_reg ,
@@ -883,6 +1160,10 @@ static const struct aspeed_spi_data ast2600_spi_data = {
883
1160
.mode_bits = SPI_RX_QUAD | SPI_RX_QUAD ,
884
1161
.we0 = 16 ,
885
1162
.ctl0 = CE0_CTRL_REG ,
1163
+ .timing = CE0_TIMING_COMPENSATION_REG ,
1164
+ .hclk_mask = 0xf0fff0ff ,
1165
+ .hdiv_max = 2 ,
1166
+ .calibrate = aspeed_spi_ast2600_calibrate ,
886
1167
.segment_start = aspeed_spi_segment_ast2600_start ,
887
1168
.segment_end = aspeed_spi_segment_ast2600_end ,
888
1169
.segment_reg = aspeed_spi_segment_ast2600_reg ,
0 commit comments