f71d34db5fd358d26f2c710db09bad050b171dff
[firefly-linux-kernel-4.4.55.git] / drivers / mmc / host / dw_mmc-rockchip.c
1 /*
2  * Rockchip Specific Extensions for Synopsys DW Multimedia Card Interface driver
3  *
4  * Copyright (C) 2014, Rockchip Electronics Co., Ltd.
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  */
11
12 #include <linux/module.h>
13 #include <linux/platform_device.h>
14 #include <linux/clk.h>
15 #include <linux/mmc/host.h>
16 #include <linux/mmc/mmc.h>
17 #include <linux/mmc/rk_mmc.h>
18 #include <linux/of.h>
19 #include <linux/of_gpio.h>
20 #include <linux/slab.h>
21 #include <linux/rockchip/cpu.h>
22 #include <linux/rockchip/cru.h>
23 #include <linux/delay.h>
24 #include <linux/mfd/syscon.h>
25 #include <linux/regmap.h>
26 #include "rk_sdmmc.h"
27 #include "dw_mmc-pltfm.h"
28 #include "../../clk/rockchip/clk-ops.h"
29
30 #include "rk_sdmmc_dbg.h"
31
32 /*CRU SDMMC TUNING*/
33 /*
34 *   sdmmc,sdio0,sdio1,emmc id=0~3
35 *   cclk_in_drv, cclk_in_sample  i=0,1
36 */
37
38 static  u32 cru_tuning_base = 0;
39
40 #define CRU_SDMMC_CON(id, tuning_type)  (cru_tuning_base + ((id) * 8) + ((tuning_type) * 4))
41
42 #define MAX_DELAY_LINE  (0xff)
43 #define FREQ_REF_150MHZ (150000000)
44 #define PRECISE_ADJUST  (0)
45
46 #define SDMMC_TUNING_SEL(tuning_type)           ( tuning_type? 10:11 )
47 #define SDMMC_TUNING_DELAYNUM(tuning_type)      ( tuning_type? 2:3 )
48 #define SDMMC_TUNING_DEGREE(tuning_type)        ( tuning_type? 0:1 )
49 #define SDMMC_TUNING_INIT_STATE                 (0)
50
51 enum{
52        SDMMC_SHIFT_DEGREE_0 = 0,
53        SDMMC_SHIFT_DEGREE_90,
54        SDMMC_SHIFT_DEGREE_180,
55        SDMMC_SHIFT_DEGREE_270,
56        SDMMC_SHIFT_DEGREE_INVALID,
57 };
58
59 const char *phase_desc[SDMMC_SHIFT_DEGREE_INVALID + 1] = {
60         "SDMMC_SHIFT_DEGREE_0",
61         "SDMMC_SHIFT_DEGREE_90",
62         "SDMMC_SHIFT_DEGREE_180",
63         "SDMMC_SHIFT_DEGREE_270",
64         "SDMMC_SHIFT_DEGREE_INVALID",
65 };
66
67 enum{
68         USE_CLK_AFTER_PHASE = 0,
69         USE_CLK_AFTER_PHASE_AND_DELAY_LINE = 1,
70 };
71
72 enum{
73         IO_DRV_2MA  = 0x0,
74         IO_DRV_4MA  = 0x1,
75         IO_DRV_8MA  = 0x2,
76         IO_DRV_12MA = 0x3,
77 };
78
79 enum{
80         SLEW_RATE_SLOW = 0,
81         SLEW_RATE_FAST = 1,
82 };
83
84
85 /* Rockchip implementation specific driver private data */
86 struct dw_mci_rockchip_priv_data {
87         enum dw_mci_rockchip_type               ctrl_type;
88         u8                              ciu_div;
89         u32                             sdr_timing;
90         u32                             ddr_timing;
91         u32                             cur_speed;
92 };
93
94 static struct dw_mci_rockchip_compatible {
95         char                            *compatible;
96         enum dw_mci_rockchip_type               ctrl_type;
97 } rockchip_compat[] = {
98         {
99                 .compatible     = "rockchip,rk31xx-sdmmc",
100                 .ctrl_type      = DW_MCI_TYPE_RK3188,
101         },{
102                 .compatible     = "rockchip,rk32xx-sdmmc",
103                 .ctrl_type      = DW_MCI_TYPE_RK3288,
104         },{
105                 .compatible     = "rockchip,rk3036-sdmmc",
106                 .ctrl_type      = DW_MCI_TYPE_RK3036,
107         },{
108                 .compatible     = "rockchip,rk312x-sdmmc",
109                 .ctrl_type      = DW_MCI_TYPE_RK312X,
110         },{
111                 .compatible     = "rockchip,rk3368-sdmmc",
112                 .ctrl_type      = DW_MCI_TYPE_RK3368,
113         },
114 };
115
116 static int dw_mci_rockchip_priv_init(struct dw_mci *host)
117 {
118         struct dw_mci_rockchip_priv_data *priv;
119         int idx;
120
121         priv = devm_kzalloc(host->dev, sizeof(*priv), GFP_KERNEL);
122         if(!priv){
123                 dev_err(host->dev, "mem alloc failed for private data\n");
124                 return -ENOMEM;
125         }
126
127         for(idx = 0; idx < ARRAY_SIZE(rockchip_compat); idx++){
128                 if(of_device_is_compatible(host->dev->of_node,
129                                 rockchip_compat[idx].compatible)) {
130                         priv->ctrl_type = rockchip_compat[idx].ctrl_type;
131                         host->cid = priv->ctrl_type;
132                         host->grf = syscon_regmap_lookup_by_phandle(host->dev->of_node,
133                                                                 "rockchip,grf");
134                 }
135         }
136
137         host->priv = priv;
138         return 0;
139 }
140
141 static int dw_mci_rockchip_setup_clock(struct dw_mci *host)
142 {
143         struct dw_mci_rockchip_priv_data *priv = host->priv;
144
145         if ((priv->ctrl_type == DW_MCI_TYPE_RK3288) ||
146                 (priv->ctrl_type == DW_MCI_TYPE_RK3036) ||
147                 (priv->ctrl_type == DW_MCI_TYPE_RK312X) ||
148                 (priv->ctrl_type == DW_MCI_TYPE_RK3368))
149                 host->bus_hz /= (priv->ciu_div + 1);
150
151         return 0;
152 }
153
154 static void dw_mci_rockchip_prepare_command(struct dw_mci *host, u32 *cmdr)
155 {
156
157 }
158
159 static void dw_mci_rockchip_set_ios(struct dw_mci *host, struct mmc_ios *ios)
160 {
161
162 }
163
164 static int dw_mci_rockchip_parse_dt(struct dw_mci *host)
165 {
166         return 0;
167 }
168 static inline u8 dw_mci_rockchip_get_delaynum(struct dw_mci *host, u8 con_id, u8 tuning_type)
169 {
170         u32 regs;
171         u8 delaynum;
172
173         regs =  cru_readl(CRU_SDMMC_CON(con_id, tuning_type));
174         delaynum = ((regs>>SDMMC_TUNING_DELAYNUM(tuning_type)) & 0xff);
175
176         return delaynum;
177 }
178
179 static inline void dw_mci_rockchip_set_delaynum(struct dw_mci *host, u8 con_id, u8 tuning_type, u8 delaynum)
180 {
181         u32 regs;
182         regs = cru_readl(CRU_SDMMC_CON(con_id, tuning_type));
183         regs &= ~( 0xff << SDMMC_TUNING_DELAYNUM(tuning_type));
184         regs |= (delaynum  << SDMMC_TUNING_DELAYNUM(tuning_type));
185         regs |= (0xff  << (SDMMC_TUNING_DELAYNUM(tuning_type)+16));
186
187         MMC_DBG_INFO_FUNC(host->mmc,"tuning_result[delayline]: con_id = %d, tuning_type = %d, CRU_CON = 0x%x. [%s]",
188                 con_id, tuning_type, regs, mmc_hostname(host->mmc));
189
190         cru_writel(regs, CRU_SDMMC_CON(con_id, tuning_type));
191
192         MMC_DBG_INFO_FUNC(host->mmc,"CRU_SDMMC_CON(con_id, tuning_type) = 0x%x, regs = 0x%x [%s]",
193                         CRU_SDMMC_CON(con_id, tuning_type), cru_readl(CRU_SDMMC_CON(con_id, tuning_type)), mmc_hostname(host->mmc));
194 }
195
196 static inline void dw_mci_rockchip_set_degree(struct dw_mci *host, u8 con_id, u8 tuning_type, u8 phase)
197 {
198         u32 regs;
199         
200         regs = cru_readl(CRU_SDMMC_CON(con_id, tuning_type));
201         regs &= ~( 0x3 << SDMMC_TUNING_DEGREE(tuning_type));
202         regs |= (phase  << SDMMC_TUNING_DEGREE(tuning_type));
203         regs |= (0x3  << (SDMMC_TUNING_DEGREE(tuning_type)+16));
204
205         MMC_DBG_INFO_FUNC(host->mmc,"tuning_result[phase]: con_id = %d, tuning_type= %d, CRU_CON = 0x%x. [%s]",
206                 con_id, tuning_type, regs, mmc_hostname(host->mmc));
207         
208         cru_writel(regs, CRU_SDMMC_CON(con_id, tuning_type));
209         MMC_DBG_INFO_FUNC(host->mmc,"CRU_SDMMC_CON(con_id, tuning_type) = 0x%x, regs = 0x%x [%s]",
210                 CRU_SDMMC_CON(con_id, tuning_type), cru_readl(CRU_SDMMC_CON(con_id, tuning_type)), mmc_hostname(host->mmc));
211 }
212
213 static inline void dw_mci_rockchip_turning_sel(struct dw_mci *host, u8 con_id, u8 tuning_type, u8 mode)
214 {
215         u32 regs;
216         regs = cru_readl(CRU_SDMMC_CON(con_id, tuning_type)) ;
217         regs &= ~( 0x1 << SDMMC_TUNING_SEL(tuning_type));
218         regs |= (mode  << SDMMC_TUNING_SEL(tuning_type));
219         regs |= (0x1  << (SDMMC_TUNING_SEL(tuning_type)+16));
220
221         MMC_DBG_INFO_FUNC(host->mmc,"tuning_sel: con_id = %d, tuning_type = %d, CRU_CON = 0x%x. [%s]",
222                 con_id, tuning_type, regs, mmc_hostname(host->mmc));
223                 
224         cru_writel(regs, CRU_SDMMC_CON(con_id, tuning_type));       
225 }
226
227
228 static inline u8 dw_mci_rockchip_get_phase(struct dw_mci *host, u8 con_id, u8 tuning_type)
229 {
230         return 0;
231 }
232
233 static inline u8 dw_mci_rockchip_move_next_clksmpl(struct dw_mci *host, u8 con_id, u8 tuning_type, u8 val)
234 {
235         u32 regs;
236         
237         regs = cru_readl(CRU_SDMMC_CON(con_id, tuning_type)) ;
238
239         if(tuning_type) {
240             val = ((regs>>SDMMC_TUNING_DELAYNUM(tuning_type)) & 0xff);
241         }
242
243         return val;
244 }
245
246 static void dw_mci_rockchip_load_signal_integrity(struct dw_mci *host, u32 sr, u32 drv)
247 {
248         if (unlikely((drv > IO_DRV_12MA) || (sr > SLEW_RATE_FAST))) {
249                 MMC_DBG_ERR_FUNC(host->mmc,"wrong signal integrity setting: drv = %d, sr = %d ![%s]",
250                         drv, sr, mmc_hostname(host->mmc));
251                 return;
252         }
253
254         if(cpu_is_rk3288()){
255                 /*Note 00: 2ma 01:4ma 10:8ma 11:12ma
256                 For consider line loading and IP's slew rate,
257                 we should match these by every board depends for signal integrity.
258                 slew rate >= 2*pi*f*Vpeak = max(|d'(Vpeak)/dt|)
259                 */
260                 if (host->mmc->restrict_caps & RESTRICT_CARD_TYPE_SDIO) {
261                         grf_writel(0xff005500 | (drv << 14) | (drv << 12) |
262                                                  (drv << 10) | (drv << 8), 0x01f8); /* GPIO4C4-C7 */
263                         grf_writel(0x000f0000 | (drv << 0) | (drv << 2), 0x01fc); /* GPIO4D0-D1 */
264                         grf_writel(0x03f00000 | (sr << 4) | (sr << 5) | (sr << 6) |
265                                                 (sr << 7) | (sr << 8) | (sr << 9) , 0x011c); /* slew rate*/
266                 }else if (host->mmc->restrict_caps & RESTRICT_CARD_TYPE_SD) {
267                         grf_writel(0x3fff0000 | (drv << 0) | (drv << 2) | (drv << 4) |
268                                                  (drv << 6) | (drv << 8) | (drv << 10) |
269                                                  (drv << 12), 0x0218); /* GPIO6C0-C6 */
270                         grf_writel(0x003f0000 | (sr << 0) | (sr << 1) | (sr << 2) |
271                                                 (sr << 3) | (sr << 4) | (sr << 5), 0x012c); /* slew rate */
272                 }else if (host->mmc->restrict_caps & RESTRICT_CARD_TYPE_EMMC) {
273                         /* emmc hardware relative addr match requirement, assume 4ma not slow slew rate */
274                         grf_writel(0xffff5555, 0x01e0); /* GPIO3A0-A7 */
275                         grf_writel(0x000c0006, 0x01e4); /* GPIO3B1 */
276                         grf_writel(0x003f0015, 0x01e8); /* GPIO3C2-C0 */
277                 }
278         } else if (host->cid == DW_MCI_TYPE_RK3368) {
279                  if (host->mmc->restrict_caps & RESTRICT_CARD_TYPE_SDIO) {
280                         regmap_write(host->grf, 0x21c, 0xff000000 | (drv << 14) | (drv << 12) |
281                                                 (drv << 10) | (drv << 8)); /* GPIO2D4-D7 */
282                         regmap_write(host->grf, 0x220, 0x000f0000 | (drv << 0) | (drv << 2)); /* GPIO3A0-A1 */
283                 }else if (host->mmc->restrict_caps & RESTRICT_CARD_TYPE_SD) {
284                         regmap_write(host->grf, 0x210, 0xfc000000 | (drv << 10) | (drv << 12) | (drv << 14)); /* GPIO2A5-A7 */
285                         regmap_write(host->grf, 0x214, 0x003f0000 | (drv << 0) | (drv << 2) | (drv << 4)); /* GPIO2B0-2 */
286                 }else if (host->mmc->restrict_caps & RESTRICT_CARD_TYPE_EMMC) {
287                         regmap_write(host->grf, 0x208, 0xfff00000 | (drv << 4) | (drv << 6) | (drv << 8) | (drv << 10) 
288                                                                 | (drv << 12) | (drv << 14)); /* GPIO1C2-C7 */
289                         regmap_write(host->grf, 0x20c, 0x003f0000 | (drv << 0) | (drv << 2) | (drv << 4)); /* GPIO1D0-D2 */
290                         regmap_write(host->grf, 0x210, 0x03000000 | (drv << 8)); /* GPIO2A4 */
291                 }
292         }
293
294 }
295 static void dw_mci_rockchip_load_tuning_base(struct dw_mci *host)
296 {
297         /* load tuning base */
298         if (cpu_is_rk3288()) {
299                 cru_tuning_base =  RK3288_CRU_SDMMC_CON0;
300         } else if (host->cid == DW_MCI_TYPE_RK3368) {
301                 if (IS_ERR(host->grf))
302                         pr_err("rk_sdmmc: dts couldn't find grf regmap\n");
303
304                 cru_tuning_base =  0x400;
305         }
306 }
307
308 static int inline __dw_mci_rockchip_execute_tuning(struct dw_mci_slot *slot, u32 opcode,
309                                         u8 *blk_test, unsigned int blksz)
310 {
311         struct dw_mci *host = slot->host;
312         struct mmc_host *mmc = slot->mmc;       
313         struct mmc_request mrq = {NULL};
314         struct mmc_command cmd = {0};
315         struct mmc_command stop = {0};
316         struct mmc_data data = {0};
317         struct scatterlist sg;
318
319         cmd.opcode = opcode;
320         cmd.arg = 0;
321         cmd.flags = MMC_RSP_R1 | MMC_CMD_ADTC;
322         stop.opcode = MMC_STOP_TRANSMISSION;
323         stop.arg = 0;
324         stop.flags = MMC_RSP_R1B | MMC_CMD_AC;
325         data.blksz = blksz;
326         data.blocks = 1;
327         data.flags = MMC_DATA_READ;
328         data.sg = &sg;
329         data.sg_len = 1;
330
331         sg_init_one(&sg, blk_test, blksz);
332         mrq.cmd = &cmd;
333         mrq.stop = &stop;
334         mrq.data = &data;
335         host->mrq = &mrq;
336         mci_writel(host, TMOUT, ~0);
337
338         mmc_wait_for_req(mmc, &mrq);
339         if(!cmd.error && !data.error){
340                 return 0;
341         }else{
342                 dev_dbg(host->dev,
343                         "Tuning error: cmd.error:%d, data.error:%d\n",cmd.error, data.error);
344                 return -EIO;
345         }
346         
347 }
348
349
350 static int dw_mci_rockchip_execute_tuning(struct dw_mci_slot *slot, u32 opcode,
351                                         struct dw_mci_tuning_data *tuning_data)
352 {
353         
354         struct dw_mci *host = slot->host;
355         u8 step;
356         u8 candidates_delayline[MAX_DELAY_LINE] = {0};
357         u8 candidates_degree[SDMMC_SHIFT_DEGREE_INVALID] = {4,4,4,4};
358         u8 default_drv;
359         u8 index = 0;
360         u8 start_degree = 0;
361         u32 start_delayline = 0;
362         const u8 *blk_pattern = tuning_data->blk_pattern;
363         u8 *blk_test;
364         int ret = -1;
365         int ref = 0;
366         unsigned int blksz = tuning_data->blksz;
367
368         MMC_DBG_INFO_FUNC(host->mmc,"execute tuning:  [%s]", mmc_hostname(host->mmc));
369
370         dw_mci_rockchip_load_tuning_base(host);
371
372         blk_test = kmalloc(blksz, GFP_KERNEL);
373         if (!blk_test)
374         {
375                 MMC_DBG_ERR_FUNC(host->mmc,"execute tuning:  blk_test kmalloc failed[%s]",
376                         mmc_hostname(host->mmc));
377                 return -ENOMEM;
378         }
379         
380         /* Select use delay line*/
381         dw_mci_rockchip_turning_sel(host, tuning_data->con_id, tuning_data->tuning_type,
382                                     USE_CLK_AFTER_PHASE_AND_DELAY_LINE);
383                                     
384         /* For RK32XX signoff 150M clk, 1 cycle = 6.66ns , and 1/4 phase = 1.66ns. 
385            Netlist level sample LT:  10.531ns / 42.126ps   WC: 19.695ns / 76.936ps.
386            So we take average --- 60ps, (1.66ns/ 2) = 0.83(middle-value),TAKE 0.9
387            0.9 / 60ps = 15 delayline
388          */
389         if (cpu_is_rk3288() && !(rockchip_get_cpu_version() > 0)) {
390                 /* RK3288, non-eco */
391                 ref = DIV_ROUND_UP(FREQ_REF_150MHZ, host->bus_hz);
392                 step = (15 * ref);
393
394                 if (step > MAX_DELAY_LINE) {
395                         step = MAX_DELAY_LINE;       
396                         MMC_DBG_WARN_FUNC(host->mmc,
397                                         "execute tuning: TOO LARGE STEP![%s]", mmc_hostname(host->mmc));
398                 }
399                 MMC_DBG_INFO_FUNC(host->mmc,
400                                 "execute tuning: SOC is RK3288, ref = %d, step = %d[%s]",
401                                 ref, step, mmc_hostname(host->mmc));
402                  
403         } else {
404                 step = (15 * ((FREQ_REF_150MHZ / host->bus_hz) * 100)) / 100;
405
406                 if (step > MAX_DELAY_LINE) {
407                         step = MAX_DELAY_LINE;
408                         MMC_DBG_WARN_FUNC(host->mmc,
409                                         "execute tuning: TOO LARGE STEP![%s]", mmc_hostname(host->mmc));
410                 }
411                 MMC_DBG_INFO_FUNC(host->mmc,
412                                 "execute tuning: SOC id is %d, step = %d[%s]",
413                                 host->cid, step, mmc_hostname(host->mmc));
414         }
415
416 re_phase:
417         /* calcute slew rate & drv strength in timing tuning */
418         if(host->mmc->restrict_caps & RESTRICT_CARD_TYPE_SD)
419                 default_drv = IO_DRV_4MA;
420         else
421                 default_drv = IO_DRV_8MA;
422
423         dw_mci_rockchip_load_signal_integrity(host, SLEW_RATE_SLOW, default_drv);
424         /* Loop degree from 0 ~ 270 */
425         for(start_degree = SDMMC_SHIFT_DEGREE_0; start_degree <= SDMMC_SHIFT_DEGREE_270; start_degree++){
426                 dw_mci_rockchip_set_degree(host, tuning_data->con_id, tuning_data->tuning_type, start_degree);
427                 if(0 == __dw_mci_rockchip_execute_tuning(slot, opcode, blk_test, blksz)){
428                         if(!memcmp(blk_pattern, blk_test, blksz)){
429                                 /* Successfully tuning in this condition*/                      
430                                 candidates_degree[index] = start_degree;
431                                 index++;
432                          }
433                 }
434                 /* eMMC spec does not require a delay between tuning cycles
435                  * but eMMC should be guaranteed to complete a sequence of 40 times CMD21
436                  * withnin 150ms, some eMMC may limit 4ms gap between any two sequential CMD21
437                  */
438                 if (opcode == MMC_SEND_TUNING_BLOCK)
439                         mdelay(1);
440                 else
441                         /* MMC_SEND_TUNING_BLOCK_HS200 */
442                         mdelay(5);
443         }
444         
445         MMC_DBG_BOOT_FUNC(host->mmc,"\n execute tuning: candidates_degree = %s \t%s \t%s \t%s[%s]",
446                 phase_desc[candidates_degree[0]], phase_desc[candidates_degree[1]],
447                 phase_desc[candidates_degree[2]], phase_desc[candidates_degree[3]],
448                 mmc_hostname(host->mmc));
449
450         
451         if((candidates_degree[0] == SDMMC_SHIFT_DEGREE_0)
452                 && (candidates_degree[1] == SDMMC_SHIFT_DEGREE_90)
453                 && (candidates_degree[2] == SDMMC_SHIFT_DEGREE_180)){
454            
455                 MMC_DBG_INFO_FUNC(host->mmc,
456                                 "execute tuning: candidates_degree = SDMMC_SHIFT_DEGREE_90 [%s]",
457                                 mmc_hostname(host->mmc));
458                                 
459                 dw_mci_rockchip_set_degree(host, tuning_data->con_id, 
460                         tuning_data->tuning_type, SDMMC_SHIFT_DEGREE_90);
461                 ret = 0;
462                 goto done;
463         }else if((candidates_degree[0] == SDMMC_SHIFT_DEGREE_90) 
464                 && (candidates_degree[1] == SDMMC_SHIFT_DEGREE_180) 
465                 && (candidates_degree[2] == SDMMC_SHIFT_DEGREE_270)){
466                 MMC_DBG_INFO_FUNC(host->mmc,
467                         "execute tuning: candidates_degree = SDMMC_SHIFT_DEGREE_180 [%s]",
468                         mmc_hostname(host->mmc));
469                 dw_mci_rockchip_set_degree(host, tuning_data->con_id, 
470                         tuning_data->tuning_type, SDMMC_SHIFT_DEGREE_180);
471                 ret = 0;
472                 goto done;
473         }else if((candidates_degree[0] == SDMMC_SHIFT_DEGREE_0) 
474                 && (candidates_degree[1] == SDMMC_SHIFT_DEGREE_90) 
475                 && (candidates_degree[2] == SDMMC_SHIFT_DEGREE_INVALID)){
476
477                 MMC_DBG_INFO_FUNC(host->mmc,
478                         "execute tuning: candidates_degree = SDMMC_SHIFT_DEGREE_0 ~  SDMMC_SHIFT_DEGREE_90[%s]",
479                         mmc_hostname(host->mmc));
480                 
481                 dw_mci_rockchip_set_degree(host, tuning_data->con_id, tuning_data->tuning_type, SDMMC_SHIFT_DEGREE_0);
482                 #if PRECISE_ADJUST
483                 goto delayline; 
484                 #else              
485                 dw_mci_rockchip_set_delaynum(host, tuning_data->con_id, tuning_data->tuning_type, step);
486                 ret = 0;
487                 goto done;  
488                 #endif       
489         }else if((candidates_degree[0]==SDMMC_SHIFT_DEGREE_0)
490                 && (candidates_degree[1]==SDMMC_SHIFT_DEGREE_180)
491                 && (candidates_degree[2]==SDMMC_SHIFT_DEGREE_270)){
492                 MMC_DBG_INFO_FUNC(host->mmc,
493                         "execute tuning: candidates_degree = SDMMC_SHIFT_DEGREE_0 AND SDMMC_SHIFT_DEGREE_180 AND SDMMC_SHIFT_DEGREE_270[%s]",
494                         mmc_hostname(host->mmc));
495                 dw_mci_rockchip_set_degree(host, tuning_data->con_id, tuning_data->tuning_type, SDMMC_SHIFT_DEGREE_180);
496                 dw_mci_rockchip_set_delaynum(host, tuning_data->con_id, tuning_data->tuning_type, step);
497                 ret = 0;
498                 goto done;
499         }else if((candidates_degree[0]==SDMMC_SHIFT_DEGREE_0) 
500                 && (candidates_degree[1]==SDMMC_SHIFT_DEGREE_180)){
501
502                 MMC_DBG_INFO_FUNC(host->mmc,
503                         "execute tuning: candidates_degree = SDMMC_SHIFT_DEGREE_0 AND SDMMC_SHIFT_DEGREE_180[%s]",
504                         mmc_hostname(host->mmc));
505
506                 /* FixMe: NO sense any signal indicator make this case happen*/
507                 dw_mci_rockchip_set_degree(host, tuning_data->con_id, tuning_data->tuning_type, SDMMC_SHIFT_DEGREE_0);
508                 goto delayline;
509         }else if((candidates_degree[0] == SDMMC_SHIFT_DEGREE_90) 
510                 && (candidates_degree[1] == SDMMC_SHIFT_DEGREE_180) 
511                 && (candidates_degree[2] == SDMMC_SHIFT_DEGREE_INVALID)){
512
513                 MMC_DBG_INFO_FUNC(host->mmc,
514                         "execute tuning: candidates_degree = SDMMC_SHIFT_DEGREE_90 ~  SDMMC_SHIFT_DEGREE_180[%s]",
515                         mmc_hostname(host->mmc));
516                
517                 dw_mci_rockchip_set_degree(host, tuning_data->con_id, tuning_data->tuning_type, SDMMC_SHIFT_DEGREE_90);
518                 #if PRECISE_ADJUST
519                 goto delayline; 
520                 #else              
521                 dw_mci_rockchip_set_delaynum(host, tuning_data->con_id, tuning_data->tuning_type, step);
522                 ret = 0;
523                 goto done;  
524                 #endif                              
525         }else if((candidates_degree[0] == SDMMC_SHIFT_DEGREE_180) 
526                 && (candidates_degree[1] == SDMMC_SHIFT_DEGREE_270)){
527
528                 MMC_DBG_INFO_FUNC(host->mmc,
529                         "execute tuning: candidates_degree = SDMMC_SHIFT_DEGREE_180 ~  SDMMC_SHIFT_DEGREE_270[%s]",
530                         mmc_hostname(host->mmc));
531                         
532                 dw_mci_rockchip_set_degree(host, tuning_data->con_id, tuning_data->tuning_type, SDMMC_SHIFT_DEGREE_180);
533                 #if PRECISE_ADJUST
534                 goto delayline; 
535                 #else              
536                 dw_mci_rockchip_set_delaynum(host, tuning_data->con_id, tuning_data->tuning_type, step);
537                 ret = 0;
538                 goto done;
539                 #endif
540         }else if((candidates_degree[0] == SDMMC_SHIFT_DEGREE_180) 
541                 && (candidates_degree[1] == SDMMC_SHIFT_DEGREE_INVALID)){
542
543                 MMC_DBG_INFO_FUNC(host->mmc,
544                         "execute tuning: candidates_degree = [SDMMC_SHIFT_DEGREE_90 + n ~  SDMMC_SHIFT_DEGREE_180][%s]",
545                         mmc_hostname(host->mmc));             
546                 
547                 dw_mci_rockchip_set_degree(host, tuning_data->con_id, tuning_data->tuning_type, SDMMC_SHIFT_DEGREE_90);
548                 #if PRECISE_ADJUST
549                 goto delayline;
550                 #else
551                 default_drv++;
552                 goto re_phase;
553                 //dw_mci_rockchip_set_delaynum(host, tuning_data->con_id, tuning_data->tuning_type, step);
554                 //ret = 0;
555                 //goto done;
556                 #endif
557         }else if((candidates_degree[0] == SDMMC_SHIFT_DEGREE_90) 
558                 && (candidates_degree[1] == SDMMC_SHIFT_DEGREE_INVALID)){
559
560                 MMC_DBG_INFO_FUNC(host->mmc,
561                         "execute tuning: candidates_degree = [SDMMC_SHIFT_DEGREE_0 + n ~  SDMMC_SHIFT_DEGREE_90][%s]",
562                         mmc_hostname(host->mmc));             
563                 
564                 dw_mci_rockchip_set_degree(host, tuning_data->con_id, tuning_data->tuning_type, SDMMC_SHIFT_DEGREE_0);
565                 #if PRECISE_ADJUST
566                 goto delayline; 
567                 #else
568                 default_drv++;
569                 goto re_phase;
570                 //dw_mci_rockchip_set_delaynum(host, tuning_data->con_id, tuning_data->tuning_type, step);
571                 //ret = 0;
572                 //goto done;
573                 #endif
574         }else if((candidates_degree[0] == SDMMC_SHIFT_DEGREE_270)){
575
576                 MMC_DBG_INFO_FUNC(host->mmc,
577                         "execute tuning: candidates_degree = SDMMC_SHIFT_DEGREE_270 [%s]",
578                         mmc_hostname(host->mmc));         
579
580                 /*FixME: so urgly signal indicator, HW engineer help!*/
581
582                 //dw_mci_rockchip_set_degree(host, tuning_data->con_id, tuning_data->tuning_type, SDMMC_SHIFT_DEGREE_180);
583                 #if PRECISE_ADJUST
584                 goto delayline; 
585                 #else
586                 default_drv++;
587                 goto re_phase;
588                 //dw_mci_rockchip_set_delaynum(host, tuning_data->con_id, tuning_data->tuning_type, step);
589                 //ret = 0;
590                 //goto done;
591                 #endif            
592         }else{
593                 MMC_DBG_ERR_FUNC(host->mmc,
594                                 "execute tuning: candidates_degree beyong limited case! [%s]",
595                                 mmc_hostname(host->mmc));
596                 default_drv++;
597                 goto re_phase;
598                 if(host->mmc->restrict_caps & RESTRICT_CARD_TYPE_EMMC)
599                         BUG();
600                 return -EAGAIN;
601         }
602
603 delayline:
604                 index = 0;
605                 for(start_delayline = 0; start_delayline <= MAX_DELAY_LINE; start_delayline += step){
606                 
607                         dw_mci_rockchip_set_delaynum(host, tuning_data->con_id, 
608                                 tuning_data->tuning_type, start_delayline);
609                         if(0 == __dw_mci_rockchip_execute_tuning(slot, opcode, blk_test, blksz)){
610                                 if(!memcmp(blk_pattern, blk_test, blksz)){
611                                         /* Successfully tuning in this condition*/                                        
612                                         candidates_delayline[index] = start_delayline;
613                                         index++; 
614                                 }
615                         }                    
616                 }
617                 if((index < 2) && (index != 0)) {
618                         /* setup 400ps, consider line loading, at least 600ps wc.
619                            for 150M, 15 steps =900ps ,too larger scale, should step smaller in principle
620                          */
621                         MMC_DBG_INFO_FUNC(host->mmc,
622                                 "execute tuning: candidates_delayline failed for no enough elements [%s]",
623                                 mmc_hostname(host->mmc));
624
625                         /* Make step smaller, and re-calculate */
626                         step = step >> 1;
627                         index = 0;
628                         goto delayline;
629                 }else if(index >= 2){
630                         /* Find it! */
631                         MMC_DBG_INFO_FUNC(host->mmc,
632                                 "execute tuning: candidates_delayline calculate successfully  [%s]",
633                                 mmc_hostname(host->mmc));
634
635                         dw_mci_rockchip_set_delaynum(host, tuning_data->con_id, 
636                                 tuning_data->tuning_type, candidates_delayline[index/2]); 
637                         ret = 0; 
638                         goto done;
639                 }
640         
641 done:
642         kfree(blk_test);
643         blk_test = NULL;
644         return ret;
645         
646 }
647
648 /* Common capabilities of RK32XX SoC */
649 static unsigned long rockchip_dwmmc_caps[4] = {
650         MMC_CAP_CMD23,
651         MMC_CAP_CMD23,
652         MMC_CAP_CMD23,
653         MMC_CAP_CMD23,
654 };
655
656 unsigned int  rockchip_dwmmc_hold_reg[4] = {1,0,0,0};
657
658 static const struct dw_mci_drv_data rockchip_drv_data = {
659         .caps                   = rockchip_dwmmc_caps,
660         .hold_reg_flag  = rockchip_dwmmc_hold_reg,
661         .init                   = dw_mci_rockchip_priv_init,
662         .setup_clock            = dw_mci_rockchip_setup_clock,
663         .prepare_command        = dw_mci_rockchip_prepare_command,
664         .set_ios                = dw_mci_rockchip_set_ios,
665         .parse_dt               = dw_mci_rockchip_parse_dt,
666         .execute_tuning         = dw_mci_rockchip_execute_tuning,
667 };
668
669 static const struct of_device_id dw_mci_rockchip_match[] = {
670         { .compatible = "rockchip,rk_mmc",
671                         .data = &rockchip_drv_data, },
672         { /* Sentinel */},
673 };
674 MODULE_DEVICE_TABLE(of, dw_mci_rockchip_match);
675
676 static int dw_mci_rockchip_probe(struct platform_device *pdev)
677 {
678         const struct dw_mci_drv_data *drv_data;
679         const struct of_device_id *match;
680         
681         match = of_match_node(dw_mci_rockchip_match, pdev->dev.of_node);
682         drv_data = match->data;
683         return dw_mci_pltfm_register(pdev, drv_data);
684 }
685
686 static struct platform_driver dw_mci_rockchip_pltfm_driver = {
687         .probe          = dw_mci_rockchip_probe,
688         .remove         = __exit_p(dw_mci_pltfm_remove),
689         .driver         = {
690                 .name           = "dwmmc_rockchip",
691                 .of_match_table = dw_mci_rockchip_match,
692                 .pm             = &dw_mci_pltfm_pmops,
693         },
694 };
695
696 module_platform_driver(dw_mci_rockchip_pltfm_driver);
697
698 MODULE_DESCRIPTION("Rockchip Specific DW-SDMMC Driver Extension");
699 MODULE_AUTHOR("Shawn Lin <lintao@rock-chips.com>");
700 MODULE_AUTHOR("Bangwang Xie <xbw@rock-chips.com>");
701 MODULE_LICENSE("GPL v2");
702 MODULE_ALIAS("platform:dwmmc-rockchip");