15
15
#include "dw_mmc.h"
16
16
#include "dw_mmc-pltfm.h"
17
17
18
- #define RK3288_CLKGEN_DIV 2
18
+ #define RK3288_CLKGEN_DIV 2
19
+ #define SDMMC_TIMING_CON0 0x130
20
+ #define SDMMC_TIMING_CON1 0x134
21
+ #define ROCKCHIP_MMC_DELAY_SEL BIT(10)
22
+ #define ROCKCHIP_MMC_DEGREE_MASK 0x3
23
+ #define ROCKCHIP_MMC_DEGREE_OFFSET 1
24
+ #define ROCKCHIP_MMC_DELAYNUM_OFFSET 2
25
+ #define ROCKCHIP_MMC_DELAYNUM_MASK (0xff << ROCKCHIP_MMC_DELAYNUM_OFFSET)
26
+ #define ROCKCHIP_MMC_DELAY_ELEMENT_PSEC 60
27
+ #define HIWORD_UPDATE (val , mask , shift ) \
28
+ ((val) << (shift) | (mask) << ((shift) + 16))
19
29
20
30
static const unsigned int freqs [] = { 100000 , 200000 , 300000 , 400000 };
21
31
@@ -24,8 +34,143 @@ struct dw_mci_rockchip_priv_data {
24
34
struct clk * sample_clk ;
25
35
int default_sample_phase ;
26
36
int num_phases ;
37
+ bool internal_phase ;
27
38
};
28
39
40
+ /*
41
+ * Each fine delay is between 44ps-77ps. Assume each fine delay is 60ps to
42
+ * simplify calculations. So 45degs could be anywhere between 33deg and 57.8deg.
43
+ */
44
+ static int rockchip_mmc_get_internal_phase (struct dw_mci * host , bool sample )
45
+ {
46
+ unsigned long rate = clk_get_rate (host -> ciu_clk );
47
+ u32 raw_value ;
48
+ u16 degrees ;
49
+ u32 delay_num = 0 ;
50
+
51
+ /* Constant signal, no measurable phase shift */
52
+ if (!rate )
53
+ return 0 ;
54
+
55
+ if (sample )
56
+ raw_value = mci_readl (host , TIMING_CON1 );
57
+ else
58
+ raw_value = mci_readl (host , TIMING_CON0 );
59
+
60
+ raw_value >>= ROCKCHIP_MMC_DEGREE_OFFSET ;
61
+ degrees = (raw_value & ROCKCHIP_MMC_DEGREE_MASK ) * 90 ;
62
+
63
+ if (raw_value & ROCKCHIP_MMC_DELAY_SEL ) {
64
+ /* degrees/delaynum * 1000000 */
65
+ unsigned long factor = (ROCKCHIP_MMC_DELAY_ELEMENT_PSEC / 10 ) *
66
+ 36 * (rate / 10000 );
67
+
68
+ delay_num = (raw_value & ROCKCHIP_MMC_DELAYNUM_MASK );
69
+ delay_num >>= ROCKCHIP_MMC_DELAYNUM_OFFSET ;
70
+ degrees += DIV_ROUND_CLOSEST (delay_num * factor , 1000000 );
71
+ }
72
+
73
+ return degrees % 360 ;
74
+ }
75
+
76
+ static int rockchip_mmc_get_phase (struct dw_mci * host , bool sample )
77
+ {
78
+ struct dw_mci_rockchip_priv_data * priv = host -> priv ;
79
+ struct clk * clock = sample ? priv -> sample_clk : priv -> drv_clk ;
80
+
81
+ if (priv -> internal_phase )
82
+ return rockchip_mmc_get_internal_phase (host , sample );
83
+ else
84
+ return clk_get_phase (clock );
85
+ }
86
+
87
+ static int rockchip_mmc_set_internal_phase (struct dw_mci * host , bool sample , int degrees )
88
+ {
89
+ unsigned long rate = clk_get_rate (host -> ciu_clk );
90
+ u8 nineties , remainder ;
91
+ u8 delay_num ;
92
+ u32 raw_value ;
93
+ u32 delay ;
94
+
95
+ /*
96
+ * The below calculation is based on the output clock from
97
+ * MMC host to the card, which expects the phase clock inherits
98
+ * the clock rate from its parent, namely the output clock
99
+ * provider of MMC host. However, things may go wrong if
100
+ * (1) It is orphan.
101
+ * (2) It is assigned to the wrong parent.
102
+ *
103
+ * This check help debug the case (1), which seems to be the
104
+ * most likely problem we often face and which makes it difficult
105
+ * for people to debug unstable mmc tuning results.
106
+ */
107
+ if (!rate ) {
108
+ dev_err (host -> dev , "%s: invalid clk rate\n" , __func__ );
109
+ return - EINVAL ;
110
+ }
111
+
112
+ nineties = degrees / 90 ;
113
+ remainder = (degrees % 90 );
114
+
115
+ /*
116
+ * Due to the inexact nature of the "fine" delay, we might
117
+ * actually go non-monotonic. We don't go _too_ monotonic
118
+ * though, so we should be OK. Here are options of how we may
119
+ * work:
120
+ *
121
+ * Ideally we end up with:
122
+ * 1.0, 2.0, ..., 69.0, 70.0, ..., 89.0, 90.0
123
+ *
124
+ * On one extreme (if delay is actually 44ps):
125
+ * .73, 1.5, ..., 50.6, 51.3, ..., 65.3, 90.0
126
+ * The other (if delay is actually 77ps):
127
+ * 1.3, 2.6, ..., 88.6. 89.8, ..., 114.0, 90
128
+ *
129
+ * It's possible we might make a delay that is up to 25
130
+ * degrees off from what we think we're making. That's OK
131
+ * though because we should be REALLY far from any bad range.
132
+ */
133
+
134
+ /*
135
+ * Convert to delay; do a little extra work to make sure we
136
+ * don't overflow 32-bit / 64-bit numbers.
137
+ */
138
+ delay = 10000000 ; /* PSECS_PER_SEC / 10000 / 10 */
139
+ delay *= remainder ;
140
+ delay = DIV_ROUND_CLOSEST (delay ,
141
+ (rate / 1000 ) * 36 *
142
+ (ROCKCHIP_MMC_DELAY_ELEMENT_PSEC / 10 ));
143
+
144
+ delay_num = (u8 ) min_t (u32 , delay , 255 );
145
+
146
+ raw_value = delay_num ? ROCKCHIP_MMC_DELAY_SEL : 0 ;
147
+ raw_value |= delay_num << ROCKCHIP_MMC_DELAYNUM_OFFSET ;
148
+ raw_value |= nineties ;
149
+
150
+ if (sample )
151
+ mci_writel (host , TIMING_CON1 , HIWORD_UPDATE (raw_value , 0x07ff , 1 ));
152
+ else
153
+ mci_writel (host , TIMING_CON0 , HIWORD_UPDATE (raw_value , 0x07ff , 1 ));
154
+
155
+ dev_dbg (host -> dev , "set %s_phase(%d) delay_nums=%u actual_degrees=%d\n" ,
156
+ sample ? "sample" : "drv" , degrees , delay_num ,
157
+ rockchip_mmc_get_phase (host , sample )
158
+ );
159
+
160
+ return 0 ;
161
+ }
162
+
163
+ static int rockchip_mmc_set_phase (struct dw_mci * host , bool sample , int degrees )
164
+ {
165
+ struct dw_mci_rockchip_priv_data * priv = host -> priv ;
166
+ struct clk * clock = sample ? priv -> sample_clk : priv -> drv_clk ;
167
+
168
+ if (priv -> internal_phase )
169
+ return rockchip_mmc_set_internal_phase (host , sample , degrees );
170
+ else
171
+ return clk_set_phase (clock , degrees );
172
+ }
173
+
29
174
static void dw_mci_rk3288_set_ios (struct dw_mci * host , struct mmc_ios * ios )
30
175
{
31
176
struct dw_mci_rockchip_priv_data * priv = host -> priv ;
@@ -64,7 +209,7 @@ static void dw_mci_rk3288_set_ios(struct dw_mci *host, struct mmc_ios *ios)
64
209
65
210
/* Make sure we use phases which we can enumerate with */
66
211
if (!IS_ERR (priv -> sample_clk ) && ios -> timing <= MMC_TIMING_SD_HS )
67
- clk_set_phase ( priv -> sample_clk , priv -> default_sample_phase );
212
+ rockchip_mmc_set_phase ( host , true , priv -> default_sample_phase );
68
213
69
214
/*
70
215
* Set the drive phase offset based on speed mode to achieve hold times.
@@ -127,7 +272,7 @@ static void dw_mci_rk3288_set_ios(struct dw_mci *host, struct mmc_ios *ios)
127
272
break ;
128
273
}
129
274
130
- clk_set_phase ( priv -> drv_clk , phase );
275
+ rockchip_mmc_set_phase ( host , false , phase );
131
276
}
132
277
}
133
278
@@ -151,6 +296,7 @@ static int dw_mci_rk3288_execute_tuning(struct dw_mci_slot *slot, u32 opcode)
151
296
int longest_range_len = -1 ;
152
297
int longest_range = -1 ;
153
298
int middle_phase ;
299
+ int phase ;
154
300
155
301
if (IS_ERR (priv -> sample_clk )) {
156
302
dev_err (host -> dev , "Tuning clock (sample_clk) not defined.\n" );
@@ -164,8 +310,10 @@ static int dw_mci_rk3288_execute_tuning(struct dw_mci_slot *slot, u32 opcode)
164
310
165
311
/* Try each phase and extract good ranges */
166
312
for (i = 0 ; i < priv -> num_phases ; ) {
167
- clk_set_phase (priv -> sample_clk ,
168
- TUNING_ITERATION_TO_PHASE (i , priv -> num_phases ));
313
+ rockchip_mmc_set_phase (host , true,
314
+ TUNING_ITERATION_TO_PHASE (
315
+ i ,
316
+ priv -> num_phases ));
169
317
170
318
v = !mmc_send_tuning (mmc , opcode , NULL );
171
319
@@ -211,7 +359,8 @@ static int dw_mci_rk3288_execute_tuning(struct dw_mci_slot *slot, u32 opcode)
211
359
}
212
360
213
361
if (ranges [0 ].start == 0 && ranges [0 ].end == priv -> num_phases - 1 ) {
214
- clk_set_phase (priv -> sample_clk , priv -> default_sample_phase );
362
+ rockchip_mmc_set_phase (host , true, priv -> default_sample_phase );
363
+
215
364
dev_info (host -> dev , "All phases work, using default phase %d." ,
216
365
priv -> default_sample_phase );
217
366
goto free ;
@@ -248,12 +397,10 @@ static int dw_mci_rk3288_execute_tuning(struct dw_mci_slot *slot, u32 opcode)
248
397
249
398
middle_phase = ranges [longest_range ].start + longest_range_len / 2 ;
250
399
middle_phase %= priv -> num_phases ;
251
- dev_info ( host -> dev , "Successfully tuned phase to %d\n" ,
252
- TUNING_ITERATION_TO_PHASE ( middle_phase , priv -> num_phases ) );
400
+ phase = TUNING_ITERATION_TO_PHASE ( middle_phase , priv -> num_phases );
401
+ dev_info ( host -> dev , "Successfully tuned phase to %d\n" , phase );
253
402
254
- clk_set_phase (priv -> sample_clk ,
255
- TUNING_ITERATION_TO_PHASE (middle_phase ,
256
- priv -> num_phases ));
403
+ rockchip_mmc_set_phase (host , true, phase );
257
404
258
405
free :
259
406
kfree (ranges );
@@ -287,6 +434,8 @@ static int dw_mci_rk3288_parse_dt(struct dw_mci *host)
287
434
288
435
host -> priv = priv ;
289
436
437
+ priv -> internal_phase = false;
438
+
290
439
return 0 ;
291
440
}
292
441
0 commit comments