From 33585de2ff202e395b5819df04c16a761e0ed2c8 Mon Sep 17 00:00:00 2001 From: long yu Date: Thu, 21 Feb 2019 15:22:01 +0800 Subject: [PATCH] storage: emmc: Add HS400 busmode support for G12B-RevB [1/1] PD#SWPL-5040 Problem: not support HS400 busmode Solution: add HS400 busmode support for G12B-RevB Verify: T962X-R311,TL1-T962X2_X301,G12B-W400 Change-Id: I11a1f47b9473fa341c7d754a51d6e270551758a7 Signed-off-by: long yu --- arch/arm/boot/dts/amlogic/g12b_a311d_w400.dts | 6 +- arch/arm/boot/dts/amlogic/mesong12b.dtsi | 3 +- arch/arm64/boot/dts/amlogic/g12b_a311d_w400.dts | 6 +- arch/arm64/boot/dts/amlogic/mesong12b.dtsi | 3 +- drivers/amlogic/clk/g12a/g12a_clk_sdemmc.c | 2 +- drivers/amlogic/mmc/aml_sd_emmc.c | 16 +- drivers/amlogic/mmc/aml_sd_emmc_v3.c | 240 +++++++++++++++++++++--- drivers/mmc/core/mmc.c | 21 ++- include/linux/amlogic/aml_sd_emmc_v3.h | 15 +- include/linux/amlogic/sd.h | 1 + include/linux/mmc/emmc_partitions.h | 8 + 11 files changed, 278 insertions(+), 43 deletions(-) diff --git a/arch/arm/boot/dts/amlogic/g12b_a311d_w400.dts b/arch/arm/boot/dts/amlogic/g12b_a311d_w400.dts index 9a6d701..d2f9141 100644 --- a/arch/arm/boot/dts/amlogic/g12b_a311d_w400.dts +++ b/arch/arm/boot/dts/amlogic/g12b_a311d_w400.dts @@ -1186,9 +1186,9 @@ /* "MMC_CAP_1_8V_DDR", */ "MMC_CAP_HW_RESET", "MMC_CAP_ERASE", - "MMC_CAP_CMD23"; - caps2 = "MMC_CAP2_HS200"; - /* "MMC_CAP2_HS400";*/ + "MMC_CAP_CMD23", + "MMC_CAP_DRIVER_TYPE_A"; + caps2 = "MMC_CAP2_HS200", "MMC_CAP2_HS400"; f_min = <400000>; f_max = <200000000>; }; diff --git a/arch/arm/boot/dts/amlogic/mesong12b.dtsi b/arch/arm/boot/dts/amlogic/mesong12b.dtsi index 5873b9c..0962fd8 100644 --- a/arch/arm/boot/dts/amlogic/mesong12b.dtsi +++ b/arch/arm/boot/dts/amlogic/mesong12b.dtsi @@ -1423,8 +1423,9 @@ <&clkc CLKID_SD_EMMC_C_P0_COMP>, <&clkc CLKID_FCLK_DIV2>, <&clkc CLKID_FCLK_DIV5>, + <&clkc CLKID_FCLK_DIV2P5>, <&xtal>; - clock-names = "core", "clkin0", "clkin1", "clkin2", "xtal"; + clock-names = "core","clkin0","clkin1","clkin2","clkin3","xtal"; bus-width = <8>; cap-sd-highspeed; diff --git a/arch/arm64/boot/dts/amlogic/g12b_a311d_w400.dts b/arch/arm64/boot/dts/amlogic/g12b_a311d_w400.dts index 9a70c6a..63021958 100644 --- a/arch/arm64/boot/dts/amlogic/g12b_a311d_w400.dts +++ b/arch/arm64/boot/dts/amlogic/g12b_a311d_w400.dts @@ -1186,9 +1186,9 @@ /* "MMC_CAP_1_8V_DDR", */ "MMC_CAP_HW_RESET", "MMC_CAP_ERASE", - "MMC_CAP_CMD23"; - caps2 = "MMC_CAP2_HS200"; - /* "MMC_CAP2_HS400";*/ + "MMC_CAP_CMD23", + "MMC_CAP_DRIVER_TYPE_A"; + caps2 = "MMC_CAP2_HS200", "MMC_CAP2_HS400"; f_min = <400000>; f_max = <200000000>; }; diff --git a/arch/arm64/boot/dts/amlogic/mesong12b.dtsi b/arch/arm64/boot/dts/amlogic/mesong12b.dtsi index 7cf0a05..062c813 100644 --- a/arch/arm64/boot/dts/amlogic/mesong12b.dtsi +++ b/arch/arm64/boot/dts/amlogic/mesong12b.dtsi @@ -1423,8 +1423,9 @@ <&clkc CLKID_SD_EMMC_C_P0_COMP>, <&clkc CLKID_FCLK_DIV2>, <&clkc CLKID_FCLK_DIV5>, + <&clkc CLKID_FCLK_DIV2P5>, <&xtal>; - clock-names = "core", "clkin0", "clkin1", "clkin2", "xtal"; + clock-names = "core","clkin0","clkin1","clkin2","clkin3","xtal"; bus-width = <8>; cap-sd-highspeed; diff --git a/drivers/amlogic/clk/g12a/g12a_clk_sdemmc.c b/drivers/amlogic/clk/g12a/g12a_clk_sdemmc.c index 6ee8f91..0912789 100644 --- a/drivers/amlogic/clk/g12a/g12a_clk_sdemmc.c +++ b/drivers/amlogic/clk/g12a/g12a_clk_sdemmc.c @@ -27,7 +27,7 @@ #include "g12a.h" static const char * const sd_emmc_parent_names[] = { "xtal", "fclk_div2", - "fclk_div3", "fclk_div5", "fclk_div7", "mpll2", "mpll3", "gp0_pll" }; + "fclk_div3", "fclk_div5", "fclk_div2p5", "mpll2", "mpll3", "gp0_pll" }; static struct clk_mux sd_emmc_p0_mux_A = { .reg = (void *)HHI_SD_EMMC_CLK_CNTL, diff --git a/drivers/amlogic/mmc/aml_sd_emmc.c b/drivers/amlogic/mmc/aml_sd_emmc.c index 9cb1d42..f679829 100644 --- a/drivers/amlogic/mmc/aml_sd_emmc.c +++ b/drivers/amlogic/mmc/aml_sd_emmc.c @@ -3325,6 +3325,16 @@ static int meson_mmc_probe(struct platform_device *pdev) #endif /* CONFIG_MESON_CPU_EMULATOR */ } pr_info("%s() : success!\n", __func__); + if (host->ctrl_ver >= 3) { + ret = device_create_file(&pdev->dev, &dev_attr_emmc_eyetest); + if (ret) + dev_warn(mmc_dev(host->mmc), + "Unable to creat sysfs attributes\n"); + ret = device_create_file(&pdev->dev, &dev_attr_emmc_clktest); + if (ret) + dev_warn(mmc_dev(host->mmc), + "Unable to creat sysfs attributes\n"); + } return 0; free_host: @@ -3554,9 +3564,11 @@ static struct meson_mmc_data mmc_data_g12b = { .sdmmc.hs.core_phase = 1, .sdmmc.ddr.core_phase = 2, .sdmmc.ddr.tx_phase = 0, - .sdmmc.hs2.core_phase = 3, + .sdmmc.hs2.core_phase = 2, .sdmmc.hs2.tx_phase = 0, - .sdmmc.hs4.tx_delay = 0, + .sdmmc.hs4.tx_phase = 0, + .sdmmc.hs4.core_phase = 0, + .sdmmc.hs4.tx_delay = 16, .sdmmc.sd_hs.core_phase = 2, .sdmmc.sdr104.core_phase = 2, .sdmmc.sdr104.tx_phase = 0, diff --git a/drivers/amlogic/mmc/aml_sd_emmc_v3.c b/drivers/amlogic/mmc/aml_sd_emmc_v3.c index bfc495a..79f362a 100644 --- a/drivers/amlogic/mmc/aml_sd_emmc_v3.c +++ b/drivers/amlogic/mmc/aml_sd_emmc_v3.c @@ -231,7 +231,10 @@ static int meson_mmc_clk_set_rate_v3(struct mmc_host *mmc, if (aml_card_type_mmc(pdata)) { if ((clk_ios >= 200000000) && conf->ddr) { - src0_clk = devm_clk_get(host->dev, "clkin2"); + if (host->data->chip_type == MMC_CHIP_G12B) + src0_clk = devm_clk_get(host->dev, "clkin3"); + else + src0_clk = devm_clk_get(host->dev, "clkin2"); ret = clk_set_parent(host->mux_parent[0], src0_clk); if (ret) pr_warn("set src0 as comp0 parent error\n"); @@ -239,13 +242,18 @@ static int meson_mmc_clk_set_rate_v3(struct mmc_host *mmc, host->mux_parent[0]); if (ret) pr_warn("set comp0 as mux_clk parent error\n"); - } else if ((host->data->chip_type == MMC_CHIP_TL1) + } else if (((host->data->chip_type == MMC_CHIP_TL1) + || (host->data->chip_type == MMC_CHIP_G12B)) && (clk_ios >= 166000000)) { src0_clk = devm_clk_get(host->dev, "clkin3"); if (ret) - pr_warn("not get GP0\n"); - ret = clk_set_rate(src0_clk, 792000000); - pr_warn("set rate gp0>>>>>>>>>clk:%lu\n", + pr_warn("not get clkin3\n"); + if (host->data->chip_type == MMC_CHIP_TL1) { + ret = clk_set_rate(src0_clk, 792000000); + if (ret) + pr_warn("not set tl1-792\n"); + } + pr_warn("set rate clkin3>>>>>>>>clk:%lu\n", clk_get_rate(src0_clk)); ret = clk_set_parent(host->mux_parent[0], src0_clk); @@ -290,11 +298,11 @@ static int meson_mmc_clk_set_rate_v3(struct mmc_host *mmc, pdata->stop_clk = 0; } #endif - pr_debug("actual_clock :%u, HHI_nand: 0x%x\n", + pr_info("actual_clock :%u, HHI_nand: 0x%x\n", mmc->actual_clock, readl(host->clksrc_base + (HHI_NAND_CLK_CNTL << 2))); - pr_debug("[%s] after clock: 0x%x\n", + pr_info("[%s] after clock: 0x%x\n", __func__, readl(host->base + SD_EMMC_CLOCK_V3)); return ret; @@ -342,7 +350,8 @@ static void aml_sd_emmc_set_timing_v3(struct amlsd_platform *pdata, if (pdata->tx_delay != 0) clkc->tx_delay = pdata->tx_delay; - if ((host->data->chip_type == MMC_CHIP_TL1) + if (((host->data->chip_type == MMC_CHIP_TL1) + || (host->data->chip_type == MMC_CHIP_G12B)) && aml_card_type_mmc(pdata)) { clkc->core_phase = para->hs4.core_phase; clkc->tx_phase = para->hs4.tx_phase; @@ -643,7 +652,7 @@ irqreturn_t meson_mmc_irq_thread_v3(int irq, void *dev_id) } static int aml_sd_emmc_cali_v3(struct mmc_host *mmc, - u8 opcode, u8 *blk_test, u32 blksz, u32 blocks) + u8 opcode, u8 *blk_test, u32 blksz, u32 blocks, u8 *pattern) { struct amlsd_platform *pdata = mmc_priv(mmc); struct amlsd_host *host = pdata->host; @@ -654,7 +663,14 @@ static int aml_sd_emmc_cali_v3(struct mmc_host *mmc, struct scatterlist sg; cmd.opcode = opcode; - cmd.arg = ((SZ_1M * (36 + 3)) / 512); + if (!strcmp(pattern, MMC_PATTERN_NAME)) + cmd.arg = MMC_PATTERN_OFFSET; + else if (!strcmp(pattern, MMC_MAGIC_NAME)) + cmd.arg = MMC_MAGIC_OFFSET; + else if (!strcmp(pattern, MMC_RANDOM_NAME)) + cmd.arg = MMC_RANDOM_OFFSET; + else if (!strcmp(pattern, MMC_DTB_NAME)) + cmd.arg = MMC_DTB_OFFSET; cmd.flags = MMC_RSP_R1 | MMC_CMD_ADTC; stop.opcode = MMC_STOP_TRANSMISSION; @@ -678,6 +694,28 @@ static int aml_sd_emmc_cali_v3(struct mmc_host *mmc, return data.error | cmd.error; } +static int emmc_test_bus(struct mmc_host *mmc) +{ + int err = 0; + u32 blksz = 512; + struct amlsd_platform *pdata = mmc_priv(mmc); + struct amlsd_host *host = pdata->host; + + err = aml_sd_emmc_cali_v3(mmc, MMC_READ_MULTIPLE_BLOCK, + host->blk_test, blksz, 40, MMC_PATTERN_NAME); + if (err) + return err; + err = aml_sd_emmc_cali_v3(mmc, MMC_READ_MULTIPLE_BLOCK, + host->blk_test, blksz, 80, MMC_RANDOM_NAME); + if (err) + return err; + err = aml_sd_emmc_cali_v3(mmc, MMC_READ_MULTIPLE_BLOCK, + host->blk_test, blksz, 40, MMC_MAGIC_NAME); + if (err) + return err; + return err; +} + static int emmc_send_cmd(struct mmc_host *mmc, u32 opcode, u32 arg, unsigned int flags) { @@ -752,7 +790,7 @@ RETRY: if (line_x < 9) aml_sd_emmc_cali_v3(mmc, MMC_READ_MULTIPLE_BLOCK, - host->blk_test, blksz, 40); + host->blk_test, blksz, 40, MMC_PATTERN_NAME); else aml_sd_emmc_cmd_v3(mmc); host->is_tunning = 0; @@ -781,7 +819,7 @@ RETRY: writel(0, host->base + SD_EMMC_ADJUST_V3); pdata->intf3 = intf3; pdata->align[line_x] = ((tmp | eyetest_out1) << 32) | eyetest_out0; - pr_info("d1:0x%x,d2:0x%x,u64eyet:0x%016llx,l_x:%d\n", + pr_debug("d1:0x%x,d2:0x%x,u64eyet:0x%016llx,l_x:%d\n", readl(host->base + SD_EMMC_DELAY1_V3), readl(host->base + SD_EMMC_DELAY2_V3), pdata->align[line_x], line_x); @@ -1042,7 +1080,6 @@ static int emmc_ds_manual_sht(struct mmc_host *mmc) struct amlsd_host *host = pdata->host; u32 intf3 = readl(host->base + SD_EMMC_INTF3); struct intf3 *gintf3 = (struct intf3 *)&(intf3); - u32 blksz = 512; int i, err = 0; int match[64]; int best_start = -1, best_size = -1; @@ -1050,18 +1087,16 @@ static int emmc_ds_manual_sht(struct mmc_host *mmc) host->is_tunning = 1; for (i = 0; i < 64; i++) { - gintf3->ds_sht_m += 1; - writel(intf3, host->base + SD_EMMC_INTF3); - pdata->intf3 = intf3; - err = aml_sd_emmc_cali_v3(mmc, - MMC_READ_MULTIPLE_BLOCK, - host->blk_test, blksz, 20); + err = emmc_test_bus(mmc); pr_debug("intf3: 0x%x, err[%d]: %d\n", readl(host->base + SD_EMMC_INTF3), i, err); if (!err) match[i] = 0; else match[i] = -1; + gintf3->ds_sht_m += 1; + writel(intf3, host->base + SD_EMMC_INTF3); + pdata->intf3 = intf3; } for (i = 0; i < 64; i++) { if (match[i] == 0) { @@ -1099,6 +1134,7 @@ static int emmc_ds_manual_sht(struct mmc_host *mmc) gintf3->ds_sht_m = best_start + best_size / 2; writel(intf3, host->base + SD_EMMC_INTF3); pdata->intf3 = intf3; + pdata->win_start = best_start; pr_info("ds_sht:%u, window:%d, intf3:0x%x, clock:0x%x", gintf3->ds_sht_m, best_size, readl(host->base + SD_EMMC_INTF3), @@ -1129,6 +1165,98 @@ static void aml_emmc_hs400_tl1(struct mmc_host *mmc) emmc_ds_manual_sht(mmc); } +static int emmc_data_alignment(struct mmc_host *mmc, int best_size) +{ + struct amlsd_platform *pdata = mmc_priv(mmc); + struct amlsd_host *host = pdata->host; + u32 delay1 = readl(host->base + SD_EMMC_DELAY1_V3); + u32 delay2 = readl(host->base + SD_EMMC_DELAY2_V3); + u32 intf3 = readl(host->base + SD_EMMC_INTF3); + struct intf3 *gintf3 = (struct intf3 *)&(intf3); + u32 delay1_bak = delay1; + u32 delay2_bak = delay2; + u32 intf3_bak = intf3; + int line_x, i, err = 0, win_new, blksz = 512; + u32 d[8]; + + host->is_tunning = 1; + gintf3->ds_sht_m = pdata->win_start + 4; + writel(intf3, host->base + SD_EMMC_INTF3); + for (line_x = 0; line_x < 8; line_x++) { + for (i = 0; i < 20; i++) { + if (line_x < 5) { + delay1 += (1 << 6*line_x); + writel(delay1, host->base + SD_EMMC_DELAY1_V3); + } else { + delay2 += (1 << 6*(line_x - 5)); + writel(delay2, host->base + SD_EMMC_DELAY2_V3); + } + err = aml_sd_emmc_cali_v3(mmc, MMC_READ_MULTIPLE_BLOCK, + host->blk_test, blksz, 40, MMC_RANDOM_NAME); + if (err) { + pr_info("[%s]adjust line_x[%d]:%d\n", + __func__, line_x, i); + d[line_x] = i; + delay1 = delay1_bak; + delay2 = delay2_bak; + writel(delay1_bak, + host->base + SD_EMMC_DELAY1_V3); + writel(delay2_bak, + host->base + SD_EMMC_DELAY2_V3); + break; + } + } + if (i == 20) { + pr_info("[%s][%d] return set default value", + __func__, __LINE__); + writel(delay1_bak, host->base + SD_EMMC_DELAY1_V3); + writel(delay2_bak, host->base + SD_EMMC_DELAY2_V3); + writel(intf3_bak, host->base + SD_EMMC_INTF3); + host->is_tunning = 0; + return -1; + } + } + delay1 += (d[0]<<0)|(d[1]<<6)|(d[2]<<12)|(d[3]<<18)|(d[4]<<24); + delay2 += (d[5]<<0)|(d[6]<<6)|(d[7]<<12); + writel(delay1, host->base + SD_EMMC_DELAY1_V3); + writel(delay2, host->base + SD_EMMC_DELAY2_V3); + pr_info("delay1:0x%x, delay2:0x%x\n", + readl(host->base + SD_EMMC_DELAY1_V3), + readl(host->base + SD_EMMC_DELAY2_V3)); + gintf3->ds_sht_m = 0; + writel(intf3, host->base + SD_EMMC_INTF3); + win_new = emmc_ds_manual_sht(mmc); + if (win_new < best_size) { + pr_info("[%s][%d] win_new:%d < win_old:%d,set default!", + __func__, __LINE__, win_new, best_size); + writel(delay1_bak, host->base + SD_EMMC_DELAY1_V3); + writel(delay2_bak, host->base + SD_EMMC_DELAY2_V3); + writel(intf3_bak, host->base + SD_EMMC_INTF3); + pr_info("intf3:0x%x, delay1:0x%x, delay2:0x%x\n", + readl(host->base + SD_EMMC_INTF3), + readl(host->base + SD_EMMC_DELAY1_V3), + readl(host->base + SD_EMMC_DELAY2_V3)); + } + host->is_tunning = 0; + return 0; +} + +static void aml_emmc_hs400_Revb(struct mmc_host *mmc) +{ + struct amlsd_platform *pdata = mmc_priv(mmc); + struct amlsd_host *host = pdata->host; + u32 delay2 = 0; + int win_size = 0; + + delay2 = readl(host->base + SD_EMMC_DELAY2_V3); + delay2 += (pdata->cmd_c<<24); + writel(delay2, host->base + SD_EMMC_DELAY2_V3); + pr_info("[%s], delay1: 0x%x, delay2: 0x%x\n", + __func__, readl(host->base + SD_EMMC_DELAY1_V3), + readl(host->base + SD_EMMC_DELAY2_V3)); + win_size = emmc_ds_manual_sht(mmc); + emmc_data_alignment(mmc, win_size); +} /* test clock, return delay cells for one cycle */ static unsigned int aml_sd_emmc_clktest(struct mmc_host *mmc) @@ -1456,6 +1584,7 @@ int aml_emmc_hs200_tl1(struct mmc_host *mmc) int i, err = 0; clk_bak = vclkc; + clkc->tx_phase = para->hs4.tx_phase; clkc->core_phase = para->hs4.core_phase; clkc->tx_delay = para->hs4.tx_delay; if (pdata->tx_delay != 0) @@ -1471,12 +1600,14 @@ int aml_emmc_hs200_tl1(struct mmc_host *mmc) continue; count = fbinary(pdata->align[9]); if (((count >= 10) && (count <= 22)) - || ((count >= 43) && (count <= 56))) + || ((count >= 45) && (count <= 56))) break; } if (i == 63) pr_err("[%s]no find cmd timing\n", __func__); pdata->cmd_c = (delay2 >> 24); + pr_info("cmd->u64eyet:0x%016llx\n", + pdata->align[9]); writel(0, host->base + SD_EMMC_DELAY2_V3); writel(clk_bak, host->base + SD_EMMC_CLOCK_V3); pr_info("[%s][%d] clk config:0x%x\n", @@ -1745,7 +1876,8 @@ int aml_mmc_execute_tuning_v3(struct mmc_host *mmc, u32 opcode) intf3 |= (1<<22); writel(intf3, (host->base + SD_EMMC_INTF3)); pdata->intf3 = intf3; - if (host->data->chip_type == MMC_CHIP_TL1) + if ((host->data->chip_type == MMC_CHIP_TL1) + || (host->data->chip_type == MMC_CHIP_G12B)) aml_emmc_hs200_tl1(mmc); err = 0; } @@ -1764,8 +1896,74 @@ int aml_post_hs400_timming(struct mmc_host *mmc) aml_sd_emmc_clktest(mmc); if (host->data->chip_type == MMC_CHIP_TL1) aml_emmc_hs400_tl1(mmc); + else if (host->data->chip_type == MMC_CHIP_G12B) + aml_emmc_hs400_Revb(mmc); else aml_emmc_hs400_general(mmc); return 0; } +ssize_t emmc_eyetest_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct amlsd_host *host = dev_get_drvdata(dev); + struct mmc_host *mmc = host->mmc; + + mmc_claim_host(mmc); + update_all_line_eyetest(mmc); + mmc_release_host(mmc); + return sprintf(buf, "%s\n", "Emmc all lines eyetest.\n"); +} + +ssize_t emmc_clktest_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct amlsd_host *host = dev_get_drvdata(dev); + struct mmc_host *mmc = host->mmc; + u32 intf3 = readl(host->base + SD_EMMC_INTF3); + struct intf3 *gintf3 = (struct intf3 *)&(intf3); + u32 clktest = 0, delay_cell = 0, clktest_log = 0, count = 0; + u32 vcfg = readl(host->base + SD_EMMC_CFG); + int i = 0; + unsigned int cycle = 0; + + writel(0, (host->base + SD_EMMC_ADJUST_V3)); + + /* one cycle = xxx(ps) */ + cycle = (1000000000 / mmc->actual_clock) * 1000; + vcfg &= ~(1 << 23); + writel(vcfg, host->base + SD_EMMC_CFG); + gintf3->clktest_exp = 8; + gintf3->clktest_on_m = 1; + writel(intf3, host->base + SD_EMMC_INTF3); + clktest_log = readl(host->base + SD_EMMC_CLKTEST_LOG); + clktest = readl(host->base + SD_EMMC_CLKTEST_OUT); + while (!(clktest_log & 0x80000000)) { + udelay(1); + i++; + clktest_log = readl(host->base + SD_EMMC_CLKTEST_LOG); + clktest = readl(host->base + SD_EMMC_CLKTEST_OUT); + if (i > 4000) { + pr_warn("[%s] [%d] emmc clktest error\n", + __func__, __LINE__); + break; + } + } + if (clktest_log & 0x80000000) { + clktest = readl(host->base + SD_EMMC_CLKTEST_OUT); + count = clktest / (1 << 8); + if (vcfg & 0x4) + delay_cell = ((cycle / 2) / count); + else + delay_cell = (cycle / count); + } + pr_info("%s [%d] clktest : %u, delay_cell: %d, count: %u\n", + __func__, __LINE__, clktest, delay_cell, count); + intf3 = readl(host->base + SD_EMMC_INTF3); + gintf3->clktest_on_m = 0; + writel(intf3, host->base + SD_EMMC_INTF3); + vcfg = readl(host->base + SD_EMMC_CFG); + vcfg |= (1 << 23); + writel(vcfg, host->base + SD_EMMC_CFG); + return count; +} diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c index f8d6df5..ae8b397 100644 --- a/drivers/mmc/core/mmc.c +++ b/drivers/mmc/core/mmc.c @@ -1131,7 +1131,10 @@ static int mmc_select_hs400(struct mmc_card *card) unsigned int max_dtr; int err = 0; u8 val; - +#ifdef CONFIG_AMLOGIC_MMC + u8 raw_driver_strength = card->ext_csd.raw_driver_strength; + u8 ds = (host->caps >> 23) & 0x7; +#endif /* * HS400 mode requires 8-bit bus width */ @@ -1175,13 +1178,25 @@ static int mmc_select_hs400(struct mmc_card *card) /* Switch card to HS400 */ #ifdef CONFIG_AMLOGIC_MMC - if (card->ext_csd.raw_driver_strength & (1 << 1)) { + if (ds) { + if (ds & (1 << 0)) { + raw_driver_strength &= (1 << 0); + pr_info("%s:use ds type0\n", + mmc_hostname(host)); + /*3 -> type4 -> MMC_CAP_DRIVER_TYPED*/ + } else if (ds & (1 << 3)) { + raw_driver_strength &= ~(1 << 1); + pr_info("%s:use ds type4\n", + mmc_hostname(host)); + } + } + if (raw_driver_strength & (1 << 1)) { val = (0x1 << EXT_CSD_DRV_STR_SHIFT) | EXT_CSD_TIMING_HS400; pr_info("%s: support driver strength type 1\n", mmc_hostname(host)); - } else if (card->ext_csd.raw_driver_strength & (1 << 4)) { + } else if (raw_driver_strength & (1 << 4)) { val = (0x4 << EXT_CSD_DRV_STR_SHIFT) | EXT_CSD_TIMING_HS400; diff --git a/include/linux/amlogic/aml_sd_emmc_v3.h b/include/linux/amlogic/aml_sd_emmc_v3.h index 8e9d96e..de6dab7 100644 --- a/include/linux/amlogic/aml_sd_emmc_v3.h +++ b/include/linux/amlogic/aml_sd_emmc_v3.h @@ -29,15 +29,14 @@ irqreturn_t meson_mmc_irq_thread_v3(int irq, void *dev_id); int aml_post_hs400_timming(struct mmc_host *mmc); -/* extern ssize_t emmc_eyetest_show(struct device *dev, - * struct device_attribute *attr, char *buf); - */ +extern ssize_t emmc_eyetest_show(struct device *dev, + struct device_attribute *attr, char *buf); -/* extern ssize_t emmc_clktest_show(struct device *dev, - * struct device_attribute *attr, char *buf); - */ -/* DEVICE_ATTR(emmc_eyetest, S_IRUGO, emmc_eyetest_show, NULL);*/ -/*DEVICE_ATTR(emmc_clktest, S_IRUGO, emmc_clktest_show, NULL);*/ +extern ssize_t emmc_clktest_show(struct device *dev, + struct device_attribute *attr, char *buf); + +DEVICE_ATTR(emmc_eyetest, 0444, emmc_eyetest_show, NULL); +DEVICE_ATTR(emmc_clktest, 0444, emmc_clktest_show, NULL); #endif diff --git a/include/linux/amlogic/sd.h b/include/linux/amlogic/sd.h index cae0a23..c051df4 100644 --- a/include/linux/amlogic/sd.h +++ b/include/linux/amlogic/sd.h @@ -279,6 +279,7 @@ struct amlsd_platform { unsigned int dly1; unsigned int dly2; unsigned int intf3; + unsigned int win_start; unsigned int irq_sdio_sleep; unsigned int clock; /* signalling voltage (1.8V or 3.3V) */ diff --git a/include/linux/mmc/emmc_partitions.h b/include/linux/mmc/emmc_partitions.h index aea6f69..e9adda0 100644 --- a/include/linux/mmc/emmc_partitions.h +++ b/include/linux/mmc/emmc_partitions.h @@ -25,6 +25,14 @@ #define SZ_1M 0x00100000 +#define MMC_PATTERN_NAME "pattern" +#define MMC_PATTERN_OFFSET ((SZ_1M*(36+3))/512) +#define MMC_MAGIC_NAME "magic" +#define MMC_MAGIC_OFFSET ((SZ_1M*(36+6))/512) +#define MMC_RANDOM_NAME "random" +#define MMC_RANDOM_OFFSET ((SZ_1M*(36+7))/512) +#define MMC_DTB_NAME "dtb" +#define MMC_DTB_OFFSET ((SZ_1M*(36+4))/512) /* the size of bootloader partition */ #define MMC_BOOT_PARTITION_SIZE (4*SZ_1M) -- 2.7.4