/* * Function: sdhci msm init * Arg : MSM specific config data for sdhci * Return : None * Flow: : Enable sdhci mode & do msm specific init */ void sdhci_msm_init(struct sdhci_host *host, struct sdhci_msm_data *config) { /* Disable HC mode */ RMWREG32((config->pwrctl_base + SDCC_MCI_HC_MODE), SDHCI_HC_START_BIT, SDHCI_HC_WIDTH, 0); /* Core power reset */ RMWREG32((config->pwrctl_base + SDCC_MCI_POWER), CORE_SW_RST_START, CORE_SW_RST_WIDTH, 1); /* Wait for the core power reset to complete*/ mdelay(1); /* Enable sdhc mode */ RMWREG32((config->pwrctl_base + SDCC_MCI_HC_MODE), SDHCI_HC_START_BIT, SDHCI_HC_WIDTH, SDHCI_HC_MODE_EN); /* Set the FF_CLK_SW_RST_DIS to 1 */ RMWREG32((config->pwrctl_base + SDCC_MCI_HC_MODE), FF_CLK_SW_RST_DIS_START, FF_CLK_SW_RST_DIS_WIDTH, 1); /* * Reset the controller */ sdhci_reset(host, SDHCI_SOFT_RESET); /* * CORE_SW_RST may trigger power irq if previous status of PWRCTL * was either BUS_ON or IO_HIGH. So before we enable the power irq * interrupt in GIC (by registering the interrupt handler), we need to * ensure that any pending power irq interrupt status is acknowledged * otherwise power irq interrupt handler would be fired prematurely. */ sdhci_clear_power_ctrl_irq(config); /* * Register the interrupt handler for pwr irq */ register_int_handler(config->pwr_irq, sdhci_int_handler, (void *)config); unmask_interrupt(config->pwr_irq); /* Enable pwr control interrupt */ writel(SDCC_HC_PWR_CTRL_INT, (config->pwrctl_base + SDCC_HC_PWRCTL_MASK_REG)); config->tuning_done = false; config->calibration_done = false; host->tuning_in_progress = false; }
/* * Function: sdhci msm init * Arg : MSM specific config data for sdhci * Return : None * Flow: : Enable sdhci mode & do msm specific init */ void sdhci_msm_init(struct sdhci_host *host, struct sdhci_msm_data *config) { uint32_t io_switch; uint32_t caps = 0; uint32_t version; /* Disable HC mode */ RMWREG32((config->pwrctl_base + SDCC_MCI_HC_MODE), SDHCI_HC_START_BIT, SDHCI_HC_WIDTH, 0); /* Core power reset */ RMWREG32((config->pwrctl_base + SDCC_MCI_POWER), CORE_SW_RST_START, CORE_SW_RST_WIDTH, 1); /* Wait for the core power reset to complete*/ mdelay(1); /* Enable sdhc mode */ RMWREG32((config->pwrctl_base + SDCC_MCI_HC_MODE), SDHCI_HC_START_BIT, SDHCI_HC_WIDTH, SDHCI_HC_MODE_EN); /* Set the FF_CLK_SW_RST_DIS to 1 */ RMWREG32((config->pwrctl_base + SDCC_MCI_HC_MODE), FF_CLK_SW_RST_DIS_START, FF_CLK_SW_RST_DIS_WIDTH, 1); /* * Reset the controller */ sdhci_reset(host, SDHCI_SOFT_RESET); /* * Some platforms have same SDC instance shared between emmc & sd card. * For such platforms the emmc IO voltage has to be switched from 3.3 to * 1.8 for the contoller to work with emmc. */ if(config->use_io_switch) { io_switch = REG_READ32(host, SDCC_VENDOR_SPECIFIC_FUNC); io_switch |= HC_IO_PAD_PWR_SWITCH | HC_IO_PAD_PWR_SWITCH_EN; REG_WRITE32(host, io_switch, SDCC_VENDOR_SPECIFIC_FUNC); } /* * CORE_SW_RST may trigger power irq if previous status of PWRCTL * was either BUS_ON or IO_HIGH. So before we enable the power irq * interrupt in GIC (by registering the interrupt handler), we need to * ensure that any pending power irq interrupt status is acknowledged * otherwise power irq interrupt handler would be fired prematurely. */ sdhci_clear_power_ctrl_irq(config); /* * Register the interrupt handler for pwr irq */ register_int_handler(config->pwr_irq, (int_handler)sdhci_int_handler, (void *)config); unmask_interrupt(config->pwr_irq); /* Enable pwr control interrupt */ writel(SDCC_HC_PWR_CTRL_INT, (config->pwrctl_base + SDCC_HC_PWRCTL_MASK_REG)); version = readl(host->msm_host->pwrctl_base + MCI_VERSION); host->major = (version & CORE_VERSION_MAJOR_MASK) >> CORE_VERSION_MAJOR_SHIFT; host->minor = (version & CORE_VERSION_MINOR_MASK); /* * For SDCC5 the capabilities registers does not have voltage advertised * Override the values using SDCC_HC_VENDOR_SPECIFIC_CAPABILITIES0 */ if (host->major >= 1 && host->minor != 0x11 && host->minor != 0x12) { caps = REG_READ32(host, SDHCI_CAPS_REG1); if (config->slot == 0x1) REG_WRITE32(host, (caps | SDHCI_1_8_VOL_MASK), SDCC_HC_VENDOR_SPECIFIC_CAPABILITIES0); else REG_WRITE32(host, (caps | SDHCI_3_0_VOL_MASK), SDCC_HC_VENDOR_SPECIFIC_CAPABILITIES0); } config->tuning_done = false; config->calibration_done = false; host->tuning_in_progress = false; }