X-Git-Url: https://git.librecmc.org/?a=blobdiff_plain;f=drivers%2Fmmc%2Fsunxi_mmc.c;h=e717c44216297fba3583098fad6cb20da8c58d98;hb=d8877e6f8ca4b6c08c0bc9c1fa8f855dc8776044;hp=22335452c56c7e241a4744d0a7ed779226464571;hpb=b9cb64825b5e6efeb715abd8b48d9b12f98973e9;p=oweals%2Fu-boot.git diff --git a/drivers/mmc/sunxi_mmc.c b/drivers/mmc/sunxi_mmc.c index 22335452c5..e717c44216 100644 --- a/drivers/mmc/sunxi_mmc.c +++ b/drivers/mmc/sunxi_mmc.c @@ -9,6 +9,7 @@ */ #include +#include #include #include #include @@ -37,7 +38,7 @@ static int sunxi_mmc_getcd_gpio(int sdc_no) case 2: return sunxi_name_to_gpio(CONFIG_MMC2_CD_PIN); case 3: return sunxi_name_to_gpio(CONFIG_MMC3_CD_PIN); } - return -1; + return -EINVAL; } static int mmc_resource_init(int sdc_no) @@ -72,10 +73,12 @@ static int mmc_resource_init(int sdc_no) mmchost->mmc_no = sdc_no; cd_pin = sunxi_mmc_getcd_gpio(sdc_no); - if (cd_pin != -1) { + if (cd_pin >= 0) { ret = gpio_request(cd_pin, "mmc_cd"); - if (!ret) + if (!ret) { + sunxi_gpio_set_pull(cd_pin, SUNXI_GPIO_PULL_UP); ret = gpio_direction_input(cd_pin); + } } return ret; @@ -117,17 +120,27 @@ static int mmc_set_mod_clk(struct sunxi_mmc_host *mmchost, unsigned int hz) /* determine delays */ if (hz <= 400000) { oclk_dly = 0; - sclk_dly = 7; + sclk_dly = 0; } else if (hz <= 25000000) { oclk_dly = 0; sclk_dly = 5; +#ifdef CONFIG_MACH_SUN9I } else if (hz <= 50000000) { - oclk_dly = 3; - sclk_dly = 5; + oclk_dly = 5; + sclk_dly = 4; } else { /* hz > 50000000 */ oclk_dly = 2; sclk_dly = 4; +#else + } else if (hz <= 50000000) { + oclk_dly = 3; + sclk_dly = 4; + } else { + /* hz > 50000000 */ + oclk_dly = 1; + sclk_dly = 4; +#endif } writel(CCM_MMC_CTRL_ENABLE | pll | CCM_MMC_CTRL_SCLK_DLY(sclk_dly) | @@ -151,8 +164,7 @@ static int mmc_clk_io_on(int sdc_no) /* config ahb clock */ setbits_le32(&ccm->ahb_gate0, 1 << AHB_GATE_OFFSET_MMC(sdc_no)); -#if defined(CONFIG_MACH_SUN6I) || defined(CONFIG_MACH_SUN8I) || \ - defined(CONFIG_MACH_SUN9I) +#ifdef CONFIG_SUNXI_GEN_SUN6I /* unassert reset */ setbits_le32(&ccm->ahb_reset0_cfg, 1 << AHB_RESET_OFFSET_MMC(sdc_no)); #endif @@ -255,9 +267,11 @@ static int mmc_trans_data_by_cpu(struct mmc *mmc, struct mmc_data *data) const uint32_t status_bit = reading ? SUNXI_MMC_STATUS_FIFO_EMPTY : SUNXI_MMC_STATUS_FIFO_FULL; unsigned i; - unsigned byte_cnt = data->blocksize * data->blocks; - unsigned timeout_msecs = 2000; unsigned *buff = (unsigned int *)(reading ? data->dest : data->src); + unsigned byte_cnt = data->blocksize * data->blocks; + unsigned timeout_msecs = byte_cnt >> 8; + if (timeout_msecs < 2000) + timeout_msecs = 2000; /* Always read / write data through the CPU */ setbits_le32(&mmchost->reg->gctrl, SUNXI_MMC_GCTRL_ACCESS_BY_AHB); @@ -425,12 +439,29 @@ static int sunxi_mmc_getcd(struct mmc *mmc) int cd_pin; cd_pin = sunxi_mmc_getcd_gpio(mmchost->mmc_no); - if (cd_pin == -1) + if (cd_pin < 0) return 1; return !gpio_get_value(cd_pin); } +int sunxi_mmc_has_egon_boot_signature(struct mmc *mmc) +{ + char *buf = malloc(512); + int valid_signature = 0; + + if (buf == NULL) + panic("Failed to allocate memory\n"); + + if (mmc_getcd(mmc) && mmc_init(mmc) == 0 && + mmc->block_dev.block_read(mmc->block_dev.dev, 16, 1, buf) == 1 && + strncmp(&buf[4], "eGON.BT0", 8) == 0) + valid_signature = 1; + + free(buf); + return valid_signature; +} + static const struct mmc_ops sunxi_mmc_ops = { .send_cmd = sunxi_mmc_send_cmd, .set_ios = sunxi_mmc_set_ios, @@ -449,7 +480,7 @@ struct mmc *sunxi_mmc_init(int sdc_no) cfg->voltages = MMC_VDD_32_33 | MMC_VDD_33_34; cfg->host_caps = MMC_MODE_4BIT; - cfg->host_caps |= MMC_MODE_HS_52MHz | MMC_MODE_HS | MMC_MODE_HC; + cfg->host_caps |= MMC_MODE_HS_52MHz | MMC_MODE_HS; cfg->b_max = CONFIG_SYS_MMC_MAX_BLK_COUNT; cfg->f_min = 400000;