/* Initialize DLL (Programmable Delay Line) */ static uint32_t sdhci_msm_init_dll(struct sdhci_host *host) { uint32_t pwr_save = 0; uint32_t timeout = SDHCI_DLL_TIMEOUT; pwr_save = REG_READ32(host, SDCC_VENDOR_SPECIFIC_FUNC) & SDCC_DLL_PWR_SAVE_EN; /* PWR SAVE to 0 */ if (pwr_save) REG_WRITE32(host, (REG_READ32(host, SDCC_VENDOR_SPECIFIC_FUNC) & ~SDCC_DLL_PWR_SAVE_EN), SDCC_VENDOR_SPECIFIC_FUNC); /* Set DLL_RST to 1 */ REG_WRITE32(host, (REG_READ32(host, SDCC_DLL_CONFIG_REG) | SDCC_DLL_RESET_EN), SDCC_DLL_CONFIG_REG); /* Set DLL_PDN to 1 */ REG_WRITE32(host, (REG_READ32(host, SDCC_DLL_CONFIG_REG) | SDCC_DLL_PDN_EN), SDCC_DLL_CONFIG_REG); /* Set frequency field in DLL_CONFIG */ msm_set_dll_freq(host); /* Write 0 to DLL_RST */ REG_WRITE32(host, (REG_READ32(host, SDCC_DLL_CONFIG_REG) & ~SDCC_DLL_RESET_EN), SDCC_DLL_CONFIG_REG); /* Write 0 to DLL_PDN */ REG_WRITE32(host, (REG_READ32(host, SDCC_DLL_CONFIG_REG) & ~SDCC_DLL_PDN_EN), SDCC_DLL_CONFIG_REG); /* Write 1 to DLL_EN */ REG_WRITE32(host, (REG_READ32(host, SDCC_DLL_CONFIG_REG) | SDCC_DLL_EN), SDCC_DLL_CONFIG_REG); /* Write 1 to CLK_OUT_EN */ REG_WRITE32(host, (REG_READ32(host, SDCC_DLL_CONFIG_REG) | SDCC_DLL_CLK_OUT_EN), SDCC_DLL_CONFIG_REG); /* Wait for DLL_LOCK in DLL_STATUS register, wait time 50us */ while(!((REG_READ32(host, SDCC_REG_DLL_STATUS)) & SDCC_DLL_LOCK_STAT)); { udelay(1); timeout--; if (!timeout) { dprintf(CRITICAL, "%s: Failed to get DLL lock: 0x%08x\n", __func__, REG_READ32(host, SDCC_REG_DLL_STATUS)); return 1; } } /* Set the powersave back on */ if (pwr_save) REG_WRITE32(host, (REG_READ32(host, SDCC_VENDOR_SPECIFIC_FUNC) | SDCC_DLL_PWR_SAVE_EN), SDCC_VENDOR_SPECIFIC_FUNC); return 0; }
/* Initialize DLL (Programmable Delay Line) */ static uint32_t sdhci_msm_init_dll(struct sdhci_host *host) { uint32_t pwr_save = 0; uint32_t timeout = SDHCI_DLL_TIMEOUT; uint32_t dll_cfg2; uint32_t mclk_clk_freq = 0; pwr_save = REG_READ32(host, SDCC_VENDOR_SPECIFIC_FUNC) & SDCC_DLL_PWR_SAVE_EN; /* Dll sequence needs additional steps for sdcc core version 42 */ if (host->major == 1 && host->minor >= 0x42) { /* Disable DLL clock before configuring */ sdhci_dll_clk_enable(host, 0); } /* PWR SAVE to 0 */ if (pwr_save) REG_WRITE32(host, (REG_READ32(host, SDCC_VENDOR_SPECIFIC_FUNC) & ~SDCC_DLL_PWR_SAVE_EN), SDCC_VENDOR_SPECIFIC_FUNC); /* Set DLL_RST to 1 */ REG_WRITE32(host, (REG_READ32(host, SDCC_DLL_CONFIG_REG) | SDCC_DLL_RESET_EN), SDCC_DLL_CONFIG_REG); /* Set DLL_PDN to 1 */ REG_WRITE32(host, (REG_READ32(host, SDCC_DLL_CONFIG_REG) | SDCC_DLL_PDN_EN), SDCC_DLL_CONFIG_REG); /* Set frequency field in DLL_CONFIG */ msm_set_dll_freq(host); /* Configure the mclk freq based on the current clock rate * and fll cycle count */ if (host->major == 1 && host->minor >= 0x42) { dll_cfg2 = REG_READ32(host, SDCC_HC_REG_DLL_CONFIG_2); if (dll_cfg2 & SDCC_FLL_CYCLE_CNT) mclk_clk_freq = (host->cur_clk_rate / TCXO_FREQ) * 8; else mclk_clk_freq = (host->cur_clk_rate / TCXO_FREQ) * 4; REG_WRITE32(host, ((REG_READ32(host, SDCC_HC_REG_DLL_CONFIG_2) & ~(0xFF << 10)) | (mclk_clk_freq << 10)), SDCC_HC_REG_DLL_CONFIG_2); udelay(5); } /* Write 0 to DLL_RST */ REG_WRITE32(host, (REG_READ32(host, SDCC_DLL_CONFIG_REG) & ~SDCC_DLL_RESET_EN), SDCC_DLL_CONFIG_REG); /* Write 0 to DLL_PDN */ REG_WRITE32(host, (REG_READ32(host, SDCC_DLL_CONFIG_REG) & ~SDCC_DLL_PDN_EN), SDCC_DLL_CONFIG_REG); /* Set the mclk clock and enable the dll clock */ if (host->major == 1 && host->minor >= 0x42) { msm_set_dll_freq(host); sdhci_dll_clk_enable(host, 1); } /* Write 1 to DLL_EN */ REG_WRITE32(host, (REG_READ32(host, SDCC_DLL_CONFIG_REG) | SDCC_DLL_EN), SDCC_DLL_CONFIG_REG); /* Write 1 to CLK_OUT_EN */ REG_WRITE32(host, (REG_READ32(host, SDCC_DLL_CONFIG_REG) | SDCC_DLL_CLK_OUT_EN), SDCC_DLL_CONFIG_REG); /* Wait for DLL_LOCK in DLL_STATUS register, wait time 50us */ while(!((REG_READ32(host, SDCC_REG_DLL_STATUS)) & SDCC_DLL_LOCK_STAT)) { udelay(1); timeout--; if (!timeout) { dprintf(CRITICAL, "%s: Failed to get DLL lock: 0x%08x\n", __func__, REG_READ32(host, SDCC_REG_DLL_STATUS)); return 1; } } /* Set the powersave back on */ if (pwr_save) REG_WRITE32(host, (REG_READ32(host, SDCC_VENDOR_SPECIFIC_FUNC) | SDCC_DLL_PWR_SAVE_EN), SDCC_VENDOR_SPECIFIC_FUNC); return 0; }