259259#define MSDC_PAD_TUNE_RD_SEL (0x1 << 13) /* RW */
260260#define MSDC_PAD_TUNE_CMD_SEL (0x1 << 21) /* RW */
261261
262+ #define PAD_DS_TUNE_DLY_SEL (0x1 << 0) /* RW */
262263#define PAD_DS_TUNE_DLY1 (0x1f << 2) /* RW */
263264#define PAD_DS_TUNE_DLY2 (0x1f << 7) /* RW */
264265#define PAD_DS_TUNE_DLY3 (0x1f << 12) /* RW */
302303#define PAD_CMD_RD_RXDLY_SEL (0x1 << 11) /* RW */
303304#define PAD_CMD_TX_DLY (0x1f << 12) /* RW */
304305
306+ /* EMMC50_PAD_DS_TUNE mask */
307+ #define PAD_DS_DLY_SEL (0x1 << 16) /* RW */
308+ #define PAD_DS_DLY1 (0x1f << 10) /* RW */
309+ #define PAD_DS_DLY3 (0x1f << 0) /* RW */
310+
305311#define REQ_CMD_EIO (0x1 << 0)
306312#define REQ_CMD_TMO (0x1 << 1)
307313#define REQ_DAT_ERR (0x1 << 2)
@@ -449,11 +455,13 @@ struct msdc_host {
449455 bool vqmmc_enabled ;
450456 u32 latch_ck ;
451457 u32 hs400_ds_delay ;
458+ u32 hs400_ds_dly3 ;
452459 u32 hs200_cmd_int_delay ; /* cmd internal delay for HS200/SDR104 */
453460 u32 hs400_cmd_int_delay ; /* cmd internal delay for HS400 */
454461 bool hs400_cmd_resp_sel_rising ;
455462 /* cmd response sample selection for HS400 */
456463 bool hs400_mode ; /* current eMMC will run at hs400 mode */
464+ bool hs400_tuning ; /* hs400 mode online tuning */
457465 bool internal_cd ; /* Use internal card-detect logic */
458466 bool cqhci ; /* support eMMC hw cmdq */
459467 struct msdc_save_para save_para ; /* used when gate HCLK */
@@ -1190,7 +1198,8 @@ static bool msdc_cmd_done(struct msdc_host *host, int events,
11901198 if (!sbc_error && !(events & MSDC_INT_CMDRDY )) {
11911199 if (events & MSDC_INT_CMDTMO ||
11921200 (cmd -> opcode != MMC_SEND_TUNING_BLOCK &&
1193- cmd -> opcode != MMC_SEND_TUNING_BLOCK_HS200 ))
1201+ cmd -> opcode != MMC_SEND_TUNING_BLOCK_HS200 &&
1202+ !host -> hs400_tuning ))
11941203 /*
11951204 * should not clear fifo/interrupt as the tune data
11961205 * may have alreay come when cmd19/cmd21 gets response
@@ -1287,7 +1296,8 @@ static void msdc_cmd_next(struct msdc_host *host,
12871296 if ((cmd -> error &&
12881297 !(cmd -> error == - EILSEQ &&
12891298 (cmd -> opcode == MMC_SEND_TUNING_BLOCK ||
1290- cmd -> opcode == MMC_SEND_TUNING_BLOCK_HS200 ))) ||
1299+ cmd -> opcode == MMC_SEND_TUNING_BLOCK_HS200 ||
1300+ host -> hs400_tuning ))) ||
12911301 (mrq -> sbc && mrq -> sbc -> error ))
12921302 msdc_request_done (host , mrq );
12931303 else if (cmd == mrq -> sbc )
@@ -2251,6 +2261,67 @@ static int msdc_prepare_hs400_tuning(struct mmc_host *mmc, struct mmc_ios *ios)
22512261 return 0 ;
22522262}
22532263
2264+ static int msdc_execute_hs400_tuning (struct mmc_host * mmc , struct mmc_card * card )
2265+ {
2266+ struct msdc_host * host = mmc_priv (mmc );
2267+ struct msdc_delay_phase dly1_delay ;
2268+ u32 val , result_dly1 = 0 ;
2269+ u8 * ext_csd ;
2270+ int i , ret ;
2271+
2272+ if (host -> top_base ) {
2273+ sdr_set_bits (host -> top_base + EMMC50_PAD_DS_TUNE ,
2274+ PAD_DS_DLY_SEL );
2275+ if (host -> hs400_ds_dly3 )
2276+ sdr_set_field (host -> top_base + EMMC50_PAD_DS_TUNE ,
2277+ PAD_DS_DLY3 , host -> hs400_ds_dly3 );
2278+ } else {
2279+ sdr_set_bits (host -> base + PAD_DS_TUNE , PAD_DS_TUNE_DLY_SEL );
2280+ if (host -> hs400_ds_dly3 )
2281+ sdr_set_field (host -> base + PAD_DS_TUNE ,
2282+ PAD_DS_TUNE_DLY3 , host -> hs400_ds_dly3 );
2283+ }
2284+
2285+ host -> hs400_tuning = true;
2286+ for (i = 0 ; i < PAD_DELAY_MAX ; i ++ ) {
2287+ if (host -> top_base )
2288+ sdr_set_field (host -> top_base + EMMC50_PAD_DS_TUNE ,
2289+ PAD_DS_DLY1 , i );
2290+ else
2291+ sdr_set_field (host -> base + PAD_DS_TUNE ,
2292+ PAD_DS_TUNE_DLY1 , i );
2293+ ret = mmc_get_ext_csd (card , & ext_csd );
2294+ if (!ret )
2295+ result_dly1 |= (1 << i );
2296+ }
2297+ host -> hs400_tuning = false;
2298+
2299+ dly1_delay = get_best_delay (host , result_dly1 );
2300+ if (dly1_delay .maxlen == 0 ) {
2301+ dev_err (host -> dev , "Failed to get DLY1 delay!\n" );
2302+ goto fail ;
2303+ }
2304+ if (host -> top_base )
2305+ sdr_set_field (host -> top_base + EMMC50_PAD_DS_TUNE ,
2306+ PAD_DS_DLY1 , dly1_delay .final_phase );
2307+ else
2308+ sdr_set_field (host -> base + PAD_DS_TUNE ,
2309+ PAD_DS_TUNE_DLY1 , dly1_delay .final_phase );
2310+
2311+ if (host -> top_base )
2312+ val = readl (host -> top_base + EMMC50_PAD_DS_TUNE );
2313+ else
2314+ val = readl (host -> base + PAD_DS_TUNE );
2315+
2316+ dev_info (host -> dev , "Fianl PAD_DS_TUNE: 0x%x\n" , val );
2317+
2318+ return 0 ;
2319+
2320+ fail :
2321+ dev_err (host -> dev , "Failed to tuning DS pin delay!\n" );
2322+ return - EIO ;
2323+ }
2324+
22542325static void msdc_hw_reset (struct mmc_host * mmc )
22552326{
22562327 struct msdc_host * host = mmc_priv (mmc );
@@ -2381,6 +2452,7 @@ static const struct mmc_host_ops mt_msdc_ops = {
23812452 .card_busy = msdc_card_busy ,
23822453 .execute_tuning = msdc_execute_tuning ,
23832454 .prepare_hs400_tuning = msdc_prepare_hs400_tuning ,
2455+ .execute_hs400_tuning = msdc_execute_hs400_tuning ,
23842456 .hw_reset = msdc_hw_reset ,
23852457};
23862458
@@ -2400,6 +2472,9 @@ static void msdc_of_property_parse(struct platform_device *pdev,
24002472 of_property_read_u32 (pdev -> dev .of_node , "hs400-ds-delay" ,
24012473 & host -> hs400_ds_delay );
24022474
2475+ of_property_read_u32 (pdev -> dev .of_node , "mediatek,hs400-ds-dly3" ,
2476+ & host -> hs400_ds_dly3 );
2477+
24032478 of_property_read_u32 (pdev -> dev .of_node , "mediatek,hs200-cmd-int-delay" ,
24042479 & host -> hs200_cmd_int_delay );
24052480
0 commit comments