* [PATCH v4 0/2] mmc: dw_mmc: exynos: Add HS400 support @ 2015-01-14 10:30 ` Alim Akhtar 0 siblings, 0 replies; 24+ messages in thread From: Alim Akhtar @ 2015-01-14 10:30 UTC (permalink / raw) To: linux-mmc Cc: chris, ulf.hansson, jh80.chung, tgih.jun, dianders, alim.akhtar, kgene, linux-arm-kernel, devicetree, linux-samsung-soc, a.kesavan This adds HS400 mode support for exynos dw_mmc host controller. Currently tested on Exynos5800-peach-pi platform for HS400 mode. Tested HS200 mode with this series applied, HS200 still works. Appreciate testing on other exynos5/7 platform which supports emmc5.0 Changes in V4: * drop the idea of changing existing binding for ciu_div as per [1] * addressed comments from Jaehoon Chung [2] [1] http://www.spinics.net/lists/linux-samsung-soc/msg40923.html [2] http://www.spinics.net/lists/devicetree/msg64373.html Changes in V3: rebased on ulf's next (commit: 607b448 mmc: core: Make tuning block patterns static) Seungwon Jeon (2): mmc: dw_mmc: exynos: Support eMMC's HS400 mode ARM: dts: Add HS400 support for exynos5420 and exynos5800 .../devicetree/bindings/mmc/exynos-dw-mshc.txt | 7 + arch/arm/boot/dts/exynos5420-peach-pit.dts | 4 +- arch/arm/boot/dts/exynos5420-pinctrl.dtsi | 7 + arch/arm/boot/dts/exynos5420-smdk5420.dts | 4 +- arch/arm/boot/dts/exynos5800-peach-pi.dts | 4 +- drivers/mmc/host/dw_mmc-exynos.c | 187 ++++++++++++++++---- drivers/mmc/host/dw_mmc-exynos.h | 19 +- drivers/mmc/host/dw_mmc.c | 16 +- drivers/mmc/host/dw_mmc.h | 2 + 9 files changed, 212 insertions(+), 38 deletions(-) -- 1.7.9.5 ^ permalink raw reply [flat|nested] 24+ messages in thread
* [PATCH v4 0/2] mmc: dw_mmc: exynos: Add HS400 support @ 2015-01-14 10:30 ` Alim Akhtar 0 siblings, 0 replies; 24+ messages in thread From: Alim Akhtar @ 2015-01-14 10:30 UTC (permalink / raw) To: linux-arm-kernel This adds HS400 mode support for exynos dw_mmc host controller. Currently tested on Exynos5800-peach-pi platform for HS400 mode. Tested HS200 mode with this series applied, HS200 still works. Appreciate testing on other exynos5/7 platform which supports emmc5.0 Changes in V4: * drop the idea of changing existing binding for ciu_div as per [1] * addressed comments from Jaehoon Chung [2] [1] http://www.spinics.net/lists/linux-samsung-soc/msg40923.html [2] http://www.spinics.net/lists/devicetree/msg64373.html Changes in V3: rebased on ulf's next (commit: 607b448 mmc: core: Make tuning block patterns static) Seungwon Jeon (2): mmc: dw_mmc: exynos: Support eMMC's HS400 mode ARM: dts: Add HS400 support for exynos5420 and exynos5800 .../devicetree/bindings/mmc/exynos-dw-mshc.txt | 7 + arch/arm/boot/dts/exynos5420-peach-pit.dts | 4 +- arch/arm/boot/dts/exynos5420-pinctrl.dtsi | 7 + arch/arm/boot/dts/exynos5420-smdk5420.dts | 4 +- arch/arm/boot/dts/exynos5800-peach-pi.dts | 4 +- drivers/mmc/host/dw_mmc-exynos.c | 187 ++++++++++++++++---- drivers/mmc/host/dw_mmc-exynos.h | 19 +- drivers/mmc/host/dw_mmc.c | 16 +- drivers/mmc/host/dw_mmc.h | 2 + 9 files changed, 212 insertions(+), 38 deletions(-) -- 1.7.9.5 ^ permalink raw reply [flat|nested] 24+ messages in thread
* [PATCH v4 1/2] mmc: dw_mmc: exynos: Support eMMC's HS400 mode 2015-01-14 10:30 ` Alim Akhtar @ 2015-01-14 10:30 ` Alim Akhtar -1 siblings, 0 replies; 24+ messages in thread From: Alim Akhtar @ 2015-01-14 10:30 UTC (permalink / raw) To: linux-mmc Cc: chris, ulf.hansson, jh80.chung, tgih.jun, dianders, alim.akhtar, kgene, linux-arm-kernel, devicetree, linux-samsung-soc, a.kesavan From: Seungwon Jeon <tgih.jun@samsung.com> Implements HS400 mode support for exynos host driver. This also include some updates as new mode is added. Signed-off-by: Seungwon Jeon <tgih.jun@samsung.com> Signed-off-by: Alim Akhtar <alim.akhtar@samsung.com> [Alim: addressed review comments] --- .../devicetree/bindings/mmc/exynos-dw-mshc.txt | 7 + drivers/mmc/host/dw_mmc-exynos.c | 187 ++++++++++++++++---- drivers/mmc/host/dw_mmc-exynos.h | 19 +- drivers/mmc/host/dw_mmc.c | 16 +- drivers/mmc/host/dw_mmc.h | 2 + 5 files changed, 196 insertions(+), 35 deletions(-) diff --git a/Documentation/devicetree/bindings/mmc/exynos-dw-mshc.txt b/Documentation/devicetree/bindings/mmc/exynos-dw-mshc.txt index ee4fc05..dcab52c 100644 --- a/Documentation/devicetree/bindings/mmc/exynos-dw-mshc.txt +++ b/Documentation/devicetree/bindings/mmc/exynos-dw-mshc.txt @@ -36,6 +36,8 @@ Required Properties: in transmit mode and CIU clock phase shift value in receive mode for double data rate mode operation. Refer notes below for the order of the cells and the valid values. +* samsung,dw-mshc-hs400-timing: Specifies the value of CIU TX and RX clock phase + shift value for hs400 mode operation. Notes for the sdr-timing and ddr-timing values: @@ -50,6 +52,9 @@ Required Properties: - if CIU clock divider value is 0 (that is divide by 1), both tx and rx phase shift clocks should be 0. +* read-strobe-delay: RCLK (Data strobe) delay to control HS400 mode + (Latency value for delay line in Read path) + Required properties for a slot (Deprecated - Recommend to use one slot per host): * gpios: specifies a list of gpios used for command, clock and data bus. The @@ -82,5 +87,7 @@ Example: samsung,dw-mshc-ciu-div = <3>; samsung,dw-mshc-sdr-timing = <2 3>; samsung,dw-mshc-ddr-timing = <1 2>; + samsung,dw-mshc-hs400-timing = <0 2>; + read-strobe-delay = <90>; bus-width = <8>; }; diff --git a/drivers/mmc/host/dw_mmc-exynos.c b/drivers/mmc/host/dw_mmc-exynos.c index 12a5eaa..172a2a8 100644 --- a/drivers/mmc/host/dw_mmc-exynos.c +++ b/drivers/mmc/host/dw_mmc-exynos.c @@ -40,7 +40,12 @@ struct dw_mci_exynos_priv_data { u8 ciu_div; u32 sdr_timing; u32 ddr_timing; + u32 hs400_timing; + u32 tuned_sample; u32 cur_speed; + u32 dqs_delay; + u32 saved_dqs_en; + u32 saved_strobe_ctrl; }; static struct dw_mci_exynos_compatible { @@ -71,6 +76,21 @@ static struct dw_mci_exynos_compatible { }, }; +static inline u8 dw_mci_exynos_get_ciu_div(struct dw_mci *host) +{ + struct dw_mci_exynos_priv_data *priv = host->priv; + + if (priv->ctrl_type == DW_MCI_TYPE_EXYNOS4412) + return EXYNOS4412_FIXED_CIU_CLK_DIV; + else if (priv->ctrl_type == DW_MCI_TYPE_EXYNOS4210) + return EXYNOS4210_FIXED_CIU_CLK_DIV; + else if (priv->ctrl_type == DW_MCI_TYPE_EXYNOS7 || + priv->ctrl_type == DW_MCI_TYPE_EXYNOS7_SMU) + return SDMMC_CLKSEL_GET_DIV(mci_readl(host, CLKSEL64)) + 1; + else + return SDMMC_CLKSEL_GET_DIV(mci_readl(host, CLKSEL)) + 1; +} + static int dw_mci_exynos_priv_init(struct dw_mci *host) { struct dw_mci_exynos_priv_data *priv = host->priv; @@ -85,6 +105,16 @@ static int dw_mci_exynos_priv_init(struct dw_mci *host) SDMMC_MPSCTRL_NON_SECURE_WRITE_BIT); } + if (priv->ctrl_type >= DW_MCI_TYPE_EXYNOS5420) { + priv->saved_strobe_ctrl = mci_readl(host, HS400_DLINE_CTRL); + priv->saved_dqs_en = mci_readl(host, HS400_DQS_EN); + priv->saved_dqs_en |= AXI_NON_BLOCKING_WR; + mci_writel(host, HS400_DQS_EN, priv->saved_dqs_en); + if (!priv->dqs_delay) + priv->dqs_delay = + DQS_CTRL_GET_RD_DELAY(priv->saved_strobe_ctrl); + } + return 0; } @@ -92,11 +122,31 @@ static int dw_mci_exynos_setup_clock(struct dw_mci *host) { struct dw_mci_exynos_priv_data *priv = host->priv; - host->bus_hz /= (priv->ciu_div + 1); + host->bus_hz /= priv->ciu_div; return 0; } +static void dw_mci_exynos_set_clksel_timing(struct dw_mci *host, u32 timing) +{ + struct dw_mci_exynos_priv_data *priv = host->priv; + u32 clksel; + + if (priv->ctrl_type == DW_MCI_TYPE_EXYNOS7 || + priv->ctrl_type == DW_MCI_TYPE_EXYNOS7_SMU) + clksel = mci_readl(host, CLKSEL64); + else + clksel = mci_readl(host, CLKSEL); + + clksel = (clksel & ~SDMMC_CLKSEL_TIMING_MASK) | timing; + + if (priv->ctrl_type == DW_MCI_TYPE_EXYNOS7 || + priv->ctrl_type == DW_MCI_TYPE_EXYNOS7_SMU) + mci_writel(host, CLKSEL64, clksel); + else + mci_writel(host, CLKSEL, clksel); +} + #ifdef CONFIG_PM_SLEEP static int dw_mci_exynos_suspend(struct device *dev) { @@ -172,30 +222,38 @@ static void dw_mci_exynos_prepare_command(struct dw_mci *host, u32 *cmdr) } } -static void dw_mci_exynos_set_ios(struct dw_mci *host, struct mmc_ios *ios) +static void dw_mci_exynos_config_hs400(struct dw_mci *host, u32 timing) { struct dw_mci_exynos_priv_data *priv = host->priv; - unsigned int wanted = ios->clock; - unsigned long actual; - u8 div = priv->ciu_div + 1; + u32 dqs, strobe; - if (ios->timing == MMC_TIMING_MMC_DDR52) { - if (priv->ctrl_type == DW_MCI_TYPE_EXYNOS7 || - priv->ctrl_type == DW_MCI_TYPE_EXYNOS7_SMU) - mci_writel(host, CLKSEL64, priv->ddr_timing); - else - mci_writel(host, CLKSEL, priv->ddr_timing); - /* Should be double rate for DDR mode */ - if (ios->bus_width == MMC_BUS_WIDTH_8) - wanted <<= 1; + /* + * Not suppported to configure register + * related to HS400 + */ + if (priv->ctrl_type < DW_MCI_TYPE_EXYNOS5420) + return; + + dqs = priv->saved_dqs_en; + strobe = priv->saved_strobe_ctrl; + + if (timing == MMC_TIMING_MMC_HS400) { + dqs |= DATA_STROBE_EN; + strobe = DQS_CTRL_RD_DELAY(strobe, priv->dqs_delay); } else { - if (priv->ctrl_type == DW_MCI_TYPE_EXYNOS7 || - priv->ctrl_type == DW_MCI_TYPE_EXYNOS7_SMU) - mci_writel(host, CLKSEL64, priv->sdr_timing); - else - mci_writel(host, CLKSEL, priv->sdr_timing); + dqs &= ~DATA_STROBE_EN; } + mci_writel(host, HS400_DQS_EN, dqs); + mci_writel(host, HS400_DLINE_CTRL, strobe); +} + +static void dw_mci_exynos_adjust_clock(struct dw_mci *host, unsigned int wanted) +{ + struct dw_mci_exynos_priv_data *priv = host->priv; + unsigned long actual; + u8 div; + int ret; /* * Don't care if wanted clock is zero or * ciu clock is unavailable @@ -207,17 +265,52 @@ static void dw_mci_exynos_set_ios(struct dw_mci *host, struct mmc_ios *ios) if (wanted < EXYNOS_CCLKIN_MIN) wanted = EXYNOS_CCLKIN_MIN; - if (wanted != priv->cur_speed) { - int ret = clk_set_rate(host->ciu_clk, wanted * div); - if (ret) - dev_warn(host->dev, - "failed to set clk-rate %u error: %d\n", - wanted * div, ret); - actual = clk_get_rate(host->ciu_clk); - host->bus_hz = actual / div; - priv->cur_speed = wanted; - host->current_speed = 0; + if (wanted == priv->cur_speed) + return; + + div = dw_mci_exynos_get_ciu_div(host); + ret = clk_set_rate(host->ciu_clk, wanted * div); + if (ret) + dev_warn(host->dev, + "failed to set clk-rate %u error: %d\n", + wanted * div, ret); + actual = clk_get_rate(host->ciu_clk); + host->bus_hz = actual / div; + priv->cur_speed = wanted; + host->current_speed = 0; +} + +static void dw_mci_exynos_set_ios(struct dw_mci *host, struct mmc_ios *ios) +{ + struct dw_mci_exynos_priv_data *priv = host->priv; + unsigned int wanted = ios->clock; + u32 timing = ios->timing, clksel; + + switch (timing) { + case MMC_TIMING_MMC_HS400: + /* Update tuned sample timing */ + clksel = SDMMC_CLKSEL_UP_SAMPLE( + priv->hs400_timing, priv->tuned_sample); + wanted <<= 1; + break; + case MMC_TIMING_MMC_DDR52: + clksel = priv->ddr_timing; + /* Should be double rate for DDR mode */ + if (ios->bus_width == MMC_BUS_WIDTH_8) + wanted <<= 1; + break; + default: + clksel = priv->sdr_timing; } + + /* Set clock timing for the requested speed mode*/ + dw_mci_exynos_set_clksel_timing(host, clksel); + + /* Configure setting for HS400 */ + dw_mci_exynos_config_hs400(host, timing); + + /* Configure clock rate */ + dw_mci_exynos_adjust_clock(host, wanted); } static int dw_mci_exynos_parse_dt(struct dw_mci *host) @@ -260,6 +353,16 @@ static int dw_mci_exynos_parse_dt(struct dw_mci *host) return ret; priv->ddr_timing = SDMMC_CLKSEL_TIMING(timing[0], timing[1], div); + + ret = of_property_read_u32_array(np, + "samsung,dw-mshc-hs400-timing", timing, 2); + if (!ret && of_property_read_u32(np, + "read-strobe-delay", &priv->dqs_delay)) + dev_info(host->dev, + "read-strobe-delay is not found, assuming usage of default value\n"); + + priv->hs400_timing = SDMMC_CLKSEL_TIMING(timing[0], timing[1], + HS400_FIXED_CIU_CLK_DIV); host->priv = priv; return 0; } @@ -285,7 +388,7 @@ static inline void dw_mci_exynos_set_clksmpl(struct dw_mci *host, u8 sample) clksel = mci_readl(host, CLKSEL64); else clksel = mci_readl(host, CLKSEL); - clksel = (clksel & ~0x7) | SDMMC_CLKSEL_CCLK_SAMPLE(sample); + clksel = SDMMC_CLKSEL_UP_SAMPLE(clksel, sample); if (priv->ctrl_type == DW_MCI_TYPE_EXYNOS7 || priv->ctrl_type == DW_MCI_TYPE_EXYNOS7_SMU) mci_writel(host, CLKSEL64, clksel); @@ -304,13 +407,16 @@ static inline u8 dw_mci_exynos_move_next_clksmpl(struct dw_mci *host) clksel = mci_readl(host, CLKSEL64); else clksel = mci_readl(host, CLKSEL); + sample = (clksel + 1) & 0x7; - clksel = (clksel & ~0x7) | sample; + clksel = SDMMC_CLKSEL_UP_SAMPLE(clksel, sample); + if (priv->ctrl_type == DW_MCI_TYPE_EXYNOS7 || priv->ctrl_type == DW_MCI_TYPE_EXYNOS7_SMU) mci_writel(host, CLKSEL64, clksel); else mci_writel(host, CLKSEL, clksel); + return sample; } @@ -343,6 +449,7 @@ out: static int dw_mci_exynos_execute_tuning(struct dw_mci_slot *slot) { struct dw_mci *host = slot->host; + struct dw_mci_exynos_priv_data *priv = host->priv; struct mmc_host *mmc = slot->mmc; u8 start_smpl, smpl, candiates = 0; s8 found = -1; @@ -360,14 +467,27 @@ static int dw_mci_exynos_execute_tuning(struct dw_mci_slot *slot) } while (start_smpl != smpl); found = dw_mci_exynos_get_best_clksmpl(candiates); - if (found >= 0) + if (found >= 0) { dw_mci_exynos_set_clksmpl(host, found); - else + priv->tuned_sample = found; + } else { ret = -EIO; + } return ret; } +int dw_mci_exynos_prepare_hs400_tuning(struct dw_mci *host, + struct mmc_ios *ios) +{ + struct dw_mci_exynos_priv_data *priv = host->priv; + + dw_mci_exynos_set_clksel_timing(host, priv->hs400_timing); + dw_mci_exynos_adjust_clock(host, (ios->clock) << 1); + + return 0; +} + /* Common capabilities of Exynos4/Exynos5 SoC */ static unsigned long exynos_dwmmc_caps[4] = { MMC_CAP_1_8V_DDR | MMC_CAP_8_BIT_DATA | MMC_CAP_CMD23, @@ -384,6 +504,7 @@ static const struct dw_mci_drv_data exynos_drv_data = { .set_ios = dw_mci_exynos_set_ios, .parse_dt = dw_mci_exynos_parse_dt, .execute_tuning = dw_mci_exynos_execute_tuning, + .prepare_hs400_tuning = dw_mci_exynos_prepare_hs400_tuning, }; static const struct of_device_id dw_mci_exynos_match[] = { diff --git a/drivers/mmc/host/dw_mmc-exynos.h b/drivers/mmc/host/dw_mmc-exynos.h index 7872ce5..595c934 100644 --- a/drivers/mmc/host/dw_mmc-exynos.h +++ b/drivers/mmc/host/dw_mmc-exynos.h @@ -12,20 +12,36 @@ #ifndef _DW_MMC_EXYNOS_H_ #define _DW_MMC_EXYNOS_H_ -/* Extended Register's Offset */ #define SDMMC_CLKSEL 0x09C #define SDMMC_CLKSEL64 0x0A8 +/* Extended Register's Offset */ +#define SDMMC_HS400_DQS_EN 0x180 +#define SDMMC_HS400_ASYNC_FIFO_CTRL 0x184 +#define SDMMC_HS400_DLINE_CTRL 0x188 + /* CLKSEL register defines */ #define SDMMC_CLKSEL_CCLK_SAMPLE(x) (((x) & 7) << 0) #define SDMMC_CLKSEL_CCLK_DRIVE(x) (((x) & 7) << 16) #define SDMMC_CLKSEL_CCLK_DIVIDER(x) (((x) & 7) << 24) #define SDMMC_CLKSEL_GET_DRV_WD3(x) (((x) >> 16) & 0x7) +#define SDMMC_CLKSEL_GET_DIV(x) (((x) >> 24) & 0x7) +#define SDMMC_CLKSEL_UP_SAMPLE(x, y) (((x) & ~SDMMC_CLKSEL_CCLK_SAMPLE(7)) |\ + SDMMC_CLKSEL_CCLK_SAMPLE(y)) #define SDMMC_CLKSEL_TIMING(x, y, z) (SDMMC_CLKSEL_CCLK_SAMPLE(x) | \ SDMMC_CLKSEL_CCLK_DRIVE(y) | \ SDMMC_CLKSEL_CCLK_DIVIDER(z)) +#define SDMMC_CLKSEL_TIMING_MASK SDMMC_CLKSEL_TIMING(0x7, 0x7, 0x7) #define SDMMC_CLKSEL_WAKEUP_INT BIT(11) +/* RCLK_EN register defines */ +#define DATA_STROBE_EN BIT(0) +#define AXI_NON_BLOCKING_WR BIT(7) + +/* DLINE_CTRL register defines */ +#define DQS_CTRL_RD_DELAY(x, y) (((x) & ~0x3FF) | ((y) & 0x3FF)) +#define DQS_CTRL_GET_RD_DELAY(x) ((x) & 0x3FF) + /* Protector Register */ #define SDMMC_EMMCP_BASE 0x1000 #define SDMMC_MPSECURITY (SDMMC_EMMCP_BASE + 0x0010) @@ -49,6 +65,7 @@ /* Fixed clock divider */ #define EXYNOS4210_FIXED_CIU_CLK_DIV 2 #define EXYNOS4412_FIXED_CIU_CLK_DIV 4 +#define HS400_FIXED_CIU_CLK_DIV 1 /* Minimal required clock frequency for cclkin, unit: HZ */ #define EXYNOS_CCLKIN_MIN 50000000 diff --git a/drivers/mmc/host/dw_mmc.c b/drivers/mmc/host/dw_mmc.c index 2e8abc8..43a3a5b 100644 --- a/drivers/mmc/host/dw_mmc.c +++ b/drivers/mmc/host/dw_mmc.c @@ -1084,7 +1084,8 @@ static void dw_mci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) regs = mci_readl(slot->host, UHS_REG); /* DDR mode set */ - if (ios->timing == MMC_TIMING_MMC_DDR52) + if (ios->timing == MMC_TIMING_MMC_DDR52 || + ios->timing == MMC_TIMING_MMC_HS400) regs |= ((0x1 << slot->id) << 16); else regs &= ~((0x1 << slot->id) << 16); @@ -1321,6 +1322,18 @@ static int dw_mci_execute_tuning(struct mmc_host *mmc, u32 opcode) return err; } +int dw_mci_prepare_hs400_tuning(struct mmc_host *mmc, struct mmc_ios *ios) +{ + struct dw_mci_slot *slot = mmc_priv(mmc); + struct dw_mci *host = slot->host; + const struct dw_mci_drv_data *drv_data = host->drv_data; + + if (drv_data && drv_data->prepare_hs400_tuning) + return drv_data->prepare_hs400_tuning(host, ios); + + return 0; +} + static const struct mmc_host_ops dw_mci_ops = { .request = dw_mci_request, .pre_req = dw_mci_pre_req, @@ -1333,6 +1346,7 @@ static const struct mmc_host_ops dw_mci_ops = { .card_busy = dw_mci_card_busy, .start_signal_voltage_switch = dw_mci_switch_voltage, .init_card = dw_mci_init_card, + .prepare_hs400_tuning = dw_mci_prepare_hs400_tuning, }; static void dw_mci_request_end(struct dw_mci *host, struct mmc_request *mrq) diff --git a/drivers/mmc/host/dw_mmc.h b/drivers/mmc/host/dw_mmc.h index 18c4afe..d239867 100644 --- a/drivers/mmc/host/dw_mmc.h +++ b/drivers/mmc/host/dw_mmc.h @@ -271,5 +271,7 @@ struct dw_mci_drv_data { void (*set_ios)(struct dw_mci *host, struct mmc_ios *ios); int (*parse_dt)(struct dw_mci *host); int (*execute_tuning)(struct dw_mci_slot *slot); + int (*prepare_hs400_tuning)(struct dw_mci *host, + struct mmc_ios *ios); }; #endif /* _DW_MMC_H_ */ -- 1.7.9.5 ^ permalink raw reply related [flat|nested] 24+ messages in thread
* [PATCH v4 1/2] mmc: dw_mmc: exynos: Support eMMC's HS400 mode @ 2015-01-14 10:30 ` Alim Akhtar 0 siblings, 0 replies; 24+ messages in thread From: Alim Akhtar @ 2015-01-14 10:30 UTC (permalink / raw) To: linux-arm-kernel From: Seungwon Jeon <tgih.jun@samsung.com> Implements HS400 mode support for exynos host driver. This also include some updates as new mode is added. Signed-off-by: Seungwon Jeon <tgih.jun@samsung.com> Signed-off-by: Alim Akhtar <alim.akhtar@samsung.com> [Alim: addressed review comments] --- .../devicetree/bindings/mmc/exynos-dw-mshc.txt | 7 + drivers/mmc/host/dw_mmc-exynos.c | 187 ++++++++++++++++---- drivers/mmc/host/dw_mmc-exynos.h | 19 +- drivers/mmc/host/dw_mmc.c | 16 +- drivers/mmc/host/dw_mmc.h | 2 + 5 files changed, 196 insertions(+), 35 deletions(-) diff --git a/Documentation/devicetree/bindings/mmc/exynos-dw-mshc.txt b/Documentation/devicetree/bindings/mmc/exynos-dw-mshc.txt index ee4fc05..dcab52c 100644 --- a/Documentation/devicetree/bindings/mmc/exynos-dw-mshc.txt +++ b/Documentation/devicetree/bindings/mmc/exynos-dw-mshc.txt @@ -36,6 +36,8 @@ Required Properties: in transmit mode and CIU clock phase shift value in receive mode for double data rate mode operation. Refer notes below for the order of the cells and the valid values. +* samsung,dw-mshc-hs400-timing: Specifies the value of CIU TX and RX clock phase + shift value for hs400 mode operation. Notes for the sdr-timing and ddr-timing values: @@ -50,6 +52,9 @@ Required Properties: - if CIU clock divider value is 0 (that is divide by 1), both tx and rx phase shift clocks should be 0. +* read-strobe-delay: RCLK (Data strobe) delay to control HS400 mode + (Latency value for delay line in Read path) + Required properties for a slot (Deprecated - Recommend to use one slot per host): * gpios: specifies a list of gpios used for command, clock and data bus. The @@ -82,5 +87,7 @@ Example: samsung,dw-mshc-ciu-div = <3>; samsung,dw-mshc-sdr-timing = <2 3>; samsung,dw-mshc-ddr-timing = <1 2>; + samsung,dw-mshc-hs400-timing = <0 2>; + read-strobe-delay = <90>; bus-width = <8>; }; diff --git a/drivers/mmc/host/dw_mmc-exynos.c b/drivers/mmc/host/dw_mmc-exynos.c index 12a5eaa..172a2a8 100644 --- a/drivers/mmc/host/dw_mmc-exynos.c +++ b/drivers/mmc/host/dw_mmc-exynos.c @@ -40,7 +40,12 @@ struct dw_mci_exynos_priv_data { u8 ciu_div; u32 sdr_timing; u32 ddr_timing; + u32 hs400_timing; + u32 tuned_sample; u32 cur_speed; + u32 dqs_delay; + u32 saved_dqs_en; + u32 saved_strobe_ctrl; }; static struct dw_mci_exynos_compatible { @@ -71,6 +76,21 @@ static struct dw_mci_exynos_compatible { }, }; +static inline u8 dw_mci_exynos_get_ciu_div(struct dw_mci *host) +{ + struct dw_mci_exynos_priv_data *priv = host->priv; + + if (priv->ctrl_type == DW_MCI_TYPE_EXYNOS4412) + return EXYNOS4412_FIXED_CIU_CLK_DIV; + else if (priv->ctrl_type == DW_MCI_TYPE_EXYNOS4210) + return EXYNOS4210_FIXED_CIU_CLK_DIV; + else if (priv->ctrl_type == DW_MCI_TYPE_EXYNOS7 || + priv->ctrl_type == DW_MCI_TYPE_EXYNOS7_SMU) + return SDMMC_CLKSEL_GET_DIV(mci_readl(host, CLKSEL64)) + 1; + else + return SDMMC_CLKSEL_GET_DIV(mci_readl(host, CLKSEL)) + 1; +} + static int dw_mci_exynos_priv_init(struct dw_mci *host) { struct dw_mci_exynos_priv_data *priv = host->priv; @@ -85,6 +105,16 @@ static int dw_mci_exynos_priv_init(struct dw_mci *host) SDMMC_MPSCTRL_NON_SECURE_WRITE_BIT); } + if (priv->ctrl_type >= DW_MCI_TYPE_EXYNOS5420) { + priv->saved_strobe_ctrl = mci_readl(host, HS400_DLINE_CTRL); + priv->saved_dqs_en = mci_readl(host, HS400_DQS_EN); + priv->saved_dqs_en |= AXI_NON_BLOCKING_WR; + mci_writel(host, HS400_DQS_EN, priv->saved_dqs_en); + if (!priv->dqs_delay) + priv->dqs_delay = + DQS_CTRL_GET_RD_DELAY(priv->saved_strobe_ctrl); + } + return 0; } @@ -92,11 +122,31 @@ static int dw_mci_exynos_setup_clock(struct dw_mci *host) { struct dw_mci_exynos_priv_data *priv = host->priv; - host->bus_hz /= (priv->ciu_div + 1); + host->bus_hz /= priv->ciu_div; return 0; } +static void dw_mci_exynos_set_clksel_timing(struct dw_mci *host, u32 timing) +{ + struct dw_mci_exynos_priv_data *priv = host->priv; + u32 clksel; + + if (priv->ctrl_type == DW_MCI_TYPE_EXYNOS7 || + priv->ctrl_type == DW_MCI_TYPE_EXYNOS7_SMU) + clksel = mci_readl(host, CLKSEL64); + else + clksel = mci_readl(host, CLKSEL); + + clksel = (clksel & ~SDMMC_CLKSEL_TIMING_MASK) | timing; + + if (priv->ctrl_type == DW_MCI_TYPE_EXYNOS7 || + priv->ctrl_type == DW_MCI_TYPE_EXYNOS7_SMU) + mci_writel(host, CLKSEL64, clksel); + else + mci_writel(host, CLKSEL, clksel); +} + #ifdef CONFIG_PM_SLEEP static int dw_mci_exynos_suspend(struct device *dev) { @@ -172,30 +222,38 @@ static void dw_mci_exynos_prepare_command(struct dw_mci *host, u32 *cmdr) } } -static void dw_mci_exynos_set_ios(struct dw_mci *host, struct mmc_ios *ios) +static void dw_mci_exynos_config_hs400(struct dw_mci *host, u32 timing) { struct dw_mci_exynos_priv_data *priv = host->priv; - unsigned int wanted = ios->clock; - unsigned long actual; - u8 div = priv->ciu_div + 1; + u32 dqs, strobe; - if (ios->timing == MMC_TIMING_MMC_DDR52) { - if (priv->ctrl_type == DW_MCI_TYPE_EXYNOS7 || - priv->ctrl_type == DW_MCI_TYPE_EXYNOS7_SMU) - mci_writel(host, CLKSEL64, priv->ddr_timing); - else - mci_writel(host, CLKSEL, priv->ddr_timing); - /* Should be double rate for DDR mode */ - if (ios->bus_width == MMC_BUS_WIDTH_8) - wanted <<= 1; + /* + * Not suppported to configure register + * related to HS400 + */ + if (priv->ctrl_type < DW_MCI_TYPE_EXYNOS5420) + return; + + dqs = priv->saved_dqs_en; + strobe = priv->saved_strobe_ctrl; + + if (timing == MMC_TIMING_MMC_HS400) { + dqs |= DATA_STROBE_EN; + strobe = DQS_CTRL_RD_DELAY(strobe, priv->dqs_delay); } else { - if (priv->ctrl_type == DW_MCI_TYPE_EXYNOS7 || - priv->ctrl_type == DW_MCI_TYPE_EXYNOS7_SMU) - mci_writel(host, CLKSEL64, priv->sdr_timing); - else - mci_writel(host, CLKSEL, priv->sdr_timing); + dqs &= ~DATA_STROBE_EN; } + mci_writel(host, HS400_DQS_EN, dqs); + mci_writel(host, HS400_DLINE_CTRL, strobe); +} + +static void dw_mci_exynos_adjust_clock(struct dw_mci *host, unsigned int wanted) +{ + struct dw_mci_exynos_priv_data *priv = host->priv; + unsigned long actual; + u8 div; + int ret; /* * Don't care if wanted clock is zero or * ciu clock is unavailable @@ -207,17 +265,52 @@ static void dw_mci_exynos_set_ios(struct dw_mci *host, struct mmc_ios *ios) if (wanted < EXYNOS_CCLKIN_MIN) wanted = EXYNOS_CCLKIN_MIN; - if (wanted != priv->cur_speed) { - int ret = clk_set_rate(host->ciu_clk, wanted * div); - if (ret) - dev_warn(host->dev, - "failed to set clk-rate %u error: %d\n", - wanted * div, ret); - actual = clk_get_rate(host->ciu_clk); - host->bus_hz = actual / div; - priv->cur_speed = wanted; - host->current_speed = 0; + if (wanted == priv->cur_speed) + return; + + div = dw_mci_exynos_get_ciu_div(host); + ret = clk_set_rate(host->ciu_clk, wanted * div); + if (ret) + dev_warn(host->dev, + "failed to set clk-rate %u error: %d\n", + wanted * div, ret); + actual = clk_get_rate(host->ciu_clk); + host->bus_hz = actual / div; + priv->cur_speed = wanted; + host->current_speed = 0; +} + +static void dw_mci_exynos_set_ios(struct dw_mci *host, struct mmc_ios *ios) +{ + struct dw_mci_exynos_priv_data *priv = host->priv; + unsigned int wanted = ios->clock; + u32 timing = ios->timing, clksel; + + switch (timing) { + case MMC_TIMING_MMC_HS400: + /* Update tuned sample timing */ + clksel = SDMMC_CLKSEL_UP_SAMPLE( + priv->hs400_timing, priv->tuned_sample); + wanted <<= 1; + break; + case MMC_TIMING_MMC_DDR52: + clksel = priv->ddr_timing; + /* Should be double rate for DDR mode */ + if (ios->bus_width == MMC_BUS_WIDTH_8) + wanted <<= 1; + break; + default: + clksel = priv->sdr_timing; } + + /* Set clock timing for the requested speed mode*/ + dw_mci_exynos_set_clksel_timing(host, clksel); + + /* Configure setting for HS400 */ + dw_mci_exynos_config_hs400(host, timing); + + /* Configure clock rate */ + dw_mci_exynos_adjust_clock(host, wanted); } static int dw_mci_exynos_parse_dt(struct dw_mci *host) @@ -260,6 +353,16 @@ static int dw_mci_exynos_parse_dt(struct dw_mci *host) return ret; priv->ddr_timing = SDMMC_CLKSEL_TIMING(timing[0], timing[1], div); + + ret = of_property_read_u32_array(np, + "samsung,dw-mshc-hs400-timing", timing, 2); + if (!ret && of_property_read_u32(np, + "read-strobe-delay", &priv->dqs_delay)) + dev_info(host->dev, + "read-strobe-delay is not found, assuming usage of default value\n"); + + priv->hs400_timing = SDMMC_CLKSEL_TIMING(timing[0], timing[1], + HS400_FIXED_CIU_CLK_DIV); host->priv = priv; return 0; } @@ -285,7 +388,7 @@ static inline void dw_mci_exynos_set_clksmpl(struct dw_mci *host, u8 sample) clksel = mci_readl(host, CLKSEL64); else clksel = mci_readl(host, CLKSEL); - clksel = (clksel & ~0x7) | SDMMC_CLKSEL_CCLK_SAMPLE(sample); + clksel = SDMMC_CLKSEL_UP_SAMPLE(clksel, sample); if (priv->ctrl_type == DW_MCI_TYPE_EXYNOS7 || priv->ctrl_type == DW_MCI_TYPE_EXYNOS7_SMU) mci_writel(host, CLKSEL64, clksel); @@ -304,13 +407,16 @@ static inline u8 dw_mci_exynos_move_next_clksmpl(struct dw_mci *host) clksel = mci_readl(host, CLKSEL64); else clksel = mci_readl(host, CLKSEL); + sample = (clksel + 1) & 0x7; - clksel = (clksel & ~0x7) | sample; + clksel = SDMMC_CLKSEL_UP_SAMPLE(clksel, sample); + if (priv->ctrl_type == DW_MCI_TYPE_EXYNOS7 || priv->ctrl_type == DW_MCI_TYPE_EXYNOS7_SMU) mci_writel(host, CLKSEL64, clksel); else mci_writel(host, CLKSEL, clksel); + return sample; } @@ -343,6 +449,7 @@ out: static int dw_mci_exynos_execute_tuning(struct dw_mci_slot *slot) { struct dw_mci *host = slot->host; + struct dw_mci_exynos_priv_data *priv = host->priv; struct mmc_host *mmc = slot->mmc; u8 start_smpl, smpl, candiates = 0; s8 found = -1; @@ -360,14 +467,27 @@ static int dw_mci_exynos_execute_tuning(struct dw_mci_slot *slot) } while (start_smpl != smpl); found = dw_mci_exynos_get_best_clksmpl(candiates); - if (found >= 0) + if (found >= 0) { dw_mci_exynos_set_clksmpl(host, found); - else + priv->tuned_sample = found; + } else { ret = -EIO; + } return ret; } +int dw_mci_exynos_prepare_hs400_tuning(struct dw_mci *host, + struct mmc_ios *ios) +{ + struct dw_mci_exynos_priv_data *priv = host->priv; + + dw_mci_exynos_set_clksel_timing(host, priv->hs400_timing); + dw_mci_exynos_adjust_clock(host, (ios->clock) << 1); + + return 0; +} + /* Common capabilities of Exynos4/Exynos5 SoC */ static unsigned long exynos_dwmmc_caps[4] = { MMC_CAP_1_8V_DDR | MMC_CAP_8_BIT_DATA | MMC_CAP_CMD23, @@ -384,6 +504,7 @@ static const struct dw_mci_drv_data exynos_drv_data = { .set_ios = dw_mci_exynos_set_ios, .parse_dt = dw_mci_exynos_parse_dt, .execute_tuning = dw_mci_exynos_execute_tuning, + .prepare_hs400_tuning = dw_mci_exynos_prepare_hs400_tuning, }; static const struct of_device_id dw_mci_exynos_match[] = { diff --git a/drivers/mmc/host/dw_mmc-exynos.h b/drivers/mmc/host/dw_mmc-exynos.h index 7872ce5..595c934 100644 --- a/drivers/mmc/host/dw_mmc-exynos.h +++ b/drivers/mmc/host/dw_mmc-exynos.h @@ -12,20 +12,36 @@ #ifndef _DW_MMC_EXYNOS_H_ #define _DW_MMC_EXYNOS_H_ -/* Extended Register's Offset */ #define SDMMC_CLKSEL 0x09C #define SDMMC_CLKSEL64 0x0A8 +/* Extended Register's Offset */ +#define SDMMC_HS400_DQS_EN 0x180 +#define SDMMC_HS400_ASYNC_FIFO_CTRL 0x184 +#define SDMMC_HS400_DLINE_CTRL 0x188 + /* CLKSEL register defines */ #define SDMMC_CLKSEL_CCLK_SAMPLE(x) (((x) & 7) << 0) #define SDMMC_CLKSEL_CCLK_DRIVE(x) (((x) & 7) << 16) #define SDMMC_CLKSEL_CCLK_DIVIDER(x) (((x) & 7) << 24) #define SDMMC_CLKSEL_GET_DRV_WD3(x) (((x) >> 16) & 0x7) +#define SDMMC_CLKSEL_GET_DIV(x) (((x) >> 24) & 0x7) +#define SDMMC_CLKSEL_UP_SAMPLE(x, y) (((x) & ~SDMMC_CLKSEL_CCLK_SAMPLE(7)) |\ + SDMMC_CLKSEL_CCLK_SAMPLE(y)) #define SDMMC_CLKSEL_TIMING(x, y, z) (SDMMC_CLKSEL_CCLK_SAMPLE(x) | \ SDMMC_CLKSEL_CCLK_DRIVE(y) | \ SDMMC_CLKSEL_CCLK_DIVIDER(z)) +#define SDMMC_CLKSEL_TIMING_MASK SDMMC_CLKSEL_TIMING(0x7, 0x7, 0x7) #define SDMMC_CLKSEL_WAKEUP_INT BIT(11) +/* RCLK_EN register defines */ +#define DATA_STROBE_EN BIT(0) +#define AXI_NON_BLOCKING_WR BIT(7) + +/* DLINE_CTRL register defines */ +#define DQS_CTRL_RD_DELAY(x, y) (((x) & ~0x3FF) | ((y) & 0x3FF)) +#define DQS_CTRL_GET_RD_DELAY(x) ((x) & 0x3FF) + /* Protector Register */ #define SDMMC_EMMCP_BASE 0x1000 #define SDMMC_MPSECURITY (SDMMC_EMMCP_BASE + 0x0010) @@ -49,6 +65,7 @@ /* Fixed clock divider */ #define EXYNOS4210_FIXED_CIU_CLK_DIV 2 #define EXYNOS4412_FIXED_CIU_CLK_DIV 4 +#define HS400_FIXED_CIU_CLK_DIV 1 /* Minimal required clock frequency for cclkin, unit: HZ */ #define EXYNOS_CCLKIN_MIN 50000000 diff --git a/drivers/mmc/host/dw_mmc.c b/drivers/mmc/host/dw_mmc.c index 2e8abc8..43a3a5b 100644 --- a/drivers/mmc/host/dw_mmc.c +++ b/drivers/mmc/host/dw_mmc.c @@ -1084,7 +1084,8 @@ static void dw_mci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) regs = mci_readl(slot->host, UHS_REG); /* DDR mode set */ - if (ios->timing == MMC_TIMING_MMC_DDR52) + if (ios->timing == MMC_TIMING_MMC_DDR52 || + ios->timing == MMC_TIMING_MMC_HS400) regs |= ((0x1 << slot->id) << 16); else regs &= ~((0x1 << slot->id) << 16); @@ -1321,6 +1322,18 @@ static int dw_mci_execute_tuning(struct mmc_host *mmc, u32 opcode) return err; } +int dw_mci_prepare_hs400_tuning(struct mmc_host *mmc, struct mmc_ios *ios) +{ + struct dw_mci_slot *slot = mmc_priv(mmc); + struct dw_mci *host = slot->host; + const struct dw_mci_drv_data *drv_data = host->drv_data; + + if (drv_data && drv_data->prepare_hs400_tuning) + return drv_data->prepare_hs400_tuning(host, ios); + + return 0; +} + static const struct mmc_host_ops dw_mci_ops = { .request = dw_mci_request, .pre_req = dw_mci_pre_req, @@ -1333,6 +1346,7 @@ static const struct mmc_host_ops dw_mci_ops = { .card_busy = dw_mci_card_busy, .start_signal_voltage_switch = dw_mci_switch_voltage, .init_card = dw_mci_init_card, + .prepare_hs400_tuning = dw_mci_prepare_hs400_tuning, }; static void dw_mci_request_end(struct dw_mci *host, struct mmc_request *mrq) diff --git a/drivers/mmc/host/dw_mmc.h b/drivers/mmc/host/dw_mmc.h index 18c4afe..d239867 100644 --- a/drivers/mmc/host/dw_mmc.h +++ b/drivers/mmc/host/dw_mmc.h @@ -271,5 +271,7 @@ struct dw_mci_drv_data { void (*set_ios)(struct dw_mci *host, struct mmc_ios *ios); int (*parse_dt)(struct dw_mci *host); int (*execute_tuning)(struct dw_mci_slot *slot); + int (*prepare_hs400_tuning)(struct dw_mci *host, + struct mmc_ios *ios); }; #endif /* _DW_MMC_H_ */ -- 1.7.9.5 ^ permalink raw reply related [flat|nested] 24+ messages in thread
* Re: [PATCH v4 1/2] mmc: dw_mmc: exynos: Support eMMC's HS400 mode 2015-01-14 10:30 ` Alim Akhtar @ 2015-01-20 23:02 ` Jaehoon Chung -1 siblings, 0 replies; 24+ messages in thread From: Jaehoon Chung @ 2015-01-20 23:02 UTC (permalink / raw) To: Alim Akhtar, linux-mmc Cc: chris, ulf.hansson, tgih.jun, dianders, alim.akhtar, kgene, linux-arm-kernel, devicetree, linux-samsung-soc, a.kesavan Hi, This patch can be separated. When i tested on my board, it's not working fine. I think it depends on my timing, so i will check after change the timing. On 01/14/2015 07:30 PM, Alim Akhtar wrote: > From: Seungwon Jeon <tgih.jun@samsung.com> > > Implements HS400 mode support for exynos host driver. > This also include some updates as new mode is added. > > Signed-off-by: Seungwon Jeon <tgih.jun@samsung.com> > Signed-off-by: Alim Akhtar <alim.akhtar@samsung.com> > [Alim: addressed review comments] > --- > .../devicetree/bindings/mmc/exynos-dw-mshc.txt | 7 + > drivers/mmc/host/dw_mmc-exynos.c | 187 ++++++++++++++++---- > drivers/mmc/host/dw_mmc-exynos.h | 19 +- > drivers/mmc/host/dw_mmc.c | 16 +- > drivers/mmc/host/dw_mmc.h | 2 + > 5 files changed, 196 insertions(+), 35 deletions(-) > > diff --git a/Documentation/devicetree/bindings/mmc/exynos-dw-mshc.txt b/Documentation/devicetree/bindings/mmc/exynos-dw-mshc.txt > index ee4fc05..dcab52c 100644 > --- a/Documentation/devicetree/bindings/mmc/exynos-dw-mshc.txt > +++ b/Documentation/devicetree/bindings/mmc/exynos-dw-mshc.txt > @@ -36,6 +36,8 @@ Required Properties: > in transmit mode and CIU clock phase shift value in receive mode for double > data rate mode operation. Refer notes below for the order of the cells and the > valid values. > +* samsung,dw-mshc-hs400-timing: Specifies the value of CIU TX and RX clock phase > + shift value for hs400 mode operation. > > Notes for the sdr-timing and ddr-timing values: > > @@ -50,6 +52,9 @@ Required Properties: > - if CIU clock divider value is 0 (that is divide by 1), both tx and rx > phase shift clocks should be 0. > > +* read-strobe-delay: RCLK (Data strobe) delay to control HS400 mode > + (Latency value for delay line in Read path) > + > Required properties for a slot (Deprecated - Recommend to use one slot per host): > > * gpios: specifies a list of gpios used for command, clock and data bus. The > @@ -82,5 +87,7 @@ Example: > samsung,dw-mshc-ciu-div = <3>; > samsung,dw-mshc-sdr-timing = <2 3>; > samsung,dw-mshc-ddr-timing = <1 2>; > + samsung,dw-mshc-hs400-timing = <0 2>; > + read-strobe-delay = <90>; read-strobe-delay is exynos specific, isn't? read-strobe-delay -> samsung.read-strobe-delay. > bus-width = <8>; > }; > diff --git a/drivers/mmc/host/dw_mmc-exynos.c b/drivers/mmc/host/dw_mmc-exynos.c > index 12a5eaa..172a2a8 100644 > --- a/drivers/mmc/host/dw_mmc-exynos.c > +++ b/drivers/mmc/host/dw_mmc-exynos.c > @@ -40,7 +40,12 @@ struct dw_mci_exynos_priv_data { > u8 ciu_div; > u32 sdr_timing; > u32 ddr_timing; > + u32 hs400_timing; > + u32 tuned_sample; > u32 cur_speed; > + u32 dqs_delay; > + u32 saved_dqs_en; > + u32 saved_strobe_ctrl; > }; > > static struct dw_mci_exynos_compatible { > @@ -71,6 +76,21 @@ static struct dw_mci_exynos_compatible { > }, > }; > > +static inline u8 dw_mci_exynos_get_ciu_div(struct dw_mci *host) > +{ > + struct dw_mci_exynos_priv_data *priv = host->priv; > + > + if (priv->ctrl_type == DW_MCI_TYPE_EXYNOS4412) > + return EXYNOS4412_FIXED_CIU_CLK_DIV; > + else if (priv->ctrl_type == DW_MCI_TYPE_EXYNOS4210) > + return EXYNOS4210_FIXED_CIU_CLK_DIV; > + else if (priv->ctrl_type == DW_MCI_TYPE_EXYNOS7 || > + priv->ctrl_type == DW_MCI_TYPE_EXYNOS7_SMU) > + return SDMMC_CLKSEL_GET_DIV(mci_readl(host, CLKSEL64)) + 1; > + else > + return SDMMC_CLKSEL_GET_DIV(mci_readl(host, CLKSEL)) + 1; > +} > + > static int dw_mci_exynos_priv_init(struct dw_mci *host) > { > struct dw_mci_exynos_priv_data *priv = host->priv; > @@ -85,6 +105,16 @@ static int dw_mci_exynos_priv_init(struct dw_mci *host) > SDMMC_MPSCTRL_NON_SECURE_WRITE_BIT); > } > > + if (priv->ctrl_type >= DW_MCI_TYPE_EXYNOS5420) { > + priv->saved_strobe_ctrl = mci_readl(host, HS400_DLINE_CTRL); > + priv->saved_dqs_en = mci_readl(host, HS400_DQS_EN); > + priv->saved_dqs_en |= AXI_NON_BLOCKING_WR; > + mci_writel(host, HS400_DQS_EN, priv->saved_dqs_en); > + if (!priv->dqs_delay) > + priv->dqs_delay = > + DQS_CTRL_GET_RD_DELAY(priv->saved_strobe_ctrl); > + } > + > return 0; > } > > @@ -92,11 +122,31 @@ static int dw_mci_exynos_setup_clock(struct dw_mci *host) > { > struct dw_mci_exynos_priv_data *priv = host->priv; > > - host->bus_hz /= (priv->ciu_div + 1); > + host->bus_hz /= priv->ciu_div; Don't need to consider the case that priv->ciu_div set to 0? > > return 0; > } > > +static void dw_mci_exynos_set_clksel_timing(struct dw_mci *host, u32 timing) > +{ > + struct dw_mci_exynos_priv_data *priv = host->priv; > + u32 clksel; > + > + if (priv->ctrl_type == DW_MCI_TYPE_EXYNOS7 || > + priv->ctrl_type == DW_MCI_TYPE_EXYNOS7_SMU) > + clksel = mci_readl(host, CLKSEL64); > + else > + clksel = mci_readl(host, CLKSEL); > + > + clksel = (clksel & ~SDMMC_CLKSEL_TIMING_MASK) | timing; > + > + if (priv->ctrl_type == DW_MCI_TYPE_EXYNOS7 || > + priv->ctrl_type == DW_MCI_TYPE_EXYNOS7_SMU) > + mci_writel(host, CLKSEL64, clksel); > + else > + mci_writel(host, CLKSEL, clksel); > +} > + > #ifdef CONFIG_PM_SLEEP > static int dw_mci_exynos_suspend(struct device *dev) > { > @@ -172,30 +222,38 @@ static void dw_mci_exynos_prepare_command(struct dw_mci *host, u32 *cmdr) > } > } > > -static void dw_mci_exynos_set_ios(struct dw_mci *host, struct mmc_ios *ios) > +static void dw_mci_exynos_config_hs400(struct dw_mci *host, u32 timing) > { > struct dw_mci_exynos_priv_data *priv = host->priv; > - unsigned int wanted = ios->clock; > - unsigned long actual; > - u8 div = priv->ciu_div + 1; > + u32 dqs, strobe; > > - if (ios->timing == MMC_TIMING_MMC_DDR52) { > - if (priv->ctrl_type == DW_MCI_TYPE_EXYNOS7 || > - priv->ctrl_type == DW_MCI_TYPE_EXYNOS7_SMU) > - mci_writel(host, CLKSEL64, priv->ddr_timing); > - else > - mci_writel(host, CLKSEL, priv->ddr_timing); > - /* Should be double rate for DDR mode */ > - if (ios->bus_width == MMC_BUS_WIDTH_8) > - wanted <<= 1; > + /* > + * Not suppported to configure register Typo..supported > + * related to HS400 > + */ > + if (priv->ctrl_type < DW_MCI_TYPE_EXYNOS5420) > + return; > + > + dqs = priv->saved_dqs_en; > + strobe = priv->saved_strobe_ctrl; priv->saved_dqs_en is set at init-time. And you read the RDDQS_EN and HS400_DLINE_CTRL register at that time. Doesn't it need to consider the changed value at those register? priv->saved_xxx is reset value? > + > + if (timing == MMC_TIMING_MMC_HS400) { > + dqs |= DATA_STROBE_EN; > + strobe = DQS_CTRL_RD_DELAY(strobe, priv->dqs_delay); > } else { > - if (priv->ctrl_type == DW_MCI_TYPE_EXYNOS7 || > - priv->ctrl_type == DW_MCI_TYPE_EXYNOS7_SMU) > - mci_writel(host, CLKSEL64, priv->sdr_timing); > - else > - mci_writel(host, CLKSEL, priv->sdr_timing); > + dqs &= ~DATA_STROBE_EN; > } > > + mci_writel(host, HS400_DQS_EN, dqs); > + mci_writel(host, HS400_DLINE_CTRL, strobe); > +} > + > +static void dw_mci_exynos_adjust_clock(struct dw_mci *host, unsigned int wanted) > +{ > + struct dw_mci_exynos_priv_data *priv = host->priv; > + unsigned long actual; > + u8 div; > + int ret; > /* > * Don't care if wanted clock is zero or > * ciu clock is unavailable > @@ -207,17 +265,52 @@ static void dw_mci_exynos_set_ios(struct dw_mci *host, struct mmc_ios *ios) > if (wanted < EXYNOS_CCLKIN_MIN) > wanted = EXYNOS_CCLKIN_MIN; > > - if (wanted != priv->cur_speed) { > - int ret = clk_set_rate(host->ciu_clk, wanted * div); > - if (ret) > - dev_warn(host->dev, > - "failed to set clk-rate %u error: %d\n", > - wanted * div, ret); > - actual = clk_get_rate(host->ciu_clk); > - host->bus_hz = actual / div; > - priv->cur_speed = wanted; > - host->current_speed = 0; > + if (wanted == priv->cur_speed) > + return; > + > + div = dw_mci_exynos_get_ciu_div(host); > + ret = clk_set_rate(host->ciu_clk, wanted * div); > + if (ret) > + dev_warn(host->dev, > + "failed to set clk-rate %u error: %d\n", > + wanted * div, ret); > + actual = clk_get_rate(host->ciu_clk); > + host->bus_hz = actual / div; > + priv->cur_speed = wanted; > + host->current_speed = 0; > +} > + > +static void dw_mci_exynos_set_ios(struct dw_mci *host, struct mmc_ios *ios) > +{ > + struct dw_mci_exynos_priv_data *priv = host->priv; > + unsigned int wanted = ios->clock; > + u32 timing = ios->timing, clksel; > + > + switch (timing) { > + case MMC_TIMING_MMC_HS400: > + /* Update tuned sample timing */ > + clksel = SDMMC_CLKSEL_UP_SAMPLE( > + priv->hs400_timing, priv->tuned_sample); > + wanted <<= 1; > + break; > + case MMC_TIMING_MMC_DDR52: > + clksel = priv->ddr_timing; > + /* Should be double rate for DDR mode */ > + if (ios->bus_width == MMC_BUS_WIDTH_8) > + wanted <<= 1; > + break; > + default: > + clksel = priv->sdr_timing; > } > + > + /* Set clock timing for the requested speed mode*/ > + dw_mci_exynos_set_clksel_timing(host, clksel); > + > + /* Configure setting for HS400 */ > + dw_mci_exynos_config_hs400(host, timing); > + > + /* Configure clock rate */ > + dw_mci_exynos_adjust_clock(host, wanted); > } > > static int dw_mci_exynos_parse_dt(struct dw_mci *host) > @@ -260,6 +353,16 @@ static int dw_mci_exynos_parse_dt(struct dw_mci *host) > return ret; > > priv->ddr_timing = SDMMC_CLKSEL_TIMING(timing[0], timing[1], div); > + > + ret = of_property_read_u32_array(np, > + "samsung,dw-mshc-hs400-timing", timing, 2); > + if (!ret && of_property_read_u32(np, > + "read-strobe-delay", &priv->dqs_delay)) > + dev_info(host->dev, > + "read-strobe-delay is not found, assuming usage of default value\n"); Need the message? > + > + priv->hs400_timing = SDMMC_CLKSEL_TIMING(timing[0], timing[1], > + HS400_FIXED_CIU_CLK_DIV); Why useed the HS400_FIXED_CIU_CLK_DIV? always set to 1? Best Regards, Jaehoon Chung > host->priv = priv; > return 0; > } > @@ -285,7 +388,7 @@ static inline void dw_mci_exynos_set_clksmpl(struct dw_mci *host, u8 sample) > clksel = mci_readl(host, CLKSEL64); > else > clksel = mci_readl(host, CLKSEL); > - clksel = (clksel & ~0x7) | SDMMC_CLKSEL_CCLK_SAMPLE(sample); > + clksel = SDMMC_CLKSEL_UP_SAMPLE(clksel, sample); > if (priv->ctrl_type == DW_MCI_TYPE_EXYNOS7 || > priv->ctrl_type == DW_MCI_TYPE_EXYNOS7_SMU) > mci_writel(host, CLKSEL64, clksel); > @@ -304,13 +407,16 @@ static inline u8 dw_mci_exynos_move_next_clksmpl(struct dw_mci *host) > clksel = mci_readl(host, CLKSEL64); > else > clksel = mci_readl(host, CLKSEL); > + > sample = (clksel + 1) & 0x7; > - clksel = (clksel & ~0x7) | sample; > + clksel = SDMMC_CLKSEL_UP_SAMPLE(clksel, sample); > + > if (priv->ctrl_type == DW_MCI_TYPE_EXYNOS7 || > priv->ctrl_type == DW_MCI_TYPE_EXYNOS7_SMU) > mci_writel(host, CLKSEL64, clksel); > else > mci_writel(host, CLKSEL, clksel); > + > return sample; > } > > @@ -343,6 +449,7 @@ out: > static int dw_mci_exynos_execute_tuning(struct dw_mci_slot *slot) > { > struct dw_mci *host = slot->host; > + struct dw_mci_exynos_priv_data *priv = host->priv; > struct mmc_host *mmc = slot->mmc; > u8 start_smpl, smpl, candiates = 0; > s8 found = -1; > @@ -360,14 +467,27 @@ static int dw_mci_exynos_execute_tuning(struct dw_mci_slot *slot) > } while (start_smpl != smpl); > > found = dw_mci_exynos_get_best_clksmpl(candiates); > - if (found >= 0) > + if (found >= 0) { > dw_mci_exynos_set_clksmpl(host, found); > - else > + priv->tuned_sample = found; > + } else { > ret = -EIO; > + } > > return ret; > } > > +int dw_mci_exynos_prepare_hs400_tuning(struct dw_mci *host, > + struct mmc_ios *ios) > +{ > + struct dw_mci_exynos_priv_data *priv = host->priv; > + > + dw_mci_exynos_set_clksel_timing(host, priv->hs400_timing); > + dw_mci_exynos_adjust_clock(host, (ios->clock) << 1); > + > + return 0; > +} > + > /* Common capabilities of Exynos4/Exynos5 SoC */ > static unsigned long exynos_dwmmc_caps[4] = { > MMC_CAP_1_8V_DDR | MMC_CAP_8_BIT_DATA | MMC_CAP_CMD23, > @@ -384,6 +504,7 @@ static const struct dw_mci_drv_data exynos_drv_data = { > .set_ios = dw_mci_exynos_set_ios, > .parse_dt = dw_mci_exynos_parse_dt, > .execute_tuning = dw_mci_exynos_execute_tuning, > + .prepare_hs400_tuning = dw_mci_exynos_prepare_hs400_tuning, > }; > > static const struct of_device_id dw_mci_exynos_match[] = { > diff --git a/drivers/mmc/host/dw_mmc-exynos.h b/drivers/mmc/host/dw_mmc-exynos.h > index 7872ce5..595c934 100644 > --- a/drivers/mmc/host/dw_mmc-exynos.h > +++ b/drivers/mmc/host/dw_mmc-exynos.h > @@ -12,20 +12,36 @@ > #ifndef _DW_MMC_EXYNOS_H_ > #define _DW_MMC_EXYNOS_H_ > > -/* Extended Register's Offset */ > #define SDMMC_CLKSEL 0x09C > #define SDMMC_CLKSEL64 0x0A8 > > +/* Extended Register's Offset */ > +#define SDMMC_HS400_DQS_EN 0x180 > +#define SDMMC_HS400_ASYNC_FIFO_CTRL 0x184 > +#define SDMMC_HS400_DLINE_CTRL 0x188 > + > /* CLKSEL register defines */ > #define SDMMC_CLKSEL_CCLK_SAMPLE(x) (((x) & 7) << 0) > #define SDMMC_CLKSEL_CCLK_DRIVE(x) (((x) & 7) << 16) > #define SDMMC_CLKSEL_CCLK_DIVIDER(x) (((x) & 7) << 24) > #define SDMMC_CLKSEL_GET_DRV_WD3(x) (((x) >> 16) & 0x7) > +#define SDMMC_CLKSEL_GET_DIV(x) (((x) >> 24) & 0x7) > +#define SDMMC_CLKSEL_UP_SAMPLE(x, y) (((x) & ~SDMMC_CLKSEL_CCLK_SAMPLE(7)) |\ > + SDMMC_CLKSEL_CCLK_SAMPLE(y)) > #define SDMMC_CLKSEL_TIMING(x, y, z) (SDMMC_CLKSEL_CCLK_SAMPLE(x) | \ > SDMMC_CLKSEL_CCLK_DRIVE(y) | \ > SDMMC_CLKSEL_CCLK_DIVIDER(z)) > +#define SDMMC_CLKSEL_TIMING_MASK SDMMC_CLKSEL_TIMING(0x7, 0x7, 0x7) > #define SDMMC_CLKSEL_WAKEUP_INT BIT(11) > > +/* RCLK_EN register defines */ > +#define DATA_STROBE_EN BIT(0) > +#define AXI_NON_BLOCKING_WR BIT(7) > + > +/* DLINE_CTRL register defines */ > +#define DQS_CTRL_RD_DELAY(x, y) (((x) & ~0x3FF) | ((y) & 0x3FF)) > +#define DQS_CTRL_GET_RD_DELAY(x) ((x) & 0x3FF) > + > /* Protector Register */ > #define SDMMC_EMMCP_BASE 0x1000 > #define SDMMC_MPSECURITY (SDMMC_EMMCP_BASE + 0x0010) > @@ -49,6 +65,7 @@ > /* Fixed clock divider */ > #define EXYNOS4210_FIXED_CIU_CLK_DIV 2 > #define EXYNOS4412_FIXED_CIU_CLK_DIV 4 > +#define HS400_FIXED_CIU_CLK_DIV 1 > > /* Minimal required clock frequency for cclkin, unit: HZ */ > #define EXYNOS_CCLKIN_MIN 50000000 > diff --git a/drivers/mmc/host/dw_mmc.c b/drivers/mmc/host/dw_mmc.c > index 2e8abc8..43a3a5b 100644 > --- a/drivers/mmc/host/dw_mmc.c > +++ b/drivers/mmc/host/dw_mmc.c > @@ -1084,7 +1084,8 @@ static void dw_mci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) > regs = mci_readl(slot->host, UHS_REG); > > /* DDR mode set */ > - if (ios->timing == MMC_TIMING_MMC_DDR52) > + if (ios->timing == MMC_TIMING_MMC_DDR52 || > + ios->timing == MMC_TIMING_MMC_HS400) > regs |= ((0x1 << slot->id) << 16); > else > regs &= ~((0x1 << slot->id) << 16); > @@ -1321,6 +1322,18 @@ static int dw_mci_execute_tuning(struct mmc_host *mmc, u32 opcode) > return err; > } > > +int dw_mci_prepare_hs400_tuning(struct mmc_host *mmc, struct mmc_ios *ios) > +{ > + struct dw_mci_slot *slot = mmc_priv(mmc); > + struct dw_mci *host = slot->host; > + const struct dw_mci_drv_data *drv_data = host->drv_data; > + > + if (drv_data && drv_data->prepare_hs400_tuning) > + return drv_data->prepare_hs400_tuning(host, ios); > + > + return 0; > +} > + > static const struct mmc_host_ops dw_mci_ops = { > .request = dw_mci_request, > .pre_req = dw_mci_pre_req, > @@ -1333,6 +1346,7 @@ static const struct mmc_host_ops dw_mci_ops = { > .card_busy = dw_mci_card_busy, > .start_signal_voltage_switch = dw_mci_switch_voltage, > .init_card = dw_mci_init_card, > + .prepare_hs400_tuning = dw_mci_prepare_hs400_tuning, > }; > > static void dw_mci_request_end(struct dw_mci *host, struct mmc_request *mrq) > diff --git a/drivers/mmc/host/dw_mmc.h b/drivers/mmc/host/dw_mmc.h > index 18c4afe..d239867 100644 > --- a/drivers/mmc/host/dw_mmc.h > +++ b/drivers/mmc/host/dw_mmc.h > @@ -271,5 +271,7 @@ struct dw_mci_drv_data { > void (*set_ios)(struct dw_mci *host, struct mmc_ios *ios); > int (*parse_dt)(struct dw_mci *host); > int (*execute_tuning)(struct dw_mci_slot *slot); > + int (*prepare_hs400_tuning)(struct dw_mci *host, > + struct mmc_ios *ios); > }; > #endif /* _DW_MMC_H_ */ > ^ permalink raw reply [flat|nested] 24+ messages in thread
* [PATCH v4 1/2] mmc: dw_mmc: exynos: Support eMMC's HS400 mode @ 2015-01-20 23:02 ` Jaehoon Chung 0 siblings, 0 replies; 24+ messages in thread From: Jaehoon Chung @ 2015-01-20 23:02 UTC (permalink / raw) To: linux-arm-kernel Hi, This patch can be separated. When i tested on my board, it's not working fine. I think it depends on my timing, so i will check after change the timing. On 01/14/2015 07:30 PM, Alim Akhtar wrote: > From: Seungwon Jeon <tgih.jun@samsung.com> > > Implements HS400 mode support for exynos host driver. > This also include some updates as new mode is added. > > Signed-off-by: Seungwon Jeon <tgih.jun@samsung.com> > Signed-off-by: Alim Akhtar <alim.akhtar@samsung.com> > [Alim: addressed review comments] > --- > .../devicetree/bindings/mmc/exynos-dw-mshc.txt | 7 + > drivers/mmc/host/dw_mmc-exynos.c | 187 ++++++++++++++++---- > drivers/mmc/host/dw_mmc-exynos.h | 19 +- > drivers/mmc/host/dw_mmc.c | 16 +- > drivers/mmc/host/dw_mmc.h | 2 + > 5 files changed, 196 insertions(+), 35 deletions(-) > > diff --git a/Documentation/devicetree/bindings/mmc/exynos-dw-mshc.txt b/Documentation/devicetree/bindings/mmc/exynos-dw-mshc.txt > index ee4fc05..dcab52c 100644 > --- a/Documentation/devicetree/bindings/mmc/exynos-dw-mshc.txt > +++ b/Documentation/devicetree/bindings/mmc/exynos-dw-mshc.txt > @@ -36,6 +36,8 @@ Required Properties: > in transmit mode and CIU clock phase shift value in receive mode for double > data rate mode operation. Refer notes below for the order of the cells and the > valid values. > +* samsung,dw-mshc-hs400-timing: Specifies the value of CIU TX and RX clock phase > + shift value for hs400 mode operation. > > Notes for the sdr-timing and ddr-timing values: > > @@ -50,6 +52,9 @@ Required Properties: > - if CIU clock divider value is 0 (that is divide by 1), both tx and rx > phase shift clocks should be 0. > > +* read-strobe-delay: RCLK (Data strobe) delay to control HS400 mode > + (Latency value for delay line in Read path) > + > Required properties for a slot (Deprecated - Recommend to use one slot per host): > > * gpios: specifies a list of gpios used for command, clock and data bus. The > @@ -82,5 +87,7 @@ Example: > samsung,dw-mshc-ciu-div = <3>; > samsung,dw-mshc-sdr-timing = <2 3>; > samsung,dw-mshc-ddr-timing = <1 2>; > + samsung,dw-mshc-hs400-timing = <0 2>; > + read-strobe-delay = <90>; read-strobe-delay is exynos specific, isn't? read-strobe-delay -> samsung.read-strobe-delay. > bus-width = <8>; > }; > diff --git a/drivers/mmc/host/dw_mmc-exynos.c b/drivers/mmc/host/dw_mmc-exynos.c > index 12a5eaa..172a2a8 100644 > --- a/drivers/mmc/host/dw_mmc-exynos.c > +++ b/drivers/mmc/host/dw_mmc-exynos.c > @@ -40,7 +40,12 @@ struct dw_mci_exynos_priv_data { > u8 ciu_div; > u32 sdr_timing; > u32 ddr_timing; > + u32 hs400_timing; > + u32 tuned_sample; > u32 cur_speed; > + u32 dqs_delay; > + u32 saved_dqs_en; > + u32 saved_strobe_ctrl; > }; > > static struct dw_mci_exynos_compatible { > @@ -71,6 +76,21 @@ static struct dw_mci_exynos_compatible { > }, > }; > > +static inline u8 dw_mci_exynos_get_ciu_div(struct dw_mci *host) > +{ > + struct dw_mci_exynos_priv_data *priv = host->priv; > + > + if (priv->ctrl_type == DW_MCI_TYPE_EXYNOS4412) > + return EXYNOS4412_FIXED_CIU_CLK_DIV; > + else if (priv->ctrl_type == DW_MCI_TYPE_EXYNOS4210) > + return EXYNOS4210_FIXED_CIU_CLK_DIV; > + else if (priv->ctrl_type == DW_MCI_TYPE_EXYNOS7 || > + priv->ctrl_type == DW_MCI_TYPE_EXYNOS7_SMU) > + return SDMMC_CLKSEL_GET_DIV(mci_readl(host, CLKSEL64)) + 1; > + else > + return SDMMC_CLKSEL_GET_DIV(mci_readl(host, CLKSEL)) + 1; > +} > + > static int dw_mci_exynos_priv_init(struct dw_mci *host) > { > struct dw_mci_exynos_priv_data *priv = host->priv; > @@ -85,6 +105,16 @@ static int dw_mci_exynos_priv_init(struct dw_mci *host) > SDMMC_MPSCTRL_NON_SECURE_WRITE_BIT); > } > > + if (priv->ctrl_type >= DW_MCI_TYPE_EXYNOS5420) { > + priv->saved_strobe_ctrl = mci_readl(host, HS400_DLINE_CTRL); > + priv->saved_dqs_en = mci_readl(host, HS400_DQS_EN); > + priv->saved_dqs_en |= AXI_NON_BLOCKING_WR; > + mci_writel(host, HS400_DQS_EN, priv->saved_dqs_en); > + if (!priv->dqs_delay) > + priv->dqs_delay = > + DQS_CTRL_GET_RD_DELAY(priv->saved_strobe_ctrl); > + } > + > return 0; > } > > @@ -92,11 +122,31 @@ static int dw_mci_exynos_setup_clock(struct dw_mci *host) > { > struct dw_mci_exynos_priv_data *priv = host->priv; > > - host->bus_hz /= (priv->ciu_div + 1); > + host->bus_hz /= priv->ciu_div; Don't need to consider the case that priv->ciu_div set to 0? > > return 0; > } > > +static void dw_mci_exynos_set_clksel_timing(struct dw_mci *host, u32 timing) > +{ > + struct dw_mci_exynos_priv_data *priv = host->priv; > + u32 clksel; > + > + if (priv->ctrl_type == DW_MCI_TYPE_EXYNOS7 || > + priv->ctrl_type == DW_MCI_TYPE_EXYNOS7_SMU) > + clksel = mci_readl(host, CLKSEL64); > + else > + clksel = mci_readl(host, CLKSEL); > + > + clksel = (clksel & ~SDMMC_CLKSEL_TIMING_MASK) | timing; > + > + if (priv->ctrl_type == DW_MCI_TYPE_EXYNOS7 || > + priv->ctrl_type == DW_MCI_TYPE_EXYNOS7_SMU) > + mci_writel(host, CLKSEL64, clksel); > + else > + mci_writel(host, CLKSEL, clksel); > +} > + > #ifdef CONFIG_PM_SLEEP > static int dw_mci_exynos_suspend(struct device *dev) > { > @@ -172,30 +222,38 @@ static void dw_mci_exynos_prepare_command(struct dw_mci *host, u32 *cmdr) > } > } > > -static void dw_mci_exynos_set_ios(struct dw_mci *host, struct mmc_ios *ios) > +static void dw_mci_exynos_config_hs400(struct dw_mci *host, u32 timing) > { > struct dw_mci_exynos_priv_data *priv = host->priv; > - unsigned int wanted = ios->clock; > - unsigned long actual; > - u8 div = priv->ciu_div + 1; > + u32 dqs, strobe; > > - if (ios->timing == MMC_TIMING_MMC_DDR52) { > - if (priv->ctrl_type == DW_MCI_TYPE_EXYNOS7 || > - priv->ctrl_type == DW_MCI_TYPE_EXYNOS7_SMU) > - mci_writel(host, CLKSEL64, priv->ddr_timing); > - else > - mci_writel(host, CLKSEL, priv->ddr_timing); > - /* Should be double rate for DDR mode */ > - if (ios->bus_width == MMC_BUS_WIDTH_8) > - wanted <<= 1; > + /* > + * Not suppported to configure register Typo..supported > + * related to HS400 > + */ > + if (priv->ctrl_type < DW_MCI_TYPE_EXYNOS5420) > + return; > + > + dqs = priv->saved_dqs_en; > + strobe = priv->saved_strobe_ctrl; priv->saved_dqs_en is set at init-time. And you read the RDDQS_EN and HS400_DLINE_CTRL register at that time. Doesn't it need to consider the changed value at those register? priv->saved_xxx is reset value? > + > + if (timing == MMC_TIMING_MMC_HS400) { > + dqs |= DATA_STROBE_EN; > + strobe = DQS_CTRL_RD_DELAY(strobe, priv->dqs_delay); > } else { > - if (priv->ctrl_type == DW_MCI_TYPE_EXYNOS7 || > - priv->ctrl_type == DW_MCI_TYPE_EXYNOS7_SMU) > - mci_writel(host, CLKSEL64, priv->sdr_timing); > - else > - mci_writel(host, CLKSEL, priv->sdr_timing); > + dqs &= ~DATA_STROBE_EN; > } > > + mci_writel(host, HS400_DQS_EN, dqs); > + mci_writel(host, HS400_DLINE_CTRL, strobe); > +} > + > +static void dw_mci_exynos_adjust_clock(struct dw_mci *host, unsigned int wanted) > +{ > + struct dw_mci_exynos_priv_data *priv = host->priv; > + unsigned long actual; > + u8 div; > + int ret; > /* > * Don't care if wanted clock is zero or > * ciu clock is unavailable > @@ -207,17 +265,52 @@ static void dw_mci_exynos_set_ios(struct dw_mci *host, struct mmc_ios *ios) > if (wanted < EXYNOS_CCLKIN_MIN) > wanted = EXYNOS_CCLKIN_MIN; > > - if (wanted != priv->cur_speed) { > - int ret = clk_set_rate(host->ciu_clk, wanted * div); > - if (ret) > - dev_warn(host->dev, > - "failed to set clk-rate %u error: %d\n", > - wanted * div, ret); > - actual = clk_get_rate(host->ciu_clk); > - host->bus_hz = actual / div; > - priv->cur_speed = wanted; > - host->current_speed = 0; > + if (wanted == priv->cur_speed) > + return; > + > + div = dw_mci_exynos_get_ciu_div(host); > + ret = clk_set_rate(host->ciu_clk, wanted * div); > + if (ret) > + dev_warn(host->dev, > + "failed to set clk-rate %u error: %d\n", > + wanted * div, ret); > + actual = clk_get_rate(host->ciu_clk); > + host->bus_hz = actual / div; > + priv->cur_speed = wanted; > + host->current_speed = 0; > +} > + > +static void dw_mci_exynos_set_ios(struct dw_mci *host, struct mmc_ios *ios) > +{ > + struct dw_mci_exynos_priv_data *priv = host->priv; > + unsigned int wanted = ios->clock; > + u32 timing = ios->timing, clksel; > + > + switch (timing) { > + case MMC_TIMING_MMC_HS400: > + /* Update tuned sample timing */ > + clksel = SDMMC_CLKSEL_UP_SAMPLE( > + priv->hs400_timing, priv->tuned_sample); > + wanted <<= 1; > + break; > + case MMC_TIMING_MMC_DDR52: > + clksel = priv->ddr_timing; > + /* Should be double rate for DDR mode */ > + if (ios->bus_width == MMC_BUS_WIDTH_8) > + wanted <<= 1; > + break; > + default: > + clksel = priv->sdr_timing; > } > + > + /* Set clock timing for the requested speed mode*/ > + dw_mci_exynos_set_clksel_timing(host, clksel); > + > + /* Configure setting for HS400 */ > + dw_mci_exynos_config_hs400(host, timing); > + > + /* Configure clock rate */ > + dw_mci_exynos_adjust_clock(host, wanted); > } > > static int dw_mci_exynos_parse_dt(struct dw_mci *host) > @@ -260,6 +353,16 @@ static int dw_mci_exynos_parse_dt(struct dw_mci *host) > return ret; > > priv->ddr_timing = SDMMC_CLKSEL_TIMING(timing[0], timing[1], div); > + > + ret = of_property_read_u32_array(np, > + "samsung,dw-mshc-hs400-timing", timing, 2); > + if (!ret && of_property_read_u32(np, > + "read-strobe-delay", &priv->dqs_delay)) > + dev_info(host->dev, > + "read-strobe-delay is not found, assuming usage of default value\n"); Need the message? > + > + priv->hs400_timing = SDMMC_CLKSEL_TIMING(timing[0], timing[1], > + HS400_FIXED_CIU_CLK_DIV); Why useed the HS400_FIXED_CIU_CLK_DIV? always set to 1? Best Regards, Jaehoon Chung > host->priv = priv; > return 0; > } > @@ -285,7 +388,7 @@ static inline void dw_mci_exynos_set_clksmpl(struct dw_mci *host, u8 sample) > clksel = mci_readl(host, CLKSEL64); > else > clksel = mci_readl(host, CLKSEL); > - clksel = (clksel & ~0x7) | SDMMC_CLKSEL_CCLK_SAMPLE(sample); > + clksel = SDMMC_CLKSEL_UP_SAMPLE(clksel, sample); > if (priv->ctrl_type == DW_MCI_TYPE_EXYNOS7 || > priv->ctrl_type == DW_MCI_TYPE_EXYNOS7_SMU) > mci_writel(host, CLKSEL64, clksel); > @@ -304,13 +407,16 @@ static inline u8 dw_mci_exynos_move_next_clksmpl(struct dw_mci *host) > clksel = mci_readl(host, CLKSEL64); > else > clksel = mci_readl(host, CLKSEL); > + > sample = (clksel + 1) & 0x7; > - clksel = (clksel & ~0x7) | sample; > + clksel = SDMMC_CLKSEL_UP_SAMPLE(clksel, sample); > + > if (priv->ctrl_type == DW_MCI_TYPE_EXYNOS7 || > priv->ctrl_type == DW_MCI_TYPE_EXYNOS7_SMU) > mci_writel(host, CLKSEL64, clksel); > else > mci_writel(host, CLKSEL, clksel); > + > return sample; > } > > @@ -343,6 +449,7 @@ out: > static int dw_mci_exynos_execute_tuning(struct dw_mci_slot *slot) > { > struct dw_mci *host = slot->host; > + struct dw_mci_exynos_priv_data *priv = host->priv; > struct mmc_host *mmc = slot->mmc; > u8 start_smpl, smpl, candiates = 0; > s8 found = -1; > @@ -360,14 +467,27 @@ static int dw_mci_exynos_execute_tuning(struct dw_mci_slot *slot) > } while (start_smpl != smpl); > > found = dw_mci_exynos_get_best_clksmpl(candiates); > - if (found >= 0) > + if (found >= 0) { > dw_mci_exynos_set_clksmpl(host, found); > - else > + priv->tuned_sample = found; > + } else { > ret = -EIO; > + } > > return ret; > } > > +int dw_mci_exynos_prepare_hs400_tuning(struct dw_mci *host, > + struct mmc_ios *ios) > +{ > + struct dw_mci_exynos_priv_data *priv = host->priv; > + > + dw_mci_exynos_set_clksel_timing(host, priv->hs400_timing); > + dw_mci_exynos_adjust_clock(host, (ios->clock) << 1); > + > + return 0; > +} > + > /* Common capabilities of Exynos4/Exynos5 SoC */ > static unsigned long exynos_dwmmc_caps[4] = { > MMC_CAP_1_8V_DDR | MMC_CAP_8_BIT_DATA | MMC_CAP_CMD23, > @@ -384,6 +504,7 @@ static const struct dw_mci_drv_data exynos_drv_data = { > .set_ios = dw_mci_exynos_set_ios, > .parse_dt = dw_mci_exynos_parse_dt, > .execute_tuning = dw_mci_exynos_execute_tuning, > + .prepare_hs400_tuning = dw_mci_exynos_prepare_hs400_tuning, > }; > > static const struct of_device_id dw_mci_exynos_match[] = { > diff --git a/drivers/mmc/host/dw_mmc-exynos.h b/drivers/mmc/host/dw_mmc-exynos.h > index 7872ce5..595c934 100644 > --- a/drivers/mmc/host/dw_mmc-exynos.h > +++ b/drivers/mmc/host/dw_mmc-exynos.h > @@ -12,20 +12,36 @@ > #ifndef _DW_MMC_EXYNOS_H_ > #define _DW_MMC_EXYNOS_H_ > > -/* Extended Register's Offset */ > #define SDMMC_CLKSEL 0x09C > #define SDMMC_CLKSEL64 0x0A8 > > +/* Extended Register's Offset */ > +#define SDMMC_HS400_DQS_EN 0x180 > +#define SDMMC_HS400_ASYNC_FIFO_CTRL 0x184 > +#define SDMMC_HS400_DLINE_CTRL 0x188 > + > /* CLKSEL register defines */ > #define SDMMC_CLKSEL_CCLK_SAMPLE(x) (((x) & 7) << 0) > #define SDMMC_CLKSEL_CCLK_DRIVE(x) (((x) & 7) << 16) > #define SDMMC_CLKSEL_CCLK_DIVIDER(x) (((x) & 7) << 24) > #define SDMMC_CLKSEL_GET_DRV_WD3(x) (((x) >> 16) & 0x7) > +#define SDMMC_CLKSEL_GET_DIV(x) (((x) >> 24) & 0x7) > +#define SDMMC_CLKSEL_UP_SAMPLE(x, y) (((x) & ~SDMMC_CLKSEL_CCLK_SAMPLE(7)) |\ > + SDMMC_CLKSEL_CCLK_SAMPLE(y)) > #define SDMMC_CLKSEL_TIMING(x, y, z) (SDMMC_CLKSEL_CCLK_SAMPLE(x) | \ > SDMMC_CLKSEL_CCLK_DRIVE(y) | \ > SDMMC_CLKSEL_CCLK_DIVIDER(z)) > +#define SDMMC_CLKSEL_TIMING_MASK SDMMC_CLKSEL_TIMING(0x7, 0x7, 0x7) > #define SDMMC_CLKSEL_WAKEUP_INT BIT(11) > > +/* RCLK_EN register defines */ > +#define DATA_STROBE_EN BIT(0) > +#define AXI_NON_BLOCKING_WR BIT(7) > + > +/* DLINE_CTRL register defines */ > +#define DQS_CTRL_RD_DELAY(x, y) (((x) & ~0x3FF) | ((y) & 0x3FF)) > +#define DQS_CTRL_GET_RD_DELAY(x) ((x) & 0x3FF) > + > /* Protector Register */ > #define SDMMC_EMMCP_BASE 0x1000 > #define SDMMC_MPSECURITY (SDMMC_EMMCP_BASE + 0x0010) > @@ -49,6 +65,7 @@ > /* Fixed clock divider */ > #define EXYNOS4210_FIXED_CIU_CLK_DIV 2 > #define EXYNOS4412_FIXED_CIU_CLK_DIV 4 > +#define HS400_FIXED_CIU_CLK_DIV 1 > > /* Minimal required clock frequency for cclkin, unit: HZ */ > #define EXYNOS_CCLKIN_MIN 50000000 > diff --git a/drivers/mmc/host/dw_mmc.c b/drivers/mmc/host/dw_mmc.c > index 2e8abc8..43a3a5b 100644 > --- a/drivers/mmc/host/dw_mmc.c > +++ b/drivers/mmc/host/dw_mmc.c > @@ -1084,7 +1084,8 @@ static void dw_mci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) > regs = mci_readl(slot->host, UHS_REG); > > /* DDR mode set */ > - if (ios->timing == MMC_TIMING_MMC_DDR52) > + if (ios->timing == MMC_TIMING_MMC_DDR52 || > + ios->timing == MMC_TIMING_MMC_HS400) > regs |= ((0x1 << slot->id) << 16); > else > regs &= ~((0x1 << slot->id) << 16); > @@ -1321,6 +1322,18 @@ static int dw_mci_execute_tuning(struct mmc_host *mmc, u32 opcode) > return err; > } > > +int dw_mci_prepare_hs400_tuning(struct mmc_host *mmc, struct mmc_ios *ios) > +{ > + struct dw_mci_slot *slot = mmc_priv(mmc); > + struct dw_mci *host = slot->host; > + const struct dw_mci_drv_data *drv_data = host->drv_data; > + > + if (drv_data && drv_data->prepare_hs400_tuning) > + return drv_data->prepare_hs400_tuning(host, ios); > + > + return 0; > +} > + > static const struct mmc_host_ops dw_mci_ops = { > .request = dw_mci_request, > .pre_req = dw_mci_pre_req, > @@ -1333,6 +1346,7 @@ static const struct mmc_host_ops dw_mci_ops = { > .card_busy = dw_mci_card_busy, > .start_signal_voltage_switch = dw_mci_switch_voltage, > .init_card = dw_mci_init_card, > + .prepare_hs400_tuning = dw_mci_prepare_hs400_tuning, > }; > > static void dw_mci_request_end(struct dw_mci *host, struct mmc_request *mrq) > diff --git a/drivers/mmc/host/dw_mmc.h b/drivers/mmc/host/dw_mmc.h > index 18c4afe..d239867 100644 > --- a/drivers/mmc/host/dw_mmc.h > +++ b/drivers/mmc/host/dw_mmc.h > @@ -271,5 +271,7 @@ struct dw_mci_drv_data { > void (*set_ios)(struct dw_mci *host, struct mmc_ios *ios); > int (*parse_dt)(struct dw_mci *host); > int (*execute_tuning)(struct dw_mci_slot *slot); > + int (*prepare_hs400_tuning)(struct dw_mci *host, > + struct mmc_ios *ios); > }; > #endif /* _DW_MMC_H_ */ > ^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: [PATCH v4 1/2] mmc: dw_mmc: exynos: Support eMMC's HS400 mode 2015-01-20 23:02 ` Jaehoon Chung @ 2015-01-21 23:42 ` Alim Akhtar -1 siblings, 0 replies; 24+ messages in thread From: Alim Akhtar @ 2015-01-21 23:42 UTC (permalink / raw) To: Jaehoon Chung Cc: Alim Akhtar, linux-mmc, Chris Ball, Ulf Hansson, Seungwon Jeon, Douglas Anderson, kgene, linux-arm-kernel, devicetree, linux-samsung-soc, Abhilash Kesavan Hi Jaehoon On Wed, Jan 21, 2015 at 4:32 AM, Jaehoon Chung <jh80.chung@samsung.com> wrote: > Hi, > > This patch can be separated. > When i tested on my board, it's not working fine. > I think it depends on my timing, so i will check after change the timing. > > On 01/14/2015 07:30 PM, Alim Akhtar wrote: >> From: Seungwon Jeon <tgih.jun@samsung.com> >> >> Implements HS400 mode support for exynos host driver. >> This also include some updates as new mode is added. >> >> Signed-off-by: Seungwon Jeon <tgih.jun@samsung.com> >> Signed-off-by: Alim Akhtar <alim.akhtar@samsung.com> >> [Alim: addressed review comments] >> --- >> .../devicetree/bindings/mmc/exynos-dw-mshc.txt | 7 + >> drivers/mmc/host/dw_mmc-exynos.c | 187 ++++++++++++++++---- >> drivers/mmc/host/dw_mmc-exynos.h | 19 +- >> drivers/mmc/host/dw_mmc.c | 16 +- >> drivers/mmc/host/dw_mmc.h | 2 + >> 5 files changed, 196 insertions(+), 35 deletions(-) >> >> diff --git a/Documentation/devicetree/bindings/mmc/exynos-dw-mshc.txt b/Documentation/devicetree/bindings/mmc/exynos-dw-mshc.txt >> index ee4fc05..dcab52c 100644 >> --- a/Documentation/devicetree/bindings/mmc/exynos-dw-mshc.txt >> +++ b/Documentation/devicetree/bindings/mmc/exynos-dw-mshc.txt >> @@ -36,6 +36,8 @@ Required Properties: >> in transmit mode and CIU clock phase shift value in receive mode for double >> data rate mode operation. Refer notes below for the order of the cells and the >> valid values. >> +* samsung,dw-mshc-hs400-timing: Specifies the value of CIU TX and RX clock phase >> + shift value for hs400 mode operation. >> >> Notes for the sdr-timing and ddr-timing values: >> >> @@ -50,6 +52,9 @@ Required Properties: >> - if CIU clock divider value is 0 (that is divide by 1), both tx and rx >> phase shift clocks should be 0. >> >> +* read-strobe-delay: RCLK (Data strobe) delay to control HS400 mode >> + (Latency value for delay line in Read path) >> + >> Required properties for a slot (Deprecated - Recommend to use one slot per host): >> >> * gpios: specifies a list of gpios used for command, clock and data bus. The >> @@ -82,5 +87,7 @@ Example: >> samsung,dw-mshc-ciu-div = <3>; >> samsung,dw-mshc-sdr-timing = <2 3>; >> samsung,dw-mshc-ddr-timing = <1 2>; >> + samsung,dw-mshc-hs400-timing = <0 2>; >> + read-strobe-delay = <90>; > > read-strobe-delay is exynos specific, isn't? > read-strobe-delay -> samsung.read-strobe-delay. > read-strobe are as per hs400 spec, ok I will change this to match the naming with other properties. >> bus-width = <8>; >> }; >> diff --git a/drivers/mmc/host/dw_mmc-exynos.c b/drivers/mmc/host/dw_mmc-exynos.c >> index 12a5eaa..172a2a8 100644 >> --- a/drivers/mmc/host/dw_mmc-exynos.c >> +++ b/drivers/mmc/host/dw_mmc-exynos.c >> @@ -40,7 +40,12 @@ struct dw_mci_exynos_priv_data { >> u8 ciu_div; >> u32 sdr_timing; >> u32 ddr_timing; >> + u32 hs400_timing; >> + u32 tuned_sample; >> u32 cur_speed; >> + u32 dqs_delay; >> + u32 saved_dqs_en; >> + u32 saved_strobe_ctrl; >> }; >> >> static struct dw_mci_exynos_compatible { >> @@ -71,6 +76,21 @@ static struct dw_mci_exynos_compatible { >> }, >> }; >> >> +static inline u8 dw_mci_exynos_get_ciu_div(struct dw_mci *host) >> +{ >> + struct dw_mci_exynos_priv_data *priv = host->priv; >> + >> + if (priv->ctrl_type == DW_MCI_TYPE_EXYNOS4412) >> + return EXYNOS4412_FIXED_CIU_CLK_DIV; >> + else if (priv->ctrl_type == DW_MCI_TYPE_EXYNOS4210) >> + return EXYNOS4210_FIXED_CIU_CLK_DIV; >> + else if (priv->ctrl_type == DW_MCI_TYPE_EXYNOS7 || >> + priv->ctrl_type == DW_MCI_TYPE_EXYNOS7_SMU) >> + return SDMMC_CLKSEL_GET_DIV(mci_readl(host, CLKSEL64)) + 1; >> + else >> + return SDMMC_CLKSEL_GET_DIV(mci_readl(host, CLKSEL)) + 1; >> +} >> + >> static int dw_mci_exynos_priv_init(struct dw_mci *host) >> { >> struct dw_mci_exynos_priv_data *priv = host->priv; >> @@ -85,6 +105,16 @@ static int dw_mci_exynos_priv_init(struct dw_mci *host) >> SDMMC_MPSCTRL_NON_SECURE_WRITE_BIT); >> } >> >> + if (priv->ctrl_type >= DW_MCI_TYPE_EXYNOS5420) { >> + priv->saved_strobe_ctrl = mci_readl(host, HS400_DLINE_CTRL); >> + priv->saved_dqs_en = mci_readl(host, HS400_DQS_EN); >> + priv->saved_dqs_en |= AXI_NON_BLOCKING_WR; >> + mci_writel(host, HS400_DQS_EN, priv->saved_dqs_en); >> + if (!priv->dqs_delay) >> + priv->dqs_delay = >> + DQS_CTRL_GET_RD_DELAY(priv->saved_strobe_ctrl); >> + } >> + >> return 0; >> } >> >> @@ -92,11 +122,31 @@ static int dw_mci_exynos_setup_clock(struct dw_mci *host) >> { >> struct dw_mci_exynos_priv_data *priv = host->priv; >> >> - host->bus_hz /= (priv->ciu_div + 1); >> + host->bus_hz /= priv->ciu_div; > > Don't need to consider the case that priv->ciu_div set to 0? > Ah ok, I know at least one board sets ciu_div as zero, let me remove this change. thanks >> >> return 0; >> } >> >> +static void dw_mci_exynos_set_clksel_timing(struct dw_mci *host, u32 timing) >> +{ >> + struct dw_mci_exynos_priv_data *priv = host->priv; >> + u32 clksel; >> + >> + if (priv->ctrl_type == DW_MCI_TYPE_EXYNOS7 || >> + priv->ctrl_type == DW_MCI_TYPE_EXYNOS7_SMU) >> + clksel = mci_readl(host, CLKSEL64); >> + else >> + clksel = mci_readl(host, CLKSEL); >> + >> + clksel = (clksel & ~SDMMC_CLKSEL_TIMING_MASK) | timing; >> + >> + if (priv->ctrl_type == DW_MCI_TYPE_EXYNOS7 || >> + priv->ctrl_type == DW_MCI_TYPE_EXYNOS7_SMU) >> + mci_writel(host, CLKSEL64, clksel); >> + else >> + mci_writel(host, CLKSEL, clksel); >> +} >> + >> #ifdef CONFIG_PM_SLEEP >> static int dw_mci_exynos_suspend(struct device *dev) >> { >> @@ -172,30 +222,38 @@ static void dw_mci_exynos_prepare_command(struct dw_mci *host, u32 *cmdr) >> } >> } >> >> -static void dw_mci_exynos_set_ios(struct dw_mci *host, struct mmc_ios *ios) >> +static void dw_mci_exynos_config_hs400(struct dw_mci *host, u32 timing) >> { >> struct dw_mci_exynos_priv_data *priv = host->priv; >> - unsigned int wanted = ios->clock; >> - unsigned long actual; >> - u8 div = priv->ciu_div + 1; >> + u32 dqs, strobe; >> >> - if (ios->timing == MMC_TIMING_MMC_DDR52) { >> - if (priv->ctrl_type == DW_MCI_TYPE_EXYNOS7 || >> - priv->ctrl_type == DW_MCI_TYPE_EXYNOS7_SMU) >> - mci_writel(host, CLKSEL64, priv->ddr_timing); >> - else >> - mci_writel(host, CLKSEL, priv->ddr_timing); >> - /* Should be double rate for DDR mode */ >> - if (ios->bus_width == MMC_BUS_WIDTH_8) >> - wanted <<= 1; >> + /* >> + * Not suppported to configure register > > Typo..supported > ok will correct. >> + * related to HS400 >> + */ >> + if (priv->ctrl_type < DW_MCI_TYPE_EXYNOS5420) >> + return; >> + >> + dqs = priv->saved_dqs_en; >> + strobe = priv->saved_strobe_ctrl; > > priv->saved_dqs_en is set at init-time. > And you read the RDDQS_EN and HS400_DLINE_CTRL register at that time. > Doesn't it need to consider the changed value at those register? > > priv->saved_xxx is reset value? > Default values are read in init and adjusted below, for now only these bits are touched other bits of these register are kept as their reset values. >> + >> + if (timing == MMC_TIMING_MMC_HS400) { >> + dqs |= DATA_STROBE_EN; >> + strobe = DQS_CTRL_RD_DELAY(strobe, priv->dqs_delay); >> } else { >> - if (priv->ctrl_type == DW_MCI_TYPE_EXYNOS7 || >> - priv->ctrl_type == DW_MCI_TYPE_EXYNOS7_SMU) >> - mci_writel(host, CLKSEL64, priv->sdr_timing); >> - else >> - mci_writel(host, CLKSEL, priv->sdr_timing); >> + dqs &= ~DATA_STROBE_EN; >> } >> >> + mci_writel(host, HS400_DQS_EN, dqs); >> + mci_writel(host, HS400_DLINE_CTRL, strobe); >> +} >> + >> +static void dw_mci_exynos_adjust_clock(struct dw_mci *host, unsigned int wanted) >> +{ >> + struct dw_mci_exynos_priv_data *priv = host->priv; >> + unsigned long actual; >> + u8 div; >> + int ret; >> /* >> * Don't care if wanted clock is zero or >> * ciu clock is unavailable >> @@ -207,17 +265,52 @@ static void dw_mci_exynos_set_ios(struct dw_mci *host, struct mmc_ios *ios) >> if (wanted < EXYNOS_CCLKIN_MIN) >> wanted = EXYNOS_CCLKIN_MIN; >> >> - if (wanted != priv->cur_speed) { >> - int ret = clk_set_rate(host->ciu_clk, wanted * div); >> - if (ret) >> - dev_warn(host->dev, >> - "failed to set clk-rate %u error: %d\n", >> - wanted * div, ret); >> - actual = clk_get_rate(host->ciu_clk); >> - host->bus_hz = actual / div; >> - priv->cur_speed = wanted; >> - host->current_speed = 0; >> + if (wanted == priv->cur_speed) >> + return; >> + >> + div = dw_mci_exynos_get_ciu_div(host); >> + ret = clk_set_rate(host->ciu_clk, wanted * div); >> + if (ret) >> + dev_warn(host->dev, >> + "failed to set clk-rate %u error: %d\n", >> + wanted * div, ret); >> + actual = clk_get_rate(host->ciu_clk); >> + host->bus_hz = actual / div; >> + priv->cur_speed = wanted; >> + host->current_speed = 0; >> +} >> + >> +static void dw_mci_exynos_set_ios(struct dw_mci *host, struct mmc_ios *ios) >> +{ >> + struct dw_mci_exynos_priv_data *priv = host->priv; >> + unsigned int wanted = ios->clock; >> + u32 timing = ios->timing, clksel; >> + >> + switch (timing) { >> + case MMC_TIMING_MMC_HS400: >> + /* Update tuned sample timing */ >> + clksel = SDMMC_CLKSEL_UP_SAMPLE( >> + priv->hs400_timing, priv->tuned_sample); >> + wanted <<= 1; >> + break; >> + case MMC_TIMING_MMC_DDR52: >> + clksel = priv->ddr_timing; >> + /* Should be double rate for DDR mode */ >> + if (ios->bus_width == MMC_BUS_WIDTH_8) >> + wanted <<= 1; >> + break; >> + default: >> + clksel = priv->sdr_timing; >> } >> + >> + /* Set clock timing for the requested speed mode*/ >> + dw_mci_exynos_set_clksel_timing(host, clksel); >> + >> + /* Configure setting for HS400 */ >> + dw_mci_exynos_config_hs400(host, timing); >> + >> + /* Configure clock rate */ >> + dw_mci_exynos_adjust_clock(host, wanted); >> } >> >> static int dw_mci_exynos_parse_dt(struct dw_mci *host) >> @@ -260,6 +353,16 @@ static int dw_mci_exynos_parse_dt(struct dw_mci *host) >> return ret; >> >> priv->ddr_timing = SDMMC_CLKSEL_TIMING(timing[0], timing[1], div); >> + >> + ret = of_property_read_u32_array(np, >> + "samsung,dw-mshc-hs400-timing", timing, 2); >> + if (!ret && of_property_read_u32(np, >> + "read-strobe-delay", &priv->dqs_delay)) >> + dev_info(host->dev, >> + "read-strobe-delay is not found, assuming usage of default value\n"); > > Need the message? > Just in case the default values does not work, then user will know this is something they need to change as per their boards. >> + >> + priv->hs400_timing = SDMMC_CLKSEL_TIMING(timing[0], timing[1], >> + HS400_FIXED_CIU_CLK_DIV); > > Why useed the HS400_FIXED_CIU_CLK_DIV? always set to 1? > I thought about this, but I didn't find a case where it is anytime set to more then div by 2 to support HS400 clock input value requirement. So instead of getting this via DT, I kept fixed value, Let me know your opinion on this, in case you wants me to change this. > Best Regards, > Jaehoon Chung > >> host->priv = priv; >> return 0; >> } >> @@ -285,7 +388,7 @@ static inline void dw_mci_exynos_set_clksmpl(struct dw_mci *host, u8 sample) >> clksel = mci_readl(host, CLKSEL64); >> else >> clksel = mci_readl(host, CLKSEL); >> - clksel = (clksel & ~0x7) | SDMMC_CLKSEL_CCLK_SAMPLE(sample); >> + clksel = SDMMC_CLKSEL_UP_SAMPLE(clksel, sample); >> if (priv->ctrl_type == DW_MCI_TYPE_EXYNOS7 || >> priv->ctrl_type == DW_MCI_TYPE_EXYNOS7_SMU) >> mci_writel(host, CLKSEL64, clksel); >> @@ -304,13 +407,16 @@ static inline u8 dw_mci_exynos_move_next_clksmpl(struct dw_mci *host) >> clksel = mci_readl(host, CLKSEL64); >> else >> clksel = mci_readl(host, CLKSEL); >> + >> sample = (clksel + 1) & 0x7; >> - clksel = (clksel & ~0x7) | sample; >> + clksel = SDMMC_CLKSEL_UP_SAMPLE(clksel, sample); >> + >> if (priv->ctrl_type == DW_MCI_TYPE_EXYNOS7 || >> priv->ctrl_type == DW_MCI_TYPE_EXYNOS7_SMU) >> mci_writel(host, CLKSEL64, clksel); >> else >> mci_writel(host, CLKSEL, clksel); >> + >> return sample; >> } >> >> @@ -343,6 +449,7 @@ out: >> static int dw_mci_exynos_execute_tuning(struct dw_mci_slot *slot) >> { >> struct dw_mci *host = slot->host; >> + struct dw_mci_exynos_priv_data *priv = host->priv; >> struct mmc_host *mmc = slot->mmc; >> u8 start_smpl, smpl, candiates = 0; >> s8 found = -1; >> @@ -360,14 +467,27 @@ static int dw_mci_exynos_execute_tuning(struct dw_mci_slot *slot) >> } while (start_smpl != smpl); >> >> found = dw_mci_exynos_get_best_clksmpl(candiates); >> - if (found >= 0) >> + if (found >= 0) { >> dw_mci_exynos_set_clksmpl(host, found); >> - else >> + priv->tuned_sample = found; >> + } else { >> ret = -EIO; >> + } >> >> return ret; >> } >> >> +int dw_mci_exynos_prepare_hs400_tuning(struct dw_mci *host, >> + struct mmc_ios *ios) >> +{ >> + struct dw_mci_exynos_priv_data *priv = host->priv; >> + >> + dw_mci_exynos_set_clksel_timing(host, priv->hs400_timing); >> + dw_mci_exynos_adjust_clock(host, (ios->clock) << 1); >> + >> + return 0; >> +} >> + >> /* Common capabilities of Exynos4/Exynos5 SoC */ >> static unsigned long exynos_dwmmc_caps[4] = { >> MMC_CAP_1_8V_DDR | MMC_CAP_8_BIT_DATA | MMC_CAP_CMD23, >> @@ -384,6 +504,7 @@ static const struct dw_mci_drv_data exynos_drv_data = { >> .set_ios = dw_mci_exynos_set_ios, >> .parse_dt = dw_mci_exynos_parse_dt, >> .execute_tuning = dw_mci_exynos_execute_tuning, >> + .prepare_hs400_tuning = dw_mci_exynos_prepare_hs400_tuning, >> }; >> >> static const struct of_device_id dw_mci_exynos_match[] = { >> diff --git a/drivers/mmc/host/dw_mmc-exynos.h b/drivers/mmc/host/dw_mmc-exynos.h >> index 7872ce5..595c934 100644 >> --- a/drivers/mmc/host/dw_mmc-exynos.h >> +++ b/drivers/mmc/host/dw_mmc-exynos.h >> @@ -12,20 +12,36 @@ >> #ifndef _DW_MMC_EXYNOS_H_ >> #define _DW_MMC_EXYNOS_H_ >> >> -/* Extended Register's Offset */ >> #define SDMMC_CLKSEL 0x09C >> #define SDMMC_CLKSEL64 0x0A8 >> >> +/* Extended Register's Offset */ >> +#define SDMMC_HS400_DQS_EN 0x180 >> +#define SDMMC_HS400_ASYNC_FIFO_CTRL 0x184 >> +#define SDMMC_HS400_DLINE_CTRL 0x188 >> + >> /* CLKSEL register defines */ >> #define SDMMC_CLKSEL_CCLK_SAMPLE(x) (((x) & 7) << 0) >> #define SDMMC_CLKSEL_CCLK_DRIVE(x) (((x) & 7) << 16) >> #define SDMMC_CLKSEL_CCLK_DIVIDER(x) (((x) & 7) << 24) >> #define SDMMC_CLKSEL_GET_DRV_WD3(x) (((x) >> 16) & 0x7) >> +#define SDMMC_CLKSEL_GET_DIV(x) (((x) >> 24) & 0x7) >> +#define SDMMC_CLKSEL_UP_SAMPLE(x, y) (((x) & ~SDMMC_CLKSEL_CCLK_SAMPLE(7)) |\ >> + SDMMC_CLKSEL_CCLK_SAMPLE(y)) >> #define SDMMC_CLKSEL_TIMING(x, y, z) (SDMMC_CLKSEL_CCLK_SAMPLE(x) | \ >> SDMMC_CLKSEL_CCLK_DRIVE(y) | \ >> SDMMC_CLKSEL_CCLK_DIVIDER(z)) >> +#define SDMMC_CLKSEL_TIMING_MASK SDMMC_CLKSEL_TIMING(0x7, 0x7, 0x7) >> #define SDMMC_CLKSEL_WAKEUP_INT BIT(11) >> >> +/* RCLK_EN register defines */ >> +#define DATA_STROBE_EN BIT(0) >> +#define AXI_NON_BLOCKING_WR BIT(7) >> + >> +/* DLINE_CTRL register defines */ >> +#define DQS_CTRL_RD_DELAY(x, y) (((x) & ~0x3FF) | ((y) & 0x3FF)) >> +#define DQS_CTRL_GET_RD_DELAY(x) ((x) & 0x3FF) >> + >> /* Protector Register */ >> #define SDMMC_EMMCP_BASE 0x1000 >> #define SDMMC_MPSECURITY (SDMMC_EMMCP_BASE + 0x0010) >> @@ -49,6 +65,7 @@ >> /* Fixed clock divider */ >> #define EXYNOS4210_FIXED_CIU_CLK_DIV 2 >> #define EXYNOS4412_FIXED_CIU_CLK_DIV 4 >> +#define HS400_FIXED_CIU_CLK_DIV 1 >> >> /* Minimal required clock frequency for cclkin, unit: HZ */ >> #define EXYNOS_CCLKIN_MIN 50000000 >> diff --git a/drivers/mmc/host/dw_mmc.c b/drivers/mmc/host/dw_mmc.c >> index 2e8abc8..43a3a5b 100644 >> --- a/drivers/mmc/host/dw_mmc.c >> +++ b/drivers/mmc/host/dw_mmc.c >> @@ -1084,7 +1084,8 @@ static void dw_mci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) >> regs = mci_readl(slot->host, UHS_REG); >> >> /* DDR mode set */ >> - if (ios->timing == MMC_TIMING_MMC_DDR52) >> + if (ios->timing == MMC_TIMING_MMC_DDR52 || >> + ios->timing == MMC_TIMING_MMC_HS400) >> regs |= ((0x1 << slot->id) << 16); >> else >> regs &= ~((0x1 << slot->id) << 16); >> @@ -1321,6 +1322,18 @@ static int dw_mci_execute_tuning(struct mmc_host *mmc, u32 opcode) >> return err; >> } >> >> +int dw_mci_prepare_hs400_tuning(struct mmc_host *mmc, struct mmc_ios *ios) >> +{ >> + struct dw_mci_slot *slot = mmc_priv(mmc); >> + struct dw_mci *host = slot->host; >> + const struct dw_mci_drv_data *drv_data = host->drv_data; >> + >> + if (drv_data && drv_data->prepare_hs400_tuning) >> + return drv_data->prepare_hs400_tuning(host, ios); >> + >> + return 0; >> +} >> + >> static const struct mmc_host_ops dw_mci_ops = { >> .request = dw_mci_request, >> .pre_req = dw_mci_pre_req, >> @@ -1333,6 +1346,7 @@ static const struct mmc_host_ops dw_mci_ops = { >> .card_busy = dw_mci_card_busy, >> .start_signal_voltage_switch = dw_mci_switch_voltage, >> .init_card = dw_mci_init_card, >> + .prepare_hs400_tuning = dw_mci_prepare_hs400_tuning, >> }; >> >> static void dw_mci_request_end(struct dw_mci *host, struct mmc_request *mrq) >> diff --git a/drivers/mmc/host/dw_mmc.h b/drivers/mmc/host/dw_mmc.h >> index 18c4afe..d239867 100644 >> --- a/drivers/mmc/host/dw_mmc.h >> +++ b/drivers/mmc/host/dw_mmc.h >> @@ -271,5 +271,7 @@ struct dw_mci_drv_data { >> void (*set_ios)(struct dw_mci *host, struct mmc_ios *ios); >> int (*parse_dt)(struct dw_mci *host); >> int (*execute_tuning)(struct dw_mci_slot *slot); >> + int (*prepare_hs400_tuning)(struct dw_mci *host, >> + struct mmc_ios *ios); >> }; >> #endif /* _DW_MMC_H_ */ >> > -- Regards, Alim ^ permalink raw reply [flat|nested] 24+ messages in thread
* [PATCH v4 1/2] mmc: dw_mmc: exynos: Support eMMC's HS400 mode @ 2015-01-21 23:42 ` Alim Akhtar 0 siblings, 0 replies; 24+ messages in thread From: Alim Akhtar @ 2015-01-21 23:42 UTC (permalink / raw) To: linux-arm-kernel Hi Jaehoon On Wed, Jan 21, 2015 at 4:32 AM, Jaehoon Chung <jh80.chung@samsung.com> wrote: > Hi, > > This patch can be separated. > When i tested on my board, it's not working fine. > I think it depends on my timing, so i will check after change the timing. > > On 01/14/2015 07:30 PM, Alim Akhtar wrote: >> From: Seungwon Jeon <tgih.jun@samsung.com> >> >> Implements HS400 mode support for exynos host driver. >> This also include some updates as new mode is added. >> >> Signed-off-by: Seungwon Jeon <tgih.jun@samsung.com> >> Signed-off-by: Alim Akhtar <alim.akhtar@samsung.com> >> [Alim: addressed review comments] >> --- >> .../devicetree/bindings/mmc/exynos-dw-mshc.txt | 7 + >> drivers/mmc/host/dw_mmc-exynos.c | 187 ++++++++++++++++---- >> drivers/mmc/host/dw_mmc-exynos.h | 19 +- >> drivers/mmc/host/dw_mmc.c | 16 +- >> drivers/mmc/host/dw_mmc.h | 2 + >> 5 files changed, 196 insertions(+), 35 deletions(-) >> >> diff --git a/Documentation/devicetree/bindings/mmc/exynos-dw-mshc.txt b/Documentation/devicetree/bindings/mmc/exynos-dw-mshc.txt >> index ee4fc05..dcab52c 100644 >> --- a/Documentation/devicetree/bindings/mmc/exynos-dw-mshc.txt >> +++ b/Documentation/devicetree/bindings/mmc/exynos-dw-mshc.txt >> @@ -36,6 +36,8 @@ Required Properties: >> in transmit mode and CIU clock phase shift value in receive mode for double >> data rate mode operation. Refer notes below for the order of the cells and the >> valid values. >> +* samsung,dw-mshc-hs400-timing: Specifies the value of CIU TX and RX clock phase >> + shift value for hs400 mode operation. >> >> Notes for the sdr-timing and ddr-timing values: >> >> @@ -50,6 +52,9 @@ Required Properties: >> - if CIU clock divider value is 0 (that is divide by 1), both tx and rx >> phase shift clocks should be 0. >> >> +* read-strobe-delay: RCLK (Data strobe) delay to control HS400 mode >> + (Latency value for delay line in Read path) >> + >> Required properties for a slot (Deprecated - Recommend to use one slot per host): >> >> * gpios: specifies a list of gpios used for command, clock and data bus. The >> @@ -82,5 +87,7 @@ Example: >> samsung,dw-mshc-ciu-div = <3>; >> samsung,dw-mshc-sdr-timing = <2 3>; >> samsung,dw-mshc-ddr-timing = <1 2>; >> + samsung,dw-mshc-hs400-timing = <0 2>; >> + read-strobe-delay = <90>; > > read-strobe-delay is exynos specific, isn't? > read-strobe-delay -> samsung.read-strobe-delay. > read-strobe are as per hs400 spec, ok I will change this to match the naming with other properties. >> bus-width = <8>; >> }; >> diff --git a/drivers/mmc/host/dw_mmc-exynos.c b/drivers/mmc/host/dw_mmc-exynos.c >> index 12a5eaa..172a2a8 100644 >> --- a/drivers/mmc/host/dw_mmc-exynos.c >> +++ b/drivers/mmc/host/dw_mmc-exynos.c >> @@ -40,7 +40,12 @@ struct dw_mci_exynos_priv_data { >> u8 ciu_div; >> u32 sdr_timing; >> u32 ddr_timing; >> + u32 hs400_timing; >> + u32 tuned_sample; >> u32 cur_speed; >> + u32 dqs_delay; >> + u32 saved_dqs_en; >> + u32 saved_strobe_ctrl; >> }; >> >> static struct dw_mci_exynos_compatible { >> @@ -71,6 +76,21 @@ static struct dw_mci_exynos_compatible { >> }, >> }; >> >> +static inline u8 dw_mci_exynos_get_ciu_div(struct dw_mci *host) >> +{ >> + struct dw_mci_exynos_priv_data *priv = host->priv; >> + >> + if (priv->ctrl_type == DW_MCI_TYPE_EXYNOS4412) >> + return EXYNOS4412_FIXED_CIU_CLK_DIV; >> + else if (priv->ctrl_type == DW_MCI_TYPE_EXYNOS4210) >> + return EXYNOS4210_FIXED_CIU_CLK_DIV; >> + else if (priv->ctrl_type == DW_MCI_TYPE_EXYNOS7 || >> + priv->ctrl_type == DW_MCI_TYPE_EXYNOS7_SMU) >> + return SDMMC_CLKSEL_GET_DIV(mci_readl(host, CLKSEL64)) + 1; >> + else >> + return SDMMC_CLKSEL_GET_DIV(mci_readl(host, CLKSEL)) + 1; >> +} >> + >> static int dw_mci_exynos_priv_init(struct dw_mci *host) >> { >> struct dw_mci_exynos_priv_data *priv = host->priv; >> @@ -85,6 +105,16 @@ static int dw_mci_exynos_priv_init(struct dw_mci *host) >> SDMMC_MPSCTRL_NON_SECURE_WRITE_BIT); >> } >> >> + if (priv->ctrl_type >= DW_MCI_TYPE_EXYNOS5420) { >> + priv->saved_strobe_ctrl = mci_readl(host, HS400_DLINE_CTRL); >> + priv->saved_dqs_en = mci_readl(host, HS400_DQS_EN); >> + priv->saved_dqs_en |= AXI_NON_BLOCKING_WR; >> + mci_writel(host, HS400_DQS_EN, priv->saved_dqs_en); >> + if (!priv->dqs_delay) >> + priv->dqs_delay = >> + DQS_CTRL_GET_RD_DELAY(priv->saved_strobe_ctrl); >> + } >> + >> return 0; >> } >> >> @@ -92,11 +122,31 @@ static int dw_mci_exynos_setup_clock(struct dw_mci *host) >> { >> struct dw_mci_exynos_priv_data *priv = host->priv; >> >> - host->bus_hz /= (priv->ciu_div + 1); >> + host->bus_hz /= priv->ciu_div; > > Don't need to consider the case that priv->ciu_div set to 0? > Ah ok, I know at least one board sets ciu_div as zero, let me remove this change. thanks >> >> return 0; >> } >> >> +static void dw_mci_exynos_set_clksel_timing(struct dw_mci *host, u32 timing) >> +{ >> + struct dw_mci_exynos_priv_data *priv = host->priv; >> + u32 clksel; >> + >> + if (priv->ctrl_type == DW_MCI_TYPE_EXYNOS7 || >> + priv->ctrl_type == DW_MCI_TYPE_EXYNOS7_SMU) >> + clksel = mci_readl(host, CLKSEL64); >> + else >> + clksel = mci_readl(host, CLKSEL); >> + >> + clksel = (clksel & ~SDMMC_CLKSEL_TIMING_MASK) | timing; >> + >> + if (priv->ctrl_type == DW_MCI_TYPE_EXYNOS7 || >> + priv->ctrl_type == DW_MCI_TYPE_EXYNOS7_SMU) >> + mci_writel(host, CLKSEL64, clksel); >> + else >> + mci_writel(host, CLKSEL, clksel); >> +} >> + >> #ifdef CONFIG_PM_SLEEP >> static int dw_mci_exynos_suspend(struct device *dev) >> { >> @@ -172,30 +222,38 @@ static void dw_mci_exynos_prepare_command(struct dw_mci *host, u32 *cmdr) >> } >> } >> >> -static void dw_mci_exynos_set_ios(struct dw_mci *host, struct mmc_ios *ios) >> +static void dw_mci_exynos_config_hs400(struct dw_mci *host, u32 timing) >> { >> struct dw_mci_exynos_priv_data *priv = host->priv; >> - unsigned int wanted = ios->clock; >> - unsigned long actual; >> - u8 div = priv->ciu_div + 1; >> + u32 dqs, strobe; >> >> - if (ios->timing == MMC_TIMING_MMC_DDR52) { >> - if (priv->ctrl_type == DW_MCI_TYPE_EXYNOS7 || >> - priv->ctrl_type == DW_MCI_TYPE_EXYNOS7_SMU) >> - mci_writel(host, CLKSEL64, priv->ddr_timing); >> - else >> - mci_writel(host, CLKSEL, priv->ddr_timing); >> - /* Should be double rate for DDR mode */ >> - if (ios->bus_width == MMC_BUS_WIDTH_8) >> - wanted <<= 1; >> + /* >> + * Not suppported to configure register > > Typo..supported > ok will correct. >> + * related to HS400 >> + */ >> + if (priv->ctrl_type < DW_MCI_TYPE_EXYNOS5420) >> + return; >> + >> + dqs = priv->saved_dqs_en; >> + strobe = priv->saved_strobe_ctrl; > > priv->saved_dqs_en is set at init-time. > And you read the RDDQS_EN and HS400_DLINE_CTRL register at that time. > Doesn't it need to consider the changed value at those register? > > priv->saved_xxx is reset value? > Default values are read in init and adjusted below, for now only these bits are touched other bits of these register are kept as their reset values. >> + >> + if (timing == MMC_TIMING_MMC_HS400) { >> + dqs |= DATA_STROBE_EN; >> + strobe = DQS_CTRL_RD_DELAY(strobe, priv->dqs_delay); >> } else { >> - if (priv->ctrl_type == DW_MCI_TYPE_EXYNOS7 || >> - priv->ctrl_type == DW_MCI_TYPE_EXYNOS7_SMU) >> - mci_writel(host, CLKSEL64, priv->sdr_timing); >> - else >> - mci_writel(host, CLKSEL, priv->sdr_timing); >> + dqs &= ~DATA_STROBE_EN; >> } >> >> + mci_writel(host, HS400_DQS_EN, dqs); >> + mci_writel(host, HS400_DLINE_CTRL, strobe); >> +} >> + >> +static void dw_mci_exynos_adjust_clock(struct dw_mci *host, unsigned int wanted) >> +{ >> + struct dw_mci_exynos_priv_data *priv = host->priv; >> + unsigned long actual; >> + u8 div; >> + int ret; >> /* >> * Don't care if wanted clock is zero or >> * ciu clock is unavailable >> @@ -207,17 +265,52 @@ static void dw_mci_exynos_set_ios(struct dw_mci *host, struct mmc_ios *ios) >> if (wanted < EXYNOS_CCLKIN_MIN) >> wanted = EXYNOS_CCLKIN_MIN; >> >> - if (wanted != priv->cur_speed) { >> - int ret = clk_set_rate(host->ciu_clk, wanted * div); >> - if (ret) >> - dev_warn(host->dev, >> - "failed to set clk-rate %u error: %d\n", >> - wanted * div, ret); >> - actual = clk_get_rate(host->ciu_clk); >> - host->bus_hz = actual / div; >> - priv->cur_speed = wanted; >> - host->current_speed = 0; >> + if (wanted == priv->cur_speed) >> + return; >> + >> + div = dw_mci_exynos_get_ciu_div(host); >> + ret = clk_set_rate(host->ciu_clk, wanted * div); >> + if (ret) >> + dev_warn(host->dev, >> + "failed to set clk-rate %u error: %d\n", >> + wanted * div, ret); >> + actual = clk_get_rate(host->ciu_clk); >> + host->bus_hz = actual / div; >> + priv->cur_speed = wanted; >> + host->current_speed = 0; >> +} >> + >> +static void dw_mci_exynos_set_ios(struct dw_mci *host, struct mmc_ios *ios) >> +{ >> + struct dw_mci_exynos_priv_data *priv = host->priv; >> + unsigned int wanted = ios->clock; >> + u32 timing = ios->timing, clksel; >> + >> + switch (timing) { >> + case MMC_TIMING_MMC_HS400: >> + /* Update tuned sample timing */ >> + clksel = SDMMC_CLKSEL_UP_SAMPLE( >> + priv->hs400_timing, priv->tuned_sample); >> + wanted <<= 1; >> + break; >> + case MMC_TIMING_MMC_DDR52: >> + clksel = priv->ddr_timing; >> + /* Should be double rate for DDR mode */ >> + if (ios->bus_width == MMC_BUS_WIDTH_8) >> + wanted <<= 1; >> + break; >> + default: >> + clksel = priv->sdr_timing; >> } >> + >> + /* Set clock timing for the requested speed mode*/ >> + dw_mci_exynos_set_clksel_timing(host, clksel); >> + >> + /* Configure setting for HS400 */ >> + dw_mci_exynos_config_hs400(host, timing); >> + >> + /* Configure clock rate */ >> + dw_mci_exynos_adjust_clock(host, wanted); >> } >> >> static int dw_mci_exynos_parse_dt(struct dw_mci *host) >> @@ -260,6 +353,16 @@ static int dw_mci_exynos_parse_dt(struct dw_mci *host) >> return ret; >> >> priv->ddr_timing = SDMMC_CLKSEL_TIMING(timing[0], timing[1], div); >> + >> + ret = of_property_read_u32_array(np, >> + "samsung,dw-mshc-hs400-timing", timing, 2); >> + if (!ret && of_property_read_u32(np, >> + "read-strobe-delay", &priv->dqs_delay)) >> + dev_info(host->dev, >> + "read-strobe-delay is not found, assuming usage of default value\n"); > > Need the message? > Just in case the default values does not work, then user will know this is something they need to change as per their boards. >> + >> + priv->hs400_timing = SDMMC_CLKSEL_TIMING(timing[0], timing[1], >> + HS400_FIXED_CIU_CLK_DIV); > > Why useed the HS400_FIXED_CIU_CLK_DIV? always set to 1? > I thought about this, but I didn't find a case where it is anytime set to more then div by 2 to support HS400 clock input value requirement. So instead of getting this via DT, I kept fixed value, Let me know your opinion on this, in case you wants me to change this. > Best Regards, > Jaehoon Chung > >> host->priv = priv; >> return 0; >> } >> @@ -285,7 +388,7 @@ static inline void dw_mci_exynos_set_clksmpl(struct dw_mci *host, u8 sample) >> clksel = mci_readl(host, CLKSEL64); >> else >> clksel = mci_readl(host, CLKSEL); >> - clksel = (clksel & ~0x7) | SDMMC_CLKSEL_CCLK_SAMPLE(sample); >> + clksel = SDMMC_CLKSEL_UP_SAMPLE(clksel, sample); >> if (priv->ctrl_type == DW_MCI_TYPE_EXYNOS7 || >> priv->ctrl_type == DW_MCI_TYPE_EXYNOS7_SMU) >> mci_writel(host, CLKSEL64, clksel); >> @@ -304,13 +407,16 @@ static inline u8 dw_mci_exynos_move_next_clksmpl(struct dw_mci *host) >> clksel = mci_readl(host, CLKSEL64); >> else >> clksel = mci_readl(host, CLKSEL); >> + >> sample = (clksel + 1) & 0x7; >> - clksel = (clksel & ~0x7) | sample; >> + clksel = SDMMC_CLKSEL_UP_SAMPLE(clksel, sample); >> + >> if (priv->ctrl_type == DW_MCI_TYPE_EXYNOS7 || >> priv->ctrl_type == DW_MCI_TYPE_EXYNOS7_SMU) >> mci_writel(host, CLKSEL64, clksel); >> else >> mci_writel(host, CLKSEL, clksel); >> + >> return sample; >> } >> >> @@ -343,6 +449,7 @@ out: >> static int dw_mci_exynos_execute_tuning(struct dw_mci_slot *slot) >> { >> struct dw_mci *host = slot->host; >> + struct dw_mci_exynos_priv_data *priv = host->priv; >> struct mmc_host *mmc = slot->mmc; >> u8 start_smpl, smpl, candiates = 0; >> s8 found = -1; >> @@ -360,14 +467,27 @@ static int dw_mci_exynos_execute_tuning(struct dw_mci_slot *slot) >> } while (start_smpl != smpl); >> >> found = dw_mci_exynos_get_best_clksmpl(candiates); >> - if (found >= 0) >> + if (found >= 0) { >> dw_mci_exynos_set_clksmpl(host, found); >> - else >> + priv->tuned_sample = found; >> + } else { >> ret = -EIO; >> + } >> >> return ret; >> } >> >> +int dw_mci_exynos_prepare_hs400_tuning(struct dw_mci *host, >> + struct mmc_ios *ios) >> +{ >> + struct dw_mci_exynos_priv_data *priv = host->priv; >> + >> + dw_mci_exynos_set_clksel_timing(host, priv->hs400_timing); >> + dw_mci_exynos_adjust_clock(host, (ios->clock) << 1); >> + >> + return 0; >> +} >> + >> /* Common capabilities of Exynos4/Exynos5 SoC */ >> static unsigned long exynos_dwmmc_caps[4] = { >> MMC_CAP_1_8V_DDR | MMC_CAP_8_BIT_DATA | MMC_CAP_CMD23, >> @@ -384,6 +504,7 @@ static const struct dw_mci_drv_data exynos_drv_data = { >> .set_ios = dw_mci_exynos_set_ios, >> .parse_dt = dw_mci_exynos_parse_dt, >> .execute_tuning = dw_mci_exynos_execute_tuning, >> + .prepare_hs400_tuning = dw_mci_exynos_prepare_hs400_tuning, >> }; >> >> static const struct of_device_id dw_mci_exynos_match[] = { >> diff --git a/drivers/mmc/host/dw_mmc-exynos.h b/drivers/mmc/host/dw_mmc-exynos.h >> index 7872ce5..595c934 100644 >> --- a/drivers/mmc/host/dw_mmc-exynos.h >> +++ b/drivers/mmc/host/dw_mmc-exynos.h >> @@ -12,20 +12,36 @@ >> #ifndef _DW_MMC_EXYNOS_H_ >> #define _DW_MMC_EXYNOS_H_ >> >> -/* Extended Register's Offset */ >> #define SDMMC_CLKSEL 0x09C >> #define SDMMC_CLKSEL64 0x0A8 >> >> +/* Extended Register's Offset */ >> +#define SDMMC_HS400_DQS_EN 0x180 >> +#define SDMMC_HS400_ASYNC_FIFO_CTRL 0x184 >> +#define SDMMC_HS400_DLINE_CTRL 0x188 >> + >> /* CLKSEL register defines */ >> #define SDMMC_CLKSEL_CCLK_SAMPLE(x) (((x) & 7) << 0) >> #define SDMMC_CLKSEL_CCLK_DRIVE(x) (((x) & 7) << 16) >> #define SDMMC_CLKSEL_CCLK_DIVIDER(x) (((x) & 7) << 24) >> #define SDMMC_CLKSEL_GET_DRV_WD3(x) (((x) >> 16) & 0x7) >> +#define SDMMC_CLKSEL_GET_DIV(x) (((x) >> 24) & 0x7) >> +#define SDMMC_CLKSEL_UP_SAMPLE(x, y) (((x) & ~SDMMC_CLKSEL_CCLK_SAMPLE(7)) |\ >> + SDMMC_CLKSEL_CCLK_SAMPLE(y)) >> #define SDMMC_CLKSEL_TIMING(x, y, z) (SDMMC_CLKSEL_CCLK_SAMPLE(x) | \ >> SDMMC_CLKSEL_CCLK_DRIVE(y) | \ >> SDMMC_CLKSEL_CCLK_DIVIDER(z)) >> +#define SDMMC_CLKSEL_TIMING_MASK SDMMC_CLKSEL_TIMING(0x7, 0x7, 0x7) >> #define SDMMC_CLKSEL_WAKEUP_INT BIT(11) >> >> +/* RCLK_EN register defines */ >> +#define DATA_STROBE_EN BIT(0) >> +#define AXI_NON_BLOCKING_WR BIT(7) >> + >> +/* DLINE_CTRL register defines */ >> +#define DQS_CTRL_RD_DELAY(x, y) (((x) & ~0x3FF) | ((y) & 0x3FF)) >> +#define DQS_CTRL_GET_RD_DELAY(x) ((x) & 0x3FF) >> + >> /* Protector Register */ >> #define SDMMC_EMMCP_BASE 0x1000 >> #define SDMMC_MPSECURITY (SDMMC_EMMCP_BASE + 0x0010) >> @@ -49,6 +65,7 @@ >> /* Fixed clock divider */ >> #define EXYNOS4210_FIXED_CIU_CLK_DIV 2 >> #define EXYNOS4412_FIXED_CIU_CLK_DIV 4 >> +#define HS400_FIXED_CIU_CLK_DIV 1 >> >> /* Minimal required clock frequency for cclkin, unit: HZ */ >> #define EXYNOS_CCLKIN_MIN 50000000 >> diff --git a/drivers/mmc/host/dw_mmc.c b/drivers/mmc/host/dw_mmc.c >> index 2e8abc8..43a3a5b 100644 >> --- a/drivers/mmc/host/dw_mmc.c >> +++ b/drivers/mmc/host/dw_mmc.c >> @@ -1084,7 +1084,8 @@ static void dw_mci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) >> regs = mci_readl(slot->host, UHS_REG); >> >> /* DDR mode set */ >> - if (ios->timing == MMC_TIMING_MMC_DDR52) >> + if (ios->timing == MMC_TIMING_MMC_DDR52 || >> + ios->timing == MMC_TIMING_MMC_HS400) >> regs |= ((0x1 << slot->id) << 16); >> else >> regs &= ~((0x1 << slot->id) << 16); >> @@ -1321,6 +1322,18 @@ static int dw_mci_execute_tuning(struct mmc_host *mmc, u32 opcode) >> return err; >> } >> >> +int dw_mci_prepare_hs400_tuning(struct mmc_host *mmc, struct mmc_ios *ios) >> +{ >> + struct dw_mci_slot *slot = mmc_priv(mmc); >> + struct dw_mci *host = slot->host; >> + const struct dw_mci_drv_data *drv_data = host->drv_data; >> + >> + if (drv_data && drv_data->prepare_hs400_tuning) >> + return drv_data->prepare_hs400_tuning(host, ios); >> + >> + return 0; >> +} >> + >> static const struct mmc_host_ops dw_mci_ops = { >> .request = dw_mci_request, >> .pre_req = dw_mci_pre_req, >> @@ -1333,6 +1346,7 @@ static const struct mmc_host_ops dw_mci_ops = { >> .card_busy = dw_mci_card_busy, >> .start_signal_voltage_switch = dw_mci_switch_voltage, >> .init_card = dw_mci_init_card, >> + .prepare_hs400_tuning = dw_mci_prepare_hs400_tuning, >> }; >> >> static void dw_mci_request_end(struct dw_mci *host, struct mmc_request *mrq) >> diff --git a/drivers/mmc/host/dw_mmc.h b/drivers/mmc/host/dw_mmc.h >> index 18c4afe..d239867 100644 >> --- a/drivers/mmc/host/dw_mmc.h >> +++ b/drivers/mmc/host/dw_mmc.h >> @@ -271,5 +271,7 @@ struct dw_mci_drv_data { >> void (*set_ios)(struct dw_mci *host, struct mmc_ios *ios); >> int (*parse_dt)(struct dw_mci *host); >> int (*execute_tuning)(struct dw_mci_slot *slot); >> + int (*prepare_hs400_tuning)(struct dw_mci *host, >> + struct mmc_ios *ios); >> }; >> #endif /* _DW_MMC_H_ */ >> > -- Regards, Alim ^ permalink raw reply [flat|nested] 24+ messages in thread
* [PATCH v4 2/2] ARM: dts: Add HS400 support for exynos5420 and exynos5800 2015-01-14 10:30 ` Alim Akhtar @ 2015-01-14 10:30 ` Alim Akhtar -1 siblings, 0 replies; 24+ messages in thread From: Alim Akhtar @ 2015-01-14 10:30 UTC (permalink / raw) To: linux-mmc Cc: chris, ulf.hansson, jh80.chung, tgih.jun, dianders, alim.akhtar, kgene, linux-arm-kernel, devicetree, linux-samsung-soc, a.kesavan From: Seungwon Jeon <tgih.jun@samsung.com> HS400 timing values are added for SMDK5420, exynos5420-peach-pit and exynos5800-peach-pi boards. This also adds RCLK GPIO line, this gpio should be in pull-down state. Signed-off-by: Seungwon Jeon <tgih.jun@samsung.com> Signed-off-by: Alim Akhtar <alim.akhtar@samsung.com> [Alim: addressed review comments] --- arch/arm/boot/dts/exynos5420-peach-pit.dts | 4 +++- arch/arm/boot/dts/exynos5420-pinctrl.dtsi | 7 +++++++ arch/arm/boot/dts/exynos5420-smdk5420.dts | 4 +++- arch/arm/boot/dts/exynos5800-peach-pi.dts | 4 +++- 4 files changed, 16 insertions(+), 3 deletions(-) diff --git a/arch/arm/boot/dts/exynos5420-peach-pit.dts b/arch/arm/boot/dts/exynos5420-peach-pit.dts index 9a050e1..7ffaba8 100644 --- a/arch/arm/boot/dts/exynos5420-peach-pit.dts +++ b/arch/arm/boot/dts/exynos5420-peach-pit.dts @@ -569,8 +569,10 @@ samsung,dw-mshc-ciu-div = <3>; samsung,dw-mshc-sdr-timing = <0 4>; samsung,dw-mshc-ddr-timing = <0 2>; + samsung,dw-mshc-hs400-timing = <0 2>; + read-strobe-delay = <90>; pinctrl-names = "default"; - pinctrl-0 = <&sd0_clk &sd0_cmd &sd0_bus4 &sd0_bus8>; + pinctrl-0 = <&sd0_clk &sd0_cmd &sd0_bus4 &sd0_bus8 &sd0_rclk>; bus-width = <8>; }; diff --git a/arch/arm/boot/dts/exynos5420-pinctrl.dtsi b/arch/arm/boot/dts/exynos5420-pinctrl.dtsi index ba686e4..8b15316 100644 --- a/arch/arm/boot/dts/exynos5420-pinctrl.dtsi +++ b/arch/arm/boot/dts/exynos5420-pinctrl.dtsi @@ -201,6 +201,13 @@ samsung,pin-drv = <3>; }; + sd0_rclk: sd0-rclk { + samsung,pins = "gpc0-7"; + samsung,pin-function = <2>; + samsung,pin-pud = <1>; + samsung,pin-drv = <3>; + }; + sd1_cmd: sd1-cmd { samsung,pins = "gpc1-1"; samsung,pin-function = <2>; diff --git a/arch/arm/boot/dts/exynos5420-smdk5420.dts b/arch/arm/boot/dts/exynos5420-smdk5420.dts index 8be3d7b..5290e79 100644 --- a/arch/arm/boot/dts/exynos5420-smdk5420.dts +++ b/arch/arm/boot/dts/exynos5420-smdk5420.dts @@ -80,8 +80,10 @@ samsung,dw-mshc-ciu-div = <3>; samsung,dw-mshc-sdr-timing = <0 4>; samsung,dw-mshc-ddr-timing = <0 2>; + samsung,dw-mshc-hs400-timing = <0 2>; + read-strobe-delay = <90>; pinctrl-names = "default"; - pinctrl-0 = <&sd0_clk &sd0_cmd &sd0_bus4 &sd0_bus8>; + pinctrl-0 = <&sd0_clk &sd0_cmd &sd0_bus4 &sd0_bus8 &sd0_rclk>; bus-width = <8>; cap-mmc-highspeed; }; diff --git a/arch/arm/boot/dts/exynos5800-peach-pi.dts b/arch/arm/boot/dts/exynos5800-peach-pi.dts index e8fdda8..fa1c858 100644 --- a/arch/arm/boot/dts/exynos5800-peach-pi.dts +++ b/arch/arm/boot/dts/exynos5800-peach-pi.dts @@ -557,8 +557,10 @@ samsung,dw-mshc-ciu-div = <3>; samsung,dw-mshc-sdr-timing = <0 4>; samsung,dw-mshc-ddr-timing = <0 2>; + samsung,dw-mshc-hs400-timing = <0 2>; + read-strobe-delay = <90>; pinctrl-names = "default"; - pinctrl-0 = <&sd0_clk &sd0_cmd &sd0_bus4 &sd0_bus8>; + pinctrl-0 = <&sd0_clk &sd0_cmd &sd0_bus4 &sd0_bus8 &sd0_rclk>; bus-width = <8>; }; -- 1.7.9.5 ^ permalink raw reply related [flat|nested] 24+ messages in thread
* [PATCH v4 2/2] ARM: dts: Add HS400 support for exynos5420 and exynos5800 @ 2015-01-14 10:30 ` Alim Akhtar 0 siblings, 0 replies; 24+ messages in thread From: Alim Akhtar @ 2015-01-14 10:30 UTC (permalink / raw) To: linux-arm-kernel From: Seungwon Jeon <tgih.jun@samsung.com> HS400 timing values are added for SMDK5420, exynos5420-peach-pit and exynos5800-peach-pi boards. This also adds RCLK GPIO line, this gpio should be in pull-down state. Signed-off-by: Seungwon Jeon <tgih.jun@samsung.com> Signed-off-by: Alim Akhtar <alim.akhtar@samsung.com> [Alim: addressed review comments] --- arch/arm/boot/dts/exynos5420-peach-pit.dts | 4 +++- arch/arm/boot/dts/exynos5420-pinctrl.dtsi | 7 +++++++ arch/arm/boot/dts/exynos5420-smdk5420.dts | 4 +++- arch/arm/boot/dts/exynos5800-peach-pi.dts | 4 +++- 4 files changed, 16 insertions(+), 3 deletions(-) diff --git a/arch/arm/boot/dts/exynos5420-peach-pit.dts b/arch/arm/boot/dts/exynos5420-peach-pit.dts index 9a050e1..7ffaba8 100644 --- a/arch/arm/boot/dts/exynos5420-peach-pit.dts +++ b/arch/arm/boot/dts/exynos5420-peach-pit.dts @@ -569,8 +569,10 @@ samsung,dw-mshc-ciu-div = <3>; samsung,dw-mshc-sdr-timing = <0 4>; samsung,dw-mshc-ddr-timing = <0 2>; + samsung,dw-mshc-hs400-timing = <0 2>; + read-strobe-delay = <90>; pinctrl-names = "default"; - pinctrl-0 = <&sd0_clk &sd0_cmd &sd0_bus4 &sd0_bus8>; + pinctrl-0 = <&sd0_clk &sd0_cmd &sd0_bus4 &sd0_bus8 &sd0_rclk>; bus-width = <8>; }; diff --git a/arch/arm/boot/dts/exynos5420-pinctrl.dtsi b/arch/arm/boot/dts/exynos5420-pinctrl.dtsi index ba686e4..8b15316 100644 --- a/arch/arm/boot/dts/exynos5420-pinctrl.dtsi +++ b/arch/arm/boot/dts/exynos5420-pinctrl.dtsi @@ -201,6 +201,13 @@ samsung,pin-drv = <3>; }; + sd0_rclk: sd0-rclk { + samsung,pins = "gpc0-7"; + samsung,pin-function = <2>; + samsung,pin-pud = <1>; + samsung,pin-drv = <3>; + }; + sd1_cmd: sd1-cmd { samsung,pins = "gpc1-1"; samsung,pin-function = <2>; diff --git a/arch/arm/boot/dts/exynos5420-smdk5420.dts b/arch/arm/boot/dts/exynos5420-smdk5420.dts index 8be3d7b..5290e79 100644 --- a/arch/arm/boot/dts/exynos5420-smdk5420.dts +++ b/arch/arm/boot/dts/exynos5420-smdk5420.dts @@ -80,8 +80,10 @@ samsung,dw-mshc-ciu-div = <3>; samsung,dw-mshc-sdr-timing = <0 4>; samsung,dw-mshc-ddr-timing = <0 2>; + samsung,dw-mshc-hs400-timing = <0 2>; + read-strobe-delay = <90>; pinctrl-names = "default"; - pinctrl-0 = <&sd0_clk &sd0_cmd &sd0_bus4 &sd0_bus8>; + pinctrl-0 = <&sd0_clk &sd0_cmd &sd0_bus4 &sd0_bus8 &sd0_rclk>; bus-width = <8>; cap-mmc-highspeed; }; diff --git a/arch/arm/boot/dts/exynos5800-peach-pi.dts b/arch/arm/boot/dts/exynos5800-peach-pi.dts index e8fdda8..fa1c858 100644 --- a/arch/arm/boot/dts/exynos5800-peach-pi.dts +++ b/arch/arm/boot/dts/exynos5800-peach-pi.dts @@ -557,8 +557,10 @@ samsung,dw-mshc-ciu-div = <3>; samsung,dw-mshc-sdr-timing = <0 4>; samsung,dw-mshc-ddr-timing = <0 2>; + samsung,dw-mshc-hs400-timing = <0 2>; + read-strobe-delay = <90>; pinctrl-names = "default"; - pinctrl-0 = <&sd0_clk &sd0_cmd &sd0_bus4 &sd0_bus8>; + pinctrl-0 = <&sd0_clk &sd0_cmd &sd0_bus4 &sd0_bus8 &sd0_rclk>; bus-width = <8>; }; -- 1.7.9.5 ^ permalink raw reply related [flat|nested] 24+ messages in thread
[parent not found: <1421231446-4776-3-git-send-email-alim.akhtar-Sze3O3UU22JBDgjK7y7TUQ@public.gmane.org>]
* Re: [PATCH v4 2/2] ARM: dts: Add HS400 support for exynos5420 and exynos5800 2015-01-14 10:30 ` Alim Akhtar @ 2015-01-20 23:02 ` Jaehoon Chung -1 siblings, 0 replies; 24+ messages in thread From: Jaehoon Chung @ 2015-01-20 23:02 UTC (permalink / raw) To: Alim Akhtar, linux-mmc-u79uwXL29TY76Z2rM5mHXA Cc: chris-OsFVWbfNK3isTnJN9+BGXg, ulf.hansson-QSEj5FYQhm4dnm+yROfE0A, tgih.jun-Sze3O3UU22JBDgjK7y7TUQ, dianders-F7+t8E8rja9g9hUCZPvPmw, alim.akhtar-Re5JQEeQqe8AvxtiuMwx3w, kgene-DgEjT+Ai2ygdnm+yROfE0A, linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r, devicetree-u79uwXL29TY76Z2rM5mHXA, linux-samsung-soc-u79uwXL29TY76Z2rM5mHXA, a.kesavan-Sze3O3UU22JBDgjK7y7TUQ Hi, If you want to enable the hs400 mode, need to add "mmc-hs400-1_8v" or "mmc-hs400-1_2v". But this patch didn't add them. do you have any other plan? On 01/14/2015 07:30 PM, Alim Akhtar wrote: > From: Seungwon Jeon <tgih.jun-Sze3O3UU22JBDgjK7y7TUQ@public.gmane.org> > > HS400 timing values are added for SMDK5420, exynos5420-peach-pit > and exynos5800-peach-pi boards. > This also adds RCLK GPIO line, this gpio should be in pull-down > state. > > Signed-off-by: Seungwon Jeon <tgih.jun-Sze3O3UU22JBDgjK7y7TUQ@public.gmane.org> > Signed-off-by: Alim Akhtar <alim.akhtar-Sze3O3UU22JBDgjK7y7TUQ@public.gmane.org> > [Alim: addressed review comments] > --- > arch/arm/boot/dts/exynos5420-peach-pit.dts | 4 +++- > arch/arm/boot/dts/exynos5420-pinctrl.dtsi | 7 +++++++ > arch/arm/boot/dts/exynos5420-smdk5420.dts | 4 +++- > arch/arm/boot/dts/exynos5800-peach-pi.dts | 4 +++- > 4 files changed, 16 insertions(+), 3 deletions(-) > > diff --git a/arch/arm/boot/dts/exynos5420-peach-pit.dts b/arch/arm/boot/dts/exynos5420-peach-pit.dts > index 9a050e1..7ffaba8 100644 > --- a/arch/arm/boot/dts/exynos5420-peach-pit.dts > +++ b/arch/arm/boot/dts/exynos5420-peach-pit.dts > @@ -569,8 +569,10 @@ > samsung,dw-mshc-ciu-div = <3>; > samsung,dw-mshc-sdr-timing = <0 4>; > samsung,dw-mshc-ddr-timing = <0 2>; > + samsung,dw-mshc-hs400-timing = <0 2>; > + read-strobe-delay = <90>; > pinctrl-names = "default"; > - pinctrl-0 = <&sd0_clk &sd0_cmd &sd0_bus4 &sd0_bus8>; > + pinctrl-0 = <&sd0_clk &sd0_cmd &sd0_bus4 &sd0_bus8 &sd0_rclk>; > bus-width = <8>; > }; > > diff --git a/arch/arm/boot/dts/exynos5420-pinctrl.dtsi b/arch/arm/boot/dts/exynos5420-pinctrl.dtsi > index ba686e4..8b15316 100644 > --- a/arch/arm/boot/dts/exynos5420-pinctrl.dtsi > +++ b/arch/arm/boot/dts/exynos5420-pinctrl.dtsi > @@ -201,6 +201,13 @@ > samsung,pin-drv = <3>; > }; > > + sd0_rclk: sd0-rclk { I know it used to "sd0_rdqs", not "sd0_rclk". Change name. Best Regards, Jaehoon Chung > + samsung,pins = "gpc0-7"; > + samsung,pin-function = <2>; > + samsung,pin-pud = <1>; > + samsung,pin-drv = <3>; > + }; > + > sd1_cmd: sd1-cmd { > samsung,pins = "gpc1-1"; > samsung,pin-function = <2>; > diff --git a/arch/arm/boot/dts/exynos5420-smdk5420.dts b/arch/arm/boot/dts/exynos5420-smdk5420.dts > index 8be3d7b..5290e79 100644 > --- a/arch/arm/boot/dts/exynos5420-smdk5420.dts > +++ b/arch/arm/boot/dts/exynos5420-smdk5420.dts > @@ -80,8 +80,10 @@ > samsung,dw-mshc-ciu-div = <3>; > samsung,dw-mshc-sdr-timing = <0 4>; > samsung,dw-mshc-ddr-timing = <0 2>; > + samsung,dw-mshc-hs400-timing = <0 2>; > + read-strobe-delay = <90>; > pinctrl-names = "default"; > - pinctrl-0 = <&sd0_clk &sd0_cmd &sd0_bus4 &sd0_bus8>; > + pinctrl-0 = <&sd0_clk &sd0_cmd &sd0_bus4 &sd0_bus8 &sd0_rclk>; > bus-width = <8>; > cap-mmc-highspeed; > }; > diff --git a/arch/arm/boot/dts/exynos5800-peach-pi.dts b/arch/arm/boot/dts/exynos5800-peach-pi.dts > index e8fdda8..fa1c858 100644 > --- a/arch/arm/boot/dts/exynos5800-peach-pi.dts > +++ b/arch/arm/boot/dts/exynos5800-peach-pi.dts > @@ -557,8 +557,10 @@ > samsung,dw-mshc-ciu-div = <3>; > samsung,dw-mshc-sdr-timing = <0 4>; > samsung,dw-mshc-ddr-timing = <0 2>; > + samsung,dw-mshc-hs400-timing = <0 2>; > + read-strobe-delay = <90>; > pinctrl-names = "default"; > - pinctrl-0 = <&sd0_clk &sd0_cmd &sd0_bus4 &sd0_bus8>; > + pinctrl-0 = <&sd0_clk &sd0_cmd &sd0_bus4 &sd0_bus8 &sd0_rclk>; > bus-width = <8>; > }; > > -- To unsubscribe from this list: send the line "unsubscribe devicetree" in the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org More majordomo info at http://vger.kernel.org/majordomo-info.html ^ permalink raw reply [flat|nested] 24+ messages in thread
* [PATCH v4 2/2] ARM: dts: Add HS400 support for exynos5420 and exynos5800 @ 2015-01-20 23:02 ` Jaehoon Chung 0 siblings, 0 replies; 24+ messages in thread From: Jaehoon Chung @ 2015-01-20 23:02 UTC (permalink / raw) To: linux-arm-kernel Hi, If you want to enable the hs400 mode, need to add "mmc-hs400-1_8v" or "mmc-hs400-1_2v". But this patch didn't add them. do you have any other plan? On 01/14/2015 07:30 PM, Alim Akhtar wrote: > From: Seungwon Jeon <tgih.jun@samsung.com> > > HS400 timing values are added for SMDK5420, exynos5420-peach-pit > and exynos5800-peach-pi boards. > This also adds RCLK GPIO line, this gpio should be in pull-down > state. > > Signed-off-by: Seungwon Jeon <tgih.jun@samsung.com> > Signed-off-by: Alim Akhtar <alim.akhtar@samsung.com> > [Alim: addressed review comments] > --- > arch/arm/boot/dts/exynos5420-peach-pit.dts | 4 +++- > arch/arm/boot/dts/exynos5420-pinctrl.dtsi | 7 +++++++ > arch/arm/boot/dts/exynos5420-smdk5420.dts | 4 +++- > arch/arm/boot/dts/exynos5800-peach-pi.dts | 4 +++- > 4 files changed, 16 insertions(+), 3 deletions(-) > > diff --git a/arch/arm/boot/dts/exynos5420-peach-pit.dts b/arch/arm/boot/dts/exynos5420-peach-pit.dts > index 9a050e1..7ffaba8 100644 > --- a/arch/arm/boot/dts/exynos5420-peach-pit.dts > +++ b/arch/arm/boot/dts/exynos5420-peach-pit.dts > @@ -569,8 +569,10 @@ > samsung,dw-mshc-ciu-div = <3>; > samsung,dw-mshc-sdr-timing = <0 4>; > samsung,dw-mshc-ddr-timing = <0 2>; > + samsung,dw-mshc-hs400-timing = <0 2>; > + read-strobe-delay = <90>; > pinctrl-names = "default"; > - pinctrl-0 = <&sd0_clk &sd0_cmd &sd0_bus4 &sd0_bus8>; > + pinctrl-0 = <&sd0_clk &sd0_cmd &sd0_bus4 &sd0_bus8 &sd0_rclk>; > bus-width = <8>; > }; > > diff --git a/arch/arm/boot/dts/exynos5420-pinctrl.dtsi b/arch/arm/boot/dts/exynos5420-pinctrl.dtsi > index ba686e4..8b15316 100644 > --- a/arch/arm/boot/dts/exynos5420-pinctrl.dtsi > +++ b/arch/arm/boot/dts/exynos5420-pinctrl.dtsi > @@ -201,6 +201,13 @@ > samsung,pin-drv = <3>; > }; > > + sd0_rclk: sd0-rclk { I know it used to "sd0_rdqs", not "sd0_rclk". Change name. Best Regards, Jaehoon Chung > + samsung,pins = "gpc0-7"; > + samsung,pin-function = <2>; > + samsung,pin-pud = <1>; > + samsung,pin-drv = <3>; > + }; > + > sd1_cmd: sd1-cmd { > samsung,pins = "gpc1-1"; > samsung,pin-function = <2>; > diff --git a/arch/arm/boot/dts/exynos5420-smdk5420.dts b/arch/arm/boot/dts/exynos5420-smdk5420.dts > index 8be3d7b..5290e79 100644 > --- a/arch/arm/boot/dts/exynos5420-smdk5420.dts > +++ b/arch/arm/boot/dts/exynos5420-smdk5420.dts > @@ -80,8 +80,10 @@ > samsung,dw-mshc-ciu-div = <3>; > samsung,dw-mshc-sdr-timing = <0 4>; > samsung,dw-mshc-ddr-timing = <0 2>; > + samsung,dw-mshc-hs400-timing = <0 2>; > + read-strobe-delay = <90>; > pinctrl-names = "default"; > - pinctrl-0 = <&sd0_clk &sd0_cmd &sd0_bus4 &sd0_bus8>; > + pinctrl-0 = <&sd0_clk &sd0_cmd &sd0_bus4 &sd0_bus8 &sd0_rclk>; > bus-width = <8>; > cap-mmc-highspeed; > }; > diff --git a/arch/arm/boot/dts/exynos5800-peach-pi.dts b/arch/arm/boot/dts/exynos5800-peach-pi.dts > index e8fdda8..fa1c858 100644 > --- a/arch/arm/boot/dts/exynos5800-peach-pi.dts > +++ b/arch/arm/boot/dts/exynos5800-peach-pi.dts > @@ -557,8 +557,10 @@ > samsung,dw-mshc-ciu-div = <3>; > samsung,dw-mshc-sdr-timing = <0 4>; > samsung,dw-mshc-ddr-timing = <0 2>; > + samsung,dw-mshc-hs400-timing = <0 2>; > + read-strobe-delay = <90>; > pinctrl-names = "default"; > - pinctrl-0 = <&sd0_clk &sd0_cmd &sd0_bus4 &sd0_bus8>; > + pinctrl-0 = <&sd0_clk &sd0_cmd &sd0_bus4 &sd0_bus8 &sd0_rclk>; > bus-width = <8>; > }; > > ^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: [PATCH v4 2/2] ARM: dts: Add HS400 support for exynos5420 and exynos5800 2015-01-20 23:02 ` Jaehoon Chung @ 2015-01-21 14:12 ` Alim Akhtar -1 siblings, 0 replies; 24+ messages in thread From: Alim Akhtar @ 2015-01-21 14:12 UTC (permalink / raw) To: Jaehoon Chung Cc: Alim Akhtar, linux-mmc, Chris Ball, Ulf Hansson, Seungwon Jeon, Douglas Anderson, kgene, linux-arm-kernel, devicetree, linux-samsung-soc, Abhilash Kesavan Hi Jaehoon On Wed, Jan 21, 2015 at 4:32 AM, Jaehoon Chung <jh80.chung@samsung.com> wrote: > Hi, > > If you want to enable the hs400 mode, need to add "mmc-hs400-1_8v" or "mmc-hs400-1_2v". > But this patch didn't add them. do you have any other plan? > Yes, right, plan is to send separate patch to enable hs400, as of now I am not sure if all the 5800-peach-pi boards are populated with emmc5.0 device or not. So I will enable HS400 after confirming this point. > On 01/14/2015 07:30 PM, Alim Akhtar wrote: >> From: Seungwon Jeon <tgih.jun@samsung.com> >> >> HS400 timing values are added for SMDK5420, exynos5420-peach-pit >> and exynos5800-peach-pi boards. >> This also adds RCLK GPIO line, this gpio should be in pull-down >> state. >> >> Signed-off-by: Seungwon Jeon <tgih.jun@samsung.com> >> Signed-off-by: Alim Akhtar <alim.akhtar@samsung.com> >> [Alim: addressed review comments] >> --- >> arch/arm/boot/dts/exynos5420-peach-pit.dts | 4 +++- >> arch/arm/boot/dts/exynos5420-pinctrl.dtsi | 7 +++++++ >> arch/arm/boot/dts/exynos5420-smdk5420.dts | 4 +++- >> arch/arm/boot/dts/exynos5800-peach-pi.dts | 4 +++- >> 4 files changed, 16 insertions(+), 3 deletions(-) >> >> diff --git a/arch/arm/boot/dts/exynos5420-peach-pit.dts b/arch/arm/boot/dts/exynos5420-peach-pit.dts >> index 9a050e1..7ffaba8 100644 >> --- a/arch/arm/boot/dts/exynos5420-peach-pit.dts >> +++ b/arch/arm/boot/dts/exynos5420-peach-pit.dts >> @@ -569,8 +569,10 @@ >> samsung,dw-mshc-ciu-div = <3>; >> samsung,dw-mshc-sdr-timing = <0 4>; >> samsung,dw-mshc-ddr-timing = <0 2>; >> + samsung,dw-mshc-hs400-timing = <0 2>; >> + read-strobe-delay = <90>; >> pinctrl-names = "default"; >> - pinctrl-0 = <&sd0_clk &sd0_cmd &sd0_bus4 &sd0_bus8>; >> + pinctrl-0 = <&sd0_clk &sd0_cmd &sd0_bus4 &sd0_bus8 &sd0_rclk>; >> bus-width = <8>; >> }; >> >> diff --git a/arch/arm/boot/dts/exynos5420-pinctrl.dtsi b/arch/arm/boot/dts/exynos5420-pinctrl.dtsi >> index ba686e4..8b15316 100644 >> --- a/arch/arm/boot/dts/exynos5420-pinctrl.dtsi >> +++ b/arch/arm/boot/dts/exynos5420-pinctrl.dtsi >> @@ -201,6 +201,13 @@ >> samsung,pin-drv = <3>; >> }; >> >> + sd0_rclk: sd0-rclk { > > I know it used to "sd0_rdqs", not "sd0_rclk". > Change name. > Ok, I will change as per UM of 5800/5420, > Best Regards, > Jaehoon Chung >> + samsung,pins = "gpc0-7"; >> + samsung,pin-function = <2>; >> + samsung,pin-pud = <1>; >> + samsung,pin-drv = <3>; >> + }; >> + >> sd1_cmd: sd1-cmd { >> samsung,pins = "gpc1-1"; >> samsung,pin-function = <2>; >> diff --git a/arch/arm/boot/dts/exynos5420-smdk5420.dts b/arch/arm/boot/dts/exynos5420-smdk5420.dts >> index 8be3d7b..5290e79 100644 >> --- a/arch/arm/boot/dts/exynos5420-smdk5420.dts >> +++ b/arch/arm/boot/dts/exynos5420-smdk5420.dts >> @@ -80,8 +80,10 @@ >> samsung,dw-mshc-ciu-div = <3>; >> samsung,dw-mshc-sdr-timing = <0 4>; >> samsung,dw-mshc-ddr-timing = <0 2>; >> + samsung,dw-mshc-hs400-timing = <0 2>; >> + read-strobe-delay = <90>; >> pinctrl-names = "default"; >> - pinctrl-0 = <&sd0_clk &sd0_cmd &sd0_bus4 &sd0_bus8>; >> + pinctrl-0 = <&sd0_clk &sd0_cmd &sd0_bus4 &sd0_bus8 &sd0_rclk>; >> bus-width = <8>; >> cap-mmc-highspeed; >> }; >> diff --git a/arch/arm/boot/dts/exynos5800-peach-pi.dts b/arch/arm/boot/dts/exynos5800-peach-pi.dts >> index e8fdda8..fa1c858 100644 >> --- a/arch/arm/boot/dts/exynos5800-peach-pi.dts >> +++ b/arch/arm/boot/dts/exynos5800-peach-pi.dts >> @@ -557,8 +557,10 @@ >> samsung,dw-mshc-ciu-div = <3>; >> samsung,dw-mshc-sdr-timing = <0 4>; >> samsung,dw-mshc-ddr-timing = <0 2>; >> + samsung,dw-mshc-hs400-timing = <0 2>; >> + read-strobe-delay = <90>; >> pinctrl-names = "default"; >> - pinctrl-0 = <&sd0_clk &sd0_cmd &sd0_bus4 &sd0_bus8>; >> + pinctrl-0 = <&sd0_clk &sd0_cmd &sd0_bus4 &sd0_bus8 &sd0_rclk>; >> bus-width = <8>; >> }; >> >> > -- Regards, Alim ^ permalink raw reply [flat|nested] 24+ messages in thread
* [PATCH v4 2/2] ARM: dts: Add HS400 support for exynos5420 and exynos5800 @ 2015-01-21 14:12 ` Alim Akhtar 0 siblings, 0 replies; 24+ messages in thread From: Alim Akhtar @ 2015-01-21 14:12 UTC (permalink / raw) To: linux-arm-kernel Hi Jaehoon On Wed, Jan 21, 2015 at 4:32 AM, Jaehoon Chung <jh80.chung@samsung.com> wrote: > Hi, > > If you want to enable the hs400 mode, need to add "mmc-hs400-1_8v" or "mmc-hs400-1_2v". > But this patch didn't add them. do you have any other plan? > Yes, right, plan is to send separate patch to enable hs400, as of now I am not sure if all the 5800-peach-pi boards are populated with emmc5.0 device or not. So I will enable HS400 after confirming this point. > On 01/14/2015 07:30 PM, Alim Akhtar wrote: >> From: Seungwon Jeon <tgih.jun@samsung.com> >> >> HS400 timing values are added for SMDK5420, exynos5420-peach-pit >> and exynos5800-peach-pi boards. >> This also adds RCLK GPIO line, this gpio should be in pull-down >> state. >> >> Signed-off-by: Seungwon Jeon <tgih.jun@samsung.com> >> Signed-off-by: Alim Akhtar <alim.akhtar@samsung.com> >> [Alim: addressed review comments] >> --- >> arch/arm/boot/dts/exynos5420-peach-pit.dts | 4 +++- >> arch/arm/boot/dts/exynos5420-pinctrl.dtsi | 7 +++++++ >> arch/arm/boot/dts/exynos5420-smdk5420.dts | 4 +++- >> arch/arm/boot/dts/exynos5800-peach-pi.dts | 4 +++- >> 4 files changed, 16 insertions(+), 3 deletions(-) >> >> diff --git a/arch/arm/boot/dts/exynos5420-peach-pit.dts b/arch/arm/boot/dts/exynos5420-peach-pit.dts >> index 9a050e1..7ffaba8 100644 >> --- a/arch/arm/boot/dts/exynos5420-peach-pit.dts >> +++ b/arch/arm/boot/dts/exynos5420-peach-pit.dts >> @@ -569,8 +569,10 @@ >> samsung,dw-mshc-ciu-div = <3>; >> samsung,dw-mshc-sdr-timing = <0 4>; >> samsung,dw-mshc-ddr-timing = <0 2>; >> + samsung,dw-mshc-hs400-timing = <0 2>; >> + read-strobe-delay = <90>; >> pinctrl-names = "default"; >> - pinctrl-0 = <&sd0_clk &sd0_cmd &sd0_bus4 &sd0_bus8>; >> + pinctrl-0 = <&sd0_clk &sd0_cmd &sd0_bus4 &sd0_bus8 &sd0_rclk>; >> bus-width = <8>; >> }; >> >> diff --git a/arch/arm/boot/dts/exynos5420-pinctrl.dtsi b/arch/arm/boot/dts/exynos5420-pinctrl.dtsi >> index ba686e4..8b15316 100644 >> --- a/arch/arm/boot/dts/exynos5420-pinctrl.dtsi >> +++ b/arch/arm/boot/dts/exynos5420-pinctrl.dtsi >> @@ -201,6 +201,13 @@ >> samsung,pin-drv = <3>; >> }; >> >> + sd0_rclk: sd0-rclk { > > I know it used to "sd0_rdqs", not "sd0_rclk". > Change name. > Ok, I will change as per UM of 5800/5420, > Best Regards, > Jaehoon Chung >> + samsung,pins = "gpc0-7"; >> + samsung,pin-function = <2>; >> + samsung,pin-pud = <1>; >> + samsung,pin-drv = <3>; >> + }; >> + >> sd1_cmd: sd1-cmd { >> samsung,pins = "gpc1-1"; >> samsung,pin-function = <2>; >> diff --git a/arch/arm/boot/dts/exynos5420-smdk5420.dts b/arch/arm/boot/dts/exynos5420-smdk5420.dts >> index 8be3d7b..5290e79 100644 >> --- a/arch/arm/boot/dts/exynos5420-smdk5420.dts >> +++ b/arch/arm/boot/dts/exynos5420-smdk5420.dts >> @@ -80,8 +80,10 @@ >> samsung,dw-mshc-ciu-div = <3>; >> samsung,dw-mshc-sdr-timing = <0 4>; >> samsung,dw-mshc-ddr-timing = <0 2>; >> + samsung,dw-mshc-hs400-timing = <0 2>; >> + read-strobe-delay = <90>; >> pinctrl-names = "default"; >> - pinctrl-0 = <&sd0_clk &sd0_cmd &sd0_bus4 &sd0_bus8>; >> + pinctrl-0 = <&sd0_clk &sd0_cmd &sd0_bus4 &sd0_bus8 &sd0_rclk>; >> bus-width = <8>; >> cap-mmc-highspeed; >> }; >> diff --git a/arch/arm/boot/dts/exynos5800-peach-pi.dts b/arch/arm/boot/dts/exynos5800-peach-pi.dts >> index e8fdda8..fa1c858 100644 >> --- a/arch/arm/boot/dts/exynos5800-peach-pi.dts >> +++ b/arch/arm/boot/dts/exynos5800-peach-pi.dts >> @@ -557,8 +557,10 @@ >> samsung,dw-mshc-ciu-div = <3>; >> samsung,dw-mshc-sdr-timing = <0 4>; >> samsung,dw-mshc-ddr-timing = <0 2>; >> + samsung,dw-mshc-hs400-timing = <0 2>; >> + read-strobe-delay = <90>; >> pinctrl-names = "default"; >> - pinctrl-0 = <&sd0_clk &sd0_cmd &sd0_bus4 &sd0_bus8>; >> + pinctrl-0 = <&sd0_clk &sd0_cmd &sd0_bus4 &sd0_bus8 &sd0_rclk>; >> bus-width = <8>; >> }; >> >> > -- Regards, Alim ^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: [PATCH v4 2/2] ARM: dts: Add HS400 support for exynos5420 and exynos5800 2015-01-21 14:12 ` Alim Akhtar @ 2015-01-22 2:28 ` Jaehoon Chung -1 siblings, 0 replies; 24+ messages in thread From: Jaehoon Chung @ 2015-01-22 2:28 UTC (permalink / raw) To: Alim Akhtar Cc: Alim Akhtar, linux-mmc, Chris Ball, Ulf Hansson, Seungwon Jeon, Douglas Anderson, kgene, linux-arm-kernel, devicetree, linux-samsung-soc, Abhilash Kesavan Hi. On 01/21/2015 11:12 PM, Alim Akhtar wrote: > Hi Jaehoon > > On Wed, Jan 21, 2015 at 4:32 AM, Jaehoon Chung <jh80.chung@samsung.com> wrote: >> Hi, >> >> If you want to enable the hs400 mode, need to add "mmc-hs400-1_8v" or "mmc-hs400-1_2v". >> But this patch didn't add them. do you have any other plan? >> > Yes, right, plan is to send separate patch to enable hs400, as of now > I am not sure if all the 5800-peach-pi boards are populated with > emmc5.0 device or not. So I will enable HS400 after confirming this > point. I know if card is not support hs400, then it should be enabled to other bus mode. Best Regards, Jaehoon Chung >> On 01/14/2015 07:30 PM, Alim Akhtar wrote: >>> From: Seungwon Jeon <tgih.jun@samsung.com> >>> >>> HS400 timing values are added for SMDK5420, exynos5420-peach-pit >>> and exynos5800-peach-pi boards. >>> This also adds RCLK GPIO line, this gpio should be in pull-down >>> state. >>> >>> Signed-off-by: Seungwon Jeon <tgih.jun@samsung.com> >>> Signed-off-by: Alim Akhtar <alim.akhtar@samsung.com> >>> [Alim: addressed review comments] >>> --- >>> arch/arm/boot/dts/exynos5420-peach-pit.dts | 4 +++- >>> arch/arm/boot/dts/exynos5420-pinctrl.dtsi | 7 +++++++ >>> arch/arm/boot/dts/exynos5420-smdk5420.dts | 4 +++- >>> arch/arm/boot/dts/exynos5800-peach-pi.dts | 4 +++- >>> 4 files changed, 16 insertions(+), 3 deletions(-) >>> >>> diff --git a/arch/arm/boot/dts/exynos5420-peach-pit.dts b/arch/arm/boot/dts/exynos5420-peach-pit.dts >>> index 9a050e1..7ffaba8 100644 >>> --- a/arch/arm/boot/dts/exynos5420-peach-pit.dts >>> +++ b/arch/arm/boot/dts/exynos5420-peach-pit.dts >>> @@ -569,8 +569,10 @@ >>> samsung,dw-mshc-ciu-div = <3>; >>> samsung,dw-mshc-sdr-timing = <0 4>; >>> samsung,dw-mshc-ddr-timing = <0 2>; >>> + samsung,dw-mshc-hs400-timing = <0 2>; >>> + read-strobe-delay = <90>; >>> pinctrl-names = "default"; >>> - pinctrl-0 = <&sd0_clk &sd0_cmd &sd0_bus4 &sd0_bus8>; >>> + pinctrl-0 = <&sd0_clk &sd0_cmd &sd0_bus4 &sd0_bus8 &sd0_rclk>; >>> bus-width = <8>; >>> }; >>> >>> diff --git a/arch/arm/boot/dts/exynos5420-pinctrl.dtsi b/arch/arm/boot/dts/exynos5420-pinctrl.dtsi >>> index ba686e4..8b15316 100644 >>> --- a/arch/arm/boot/dts/exynos5420-pinctrl.dtsi >>> +++ b/arch/arm/boot/dts/exynos5420-pinctrl.dtsi >>> @@ -201,6 +201,13 @@ >>> samsung,pin-drv = <3>; >>> }; >>> >>> + sd0_rclk: sd0-rclk { >> >> I know it used to "sd0_rdqs", not "sd0_rclk". >> Change name. >> > Ok, I will change as per UM of 5800/5420, > >> Best Regards, >> Jaehoon Chung >>> + samsung,pins = "gpc0-7"; >>> + samsung,pin-function = <2>; >>> + samsung,pin-pud = <1>; >>> + samsung,pin-drv = <3>; >>> + }; >>> + >>> sd1_cmd: sd1-cmd { >>> samsung,pins = "gpc1-1"; >>> samsung,pin-function = <2>; >>> diff --git a/arch/arm/boot/dts/exynos5420-smdk5420.dts b/arch/arm/boot/dts/exynos5420-smdk5420.dts >>> index 8be3d7b..5290e79 100644 >>> --- a/arch/arm/boot/dts/exynos5420-smdk5420.dts >>> +++ b/arch/arm/boot/dts/exynos5420-smdk5420.dts >>> @@ -80,8 +80,10 @@ >>> samsung,dw-mshc-ciu-div = <3>; >>> samsung,dw-mshc-sdr-timing = <0 4>; >>> samsung,dw-mshc-ddr-timing = <0 2>; >>> + samsung,dw-mshc-hs400-timing = <0 2>; >>> + read-strobe-delay = <90>; >>> pinctrl-names = "default"; >>> - pinctrl-0 = <&sd0_clk &sd0_cmd &sd0_bus4 &sd0_bus8>; >>> + pinctrl-0 = <&sd0_clk &sd0_cmd &sd0_bus4 &sd0_bus8 &sd0_rclk>; >>> bus-width = <8>; >>> cap-mmc-highspeed; >>> }; >>> diff --git a/arch/arm/boot/dts/exynos5800-peach-pi.dts b/arch/arm/boot/dts/exynos5800-peach-pi.dts >>> index e8fdda8..fa1c858 100644 >>> --- a/arch/arm/boot/dts/exynos5800-peach-pi.dts >>> +++ b/arch/arm/boot/dts/exynos5800-peach-pi.dts >>> @@ -557,8 +557,10 @@ >>> samsung,dw-mshc-ciu-div = <3>; >>> samsung,dw-mshc-sdr-timing = <0 4>; >>> samsung,dw-mshc-ddr-timing = <0 2>; >>> + samsung,dw-mshc-hs400-timing = <0 2>; >>> + read-strobe-delay = <90>; >>> pinctrl-names = "default"; >>> - pinctrl-0 = <&sd0_clk &sd0_cmd &sd0_bus4 &sd0_bus8>; >>> + pinctrl-0 = <&sd0_clk &sd0_cmd &sd0_bus4 &sd0_bus8 &sd0_rclk>; >>> bus-width = <8>; >>> }; >>> >>> >> > > > ^ permalink raw reply [flat|nested] 24+ messages in thread
* [PATCH v4 2/2] ARM: dts: Add HS400 support for exynos5420 and exynos5800 @ 2015-01-22 2:28 ` Jaehoon Chung 0 siblings, 0 replies; 24+ messages in thread From: Jaehoon Chung @ 2015-01-22 2:28 UTC (permalink / raw) To: linux-arm-kernel Hi. On 01/21/2015 11:12 PM, Alim Akhtar wrote: > Hi Jaehoon > > On Wed, Jan 21, 2015 at 4:32 AM, Jaehoon Chung <jh80.chung@samsung.com> wrote: >> Hi, >> >> If you want to enable the hs400 mode, need to add "mmc-hs400-1_8v" or "mmc-hs400-1_2v". >> But this patch didn't add them. do you have any other plan? >> > Yes, right, plan is to send separate patch to enable hs400, as of now > I am not sure if all the 5800-peach-pi boards are populated with > emmc5.0 device or not. So I will enable HS400 after confirming this > point. I know if card is not support hs400, then it should be enabled to other bus mode. Best Regards, Jaehoon Chung >> On 01/14/2015 07:30 PM, Alim Akhtar wrote: >>> From: Seungwon Jeon <tgih.jun@samsung.com> >>> >>> HS400 timing values are added for SMDK5420, exynos5420-peach-pit >>> and exynos5800-peach-pi boards. >>> This also adds RCLK GPIO line, this gpio should be in pull-down >>> state. >>> >>> Signed-off-by: Seungwon Jeon <tgih.jun@samsung.com> >>> Signed-off-by: Alim Akhtar <alim.akhtar@samsung.com> >>> [Alim: addressed review comments] >>> --- >>> arch/arm/boot/dts/exynos5420-peach-pit.dts | 4 +++- >>> arch/arm/boot/dts/exynos5420-pinctrl.dtsi | 7 +++++++ >>> arch/arm/boot/dts/exynos5420-smdk5420.dts | 4 +++- >>> arch/arm/boot/dts/exynos5800-peach-pi.dts | 4 +++- >>> 4 files changed, 16 insertions(+), 3 deletions(-) >>> >>> diff --git a/arch/arm/boot/dts/exynos5420-peach-pit.dts b/arch/arm/boot/dts/exynos5420-peach-pit.dts >>> index 9a050e1..7ffaba8 100644 >>> --- a/arch/arm/boot/dts/exynos5420-peach-pit.dts >>> +++ b/arch/arm/boot/dts/exynos5420-peach-pit.dts >>> @@ -569,8 +569,10 @@ >>> samsung,dw-mshc-ciu-div = <3>; >>> samsung,dw-mshc-sdr-timing = <0 4>; >>> samsung,dw-mshc-ddr-timing = <0 2>; >>> + samsung,dw-mshc-hs400-timing = <0 2>; >>> + read-strobe-delay = <90>; >>> pinctrl-names = "default"; >>> - pinctrl-0 = <&sd0_clk &sd0_cmd &sd0_bus4 &sd0_bus8>; >>> + pinctrl-0 = <&sd0_clk &sd0_cmd &sd0_bus4 &sd0_bus8 &sd0_rclk>; >>> bus-width = <8>; >>> }; >>> >>> diff --git a/arch/arm/boot/dts/exynos5420-pinctrl.dtsi b/arch/arm/boot/dts/exynos5420-pinctrl.dtsi >>> index ba686e4..8b15316 100644 >>> --- a/arch/arm/boot/dts/exynos5420-pinctrl.dtsi >>> +++ b/arch/arm/boot/dts/exynos5420-pinctrl.dtsi >>> @@ -201,6 +201,13 @@ >>> samsung,pin-drv = <3>; >>> }; >>> >>> + sd0_rclk: sd0-rclk { >> >> I know it used to "sd0_rdqs", not "sd0_rclk". >> Change name. >> > Ok, I will change as per UM of 5800/5420, > >> Best Regards, >> Jaehoon Chung >>> + samsung,pins = "gpc0-7"; >>> + samsung,pin-function = <2>; >>> + samsung,pin-pud = <1>; >>> + samsung,pin-drv = <3>; >>> + }; >>> + >>> sd1_cmd: sd1-cmd { >>> samsung,pins = "gpc1-1"; >>> samsung,pin-function = <2>; >>> diff --git a/arch/arm/boot/dts/exynos5420-smdk5420.dts b/arch/arm/boot/dts/exynos5420-smdk5420.dts >>> index 8be3d7b..5290e79 100644 >>> --- a/arch/arm/boot/dts/exynos5420-smdk5420.dts >>> +++ b/arch/arm/boot/dts/exynos5420-smdk5420.dts >>> @@ -80,8 +80,10 @@ >>> samsung,dw-mshc-ciu-div = <3>; >>> samsung,dw-mshc-sdr-timing = <0 4>; >>> samsung,dw-mshc-ddr-timing = <0 2>; >>> + samsung,dw-mshc-hs400-timing = <0 2>; >>> + read-strobe-delay = <90>; >>> pinctrl-names = "default"; >>> - pinctrl-0 = <&sd0_clk &sd0_cmd &sd0_bus4 &sd0_bus8>; >>> + pinctrl-0 = <&sd0_clk &sd0_cmd &sd0_bus4 &sd0_bus8 &sd0_rclk>; >>> bus-width = <8>; >>> cap-mmc-highspeed; >>> }; >>> diff --git a/arch/arm/boot/dts/exynos5800-peach-pi.dts b/arch/arm/boot/dts/exynos5800-peach-pi.dts >>> index e8fdda8..fa1c858 100644 >>> --- a/arch/arm/boot/dts/exynos5800-peach-pi.dts >>> +++ b/arch/arm/boot/dts/exynos5800-peach-pi.dts >>> @@ -557,8 +557,10 @@ >>> samsung,dw-mshc-ciu-div = <3>; >>> samsung,dw-mshc-sdr-timing = <0 4>; >>> samsung,dw-mshc-ddr-timing = <0 2>; >>> + samsung,dw-mshc-hs400-timing = <0 2>; >>> + read-strobe-delay = <90>; >>> pinctrl-names = "default"; >>> - pinctrl-0 = <&sd0_clk &sd0_cmd &sd0_bus4 &sd0_bus8>; >>> + pinctrl-0 = <&sd0_clk &sd0_cmd &sd0_bus4 &sd0_bus8 &sd0_rclk>; >>> bus-width = <8>; >>> }; >>> >>> >> > > > ^ permalink raw reply [flat|nested] 24+ messages in thread
[parent not found: <54C06049.5070106-Sze3O3UU22JBDgjK7y7TUQ@public.gmane.org>]
* Re: [PATCH v4 2/2] ARM: dts: Add HS400 support for exynos5420 and exynos5800 2015-01-22 2:28 ` Jaehoon Chung @ 2015-01-29 2:43 ` Alim Akhtar -1 siblings, 0 replies; 24+ messages in thread From: Alim Akhtar @ 2015-01-29 2:43 UTC (permalink / raw) To: Jaehoon Chung Cc: Alim Akhtar, linux-mmc-u79uwXL29TY76Z2rM5mHXA, Chris Ball, Ulf Hansson, Seungwon Jeon, Douglas Anderson, kgene, linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r, devicetree-u79uwXL29TY76Z2rM5mHXA, linux-samsung-soc-u79uwXL29TY76Z2rM5mHXA, Abhilash Kesavan Hi Jaehoon, Thanks for review. On Thu, Jan 22, 2015 at 11:28 AM, Jaehoon Chung <jh80.chung-Sze3O3UU22JBDgjK7y7TUQ@public.gmane.org> wrote: > Hi. > > On 01/21/2015 11:12 PM, Alim Akhtar wrote: >> Hi Jaehoon >> >> On Wed, Jan 21, 2015 at 4:32 AM, Jaehoon Chung <jh80.chung-Sze3O3UU22JBDgjK7y7TUQ@public.gmane.org> wrote: >>> Hi, >>> >>> If you want to enable the hs400 mode, need to add "mmc-hs400-1_8v" or "mmc-hs400-1_2v". >>> But this patch didn't add them. do you have any other plan? >>> >> Yes, right, plan is to send separate patch to enable hs400, as of now >> I am not sure if all the 5800-peach-pi boards are populated with >> emmc5.0 device or not. So I will enable HS400 after confirming this >> point. > > I know if card is not support hs400, then it should be enabled to other bus mode. > hmm...mmc-hs{200/400}-1_8v are host capabilities, so host should first support this, then we can enable it. ok, I will enable HS400 for peach-pi in this series. Also I checked UMs for 5420/5800, in UM, strobe signal is named as RCLK, so going to keep the same name as UM. Will resend the patches after modification shortly. > Best Regards, > Jaehoon Chung > >>> On 01/14/2015 07:30 PM, Alim Akhtar wrote: >>>> From: Seungwon Jeon <tgih.jun-Sze3O3UU22JBDgjK7y7TUQ@public.gmane.org> >>>> >>>> HS400 timing values are added for SMDK5420, exynos5420-peach-pit >>>> and exynos5800-peach-pi boards. >>>> This also adds RCLK GPIO line, this gpio should be in pull-down >>>> state. >>>> >>>> Signed-off-by: Seungwon Jeon <tgih.jun-Sze3O3UU22JBDgjK7y7TUQ@public.gmane.org> >>>> Signed-off-by: Alim Akhtar <alim.akhtar-Sze3O3UU22JBDgjK7y7TUQ@public.gmane.org> >>>> [Alim: addressed review comments] >>>> --- >>>> arch/arm/boot/dts/exynos5420-peach-pit.dts | 4 +++- >>>> arch/arm/boot/dts/exynos5420-pinctrl.dtsi | 7 +++++++ >>>> arch/arm/boot/dts/exynos5420-smdk5420.dts | 4 +++- >>>> arch/arm/boot/dts/exynos5800-peach-pi.dts | 4 +++- >>>> 4 files changed, 16 insertions(+), 3 deletions(-) >>>> >>>> diff --git a/arch/arm/boot/dts/exynos5420-peach-pit.dts b/arch/arm/boot/dts/exynos5420-peach-pit.dts >>>> index 9a050e1..7ffaba8 100644 >>>> --- a/arch/arm/boot/dts/exynos5420-peach-pit.dts >>>> +++ b/arch/arm/boot/dts/exynos5420-peach-pit.dts >>>> @@ -569,8 +569,10 @@ >>>> samsung,dw-mshc-ciu-div = <3>; >>>> samsung,dw-mshc-sdr-timing = <0 4>; >>>> samsung,dw-mshc-ddr-timing = <0 2>; >>>> + samsung,dw-mshc-hs400-timing = <0 2>; >>>> + read-strobe-delay = <90>; >>>> pinctrl-names = "default"; >>>> - pinctrl-0 = <&sd0_clk &sd0_cmd &sd0_bus4 &sd0_bus8>; >>>> + pinctrl-0 = <&sd0_clk &sd0_cmd &sd0_bus4 &sd0_bus8 &sd0_rclk>; >>>> bus-width = <8>; >>>> }; >>>> >>>> diff --git a/arch/arm/boot/dts/exynos5420-pinctrl.dtsi b/arch/arm/boot/dts/exynos5420-pinctrl.dtsi >>>> index ba686e4..8b15316 100644 >>>> --- a/arch/arm/boot/dts/exynos5420-pinctrl.dtsi >>>> +++ b/arch/arm/boot/dts/exynos5420-pinctrl.dtsi >>>> @@ -201,6 +201,13 @@ >>>> samsung,pin-drv = <3>; >>>> }; >>>> >>>> + sd0_rclk: sd0-rclk { >>> >>> I know it used to "sd0_rdqs", not "sd0_rclk". >>> Change name. >>> >> Ok, I will change as per UM of 5800/5420, >> >>> Best Regards, >>> Jaehoon Chung >>>> + samsung,pins = "gpc0-7"; >>>> + samsung,pin-function = <2>; >>>> + samsung,pin-pud = <1>; >>>> + samsung,pin-drv = <3>; >>>> + }; >>>> + >>>> sd1_cmd: sd1-cmd { >>>> samsung,pins = "gpc1-1"; >>>> samsung,pin-function = <2>; >>>> diff --git a/arch/arm/boot/dts/exynos5420-smdk5420.dts b/arch/arm/boot/dts/exynos5420-smdk5420.dts >>>> index 8be3d7b..5290e79 100644 >>>> --- a/arch/arm/boot/dts/exynos5420-smdk5420.dts >>>> +++ b/arch/arm/boot/dts/exynos5420-smdk5420.dts >>>> @@ -80,8 +80,10 @@ >>>> samsung,dw-mshc-ciu-div = <3>; >>>> samsung,dw-mshc-sdr-timing = <0 4>; >>>> samsung,dw-mshc-ddr-timing = <0 2>; >>>> + samsung,dw-mshc-hs400-timing = <0 2>; >>>> + read-strobe-delay = <90>; >>>> pinctrl-names = "default"; >>>> - pinctrl-0 = <&sd0_clk &sd0_cmd &sd0_bus4 &sd0_bus8>; >>>> + pinctrl-0 = <&sd0_clk &sd0_cmd &sd0_bus4 &sd0_bus8 &sd0_rclk>; >>>> bus-width = <8>; >>>> cap-mmc-highspeed; >>>> }; >>>> diff --git a/arch/arm/boot/dts/exynos5800-peach-pi.dts b/arch/arm/boot/dts/exynos5800-peach-pi.dts >>>> index e8fdda8..fa1c858 100644 >>>> --- a/arch/arm/boot/dts/exynos5800-peach-pi.dts >>>> +++ b/arch/arm/boot/dts/exynos5800-peach-pi.dts >>>> @@ -557,8 +557,10 @@ >>>> samsung,dw-mshc-ciu-div = <3>; >>>> samsung,dw-mshc-sdr-timing = <0 4>; >>>> samsung,dw-mshc-ddr-timing = <0 2>; >>>> + samsung,dw-mshc-hs400-timing = <0 2>; >>>> + read-strobe-delay = <90>; >>>> pinctrl-names = "default"; >>>> - pinctrl-0 = <&sd0_clk &sd0_cmd &sd0_bus4 &sd0_bus8>; >>>> + pinctrl-0 = <&sd0_clk &sd0_cmd &sd0_bus4 &sd0_bus8 &sd0_rclk>; >>>> bus-width = <8>; >>>> }; >>>> >>>> >>> >> >> >> > -- Regards, Alim -- To unsubscribe from this list: send the line "unsubscribe devicetree" in the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org More majordomo info at http://vger.kernel.org/majordomo-info.html ^ permalink raw reply [flat|nested] 24+ messages in thread
* [PATCH v4 2/2] ARM: dts: Add HS400 support for exynos5420 and exynos5800 @ 2015-01-29 2:43 ` Alim Akhtar 0 siblings, 0 replies; 24+ messages in thread From: Alim Akhtar @ 2015-01-29 2:43 UTC (permalink / raw) To: linux-arm-kernel Hi Jaehoon, Thanks for review. On Thu, Jan 22, 2015 at 11:28 AM, Jaehoon Chung <jh80.chung@samsung.com> wrote: > Hi. > > On 01/21/2015 11:12 PM, Alim Akhtar wrote: >> Hi Jaehoon >> >> On Wed, Jan 21, 2015 at 4:32 AM, Jaehoon Chung <jh80.chung@samsung.com> wrote: >>> Hi, >>> >>> If you want to enable the hs400 mode, need to add "mmc-hs400-1_8v" or "mmc-hs400-1_2v". >>> But this patch didn't add them. do you have any other plan? >>> >> Yes, right, plan is to send separate patch to enable hs400, as of now >> I am not sure if all the 5800-peach-pi boards are populated with >> emmc5.0 device or not. So I will enable HS400 after confirming this >> point. > > I know if card is not support hs400, then it should be enabled to other bus mode. > hmm...mmc-hs{200/400}-1_8v are host capabilities, so host should first support this, then we can enable it. ok, I will enable HS400 for peach-pi in this series. Also I checked UMs for 5420/5800, in UM, strobe signal is named as RCLK, so going to keep the same name as UM. Will resend the patches after modification shortly. > Best Regards, > Jaehoon Chung > >>> On 01/14/2015 07:30 PM, Alim Akhtar wrote: >>>> From: Seungwon Jeon <tgih.jun@samsung.com> >>>> >>>> HS400 timing values are added for SMDK5420, exynos5420-peach-pit >>>> and exynos5800-peach-pi boards. >>>> This also adds RCLK GPIO line, this gpio should be in pull-down >>>> state. >>>> >>>> Signed-off-by: Seungwon Jeon <tgih.jun@samsung.com> >>>> Signed-off-by: Alim Akhtar <alim.akhtar@samsung.com> >>>> [Alim: addressed review comments] >>>> --- >>>> arch/arm/boot/dts/exynos5420-peach-pit.dts | 4 +++- >>>> arch/arm/boot/dts/exynos5420-pinctrl.dtsi | 7 +++++++ >>>> arch/arm/boot/dts/exynos5420-smdk5420.dts | 4 +++- >>>> arch/arm/boot/dts/exynos5800-peach-pi.dts | 4 +++- >>>> 4 files changed, 16 insertions(+), 3 deletions(-) >>>> >>>> diff --git a/arch/arm/boot/dts/exynos5420-peach-pit.dts b/arch/arm/boot/dts/exynos5420-peach-pit.dts >>>> index 9a050e1..7ffaba8 100644 >>>> --- a/arch/arm/boot/dts/exynos5420-peach-pit.dts >>>> +++ b/arch/arm/boot/dts/exynos5420-peach-pit.dts >>>> @@ -569,8 +569,10 @@ >>>> samsung,dw-mshc-ciu-div = <3>; >>>> samsung,dw-mshc-sdr-timing = <0 4>; >>>> samsung,dw-mshc-ddr-timing = <0 2>; >>>> + samsung,dw-mshc-hs400-timing = <0 2>; >>>> + read-strobe-delay = <90>; >>>> pinctrl-names = "default"; >>>> - pinctrl-0 = <&sd0_clk &sd0_cmd &sd0_bus4 &sd0_bus8>; >>>> + pinctrl-0 = <&sd0_clk &sd0_cmd &sd0_bus4 &sd0_bus8 &sd0_rclk>; >>>> bus-width = <8>; >>>> }; >>>> >>>> diff --git a/arch/arm/boot/dts/exynos5420-pinctrl.dtsi b/arch/arm/boot/dts/exynos5420-pinctrl.dtsi >>>> index ba686e4..8b15316 100644 >>>> --- a/arch/arm/boot/dts/exynos5420-pinctrl.dtsi >>>> +++ b/arch/arm/boot/dts/exynos5420-pinctrl.dtsi >>>> @@ -201,6 +201,13 @@ >>>> samsung,pin-drv = <3>; >>>> }; >>>> >>>> + sd0_rclk: sd0-rclk { >>> >>> I know it used to "sd0_rdqs", not "sd0_rclk". >>> Change name. >>> >> Ok, I will change as per UM of 5800/5420, >> >>> Best Regards, >>> Jaehoon Chung >>>> + samsung,pins = "gpc0-7"; >>>> + samsung,pin-function = <2>; >>>> + samsung,pin-pud = <1>; >>>> + samsung,pin-drv = <3>; >>>> + }; >>>> + >>>> sd1_cmd: sd1-cmd { >>>> samsung,pins = "gpc1-1"; >>>> samsung,pin-function = <2>; >>>> diff --git a/arch/arm/boot/dts/exynos5420-smdk5420.dts b/arch/arm/boot/dts/exynos5420-smdk5420.dts >>>> index 8be3d7b..5290e79 100644 >>>> --- a/arch/arm/boot/dts/exynos5420-smdk5420.dts >>>> +++ b/arch/arm/boot/dts/exynos5420-smdk5420.dts >>>> @@ -80,8 +80,10 @@ >>>> samsung,dw-mshc-ciu-div = <3>; >>>> samsung,dw-mshc-sdr-timing = <0 4>; >>>> samsung,dw-mshc-ddr-timing = <0 2>; >>>> + samsung,dw-mshc-hs400-timing = <0 2>; >>>> + read-strobe-delay = <90>; >>>> pinctrl-names = "default"; >>>> - pinctrl-0 = <&sd0_clk &sd0_cmd &sd0_bus4 &sd0_bus8>; >>>> + pinctrl-0 = <&sd0_clk &sd0_cmd &sd0_bus4 &sd0_bus8 &sd0_rclk>; >>>> bus-width = <8>; >>>> cap-mmc-highspeed; >>>> }; >>>> diff --git a/arch/arm/boot/dts/exynos5800-peach-pi.dts b/arch/arm/boot/dts/exynos5800-peach-pi.dts >>>> index e8fdda8..fa1c858 100644 >>>> --- a/arch/arm/boot/dts/exynos5800-peach-pi.dts >>>> +++ b/arch/arm/boot/dts/exynos5800-peach-pi.dts >>>> @@ -557,8 +557,10 @@ >>>> samsung,dw-mshc-ciu-div = <3>; >>>> samsung,dw-mshc-sdr-timing = <0 4>; >>>> samsung,dw-mshc-ddr-timing = <0 2>; >>>> + samsung,dw-mshc-hs400-timing = <0 2>; >>>> + read-strobe-delay = <90>; >>>> pinctrl-names = "default"; >>>> - pinctrl-0 = <&sd0_clk &sd0_cmd &sd0_bus4 &sd0_bus8>; >>>> + pinctrl-0 = <&sd0_clk &sd0_cmd &sd0_bus4 &sd0_bus8 &sd0_rclk>; >>>> bus-width = <8>; >>>> }; >>>> >>>> >>> >> >> >> > -- Regards, Alim ^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: [PATCH v4 0/2] mmc: dw_mmc: exynos: Add HS400 support 2015-01-14 10:30 ` Alim Akhtar @ 2015-01-14 13:32 ` Jaehoon Chung -1 siblings, 0 replies; 24+ messages in thread From: Jaehoon Chung @ 2015-01-14 13:32 UTC (permalink / raw) To: Alim Akhtar, linux-mmc Cc: devicetree, ulf.hansson, linux-samsung-soc, tgih.jun, chris, dianders, jh80.chung, kgene, a.kesavan, alim.akhtar, linux-arm-kernel Hi, Alim. On 01/14/2015 07:30 PM, Alim Akhtar wrote: > This adds HS400 mode support for exynos dw_mmc host controller. > > Currently tested on Exynos5800-peach-pi platform for HS400 mode. > Tested HS200 mode with this series applied, HS200 still works. > > Appreciate testing on other exynos5/7 platform which supports emmc5.0 I will test this patch on exynos5/7 board. Best Regards, Jaehoon Chung > > Changes in V4: > * drop the idea of changing existing binding for ciu_div as per [1] > * addressed comments from Jaehoon Chung [2] > > [1] http://www.spinics.net/lists/linux-samsung-soc/msg40923.html > [2] http://www.spinics.net/lists/devicetree/msg64373.html > > Changes in V3: > rebased on ulf's next (commit: 607b448 mmc: core: Make tuning block patterns static) > > Seungwon Jeon (2): > mmc: dw_mmc: exynos: Support eMMC's HS400 mode > ARM: dts: Add HS400 support for exynos5420 and exynos5800 > > .../devicetree/bindings/mmc/exynos-dw-mshc.txt | 7 + > arch/arm/boot/dts/exynos5420-peach-pit.dts | 4 +- > arch/arm/boot/dts/exynos5420-pinctrl.dtsi | 7 + > arch/arm/boot/dts/exynos5420-smdk5420.dts | 4 +- > arch/arm/boot/dts/exynos5800-peach-pi.dts | 4 +- > drivers/mmc/host/dw_mmc-exynos.c | 187 ++++++++++++++++---- > drivers/mmc/host/dw_mmc-exynos.h | 19 +- > drivers/mmc/host/dw_mmc.c | 16 +- > drivers/mmc/host/dw_mmc.h | 2 + > 9 files changed, 212 insertions(+), 38 deletions(-) > ^ permalink raw reply [flat|nested] 24+ messages in thread
* [PATCH v4 0/2] mmc: dw_mmc: exynos: Add HS400 support @ 2015-01-14 13:32 ` Jaehoon Chung 0 siblings, 0 replies; 24+ messages in thread From: Jaehoon Chung @ 2015-01-14 13:32 UTC (permalink / raw) To: linux-arm-kernel Hi, Alim. On 01/14/2015 07:30 PM, Alim Akhtar wrote: > This adds HS400 mode support for exynos dw_mmc host controller. > > Currently tested on Exynos5800-peach-pi platform for HS400 mode. > Tested HS200 mode with this series applied, HS200 still works. > > Appreciate testing on other exynos5/7 platform which supports emmc5.0 I will test this patch on exynos5/7 board. Best Regards, Jaehoon Chung > > Changes in V4: > * drop the idea of changing existing binding for ciu_div as per [1] > * addressed comments from Jaehoon Chung [2] > > [1] http://www.spinics.net/lists/linux-samsung-soc/msg40923.html > [2] http://www.spinics.net/lists/devicetree/msg64373.html > > Changes in V3: > rebased on ulf's next (commit: 607b448 mmc: core: Make tuning block patterns static) > > Seungwon Jeon (2): > mmc: dw_mmc: exynos: Support eMMC's HS400 mode > ARM: dts: Add HS400 support for exynos5420 and exynos5800 > > .../devicetree/bindings/mmc/exynos-dw-mshc.txt | 7 + > arch/arm/boot/dts/exynos5420-peach-pit.dts | 4 +- > arch/arm/boot/dts/exynos5420-pinctrl.dtsi | 7 + > arch/arm/boot/dts/exynos5420-smdk5420.dts | 4 +- > arch/arm/boot/dts/exynos5800-peach-pi.dts | 4 +- > drivers/mmc/host/dw_mmc-exynos.c | 187 ++++++++++++++++---- > drivers/mmc/host/dw_mmc-exynos.h | 19 +- > drivers/mmc/host/dw_mmc.c | 16 +- > drivers/mmc/host/dw_mmc.h | 2 + > 9 files changed, 212 insertions(+), 38 deletions(-) > ^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: [PATCH v4 0/2] mmc: dw_mmc: exynos: Add HS400 support 2015-01-14 13:32 ` Jaehoon Chung @ 2015-01-14 15:35 ` Kukjin Kim -1 siblings, 0 replies; 24+ messages in thread From: Kukjin Kim @ 2015-01-14 15:35 UTC (permalink / raw) To: Jaehoon Chung Cc: Alim Akhtar, linux-mmc, devicetree, ulf.hansson, linux-samsung-soc, tgih.jun, chris, dianders, kgene, a.kesavan, alim.akhtar, linux-arm-kernel On 01/14/15 22:32, Jaehoon Chung wrote: > Hi, Alim. > > On 01/14/2015 07:30 PM, Alim Akhtar wrote: >> This adds HS400 mode support for exynos dw_mmc host controller. >> >> Currently tested on Exynos5800-peach-pi platform for HS400 mode. >> Tested HS200 mode with this series applied, HS200 still works. >> >> Appreciate testing on other exynos5/7 platform which supports emmc5.0 > > I will test this patch on exynos5/7 board. > What's the result? :-) If it's OK, I'll take DT changes for exynos stuff, I'm not sure about the driver changes though... Thanks, Kukjin > Best Regards, > Jaehoon Chung >> >> Changes in V4: >> * drop the idea of changing existing binding for ciu_div as per [1] >> * addressed comments from Jaehoon Chung [2] >> >> [1] http://www.spinics.net/lists/linux-samsung-soc/msg40923.html >> [2] http://www.spinics.net/lists/devicetree/msg64373.html >> >> Changes in V3: >> rebased on ulf's next (commit: 607b448 mmc: core: Make tuning block patterns static) >> >> Seungwon Jeon (2): >> mmc: dw_mmc: exynos: Support eMMC's HS400 mode >> ARM: dts: Add HS400 support for exynos5420 and exynos5800 >> >> .../devicetree/bindings/mmc/exynos-dw-mshc.txt | 7 + >> arch/arm/boot/dts/exynos5420-peach-pit.dts | 4 +- >> arch/arm/boot/dts/exynos5420-pinctrl.dtsi | 7 + >> arch/arm/boot/dts/exynos5420-smdk5420.dts | 4 +- >> arch/arm/boot/dts/exynos5800-peach-pi.dts | 4 +- >> drivers/mmc/host/dw_mmc-exynos.c | 187 ++++++++++++++++---- >> drivers/mmc/host/dw_mmc-exynos.h | 19 +- >> drivers/mmc/host/dw_mmc.c | 16 +- >> drivers/mmc/host/dw_mmc.h | 2 + >> 9 files changed, 212 insertions(+), 38 deletions(-) ^ permalink raw reply [flat|nested] 24+ messages in thread
* [PATCH v4 0/2] mmc: dw_mmc: exynos: Add HS400 support @ 2015-01-14 15:35 ` Kukjin Kim 0 siblings, 0 replies; 24+ messages in thread From: Kukjin Kim @ 2015-01-14 15:35 UTC (permalink / raw) To: linux-arm-kernel On 01/14/15 22:32, Jaehoon Chung wrote: > Hi, Alim. > > On 01/14/2015 07:30 PM, Alim Akhtar wrote: >> This adds HS400 mode support for exynos dw_mmc host controller. >> >> Currently tested on Exynos5800-peach-pi platform for HS400 mode. >> Tested HS200 mode with this series applied, HS200 still works. >> >> Appreciate testing on other exynos5/7 platform which supports emmc5.0 > > I will test this patch on exynos5/7 board. > What's the result? :-) If it's OK, I'll take DT changes for exynos stuff, I'm not sure about the driver changes though... Thanks, Kukjin > Best Regards, > Jaehoon Chung >> >> Changes in V4: >> * drop the idea of changing existing binding for ciu_div as per [1] >> * addressed comments from Jaehoon Chung [2] >> >> [1] http://www.spinics.net/lists/linux-samsung-soc/msg40923.html >> [2] http://www.spinics.net/lists/devicetree/msg64373.html >> >> Changes in V3: >> rebased on ulf's next (commit: 607b448 mmc: core: Make tuning block patterns static) >> >> Seungwon Jeon (2): >> mmc: dw_mmc: exynos: Support eMMC's HS400 mode >> ARM: dts: Add HS400 support for exynos5420 and exynos5800 >> >> .../devicetree/bindings/mmc/exynos-dw-mshc.txt | 7 + >> arch/arm/boot/dts/exynos5420-peach-pit.dts | 4 +- >> arch/arm/boot/dts/exynos5420-pinctrl.dtsi | 7 + >> arch/arm/boot/dts/exynos5420-smdk5420.dts | 4 +- >> arch/arm/boot/dts/exynos5800-peach-pi.dts | 4 +- >> drivers/mmc/host/dw_mmc-exynos.c | 187 ++++++++++++++++---- >> drivers/mmc/host/dw_mmc-exynos.h | 19 +- >> drivers/mmc/host/dw_mmc.c | 16 +- >> drivers/mmc/host/dw_mmc.h | 2 + >> 9 files changed, 212 insertions(+), 38 deletions(-) ^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: [PATCH v4 0/2] mmc: dw_mmc: exynos: Add HS400 support 2015-01-14 15:35 ` Kukjin Kim @ 2015-01-14 15:56 ` Ulf Hansson -1 siblings, 0 replies; 24+ messages in thread From: Ulf Hansson @ 2015-01-14 15:56 UTC (permalink / raw) To: Kukjin Kim Cc: Jaehoon Chung, Alim Akhtar, linux-mmc, devicetree, linux-samsung-soc, tgih.jun, Chris Ball, Doug Anderson, ABHILASH KESAVAN, Alim Akhtar, linux-arm-kernel On 14 January 2015 at 16:35, Kukjin Kim <kgene@kernel.org> wrote: > On 01/14/15 22:32, Jaehoon Chung wrote: >> Hi, Alim. >> >> On 01/14/2015 07:30 PM, Alim Akhtar wrote: >>> This adds HS400 mode support for exynos dw_mmc host controller. >>> >>> Currently tested on Exynos5800-peach-pi platform for HS400 mode. >>> Tested HS200 mode with this series applied, HS200 still works. >>> >>> Appreciate testing on other exynos5/7 platform which supports emmc5.0 >> >> I will test this patch on exynos5/7 board. >> > > What's the result? :-) If it's OK, I'll take DT changes for exynos > stuff, I'm not sure about the driver changes though... Kukjin, As I understand it, there is a dependency between the patches, since driver adds supports for new DT bindings. So, unless I am mistaken I think it would be best to take this complete patchset through my mmc tree. With your ack of course. Kind regards Uffe ^ permalink raw reply [flat|nested] 24+ messages in thread
* [PATCH v4 0/2] mmc: dw_mmc: exynos: Add HS400 support @ 2015-01-14 15:56 ` Ulf Hansson 0 siblings, 0 replies; 24+ messages in thread From: Ulf Hansson @ 2015-01-14 15:56 UTC (permalink / raw) To: linux-arm-kernel On 14 January 2015 at 16:35, Kukjin Kim <kgene@kernel.org> wrote: > On 01/14/15 22:32, Jaehoon Chung wrote: >> Hi, Alim. >> >> On 01/14/2015 07:30 PM, Alim Akhtar wrote: >>> This adds HS400 mode support for exynos dw_mmc host controller. >>> >>> Currently tested on Exynos5800-peach-pi platform for HS400 mode. >>> Tested HS200 mode with this series applied, HS200 still works. >>> >>> Appreciate testing on other exynos5/7 platform which supports emmc5.0 >> >> I will test this patch on exynos5/7 board. >> > > What's the result? :-) If it's OK, I'll take DT changes for exynos > stuff, I'm not sure about the driver changes though... Kukjin, As I understand it, there is a dependency between the patches, since driver adds supports for new DT bindings. So, unless I am mistaken I think it would be best to take this complete patchset through my mmc tree. With your ack of course. Kind regards Uffe ^ permalink raw reply [flat|nested] 24+ messages in thread
end of thread, other threads:[~2015-01-29 2:43 UTC | newest] Thread overview: 24+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2015-01-14 10:30 [PATCH v4 0/2] mmc: dw_mmc: exynos: Add HS400 support Alim Akhtar 2015-01-14 10:30 ` Alim Akhtar 2015-01-14 10:30 ` [PATCH v4 1/2] mmc: dw_mmc: exynos: Support eMMC's HS400 mode Alim Akhtar 2015-01-14 10:30 ` Alim Akhtar 2015-01-20 23:02 ` Jaehoon Chung 2015-01-20 23:02 ` Jaehoon Chung 2015-01-21 23:42 ` Alim Akhtar 2015-01-21 23:42 ` Alim Akhtar 2015-01-14 10:30 ` [PATCH v4 2/2] ARM: dts: Add HS400 support for exynos5420 and exynos5800 Alim Akhtar 2015-01-14 10:30 ` Alim Akhtar [not found] ` <1421231446-4776-3-git-send-email-alim.akhtar-Sze3O3UU22JBDgjK7y7TUQ@public.gmane.org> 2015-01-20 23:02 ` Jaehoon Chung 2015-01-20 23:02 ` Jaehoon Chung 2015-01-21 14:12 ` Alim Akhtar 2015-01-21 14:12 ` Alim Akhtar 2015-01-22 2:28 ` Jaehoon Chung 2015-01-22 2:28 ` Jaehoon Chung [not found] ` <54C06049.5070106-Sze3O3UU22JBDgjK7y7TUQ@public.gmane.org> 2015-01-29 2:43 ` Alim Akhtar 2015-01-29 2:43 ` Alim Akhtar 2015-01-14 13:32 ` [PATCH v4 0/2] mmc: dw_mmc: exynos: Add HS400 support Jaehoon Chung 2015-01-14 13:32 ` Jaehoon Chung 2015-01-14 15:35 ` Kukjin Kim 2015-01-14 15:35 ` Kukjin Kim 2015-01-14 15:56 ` Ulf Hansson 2015-01-14 15:56 ` Ulf Hansson
This is an external index of several public inboxes, see mirroring instructions on how to clone and mirror all data and code used by this external index.