ThinkNotes

Simple is not easy | 化繁为简,知易行难

0%

高通平台 -- QCOM BH202 SDR50 tuning问题记录

QCOM BH202 SDR50 tuning问题

问题描述

现象:QCOM+BH202平台,SDR50模式下,Host侧发送tuning CMD19命令处理响应失败(TIMEOUT),导致无法工作在SDR50模式,BH202驱动log打印wait DLL unlock和CMD19 timeout。其他模式如SDR104模式可以正常工作。

分析:经SD CMD/DATA line信号测量,SD card发送了CMD19的响应,问题出在SD Host侧未处理响应。

问题指向SD Host侧在SDR50模式的tuning配置有问题。

解决方案

BH202 tuning sdr50.drawio

如图是SD Host - BH20X bridge - SD card系统。

通常SD Host直连SD card时,SDR50模式host clock <=100MHz, 不需要执行SDR50 tuning流程,SDR50 tuning只是可选项。

但是BH20X bridge的数字逻辑要求SDR50模式下也走SDR50 tuning流程,否则SDR50模式无法正常工作。

因此需要修改Host驱动,支持SDR50 tuning,包括两个部分:

  • 配置DLL,以支持tuning block所需要的时钟
  • 发送多个(16个) tuning block CMD19命令,解析SD卡响应数据,统计tuning pass相位窗口

BH20X驱动也需要适配,调用Host tuning函数时使用高通的tuning流程,而不再直接发tuning block CMD19而不配置DLL。

代码说明

如下是SDR50 tuning patch,修改点见三处注释

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
diff --git a/mmc/host/sdhci-bayhub.c b/mmc/host/sdhci-bayhub.c
index 5533d38..762d46c 100644
--- a/mmc/host/sdhci-bayhub.c
+++ b/mmc/host/sdhci-bayhub.c
@@ -2087,7 +2087,7 @@ int sdhci_bht_sdr104_execute_tuning(struct sdhci_host *host, u32 opcode)

int sdhci_bht_sdr50_execute_tuning(struct sdhci_host *host, u32 opcode)
{
-#ifdef MSM_HOST_USED
+#if 0 /* SDR50 host side tuning使用SDR104一样的入口,即调用qcom的sdhci_msm_execute_tuning */
u8 phase, *data_buf;
int size = 64;
int rc = 0;
@@ -3671,7 +3671,7 @@ void ggc_tuning_result_reset(struct sdhci_host *host)
vendor_host->ggc.dll_unlock_reinit_flg = 0;
vendor_host->ggc.tuning_cmd7_timeout_reinit_flg = 0;
vendor_host->ggc.tuning_cmd7_timeout_reinit_cnt = 0;
- vendor_host->ggc.sdr50_notuning_sela_inject_flag = 1;
+ vendor_host->ggc.sdr50_notuning_sela_inject_flag = 0; /* SDR50不需要指定notuning相位,按高通tuning流程执行即可 */
vendor_host->ggc.sdr50_notuning_crc_error_flag = 0;
vendor_host->ggc.degrade = 0;

diff --git a/mmc/host/sdhci-msm.c b/mmc/host/sdhci-msm.c
index 8da7c4f..5a49b7e 100644
--- a/mmc/host/sdhci-msm.c
+++ b/mmc/host/sdhci-msm.c
@@ -1131,6 +1131,10 @@ static bool sdhci_msm_is_tuning_needed(struct sdhci_host *host)
{
struct mmc_ios *ios = &host->mmc->ios;

/* 如果当前模式是SDR50且host flag配置了NEEDS_TUNING,则执行tuning流程(DLL配置和CMD19)
* 注:BH20X驱动默认配置了host->flags SDHCI_SDR50_NEEDS_TUNING
*/
+#ifdef CONFIG_MMC_SDHCI_BH201
+ if (ios->timing == MMC_TIMING_UHS_SDR50 &&
+ host->flags & SDHCI_SDR50_NEEDS_TUNING)
+ return true;
+#endif
/*
* Tuning is required for SDR104, HS200 and HS400 cards and
* if clock frequency is greater than 100MHz in these modes.