[PATCH] mmc: dw_mmc: dw_mci_get_cd check MMC_CAP_NONREMOVABLE
When non-removable is used for emmc, MMC_CAP_NONREMOVABLE should also be checked, otherwise detection fail since present=0 Signed-off-by: Zhangfei Gao zhangfei@linaro.org --- drivers/mmc/host/dw_mmc.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/mmc/host/dw_mmc.c b/drivers/mmc/host/dw_mmc.c index 488a8af..5d327e4 100644 --- a/drivers/mmc/host/dw_mmc.c +++ b/drivers/mmc/host/dw_mmc.c @@ -1308,7 +1308,8 @@ static int dw_mci_get_cd(struct mmc_host *mmc) int gpio_cd = mmc_gpio_get_cd(mmc); /* Use platform get_cd function, else try onboard card detect */ - if (brd-quirks DW_MCI_QUIRK_BROKEN_CARD_DETECTION) + if ((brd-quirks DW_MCI_QUIRK_BROKEN_CARD_DETECTION) || + (mmc-caps MMC_CAP_NONREMOVABLE)) present = 1; else if (!IS_ERR_VALUE(gpio_cd)) present = gpio_cd; -- 1.9.1 -- To unsubscribe from this list: send the line unsubscribe linux-mmc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH] mmc: dw_mmc: fix dw_mci_get_cd
Introduced from commit bf626e5550f24aec24975a0e85ad8e572ca76a6b CDETECT is ignored since negated return value of mmc_gpio_get_cd(mmc) can not be checked by IS_ERR_VALUE. Add spin_lock_bh(host-lock) for atomic accessing DW_MMC_CARD_PRESENT, otherwise sd detect may occasionally fail. Signed-off-by: Zhangfei Gao zhangfei@linaro.org Reported-by: Kevin Hilman khil...@linaro.org Reviewed-by: Sachin Kamat sachin.ka...@linaro.org Tested-by: Sachin Kamat sachin.ka...@linaro.org --- drivers/mmc/host/dw_mmc.c | 12 +--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/drivers/mmc/host/dw_mmc.c b/drivers/mmc/host/dw_mmc.c index a776f24f4311..55cd110a49c4 100644 --- a/drivers/mmc/host/dw_mmc.c +++ b/drivers/mmc/host/dw_mmc.c @@ -1033,7 +1033,8 @@ static int dw_mci_get_cd(struct mmc_host *mmc) int present; struct dw_mci_slot *slot = mmc_priv(mmc); struct dw_mci_board *brd = slot-host-pdata; - int gpio_cd = !mmc_gpio_get_cd(mmc); + struct dw_mci *host = slot-host; + int gpio_cd = mmc_gpio_get_cd(mmc); /* Use platform get_cd function, else try onboard card detect */ if (brd-quirks DW_MCI_QUIRK_BROKEN_CARD_DETECTION) @@ -1041,11 +1042,12 @@ static int dw_mci_get_cd(struct mmc_host *mmc) else if (brd-get_cd) present = !brd-get_cd(slot-id); else if (!IS_ERR_VALUE(gpio_cd)) - present = !!gpio_cd; + present = gpio_cd; else present = (mci_readl(slot-host, CDETECT) (1 slot-id)) == 0 ? 1 : 0; + spin_lock_bh(host-lock); if (present) { set_bit(DW_MMC_CARD_PRESENT, slot-flags); dev_dbg(mmc-class_dev, card is present\n); @@ -1053,6 +1055,7 @@ static int dw_mci_get_cd(struct mmc_host *mmc) clear_bit(DW_MMC_CARD_PRESENT, slot-flags); dev_dbg(mmc-class_dev, card is not present\n); } + spin_unlock_bh(host-lock); return present; } @@ -2081,7 +2084,7 @@ static int dw_mci_of_get_wp_gpio(struct device *dev, u8 slot) return gpio; } -/* find the cd gpio for a given slot; or -1 if none specified */ +/* find the cd gpio for a given slot */ static void dw_mci_of_get_cd_gpio(struct device *dev, u8 slot, struct mmc_host *mmc) { @@ -2411,6 +2414,9 @@ static struct dw_mci_board *dw_mci_parse_dt(struct dw_mci *host) if (of_find_property(np, caps2-mmc-hs200-1_2v, NULL)) pdata-caps2 |= MMC_CAP2_HS200_1_2V_SDR; + if (of_get_property(np, cd-inverted, NULL)) + pdata-caps2 |= MMC_CAP2_CD_ACTIVE_HIGH; + return pdata; } -- 1.7.9.5 -- To unsubscribe from this list: send the line unsubscribe linux-mmc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH] mmc: dw_mmc: fix dw_mci_get_cd
Introduced from commit bf626e5550f24aec24975a0e85ad8e572ca76a6b CDETECT is ignored since negated return value of mmc_gpio_get_cd(mmc) can not be checked by IS_ERR_VALUE. Add spin_lock_bh(host-lock) for atomic accessing DW_MMC_CARD_PRESENT, otherwise sd detect may occasionally fail. Signed-off-by: Zhangfei Gao zhangfei@linaro.org Reported-by: Kevin Hilman khil...@linaro.org Reviewed-by: Sachin Kamat sachin.ka...@linaro.org Tested-by: Sachin Kamat sachin.ka...@linaro.org --- drivers/mmc/host/dw_mmc.c |9 ++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/drivers/mmc/host/dw_mmc.c b/drivers/mmc/host/dw_mmc.c index a776f24f4311..9ded62c8225e 100644 --- a/drivers/mmc/host/dw_mmc.c +++ b/drivers/mmc/host/dw_mmc.c @@ -1033,7 +1033,8 @@ static int dw_mci_get_cd(struct mmc_host *mmc) int present; struct dw_mci_slot *slot = mmc_priv(mmc); struct dw_mci_board *brd = slot-host-pdata; - int gpio_cd = !mmc_gpio_get_cd(mmc); + struct dw_mci *host = slot-host; + int gpio_cd = mmc_gpio_get_cd(mmc); /* Use platform get_cd function, else try onboard card detect */ if (brd-quirks DW_MCI_QUIRK_BROKEN_CARD_DETECTION) @@ -1041,11 +1042,12 @@ static int dw_mci_get_cd(struct mmc_host *mmc) else if (brd-get_cd) present = !brd-get_cd(slot-id); else if (!IS_ERR_VALUE(gpio_cd)) - present = !!gpio_cd; + present = !gpio_cd; else present = (mci_readl(slot-host, CDETECT) (1 slot-id)) == 0 ? 1 : 0; + spin_lock_bh(host-lock); if (present) { set_bit(DW_MMC_CARD_PRESENT, slot-flags); dev_dbg(mmc-class_dev, card is present\n); @@ -1053,6 +1055,7 @@ static int dw_mci_get_cd(struct mmc_host *mmc) clear_bit(DW_MMC_CARD_PRESENT, slot-flags); dev_dbg(mmc-class_dev, card is not present\n); } + spin_unlock_bh(host-lock); return present; } @@ -2081,7 +2084,7 @@ static int dw_mci_of_get_wp_gpio(struct device *dev, u8 slot) return gpio; } -/* find the cd gpio for a given slot; or -1 if none specified */ +/* find the cd gpio for a given slot */ static void dw_mci_of_get_cd_gpio(struct device *dev, u8 slot, struct mmc_host *mmc) { -- 1.7.9.5 -- To unsubscribe from this list: send the line unsubscribe linux-mmc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH] mmc: dw_mmc: fix dw_mci_get_cd
Introduced from commit bf626e5550f24aec24975a0e85ad8e572ca76a6b CDETECT is ignored since negated return value of mmc_gpio_get_cd(mmc) can not be checked by IS_ERR_VALUE. Add spin_lock_bh(host-lock) for atomic accessing DW_MMC_CARD_PRESENT, otherwise sd detect may occasionally fail. Signed-off-by: Zhangfei Gao zhangfei@linaro.org Reported-by: Kevin Hilman khil...@linaro.org Reviewed-by: Sachin Kamat sachin.ka...@linaro.org Tested-by: Sachin Kamat sachin.ka...@linaro.org --- drivers/mmc/host/dw_mmc.c | 12 +--- include/linux/mmc/dw_mmc.h |1 + 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/drivers/mmc/host/dw_mmc.c b/drivers/mmc/host/dw_mmc.c index a776f24f4311..8326e54b96a8 100644 --- a/drivers/mmc/host/dw_mmc.c +++ b/drivers/mmc/host/dw_mmc.c @@ -1033,7 +1033,8 @@ static int dw_mci_get_cd(struct mmc_host *mmc) int present; struct dw_mci_slot *slot = mmc_priv(mmc); struct dw_mci_board *brd = slot-host-pdata; - int gpio_cd = !mmc_gpio_get_cd(mmc); + struct dw_mci *host = slot-host; + int gpio_cd = mmc_gpio_get_cd(mmc); /* Use platform get_cd function, else try onboard card detect */ if (brd-quirks DW_MCI_QUIRK_BROKEN_CARD_DETECTION) @@ -1041,11 +1042,12 @@ static int dw_mci_get_cd(struct mmc_host *mmc) else if (brd-get_cd) present = !brd-get_cd(slot-id); else if (!IS_ERR_VALUE(gpio_cd)) - present = !!gpio_cd; + present = gpio_cd ^ brd-cd_inverted; else present = (mci_readl(slot-host, CDETECT) (1 slot-id)) == 0 ? 1 : 0; + spin_lock_bh(host-lock); if (present) { set_bit(DW_MMC_CARD_PRESENT, slot-flags); dev_dbg(mmc-class_dev, card is present\n); @@ -1053,6 +1055,7 @@ static int dw_mci_get_cd(struct mmc_host *mmc) clear_bit(DW_MMC_CARD_PRESENT, slot-flags); dev_dbg(mmc-class_dev, card is not present\n); } + spin_unlock_bh(host-lock); return present; } @@ -2081,7 +2084,7 @@ static int dw_mci_of_get_wp_gpio(struct device *dev, u8 slot) return gpio; } -/* find the cd gpio for a given slot; or -1 if none specified */ +/* find the cd gpio for a given slot */ static void dw_mci_of_get_cd_gpio(struct device *dev, u8 slot, struct mmc_host *mmc) { @@ -2411,6 +2414,9 @@ static struct dw_mci_board *dw_mci_parse_dt(struct dw_mci *host) if (of_find_property(np, caps2-mmc-hs200-1_2v, NULL)) pdata-caps2 |= MMC_CAP2_HS200_1_2V_SDR; + if (of_get_property(np, cd-inverted, NULL)) + pdata-cd_inverted = 1; + return pdata; } diff --git a/include/linux/mmc/dw_mmc.h b/include/linux/mmc/dw_mmc.h index 6ce7d2cd3c7a..4535282589ab 100644 --- a/include/linux/mmc/dw_mmc.h +++ b/include/linux/mmc/dw_mmc.h @@ -238,6 +238,7 @@ struct dw_mci_board { u32 caps; /* Capabilities */ u32 caps2; /* More capabilities */ u32 pm_caps;/* PM capabilities */ + u8 cd_inverted; /* * Override fifo depth. If 0, autodetect it from the FIFOTH register, * but note that this may not be reliable after a bootloader has used -- 1.7.9.5 -- To unsubscribe from this list: send the line unsubscribe linux-mmc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 1/2] clk: hisilicon: add hi3620_mmc_clks
+static long mmc_clk_determine_rate(struct clk_hw *hw, unsigned long rate, + unsigned long *best_parent_rate, + struct clk **best_parent_p) +{ + struct clk_mmc *mclk = to_mmc(hw); + unsigned long best = 0; + + if ((rate = 1300) (mclk-id == HI3620_MMC_CIUCLK1)) { No need to check HI3620_MMC_CIUCLK2 and HI3620_MMC_CIUCLK3? Yes, only emmc, id=HI3620_MMC_CIUCLK1, using init clk 13M, while others use init clock 25M. Add this to handle init mmc init clk 400K and return source clock rate 13M, from your suggestion in fact. + rate = 1300; + best = 2600; + } else if (rate = 2600) { + rate = 2500; + best = 18000; + } else if (rate = 5200) { + rate = 5000; + best = 36000; + } else if (rate = 1) { + rate = 1; + best = 72000; + } else { + /* max is 180M */ + rate = 18000; + best = 144000; + } + *best_parent_rate = best; + return rate; +} +static int mmc_clk_prepare(struct clk_hw *hw) +{ + struct clk_mmc *mclk = to_mmc(hw); + unsigned long rate; + + if (mclk-id == HI3620_MMC_CIUCLK1) HI3620_SD_CIUCLK was used in previous version. Yes, fixed, though it can work on the dev board. Is it fixed with HI3620_MMC_CIUCLK1? And, please clarify in case of HI3620_MMC_CIUCLK2 and HI3620_MMC_CIUCLK3 as well. Only HI3620_MMC_CIUCLK1 use 13M for init, all others use 25M on hi3620. Thanks, Seungwon Jeon + rate = 1300; + else + rate = 2500; + + return mmc_clk_set_timing(hw, rate); +} + Thanks -- To unsubscribe from this list: send the line unsubscribe linux-mmc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH] mmc: dw_mmc: fix dw_mci_get_cd
Introdeced from commit b7db86adfa58b CDETECT is ingored since IS_ERR_VALUE(!mmc_gpio_get_cd(mmc)) does not work Add spin_lock_bh(host-lock) for atomic accessing DW_MMC_CARD_PRESENT Signed-off-by: Zhangfei Gao zhangfei@linaro.org Reported-by: Kevin Hilman khil...@linaro.org --- drivers/mmc/host/dw_mmc.c |9 ++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/drivers/mmc/host/dw_mmc.c b/drivers/mmc/host/dw_mmc.c index a776f24f4311..9ded62c8225e 100644 --- a/drivers/mmc/host/dw_mmc.c +++ b/drivers/mmc/host/dw_mmc.c @@ -1033,7 +1033,8 @@ static int dw_mci_get_cd(struct mmc_host *mmc) int present; struct dw_mci_slot *slot = mmc_priv(mmc); struct dw_mci_board *brd = slot-host-pdata; - int gpio_cd = !mmc_gpio_get_cd(mmc); + struct dw_mci *host = slot-host; + int gpio_cd = mmc_gpio_get_cd(mmc); /* Use platform get_cd function, else try onboard card detect */ if (brd-quirks DW_MCI_QUIRK_BROKEN_CARD_DETECTION) @@ -1041,11 +1042,12 @@ static int dw_mci_get_cd(struct mmc_host *mmc) else if (brd-get_cd) present = !brd-get_cd(slot-id); else if (!IS_ERR_VALUE(gpio_cd)) - present = !!gpio_cd; + present = !gpio_cd; else present = (mci_readl(slot-host, CDETECT) (1 slot-id)) == 0 ? 1 : 0; + spin_lock_bh(host-lock); if (present) { set_bit(DW_MMC_CARD_PRESENT, slot-flags); dev_dbg(mmc-class_dev, card is present\n); @@ -1053,6 +1055,7 @@ static int dw_mci_get_cd(struct mmc_host *mmc) clear_bit(DW_MMC_CARD_PRESENT, slot-flags); dev_dbg(mmc-class_dev, card is not present\n); } + spin_unlock_bh(host-lock); return present; } @@ -2081,7 +2084,7 @@ static int dw_mci_of_get_wp_gpio(struct device *dev, u8 slot) return gpio; } -/* find the cd gpio for a given slot; or -1 if none specified */ +/* find the cd gpio for a given slot */ static void dw_mci_of_get_cd_gpio(struct device *dev, u8 slot, struct mmc_host *mmc) { -- 1.7.9.5 -- To unsubscribe from this list: send the line unsubscribe linux-mmc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 1/2] clk: hisilicon: add hi3620_mmc_clks
Suggest by Arnd: abstract mmc tuning as clock behavior, also because different soc have different tuning method and registers. hi3620_mmc_clks is added to handle mmc clock specifically on hi3620. Signed-off-by: Zhangfei Gao zhangfei@linaro.org Acked-by: Arnd Bergmann a...@arndb.de Acked-by: Jaehoon Chung jh80.ch...@samsung.com --- .../bindings/arm/hisilicon/hisilicon.txt | 14 + .../devicetree/bindings/clock/hi3620-clock.txt |1 + drivers/clk/hisilicon/clk-hi3620.c | 267 include/dt-bindings/clock/hi3620-clock.h |5 + 4 files changed, 287 insertions(+) diff --git a/Documentation/devicetree/bindings/arm/hisilicon/hisilicon.txt b/Documentation/devicetree/bindings/arm/hisilicon/hisilicon.txt index 8c7a4653508d..df0a452b8526 100644 --- a/Documentation/devicetree/bindings/arm/hisilicon/hisilicon.txt +++ b/Documentation/devicetree/bindings/arm/hisilicon/hisilicon.txt @@ -30,3 +30,17 @@ Example: resume-offset = 0x308; reboot-offset = 0x4; }; + +PCTRL: Peripheral misc control register + +Required Properties: +- compatible: hisilicon,pctrl +- reg: Address and size of pctrl. + +Example: + + /* for Hi3620 */ + pctrl: pctrl@fca09000 { + compatible = hisilicon,pctrl; + reg = 0xfca09000 0x1000; + }; diff --git a/Documentation/devicetree/bindings/clock/hi3620-clock.txt b/Documentation/devicetree/bindings/clock/hi3620-clock.txt index 4b71ab41be53..dad6269f52c5 100644 --- a/Documentation/devicetree/bindings/clock/hi3620-clock.txt +++ b/Documentation/devicetree/bindings/clock/hi3620-clock.txt @@ -7,6 +7,7 @@ Required Properties: - compatible: should be one of the following. - hisilicon,hi3620-clock - controller compatible with Hi3620 SoC. + - hisilicon,hi3620-mmc-clock - controller specific for Hi3620 mmc. - reg: physical base address of the controller and length of memory mapped region. diff --git a/drivers/clk/hisilicon/clk-hi3620.c b/drivers/clk/hisilicon/clk-hi3620.c index f24ad6a3a797..54cc3475ec36 100644 --- a/drivers/clk/hisilicon/clk-hi3620.c +++ b/drivers/clk/hisilicon/clk-hi3620.c @@ -240,3 +240,270 @@ static void __init hi3620_clk_init(struct device_node *np) base); } CLK_OF_DECLARE(hi3620_clk, hisilicon,hi3620-clock, hi3620_clk_init); + +struct hisi_mmc_clock { + unsigned intid; + const char *name; + const char *parent_name; + unsigned long flags; + u32 clken_reg; + u32 clken_bit; + u32 div_reg; + u32 div_off; + u32 div_bits; + u32 drv_reg; + u32 drv_off; + u32 drv_bits; + u32 sam_reg; + u32 sam_off; + u32 sam_bits; +}; + +struct clk_mmc { + struct clk_hw hw; + u32 id; + void __iomem*clken_reg; + u32 clken_bit; + void __iomem*div_reg; + u32 div_off; + u32 div_bits; + void __iomem*drv_reg; + u32 drv_off; + u32 drv_bits; + void __iomem*sam_reg; + u32 sam_off; + u32 sam_bits; +}; + +#define to_mmc(_hw) container_of(_hw, struct clk_mmc, hw) + +static struct hisi_mmc_clock hi3620_mmc_clks[] __initdata = { + { HI3620_SD_CIUCLK, sd_bclk1, sd_clk, CLK_SET_RATE_PARENT, 0x1f8, 0, 0x1f8, 1, 3, 0x1f8, 4, 4, 0x1f8, 8, 4}, + { HI3620_MMC_CIUCLK1, mmc_bclk1, mmc_clk1, CLK_SET_RATE_PARENT, 0x1f8, 12, 0x1f8, 13, 3, 0x1f8, 16, 4, 0x1f8, 20, 4}, + { HI3620_MMC_CIUCLK2, mmc_bclk2, mmc_clk2, CLK_SET_RATE_PARENT, 0x1f8, 24, 0x1f8, 25, 3, 0x1f8, 28, 4, 0x1fc, 0, 4}, + { HI3620_MMC_CIUCLK3, mmc_bclk3, mmc_clk3, CLK_SET_RATE_PARENT, 0x1fc, 4, 0x1fc, 5, 3, 0x1fc, 8, 4, 0x1fc, 12, 4}, +}; + +static unsigned long mmc_clk_recalc_rate(struct clk_hw *hw, + unsigned long parent_rate) +{ + switch (parent_rate) { + case 2600: + return 1300; + case 18000: + return 2500; + case 36000: + return 5000; + case 72000: + return 1; + default: + return parent_rate; + } +} + +static long mmc_clk_determine_rate(struct clk_hw *hw, unsigned long rate, + unsigned long *best_parent_rate, + struct clk **best_parent_p) +{ + struct clk_mmc *mclk = to_mmc(hw); + unsigned long best = 0; + + if ((rate = 1300) (mclk-id == HI3620_MMC_CIUCLK1)) { + rate = 1300; + best = 2600; + } else if (rate
[PATCH 2/2] mmc: dw_mmc: k3: remove clk_table
Remove clk_table and directly use ios-clock as clock source rate. Abstract init clock rate and max clock limitation in clk.c Signed-off-by: Zhangfei Gao zhangfei@linaro.org --- .../devicetree/bindings/mmc/k3-dw-mshc.txt | 14 --- drivers/mmc/host/dw_mmc-k3.c | 41 +--- 2 files changed, 2 insertions(+), 53 deletions(-) diff --git a/Documentation/devicetree/bindings/mmc/k3-dw-mshc.txt b/Documentation/devicetree/bindings/mmc/k3-dw-mshc.txt index d7e2d7f159bb..b8653ea97957 100644 --- a/Documentation/devicetree/bindings/mmc/k3-dw-mshc.txt +++ b/Documentation/devicetree/bindings/mmc/k3-dw-mshc.txt @@ -14,18 +14,6 @@ Required Properties: * compatible: should be one of the following. - hisilicon,hi4511-dw-mshc: for controllers with hi4511 specific extentions. -* clock-freq-table: should be the frequency (in Hz) array of the ciu clock - in each supported mode. - 0. CIU clock rate in Hz for DS mode - 1. CIU clock rate in Hz for MMC HS mode - 2. CIU clock rate in Hz for SD HS mode - 3. CIU clock rate in Hz for SDR12 mode - 4. CIU clock rate in Hz for SDR25 mode - 5. CIU clock rate in Hz for SDR50 mode - 6. CIU clock rate in Hz for SDR104 mode - 7. CIU clock rate in Hz for DDR50 mode - 8. CIU clock rate in Hz for HS200 mode - Example: /* for Hi3620 */ @@ -39,8 +27,6 @@ Example: #size-cells = 0; clocks = mmc_clock HI3620_SD_CIUCLK, clock HI3620_DDRC_PER_CLK; clock-names = ciu, biu; - clock-freq-table = - 2500 0 5000 2500 5000 1 0 5000; }; /* Board portion */ diff --git a/drivers/mmc/host/dw_mmc-k3.c b/drivers/mmc/host/dw_mmc-k3.c index 68e5e428e8f6..84e1a670f8c7 100644 --- a/drivers/mmc/host/dw_mmc-k3.c +++ b/drivers/mmc/host/dw_mmc-k3.c @@ -18,56 +18,19 @@ #include dw_mmc.h #include dw_mmc-pltfm.h -#define MAX_NUMS 10 -struct dw_mci_k3_priv_data { - u32 clk_table[MAX_NUMS]; -}; - static void dw_mci_k3_set_ios(struct dw_mci *host, struct mmc_ios *ios) { - struct dw_mci_k3_priv_data *priv = host-priv; - u32 rate = priv-clk_table[ios-timing]; int ret; - if (!rate) { - dev_warn(host-dev, - no specified rate in timing %u\n, ios-timing); - return; - } - - ret = clk_set_rate(host-ciu_clk, rate); + ret = clk_set_rate(host-ciu_clk, ios-clock); if (ret) - dev_warn(host-dev, failed to set clock rate %uHz\n, rate); + dev_warn(host-dev, failed to set rate %uHz\n, ios-clock); host-bus_hz = clk_get_rate(host-ciu_clk); } -static int dw_mci_k3_parse_dt(struct dw_mci *host) -{ - struct dw_mci_k3_priv_data *priv; - struct device_node *node = host-dev-of_node; - struct property *prop; - const __be32 *cur; - u32 val, num = 0; - - priv = devm_kzalloc(host-dev, sizeof(*priv), GFP_KERNEL); - if (!priv) { - dev_err(host-dev, mem alloc failed for private data\n); - return -ENOMEM; - } - host-priv = priv; - - of_property_for_each_u32(node, clock-freq-table, prop, cur, val) { - if (num = MAX_NUMS) - break; - priv-clk_table[num++] = val; - } - return 0; -} - static const struct dw_mci_drv_data k3_drv_data = { .set_ios= dw_mci_k3_set_ios, - .parse_dt = dw_mci_k3_parse_dt, }; static const struct of_device_id dw_mci_k3_match[] = { -- 1.7.9.5 -- To unsubscribe from this list: send the line unsubscribe linux-mmc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 0/2] mmc: dw_mmc: k3 remove clk_table
clk_table is used to set clock source in each mode, as well as limitation, max_rate and init rate. It concerned many experts though, and Seungwon recommended some limitation can be hide in clk.c. Also soc is updated as the limitation now same as max_rate, so directly using ios-clock. Zhangfei Gao (2): clk: hisilicon: add hi3620_mmc_clks mmc: dw_mmc: k3: remove clk_table .../bindings/arm/hisilicon/hisilicon.txt | 14 + .../devicetree/bindings/clock/hi3620-clock.txt |1 + .../devicetree/bindings/mmc/k3-dw-mshc.txt | 14 - drivers/clk/hisilicon/clk-hi3620.c | 267 drivers/mmc/host/dw_mmc-k3.c | 41 +-- include/dt-bindings/clock/hi3620-clock.h |5 + 6 files changed, 289 insertions(+), 53 deletions(-) -- 1.7.9.5 -- To unsubscribe from this list: send the line unsubscribe linux-mmc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH] clk: hisilicon: add hi3620_mmc_clks
Suggest by Arnd: abstract mmc tuning as clock behavior, also because different soc have different tuning method and registers. hi3620_mmc_clks is added to handle mmc clock specifically on hi3620. Signed-off-by: Zhangfei Gao zhangfei@linaro.org Acked-by: Arnd Bergmann a...@arndb.de Acked-by: Jaehoon Chung jh80.ch...@samsung.com --- .../bindings/arm/hisilicon/hisilicon.txt | 14 + .../devicetree/bindings/clock/hi3620-clock.txt |1 + drivers/clk/hisilicon/clk-hi3620.c | 274 include/dt-bindings/clock/hi3620-clock.h |5 + 4 files changed, 294 insertions(+) diff --git a/Documentation/devicetree/bindings/arm/hisilicon/hisilicon.txt b/Documentation/devicetree/bindings/arm/hisilicon/hisilicon.txt index 8c7a4653508d..df0a452b8526 100644 --- a/Documentation/devicetree/bindings/arm/hisilicon/hisilicon.txt +++ b/Documentation/devicetree/bindings/arm/hisilicon/hisilicon.txt @@ -30,3 +30,17 @@ Example: resume-offset = 0x308; reboot-offset = 0x4; }; + +PCTRL: Peripheral misc control register + +Required Properties: +- compatible: hisilicon,pctrl +- reg: Address and size of pctrl. + +Example: + + /* for Hi3620 */ + pctrl: pctrl@fca09000 { + compatible = hisilicon,pctrl; + reg = 0xfca09000 0x1000; + }; diff --git a/Documentation/devicetree/bindings/clock/hi3620-clock.txt b/Documentation/devicetree/bindings/clock/hi3620-clock.txt index 4b71ab41be53..dad6269f52c5 100644 --- a/Documentation/devicetree/bindings/clock/hi3620-clock.txt +++ b/Documentation/devicetree/bindings/clock/hi3620-clock.txt @@ -7,6 +7,7 @@ Required Properties: - compatible: should be one of the following. - hisilicon,hi3620-clock - controller compatible with Hi3620 SoC. + - hisilicon,hi3620-mmc-clock - controller specific for Hi3620 mmc. - reg: physical base address of the controller and length of memory mapped region. diff --git a/drivers/clk/hisilicon/clk-hi3620.c b/drivers/clk/hisilicon/clk-hi3620.c index f24ad6a3a797..38faa469d288 100644 --- a/drivers/clk/hisilicon/clk-hi3620.c +++ b/drivers/clk/hisilicon/clk-hi3620.c @@ -240,3 +240,277 @@ static void __init hi3620_clk_init(struct device_node *np) base); } CLK_OF_DECLARE(hi3620_clk, hisilicon,hi3620-clock, hi3620_clk_init); + +struct hisi_mmc_clock { + unsigned intid; + const char *name; + const char *parent_name; + unsigned long flags; + u32 clken_reg; + u32 clken_bit; + u32 div_reg; + u32 div_off; + u32 div_bits; + u32 drv_reg; + u32 drv_off; + u32 drv_bits; + u32 sam_reg; + u32 sam_off; + u32 sam_bits; +}; + +struct clk_mmc { + struct clk_hw hw; + u32 id; + void __iomem*clken_reg; + u32 clken_bit; + void __iomem*div_reg; + u32 div_off; + u32 div_bits; + void __iomem*drv_reg; + u32 drv_off; + u32 drv_bits; + void __iomem*sam_reg; + u32 sam_off; + u32 sam_bits; +}; + +#define to_mmc(_hw) container_of(_hw, struct clk_mmc, hw) + +static struct hisi_mmc_clock hi3620_mmc_clks[] __initdata = { + { HI3620_SD_CIUCLK, sd_bclk1, sd_clk, CLK_SET_RATE_PARENT, 0x1f8, 0, 0x1f8, 1, 3, 0x1f8, 4, 4, 0x1f8, 8, 4}, + { HI3620_MMC_CIUCLK1, mmc_bclk1, mmc_clk1, CLK_SET_RATE_PARENT, 0x1f8, 12, 0x1f8, 13, 3, 0x1f8, 16, 4, 0x1f8, 20, 4}, + { HI3620_MMC_CIUCLK2, mmc_bclk2, mmc_clk2, CLK_SET_RATE_PARENT, 0x1f8, 24, 0x1f8, 25, 3, 0x1f8, 28, 4, 0x1fc, 0, 4}, + { HI3620_MMC_CIUCLK3, mmc_bclk3, mmc_clk3, CLK_SET_RATE_PARENT, 0x1fc, 4, 0x1fc, 5, 3, 0x1fc, 8, 4, 0x1fc, 12, 4}, +}; + +static unsigned long mmc_clk_recalc_rate(struct clk_hw *hw, + unsigned long parent_rate) +{ + switch (parent_rate) { + case 2600: + return 1300; + case 18000: + return 2500; + case 36000: + return 5000; + case 72000: + return 1; + case 144000: + return 18000; + default: + return parent_rate; + } +} + +static long mmc_clk_determine_rate(struct clk_hw *hw, unsigned long rate, + unsigned long *best_parent_rate, + struct clk **best_parent_p) +{ + struct clk_mmc *mclk = to_mmc(hw); + unsigned long best = 0; + + if ((rate = 1300) (mclk-id == HI3620_MMC_CIUCLK1)) { + rate = 1300
Re: [PATCH v7 0/3] mmc: dw_mmc: add dw_mmc-k3
On Mon, Jan 13, 2014 at 12:35 AM, Chris Ball ch...@printf.net wrote: Hi, I've pushed patches 1 and 2 to mmc-next for 3.14, with Arnd and Jaehoon's ACK -- since patch 3 depends on files that aren't in my tree, please can you push that one through arm-soc? Great, thanks Chris. The 3rd patch may need go to Mike's tree, will search Mike's help. Thanks. -- To unsubscribe from this list: send the line unsubscribe linux-mmc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v7 0/3] mmc: dw_mmc: add dw_mmc-k3
v7: 0002: use undefined local value in suspend/resume v6: 0002: Jaehoon pointed HIGHSPEED cap can be omitted if supports-highspeed is defined. Seungwon mentioned clk operation should be called after suspend. Remove k3_dwmmc_caps V5: 0002: Follow advice from Arnd, Update dt descirption and use of_property_for_each_u32 to get table number. v4: Follow Arnd's suggestion abstracting specific tuning to clock, also because new version ip use different method and not use same tuning registers. 0001 acked by Jaehoon v3: 0001: Put set/clear_bit DW_MMC_CARD_PRESENT in dw_mci_get_cd, Since dw_mci_request will check DW_MMC_CARD_PRESENT before sending cmd 0002: Follow suggestion from Chris, Kumar and Seungwon Sync to latest mmc-next, which is 3.12-rc2 Remove enum dw_mci_k3_type etc v2: Follow Jaehoon's suggestion Use slot-gpio.c handle cd pin Move table out to dts other suggestion Zhangfei Gao (3): mmc: dw_mmc: use slot-gpio to handle cd pin mmc: dw_mmc: add dw_mmc-k3 for k3 platform clk: hisilicon: add hi3620_mmc_clks .../bindings/arm/hisilicon/hisilicon.txt | 14 ++ .../devicetree/bindings/clock/hi3620-clock.txt |1 + .../devicetree/bindings/mmc/k3-dw-mshc.txt | 60 + drivers/clk/hisilicon/clk-hi3620.c | 262 drivers/mmc/host/Kconfig | 10 + drivers/mmc/host/Makefile |1 + drivers/mmc/host/dw_mmc-k3.c | 126 ++ drivers/mmc/host/dw_mmc.c | 48 +++- include/dt-bindings/clock/hi3620-clock.h |5 + 9 files changed, 514 insertions(+), 13 deletions(-) create mode 100644 Documentation/devicetree/bindings/mmc/k3-dw-mshc.txt create mode 100644 drivers/mmc/host/dw_mmc-k3.c -- 1.7.9.5 -- To unsubscribe from this list: send the line unsubscribe linux-mmc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 2/3] mmc: dw_mmc: add dw_mmc-k3 for k3 platform
Add dw_mmc-k3.c for k3v2, support sd/emmc Signed-off-by: Zhangfei Gao zhangfei@linaro.org Signed-off-by: Zhigang Wang brooke.wangzhig...@huawei.com --- .../devicetree/bindings/mmc/k3-dw-mshc.txt | 60 + drivers/mmc/host/Kconfig | 10 ++ drivers/mmc/host/Makefile |1 + drivers/mmc/host/dw_mmc-k3.c | 132 4 files changed, 203 insertions(+) create mode 100644 Documentation/devicetree/bindings/mmc/k3-dw-mshc.txt create mode 100644 drivers/mmc/host/dw_mmc-k3.c diff --git a/Documentation/devicetree/bindings/mmc/k3-dw-mshc.txt b/Documentation/devicetree/bindings/mmc/k3-dw-mshc.txt new file mode 100644 index ..d7e2d7f159bb --- /dev/null +++ b/Documentation/devicetree/bindings/mmc/k3-dw-mshc.txt @@ -0,0 +1,60 @@ +* Hisilicon specific extensions to the Synopsys Designware Mobile + Storage Host Controller + +Read synopsys-dw-mshc.txt for more details + +The Synopsys designware mobile storage host controller is used to interface +a SoC with storage medium such as eMMC or SD/MMC cards. This file documents +differences between the core Synopsys dw mshc controller properties described +by synopsys-dw-mshc.txt and the properties used by the Hisilicon specific +extensions to the Synopsys Designware Mobile Storage Host Controller. + +Required Properties: + +* compatible: should be one of the following. + - hisilicon,hi4511-dw-mshc: for controllers with hi4511 specific extentions. + +* clock-freq-table: should be the frequency (in Hz) array of the ciu clock + in each supported mode. + 0. CIU clock rate in Hz for DS mode + 1. CIU clock rate in Hz for MMC HS mode + 2. CIU clock rate in Hz for SD HS mode + 3. CIU clock rate in Hz for SDR12 mode + 4. CIU clock rate in Hz for SDR25 mode + 5. CIU clock rate in Hz for SDR50 mode + 6. CIU clock rate in Hz for SDR104 mode + 7. CIU clock rate in Hz for DDR50 mode + 8. CIU clock rate in Hz for HS200 mode + +Example: + + /* for Hi3620 */ + + /* SoC portion */ + dwmmc_0: dwmmc0@fcd03000 { + compatible = hisilicon,hi4511-dw-mshc; + reg = 0xfcd03000 0x1000; + interrupts = 0 16 4; + #address-cells = 1; + #size-cells = 0; + clocks = mmc_clock HI3620_SD_CIUCLK, clock HI3620_DDRC_PER_CLK; + clock-names = ciu, biu; + clock-freq-table = + 2500 0 5000 2500 5000 1 0 5000; + }; + + /* Board portion */ + dwmmc0@fcd03000 { + num-slots = 1; + vmmc-supply = ldo12; + fifo-depth = 0x100; + supports-highspeed; + pinctrl-names = default; + pinctrl-0 = sd_pmx_pins sd_cfg_func1 sd_cfg_func2; + slot@0 { + reg = 0; + bus-width = 4; + disable-wp; + cd-gpios = gpio10 3 0; + }; + }; diff --git a/drivers/mmc/host/Kconfig b/drivers/mmc/host/Kconfig index 7fc5099e44b2..45aaa2de0f58 100644 --- a/drivers/mmc/host/Kconfig +++ b/drivers/mmc/host/Kconfig @@ -575,6 +575,16 @@ config MMC_DW_SOCFPGA This selects support for Altera SoCFPGA specific extensions to the Synopsys DesignWare Memory Card Interface driver. +config MMC_DW_K3 + tristate K3 specific extensions for Synopsys DW Memory Card Interface + depends on MMC_DW + select MMC_DW_PLTFM + select MMC_DW_IDMAC + help + This selects support for Hisilicon K3 SoC specific extensions to the + Synopsys DesignWare Memory Card Interface driver. Select this option + for platforms based on Hisilicon K3 SoC's. + config MMC_DW_PCI tristate Synopsys Designware MCI support on PCI bus depends on MMC_DW PCI diff --git a/drivers/mmc/host/Makefile b/drivers/mmc/host/Makefile index c41d0c364509..64f5f8d35839 100644 --- a/drivers/mmc/host/Makefile +++ b/drivers/mmc/host/Makefile @@ -43,6 +43,7 @@ obj-$(CONFIG_MMC_DW) += dw_mmc.o obj-$(CONFIG_MMC_DW_PLTFM) += dw_mmc-pltfm.o obj-$(CONFIG_MMC_DW_EXYNOS)+= dw_mmc-exynos.o obj-$(CONFIG_MMC_DW_SOCFPGA) += dw_mmc-socfpga.o +obj-$(CONFIG_MMC_DW_K3)+= dw_mmc-k3.o obj-$(CONFIG_MMC_DW_PCI) += dw_mmc-pci.o obj-$(CONFIG_MMC_SH_MMCIF) += sh_mmcif.o obj-$(CONFIG_MMC_JZ4740) += jz4740_mmc.o diff --git a/drivers/mmc/host/dw_mmc-k3.c b/drivers/mmc/host/dw_mmc-k3.c new file mode 100644 index ..68e5e428e8f6 --- /dev/null +++ b/drivers/mmc/host/dw_mmc-k3.c @@ -0,0 +1,132 @@ +/* + * Copyright (c) 2013 Linaro Ltd. + * Copyright (c) 2013 Hisilicon Limited. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published
[PATCH 3/3] clk: hisilicon: add hi3620_mmc_clks
Suggest by Arnd: abstract mmc tuning as clock behavior, also because different soc have different tuning method and registers. hi3620_mmc_clks is added to handle mmc clock specifically on hi3620. Signed-off-by: Zhangfei Gao zhangfei@linaro.org --- .../bindings/arm/hisilicon/hisilicon.txt | 14 ++ .../devicetree/bindings/clock/hi3620-clock.txt |1 + drivers/clk/hisilicon/clk-hi3620.c | 262 include/dt-bindings/clock/hi3620-clock.h |5 + 4 files changed, 282 insertions(+) diff --git a/Documentation/devicetree/bindings/arm/hisilicon/hisilicon.txt b/Documentation/devicetree/bindings/arm/hisilicon/hisilicon.txt index 8c7a4653508d..df0a452b8526 100644 --- a/Documentation/devicetree/bindings/arm/hisilicon/hisilicon.txt +++ b/Documentation/devicetree/bindings/arm/hisilicon/hisilicon.txt @@ -30,3 +30,17 @@ Example: resume-offset = 0x308; reboot-offset = 0x4; }; + +PCTRL: Peripheral misc control register + +Required Properties: +- compatible: hisilicon,pctrl +- reg: Address and size of pctrl. + +Example: + + /* for Hi3620 */ + pctrl: pctrl@fca09000 { + compatible = hisilicon,pctrl; + reg = 0xfca09000 0x1000; + }; diff --git a/Documentation/devicetree/bindings/clock/hi3620-clock.txt b/Documentation/devicetree/bindings/clock/hi3620-clock.txt index 4b71ab41be53..dad6269f52c5 100644 --- a/Documentation/devicetree/bindings/clock/hi3620-clock.txt +++ b/Documentation/devicetree/bindings/clock/hi3620-clock.txt @@ -7,6 +7,7 @@ Required Properties: - compatible: should be one of the following. - hisilicon,hi3620-clock - controller compatible with Hi3620 SoC. + - hisilicon,hi3620-mmc-clock - controller specific for Hi3620 mmc. - reg: physical base address of the controller and length of memory mapped region. diff --git a/drivers/clk/hisilicon/clk-hi3620.c b/drivers/clk/hisilicon/clk-hi3620.c index f24ad6a3a797..e47a4a659df7 100644 --- a/drivers/clk/hisilicon/clk-hi3620.c +++ b/drivers/clk/hisilicon/clk-hi3620.c @@ -240,3 +240,265 @@ static void __init hi3620_clk_init(struct device_node *np) base); } CLK_OF_DECLARE(hi3620_clk, hisilicon,hi3620-clock, hi3620_clk_init); + +struct hisi_mmc_clock { + unsigned intid; + const char *name; + const char *parent_name; + unsigned long flags; + u32 clken_reg; + u32 clken_bit; + u32 div_reg; + u32 div_off; + u32 div_bits; + u32 drv_reg; + u32 drv_off; + u32 drv_bits; + u32 sam_reg; + u32 sam_off; + u32 sam_bits; +}; + +struct clk_mmc { + struct clk_hw hw; + u32 id; + void __iomem*clken_reg; + u32 clken_bit; + void __iomem*div_reg; + u32 div_off; + u32 div_bits; + void __iomem*drv_reg; + u32 drv_off; + u32 drv_bits; + void __iomem*sam_reg; + u32 sam_off; + u32 sam_bits; +}; + +#define to_mmc(_hw) container_of(_hw, struct clk_mmc, hw) + +static struct hisi_mmc_clock hi3620_mmc_clks[] __initdata = { + { HI3620_SD_CIUCLK, sd_bclk1, sd_clk, CLK_SET_RATE_PARENT, 0x1f8, 0, 0x1f8, 1, 3, 0x1f8, 4, 4, 0x1f8, 8, 4}, + { HI3620_MMC_CIUCLK1, mmc_bclk1, mmc_clk1, CLK_SET_RATE_PARENT, 0x1f8, 12, 0x1f8, 13, 3, 0x1f8, 16, 4, 0x1f8, 20, 4}, + { HI3620_MMC_CIUCLK2, mmc_bclk2, mmc_clk2, CLK_SET_RATE_PARENT, 0x1f8, 24, 0x1f8, 25, 3, 0x1f8, 28, 4, 0x1fc, 0, 4}, + { HI3620_MMC_CIUCLK3, mmc_bclk3, mmc_clk3, CLK_SET_RATE_PARENT, 0x1fc, 4, 0x1fc, 5, 3, 0x1fc, 8, 4, 0x1fc, 12, 4}, +}; + +static unsigned long mmc_clk_recalc_rate(struct clk_hw *hw, + unsigned long parent_rate) +{ + switch (parent_rate) { + case 2600: + return 1300; + case 18000: + return 2500; + case 36000: + return 5000; + case 72000: + return 1; + default: + return parent_rate; + } +} + +static long mmc_clk_determine_rate(struct clk_hw *hw, unsigned long rate, + unsigned long *best_parent_rate, + struct clk **best_parent_p) +{ + unsigned long best = 0; + + if (rate = 1300) { + rate = 1300; + best = 2600; + } else if (rate = 2600) { + rate = 2500; + best = 18000; + } else if (rate = 5200) { + rate = 5000
[PATCH 2/3] mmc: dw_mmc: add dw_mmc-k3 for k3 platform
Add dw_mmc-k3.c for k3v2, support sd/emmc Signed-off-by: Zhangfei Gao zhangfei@linaro.org Signed-off-by: Zhigang Wang brooke.wangzhig...@huawei.com --- .../devicetree/bindings/mmc/k3-dw-mshc.txt | 60 + drivers/mmc/host/Kconfig | 10 ++ drivers/mmc/host/Makefile |1 + drivers/mmc/host/dw_mmc-k3.c | 132 4 files changed, 203 insertions(+) create mode 100644 Documentation/devicetree/bindings/mmc/k3-dw-mshc.txt create mode 100644 drivers/mmc/host/dw_mmc-k3.c diff --git a/Documentation/devicetree/bindings/mmc/k3-dw-mshc.txt b/Documentation/devicetree/bindings/mmc/k3-dw-mshc.txt new file mode 100644 index ..d7e2d7f159bb --- /dev/null +++ b/Documentation/devicetree/bindings/mmc/k3-dw-mshc.txt @@ -0,0 +1,60 @@ +* Hisilicon specific extensions to the Synopsys Designware Mobile + Storage Host Controller + +Read synopsys-dw-mshc.txt for more details + +The Synopsys designware mobile storage host controller is used to interface +a SoC with storage medium such as eMMC or SD/MMC cards. This file documents +differences between the core Synopsys dw mshc controller properties described +by synopsys-dw-mshc.txt and the properties used by the Hisilicon specific +extensions to the Synopsys Designware Mobile Storage Host Controller. + +Required Properties: + +* compatible: should be one of the following. + - hisilicon,hi4511-dw-mshc: for controllers with hi4511 specific extentions. + +* clock-freq-table: should be the frequency (in Hz) array of the ciu clock + in each supported mode. + 0. CIU clock rate in Hz for DS mode + 1. CIU clock rate in Hz for MMC HS mode + 2. CIU clock rate in Hz for SD HS mode + 3. CIU clock rate in Hz for SDR12 mode + 4. CIU clock rate in Hz for SDR25 mode + 5. CIU clock rate in Hz for SDR50 mode + 6. CIU clock rate in Hz for SDR104 mode + 7. CIU clock rate in Hz for DDR50 mode + 8. CIU clock rate in Hz for HS200 mode + +Example: + + /* for Hi3620 */ + + /* SoC portion */ + dwmmc_0: dwmmc0@fcd03000 { + compatible = hisilicon,hi4511-dw-mshc; + reg = 0xfcd03000 0x1000; + interrupts = 0 16 4; + #address-cells = 1; + #size-cells = 0; + clocks = mmc_clock HI3620_SD_CIUCLK, clock HI3620_DDRC_PER_CLK; + clock-names = ciu, biu; + clock-freq-table = + 2500 0 5000 2500 5000 1 0 5000; + }; + + /* Board portion */ + dwmmc0@fcd03000 { + num-slots = 1; + vmmc-supply = ldo12; + fifo-depth = 0x100; + supports-highspeed; + pinctrl-names = default; + pinctrl-0 = sd_pmx_pins sd_cfg_func1 sd_cfg_func2; + slot@0 { + reg = 0; + bus-width = 4; + disable-wp; + cd-gpios = gpio10 3 0; + }; + }; diff --git a/drivers/mmc/host/Kconfig b/drivers/mmc/host/Kconfig index 7fc5099e44b2..45aaa2de0f58 100644 --- a/drivers/mmc/host/Kconfig +++ b/drivers/mmc/host/Kconfig @@ -575,6 +575,16 @@ config MMC_DW_SOCFPGA This selects support for Altera SoCFPGA specific extensions to the Synopsys DesignWare Memory Card Interface driver. +config MMC_DW_K3 + tristate K3 specific extensions for Synopsys DW Memory Card Interface + depends on MMC_DW + select MMC_DW_PLTFM + select MMC_DW_IDMAC + help + This selects support for Hisilicon K3 SoC specific extensions to the + Synopsys DesignWare Memory Card Interface driver. Select this option + for platforms based on Hisilicon K3 SoC's. + config MMC_DW_PCI tristate Synopsys Designware MCI support on PCI bus depends on MMC_DW PCI diff --git a/drivers/mmc/host/Makefile b/drivers/mmc/host/Makefile index c41d0c364509..64f5f8d35839 100644 --- a/drivers/mmc/host/Makefile +++ b/drivers/mmc/host/Makefile @@ -43,6 +43,7 @@ obj-$(CONFIG_MMC_DW) += dw_mmc.o obj-$(CONFIG_MMC_DW_PLTFM) += dw_mmc-pltfm.o obj-$(CONFIG_MMC_DW_EXYNOS)+= dw_mmc-exynos.o obj-$(CONFIG_MMC_DW_SOCFPGA) += dw_mmc-socfpga.o +obj-$(CONFIG_MMC_DW_K3)+= dw_mmc-k3.o obj-$(CONFIG_MMC_DW_PCI) += dw_mmc-pci.o obj-$(CONFIG_MMC_SH_MMCIF) += sh_mmcif.o obj-$(CONFIG_MMC_JZ4740) += jz4740_mmc.o diff --git a/drivers/mmc/host/dw_mmc-k3.c b/drivers/mmc/host/dw_mmc-k3.c new file mode 100644 index ..68e5e428e8f6 --- /dev/null +++ b/drivers/mmc/host/dw_mmc-k3.c @@ -0,0 +1,132 @@ +/* + * Copyright (c) 2013 Linaro Ltd. + * Copyright (c) 2013 Hisilicon Limited. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published
Re: [PATCH 2/3] mmc: dw_mmc: add dw_mmc-k3 for k3 platform
On Mon, Dec 30, 2013 at 7:55 AM, Jaehoon Chung jh80.ch...@samsung.com wrote: On 12/30/2013 06:05 AM, Arnd Bergmann wrote: On Saturday 28 December 2013, Zhangfei Gao wrote: Add dw_mmc-k3.c for k3v2, support sd/emmc Signed-off-by: Zhangfei Gao zhangfei@linaro.org Signed-off-by: Zhigang Wang brooke.wangzhig...@huawei.com --- .../devicetree/bindings/mmc/k3-dw-mshc.txt | 60 ++ drivers/mmc/host/Kconfig | 10 ++ drivers/mmc/host/Makefile |1 + drivers/mmc/host/dw_mmc-k3.c | 126 4 files changed, 197 insertions(+) create mode 100644 Documentation/devicetree/bindings/mmc/k3-dw-mshc.txt create mode 100644 drivers/mmc/host/dw_mmc-k3.c diff --git a/Documentation/devicetree/bindings/mmc/k3-dw-mshc.txt b/Documentation/devicetree/bindings/mmc/k3-dw-mshc.txt new file mode 100644 index ..d7e2d7f159bb --- /dev/null +++ b/Documentation/devicetree/bindings/mmc/k3-dw-mshc.txt @@ -0,0 +1,60 @@ +* Hisilicon specific extensions to the Synopsys Designware Mobile + Storage Host Controller + +Read synopsys-dw-mshc.txt for more details + +The Synopsys designware mobile storage host controller is used to interface +a SoC with storage medium such as eMMC or SD/MMC cards. This file documents +differences between the core Synopsys dw mshc controller properties described +by synopsys-dw-mshc.txt and the properties used by the Hisilicon specific +extensions to the Synopsys Designware Mobile Storage Host Controller. + +Required Properties: + +* compatible: should be one of the following. + - hisilicon,hi4511-dw-mshc: for controllers with hi4511 specific extentions. I wonder if this is actually a different variant of the mshc hardware, or just wired up in a different way. Do you know details? Since the only difference in the binding is the presence of the clock-freq-table property, we could also make this property generic for the mshc driver and use it if present but fall back to the normal behavior when it is absent. There are still other differences and limitations besides clock-freq-table. The controller seems less intelligent than other Synopsys mmc controller. The tuning process like HS200 is not intelligent, as a result, some local registers are added to help this. +* clock-freq-table: should be the frequency (in Hz) array of the ciu clock +in each supported mode. +0. CIU clock rate in Hz for DS mode +1. CIU clock rate in Hz for MMC HS mode +2. CIU clock rate in Hz for SD HS mode +3. CIU clock rate in Hz for SDR12 mode +4. CIU clock rate in Hz for SDR25 mode +5. CIU clock rate in Hz for SDR50 mode +6. CIU clock rate in Hz for SDR104 mode +7. CIU clock rate in Hz for DDR50 mode +8. CIU clock rate in Hz for HS200 mode This looks god now. +static void dw_mci_k3_set_ios(struct dw_mci *host, struct mmc_ios *ios) +{ +struct dw_mci_k3_priv_data *priv = host-priv; +u32 rate = priv-clk_table[ios-timing]; +int ret; I think this should have some range checking to see if the mode that is being set had a clock frequency set in the DT. The range safety should be ensured by the clk_table array, MAX_NUMS=10. + +ret = clk_set_rate(host-ciu_clk, rate); +if (ret) +dev_warn(host-dev, failed to set clock rate %uHz\n, rate); + +host-bus_hz = clk_get_rate(host-ciu_clk); +} Why do you call clk_get_rate() here, shouldn't it always be the same rate that you have just set? It is more accurate to use clk_get_rate here. For example, if switch to ios-clock as you suggested before, 52M will be set for mmc, while 50M is supported. However, it can simply use rate set currently. +static int dw_mci_k3_parse_dt(struct dw_mci *host) +{ +struct dw_mci_k3_priv_data *priv; +struct device_node *node = host-dev-of_node; +struct property *prop; +const __be32 *cur; +u32 val, num = 0; + +priv = devm_kzalloc(host-dev, sizeof(*priv), GFP_KERNEL); +if (!priv) { +dev_err(host-dev, mem alloc failed for private data\n); +return -ENOMEM; +} +host-priv = priv; + +of_property_for_each_u32(node, clock-freq-table, prop, cur, val) { +if (num = MAX_NUMS) +break; +priv-clk_table[num++] = val; +} +return 0; +} If we make this property part of the generic binding, this function could also get moved to the main dw_mci driver. This may be not general. The controller does not generate the clock itself, and set rate to the outside clock source, which may be different according to the working mode. +static int dw_mci_k3_suspend(struct device *dev) +{ +struct dw_mci *host = dev_get_drvdata(dev); +int ret = 0; + +ret = dw_mci_suspend(host); You should never initialize local variables when they are set later in the function (the ret
[PATCH v6 0/3] mmc: dw_mmc: add dw_mmc-k3
v6: 0002: Jaehoon pointed HIGHSPEED cap can be omitted if supports-highspeed is defined. Seungwon mentioned clk operation should be called after suspend. Remove k3_dwmmc_caps V5: 0002: Follow advice from Arnd, Update dt descirption and use of_property_for_each_u32 to get table number. v4: Follow Arnd's suggestion abstracting specific tuning to clock, also because new version ip use different method and not use same tuning registers. 0001 acked by Jaehoon v3: 0001: Put set/clear_bit DW_MMC_CARD_PRESENT in dw_mci_get_cd, Since dw_mci_request will check DW_MMC_CARD_PRESENT before sending cmd 0002: Follow suggestion from Chris, Kumar and Seungwon Sync to latest mmc-next, which is 3.12-rc2 Remove enum dw_mci_k3_type etc v2: Follow Jaehoon's suggestion Use slot-gpio.c handle cd pin Move table out to dts other suggestion Zhangfei Gao (3): mmc: dw_mmc: use slot-gpio to handle cd pin mmc: dw_mmc: add dw_mmc-k3 for k3 platform clk: hisilicon: add hi3620_mmc_clks .../bindings/arm/hisilicon/hisilicon.txt | 14 ++ .../devicetree/bindings/clock/hi3620-clock.txt |1 + .../devicetree/bindings/mmc/k3-dw-mshc.txt | 60 + drivers/clk/hisilicon/clk-hi3620.c | 262 drivers/mmc/host/Kconfig | 10 + drivers/mmc/host/Makefile |1 + drivers/mmc/host/dw_mmc-k3.c | 126 ++ drivers/mmc/host/dw_mmc.c | 48 +++- include/dt-bindings/clock/hi3620-clock.h |5 + 9 files changed, 514 insertions(+), 13 deletions(-) create mode 100644 Documentation/devicetree/bindings/mmc/k3-dw-mshc.txt create mode 100644 drivers/mmc/host/dw_mmc-k3.c -- 1.7.9.5 -- To unsubscribe from this list: send the line unsubscribe linux-mmc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 2/3] mmc: dw_mmc: add dw_mmc-k3 for k3 platform
Add dw_mmc-k3.c for k3v2, support sd/emmc Signed-off-by: Zhangfei Gao zhangfei@linaro.org Signed-off-by: Zhigang Wang brooke.wangzhig...@huawei.com --- .../devicetree/bindings/mmc/k3-dw-mshc.txt | 60 ++ drivers/mmc/host/Kconfig | 10 ++ drivers/mmc/host/Makefile |1 + drivers/mmc/host/dw_mmc-k3.c | 126 4 files changed, 197 insertions(+) create mode 100644 Documentation/devicetree/bindings/mmc/k3-dw-mshc.txt create mode 100644 drivers/mmc/host/dw_mmc-k3.c diff --git a/Documentation/devicetree/bindings/mmc/k3-dw-mshc.txt b/Documentation/devicetree/bindings/mmc/k3-dw-mshc.txt new file mode 100644 index ..d7e2d7f159bb --- /dev/null +++ b/Documentation/devicetree/bindings/mmc/k3-dw-mshc.txt @@ -0,0 +1,60 @@ +* Hisilicon specific extensions to the Synopsys Designware Mobile + Storage Host Controller + +Read synopsys-dw-mshc.txt for more details + +The Synopsys designware mobile storage host controller is used to interface +a SoC with storage medium such as eMMC or SD/MMC cards. This file documents +differences between the core Synopsys dw mshc controller properties described +by synopsys-dw-mshc.txt and the properties used by the Hisilicon specific +extensions to the Synopsys Designware Mobile Storage Host Controller. + +Required Properties: + +* compatible: should be one of the following. + - hisilicon,hi4511-dw-mshc: for controllers with hi4511 specific extentions. + +* clock-freq-table: should be the frequency (in Hz) array of the ciu clock + in each supported mode. + 0. CIU clock rate in Hz for DS mode + 1. CIU clock rate in Hz for MMC HS mode + 2. CIU clock rate in Hz for SD HS mode + 3. CIU clock rate in Hz for SDR12 mode + 4. CIU clock rate in Hz for SDR25 mode + 5. CIU clock rate in Hz for SDR50 mode + 6. CIU clock rate in Hz for SDR104 mode + 7. CIU clock rate in Hz for DDR50 mode + 8. CIU clock rate in Hz for HS200 mode + +Example: + + /* for Hi3620 */ + + /* SoC portion */ + dwmmc_0: dwmmc0@fcd03000 { + compatible = hisilicon,hi4511-dw-mshc; + reg = 0xfcd03000 0x1000; + interrupts = 0 16 4; + #address-cells = 1; + #size-cells = 0; + clocks = mmc_clock HI3620_SD_CIUCLK, clock HI3620_DDRC_PER_CLK; + clock-names = ciu, biu; + clock-freq-table = + 2500 0 5000 2500 5000 1 0 5000; + }; + + /* Board portion */ + dwmmc0@fcd03000 { + num-slots = 1; + vmmc-supply = ldo12; + fifo-depth = 0x100; + supports-highspeed; + pinctrl-names = default; + pinctrl-0 = sd_pmx_pins sd_cfg_func1 sd_cfg_func2; + slot@0 { + reg = 0; + bus-width = 4; + disable-wp; + cd-gpios = gpio10 3 0; + }; + }; diff --git a/drivers/mmc/host/Kconfig b/drivers/mmc/host/Kconfig index 7fc5099e44b2..45aaa2de0f58 100644 --- a/drivers/mmc/host/Kconfig +++ b/drivers/mmc/host/Kconfig @@ -575,6 +575,16 @@ config MMC_DW_SOCFPGA This selects support for Altera SoCFPGA specific extensions to the Synopsys DesignWare Memory Card Interface driver. +config MMC_DW_K3 + tristate K3 specific extensions for Synopsys DW Memory Card Interface + depends on MMC_DW + select MMC_DW_PLTFM + select MMC_DW_IDMAC + help + This selects support for Hisilicon K3 SoC specific extensions to the + Synopsys DesignWare Memory Card Interface driver. Select this option + for platforms based on Hisilicon K3 SoC's. + config MMC_DW_PCI tristate Synopsys Designware MCI support on PCI bus depends on MMC_DW PCI diff --git a/drivers/mmc/host/Makefile b/drivers/mmc/host/Makefile index c41d0c364509..64f5f8d35839 100644 --- a/drivers/mmc/host/Makefile +++ b/drivers/mmc/host/Makefile @@ -43,6 +43,7 @@ obj-$(CONFIG_MMC_DW) += dw_mmc.o obj-$(CONFIG_MMC_DW_PLTFM) += dw_mmc-pltfm.o obj-$(CONFIG_MMC_DW_EXYNOS)+= dw_mmc-exynos.o obj-$(CONFIG_MMC_DW_SOCFPGA) += dw_mmc-socfpga.o +obj-$(CONFIG_MMC_DW_K3)+= dw_mmc-k3.o obj-$(CONFIG_MMC_DW_PCI) += dw_mmc-pci.o obj-$(CONFIG_MMC_SH_MMCIF) += sh_mmcif.o obj-$(CONFIG_MMC_JZ4740) += jz4740_mmc.o diff --git a/drivers/mmc/host/dw_mmc-k3.c b/drivers/mmc/host/dw_mmc-k3.c new file mode 100644 index ..89f69428e3dc --- /dev/null +++ b/drivers/mmc/host/dw_mmc-k3.c @@ -0,0 +1,126 @@ +/* + * Copyright (c) 2013 Linaro Ltd. + * Copyright (c) 2013 Hisilicon Limited. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published
[PATCH 3/3] clk: hisilicon: add hi3620_mmc_clks
Suggest by Arnd: abstract mmc tuning as clock behavior, also because different soc have different tuning method and registers. hi3620_mmc_clks is added to handle mmc clock specifically on hi3620. Signed-off-by: Zhangfei Gao zhangfei@linaro.org --- .../bindings/arm/hisilicon/hisilicon.txt | 14 ++ .../devicetree/bindings/clock/hi3620-clock.txt |1 + drivers/clk/hisilicon/clk-hi3620.c | 262 include/dt-bindings/clock/hi3620-clock.h |5 + 4 files changed, 282 insertions(+) diff --git a/Documentation/devicetree/bindings/arm/hisilicon/hisilicon.txt b/Documentation/devicetree/bindings/arm/hisilicon/hisilicon.txt index 8c7a4653508d..df0a452b8526 100644 --- a/Documentation/devicetree/bindings/arm/hisilicon/hisilicon.txt +++ b/Documentation/devicetree/bindings/arm/hisilicon/hisilicon.txt @@ -30,3 +30,17 @@ Example: resume-offset = 0x308; reboot-offset = 0x4; }; + +PCTRL: Peripheral misc control register + +Required Properties: +- compatible: hisilicon,pctrl +- reg: Address and size of pctrl. + +Example: + + /* for Hi3620 */ + pctrl: pctrl@fca09000 { + compatible = hisilicon,pctrl; + reg = 0xfca09000 0x1000; + }; diff --git a/Documentation/devicetree/bindings/clock/hi3620-clock.txt b/Documentation/devicetree/bindings/clock/hi3620-clock.txt index 4b71ab41be53..dad6269f52c5 100644 --- a/Documentation/devicetree/bindings/clock/hi3620-clock.txt +++ b/Documentation/devicetree/bindings/clock/hi3620-clock.txt @@ -7,6 +7,7 @@ Required Properties: - compatible: should be one of the following. - hisilicon,hi3620-clock - controller compatible with Hi3620 SoC. + - hisilicon,hi3620-mmc-clock - controller specific for Hi3620 mmc. - reg: physical base address of the controller and length of memory mapped region. diff --git a/drivers/clk/hisilicon/clk-hi3620.c b/drivers/clk/hisilicon/clk-hi3620.c index f24ad6a3a797..e47a4a659df7 100644 --- a/drivers/clk/hisilicon/clk-hi3620.c +++ b/drivers/clk/hisilicon/clk-hi3620.c @@ -240,3 +240,265 @@ static void __init hi3620_clk_init(struct device_node *np) base); } CLK_OF_DECLARE(hi3620_clk, hisilicon,hi3620-clock, hi3620_clk_init); + +struct hisi_mmc_clock { + unsigned intid; + const char *name; + const char *parent_name; + unsigned long flags; + u32 clken_reg; + u32 clken_bit; + u32 div_reg; + u32 div_off; + u32 div_bits; + u32 drv_reg; + u32 drv_off; + u32 drv_bits; + u32 sam_reg; + u32 sam_off; + u32 sam_bits; +}; + +struct clk_mmc { + struct clk_hw hw; + u32 id; + void __iomem*clken_reg; + u32 clken_bit; + void __iomem*div_reg; + u32 div_off; + u32 div_bits; + void __iomem*drv_reg; + u32 drv_off; + u32 drv_bits; + void __iomem*sam_reg; + u32 sam_off; + u32 sam_bits; +}; + +#define to_mmc(_hw) container_of(_hw, struct clk_mmc, hw) + +static struct hisi_mmc_clock hi3620_mmc_clks[] __initdata = { + { HI3620_SD_CIUCLK, sd_bclk1, sd_clk, CLK_SET_RATE_PARENT, 0x1f8, 0, 0x1f8, 1, 3, 0x1f8, 4, 4, 0x1f8, 8, 4}, + { HI3620_MMC_CIUCLK1, mmc_bclk1, mmc_clk1, CLK_SET_RATE_PARENT, 0x1f8, 12, 0x1f8, 13, 3, 0x1f8, 16, 4, 0x1f8, 20, 4}, + { HI3620_MMC_CIUCLK2, mmc_bclk2, mmc_clk2, CLK_SET_RATE_PARENT, 0x1f8, 24, 0x1f8, 25, 3, 0x1f8, 28, 4, 0x1fc, 0, 4}, + { HI3620_MMC_CIUCLK3, mmc_bclk3, mmc_clk3, CLK_SET_RATE_PARENT, 0x1fc, 4, 0x1fc, 5, 3, 0x1fc, 8, 4, 0x1fc, 12, 4}, +}; + +static unsigned long mmc_clk_recalc_rate(struct clk_hw *hw, + unsigned long parent_rate) +{ + switch (parent_rate) { + case 2600: + return 1300; + case 18000: + return 2500; + case 36000: + return 5000; + case 72000: + return 1; + default: + return parent_rate; + } +} + +static long mmc_clk_determine_rate(struct clk_hw *hw, unsigned long rate, + unsigned long *best_parent_rate, + struct clk **best_parent_p) +{ + unsigned long best = 0; + + if (rate = 1300) { + rate = 1300; + best = 2600; + } else if (rate = 2600) { + rate = 2500; + best = 18000; + } else if (rate = 5200) { + rate = 5000
[PATCH 1/3] mmc: dw_mmc: use slot-gpio to handle cd pin
Suggested by Jaehoon: Use slot-gpio to handle cd-gpio Add function dw_mci_of_get_cd_gpio to check cd-gpios from dts. mmc_gpio_request_cd and mmc_gpio_get_cd are used to handle cd pin Signed-off-by: Zhangfei Gao zhangfei@linaro.org Acked-by: Jaehoon Chung jh80.ch...@samsung.com --- drivers/mmc/host/dw_mmc.c | 48 + 1 file changed, 35 insertions(+), 13 deletions(-) diff --git a/drivers/mmc/host/dw_mmc.c b/drivers/mmc/host/dw_mmc.c index 4bce0deec362..a776f24f4311 100644 --- a/drivers/mmc/host/dw_mmc.c +++ b/drivers/mmc/host/dw_mmc.c @@ -36,6 +36,7 @@ #include linux/workqueue.h #include linux/of.h #include linux/of_gpio.h +#include linux/mmc/slot-gpio.h #include dw_mmc.h @@ -1032,20 +1033,26 @@ static int dw_mci_get_cd(struct mmc_host *mmc) int present; struct dw_mci_slot *slot = mmc_priv(mmc); struct dw_mci_board *brd = slot-host-pdata; + int gpio_cd = !mmc_gpio_get_cd(mmc); /* Use platform get_cd function, else try onboard card detect */ if (brd-quirks DW_MCI_QUIRK_BROKEN_CARD_DETECTION) present = 1; else if (brd-get_cd) present = !brd-get_cd(slot-id); + else if (!IS_ERR_VALUE(gpio_cd)) + present = !!gpio_cd; else present = (mci_readl(slot-host, CDETECT) (1 slot-id)) == 0 ? 1 : 0; - if (present) + if (present) { + set_bit(DW_MMC_CARD_PRESENT, slot-flags); dev_dbg(mmc-class_dev, card is present\n); - else + } else { + clear_bit(DW_MMC_CARD_PRESENT, slot-flags); dev_dbg(mmc-class_dev, card is not present\n); + } return present; } @@ -1926,10 +1933,6 @@ static void dw_mci_work_routine_card(struct work_struct *work) /* Card change detected */ slot-last_detect_state = present; - /* Mark card as present if applicable */ - if (present != 0) - set_bit(DW_MMC_CARD_PRESENT, slot-flags); - /* Clean up queue if present */ mrq = slot-mrq; if (mrq) { @@ -1977,8 +1980,6 @@ static void dw_mci_work_routine_card(struct work_struct *work) /* Power down slot */ if (present == 0) { - clear_bit(DW_MMC_CARD_PRESENT, slot-flags); - /* Clear down the FIFO */ dw_mci_fifo_reset(host); #ifdef CONFIG_MMC_DW_IDMAC @@ -2079,6 +2080,26 @@ static int dw_mci_of_get_wp_gpio(struct device *dev, u8 slot) return gpio; } + +/* find the cd gpio for a given slot; or -1 if none specified */ +static void dw_mci_of_get_cd_gpio(struct device *dev, u8 slot, + struct mmc_host *mmc) +{ + struct device_node *np = dw_mci_of_find_slot_node(dev, slot); + int gpio; + + if (!np) + return; + + gpio = of_get_named_gpio(np, cd-gpios, 0); + + /* Having a missing entry is valid; return silently */ + if (!gpio_is_valid(gpio)) + return; + + if (mmc_gpio_request_cd(mmc, gpio, 0)) + dev_warn(dev, gpio [%d] request failed\n, gpio); +} #else /* CONFIG_OF */ static int dw_mci_of_get_slot_quirks(struct device *dev, u8 slot) { @@ -2096,6 +2117,11 @@ static int dw_mci_of_get_wp_gpio(struct device *dev, u8 slot) { return -EINVAL; } +static void dw_mci_of_get_cd_gpio(struct device *dev, u8 slot, + struct mmc_host *mmc) +{ + return; +} #endif /* CONFIG_OF */ static int dw_mci_init_slot(struct dw_mci *host, unsigned int id) @@ -2197,12 +2223,8 @@ static int dw_mci_init_slot(struct dw_mci *host, unsigned int id) #endif /* CONFIG_MMC_DW_IDMAC */ } - if (dw_mci_get_cd(mmc)) - set_bit(DW_MMC_CARD_PRESENT, slot-flags); - else - clear_bit(DW_MMC_CARD_PRESENT, slot-flags); - slot-wp_gpio = dw_mci_of_get_wp_gpio(host-dev, slot-id); + dw_mci_of_get_cd_gpio(host-dev, slot-id, mmc); ret = mmc_add_host(mmc); if (ret) -- 1.7.9.5 -- To unsubscribe from this list: send the line unsubscribe linux-mmc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 2/3] mmc: dw_mmc: add dw_mmc-k3 for k3 platform
Add dw_mmc-k3.c for k3v2, support sd/emmc Signed-off-by: Zhangfei Gao zhangfei@linaro.org Signed-off-by: Zhigang Wang brooke.wangzhig...@huawei.com --- .../devicetree/bindings/mmc/k3-dw-mshc.txt | 60 + drivers/mmc/host/Kconfig | 10 ++ drivers/mmc/host/Makefile |1 + drivers/mmc/host/dw_mmc-k3.c | 134 4 files changed, 205 insertions(+) create mode 100644 Documentation/devicetree/bindings/mmc/k3-dw-mshc.txt create mode 100644 drivers/mmc/host/dw_mmc-k3.c diff --git a/Documentation/devicetree/bindings/mmc/k3-dw-mshc.txt b/Documentation/devicetree/bindings/mmc/k3-dw-mshc.txt new file mode 100644 index ..d7e2d7f159bb --- /dev/null +++ b/Documentation/devicetree/bindings/mmc/k3-dw-mshc.txt @@ -0,0 +1,60 @@ +* Hisilicon specific extensions to the Synopsys Designware Mobile + Storage Host Controller + +Read synopsys-dw-mshc.txt for more details + +The Synopsys designware mobile storage host controller is used to interface +a SoC with storage medium such as eMMC or SD/MMC cards. This file documents +differences between the core Synopsys dw mshc controller properties described +by synopsys-dw-mshc.txt and the properties used by the Hisilicon specific +extensions to the Synopsys Designware Mobile Storage Host Controller. + +Required Properties: + +* compatible: should be one of the following. + - hisilicon,hi4511-dw-mshc: for controllers with hi4511 specific extentions. + +* clock-freq-table: should be the frequency (in Hz) array of the ciu clock + in each supported mode. + 0. CIU clock rate in Hz for DS mode + 1. CIU clock rate in Hz for MMC HS mode + 2. CIU clock rate in Hz for SD HS mode + 3. CIU clock rate in Hz for SDR12 mode + 4. CIU clock rate in Hz for SDR25 mode + 5. CIU clock rate in Hz for SDR50 mode + 6. CIU clock rate in Hz for SDR104 mode + 7. CIU clock rate in Hz for DDR50 mode + 8. CIU clock rate in Hz for HS200 mode + +Example: + + /* for Hi3620 */ + + /* SoC portion */ + dwmmc_0: dwmmc0@fcd03000 { + compatible = hisilicon,hi4511-dw-mshc; + reg = 0xfcd03000 0x1000; + interrupts = 0 16 4; + #address-cells = 1; + #size-cells = 0; + clocks = mmc_clock HI3620_SD_CIUCLK, clock HI3620_DDRC_PER_CLK; + clock-names = ciu, biu; + clock-freq-table = + 2500 0 5000 2500 5000 1 0 5000; + }; + + /* Board portion */ + dwmmc0@fcd03000 { + num-slots = 1; + vmmc-supply = ldo12; + fifo-depth = 0x100; + supports-highspeed; + pinctrl-names = default; + pinctrl-0 = sd_pmx_pins sd_cfg_func1 sd_cfg_func2; + slot@0 { + reg = 0; + bus-width = 4; + disable-wp; + cd-gpios = gpio10 3 0; + }; + }; diff --git a/drivers/mmc/host/Kconfig b/drivers/mmc/host/Kconfig index 7fc5099e44b2..45aaa2de0f58 100644 --- a/drivers/mmc/host/Kconfig +++ b/drivers/mmc/host/Kconfig @@ -575,6 +575,16 @@ config MMC_DW_SOCFPGA This selects support for Altera SoCFPGA specific extensions to the Synopsys DesignWare Memory Card Interface driver. +config MMC_DW_K3 + tristate K3 specific extensions for Synopsys DW Memory Card Interface + depends on MMC_DW + select MMC_DW_PLTFM + select MMC_DW_IDMAC + help + This selects support for Hisilicon K3 SoC specific extensions to the + Synopsys DesignWare Memory Card Interface driver. Select this option + for platforms based on Hisilicon K3 SoC's. + config MMC_DW_PCI tristate Synopsys Designware MCI support on PCI bus depends on MMC_DW PCI diff --git a/drivers/mmc/host/Makefile b/drivers/mmc/host/Makefile index c41d0c364509..64f5f8d35839 100644 --- a/drivers/mmc/host/Makefile +++ b/drivers/mmc/host/Makefile @@ -43,6 +43,7 @@ obj-$(CONFIG_MMC_DW) += dw_mmc.o obj-$(CONFIG_MMC_DW_PLTFM) += dw_mmc-pltfm.o obj-$(CONFIG_MMC_DW_EXYNOS)+= dw_mmc-exynos.o obj-$(CONFIG_MMC_DW_SOCFPGA) += dw_mmc-socfpga.o +obj-$(CONFIG_MMC_DW_K3)+= dw_mmc-k3.o obj-$(CONFIG_MMC_DW_PCI) += dw_mmc-pci.o obj-$(CONFIG_MMC_SH_MMCIF) += sh_mmcif.o obj-$(CONFIG_MMC_JZ4740) += jz4740_mmc.o diff --git a/drivers/mmc/host/dw_mmc-k3.c b/drivers/mmc/host/dw_mmc-k3.c new file mode 100644 index ..e3eea2883ae7 --- /dev/null +++ b/drivers/mmc/host/dw_mmc-k3.c @@ -0,0 +1,134 @@ +/* + * Copyright (c) 2013 Linaro Ltd. + * Copyright (c) 2013 Hisilicon Limited. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published
Re: [PATCHv6 1/5] mmc: dw_mmc: Add support to set the SDR and DDR timing through clock framework
On 16 December 2013 11:24, Dinh Nguyen dinh.li...@gmail.com wrote: @@ -2478,6 +2480,27 @@ int dw_mci_probe(struct dw_mci *host) dev_dbg(host-dev, ciu clock not available\n); host-bus_hz = host-pdata-bus_hz; } else { +/* If the CIU clk is available, we check for SDR and DDR + * timing phase shift settings. But not all platforms + * may have populated these settings, the driver will not fail + * if these settings are not specified. + */ +if (host-pdata-sdr_timing) { +host-sdr_clk = devm_clk_get(host-dev, sdr_mmc_clk); +if (IS_ERR(host-sdr_clk)) +dev_dbg(host-dev, sdr_mmc clock not available\n); +else +clk_set_rate(host-sdr_clk, host-pdata-sdr_timing); +} + +if (host-pdata-ddr_timing) { +host-ddr_clk = devm_clk_get(host-dev, ddr_mmc_clk); +if (IS_ERR(host-ddr_clk)) +dev_dbg(host-dev, ddr_mmc clock not available\n); +else +clk_set_rate(host-ddr_clk, host-pdata-ddr_timing); +} + Just curious, does pdata-sdr_timing and pdata-ddr_timing are fixed, fixed as each controller, or different with different board. Yes, they are fixed for each controller per SoC. In case they are fixed, or fixed in each controller, and only required to be set in probe only once, maybe they can be hide in clk_mmc_ops.prepare And the clock can be used as ciu_clock, or parent of ciu_clock, which is called in dw_mmc.c, maybe these code can be ignored. Please see v5 of this patch: https://patchwork.kernel.org/patch/3311121/ The issue with V5 was that there is no way for the dw_mmc driver to pass the clock phase settings in the clk_mmc_ops.prepare function. Personally, I think v5 is simpler :) I agree... Could these fixed para be used as internal para when register. Like socfpga_gate_clk_init rc = of_property_read_u32_array(node, clk-gate, clk_gate, 2); compatible = altr,socfpga-gate-clk; clocks = mainclk; div-reg = 0x64 0 2; clk-gate = 0x60 1; Could we also define mmc-ciu-clock with para clk-init. Hmm..this was one of Arnd's suggestion. Will this also work for you? If so then I think I can proceed down this path, as I think this should be the most direct and simplest. Yes, go ahead. sdr_timing ddr_timing only takes effect on socfpga-mmc. It is good to put in clk driver specifically for socfpga, instead of putting in common dw_mmc.c Thanks -- To unsubscribe from this list: send the line unsubscribe linux-mmc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 3/3] clk: hisilicon: add hi3620_mmc_clks
Suggest by Arnd: abstract mmc tuning as clock behavior, also because different soc have different tuning method and registers. hi3620_mmc_clks is added to handle mmc clock specifically on hi3620. Signed-off-by: Zhangfei Gao zhangfei@linaro.org --- .../bindings/arm/hisilicon/hisilicon.txt | 14 ++ .../devicetree/bindings/clock/hi3620-clock.txt |1 + drivers/clk/hisilicon/clk-hi3620.c | 262 include/dt-bindings/clock/hi3620-clock.h |5 + 4 files changed, 282 insertions(+) diff --git a/Documentation/devicetree/bindings/arm/hisilicon/hisilicon.txt b/Documentation/devicetree/bindings/arm/hisilicon/hisilicon.txt index 8c7a4653508d..df0a452b8526 100644 --- a/Documentation/devicetree/bindings/arm/hisilicon/hisilicon.txt +++ b/Documentation/devicetree/bindings/arm/hisilicon/hisilicon.txt @@ -30,3 +30,17 @@ Example: resume-offset = 0x308; reboot-offset = 0x4; }; + +PCTRL: Peripheral misc control register + +Required Properties: +- compatible: hisilicon,pctrl +- reg: Address and size of pctrl. + +Example: + + /* for Hi3620 */ + pctrl: pctrl@fca09000 { + compatible = hisilicon,pctrl; + reg = 0xfca09000 0x1000; + }; diff --git a/Documentation/devicetree/bindings/clock/hi3620-clock.txt b/Documentation/devicetree/bindings/clock/hi3620-clock.txt index 4b71ab41be53..dad6269f52c5 100644 --- a/Documentation/devicetree/bindings/clock/hi3620-clock.txt +++ b/Documentation/devicetree/bindings/clock/hi3620-clock.txt @@ -7,6 +7,7 @@ Required Properties: - compatible: should be one of the following. - hisilicon,hi3620-clock - controller compatible with Hi3620 SoC. + - hisilicon,hi3620-mmc-clock - controller specific for Hi3620 mmc. - reg: physical base address of the controller and length of memory mapped region. diff --git a/drivers/clk/hisilicon/clk-hi3620.c b/drivers/clk/hisilicon/clk-hi3620.c index f24ad6a3a797..e47a4a659df7 100644 --- a/drivers/clk/hisilicon/clk-hi3620.c +++ b/drivers/clk/hisilicon/clk-hi3620.c @@ -240,3 +240,265 @@ static void __init hi3620_clk_init(struct device_node *np) base); } CLK_OF_DECLARE(hi3620_clk, hisilicon,hi3620-clock, hi3620_clk_init); + +struct hisi_mmc_clock { + unsigned intid; + const char *name; + const char *parent_name; + unsigned long flags; + u32 clken_reg; + u32 clken_bit; + u32 div_reg; + u32 div_off; + u32 div_bits; + u32 drv_reg; + u32 drv_off; + u32 drv_bits; + u32 sam_reg; + u32 sam_off; + u32 sam_bits; +}; + +struct clk_mmc { + struct clk_hw hw; + u32 id; + void __iomem*clken_reg; + u32 clken_bit; + void __iomem*div_reg; + u32 div_off; + u32 div_bits; + void __iomem*drv_reg; + u32 drv_off; + u32 drv_bits; + void __iomem*sam_reg; + u32 sam_off; + u32 sam_bits; +}; + +#define to_mmc(_hw) container_of(_hw, struct clk_mmc, hw) + +static struct hisi_mmc_clock hi3620_mmc_clks[] __initdata = { + { HI3620_SD_CIUCLK, sd_bclk1, sd_clk, CLK_SET_RATE_PARENT, 0x1f8, 0, 0x1f8, 1, 3, 0x1f8, 4, 4, 0x1f8, 8, 4}, + { HI3620_MMC_CIUCLK1, mmc_bclk1, mmc_clk1, CLK_SET_RATE_PARENT, 0x1f8, 12, 0x1f8, 13, 3, 0x1f8, 16, 4, 0x1f8, 20, 4}, + { HI3620_MMC_CIUCLK2, mmc_bclk2, mmc_clk2, CLK_SET_RATE_PARENT, 0x1f8, 24, 0x1f8, 25, 3, 0x1f8, 28, 4, 0x1fc, 0, 4}, + { HI3620_MMC_CIUCLK3, mmc_bclk3, mmc_clk3, CLK_SET_RATE_PARENT, 0x1fc, 4, 0x1fc, 5, 3, 0x1fc, 8, 4, 0x1fc, 12, 4}, +}; + +static unsigned long mmc_clk_recalc_rate(struct clk_hw *hw, + unsigned long parent_rate) +{ + switch (parent_rate) { + case 2600: + return 1300; + case 18000: + return 2500; + case 36000: + return 5000; + case 72000: + return 1; + default: + return parent_rate; + } +} + +static long mmc_clk_determine_rate(struct clk_hw *hw, unsigned long rate, + unsigned long *best_parent_rate, + struct clk **best_parent_p) +{ + unsigned long best = 0; + + if (rate = 1300) { + rate = 1300; + best = 2600; + } else if (rate = 2600) { + rate = 2500; + best = 18000; + } else if (rate = 5200) { + rate = 5000
[PATCH v5 0/3] mmc: dw_mmc: add dw_mmc-k3
V5: 0002: Follow advice from Arnd, Update dt descirption and use of_property_for_each_u32 to get table number. v4: Follow Arnd's suggestion abstracting specific tuning to clock, also because new version ip use different method and not use same tuning registers. 0001 acked by Jaehoon v3: 0001: Put set/clear_bit DW_MMC_CARD_PRESENT in dw_mci_get_cd, Since dw_mci_request will check DW_MMC_CARD_PRESENT before sending cmd 0002: Follow suggestion from Chris, Kumar and Seungwon Sync to latest mmc-next, which is 3.12-rc2 Remove enum dw_mci_k3_type etc v2: Follow Jaehoon's suggestion Use slot-gpio.c handle cd pin Move table out to dts other suggestion Zhangfei Gao (3): mmc: dw_mmc: use slot-gpio to handle cd pin mmc: dw_mmc: add dw_mmc-k3 for k3 platform clk: hisilicon: add hi3620_mmc_clks .../bindings/arm/hisilicon/hisilicon.txt | 14 ++ .../devicetree/bindings/clock/hi3620-clock.txt |1 + .../devicetree/bindings/mmc/k3-dw-mshc.txt | 59 + drivers/clk/hisilicon/clk-hi3620.c | 262 drivers/mmc/host/Kconfig | 10 + drivers/mmc/host/Makefile |1 + drivers/mmc/host/dw_mmc-k3.c | 133 ++ drivers/mmc/host/dw_mmc.c | 48 +++- include/dt-bindings/clock/hi3620-clock.h |5 + 9 files changed, 520 insertions(+), 13 deletions(-) create mode 100644 Documentation/devicetree/bindings/mmc/k3-dw-mshc.txt create mode 100644 drivers/mmc/host/dw_mmc-k3.c -- 1.7.9.5 -- To unsubscribe from this list: send the line unsubscribe linux-mmc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 1/3] mmc: dw_mmc: use slot-gpio to handle cd pin
Suggested by Jaehoon: Use slot-gpio to handle cd-gpio Add function dw_mci_of_get_cd_gpio to check cd-gpios from dts. mmc_gpio_request_cd and mmc_gpio_get_cd are used to handle cd pin Signed-off-by: Zhangfei Gao zhangfei@linaro.org Acked-by: Jaehoon Chung jh80.ch...@samsung.com --- drivers/mmc/host/dw_mmc.c | 48 + 1 file changed, 35 insertions(+), 13 deletions(-) diff --git a/drivers/mmc/host/dw_mmc.c b/drivers/mmc/host/dw_mmc.c index 4bce0deec362..a776f24f4311 100644 --- a/drivers/mmc/host/dw_mmc.c +++ b/drivers/mmc/host/dw_mmc.c @@ -36,6 +36,7 @@ #include linux/workqueue.h #include linux/of.h #include linux/of_gpio.h +#include linux/mmc/slot-gpio.h #include dw_mmc.h @@ -1032,20 +1033,26 @@ static int dw_mci_get_cd(struct mmc_host *mmc) int present; struct dw_mci_slot *slot = mmc_priv(mmc); struct dw_mci_board *brd = slot-host-pdata; + int gpio_cd = !mmc_gpio_get_cd(mmc); /* Use platform get_cd function, else try onboard card detect */ if (brd-quirks DW_MCI_QUIRK_BROKEN_CARD_DETECTION) present = 1; else if (brd-get_cd) present = !brd-get_cd(slot-id); + else if (!IS_ERR_VALUE(gpio_cd)) + present = !!gpio_cd; else present = (mci_readl(slot-host, CDETECT) (1 slot-id)) == 0 ? 1 : 0; - if (present) + if (present) { + set_bit(DW_MMC_CARD_PRESENT, slot-flags); dev_dbg(mmc-class_dev, card is present\n); - else + } else { + clear_bit(DW_MMC_CARD_PRESENT, slot-flags); dev_dbg(mmc-class_dev, card is not present\n); + } return present; } @@ -1926,10 +1933,6 @@ static void dw_mci_work_routine_card(struct work_struct *work) /* Card change detected */ slot-last_detect_state = present; - /* Mark card as present if applicable */ - if (present != 0) - set_bit(DW_MMC_CARD_PRESENT, slot-flags); - /* Clean up queue if present */ mrq = slot-mrq; if (mrq) { @@ -1977,8 +1980,6 @@ static void dw_mci_work_routine_card(struct work_struct *work) /* Power down slot */ if (present == 0) { - clear_bit(DW_MMC_CARD_PRESENT, slot-flags); - /* Clear down the FIFO */ dw_mci_fifo_reset(host); #ifdef CONFIG_MMC_DW_IDMAC @@ -2079,6 +2080,26 @@ static int dw_mci_of_get_wp_gpio(struct device *dev, u8 slot) return gpio; } + +/* find the cd gpio for a given slot; or -1 if none specified */ +static void dw_mci_of_get_cd_gpio(struct device *dev, u8 slot, + struct mmc_host *mmc) +{ + struct device_node *np = dw_mci_of_find_slot_node(dev, slot); + int gpio; + + if (!np) + return; + + gpio = of_get_named_gpio(np, cd-gpios, 0); + + /* Having a missing entry is valid; return silently */ + if (!gpio_is_valid(gpio)) + return; + + if (mmc_gpio_request_cd(mmc, gpio, 0)) + dev_warn(dev, gpio [%d] request failed\n, gpio); +} #else /* CONFIG_OF */ static int dw_mci_of_get_slot_quirks(struct device *dev, u8 slot) { @@ -2096,6 +2117,11 @@ static int dw_mci_of_get_wp_gpio(struct device *dev, u8 slot) { return -EINVAL; } +static void dw_mci_of_get_cd_gpio(struct device *dev, u8 slot, + struct mmc_host *mmc) +{ + return; +} #endif /* CONFIG_OF */ static int dw_mci_init_slot(struct dw_mci *host, unsigned int id) @@ -2197,12 +2223,8 @@ static int dw_mci_init_slot(struct dw_mci *host, unsigned int id) #endif /* CONFIG_MMC_DW_IDMAC */ } - if (dw_mci_get_cd(mmc)) - set_bit(DW_MMC_CARD_PRESENT, slot-flags); - else - clear_bit(DW_MMC_CARD_PRESENT, slot-flags); - slot-wp_gpio = dw_mci_of_get_wp_gpio(host-dev, slot-id); + dw_mci_of_get_cd_gpio(host-dev, slot-id, mmc); ret = mmc_add_host(mmc); if (ret) -- 1.7.9.5 -- To unsubscribe from this list: send the line unsubscribe linux-mmc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 2/3] mmc: dw_mmc: add dw_mmc-k3 for k3 platform
Add dw_mmc-k3.c for k3v2, support sd/emmc Signed-off-by: Zhangfei Gao zhangfei@linaro.org Signed-off-by: Zhigang Wang brooke.wangzhig...@huawei.com --- .../devicetree/bindings/mmc/k3-dw-mshc.txt | 60 + drivers/mmc/host/Kconfig | 10 ++ drivers/mmc/host/Makefile |1 + drivers/mmc/host/dw_mmc-k3.c | 133 4 files changed, 204 insertions(+) create mode 100644 Documentation/devicetree/bindings/mmc/k3-dw-mshc.txt create mode 100644 drivers/mmc/host/dw_mmc-k3.c diff --git a/Documentation/devicetree/bindings/mmc/k3-dw-mshc.txt b/Documentation/devicetree/bindings/mmc/k3-dw-mshc.txt new file mode 100644 index ..d7e2d7f159bb --- /dev/null +++ b/Documentation/devicetree/bindings/mmc/k3-dw-mshc.txt @@ -0,0 +1,60 @@ +* Hisilicon specific extensions to the Synopsys Designware Mobile + Storage Host Controller + +Read synopsys-dw-mshc.txt for more details + +The Synopsys designware mobile storage host controller is used to interface +a SoC with storage medium such as eMMC or SD/MMC cards. This file documents +differences between the core Synopsys dw mshc controller properties described +by synopsys-dw-mshc.txt and the properties used by the Hisilicon specific +extensions to the Synopsys Designware Mobile Storage Host Controller. + +Required Properties: + +* compatible: should be one of the following. + - hisilicon,hi4511-dw-mshc: for controllers with hi4511 specific extentions. + +* clock-freq-table: should be the frequency (in Hz) array of the ciu clock + in each supported mode. + 0. CIU clock rate in Hz for DS mode + 1. CIU clock rate in Hz for MMC HS mode + 2. CIU clock rate in Hz for SD HS mode + 3. CIU clock rate in Hz for SDR12 mode + 4. CIU clock rate in Hz for SDR25 mode + 5. CIU clock rate in Hz for SDR50 mode + 6. CIU clock rate in Hz for SDR104 mode + 7. CIU clock rate in Hz for DDR50 mode + 8. CIU clock rate in Hz for HS200 mode + +Example: + + /* for Hi3620 */ + + /* SoC portion */ + dwmmc_0: dwmmc0@fcd03000 { + compatible = hisilicon,hi4511-dw-mshc; + reg = 0xfcd03000 0x1000; + interrupts = 0 16 4; + #address-cells = 1; + #size-cells = 0; + clocks = mmc_clock HI3620_SD_CIUCLK, clock HI3620_DDRC_PER_CLK; + clock-names = ciu, biu; + clock-freq-table = + 2500 0 5000 2500 5000 1 0 5000; + }; + + /* Board portion */ + dwmmc0@fcd03000 { + num-slots = 1; + vmmc-supply = ldo12; + fifo-depth = 0x100; + supports-highspeed; + pinctrl-names = default; + pinctrl-0 = sd_pmx_pins sd_cfg_func1 sd_cfg_func2; + slot@0 { + reg = 0; + bus-width = 4; + disable-wp; + cd-gpios = gpio10 3 0; + }; + }; diff --git a/drivers/mmc/host/Kconfig b/drivers/mmc/host/Kconfig index 7fc5099e44b2..45aaa2de0f58 100644 --- a/drivers/mmc/host/Kconfig +++ b/drivers/mmc/host/Kconfig @@ -575,6 +575,16 @@ config MMC_DW_SOCFPGA This selects support for Altera SoCFPGA specific extensions to the Synopsys DesignWare Memory Card Interface driver. +config MMC_DW_K3 + tristate K3 specific extensions for Synopsys DW Memory Card Interface + depends on MMC_DW + select MMC_DW_PLTFM + select MMC_DW_IDMAC + help + This selects support for Hisilicon K3 SoC specific extensions to the + Synopsys DesignWare Memory Card Interface driver. Select this option + for platforms based on Hisilicon K3 SoC's. + config MMC_DW_PCI tristate Synopsys Designware MCI support on PCI bus depends on MMC_DW PCI diff --git a/drivers/mmc/host/Makefile b/drivers/mmc/host/Makefile index c41d0c364509..64f5f8d35839 100644 --- a/drivers/mmc/host/Makefile +++ b/drivers/mmc/host/Makefile @@ -43,6 +43,7 @@ obj-$(CONFIG_MMC_DW) += dw_mmc.o obj-$(CONFIG_MMC_DW_PLTFM) += dw_mmc-pltfm.o obj-$(CONFIG_MMC_DW_EXYNOS)+= dw_mmc-exynos.o obj-$(CONFIG_MMC_DW_SOCFPGA) += dw_mmc-socfpga.o +obj-$(CONFIG_MMC_DW_K3)+= dw_mmc-k3.o obj-$(CONFIG_MMC_DW_PCI) += dw_mmc-pci.o obj-$(CONFIG_MMC_SH_MMCIF) += sh_mmcif.o obj-$(CONFIG_MMC_JZ4740) += jz4740_mmc.o diff --git a/drivers/mmc/host/dw_mmc-k3.c b/drivers/mmc/host/dw_mmc-k3.c new file mode 100644 index ..90ebee0ce5ef --- /dev/null +++ b/drivers/mmc/host/dw_mmc-k3.c @@ -0,0 +1,133 @@ +/* + * Copyright (c) 2013 Linaro Ltd. + * Copyright (c) 2013 Hisilicon Limited. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published
[PATCH 2/3] mmc: dw_mmc: add dw_mmc-k3 for k3 platform
Add dw_mmc-k3.c for k3v2, support sd/emmc Signed-off-by: Zhangfei Gao zhangfei@linaro.org Signed-off-by: Zhigang Wang brooke.wangzhig...@huawei.com --- .../devicetree/bindings/mmc/k3-dw-mshc.txt | 59 + drivers/mmc/host/Kconfig | 10 ++ drivers/mmc/host/Makefile |1 + drivers/mmc/host/dw_mmc-k3.c | 128 4 files changed, 198 insertions(+) create mode 100644 Documentation/devicetree/bindings/mmc/k3-dw-mshc.txt create mode 100644 drivers/mmc/host/dw_mmc-k3.c diff --git a/Documentation/devicetree/bindings/mmc/k3-dw-mshc.txt b/Documentation/devicetree/bindings/mmc/k3-dw-mshc.txt new file mode 100644 index ..5501c7c1138f --- /dev/null +++ b/Documentation/devicetree/bindings/mmc/k3-dw-mshc.txt @@ -0,0 +1,59 @@ +* Hisilicon specific extensions to the Synopsys Designware Mobile + Storage Host Controller + +Read synopsys-dw-mshc.txt for more details + +The Synopsys designware mobile storage host controller is used to interface +a SoC with storage medium such as eMMC or SD/MMC cards. This file documents +differences between the core Synopsys dw mshc controller properties described +by synopsys-dw-mshc.txt and the properties used by the Hisilicon specific +extensions to the Synopsys Designware Mobile Storage Host Controller. + +Required Properties: + +* compatible: should be one of the following. + - hisilicon,hi4511-dw-mshc: for controllers with hi4511 specific extentions. +* clock-freq-table: should be the frequency (in Hz) array of the ciu clock + in each supported timing mode. + 1. CIU clock rate in HZ for MMC_TIMING_LEGACY mode + 2. CIU clock rate in HZ for MMC_TIMING_MMC_HS mode + 3. CIU clock rate in HZ for MMC_TIMING_SD_HS mode + 4. CIU clock rate in HZ for MMC_TIMING_UHS_SDR12 mode + 5. CIU clock rate in HZ for MMC_TIMING_UHS_SDR25 mode + 6. CIU clock rate in HZ for MMC_TIMING_UHS_SDR50 mode + 7. CIU clock rate in HZ for MMC_TIMING_UHS_SDR104 mode + 8. CIU clock rate in HZ for MMC_TIMING_SD_HS mode + 9. CIU clock rate in HZ for MMC_TIMING_MMC_HS200 mode + +Example: + + /* for Hi3620 */ + + /* SoC portion */ + dwmmc_0: dwmmc0@fcd03000 { + compatible = hisilicon,hi4511-dw-mshc; + reg = 0xfcd03000 0x1000; + interrupts = 0 16 4; + #address-cells = 1; + #size-cells = 0; + clocks = mmc_clock HI3620_SD_CIUCLK, clock HI3620_DDRC_PER_CLK; + clock-names = ciu, biu; + clk-table = + 2500 0 5000 2500 5000 1 0 5000; + }; + + /* Board portion */ + dwmmc0@fcd03000 { + num-slots = 1; + vmmc-supply = ldo12; + fifo-depth = 0x100; + supports-highspeed; + pinctrl-names = default; + pinctrl-0 = sd_pmx_pins sd_cfg_func1 sd_cfg_func2; + slot@0 { + reg = 0; + bus-width = 4; + disable-wp; + cd-gpios = gpio10 3 0; + }; + }; diff --git a/drivers/mmc/host/Kconfig b/drivers/mmc/host/Kconfig index 7fc5099e44b2..45aaa2de0f58 100644 --- a/drivers/mmc/host/Kconfig +++ b/drivers/mmc/host/Kconfig @@ -575,6 +575,16 @@ config MMC_DW_SOCFPGA This selects support for Altera SoCFPGA specific extensions to the Synopsys DesignWare Memory Card Interface driver. +config MMC_DW_K3 + tristate K3 specific extensions for Synopsys DW Memory Card Interface + depends on MMC_DW + select MMC_DW_PLTFM + select MMC_DW_IDMAC + help + This selects support for Hisilicon K3 SoC specific extensions to the + Synopsys DesignWare Memory Card Interface driver. Select this option + for platforms based on Hisilicon K3 SoC's. + config MMC_DW_PCI tristate Synopsys Designware MCI support on PCI bus depends on MMC_DW PCI diff --git a/drivers/mmc/host/Makefile b/drivers/mmc/host/Makefile index c41d0c364509..64f5f8d35839 100644 --- a/drivers/mmc/host/Makefile +++ b/drivers/mmc/host/Makefile @@ -43,6 +43,7 @@ obj-$(CONFIG_MMC_DW) += dw_mmc.o obj-$(CONFIG_MMC_DW_PLTFM) += dw_mmc-pltfm.o obj-$(CONFIG_MMC_DW_EXYNOS)+= dw_mmc-exynos.o obj-$(CONFIG_MMC_DW_SOCFPGA) += dw_mmc-socfpga.o +obj-$(CONFIG_MMC_DW_K3)+= dw_mmc-k3.o obj-$(CONFIG_MMC_DW_PCI) += dw_mmc-pci.o obj-$(CONFIG_MMC_SH_MMCIF) += sh_mmcif.o obj-$(CONFIG_MMC_JZ4740) += jz4740_mmc.o diff --git a/drivers/mmc/host/dw_mmc-k3.c b/drivers/mmc/host/dw_mmc-k3.c new file mode 100644 index ..54b2503b211f --- /dev/null +++ b/drivers/mmc/host/dw_mmc-k3.c @@ -0,0 +1,128 @@ +/* + * Copyright (c) 2013 Linaro Ltd. + * Copyright (c) 2013 Hisilicon Limited. + * + * This program is free
[PATCH 3/3] clk: hisilicon: add hi3620_mmc_clks
hi3620_mmc_clks is added to handle mmc clock specifically on hi3620 Signed-off-by: Zhangfei Gao zhangfei@linaro.org --- .../bindings/arm/hisilicon/hisilicon.txt | 14 ++ .../devicetree/bindings/clock/hi3620-clock.txt |1 + drivers/clk/hisilicon/clk-hi3620.c | 262 include/dt-bindings/clock/hi3620-clock.h |5 + 4 files changed, 282 insertions(+) diff --git a/Documentation/devicetree/bindings/arm/hisilicon/hisilicon.txt b/Documentation/devicetree/bindings/arm/hisilicon/hisilicon.txt index 8c7a4653508d..df0a452b8526 100644 --- a/Documentation/devicetree/bindings/arm/hisilicon/hisilicon.txt +++ b/Documentation/devicetree/bindings/arm/hisilicon/hisilicon.txt @@ -30,3 +30,17 @@ Example: resume-offset = 0x308; reboot-offset = 0x4; }; + +PCTRL: Peripheral misc control register + +Required Properties: +- compatible: hisilicon,pctrl +- reg: Address and size of pctrl. + +Example: + + /* for Hi3620 */ + pctrl: pctrl@fca09000 { + compatible = hisilicon,pctrl; + reg = 0xfca09000 0x1000; + }; diff --git a/Documentation/devicetree/bindings/clock/hi3620-clock.txt b/Documentation/devicetree/bindings/clock/hi3620-clock.txt index 4b71ab41be53..dad6269f52c5 100644 --- a/Documentation/devicetree/bindings/clock/hi3620-clock.txt +++ b/Documentation/devicetree/bindings/clock/hi3620-clock.txt @@ -7,6 +7,7 @@ Required Properties: - compatible: should be one of the following. - hisilicon,hi3620-clock - controller compatible with Hi3620 SoC. + - hisilicon,hi3620-mmc-clock - controller specific for Hi3620 mmc. - reg: physical base address of the controller and length of memory mapped region. diff --git a/drivers/clk/hisilicon/clk-hi3620.c b/drivers/clk/hisilicon/clk-hi3620.c index f24ad6a3a797..eeb89b7a3507 100644 --- a/drivers/clk/hisilicon/clk-hi3620.c +++ b/drivers/clk/hisilicon/clk-hi3620.c @@ -240,3 +240,265 @@ static void __init hi3620_clk_init(struct device_node *np) base); } CLK_OF_DECLARE(hi3620_clk, hisilicon,hi3620-clock, hi3620_clk_init); + +struct hisi_mmc_clock { + unsigned intid; + const char *name; + const char *parent_name; + unsigned long flags; + u32 clken_reg; + u32 clken_bit; + u32 div_reg; + u32 div_off; + u32 div_bits; + u32 drv_reg; + u32 drv_off; + u32 drv_bits; + u32 sam_reg; + u32 sam_off; + u32 sam_bits; +}; + +struct clk_mmc { + struct clk_hw hw; + u32 id; + void __iomem*clken_reg; + u32 clken_bit; + void __iomem*div_reg; + u32 div_off; + u32 div_bits; + void __iomem*drv_reg; + u32 drv_off; + u32 drv_bits; + void __iomem*sam_reg; + u32 sam_off; + u32 sam_bits; +}; + +#define to_mmc(_hw) container_of(_hw, struct clk_mmc, hw) + +static struct hisi_mmc_clock hi3620_mmc_clks[] __initdata = { + { HI3620_SD_CIUCLK, sd_bclk1, sd_clk, CLK_SET_RATE_PARENT, 0x1f8, 0, 0x1f8, 1, 3, 0x1f8, 4, 4, 0x1f8, 8, 4}, + { HI3620_MMC_CIUCLK1, mmc_bclk1, mmc_clk1, CLK_SET_RATE_PARENT, 0x1f8, 12, 0x1f8, 13, 3, 0x1f8, 16, 4, 0x1f8, 20, 4}, + { HI3620_MMC_CIUCLK2, mmc_bclk2, mmc_clk2, CLK_SET_RATE_PARENT, 0x1f8, 24, 0x1f8, 25, 3, 0x1f8, 28, 4, 0x1fc, 0, 4}, + { HI3620_MMC_CIUCLK3, mmc_bclk3, mmc_clk3, CLK_SET_RATE_PARENT, 0x1fc, 4, 0x1fc, 5, 3, 0x1fc, 8, 4, 0x1fc, 12, 4}, +}; + +static unsigned long mmc_clk_recalc_rate(struct clk_hw *hw, + unsigned long parent_rate) +{ + switch (parent_rate) { + case 2600: + return 1300; + case 18000: + return 2500; + case 36000: + return 5000; + case 72000: + return 1; + default: + return parent_rate; + } +} + +static long mmc_clk_determine_rate(struct clk_hw *hw, unsigned long rate, + unsigned long *best_parent_rate, + struct clk **best_parent_p) +{ + unsigned long best = 0; + + if (rate = 1300) { + rate = 1300; + best = 2600; + } else if (rate = 2500) { + rate = 2500; + best = 18000; + } else if (rate = 5000) { + rate = 5000; + best = 36000; + } else if (rate = 1) { + rate = 1; + best
[PATCH v4 0/3] mmc: dw_mmc: add dw_mmc-k3
v4: Follow Arnd's suggestion abstracting specific tuning to clock, also because new version ip use different method and not use same tuning registers. 0001 acked by Jaehoon v3: 0001: Put set/clear_bit DW_MMC_CARD_PRESENT in dw_mci_get_cd, Since dw_mci_request will check DW_MMC_CARD_PRESENT before sending cmd 0002: Follow suggestion from Chris, Kumar and Seungwon Sync to latest mmc-next, which is 3.12-rc2 Remove enum dw_mci_k3_type etc v2: Follow Jaehoon's suggestion Use slot-gpio.c handle cd pin Move table out to dts other suggestion Zhangfei Gao (3): mmc: dw_mmc: use slot-gpio to handle cd pin mmc: dw_mmc: add dw_mmc-k3 for k3 platform clk: hisilicon: add hi3620_mmc_clks .../bindings/arm/hisilicon/hisilicon.txt | 14 ++ .../devicetree/bindings/clock/hi3620-clock.txt |1 + .../devicetree/bindings/mmc/k3-dw-mshc.txt | 51 drivers/clk/hisilicon/clk-hi3620.c | 266 drivers/mmc/host/Kconfig | 10 + drivers/mmc/host/Makefile |1 + drivers/mmc/host/dw_mmc-k3.c | 136 ++ drivers/mmc/host/dw_mmc.c | 48 +++- include/dt-bindings/clock/hi3620-clock.h |5 + 9 files changed, 519 insertions(+), 13 deletions(-) create mode 100644 Documentation/devicetree/bindings/mmc/k3-dw-mshc.txt create mode 100644 drivers/mmc/host/dw_mmc-k3.c -- 1.7.9.5 -- To unsubscribe from this list: send the line unsubscribe linux-mmc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 1/3] mmc: dw_mmc: use slot-gpio to handle cd pin
Suggested by Jaehoon: Use slot-gpio to handle cd-gpio Add function dw_mci_of_get_cd_gpio to check cd-gpios from dts. mmc_gpio_request_cd and mmc_gpio_get_cd are used to handle cd pin Signed-off-by: Zhangfei Gao zhangfei@linaro.org Acked-by: Jaehoon Chung jh80.ch...@samsung.com --- drivers/mmc/host/dw_mmc.c | 48 + 1 file changed, 35 insertions(+), 13 deletions(-) diff --git a/drivers/mmc/host/dw_mmc.c b/drivers/mmc/host/dw_mmc.c index 4bce0deec362..a776f24f4311 100644 --- a/drivers/mmc/host/dw_mmc.c +++ b/drivers/mmc/host/dw_mmc.c @@ -36,6 +36,7 @@ #include linux/workqueue.h #include linux/of.h #include linux/of_gpio.h +#include linux/mmc/slot-gpio.h #include dw_mmc.h @@ -1032,20 +1033,26 @@ static int dw_mci_get_cd(struct mmc_host *mmc) int present; struct dw_mci_slot *slot = mmc_priv(mmc); struct dw_mci_board *brd = slot-host-pdata; + int gpio_cd = !mmc_gpio_get_cd(mmc); /* Use platform get_cd function, else try onboard card detect */ if (brd-quirks DW_MCI_QUIRK_BROKEN_CARD_DETECTION) present = 1; else if (brd-get_cd) present = !brd-get_cd(slot-id); + else if (!IS_ERR_VALUE(gpio_cd)) + present = !!gpio_cd; else present = (mci_readl(slot-host, CDETECT) (1 slot-id)) == 0 ? 1 : 0; - if (present) + if (present) { + set_bit(DW_MMC_CARD_PRESENT, slot-flags); dev_dbg(mmc-class_dev, card is present\n); - else + } else { + clear_bit(DW_MMC_CARD_PRESENT, slot-flags); dev_dbg(mmc-class_dev, card is not present\n); + } return present; } @@ -1926,10 +1933,6 @@ static void dw_mci_work_routine_card(struct work_struct *work) /* Card change detected */ slot-last_detect_state = present; - /* Mark card as present if applicable */ - if (present != 0) - set_bit(DW_MMC_CARD_PRESENT, slot-flags); - /* Clean up queue if present */ mrq = slot-mrq; if (mrq) { @@ -1977,8 +1980,6 @@ static void dw_mci_work_routine_card(struct work_struct *work) /* Power down slot */ if (present == 0) { - clear_bit(DW_MMC_CARD_PRESENT, slot-flags); - /* Clear down the FIFO */ dw_mci_fifo_reset(host); #ifdef CONFIG_MMC_DW_IDMAC @@ -2079,6 +2080,26 @@ static int dw_mci_of_get_wp_gpio(struct device *dev, u8 slot) return gpio; } + +/* find the cd gpio for a given slot; or -1 if none specified */ +static void dw_mci_of_get_cd_gpio(struct device *dev, u8 slot, + struct mmc_host *mmc) +{ + struct device_node *np = dw_mci_of_find_slot_node(dev, slot); + int gpio; + + if (!np) + return; + + gpio = of_get_named_gpio(np, cd-gpios, 0); + + /* Having a missing entry is valid; return silently */ + if (!gpio_is_valid(gpio)) + return; + + if (mmc_gpio_request_cd(mmc, gpio, 0)) + dev_warn(dev, gpio [%d] request failed\n, gpio); +} #else /* CONFIG_OF */ static int dw_mci_of_get_slot_quirks(struct device *dev, u8 slot) { @@ -2096,6 +2117,11 @@ static int dw_mci_of_get_wp_gpio(struct device *dev, u8 slot) { return -EINVAL; } +static void dw_mci_of_get_cd_gpio(struct device *dev, u8 slot, + struct mmc_host *mmc) +{ + return; +} #endif /* CONFIG_OF */ static int dw_mci_init_slot(struct dw_mci *host, unsigned int id) @@ -2197,12 +2223,8 @@ static int dw_mci_init_slot(struct dw_mci *host, unsigned int id) #endif /* CONFIG_MMC_DW_IDMAC */ } - if (dw_mci_get_cd(mmc)) - set_bit(DW_MMC_CARD_PRESENT, slot-flags); - else - clear_bit(DW_MMC_CARD_PRESENT, slot-flags); - slot-wp_gpio = dw_mci_of_get_wp_gpio(host-dev, slot-id); + dw_mci_of_get_cd_gpio(host-dev, slot-id, mmc); ret = mmc_add_host(mmc); if (ret) -- 1.7.9.5 -- To unsubscribe from this list: send the line unsubscribe linux-mmc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 2/3] mmc: dw_mmc: add dw_mmc-k3 for k3 platform
Add dw_mmc-k3.c for k3v2, support sd/emmc Signed-off-by: Zhangfei Gao zhangfei@linaro.org Tested-by: Zhigang Wang brooke.wangzhig...@huawei.com --- .../devicetree/bindings/mmc/k3-dw-mshc.txt | 51 drivers/mmc/host/Kconfig | 10 ++ drivers/mmc/host/Makefile |1 + drivers/mmc/host/dw_mmc-k3.c | 136 4 files changed, 198 insertions(+) create mode 100644 Documentation/devicetree/bindings/mmc/k3-dw-mshc.txt create mode 100644 drivers/mmc/host/dw_mmc-k3.c diff --git a/Documentation/devicetree/bindings/mmc/k3-dw-mshc.txt b/Documentation/devicetree/bindings/mmc/k3-dw-mshc.txt new file mode 100644 index ..d816b89c386a --- /dev/null +++ b/Documentation/devicetree/bindings/mmc/k3-dw-mshc.txt @@ -0,0 +1,51 @@ +* Hisilicon specific extensions to the Synopsys Designware Mobile + Storage Host Controller + +Read synopsys-dw-mshc.txt for more details + +The Synopsys designware mobile storage host controller is used to interface +a SoC with storage medium such as eMMC or SD/MMC cards. This file documents +differences between the core Synopsys dw mshc controller properties described +by synopsys-dw-mshc.txt and the properties used by the Hisilicon specific +extensions to the Synopsys Designware Mobile Storage Host Controller. + +Required Properties: + +* compatible: should be one of the following. + - hisilicon,hi4511-dw-mshc: for controllers with hi4511 specific extentions. +* clk-table-num: should be number of clks in clk-table required by each mmc timing +* clk-table: should clock list required by each mmc timing + +Example: + + /* for Hi3620 */ + + /* SoC portion */ + dwmmc_0: dwmmc0@fcd03000 { + compatible = hisilicon,hi4511-dw-mshc; + reg = 0xfcd03000 0x1000; + interrupts = 0 16 4; + #address-cells = 1; + #size-cells = 0; + clocks = mmc_clock HI3620_SD_CIUCLK, clock HI3620_DDRC_PER_CLK; + clock-names = ciu, biu; + clk-table-num = 8; + clk-table = + 1300 5000 0 0 1300 5000 0 1; + }; + + /* Board portion */ + dwmmc0@fcd03000 { + num-slots = 1; + vmmc-supply = ldo12; + fifo-depth = 0x100; + supports-highspeed; + pinctrl-names = default; + pinctrl-0 = sd_pmx_pins sd_cfg_func1 sd_cfg_func2; + slot@0 { + reg = 0; + bus-width = 4; + disable-wp; + cd-gpios = gpio10 3 0; + }; + }; diff --git a/drivers/mmc/host/Kconfig b/drivers/mmc/host/Kconfig index 7fc5099e44b2..45aaa2de0f58 100644 --- a/drivers/mmc/host/Kconfig +++ b/drivers/mmc/host/Kconfig @@ -575,6 +575,16 @@ config MMC_DW_SOCFPGA This selects support for Altera SoCFPGA specific extensions to the Synopsys DesignWare Memory Card Interface driver. +config MMC_DW_K3 + tristate K3 specific extensions for Synopsys DW Memory Card Interface + depends on MMC_DW + select MMC_DW_PLTFM + select MMC_DW_IDMAC + help + This selects support for Hisilicon K3 SoC specific extensions to the + Synopsys DesignWare Memory Card Interface driver. Select this option + for platforms based on Hisilicon K3 SoC's. + config MMC_DW_PCI tristate Synopsys Designware MCI support on PCI bus depends on MMC_DW PCI diff --git a/drivers/mmc/host/Makefile b/drivers/mmc/host/Makefile index c41d0c364509..64f5f8d35839 100644 --- a/drivers/mmc/host/Makefile +++ b/drivers/mmc/host/Makefile @@ -43,6 +43,7 @@ obj-$(CONFIG_MMC_DW) += dw_mmc.o obj-$(CONFIG_MMC_DW_PLTFM) += dw_mmc-pltfm.o obj-$(CONFIG_MMC_DW_EXYNOS)+= dw_mmc-exynos.o obj-$(CONFIG_MMC_DW_SOCFPGA) += dw_mmc-socfpga.o +obj-$(CONFIG_MMC_DW_K3)+= dw_mmc-k3.o obj-$(CONFIG_MMC_DW_PCI) += dw_mmc-pci.o obj-$(CONFIG_MMC_SH_MMCIF) += sh_mmcif.o obj-$(CONFIG_MMC_JZ4740) += jz4740_mmc.o diff --git a/drivers/mmc/host/dw_mmc-k3.c b/drivers/mmc/host/dw_mmc-k3.c new file mode 100644 index ..08fd7d7bbb23 --- /dev/null +++ b/drivers/mmc/host/dw_mmc-k3.c @@ -0,0 +1,136 @@ +/* + * Copyright (c) 2013 Linaro Ltd. + * Copyright (c) 2013 Hisilicon Limited. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + */ + +#include linux/module.h +#include linux/platform_device.h +#include linux/clk.h +#include linux/mmc/host.h +#include linux/mmc/dw_mmc.h +#include linux/of_address.h + +#include dw_mmc.h +#include dw_mmc-pltfm.h + +#define MAX_NUMS 10 +struct
Re: [PATCH 2/2] mmc: dw_mmc: add dw_mmc-k3 for k3 platform
Dear Arnd On Fri, Dec 6, 2013 at 9:39 AM, Arnd Bergmann a...@arndb.de wrote: On Friday 08 November 2013, Zhangfei Gao wrote: Add dw_mmc-k3.c for k3v2, support sd/emmc Signed-off-by: Zhangfei Gao zhangfei@linaro.org Tested-by: Zhigang Wang brooke.wangzhig...@huawei.com We are currently having the exact same discussion problem on the altera version of dw_mmc: It seems that all this driver does in addition to the common code is to have a custom way to set up the card clocks. In both cases, there is a custom piece of IP logic providing this clock (here it is in the hisilicon,pctrl node). IMHO that should be a proper clock driver so you can use the existing call to clk_set_rate to set it up and not need a special platform driver at all. Thanks for the good suggestion, it can be abstracted to clock. The issue for this version's ip is there are some registers need to be set, including fixed factor and phase, which may be required to be tuned, however it can be hide in clock. Double checked next version's ip, it is more intelligent and only fixed factor is required, more like a clock, and all these register accessing are NOT required. Will update new version to abstract these chip depended registers to clock. Thanks -- To unsubscribe from this list: send the line unsubscribe linux-mmc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 2/2] mmc: dw_mmc: add dw_mmc-k3 for k3 platform
Dear Seungwon On Thu, Dec 5, 2013 at 10:00 PM, Seungwon Jeon tgih@samsung.com wrote: +static DEFINE_SPINLOCK(mmc_tuning_lock); Can the above variables be involved in dw_mci_k3_priv_data instead of global declaration? Unfortunately, this can be be put in priv_data, which is different instance for different controller. Here need protect register shared by different controllers +static int dw_mci_k3_setup_clock(struct dw_mci *host) +{ + dw_mci_k3_tun(host, MMC_TIMING_LEGACY); Is it necessary here? When card-init, MMC_TIMING_LEGACY will be passed via dw_mci_k3_set_ios(). Read register will fail if not set these register earlier, and set_ios is too late. Same reason for resume. Thanks -- To unsubscribe from this list: send the line unsubscribe linux-mmc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 2/2] mmc: dw_mmc: add dw_mmc-k3 for k3 platform
Dear Rob On Thu, Dec 5, 2013 at 10:29 PM, Rob Herring robherri...@gmail.com wrote: On Thu, Nov 7, 2013 at 11:38 PM, Zhangfei Gao zhangfei@linaro.org wrote: +++ b/Documentation/devicetree/bindings/mmc/k3-dw-mshc.txt @@ -0,0 +1,83 @@ +* Hisilicon specific extensions to the Synopsys Designware Mobile + Storage Host Controller + +Read synopsis-dw-mshc.txt for more details +The Synopsys designware mobile storage host controller is used to interface +a SoC with storage medium such as eMMC or SD/MMC cards. This file documents +differences between the core Synopsys dw mshc controller properties described +by synopsis-dw-mshc.txt and the properties used by the Hisilicon specific +extensions to the Synopsys Designware Mobile Storage Host Controller. + +Required Properties: + +* compatible: should be + - hisilicon,hi4511-dw-mshc: for controllers with hi4511 + specific extentions. +* reg: should be address and size of mmc controller This should be covered by the base binding. Yes, got it. +* vmmc-supply: should be vmmc used in dwmmc +* fifo-depth: should be provided if register can not provide correct value +* tuning-table: should be array to tune mmc controller, including clock rate + to be set and values for setting optional register. Please define the size and what the values mean. + +Optional properties: + +/* These registers from pctrl node used for tuning mmc controller if required */ +* clken-reg: should be clock enable register and offset bit +* drv-sel-reg: should be driver delay select register, start bit and bits numbers +* sam-sel-reg: should be sample delay select register, start bit and bits numbers +* div-reg: should be divider register, start bit and bits numbers Do these really vary on different boards or versions of the IP? If not, then put this information in the kernel. Otherwise, these need better description such as number of words and order of values. Double checked these registers are not used in newer version. Will follow Arnd's suggestion to abstract in clock. + + /* Board portion */ + dwmmc0@fcd03000 { + num-slots = 1; + vmmc-supply = ldo12; + fifo-depth = 0x100; + supports-highspeed; Please reference that the binding uses standard SD properties (state which binding document). Documentation/devicetree/bindings/mmc/synopsys-dw-mshc.txt is used for base doc describing supports-highspeed. + pinctrl-names = default; + pinctrl-0 = sd_pmx_pins sd_cfg_func1 sd_cfg_func2; + slot@0 { + reg = 0; + bus-width = 4; + disable-wp; + cd-gpios = gpio10 3 0; + }; + }; + +PCTRL: Peripheral misc control register Is this only MMC control bits? Seems like this belongs in its own doc. OK, will move out. Thanks -- To unsubscribe from this list: send the line unsubscribe linux-mmc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 1/2] mmc: dw_mmc: add dw_mci_of_get_cd_gpio to handle cd pin
Change function dw_mci_of_get_cd_gpio type to void suggested by Jaehoon And check any other comments Thanks Add function dw_mci_of_get_cd_gpio to check cd-gpios from dts. mmc_gpio_request_cd and mmc_gpio_get_cd are used to handle cd pin Signed-off-by: Zhangfei Gao zhangfei@linaro.org CC: Jaehoon Chung jh80.ch...@samsung.com --- drivers/mmc/host/dw_mmc.c | 48 + 1 file changed, 35 insertions(+), 13 deletions(-) diff --git a/drivers/mmc/host/dw_mmc.c b/drivers/mmc/host/dw_mmc.c index 4bce0de..a776f24 100644 --- a/drivers/mmc/host/dw_mmc.c +++ b/drivers/mmc/host/dw_mmc.c @@ -36,6 +36,7 @@ #include linux/workqueue.h #include linux/of.h #include linux/of_gpio.h +#include linux/mmc/slot-gpio.h #include dw_mmc.h @@ -1032,20 +1033,26 @@ static int dw_mci_get_cd(struct mmc_host *mmc) int present; struct dw_mci_slot *slot = mmc_priv(mmc); struct dw_mci_board *brd = slot-host-pdata; + int gpio_cd = !mmc_gpio_get_cd(mmc); /* Use platform get_cd function, else try onboard card detect */ if (brd-quirks DW_MCI_QUIRK_BROKEN_CARD_DETECTION) present = 1; else if (brd-get_cd) present = !brd-get_cd(slot-id); + else if (!IS_ERR_VALUE(gpio_cd)) + present = !!gpio_cd; else present = (mci_readl(slot-host, CDETECT) (1 slot-id)) == 0 ? 1 : 0; - if (present) + if (present) { + set_bit(DW_MMC_CARD_PRESENT, slot-flags); dev_dbg(mmc-class_dev, card is present\n); - else + } else { + clear_bit(DW_MMC_CARD_PRESENT, slot-flags); dev_dbg(mmc-class_dev, card is not present\n); + } return present; } @@ -1926,10 +1933,6 @@ static void dw_mci_work_routine_card(struct work_struct *work) /* Card change detected */ slot-last_detect_state = present; - /* Mark card as present if applicable */ - if (present != 0) - set_bit(DW_MMC_CARD_PRESENT, slot-flags); - /* Clean up queue if present */ mrq = slot-mrq; if (mrq) { @@ -1977,8 +1980,6 @@ static void dw_mci_work_routine_card(struct work_struct *work) /* Power down slot */ if (present == 0) { - clear_bit(DW_MMC_CARD_PRESENT, slot-flags); - /* Clear down the FIFO */ dw_mci_fifo_reset(host); #ifdef CONFIG_MMC_DW_IDMAC @@ -2079,6 +2080,26 @@ static int dw_mci_of_get_wp_gpio(struct device *dev, u8 slot) return gpio; } + +/* find the cd gpio for a given slot; or -1 if none specified */ +static void dw_mci_of_get_cd_gpio(struct device *dev, u8 slot, + struct mmc_host *mmc) +{ + struct device_node *np = dw_mci_of_find_slot_node(dev, slot); + int gpio; + + if (!np) + return; + + gpio = of_get_named_gpio(np, cd-gpios, 0); + + /* Having a missing entry is valid; return silently */ + if (!gpio_is_valid(gpio)) + return; + + if (mmc_gpio_request_cd(mmc, gpio, 0)) + dev_warn(dev, gpio [%d] request failed\n, gpio); +} #else /* CONFIG_OF */ static int dw_mci_of_get_slot_quirks(struct device *dev, u8 slot) { @@ -2096,6 +2117,11 @@ static int dw_mci_of_get_wp_gpio(struct device *dev, u8 slot) { return -EINVAL; } +static void dw_mci_of_get_cd_gpio(struct device *dev, u8 slot, + struct mmc_host *mmc) +{ + return; +} #endif /* CONFIG_OF */ static int dw_mci_init_slot(struct dw_mci *host, unsigned int id) @@ -2197,12 +2223,8 @@ static int dw_mci_init_slot(struct dw_mci *host, unsigned int id) #endif /* CONFIG_MMC_DW_IDMAC */ } - if (dw_mci_get_cd(mmc)) - set_bit(DW_MMC_CARD_PRESENT, slot-flags); - else - clear_bit(DW_MMC_CARD_PRESENT, slot-flags); - slot-wp_gpio = dw_mci_of_get_wp_gpio(host-dev, slot-id); + dw_mci_of_get_cd_gpio(host-dev, slot-id, mmc); ret = mmc_add_host(mmc); if (ret) -- 1.7.9.5 -- To unsubscribe from this list: send the line unsubscribe linux-mmc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 1/2] mmc: dw_mmc: add dw_mci_of_get_cd_gpio to handle cd pin
Add function dw_mci_of_get_cd_gpio to check cd-gpios from dts. mmc_gpio_request_cd and mmc_gpio_get_cd are used to handle cd pin Signed-off-by: Zhangfei Gao zhangfei@linaro.org CC: Jaehoon Chung jh80.ch...@samsung.com --- drivers/mmc/host/dw_mmc.c | 52 + 1 file changed, 39 insertions(+), 13 deletions(-) diff --git a/drivers/mmc/host/dw_mmc.c b/drivers/mmc/host/dw_mmc.c index 4bce0de..0d5ad80 100644 --- a/drivers/mmc/host/dw_mmc.c +++ b/drivers/mmc/host/dw_mmc.c @@ -36,6 +36,7 @@ #include linux/workqueue.h #include linux/of.h #include linux/of_gpio.h +#include linux/mmc/slot-gpio.h #include dw_mmc.h @@ -1032,20 +1033,26 @@ static int dw_mci_get_cd(struct mmc_host *mmc) int present; struct dw_mci_slot *slot = mmc_priv(mmc); struct dw_mci_board *brd = slot-host-pdata; + int gpio_cd = !mmc_gpio_get_cd(mmc); /* Use platform get_cd function, else try onboard card detect */ if (brd-quirks DW_MCI_QUIRK_BROKEN_CARD_DETECTION) present = 1; else if (brd-get_cd) present = !brd-get_cd(slot-id); + else if (!IS_ERR_VALUE(gpio_cd)) + present = !!gpio_cd; else present = (mci_readl(slot-host, CDETECT) (1 slot-id)) == 0 ? 1 : 0; - if (present) + if (present) { + set_bit(DW_MMC_CARD_PRESENT, slot-flags); dev_dbg(mmc-class_dev, card is present\n); - else + } else { + clear_bit(DW_MMC_CARD_PRESENT, slot-flags); dev_dbg(mmc-class_dev, card is not present\n); + } return present; } @@ -1926,10 +1933,6 @@ static void dw_mci_work_routine_card(struct work_struct *work) /* Card change detected */ slot-last_detect_state = present; - /* Mark card as present if applicable */ - if (present != 0) - set_bit(DW_MMC_CARD_PRESENT, slot-flags); - /* Clean up queue if present */ mrq = slot-mrq; if (mrq) { @@ -1977,8 +1980,6 @@ static void dw_mci_work_routine_card(struct work_struct *work) /* Power down slot */ if (present == 0) { - clear_bit(DW_MMC_CARD_PRESENT, slot-flags); - /* Clear down the FIFO */ dw_mci_fifo_reset(host); #ifdef CONFIG_MMC_DW_IDMAC @@ -2079,6 +2080,30 @@ static int dw_mci_of_get_wp_gpio(struct device *dev, u8 slot) return gpio; } + +/* find the cd gpio for a given slot; or -1 if none specified */ +static int dw_mci_of_get_cd_gpio(struct device *dev, u8 slot, + struct mmc_host *mmc) +{ + struct device_node *np = dw_mci_of_find_slot_node(dev, slot); + int gpio; + + if (!np) + return -EINVAL; + + gpio = of_get_named_gpio(np, cd-gpios, 0); + + /* Having a missing entry is valid; return silently */ + if (!gpio_is_valid(gpio)) + return -EINVAL; + + if (mmc_gpio_request_cd(mmc, gpio, 0)) { + dev_warn(dev, gpio [%d] request failed\n, gpio); + return -EINVAL; + } + + return gpio; +} #else /* CONFIG_OF */ static int dw_mci_of_get_slot_quirks(struct device *dev, u8 slot) { @@ -2096,6 +2121,11 @@ static int dw_mci_of_get_wp_gpio(struct device *dev, u8 slot) { return -EINVAL; } +static int dw_mci_of_get_cd_gpio(struct device *dev, u8 slot, + struct mmc_host *mmc) +{ + return -EINVAL; +} #endif /* CONFIG_OF */ static int dw_mci_init_slot(struct dw_mci *host, unsigned int id) @@ -2197,12 +2227,8 @@ static int dw_mci_init_slot(struct dw_mci *host, unsigned int id) #endif /* CONFIG_MMC_DW_IDMAC */ } - if (dw_mci_get_cd(mmc)) - set_bit(DW_MMC_CARD_PRESENT, slot-flags); - else - clear_bit(DW_MMC_CARD_PRESENT, slot-flags); - slot-wp_gpio = dw_mci_of_get_wp_gpio(host-dev, slot-id); + dw_mci_of_get_cd_gpio(host-dev, slot-id, mmc); ret = mmc_add_host(mmc); if (ret) -- 1.7.9.5 -- To unsubscribe from this list: send the line unsubscribe linux-mmc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v3 0/2] mmc: dw_mmc: add dw_mmc-k3
v3: 0001: Put set/clear_bit DW_MMC_CARD_PRESENT in dw_mci_get_cd, Since dw_mci_request will check DW_MMC_CARD_PRESENT before sending cmd 0002: Follow suggestion from Chris, Kumar and Seungwon Sync to latest mmc-next, which is 3.12-rc2 Remove enum dw_mci_k3_type etc v2: Follow Jaehoon's suggestion Use slot-gpio.c handle cd pin Move table out to dts other suggestion Zhangfei Gao (2): mmc: dw_mmc: add dw_mci_of_get_cd_gpio to handle cd pin mmc: dw_mmc: add dw_mmc-k3 for k3 platform .../devicetree/bindings/mmc/k3-dw-mshc.txt | 83 +++ drivers/mmc/host/Kconfig | 10 + drivers/mmc/host/Makefile |1 + drivers/mmc/host/dw_mmc-k3.c | 247 drivers/mmc/host/dw_mmc.c | 52 +++-- 5 files changed, 380 insertions(+), 13 deletions(-) create mode 100644 Documentation/devicetree/bindings/mmc/k3-dw-mshc.txt create mode 100644 drivers/mmc/host/dw_mmc-k3.c -- 1.7.9.5 -- To unsubscribe from this list: send the line unsubscribe linux-mmc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 2/2] mmc: dw_mmc: add dw_mmc-k3 for k3 platform
Add dw_mmc-k3.c for k3v2, support sd/emmc Signed-off-by: Zhangfei Gao zhangfei@linaro.org Tested-by: Zhigang Wang brooke.wangzhig...@huawei.com --- .../devicetree/bindings/mmc/k3-dw-mshc.txt | 83 +++ drivers/mmc/host/Kconfig | 10 + drivers/mmc/host/Makefile |1 + drivers/mmc/host/dw_mmc-k3.c | 247 4 files changed, 341 insertions(+) create mode 100644 Documentation/devicetree/bindings/mmc/k3-dw-mshc.txt create mode 100644 drivers/mmc/host/dw_mmc-k3.c diff --git a/Documentation/devicetree/bindings/mmc/k3-dw-mshc.txt b/Documentation/devicetree/bindings/mmc/k3-dw-mshc.txt new file mode 100644 index 000..ea858f4 --- /dev/null +++ b/Documentation/devicetree/bindings/mmc/k3-dw-mshc.txt @@ -0,0 +1,83 @@ +* Hisilicon specific extensions to the Synopsys Designware Mobile + Storage Host Controller + +Read synopsis-dw-mshc.txt for more details +The Synopsys designware mobile storage host controller is used to interface +a SoC with storage medium such as eMMC or SD/MMC cards. This file documents +differences between the core Synopsys dw mshc controller properties described +by synopsis-dw-mshc.txt and the properties used by the Hisilicon specific +extensions to the Synopsys Designware Mobile Storage Host Controller. + +Required Properties: + +* compatible: should be + - hisilicon,hi4511-dw-mshc: for controllers with hi4511 + specific extentions. +* reg: should be address and size of mmc controller +* vmmc-supply: should be vmmc used in dwmmc +* fifo-depth: should be provided if register can not provide correct value +* tuning-table: should be array to tune mmc controller, including clock rate + to be set and values for setting optional register. + +Optional properties: + +/* These registers from pctrl node used for tuning mmc controller if required */ +* clken-reg: should be clock enable register and offset bit +* drv-sel-reg: should be driver delay select register, start bit and bits numbers +* sam-sel-reg: should be sample delay select register, start bit and bits numbers +* div-reg: should be divider register, start bit and bits numbers + +Example: + + /* SoC portion */ + dwmmc_0: dwmmc0@fcd03000 { + compatible = hisilicon,hi4511-dw-mshc; + reg = 0xfcd03000 0x1000; + interrupts = 0 16 4; + #address-cells = 1; + #size-cells = 0; + clocks = clk_sd, clk_ddrc_per; + clock-names = ciu, biu; + clken-reg = 0x1f8 0; + drv-sel-reg = 0x1f8 4 4; + sam-sel-reg = 0x1f8 8 4; + div-reg = 0x1f8 1 3; + tuning-table = + 18000 6 6 13 13 2500, + 0 0 0 0 0 0, + 36000 6 4 2 0 5000, + 18000 6 4 13 13 2500, + 36000 6 4 2 0 5000, + 72000 6 1 9 4 1, + 0 0 0 0 0 0, + 36000 7 1 3 0 5000; + }; + + /* Board portion */ + dwmmc0@fcd03000 { + num-slots = 1; + vmmc-supply = ldo12; + fifo-depth = 0x100; + supports-highspeed; + pinctrl-names = default; + pinctrl-0 = sd_pmx_pins sd_cfg_func1 sd_cfg_func2; + slot@0 { + reg = 0; + bus-width = 4; + disable-wp; + cd-gpios = gpio10 3 0; + }; + }; + +PCTRL: Peripheral misc control register + +Required Properties: +- compatible: hisilicon,pctrl +- reg: Address and size of pctrl. + +Example: + + pctrl: pctrl@fca09000 { + compatible = hisilicon,pctrl; + reg = 0xfca09000 0x1000; + }; diff --git a/drivers/mmc/host/Kconfig b/drivers/mmc/host/Kconfig index 7fc5099..45aaa2d 100644 --- a/drivers/mmc/host/Kconfig +++ b/drivers/mmc/host/Kconfig @@ -575,6 +575,16 @@ config MMC_DW_SOCFPGA This selects support for Altera SoCFPGA specific extensions to the Synopsys DesignWare Memory Card Interface driver. +config MMC_DW_K3 + tristate K3 specific extensions for Synopsys DW Memory Card Interface + depends on MMC_DW + select MMC_DW_PLTFM + select MMC_DW_IDMAC + help + This selects support for Hisilicon K3 SoC specific extensions to the + Synopsys DesignWare Memory Card Interface driver. Select this option + for platforms based on Hisilicon K3 SoC's. + config MMC_DW_PCI tristate Synopsys Designware MCI support on PCI bus depends on MMC_DW PCI diff --git a/drivers/mmc/host/Makefile b/drivers/mmc/host/Makefile index c41d0c3..64f5f8d 100644 --- a/drivers/mmc/host/Makefile +++ b/drivers/mmc/host/Makefile @@ -43,6 +43,7 @@ obj-$(CONFIG_MMC_DW) += dw_mmc.o obj
Re: [PATCH 2/2] mmc: dw_mmc: add dw_mmc-k3 for k3 platform
Dear Seungwon Thanks for giving suggestion. On Thu, Oct 31, 2013 at 11:24 PM, Seungwon Jeon tgih@samsung.com wrote: Hi Zhangfei, +static void dw_mci_k3_set_ios(struct dw_mci *host, struct mmc_ios *ios) +{ + struct dw_mci_k3_priv_data *priv = host-priv; + + if (priv-type == DW_MCI_TYPE_HI4511) There are several checking controller type. But now DW_MCI_TYPE_HI4511 is just introduced alone. It seems like unnecessary. Yes, currently only K3V2 is added, and k3v3 code will be added soon. Do you think type is more suitable to add later? +static int dw_mci_k3_parse_dt(struct dw_mci *host) +{ + struct dw_mci_k3_priv_data *priv = host-priv; + struct device_node *np = host-dev-of_node; + u32 data[3]; + int ret; + + if (priv-type == DW_MCI_TYPE_HI4511) { Didn't you see Kernel panic here? host-priv is not allocated yet, it's a invalid pointer dereference. dw_mci_k3_parse_dt() is called prior to dw_mci_k3_priv_init(). You can check dw_mci_probe() sequence. It is no problem here dw_mci_pltfm_register - drv_data-init(host) - dw_mci_probe - dw_mci_parse_dt + ret = of_property_read_u32_array(np, + clken-reg, data, 2); + if (!ret) { + priv-clken_reg = data[0]; + priv-clken_bit = data[1]; + } + + ret = of_property_read_u32_array(np, + drv-sel-reg, data, 3); + if (!ret) { + priv-drv_reg = data[0]; + priv-drv_off = data[1]; + priv-drv_bits = data[2]; + } + + ret = of_property_read_u32_array(np, + sam-sel-reg, data, 3); + if (!ret) { + priv-sam_reg = data[0]; + priv-sam_off = data[1]; + priv-sam_bits = data[2]; + } + + ret = of_property_read_u32_array(np, + div-reg, data, 3); + if (!ret) { + priv-div_reg = data[0]; + priv-div_off = data[1]; + priv-div_bits = data[2]; + } Should these register information be got from dt? It could be define in source code instead. There are many register from pctrl node instead of mmc controller. If set in code, we may read id and then switch id, set register, start bit, bits number, which is no rules for different controller, using defiine is not helpful. for example: switch (idx) { case 0: clken_reg = 0x1F8; clken_bit = 0; drv_sel_reg = 0x1F8; drv_sel_bit = 4; sam_sel_reg = 0x1F8; sam_sel_bit = 8; div_reg = 0x1F8; div_bit = 1; break; case 1: clken_reg = 0x1F8; clken_bit = 12; drv_sel_reg = 0x1F8; drv_sel_bit = 16; sam_sel_reg = 0x1F8; sam_sel_bit = 20; div_reg = 0x1F8; div_bit = 13; break; case 2: clken_reg = 0x1F8; clken_bit = 24; drv_sel_reg = 0x1F8; drv_sel_bit = 28; sam_sel_reg = 0x1FC; sam_sel_bit = 0; div_reg = 0x1F8; div_bit = 25; break; So define register offset, start bit and bits number in dts make it simplier. Is this acceptable? Thanks. -- To unsubscribe from this list: send the line unsubscribe linux-mmc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 2/2] mmc: dw_mmc: add dw_mmc-k3 for k3 platform
On Fri, Nov 1, 2013 at 1:21 AM, Seungwon Jeon tgih@samsung.com wrote: On Fri, November 01, 2013, zhangfei gao wrote: Dear Seungwon Thanks for giving suggestion. On Thu, Oct 31, 2013 at 11:24 PM, Seungwon Jeon tgih@samsung.com wrote: Hi Zhangfei, +static void dw_mci_k3_set_ios(struct dw_mci *host, struct mmc_ios *ios) +{ + struct dw_mci_k3_priv_data *priv = host-priv; + + if (priv-type == DW_MCI_TYPE_HI4511) There are several checking controller type. But now DW_MCI_TYPE_HI4511 is just introduced alone. It seems like unnecessary. Yes, currently only K3V2 is added, and k3v3 code will be added soon. Do you think type is more suitable to add later? Yes, it would be better. OK, got it. +static int dw_mci_k3_parse_dt(struct dw_mci *host) +{ + struct dw_mci_k3_priv_data *priv = host-priv; + struct device_node *np = host-dev-of_node; + u32 data[3]; + int ret; + + if (priv-type == DW_MCI_TYPE_HI4511) { Didn't you see Kernel panic here? host-priv is not allocated yet, it's a invalid pointer dereference. dw_mci_k3_parse_dt() is called prior to dw_mci_k3_priv_init(). You can check dw_mci_probe() sequence. It is no problem here dw_mci_pltfm_register - drv_data-init(host) - dw_mci_probe - dw_mci_parse_dt I guess your base is not latest. Can you check cjb's tree? Yes, thanks for the info. It is changed in 3.12-rc2 While what we use is 3.12-rc1, will rebase. + ret = of_property_read_u32_array(np, + clken-reg, data, 2); + if (!ret) { + priv-clken_reg = data[0]; + priv-clken_bit = data[1]; + } + + ret = of_property_read_u32_array(np, + drv-sel-reg, data, 3); + if (!ret) { + priv-drv_reg = data[0]; + priv-drv_off = data[1]; + priv-drv_bits = data[2]; + } + + ret = of_property_read_u32_array(np, + sam-sel-reg, data, 3); + if (!ret) { + priv-sam_reg = data[0]; + priv-sam_off = data[1]; + priv-sam_bits = data[2]; + } + + ret = of_property_read_u32_array(np, + div-reg, data, 3); + if (!ret) { + priv-div_reg = data[0]; + priv-div_off = data[1]; + priv-div_bits = data[2]; + } Should these register information be got from dt? It could be define in source code instead. There are many register from pctrl node instead of mmc controller. If set in code, we may read id and then switch id, set register, start bit, bits number, which is no rules for different controller, using defiine is not helpful. for example: switch (idx) { case 0: clken_reg = 0x1F8; clken_bit = 0; drv_sel_reg = 0x1F8; drv_sel_bit = 4; sam_sel_reg = 0x1F8; sam_sel_bit = 8; div_reg = 0x1F8; div_bit = 1; break; case 1: clken_reg = 0x1F8; clken_bit = 12; drv_sel_reg = 0x1F8; drv_sel_bit = 16; sam_sel_reg = 0x1F8; sam_sel_bit = 20; div_reg = 0x1F8; div_bit = 13; break; case 2: clken_reg = 0x1F8; clken_bit = 24; drv_sel_reg = 0x1F8; drv_sel_bit = 28; sam_sel_reg = 0x1FC; sam_sel_bit = 0; div_reg = 0x1F8; div_bit = 25; break; So define register offset, start bit and bits number in dts make it simplier. Is this acceptable? It's up to you. I think there will be better ways. For example, some table for variable register can be used for each controller type. Additionally, if you intend to use dt, error handling is needed. dw_mci_k3_parse_dt always returns success although of_property_read_u32_array is failed. The reason is they are optional property. SD would fail if not setting the property, while emmc does not matter. So set for optional, dw_mci_k3_set_timing will check whether they exists. Thanks -- To unsubscribe from this list: send the line unsubscribe linux-mmc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 2/2] mmc: dw_mmc: add dw_mmc-k3 for k3 platform
Dear Kumar Thanks for the careful review. On Sun, Oct 27, 2013 at 11:29 PM, Kumar Gala ga...@codeaurora.org wrote: On Oct 23, 2013, at 8:03 AM, Zhangfei Gao wrote: +Required Properties: + +* compatible: should be + - hisilicon,hi4511-dw-mshc: for controllers with hi4511 + specific extentions. +* vmmc-supply: should be vmmc used in dwmmc +* fifo-depth: should be provided if register can not provide correct value +* clken-reg: should be clock enable register and offset +* drv-sel-reg: should be driver delay select register, offset and bits +* sam-sel-reg: should be sample delay select register, offset and bits +* div-reg: should be divider register, offset and bits +* tune-table: should be array of clock tune mmc controller + 1. These should have vendor prefixes However Olof and Mark once suggested not using prefix if vector is internally used. Example before: + - #hisilicon,clkdiv-table-cells : the number of parameters after phandle in + hisilicon,clkdiv-table property. + - hisilicon,clkdiv-table : list of value that are used to configure clock Olof: For a binding that is your own, you don't need to prefix the properties. Prefixes are mostly used when adding new vendor-specific attributes to a common binding. Mark: People seem to be *very* keen on adding them for all bindings for some reason. 2. why do we need the *-reg properties 3. for the *-reg properties its not clear what bits means? The silicon has some limitaiton to tune the clock timing according to working mode, including driver delay, sample delay, and divider. If not set even the host register may not read out. The register in PCTRL described below, And one register may contains sereral usage, for example mmc0: 0x1f8: bit 0 is clock en/dis, bit 1 ~ bit 3 controls div, bit 4~7 controls drv-sel, bit 8 ~11 controls sam-sel mmc1: 0x1f8: bit 12 ~~ register, offset and bits stands for 0x1f8, start bit and how many bits. Is this fine? 4. tune-table is not well described, what does 'clock tune' mean, why an array? Will change to tuning-table It is values used for computing these div, drv, sample register, Also contains system clock need to be set, and output clock output after PCTRL control. +Example: + + The MSHC controller node can be split into two portions, SoC specific and + board specific portions as listed below. + Does dtc merge this all into a single node? Would probably be good to have comments in the example stating both that the merge into one node, and which is board and which is soc. OK, will add comments to distinguish dtsi for soc and dts for board. + dwmmc_0: dwmmc0@fcd03000 { + compatible = hisilicon,hi4511-dw-mshc; + reg = 0xfcd03000 0x1000; + interrupts = 0 16 4; + #address-cells = 1; + #size-cells = 0; + clocks = clk_sd, clk_ddrc_per; + clock-names = ciu, biu; + clken-reg = 0x1f8 0; + drv-sel-reg = 0x1f8 4 4; + sam-sel-reg = 0x1f8 8 4; + div-reg = 0x1f8 1 3; + tune-table = + 18000 6 6 13 13 2500, + 0 0 0 0 0 0, + 36000 6 4 2 0 5000, + 18000 6 4 13 13 2500, + 36000 6 4 2 0 5000, + 72000 6 1 9 4 1, + 0 0 0 0 0 0, + 36000 7 1 3 0 5000; + }; + dwmmc0@fcd03000 { + num-slots = 1; + vmmc-supply = ldo12; + fifo-depth = 0x100; + supports-highspeed; + pinctrl-names = default; + pinctrl-0 = sd_pmx_pins sd_cfg_func1 sd_cfg_func2; + slot@0 { + reg = 0; + bus-width = 4; + disable-wp; + cd-gpios = gpio10 3 0; + }; + }; + +PCTRL: + should have a description OK. +Required Properties: +* compatible: should be + - hisilicon,pctrl: Peripheral control + Reg is not described as a required property. OK. +Example: + + pctrl: pctrl@fca09000 { + compatible = hisilicon,pctrl; + reg = 0xfca09000 0x1000; + }; This should be in its own binding document, and not part of the mmc binding bindings/arm/hisilicon/hisilicon.txt still not been merged in another patch, where we want to push such desc as well as other system binding. Is it OK adding this node desc twice in two files, since mmc need such node. or move this desc after hisilicon.txt get merged for saving conflict? Thanks -- To unsubscribe from this list: send the line unsubscribe linux-mmc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 2/2] mmc: dw_mmc: add dw_mmc-k3 for k3 platform
update: fix typo Add dw_mmc-k3.c for k3v2, support sd/emmc Signed-off-by: Zhangfei Gao zhangfei@linaro.org Tested-by: Zhigang Wang brooke.wangzhig...@huawei.com --- .../devicetree/bindings/mmc/k3-dw-mshc.txt | 77 + drivers/mmc/host/Kconfig | 10 + drivers/mmc/host/Makefile |1 + drivers/mmc/host/dw_mmc-k3.c | 297 4 files changed, 385 insertions(+) create mode 100644 Documentation/devicetree/bindings/mmc/k3-dw-mshc.txt create mode 100644 drivers/mmc/host/dw_mmc-k3.c diff --git a/Documentation/devicetree/bindings/mmc/k3-dw-mshc.txt b/Documentation/devicetree/bindings/mmc/k3-dw-mshc.txt new file mode 100644 index 000..0de8c27 --- /dev/null +++ b/Documentation/devicetree/bindings/mmc/k3-dw-mshc.txt @@ -0,0 +1,77 @@ +* Hisilicon specific extensions to the Synopsys Designware Mobile + Storage Host Controller + +Read synopsis-dw-mshc.txt for more details +The Synopsys designware mobile storage host controller is used to interface +a SoC with storage medium such as eMMC or SD/MMC cards. This file documents +differences between the core Synopsys dw mshc controller properties described +by synopsis-dw-mshc.txt and the properties used by the Hisilicon specific +extensions to the Synopsys Designware Mobile Storage Host Controller. + +Required Properties: + +* compatible: should be + - hisilicon,hi4511-dw-mshc: for controllers with hi4511 + specific extentions. +* vmmc-supply: should be vmmc used in dwmmc +* fifo-depth: should be provided if register can not provide correct value +* clken-reg: should be clock enable register and offset +* drv-sel-reg: should be driver delay select register, offset and bits +* sam-sel-reg: should be sample delay select register, offset and bits +* div-reg: should be divider register, offset and bits +* tune-table: should be array of clock tune mmc controller + +Example: + + The MSHC controller node can be split into two portions, SoC specific and + board specific portions as listed below. + + dwmmc_0: dwmmc0@fcd03000 { + compatible = hisilicon,hi4511-dw-mshc; + reg = 0xfcd03000 0x1000; + interrupts = 0 16 4; + #address-cells = 1; + #size-cells = 0; + clocks = clk_sd, clk_ddrc_per; + clock-names = ciu, biu; + clken-reg = 0x1f8 0; + drv-sel-reg = 0x1f8 4 4; + sam-sel-reg = 0x1f8 8 4; + div-reg = 0x1f8 1 3; + tune-table = + 18000 6 6 13 13 2500, + 0 0 0 0 0 0, + 36000 6 4 2 0 5000, + 18000 6 4 13 13 2500, + 36000 6 4 2 0 5000, + 72000 6 1 9 4 1, + 0 0 0 0 0 0, + 36000 7 1 3 0 5000; + }; + dwmmc0@fcd03000 { + num-slots = 1; + vmmc-supply = ldo12; + fifo-depth = 0x100; + supports-highspeed; + pinctrl-names = default; + pinctrl-0 = sd_pmx_pins sd_cfg_func1 sd_cfg_func2; + slot@0 { + reg = 0; + bus-width = 4; + disable-wp; + cd-gpios = gpio10 3 0; + }; + }; + +PCTRL: + +Required Properties: +* compatible: should be + - hisilicon,pctrl: Peripheral control + +Example: + + pctrl: pctrl@fca09000 { + compatible = hisilicon,pctrl; + reg = 0xfca09000 0x1000; + }; diff --git a/drivers/mmc/host/Kconfig b/drivers/mmc/host/Kconfig index 7fc5099..45aaa2d 100644 --- a/drivers/mmc/host/Kconfig +++ b/drivers/mmc/host/Kconfig @@ -575,6 +575,16 @@ config MMC_DW_SOCFPGA This selects support for Altera SoCFPGA specific extensions to the Synopsys DesignWare Memory Card Interface driver. +config MMC_DW_K3 + tristate K3 specific extensions for Synopsys DW Memory Card Interface + depends on MMC_DW + select MMC_DW_PLTFM + select MMC_DW_IDMAC + help + This selects support for Hisilicon K3 SoC specific extensions to the + Synopsys DesignWare Memory Card Interface driver. Select this option + for platforms based on Hisilicon K3 SoC's. + config MMC_DW_PCI tristate Synopsys Designware MCI support on PCI bus depends on MMC_DW PCI diff --git a/drivers/mmc/host/Makefile b/drivers/mmc/host/Makefile index c41d0c3..64f5f8d 100644 --- a/drivers/mmc/host/Makefile +++ b/drivers/mmc/host/Makefile @@ -43,6 +43,7 @@ obj-$(CONFIG_MMC_DW) += dw_mmc.o obj-$(CONFIG_MMC_DW_PLTFM) += dw_mmc-pltfm.o obj-$(CONFIG_MMC_DW_EXYNOS)+= dw_mmc-exynos.o obj-$(CONFIG_MMC_DW_SOCFPGA) += dw_mmc-socfpga.o +obj-$(CONFIG_MMC_DW_K3)+= dw_mmc-k3.o obj-$(CONFIG_MMC_DW_PCI) += dw_mmc
[PATCH 1/2] mmc: dw_mmc: add dw_mci_of_get_cd_gpio to handle cd pin
Add function dw_mci_of_get_cd_gpio to check cd-gpios from dts. mmc_gpio_request_cd and mmc_gpio_get_cd are used to handle cd pin Signed-off-by: Zhangfei Gao zhangfei@linaro.org CC: Jaehoon Chung jh80.ch...@samsung.com --- drivers/mmc/host/dw_mmc.c | 34 ++ 1 file changed, 34 insertions(+) diff --git a/drivers/mmc/host/dw_mmc.c b/drivers/mmc/host/dw_mmc.c index 018f365..b8bb9a5 100644 --- a/drivers/mmc/host/dw_mmc.c +++ b/drivers/mmc/host/dw_mmc.c @@ -35,6 +35,7 @@ #include linux/workqueue.h #include linux/of.h #include linux/of_gpio.h +#include linux/mmc/slot-gpio.h #include dw_mmc.h @@ -872,12 +873,15 @@ static int dw_mci_get_cd(struct mmc_host *mmc) int present; struct dw_mci_slot *slot = mmc_priv(mmc); struct dw_mci_board *brd = slot-host-pdata; + int gpio_cd = !mmc_gpio_get_cd(mmc); /* Use platform get_cd function, else try onboard card detect */ if (brd-quirks DW_MCI_QUIRK_BROKEN_CARD_DETECTION) present = 1; else if (brd-get_cd) present = !brd-get_cd(slot-id); + else if (!IS_ERR_VALUE(gpio_cd)) + present = !!gpio_cd; else present = (mci_readl(slot-host, CDETECT) (1 slot-id)) == 0 ? 1 : 0; @@ -1876,6 +1880,30 @@ static int dw_mci_of_get_wp_gpio(struct device *dev, u8 slot) return gpio; } + +/* find the cd gpio for a given slot; or -1 if none specified */ +static int dw_mci_of_get_cd_gpio(struct device *dev, u8 slot, + struct mmc_host *mmc) +{ + struct device_node *np = dw_mci_of_find_slot_node(dev, slot); + int gpio; + + if (!np) + return -EINVAL; + + gpio = of_get_named_gpio(np, cd-gpios, 0); + + /* Having a missing entry is valid; return silently */ + if (!gpio_is_valid(gpio)) + return -EINVAL; + + if (mmc_gpio_request_cd(mmc, gpio, 0)) { + dev_warn(dev, gpio [%d] request failed\n, gpio); + return -EINVAL; + } + + return gpio; +} #else /* CONFIG_OF */ static int dw_mci_of_get_slot_quirks(struct device *dev, u8 slot) { @@ -1893,6 +1921,11 @@ static int dw_mci_of_get_wp_gpio(struct device *dev, u8 slot) { return -EINVAL; } +static int dw_mci_of_get_cd_gpio(struct device *dev, u8 slot, + struct mmc_host *mmc) +{ + return -EINVAL; +} #endif /* CONFIG_OF */ static int dw_mci_init_slot(struct dw_mci *host, unsigned int id) @@ -1996,6 +2029,7 @@ static int dw_mci_init_slot(struct dw_mci *host, unsigned int id) clear_bit(DW_MMC_CARD_PRESENT, slot-flags); slot-wp_gpio = dw_mci_of_get_wp_gpio(host-dev, slot-id); + dw_mci_of_get_cd_gpio(host-dev, slot-id, mmc); ret = mmc_add_host(mmc); if (ret) -- 1.7.9.5 -- To unsubscribe from this list: send the line unsubscribe linux-mmc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[v2 PATCH 0/2] mmc: dw_mmc: add dw_mmc-k3
v2: Follow Jaehoon's suggestion Use slot-gpio.c handle cd pin Move table out to dts other suggestion Zhangfei Gao (2): mmc: dw_mmc: add dw_mci_of_get_cd_gpio to handle cd pin mmc: dw_mmc: add dw_mmc-k3 for k3 platform .../devicetree/bindings/mmc/k3-dw-mshc.txt | 77 + drivers/mmc/host/Kconfig | 10 + drivers/mmc/host/Makefile |1 + drivers/mmc/host/dw_mmc-k3.c | 298 drivers/mmc/host/dw_mmc.c | 34 +++ 5 files changed, 420 insertions(+) create mode 100644 Documentation/devicetree/bindings/mmc/k3-dw-mshc.txt create mode 100644 drivers/mmc/host/dw_mmc-k3.c -- 1.7.9.5 -- To unsubscribe from this list: send the line unsubscribe linux-mmc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 2/2] mmc: dw_mmc: add dw_mmc-k3 for k3 platform
Add dw_mmc-k3.c for k3v2, support sd/emmc Signed-off-by: Zhangfei Gao zhangfei@linaro.org Tested-by: Zhigang Wang brooke.wangzhig...@huawei.com --- .../devicetree/bindings/mmc/k3-dw-mshc.txt | 77 + drivers/mmc/host/Kconfig | 10 + drivers/mmc/host/Makefile |1 + drivers/mmc/host/dw_mmc-k3.c | 298 4 files changed, 386 insertions(+) create mode 100644 Documentation/devicetree/bindings/mmc/k3-dw-mshc.txt create mode 100644 drivers/mmc/host/dw_mmc-k3.c diff --git a/Documentation/devicetree/bindings/mmc/k3-dw-mshc.txt b/Documentation/devicetree/bindings/mmc/k3-dw-mshc.txt new file mode 100644 index 000..0de8c27 --- /dev/null +++ b/Documentation/devicetree/bindings/mmc/k3-dw-mshc.txt @@ -0,0 +1,77 @@ +* Hisilicon specific extensions to the Synopsys Designware Mobile + Storage Host Controller + +Read synopsis-dw-mshc.txt for more details +The Synopsys designware mobile storage host controller is used to interface +a SoC with storage medium such as eMMC or SD/MMC cards. This file documents +differences between the core Synopsys dw mshc controller properties described +by synopsis-dw-mshc.txt and the properties used by the Hisilicon specific +extensions to the Synopsys Designware Mobile Storage Host Controller. + +Required Properties: + +* compatible: should be + - hisilicon,hi4511-dw-mshc: for controllers with hi4511 + specific extentions. +* vmmc-supply: should be vmmc used in dwmmc +* fifo-depth: should be provided if register can not provide correct value +* clken-reg: should be clock enable register and offset +* drv-sel-reg: should be driver delay select register, offset and bits +* sam-sel-reg: should be sample delay select register, offset and bits +* div-reg: should be divider register, offset and bits +* tune-table: should be array of clock tune mmc controller + +Example: + + The MSHC controller node can be split into two portions, SoC specific and + board specific portions as listed below. + + dwmmc_0: dwmmc0@fcd03000 { + compatible = hisilicon,hi4511-dw-mshc; + reg = 0xfcd03000 0x1000; + interrupts = 0 16 4; + #address-cells = 1; + #size-cells = 0; + clocks = clk_sd, clk_ddrc_per; + clock-names = ciu, biu; + clken-reg = 0x1f8 0; + drv-sel-reg = 0x1f8 4 4; + sam-sel-reg = 0x1f8 8 4; + div-reg = 0x1f8 1 3; + tune-table = + 18000 6 6 13 13 2500, + 0 0 0 0 0 0, + 36000 6 4 2 0 5000, + 18000 6 4 13 13 2500, + 36000 6 4 2 0 5000, + 72000 6 1 9 4 1, + 0 0 0 0 0 0, + 36000 7 1 3 0 5000; + }; + dwmmc0@fcd03000 { + num-slots = 1; + vmmc-supply = ldo12; + fifo-depth = 0x100; + supports-highspeed; + pinctrl-names = default; + pinctrl-0 = sd_pmx_pins sd_cfg_func1 sd_cfg_func2; + slot@0 { + reg = 0; + bus-width = 4; + disable-wp; + cd-gpios = gpio10 3 0; + }; + }; + +PCTRL: + +Required Properties: +* compatible: should be + - hisilicon,pctrl: Peripheral control + +Example: + + pctrl: pctrl@fca09000 { + compatible = hisilicon,pctrl; + reg = 0xfca09000 0x1000; + }; diff --git a/drivers/mmc/host/Kconfig b/drivers/mmc/host/Kconfig index 7fc5099..45aaa2d 100644 --- a/drivers/mmc/host/Kconfig +++ b/drivers/mmc/host/Kconfig @@ -575,6 +575,16 @@ config MMC_DW_SOCFPGA This selects support for Altera SoCFPGA specific extensions to the Synopsys DesignWare Memory Card Interface driver. +config MMC_DW_K3 + tristate K3 specific extensions for Synopsys DW Memory Card Interface + depends on MMC_DW + select MMC_DW_PLTFM + select MMC_DW_IDMAC + help + This selects support for Hisilicon K3 SoC specific extensions to the + Synopsys DesignWare Memory Card Interface driver. Select this option + for platforms based on Hisilicon K3 SoC's. + config MMC_DW_PCI tristate Synopsys Designware MCI support on PCI bus depends on MMC_DW PCI diff --git a/drivers/mmc/host/Makefile b/drivers/mmc/host/Makefile index c41d0c3..64f5f8d 100644 --- a/drivers/mmc/host/Makefile +++ b/drivers/mmc/host/Makefile @@ -43,6 +43,7 @@ obj-$(CONFIG_MMC_DW) += dw_mmc.o obj-$(CONFIG_MMC_DW_PLTFM) += dw_mmc-pltfm.o obj-$(CONFIG_MMC_DW_EXYNOS)+= dw_mmc-exynos.o obj-$(CONFIG_MMC_DW_SOCFPGA) += dw_mmc-socfpga.o +obj-$(CONFIG_MMC_DW_K3)+= dw_mmc-k3.o obj-$(CONFIG_MMC_DW_PCI) += dw_mmc-pci.o obj
Re: [PATCH 2/2] mmc: add dw-mmc-k3
Dear Jaehoon Thanks for the valueable suggestion. On Mon, Oct 14, 2013 at 5:27 PM, Jaehoon Chung jh80.ch...@samsung.com wrote: Hi, If you will send the patch, plz, add the prefix mmc: dw_mmc: xxx at subject. OK, got it. And i think good that device-tree and mmc patch is separated. It is Documentation/devicetree/bindings/mmc/k3-dw-mshc.txt, instead of dts. Should be combined with initial version? +* Hisilicon specific extensions to the Synopsis Designware Mobile + Storage Host Controller Maybe fixed the Synopsys instead of Synopsis. OK, thanks +struct dw_mci_k3_priv_data { + enum dw_mci_k3_type type; + int old_timing; + u32 id; You're using id as the int type at the below code. which type is exactly? + u32 gpio_cd; + u32 clken_reg; + u32 clken_bit; + u32 sam_sel_reg; + u32 sam_sel_bit; + u32 drv_sel_reg; + u32 drv_sel_bit; + u32 div_reg; + u32 div_bit; +}; clken_reg/sam_sel_reg/drv_sel_reg can be changed? Otherwise, it's not host register? If it's host register, then you can use the mci_writeX(). clken_reg/sam_sel_reg/drv_sel_reg is not host register, But other register from pctrl register, used for tuning clock, which is silicon special requirement. + +static void __iomem *pctrl; +static DEFINE_SPINLOCK(mmc_tuning_lock); +static int k3_tuning_config[][8][6] = { + /* bus_clk, div, drv_sel, sam_sel_max, sam_sel_min, input_clk */ + { + {18000, 6, 6, 13, 13, 2500},/* 0: LEGACY 400k */ + {0},/* 1: MMC_HS */ + {36000, 6, 4, 2, 0, 5000 },/* 2: SD_HS */ + {18000, 6, 4, 13, 13, 2500},/* 3: SDR12 */ + {36000, 6, 4, 2, 0, 5000 },/* 4: SDR25 */ + {72000, 6, 1, 9, 4, 1 },/* 5: SDR50 */ + {0},/* 6: SDR104 */ + {36000, 7, 1, 3, 0, 5000 },/* 7: DDR50 */ + }, { + {2600, 1, 1, 3, 3, 1300 }, /* 0: LEGACY 400k */ + {36000, 6, 3, 3, 1, 5000 }, /* 1: MMC_HS*/ + {0},/* 2: SD_HS */ + {0},/* 3: SDR12 */ + {2600, 1, 1, 3, 3, 1300 }, /* 4: SDR25 */ + {36000, 6, 3, 3, 1, 5000 }, /* 5: SDR50 */ + {0},/* 6: SDR104 */ + {72000, 6, 4, 8, 4, 1}, /* 7: DDR50 */ + }, +}; Can't this config be included the dt-file? Yes, good suggestion, it can be. However, additional API of_property_read_u32_array_index required. since there is no existing API get one array from list of arrays. Have test this API, may send out for comments, however, not sure it can ne accepted. What do you think? + * of_property_read_u32_array_index - Find and read an array of 32 bit integers + * pointed by index from a property. + * + * @np:device node from which the property value is to be read. + * @propname: name of the property to be searched. + * @out_values:pointer to return value, modified only if return value is 0. + * @sz:number of array elements to read + * @index: index of the u32 array in the list of values + * + * Search for a property in a device node and read 32-bit value(s) from + * it. Returns 0 on success, -EINVAL if the property does not exist, + * -ENODATA if property does not have a value, and -EOVERFLOW if the + * property data isn't large enough. + * + * The out_values is modified only if a valid u32 value can be decoded. + */ +int of_property_read_u32_array_index(const struct device_node *np, + const char *propname, u32 *out_values, + size_t sz, u32 index) +{ + const __be32 *val = of_find_property_value_of_size(np, propname, + (index + 1) * (sz * sizeof(*out_values))); + + if (IS_ERR(val)) + return PTR_ERR(val); + + while (index--) + val += sz; + while (sz--) + *out_values++ = be32_to_cpup(val++); + return 0; +} +EXPORT_SYMBOL_GPL(of_property_read_u32_array_index); + +static void dw_mci_k3_set_timing(struct dw_mci_k3_priv_data *priv, + int idx, int sam, int drv, int div) Where is idx used? Yes, it can be removed. +{ + unsigned int clken_reg = priv-clken_reg; + unsigned int clken_bit = priv-clken_bit; + unsigned int sam_sel_reg = priv-sam_sel_reg; + unsigned int sam_sel_bit = priv-sam_sel_bit; + unsigned int drv_sel_reg = priv-drv_sel_reg;
[PATCH 1/2] mmc: dw_mmc: change definition of get_cd
int (*get_cd)(struct dw_mci *host, u32 slot_id) Add host info to pass priv, where contains cd pin Signed-off-by: Zhangfei Gao zhangfei@linaro.org --- drivers/mmc/host/dw_mmc.c |2 +- include/linux/mmc/dw_mmc.h |2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/mmc/host/dw_mmc.c b/drivers/mmc/host/dw_mmc.c index 018f365..97ec3d3 100644 --- a/drivers/mmc/host/dw_mmc.c +++ b/drivers/mmc/host/dw_mmc.c @@ -877,7 +877,7 @@ static int dw_mci_get_cd(struct mmc_host *mmc) if (brd-quirks DW_MCI_QUIRK_BROKEN_CARD_DETECTION) present = 1; else if (brd-get_cd) - present = !brd-get_cd(slot-id); + present = !brd-get_cd(slot-host, slot-id); else present = (mci_readl(slot-host, CDETECT) (1 slot-id)) == 0 ? 1 : 0; diff --git a/include/linux/mmc/dw_mmc.h b/include/linux/mmc/dw_mmc.h index 198f0fa..5a359dc 100644 --- a/include/linux/mmc/dw_mmc.h +++ b/include/linux/mmc/dw_mmc.h @@ -246,7 +246,7 @@ struct dw_mci_board { int (*init)(u32 slot_id, irq_handler_t , void *); int (*get_ro)(u32 slot_id); - int (*get_cd)(u32 slot_id); + int (*get_cd)(struct dw_mci *host, u32 slot_id); int (*get_ocr)(u32 slot_id); int (*get_bus_wd)(u32 slot_id); /* -- 1.7.9.5 -- To unsubscribe from this list: send the line unsubscribe linux-mmc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH V3 3/4] mmc: block: Enable runtime pm for mmc blkdevice
Maybe I make misunderstood, or do some mistake. since CONFIG_MMC_UNSAFE_RESUME has to be set, is that mean sd card can not be unpluged with the feature enabled. It can be reproduced here if unplug card in suspend or not. static void mmc_sd_detect(struct mmc_host *host) { err = _mmc_detect_card_removed(host); if (err) { mmc_sd_remove(host); /* host - card is NULL now */ mmc_get_card(host-card); } I have no idea how you applied and tested this patch, but it seems like you have screwed it up. The above code is aligned with this patch. Sorry, the above code is NOT aligned with the code in this patch. mmc_get_card is called before err = _mmc_detect_card_removed(host). And mmc_put_card, immediately after err = _mmc_detect_card_removed(host). Please consider re-applying the patch and re-test. The patches works fine. I am sorry, my mistake. When back-port to 3.9, some mess up :( Thanks -- To unsubscribe from this list: send the line unsubscribe linux-mmc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH V4 1/4] mmc: core: Stop bkops for eMMC only from mmc suspend
On Thu, May 2, 2013 at 8:02 PM, Ulf Hansson ulf.hans...@stericsson.com wrote: From: Ulf Hansson ulf.hans...@linaro.org Move mmc suspend specific operations to be executed from the .suspend callback in the mmc bus_ops. This simplifies the mmc_suspend_host function which is supposed to handle nothing but common suspend tasks. Since eMMC can be considered non-removable there are no need to check for ongoing bkops at PM_SUSPEND_PREPARE notification so remove it. Sorry, a bit confused about this desc. How about mmc card, which can be removable. -- To unsubscribe from this list: send the line unsubscribe linux-mmc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v5 07/13] mmc: sdhci-pxav3: controller can't get base clock
On Fri, Sep 28, 2012 at 3:56 PM, Kevin Liu keyuan@gmail.com wrote: From: Kevin Liu kl...@marvell.com Enable the quirk SDHCI_QUIRK_CAP_CLOCK_BASE_BROKEN since SD_CAPABILITIES_1[15:8](BASE_FREQ) can't get correct base clock value. It return a fixed pre-set value like 200 on some sdhci-pxav3 based platforms like MMP3 while return 0 on the other sdhci-pxav3 based platforms. So we enable the quirk and get the base clock via function get_max_clock. Also add get_max_clock. Reported-by: Philip Rakity prak...@marvell.com Reviewed-by: Philip Rakity prak...@marvell.com Signed-off-by: Kevin Liu kl...@marvell.com Acked-by: Zhangfei Gao zhangfei@marvell.com -- To unsubscribe from this list: send the line unsubscribe linux-mmc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v5 10/13] mmc: sdhci-pxav3: add quirks2
On Fri, Sep 28, 2012 at 3:56 PM, Kevin Liu keyuan@gmail.com wrote: From: Kevin Liu kl...@marvell.com Signed-off-by: Kevin Liu kl...@marvell.com Acked-by: Zhangfei Gao zhangfei@marvell.com --- drivers/mmc/host/sdhci-pxav3.c |2 ++ include/linux/platform_data/pxa_sdhci.h |2 ++ 2 files changed, 4 insertions(+), 0 deletions(-) diff --git a/drivers/mmc/host/sdhci-pxav3.c b/drivers/mmc/host/sdhci-pxav3.c index ccd1906..60829c9 100644 --- a/drivers/mmc/host/sdhci-pxav3.c +++ b/drivers/mmc/host/sdhci-pxav3.c @@ -280,6 +280,8 @@ static int __devinit sdhci_pxav3_probe(struct platform_device *pdev) if (pdata-quirks) host-quirks |= pdata-quirks; + if (pdata-quirks2) + host-quirks2 |= pdata-quirks2; if (pdata-host_caps) host-mmc-caps |= pdata-host_caps; if (pdata-host_caps2) diff --git a/include/linux/platform_data/pxa_sdhci.h b/include/linux/platform_data/pxa_sdhci.h index 59acd98..fdf38d6 100644 --- a/include/linux/platform_data/pxa_sdhci.h +++ b/include/linux/platform_data/pxa_sdhci.h @@ -38,6 +38,7 @@ * @max_speed: the maximum speed supported * @host_caps: Standard MMC host capabilities bit field. * @quirks: quirks of platfrom + * @quirks2: quirks2 of platfrom * @pm_caps: pm_caps of platfrom */ struct sdhci_pxa_platdata { @@ -51,6 +52,7 @@ struct sdhci_pxa_platdata { unsigned inthost_caps; unsigned inthost_caps2; unsigned intquirks; + unsigned intquirks2; unsigned intpm_caps; }; -- 1.7.0.4 -- To unsubscribe from this list: send the line unsubscribe linux-mmc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html -- To unsubscribe from this list: send the line unsubscribe linux-mmc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v5 13/13] mmc: sdhci-pxav3: remove set_uhs_signaling function
On Fri, Sep 28, 2012 at 3:56 PM, Kevin Liu keyuan@gmail.com wrote: From: Kevin Liu kl...@marvell.com Because sdhci can do the same thing so no need to implement this. Signed-off-by: Kevin Liu kl...@marvell.com Acked-by: Zhangfei Gao zhangfei@marvell.com If so, (*set_uhs_signaling) can be removed from sdhci.h. int (*set_uhs_signaling)(struct sdhci_host *host, unsigned int uhs); /Zhangfei -- To unsubscribe from this list: send the line unsubscribe linux-mmc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v4 04/15] mmc: sdhci: keep the saved clock var up to date
On Wed, Sep 26, 2012 at 7:38 PM, Kevin Liu keyuan@gmail.com wrote: From: Kevin Liu kl...@marvell.com The clock rate set to the sdh controller may not exactly as requested by the mmc core, this patch make the clock rate saved in the mmc_ios and sdhci_host updated with the actual setting as in the controller. Thus /sys/kernel/debug/mmcx/ios and card detect prints can show the correct clock rate. The patch may not required if only updating debugfs, since actual_clock already been considered in debugfs. However, does incorrect ios-clock cause unexpected result, such as powerclass. If so, how about directly correct ios-clock, and remove actual_clock at all? /Zhangfei -- To unsubscribe from this list: send the line unsubscribe linux-mmc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v4 06/15] mmc: sdhci-pxav3: controller can't get base clock
On Wed, Sep 26, 2012 at 7:38 PM, Kevin Liu keyuan@gmail.com wrote: From: Kevin Liu kl...@marvell.com Enable the quirk SDHCI_QUIRK_CAP_CLOCK_BASE_BROKEN since SD_CAPABILITIES_1[15:8](BASE_FREQ) can't get correct base clock value. It return a fixed pre-set value like 200 on some sdhci-pxav3 based platforms like MMP3 while return 0 on the other sdhci-pxav3 based platforms. So we enable the quirk and get the base clock via function get_max_clock. Could you provide get_max_clock as well. -- To unsubscribe from this list: send the line unsubscribe linux-mmc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v4 11/15] mmc: sdhci-pxav3: add signal_voltage_switch function
+ if (pdata pdata-signal_voltage_switch) + pdata-signal_voltage_switch(set); +} + #ifdef CONFIG_OF diff --git a/include/linux/platform_data/pxa_sdhci.h b/include/linux/platform_data/pxa_sdhci.h index fdf38d6..3b94ab1 100644 --- a/include/linux/platform_data/pxa_sdhci.h +++ b/include/linux/platform_data/pxa_sdhci.h @@ -40,6 +40,7 @@ * @quirks: quirks of platfrom * @quirks2: quirks2 of platfrom * @pm_caps: pm_caps of platfrom + * @signal_voltage_switch: soc/platfrom handling needed for voltage switch */ struct sdhci_pxa_platdata { unsigned intflags; @@ -54,6 +55,7 @@ struct sdhci_pxa_platdata { unsigned intquirks; unsigned intquirks2; unsigned intpm_caps; + void(*signal_voltage_switch)(unsigned int set); }; Using callback from pdata is in-acceptable. DT can not doing such way. /Zhangfei -- To unsubscribe from this list: send the line unsubscribe linux-mmc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v4 09/15] mmc: sdhci-pxav3: add quirks2
diff --git a/include/linux/platform_data/pxa_sdhci.h b/include/linux/platform_data/pxa_sdhci.h index 59acd98..fdf38d6 100644 --- a/include/linux/platform_data/pxa_sdhci.h +++ b/include/linux/platform_data/pxa_sdhci.h @@ -38,6 +38,7 @@ * @max_speed: the maximum speed supported * @host_caps: Standard MMC host capabilities bit field. * @quirks: quirks of platfrom + * @quirks2: quirks2 of platfrom * @pm_caps: pm_caps of platfrom */ struct sdhci_pxa_platdata { @@ -51,6 +52,7 @@ struct sdhci_pxa_platdata { unsigned inthost_caps; unsigned inthost_caps2; unsigned intquirks; + unsigned intquirks2; unsigned intpm_caps; }; Not find the patch using quirks2. Could you merge the patch together? -- To unsubscribe from this list: send the line unsubscribe linux-mmc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v4 01/15] mmc: sdhci: fix transfer mode setting bug for cmds w/o data transfer
On Wed, Sep 26, 2012 at 7:38 PM, Kevin Liu keyuan@gmail.com wrote: From: Kevin Liu kl...@marvell.com Commands without data transfer like cmd5/cmd7 will use previous transfer mode setting, which may lead to error since some bits may have been set unexpectedly. For example, cmd5 following cmd18/cmd25 will have timeout error since audo cmd23 has been enabled. Signed-off-by: Jialing Fu j...@marvell.com Signed-off-by: Tim Wang wan...@marvell.com Signed-off-by: Kevin Liu kl...@marvell.com --- Reviewed-by: Zhangfei Gao zhangfei@marvell.com -- To unsubscribe from this list: send the line unsubscribe linux-mmc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH] mmc: sdhci-pxav3: Use sdhci_get_of_property for parsing DT quirks
On Wed, Sep 19, 2012 at 4:27 PM, Chris Ball c...@laptop.org wrote: In particular, this is done to gain support for broken-cd and wp-inverted. Signed-off-by: Chris Ball c...@laptop.org --- (A previously submitted patch of mine added broken-cd support to sdhci-pxav3 directly; I think it's a better idea to discard that patch and use this one instead.) Thanks Chris, it's really better. Acked-by: Zhangfei Gao zhangfei@marvell.com -- To unsubscribe from this list: send the line unsubscribe linux-mmc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH] mmc: sdhci-pxav3: dt: Support power-gpios property
On Sun, Sep 9, 2012 at 11:06 AM, Chris Ball c...@laptop.org wrote: Tested on OLPC XO-4/MMP3, where the card power for two of the controllers is a sideband GPIO. The third cell in the power-gpios property controls whether the GPIO is active high/active low. (Also, pass host_caps2 through from platdata to the mmc host.) Signed-off-by: Chris Ball c...@laptop.org --- This patch depends on mmc: slot-gpio: Add support for power gpios drivers/mmc/host/sdhci-pxav3.c | 25 + include/linux/platform_data/pxa_sdhci.h | 2 ++ 2 files changed, 27 insertions(+) Thanks Chris. One questions is could we simply use fixed voltage regulator to control gpio? And register this gpio as vmmc. Thanks -- To unsubscribe from this list: send the line unsubscribe linux-mmc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH] mmc: sdhci-pxa: Add device tree support
On Wed, Jun 13, 2012 at 3:05 AM, Chris Ball c...@laptop.org wrote: Tested on an OLPC XO-1.75. (MMP2, sdhci-pxav3, CONFIG_MACH_MMP2_DT=y) Signed-off-by: Chris Ball c...@laptop.org --- .../devicetree/bindings/mmc/sdhci-pxa.txt | 21 drivers/mmc/host/sdhci-pxav2.c | 52 drivers/mmc/host/sdhci-pxav3.c | 50 +++ 3 files changed, 123 insertions(+) create mode 100644 Documentation/devicetree/bindings/mmc/sdhci-pxa.txt Thanks Chris for the great help, compile error if CONFIG_OF not defined. +#ifdef CONFIG_OF +static const struct of_device_id sdhci_pxav2_of_match[] = { + { + .compatible = mrvl,pxav2-mmc, + }, + {}, +}; +MODULE_DEVICE_TABLE(of, sdhci_pxav2_of_match); + +static struct sdhci_pxa_platdata *pxav2_get_mmc_pdata(struct device *dev) +{ + struct sdhci_pxa_platdata *pdata; + struct device_node *np = dev-of_node; + u32 bus_width; + u32 clk_delay_cycles; + + return pdata; +} +#else +static inline struct sdhci_pxa_platdata pxav2_get_mmc_pdata(struct device *dev) Should be static struct sdhci_pxa_platdata *pxav2_get_mmc_pdata(struct device *dev) +{ + return NULL; +} +#endif + static int __devinit sdhci_pxav2_probe(struct platform_device *pdev) { struct sdhci_pltfm_host *pltfm_host; @@ -128,6 +173,8 @@ static int __devinit sdhci_pxav2_probe(struct platform_device *pdev) struct device *dev = pdev-dev; struct sdhci_host *host = NULL; struct sdhci_pxa *pxa = NULL; + const struct of_device_id *match; + int ret; struct clk *clk; @@ -156,6 +203,10 @@ static int __devinit sdhci_pxav2_probe(struct platform_device *pdev) | SDHCI_QUIRK_BROKEN_TIMEOUT_VAL | SDHCI_QUIRK_CAP_CLOCK_BASE_BROKEN; + match = of_match_device(of_match_ptr(sdhci_pxav2_of_match), pdev-dev); + if (match) { + pdata = pxav2_get_mmc_pdata(dev); + } if (pdata) { if (pdata-flags PXA_FLAG_CARD_PERMANENT) { /* on-chip device */ @@ -218,6 +269,7 @@ static struct platform_driver sdhci_pxav2_driver = { .driver = { .name = sdhci-pxav2, .owner = THIS_MODULE, #ifdef CONFIG_OF required, otherwise build fail. + .of_match_table = sdhci_pxav2_of_match, #endif .pm = SDHCI_PLTFM_PMOPS, }, .probe = sdhci_pxav2_probe, diff --git a/drivers/mmc/host/sdhci-pxav3.c b/drivers/mmc/host/sdhci-pxav3.c index f296956..1835c94 100644 --- a/drivers/mmc/host/sdhci-pxav3.c +++ b/drivers/mmc/host/sdhci-pxav3.c +#ifdef CONFIG_OF +static const struct of_device_id sdhci_pxav3_of_match[] = { + { + .compatible = mrvl,pxav3-mmc, + }, + {}, +}; +MODULE_DEVICE_TABLE(of, sdhci_pxav3_of_match); + +static struct sdhci_pxa_platdata *pxav3_get_mmc_pdata(struct device *dev) +{ +} +#else +static inline struct sdhci_pxa_platdata pxav3_get_mmc_pdata(struct device *dev) Should be static struct sdhci_pxa_platdata *pxav3_get_mmc_pdata(struct device *dev) +{ + return NULL; +} +#endif + @@ -263,6 +312,7 @@ static int __devexit sdhci_pxav3_remove(struct platform_device *pdev) static struct platform_driver sdhci_pxav3_driver = { .driver = { .name = sdhci-pxav3, #ifdef CONFIG_OF required, otherwise build fail. + .of_match_table = sdhci_pxav3_of_match, #endif .owner = THIS_MODULE, .pm = SDHCI_PLTFM_PMOPS, }, -- Chris Ball c...@laptop.org http://printf.net/ One Laptop Per Child -- To unsubscribe from this list: send the line unsubscribe linux-mmc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html -- To unsubscribe from this list: send the line unsubscribe linux-mmc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH] mmc: sdhci-pxa: Check pdata before using its members
On Wed, Sep 14, 2011 at 1:59 PM, Tanmay Upadhyay tanmay.upadh...@einfochips.com wrote: Signed-off-by: Tanmay Upadhyay tanmay.upadh...@einfochips.com Acked-by: Zhangfei Gao zhangfei@marvell.com Thanks --- drivers/mmc/host/sdhci-pxav2.c | 4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-) -- To unsubscribe from this list: send the line unsubscribe linux-mmc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v3 0/2] mmc add vsdio to dynamically control sdio power
v2-v3, change vmmc to vsdio In v2, vmmc is reused, however, sd may be impacted if move vmmc to set_ios. When no card inserted, CD is high, vmmc will be disabled when detect fail, CD will pull low accordingly, controller may treat as card inserted and re-detect. Zhangfei Gao (2): mmc: sdio add regulator vsdio ARM: mmp2: support sdio with regulator vsdio arch/arm/mach-mmp/brownstone.c | 60 ++- drivers/mmc/host/sdhci.c | 22 ++ include/linux/mmc/sdhci.h |2 + 3 files changed, 82 insertions(+), 2 deletions(-) -- To unsubscribe from this list: send the line unsubscribe linux-mmc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v3 1/2] mmc: sdio add regulator vsdio
sdio client may be required power on/off dynamically. With regulator vsdio, sdio client power on/off could be executed by mmc_power_up/down CC: Ohad Ben-Cohen o...@wizery.com Signed-off-by: Zhangfei Gao zhangfei@marvell.com --- drivers/mmc/host/sdhci.c | 22 ++ include/linux/mmc/sdhci.h |2 ++ 2 files changed, 24 insertions(+), 0 deletions(-) diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c index 0e02cc1..e0ef7d3 100644 --- a/drivers/mmc/host/sdhci.c +++ b/drivers/mmc/host/sdhci.c @@ -1424,6 +1424,18 @@ static void sdhci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) out: mmiowb(); spin_unlock_irqrestore(host-lock, flags); + + if (host-vsdio) { + if (ios-power_mode != host-power_mode_old) { + if (ios-power_mode == MMC_POWER_OFF) + regulator_disable(host-vsdio); + + if (ios-power_mode == MMC_POWER_UP) + regulator_enable(host-vsdio); + } + + host-power_mode_old = ios-power_mode; + } } static int check_ro(struct sdhci_host *host) @@ -2748,6 +2760,13 @@ int sdhci_add_host(struct sdhci_host *host) regulator_enable(host-vmmc); } + host-vsdio = regulator_get(mmc_dev(mmc), vsdio); + if (IS_ERR(host-vsdio)) + host-vsdio = NULL; + else + printk(KERN_INFO %s: vsdio regulator found\n, + mmc_hostname(mmc)); + sdhci_init(host, 0); #ifdef CONFIG_MMC_DEBUG @@ -2839,6 +2858,9 @@ void sdhci_remove_host(struct sdhci_host *host, int dead) regulator_put(host-vmmc); } + if (host-vsdio) + regulator_put(host-vsdio); + kfree(host-adma_desc); kfree(host-align_buffer); diff --git a/include/linux/mmc/sdhci.h b/include/linux/mmc/sdhci.h index 5666f3a..201207a 100644 --- a/include/linux/mmc/sdhci.h +++ b/include/linux/mmc/sdhci.h @@ -94,6 +94,8 @@ struct sdhci_host { const struct sdhci_ops *ops;/* Low level hw interface */ struct regulator *vmmc; /* Power regulator */ + struct regulator *vsdio;/* sdio Power regulator */ + unsigned char power_mode_old; /* power supply mode */ /* Internal data */ struct mmc_host *mmc; /* MMC structure */ -- 1.7.0.4 -- To unsubscribe from this list: send the line unsubscribe linux-mmc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v3 2/2] ARM: mmp2: support sdio with regulator vsdio
Add regulator vsdio, which controled by mmc core to handle sdio chip power Test With CONFIG_PM_RUNTIME=y 8787 power is enabled if any client module over sdio is insmod, and disbled automatically after all client modules over sdio are rmmod Also 8787 power could be controled by mmc_start/stop_host Signed-off-by: Zhangfei Gao zhangfei@marvell.com --- arch/arm/mach-mmp/brownstone.c | 60 ++- 1 files changed, 58 insertions(+), 2 deletions(-) diff --git a/arch/arm/mach-mmp/brownstone.c b/arch/arm/mach-mmp/brownstone.c index c79162a..752c5bf 100644 --- a/arch/arm/mach-mmp/brownstone.c +++ b/arch/arm/mach-mmp/brownstone.c @@ -89,6 +89,9 @@ static unsigned long brownstone_pin_config[] __initdata = { GPIO41_MMC2_CMD | MFP_PULL_HIGH, GPIO42_MMC2_CLK, + GPIO57_GPIO | MFP_LPM_DRIVE_HIGH, + GPIO58_GPIO | MFP_LPM_DRIVE_HIGH, + /* MMC2 */ GPIO165_MMC3_DAT7 | MFP_PULL_HIGH, GPIO162_MMC3_DAT6 | MFP_PULL_HIGH, @@ -180,12 +183,66 @@ static struct sdhci_pxa_platdata mmp2_sdh_platdata_mmc0 = { .clk_delay_cycles = 0x1f, }; +static struct sdhci_pxa_platdata mmp2_sdh_platdata_mmc1 = { + .flags = PXA_FLAG_CARD_PERMANENT, +}; + static struct sdhci_pxa_platdata mmp2_sdh_platdata_mmc2 = { .clk_delay_cycles = 0x1f, .flags = PXA_FLAG_CARD_PERMANENT | PXA_FLAG_SD_8_BIT_CAPABLE_SLOT, }; +static struct regulator_consumer_supply sdio_power_supplies[] = { + REGULATOR_SUPPLY(vsdio, sdhci-pxav3.1), +}; + +static struct regulator_init_data sdio_power_data = { + .constraints= { + .valid_ops_mask = REGULATOR_CHANGE_STATUS, + }, + .num_consumer_supplies = ARRAY_SIZE(sdio_power_supplies), + .consumer_supplies = sdio_power_supplies, +}; + +static struct fixed_voltage_config sdio_power = { + .supply_name= vsdio, + .microvolts = 300, + .gpio = mfp_to_gpio(MFP_PIN_GPIO57), + .enable_high= 1, + .enabled_at_boot= 0, + .init_data = sdio_power_data, +}; + +static struct platform_device sdio_power_device = { + .name = reg-fixed-voltage, + .id = 2, + .dev = { + .platform_data = sdio_power, + }, +}; + +static void __init brownstone_init_mmc(void) +{ + /* +* PDn: GPIO57; RESETn: GPIO58 +* 8787, RESETn keeps high, PDn control power +* on: PDn 1; off: PDn 0; +*/ + int RESETn = mfp_to_gpio(MFP_PIN_GPIO58); + + if (gpio_request(RESETn, sdio RESETn)) { + pr_err(Failed to request sdio RESETn gpio\n); + return; + } + gpio_direction_output(RESETn, 1); + gpio_free(RESETn); + + platform_device_register(sdio_power_device); + mmp2_add_sdhost(0, mmp2_sdh_platdata_mmc0); /* SD/MMC */ + mmp2_add_sdhost(1, mmp2_sdh_platdata_mmc1); /* sdio */ + mmp2_add_sdhost(2, mmp2_sdh_platdata_mmc2); /* eMMC */ +} static void __init brownstone_init(void) { @@ -195,8 +252,7 @@ static void __init brownstone_init(void) mmp2_add_uart(1); mmp2_add_uart(3); mmp2_add_twsi(1, NULL, ARRAY_AND_SIZE(brownstone_twsi1_info)); - mmp2_add_sdhost(0, mmp2_sdh_platdata_mmc0); /* SD/MMC */ - mmp2_add_sdhost(2, mmp2_sdh_platdata_mmc2); /* eMMC */ + brownstone_init_mmc(); /* enable 5v regulator */ platform_device_register(brownstone_v_5vp_device); -- 1.7.0.4 -- To unsubscribe from this list: send the line unsubscribe linux-mmc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 1/2] mmc: sdhci move vmmc to set_ios
On Tue, Jul 26, 2011 at 3:06 PM, Zhangfei Gao zhangfei@marvell.com wrote: Move vmmc to set_ios, as a result mmc_power_up/down handles regulator_enable/disable vmmc Move regulator outof spin_lock, since usually i2c operation is called Remove vmmc from suspend/resume function, instead vmmc is handled properly in mmc_suspend/resume_host according to mmc_card_keep_power CC: Ohad Ben-Cohen o...@wizery.com Signed-off-by: Zhangfei Gao zhangfei@marvell.com --- drivers/mmc/host/sdhci.c | 27 +++ include/linux/mmc/sdhci.h | 1 + 2 files changed, 16 insertions(+), 12 deletions(-) Hi, Daniel We found some impact to sd if reusing vmmc in set_ios, when no sd card is inserted. When no sd card, CD pin is high, but when vmmc is disabled in mmc_power_down, as a result CD pin will be pulled down, which is same as sd card is inserted, however the card detect will fail since no sd card in fact. So additional regulator vsdio still required to control power of vsdio, to make mmc_power_up/down control sdio power. Thanks -- To unsubscribe from this list: send the line unsubscribe linux-mmc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 2/2] ARM: mmp2: support sdio device 8787
+ +static struct fixed_voltage_config sdio_power = { + .supply_name = vmmc, + .microvolts = 300, + .gpio = mfp_to_gpio(MFP_PIN_GPIO57), + .enable_high = 1, + .enabled_at_boot = 0, + .init_data = sdio_power_data, +}; + ldo7 is the power source. The 8787 is the consumer and the code should reflect this. GPIO57 is an on/off switch to the 8787. Instead of LDO7, 8787 is powered with V_SD2, V_BATT, and VLDO12 on brownstone. Use PDn to control 8787 power is recommended method. 1. Some LDO is shared and can not be cut down. 2. Control LDO is much slower, some time is needed for voltage to decay, and the time is not accurate to control. 3. With LDO powered, 8787 is under control and 8787 could put itself to the lowest state. -- To unsubscribe from this list: send the line unsubscribe linux-mmc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 2/2] ARM: mmp2: support sdio device 8787
On Thu, Jul 28, 2011 at 12:23 PM, Philip Rakity prak...@marvell.com wrote: On Jul 27, 2011, at 7:44 PM, zhangfei gao wrote: + +static struct fixed_voltage_config sdio_power = { + .supply_name = vmmc, + .microvolts = 300, + .gpio = mfp_to_gpio(MFP_PIN_GPIO57), + .enable_high = 1, + .enabled_at_boot = 0, + .init_data = sdio_power_data, +}; + ldo7 is the power source. The 8787 is the consumer and the code should reflect this. GPIO57 is an on/off switch to the 8787. Instead of LDO7, 8787 is powered with V_SD2, V_BATT, and VLDO12 on brownstone. Use PDn to control 8787 power is recommended method. 1. Some LDO is shared and can not be cut down. 2. Control LDO is much slower, some time is needed for voltage to decay, and the time is not accurate to control. 3. With LDO powered, 8787 is under control and 8787 could put itself to the lowest state. LDO is dedicated to 8787 and can be left on. The power picture is ldo (as regulator) and 8787 as consumer. Code does not show this relationship. The 8787 in deep sleep draws very little power but since even this small power usage is a concern the disabling the ldo can reduce power further. In fact, disable ldo may consume more power than put 8787 in low power mode, since leakage from pin, which can not be controlled by 8787 any more if ldo is disabled. -- To unsubscribe from this list: send the line unsubscribe linux-mmc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v2 0/2] set_ios handle vmmc
v2: reuse vmmc vmmc is controled inside set_ios according to mmc_power_up/down Brownstone add support of sdio device 8787 Zhangfei Gao (2): mmc: sdhci move vmmc to set_ios ARM: mmp2: support sdio device 8787 arch/arm/mach-mmp/brownstone.c | 60 ++- drivers/mmc/host/sdhci.c | 27 ++ include/linux/mmc/sdhci.h |1 + 3 files changed, 74 insertions(+), 14 deletions(-) -- To unsubscribe from this list: send the line unsubscribe linux-mmc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 2/2] ARM: mmp2: support sdio device 8787
Support 8787 device, provide regulator vmmc With CONFIG_PM_RUNTIME=y 8787 power is enabled if any client module over sdio is insmod, and disbled automatically after all client modules over sdio are rmmod Also 8787 power could be controled by mmc_start/stop_host via debugfs Signed-off-by: Zhangfei Gao zhangfei@marvell.com --- arch/arm/mach-mmp/brownstone.c | 60 ++- 1 files changed, 58 insertions(+), 2 deletions(-) diff --git a/arch/arm/mach-mmp/brownstone.c b/arch/arm/mach-mmp/brownstone.c index c79162a..46a67b9 100644 --- a/arch/arm/mach-mmp/brownstone.c +++ b/arch/arm/mach-mmp/brownstone.c @@ -89,6 +89,9 @@ static unsigned long brownstone_pin_config[] __initdata = { GPIO41_MMC2_CMD | MFP_PULL_HIGH, GPIO42_MMC2_CLK, + GPIO57_GPIO | MFP_LPM_DRIVE_HIGH | MFP_PULL_HIGH, + GPIO58_GPIO | MFP_LPM_DRIVE_HIGH | MFP_PULL_HIGH, + /* MMC2 */ GPIO165_MMC3_DAT7 | MFP_PULL_HIGH, GPIO162_MMC3_DAT6 | MFP_PULL_HIGH, @@ -180,12 +183,66 @@ static struct sdhci_pxa_platdata mmp2_sdh_platdata_mmc0 = { .clk_delay_cycles = 0x1f, }; +static struct sdhci_pxa_platdata mmp2_sdh_platdata_mmc1 = { + .flags = PXA_FLAG_CARD_PERMANENT, +}; + static struct sdhci_pxa_platdata mmp2_sdh_platdata_mmc2 = { .clk_delay_cycles = 0x1f, .flags = PXA_FLAG_CARD_PERMANENT | PXA_FLAG_SD_8_BIT_CAPABLE_SLOT, }; +static struct regulator_consumer_supply sdio_power_supplies[] = { + REGULATOR_SUPPLY(vmmc, sdhci-pxav3.1), +}; + +static struct regulator_init_data sdio_power_data = { + .constraints= { + .valid_ops_mask = REGULATOR_CHANGE_STATUS, + }, + .num_consumer_supplies = ARRAY_SIZE(sdio_power_supplies), + .consumer_supplies = sdio_power_supplies, +}; + +static struct fixed_voltage_config sdio_power = { + .supply_name= vmmc, + .microvolts = 300, + .gpio = mfp_to_gpio(MFP_PIN_GPIO57), + .enable_high= 1, + .enabled_at_boot= 0, + .init_data = sdio_power_data, +}; + +static struct platform_device sdio_power_device = { + .name = reg-fixed-voltage, + .id = 2, + .dev = { + .platform_data = sdio_power, + }, +}; + +static void __init brownstone_init_mmc(void) +{ + /* +* PDn: GPIO57; RESETn: GPIO58 +* 8787, RESETn keeps high, PDn control power +* on: PDn 1; off: PDn 0; +*/ + int RESETn = mfp_to_gpio(MFP_PIN_GPIO58); + + if (gpio_request(RESETn, sdio RESETn)) { + pr_err(Failed to request sdio RESETn gpio\n); + return; + } + gpio_direction_output(RESETn, 1); + gpio_free(RESETn); + + platform_device_register(sdio_power_device); + mmp2_add_sdhost(0, mmp2_sdh_platdata_mmc0); /* SD/MMC */ + mmp2_add_sdhost(1, mmp2_sdh_platdata_mmc1); /* sdio */ + mmp2_add_sdhost(2, mmp2_sdh_platdata_mmc2); /* eMMC */ +} static void __init brownstone_init(void) { @@ -195,8 +252,7 @@ static void __init brownstone_init(void) mmp2_add_uart(1); mmp2_add_uart(3); mmp2_add_twsi(1, NULL, ARRAY_AND_SIZE(brownstone_twsi1_info)); - mmp2_add_sdhost(0, mmp2_sdh_platdata_mmc0); /* SD/MMC */ - mmp2_add_sdhost(2, mmp2_sdh_platdata_mmc2); /* eMMC */ + brownstone_init_mmc(); /* enable 5v regulator */ platform_device_register(brownstone_v_5vp_device); -- 1.7.0.4 -- To unsubscribe from this list: send the line unsubscribe linux-mmc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH] mmc: sdio add regulator vsdio
On Fri, Jul 22, 2011 at 2:50 PM, Daniel Drake d...@laptop.org wrote: On 21 July 2011 03:34, Zhangfei Gao zhangfei@marvell.com wrote: sdio client may be required power on/off dynamically. With regulator vsdio, sdio client power on/off could be executed by mmc_power_up/down I think you can/should do this with vmmc. When the device gets powered down (e.g. in runtime suspend), the voltage should be cut, so it should be possible to use the existing regulator. Have considered re-use vmmc before, Consider dynamically power control only required for sdio, so use vsdio to exclude potential issue to sd/mmc. Anyway, will try re-use vmmc. I also looked at doing this before, when it looked like we would have to manipulate a GPIO reset line for SD8686. I decided that the current vmmc implementation in sdhci wasn't quite complete enough, but it wouldn't be much effort to correct this. Daniel ___ linux-arm-kernel mailing list linux-arm-ker...@lists.infradead.org http://lists.infradead.org/mailman/listinfo/linux-arm-kernel -- To unsubscribe from this list: send the line unsubscribe linux-mmc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH] mmc: sdhci: fix retuning timer wrongly deleted in sdhci_tasklet_finish
On Thu, Jul 21, 2011 at 6:03 PM, Aaron Lu aaron...@amd.com wrote: On Thu, Jul 21, 2011 at 05:35:02PM +0800, zhangfei gao wrote: Does the execute_tuning is called again? del_timer is not delete timer really, but deactivate the timer, which could be re-activated by mod_timer. So if execute_tuning is called, the mod_timer will tigger the tuning timer again. Hi zhangfei, Thanks for the comment. The execute_tuning will be called at two places: 1 In mmc_sd_init_uhs_card, when host is initializing an UHS card, and the re-tuning timer will be activated for the first time; 2 When re-tuning timer expired So if the re-tuning timer is deactivated in sdhci_tasklet_finish, execute_tuning will have no chance of getting called again, and the host will not be able to do the re-tuning anymore. Thanks for explanation, looks good to me. Signed-off-by: Aaron Lu aaron...@amd.com --- drivers/mmc/host/sdhci.c | 3 --- 1 files changed, 0 insertions(+), 3 deletions(-) diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c index 91d9892..6250bac 100644 --- a/drivers/mmc/host/sdhci.c +++ b/drivers/mmc/host/sdhci.c @@ -1863,9 +1863,6 @@ static void sdhci_tasklet_finish(unsigned long param) del_timer(host-timer); - if (host-version = SDHCI_SPEC_300) - del_timer(host-tuning_timer); - mrq = host-mrq; /* -- 1.7.1 -- To unsubscribe from this list: send the line unsubscribe linux-mmc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: mmc: sdio add regulator vsdio
diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c index 790f959..61fff10 100644 --- a/drivers/mmc/host/sdhci.c +++ b/drivers/mmc/host/sdhci.c @@ -1295,6 +1295,18 @@ static void sdhci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) sdhci_set_clock(host, ios-clock); + if (host-vsdio) { Why does this code need to be specific to sdio ? Should be generalized. sdio device, like bt/wlan have the requirement to dynamically control power. Also the runtime_pm introduced to mmc core by Ohad, is specifically for sdio. For mmc/sd, still not consider to dynamically control power, there already regulator vmmc to control power. The requirement for sdio device is more complicated, for example during suspend, sdio device may require continue power on. + if (ios-power_mode != host-power_mode_old) { + if (ios-power_mode == MMC_POWER_OFF) + regulator_disable(host-vsdio); + + if (ios-power_mode == MMC_POWER_UP) + regulator_enable(host-vsdio); + } + + host-power_mode_old = ios-power_mode; move up inside if since if not change no need to set. if the regulator is shared between different devices will this work ? What do you mean different devices. It is considered for different sdio client devices, not consider mmc/sd. + } + if (ios-power_mode == MMC_POWER_OFF) sdhci_set_power(host, -1); else @@ -2751,6 +2763,13 @@ int sdhci_add_host(struct sdhci_host *host) regulator_enable(host-vmmc); } + host-vsdio = regulator_get(mmc_dev(mmc), vsdio); comment on name -- should have nothing to do with sdio. -- To unsubscribe from this list: send the line unsubscribe linux-mmc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: mmc: sdio add regulator vsdio
+ +static int __init brownstone_init_mmc(void) +{ + /* + * PDn: GPIO58; RESETn: GPIO57 + * 8787, RESETn keeps high, PDn control power + * on: PDn 1; off: PDn 0; + */ Comment unclear GPIO57 is power GPIO58 is reset yes, typo, thanks + int RESETn = mfp_to_gpio(MFP_PIN_GPIO58); + + if (gpio_request(RESETn, sdio RESETn)) { + pr_err(Failed to request sdio RESETn gpio\n); + return -EIO; + } + gpio_direction_output(RESETn, 1); + gpio_free(RESETn); The 8787 data sheet indicated that PDn should be inactive as well as reset before initiating power up. Pull PDn high. The PDn is super-set of RESETn, keep RESETn high, and control 8787 with PDn is enough. The Internal Reset in data sheet is not RESET pin. -- To unsubscribe from this list: send the line unsubscribe linux-mmc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH] sdio add regulator vsdio to dynamic control sdio power
sdio client has the requirement to dynamically power on/off With regulator vsdio, so sdio client power on/off when mmc_power_up/down Add brownstone support sdio with regulator vsdio, Zhangfei Gao (2): mmc: sdio add regulator vsdio ARM: mmp2: support sdio with regulator vsdio arch/arm/mach-mmp/brownstone.c | 60 ++- drivers/mmc/host/sdhci.c | 24 include/linux/mmc/sdhci.h |2 + 3 files changed, 84 insertions(+), 2 deletions(-) -- To unsubscribe from this list: send the line unsubscribe linux-mmc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH] mmc: sdio add regulator vsdio
sdio client may be required power on/off dynamically. With regulator vsdio, sdio client power on/off could be executed by mmc_power_up/down CC: Ohad Ben-Cohen o...@wizery.com Signed-off-by: Zhangfei Gao zhangfei@marvell.com --- drivers/mmc/host/sdhci.c | 24 include/linux/mmc/sdhci.h |2 ++ 2 files changed, 26 insertions(+), 0 deletions(-) diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c index 790f959..61fff10 100644 --- a/drivers/mmc/host/sdhci.c +++ b/drivers/mmc/host/sdhci.c @@ -1295,6 +1295,18 @@ static void sdhci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) sdhci_set_clock(host, ios-clock); + if (host-vsdio) { + if (ios-power_mode != host-power_mode_old) { + if (ios-power_mode == MMC_POWER_OFF) + regulator_disable(host-vsdio); + + if (ios-power_mode == MMC_POWER_UP) + regulator_enable(host-vsdio); + } + + host-power_mode_old = ios-power_mode; + } + if (ios-power_mode == MMC_POWER_OFF) sdhci_set_power(host, -1); else @@ -2751,6 +2763,13 @@ int sdhci_add_host(struct sdhci_host *host) regulator_enable(host-vmmc); } + host-vsdio = regulator_get(mmc_dev(mmc), vsdio); + if (IS_ERR(host-vsdio)) + host-vsdio = NULL; + else + printk(KERN_INFO %s: vsdio regulator found\n, + mmc_hostname(mmc)); + sdhci_init(host, 0); #ifdef CONFIG_MMC_DEBUG @@ -2842,6 +2861,11 @@ void sdhci_remove_host(struct sdhci_host *host, int dead) regulator_put(host-vmmc); } + if (host-vsdio) { + regulator_disable(host-vsdio); + regulator_put(host-vsdio); + } + kfree(host-adma_desc); kfree(host-align_buffer); diff --git a/include/linux/mmc/sdhci.h b/include/linux/mmc/sdhci.h index 13c13f8..bea07c7 100644 --- a/include/linux/mmc/sdhci.h +++ b/include/linux/mmc/sdhci.h @@ -94,6 +94,8 @@ struct sdhci_host { const struct sdhci_ops *ops;/* Low level hw interface */ struct regulator *vmmc; /* Power regulator */ + struct regulator *vsdio;/* sdio Power regulator */ + unsigned char power_mode_old; /* power supply mode */ /* Internal data */ struct mmc_host *mmc; /* MMC structure */ -- 1.6.0.4 -- To unsubscribe from this list: send the line unsubscribe linux-mmc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH] ARM: mmp2: support sdio with regulator vsdio
Add regulator vsdio, which controled by mmc core to handle sdio chip power Test With CONFIG_PM_RUNTIME=y 8787 power is enabled if any client module over sdio is insmod, and disbled automatically after all client modules over sdio are rmmod Also 8787 power could be controled by mmc_start/stop_host Signed-off-by: Zhangfei Gao zhangfei@marvell.com --- arch/arm/mach-mmp/brownstone.c | 60 ++- 1 files changed, 58 insertions(+), 2 deletions(-) diff --git a/arch/arm/mach-mmp/brownstone.c b/arch/arm/mach-mmp/brownstone.c index c79162a..63315e2 100644 --- a/arch/arm/mach-mmp/brownstone.c +++ b/arch/arm/mach-mmp/brownstone.c @@ -89,6 +89,9 @@ static unsigned long brownstone_pin_config[] __initdata = { GPIO41_MMC2_CMD | MFP_PULL_HIGH, GPIO42_MMC2_CLK, + GPIO57_GPIO | MFP_LPM_DRIVE_HIGH | MFP_PULL_HIGH, + GPIO58_GPIO | MFP_LPM_DRIVE_HIGH | MFP_PULL_HIGH, + /* MMC2 */ GPIO165_MMC3_DAT7 | MFP_PULL_HIGH, GPIO162_MMC3_DAT6 | MFP_PULL_HIGH, @@ -180,12 +183,66 @@ static struct sdhci_pxa_platdata mmp2_sdh_platdata_mmc0 = { .clk_delay_cycles = 0x1f, }; +static struct sdhci_pxa_platdata mmp2_sdh_platdata_mmc1 = { + .flags = PXA_FLAG_CARD_PERMANENT, +}; + static struct sdhci_pxa_platdata mmp2_sdh_platdata_mmc2 = { .clk_delay_cycles = 0x1f, .flags = PXA_FLAG_CARD_PERMANENT | PXA_FLAG_SD_8_BIT_CAPABLE_SLOT, }; +static struct regulator_consumer_supply sdio_power_supplies[] = { + REGULATOR_SUPPLY(vsdio, sdhci-pxav3.1), +}; + +static struct regulator_init_data sdio_power_data = { + .constraints= { + .valid_ops_mask = REGULATOR_CHANGE_STATUS, + }, + .num_consumer_supplies = ARRAY_SIZE(sdio_power_supplies), + .consumer_supplies = sdio_power_supplies, +}; + +static struct fixed_voltage_config sdio_power = { + .supply_name= vsdio, + .microvolts = 300, + .gpio = mfp_to_gpio(MFP_PIN_GPIO57), + .enable_high= 1, + .enabled_at_boot= 0, + .init_data = sdio_power_data, +}; + +static struct platform_device sdio_power_device = { + .name = reg-fixed-voltage, + .id = 2, + .dev = { + .platform_data = sdio_power, + }, +}; + +static int __init brownstone_init_mmc(void) +{ + /* +* PDn: GPIO58; RESETn: GPIO57 +* 8787, RESETn keeps high, PDn control power +* on: PDn 1; off: PDn 0; +*/ + int RESETn = mfp_to_gpio(MFP_PIN_GPIO58); + + if (gpio_request(RESETn, sdio RESETn)) { + pr_err(Failed to request sdio RESETn gpio\n); + return -EIO; + } + gpio_direction_output(RESETn, 1); + gpio_free(RESETn); + + platform_device_register(sdio_power_device); + mmp2_add_sdhost(0, mmp2_sdh_platdata_mmc0); /* SD/MMC */ + mmp2_add_sdhost(1, mmp2_sdh_platdata_mmc1); /* sdio */ + mmp2_add_sdhost(2, mmp2_sdh_platdata_mmc2); /* eMMC */ +} static void __init brownstone_init(void) { @@ -195,8 +252,7 @@ static void __init brownstone_init(void) mmp2_add_uart(1); mmp2_add_uart(3); mmp2_add_twsi(1, NULL, ARRAY_AND_SIZE(brownstone_twsi1_info)); - mmp2_add_sdhost(0, mmp2_sdh_platdata_mmc0); /* SD/MMC */ - mmp2_add_sdhost(2, mmp2_sdh_platdata_mmc2); /* eMMC */ + brownstone_init_mmc(); /* enable 5v regulator */ platform_device_register(brownstone_v_5vp_device); -- 1.6.0.4 -- To unsubscribe from this list: send the line unsubscribe linux-mmc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH] sdhci: pxav3 controller needs 32 bit ADMA addressing
On Tue, Jul 12, 2011 at 5:47 AM, Philip Rakity prak...@marvell.com wrote: enable the quirk. Best used in conjunction with patch downgrading ADMA to SDMA when transfer is not aligned. Signed-off-by: Philip Rakity prak...@marvell.com --- drivers/mmc/host/sdhci-pxav3.c | 3 ++- 1 files changed, 2 insertions(+), 1 deletions(-) diff --git a/drivers/mmc/host/sdhci-pxav3.c b/drivers/mmc/host/sdhci-pxav3.c index 4198dbb..fc7e4a5 100644 --- a/drivers/mmc/host/sdhci-pxav3.c +++ b/drivers/mmc/host/sdhci-pxav3.c @@ -195,7 +195,8 @@ static int __devinit sdhci_pxav3_probe(struct platform_device *pdev) clk_enable(clk); host-quirks = SDHCI_QUIRK_BROKEN_TIMEOUT_VAL - | SDHCI_QUIRK_NO_ENDATTR_IN_NOPDESC; + | SDHCI_QUIRK_NO_ENDATTR_IN_NOPDESC + | SDHCI_QUIRK_32BIT_ADMA_SIZE; /* enable 1/8V DDR capable */ host-mmc-caps |= MMC_CAP_1_8V_DDR; -- 1.7.0.4 Acked-by: Zhangfei Gao zhangfei@marvell.com -- To unsubscribe from this list: send the line unsubscribe linux-mmc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v3] arm: mach-mmp: brownstone.c support multiple sd slots
On Wed, Jul 6, 2011 at 4:20 AM, Philip Rakity prak...@marvell.com wrote: Subject: [PATCH V3] arm: mach-mmp: brownstone.c support multiple sd slots V3 == Change since V2 -- delete mmc3 since it was committed to linux next. enable mmc1 used for wifi (8688) and marked PERMANENT. Wifi requires enabling of power on the device by toggling the gpio lines for power and reset. Enable eMMC first to work around problem in booting order due to workqueue bug. Signed-off-by: Philip Rakity prak...@marvell.com --- arch/arm/mach-mmp/brownstone.c | 41 +++- 1 files changed, 40 insertions(+), 1 deletions(-) diff --git a/arch/arm/mach-mmp/brownstone.c b/arch/arm/mach-mmp/brownstone.c index c79162a..940982c 100644 --- a/arch/arm/mach-mmp/brownstone.c +++ b/arch/arm/mach-mmp/brownstone.c @@ -19,6 +19,7 @@ #include linux/regulator/max8649.h #include linux/regulator/fixed.h #include linux/mfd/max8925.h +#include linux/delay.h #include asm/mach-types.h #include asm/mach/arch.h @@ -180,6 +181,11 @@ static struct sdhci_pxa_platdata mmp2_sdh_platdata_mmc0 = { .clk_delay_cycles = 0x1f, }; +static struct sdhci_pxa_platdata mmp2_sdh_platdata_mmc1 = { + .clk_delay_cycles = 0x1f, + .flags = PXA_FLAG_CARD_PERMANENT, +}; + static struct sdhci_pxa_platdata mmp2_sdh_platdata_mmc2 = { .clk_delay_cycles = 0x1f, .flags = PXA_FLAG_CARD_PERMANENT @@ -187,6 +193,38 @@ static struct sdhci_pxa_platdata mmp2_sdh_platdata_mmc2 = { }; +static void __init mmc_sdio_wifi(void) +{ + int poweron; + int reset; + + poweron = mfp_to_gpio(GPIO57_GPIO); + reset = mfp_to_gpio(GPIO58_GPIO); + + if (gpio_request(reset, sd8xxx reset)) { + printk(KERN_INFO gpio %d request failed\n, reset); + return; + } + + if (gpio_request(poweron, sd8xxx PDn)) { + gpio_free(reset); + printk(KERN_INFO gpio %d request failed\n, poweron); + return; + } + + gpio_direction_output(poweron, 0); + msleep(1); + gpio_direction_output(poweron, 1); + msleep(1); + gpio_direction_output(reset, 0); + msleep(1); + gpio_direction_output(reset, 1); + gpio_free(reset); + gpio_free(poweron); + + mmp2_add_sdhost(1, mmp2_sdh_platdata_mmc1); /* Wifi */ +} + The method keeps power on wifi chip, without dynamically enable/disable wifi power, which is not final solution. How about pushing later with dynamically control power, which is in debugging here. static void __init brownstone_init(void) { mfp_config(ARRAY_AND_SIZE(brownstone_pin_config)); @@ -195,8 +233,9 @@ static void __init brownstone_init(void) mmp2_add_uart(1); mmp2_add_uart(3); mmp2_add_twsi(1, NULL, ARRAY_AND_SIZE(brownstone_twsi1_info)); - mmp2_add_sdhost(0, mmp2_sdh_platdata_mmc0); /* SD/MMC */ mmp2_add_sdhost(2, mmp2_sdh_platdata_mmc2); /* eMMC */ + mmp2_add_sdhost(0, mmp2_sdh_platdata_mmc0); /* SD/MMC */ + mmc_sdio_wifi(); /* enable 5v regulator */ platform_device_register(brownstone_v_5vp_device); -- 1.7.0.4 -- To unsubscribe from this list: send the line unsubscribe linux-mmc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v2] arm: mach-mmp: brownstone.c support multiple sd slots
On Tue, Jul 5, 2011 at 2:52 PM, Eric Miao eric.y.m...@gmail.com wrote: On Fri, Apr 29, 2011 at 4:45 AM, Philip Rakity prak...@marvell.com wrote: Support multiple sd/eMMC interfaces. enable mmc1, 2, and 3. mmc2 is used eMMC and slot is marked PERMANENT and 8 bit device. mmc1 is used for Wifi and slot is marked PERMANENT Note: eMMC (mmc2) is set to initialize first to workaround a problem where booting in logical order requires mmc create work queue to be multi-threaded otherwise boot process hangs. BUG report send to linux-mmc and linux-kernel mailing list. Wifi (mmc1) requires we enable power on the device by toggling the gpio lines for power and reset. Signed-off-by: Philip Rakity prak...@marvell.com Applied. Though the email client was fiddling the spaces/CR-LF a bit. --- arch/arm/mach-mmp/brownstone.c | 52 +++- 1 files changed, 51 insertions(+), 1 deletions(-) Hi, Eric arch/arm/mach-mmp/brownstone.c has already been modified from mmc-next, here will have conflict. Sorry for inconvenience. Thanks -- To unsubscribe from this list: send the line unsubscribe linux-mmc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH] mmc: sdio: reset card during power_restore
So wlan probe function should be called for re-downloading, is it be achieved by calling pm_runtime_get_sync and mmc_power_restore_host? Not really; I assume you refer to libertas_sdio, which AFAICT, is built to power on the device (and configure it) on -probe(), and then power it off on -remove(). It then seems that this model was extended to support suspend/resume by asking the MMC core to -remove() the card on suspend, and then relying on it to re-detect and re-add the card on resume, which will trigger libertas' -probe() again. IMHO this model is a little awkward; as you can see, powering on/off the chip requires re-probing the driver. Take a look how mac80211 drivers (and wl12xx in particular) behave: they are powered on (and firmware is downloaded) when the user brings the wlan0 interface up, and then powered off when the wlan interface is brought down. The runtime PM API is only being used to control the power to the device, but downloading the firmware and doing driver-specific configuration is up to the driver to do. Thanks Ohad for your kind explanation. However still not fully understand how to call -remove to power off wlan, using suspend system looks to me is only test method, which counting on bus_ops-suspend returns -ENOSYS. What we do before is 1. From user space use rfkill unblock wifi, or echo on/off /sys/~ to enable/disable wlan power, which could be replaced by pm_runtime of course. 2. Explicitly call mmc_detect_change, when power off, mmc_rescan - bus_ops-detect(host) - mmc_select_card fail - mmc_sdio_remove; when power on, mmc_rescan - mmc_attach_sdio-wlan probe. However, this is not workable if using mmc_power_save_host, since bus_ops-detect not workable after power off card. 1. detect is only for !MMC_CAP_NONREMOVABLE 2. In mmc_sdio_detect, power is provided before mmc_select_card via pm_runtime_get_sync. 3. Most important, mmc_power_save_host-mmc_power_off-set clk=0 via set_ios, so controller will no response and timeout. How to enable/disable mac80211 at runtime from user space? In wl12xx/debugfs.c, gpio_power_write-wl1271_sdio_power_off? still unclear how remove is called. Thanks -- To unsubscribe from this list: send the line unsubscribe linux-mmc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH] mmc: sdio: reset card during power_restore
Hi, Ohad One question :( Under pm_runtime mechanism, how to dynamically open/close wlan. If the wlan chip really power off, the firmware should be reloaded, since the firmware is download to ram and disappear after power off. So wlan probe function should be called for re-downloading, is it be achieved by calling pm_runtime_get_sync and mmc_power_restore_host? From Daniel's test log, echo mem /sys/power/state is used to restart wlan, is this standard method? Since host-bus_ops is already not NULL, mmc_rescan will return direclty. Thanks -- To unsubscribe from this list: send the line unsubscribe linux-mmc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH] mmc: sdhci-pxa move platform data to include/linux/platform_data
As suggested by Arnd, move platform data to include/linux/platform_data, Add 'depends on CLKDEV_LOOKUP' since clk API is used, As a result driver could be built on all platforms which support CLKDEV_LOOKUP This can improve the build test coverage Signed-off-by: Zhangfei Gao zhangfei@marvell.com CC: Arnd Bergmann a...@arndb.de --- arch/arm/mach-mmp/include/mach/mmp2.h |2 +- drivers/mmc/host/Kconfig |2 ++ drivers/mmc/host/sdhci-pxav2.c |2 +- drivers/mmc/host/sdhci-pxav3.c |2 +- .../linux/platform_data/pxa_sdhci.h| 10 +- 5 files changed, 10 insertions(+), 8 deletions(-) rename arch/arm/plat-pxa/include/plat/sdhci.h = include/linux/platform_data/pxa_sdhci.h (92%) diff --git a/arch/arm/mach-mmp/include/mach/mmp2.h b/arch/arm/mach-mmp/include/mach/mmp2.h index 2cbf6df..de7b888 100644 --- a/arch/arm/mach-mmp/include/mach/mmp2.h +++ b/arch/arm/mach-mmp/include/mach/mmp2.h @@ -1,7 +1,7 @@ #ifndef __ASM_MACH_MMP2_H #define __ASM_MACH_MMP2_H -#include plat/sdhci.h +#include linux/platform_data/pxa_sdhci.h struct sys_timer; diff --git a/drivers/mmc/host/Kconfig b/drivers/mmc/host/Kconfig index 198ddda..204ad7c 100644 --- a/drivers/mmc/host/Kconfig +++ b/drivers/mmc/host/Kconfig @@ -183,6 +183,7 @@ config MMC_SDHCI_S3C config MMC_SDHCI_PXAV3 tristate Marvell MMP2 SD Host Controller support (PXAV3) + depends on CLKDEV_LOOKUP select MMC_SDHCI select MMC_SDHCI_PLTFM default CPU_MMP2 @@ -195,6 +196,7 @@ config MMC_SDHCI_PXAV3 config MMC_SDHCI_PXAV2 tristate Marvell PXA9XX SD Host Controller support (PXAV2) + depends on CLKDEV_LOOKUP select MMC_SDHCI select MMC_SDHCI_PLTFM default CPU_PXA910 diff --git a/drivers/mmc/host/sdhci-pxav2.c b/drivers/mmc/host/sdhci-pxav2.c index 7a6fa8c..38f5899 100644 --- a/drivers/mmc/host/sdhci-pxav2.c +++ b/drivers/mmc/host/sdhci-pxav2.c @@ -25,7 +25,7 @@ #include linux/gpio.h #include linux/mmc/card.h #include linux/mmc/host.h -#include plat/sdhci.h +#include linux/platform_data/pxa_sdhci.h #include linux/slab.h #include sdhci.h #include sdhci-pltfm.h diff --git a/drivers/mmc/host/sdhci-pxav3.c b/drivers/mmc/host/sdhci-pxav3.c index 901f00f..4198dbb 100644 --- a/drivers/mmc/host/sdhci-pxav3.c +++ b/drivers/mmc/host/sdhci-pxav3.c @@ -24,7 +24,7 @@ #include linux/gpio.h #include linux/mmc/card.h #include linux/mmc/host.h -#include plat/sdhci.h +#include linux/platform_data/pxa_sdhci.h #include linux/slab.h #include linux/delay.h #include sdhci.h diff --git a/arch/arm/plat-pxa/include/plat/sdhci.h b/include/linux/platform_data/pxa_sdhci.h similarity index 92% rename from arch/arm/plat-pxa/include/plat/sdhci.h rename to include/linux/platform_data/pxa_sdhci.h index 800ebc1..51ad099 100644 --- a/arch/arm/plat-pxa/include/plat/sdhci.h +++ b/include/linux/platform_data/pxa_sdhci.h @@ -1,4 +1,5 @@ -/* linux/arch/arm/plat-pxa/include/plat/sdhci.h +/* + * include/linux/platform_data/pxa_sdhci.h * * Copyright 2010 Marvell * Zhangfei Gao zhangfei@marvell.com @@ -10,8 +11,8 @@ * published by the Free Software Foundation. */ -#ifndef __PLAT_PXA_SDHCI_H -#define __PLAT_PXA_SDHCI_H +#ifndef _PXA_SDHCI_H_ +#define _PXA_SDHCI_H_ /* pxa specific flag */ /* Require clock free running */ @@ -56,5 +57,4 @@ struct sdhci_pxa { u8 clk_enable; u8 power_mode; }; - -#endif /* __PLAT_PXA_SDHCI_H */ +#endif /* _PXA_SDHCI_H_ */ -- 1.7.0.4 -- To unsubscribe from this list: send the line unsubscribe linux-mmc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH] mmc: sdhci-pxa move platform data to include/linux/platform_data
resend: As suggested by Arnd, move platform data to include/linux/platform_data. Add 'depends on CLKDEV_LOOKUP' since clk API is used, As a result driver could be built on all platforms which support CLKDEV_LOOKUP, which can improve the build test coverage. CC: Arnd Bergmann a...@arndb.de CC: Stephen Rothwell s...@canb.auug.org.au Signed-off-by: Zhangfei Gao zhangfei@marvell.com Acked-by: Arnd Bergmann a...@arndb.de --- arch/arm/mach-mmp/include/mach/mmp2.h |2 +- drivers/mmc/host/Kconfig |2 ++ drivers/mmc/host/sdhci-pxav2.c |2 +- drivers/mmc/host/sdhci-pxav3.c |2 +- .../linux/platform_data/pxa_sdhci.h| 10 +- 5 files changed, 10 insertions(+), 8 deletions(-) rename arch/arm/plat-pxa/include/plat/sdhci.h = include/linux/platform_data/pxa_sdhci.h (92%) diff --git a/arch/arm/mach-mmp/include/mach/mmp2.h b/arch/arm/mach-mmp/include/mach/mmp2.h index 2cbf6df..de7b888 100644 --- a/arch/arm/mach-mmp/include/mach/mmp2.h +++ b/arch/arm/mach-mmp/include/mach/mmp2.h @@ -1,7 +1,7 @@ #ifndef __ASM_MACH_MMP2_H #define __ASM_MACH_MMP2_H -#include plat/sdhci.h +#include linux/platform_data/pxa_sdhci.h struct sys_timer; diff --git a/drivers/mmc/host/Kconfig b/drivers/mmc/host/Kconfig index 198ddda..204ad7c 100644 --- a/drivers/mmc/host/Kconfig +++ b/drivers/mmc/host/Kconfig @@ -183,6 +183,7 @@ config MMC_SDHCI_S3C config MMC_SDHCI_PXAV3 tristate Marvell MMP2 SD Host Controller support (PXAV3) + depends on CLKDEV_LOOKUP select MMC_SDHCI select MMC_SDHCI_PLTFM default CPU_MMP2 @@ -195,6 +196,7 @@ config MMC_SDHCI_PXAV3 config MMC_SDHCI_PXAV2 tristate Marvell PXA9XX SD Host Controller support (PXAV2) + depends on CLKDEV_LOOKUP select MMC_SDHCI select MMC_SDHCI_PLTFM default CPU_PXA910 diff --git a/drivers/mmc/host/sdhci-pxav2.c b/drivers/mmc/host/sdhci-pxav2.c index 7a6fa8c..38f5899 100644 --- a/drivers/mmc/host/sdhci-pxav2.c +++ b/drivers/mmc/host/sdhci-pxav2.c @@ -25,7 +25,7 @@ #include linux/gpio.h #include linux/mmc/card.h #include linux/mmc/host.h -#include plat/sdhci.h +#include linux/platform_data/pxa_sdhci.h #include linux/slab.h #include sdhci.h #include sdhci-pltfm.h diff --git a/drivers/mmc/host/sdhci-pxav3.c b/drivers/mmc/host/sdhci-pxav3.c index 901f00f..4198dbb 100644 --- a/drivers/mmc/host/sdhci-pxav3.c +++ b/drivers/mmc/host/sdhci-pxav3.c @@ -24,7 +24,7 @@ #include linux/gpio.h #include linux/mmc/card.h #include linux/mmc/host.h -#include plat/sdhci.h +#include linux/platform_data/pxa_sdhci.h #include linux/slab.h #include linux/delay.h #include sdhci.h diff --git a/arch/arm/plat-pxa/include/plat/sdhci.h b/include/linux/platform_data/pxa_sdhci.h similarity index 92% rename from arch/arm/plat-pxa/include/plat/sdhci.h rename to include/linux/platform_data/pxa_sdhci.h index 800ebc1..51ad099 100644 --- a/arch/arm/plat-pxa/include/plat/sdhci.h +++ b/include/linux/platform_data/pxa_sdhci.h @@ -1,4 +1,5 @@ -/* linux/arch/arm/plat-pxa/include/plat/sdhci.h +/* + * include/linux/platform_data/pxa_sdhci.h * * Copyright 2010 Marvell * Zhangfei Gao zhangfei@marvell.com @@ -10,8 +11,8 @@ * published by the Free Software Foundation. */ -#ifndef __PLAT_PXA_SDHCI_H -#define __PLAT_PXA_SDHCI_H +#ifndef _PXA_SDHCI_H_ +#define _PXA_SDHCI_H_ /* pxa specific flag */ /* Require clock free running */ @@ -56,5 +57,4 @@ struct sdhci_pxa { u8 clk_enable; u8 power_mode; }; - -#endif /* __PLAT_PXA_SDHCI_H */ +#endif /* _PXA_SDHCI_H_ */ -- 1.7.0.4 -- To unsubscribe from this list: send the line unsubscribe linux-mmc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: UHS-I bus speed mode should be set last in UHS initialization
On Wed, Jun 15, 2011 at 7:57 AM, subha...@codeaurora.org wrote: Hi Arindam, -Original Message- From: linux-mmc-ow...@vger.kernel.org [mailto:linux-mmc- ow...@vger.kernel.org] On Behalf Of Nath, Arindam Sent: Tuesday, June 14, 2011 12:00 AM To: subha...@codeaurora.org Cc: Philip Rakity; zhangfei gao; c...@laptop.org; linux- m...@vger.kernel.org; Lu, Aaron Subject: RE: UHS-I bus speed mode should be set last in UHS initialization Adding Philip and Zhangfei. Hi Subhash, Does your controller follow some non-standard steps for initialization? I referred to Figure 3-14, section 3.9.4 of Physical Layer Spec v3.01, and it shows the order, setting Driver Strength Select, Bus Speed Mode, and then Current Limit. So please confirm back. Sorry, I don't know what do you mean by non standard steps for initialization. Nowhere in v3.01 spec, it is mentioned that Bus speed mode **must** be set before current limit. Figure 3-14 also doesn't indicate this. If you set the bus speed mode in sd_set_bus_speed_mode(), you are changing the host controller timings as well and if it's SDR50/SDR104 mode, then immediately after setting the host controller timing mode, we have to execute tuning sequence but here before executing tuning sequence, you are sending the CMD6 which involves the read data transfer from card which is bound to fail without tuning and it does fail with our host controller. Do let me know if this explanation make sense. I think the concern does make sense. Though Figure 3-14 and 4-6 describe Bus Speed Mode is selected ahead of Current limit, the controller timing is changed in sd_set_bus_speed_mode, which may cause following cmd6 fail. However, the test here shows mmp2 does not care the sequence of speed_mode and current_limit. Thanks -- To unsubscribe from this list: send the line unsubscribe linux-mmc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v4 2/5] mmc: support sdhci-pxav2.c
+static void pxav2_set_private_registers(struct sdhci_host *host, u8 mask) +{ + struct platform_device *pdev = to_platform_device(mmc_dev(host-mmc)); + struct sdhci_pxa_platdata *pdata = pdev-dev.platform_data; + + if (mask == SDHCI_RESET_ALL) { + u16 tmp = 0; + + /* + * tune timing of read data/command when crc error happen + * no performance impact + */ + if (pdata-clk_delay_sel == 1) { + tmp = readw(host-ioaddr + SD_CLOCK_BURST_SIZE_SETUP); + + tmp = ~(SDCLK_DELAY_MASK SDCLK_DELAY_SHIFT); + tmp |= (pdata-clk_delay_cycles SDCLK_DELAY_MASK) + SDCLK_DELAY_SHIFT; + tmp = ~(SDCLK_SEL_MASK SDCLK_SEL_SHIFT); + tmp |= (1 SDCLK_SEL_MASK) SDCLK_SEL_SHIFT; + + writew(tmp, host-ioaddr + SD_CLOCK_BURST_SIZE_SETUP); + } There are 3 possible value for clk_delay_sel. 0 == do not use clk_delay_cycles 1 == use programmed clk_delay_cycles value (the code above) all other values use the sd_clk which was used to drive the output The code about only handles 2 of the 3 cases pxa910/920 only require two cases. 1, clk_delay_sel = 1 with delay value. 2, use default setting and directly use sd_clk. clk_delay_sel = 3. suggest (if (pdata-clk_delay_sel) { + if (pdata-clk_delay_sel == 1) { + tmp = readw(host-ioaddr + SD_CLOCK_BURST_SIZE_SETUP); + + tmp = ~(SDCLK_DELAY_MASK SDCLK_DELAY_SHIFT); + tmp |= (pdata-clk_delay_cycles SDCLK_DELAY_MASK) + SDCLK_DELAY_SHIFT; + tmp = ~(SDCLK_SEL_MASK SDCLK_SEL_SHIFT); + tmp |= 1 SDCLK_SEL_SHIFT; + + writew(tmp, host-ioaddr + SD_CLOCK_BURST_SIZE_SETUP); + } else { + tmp = readw(host-ioaddr + SD_CLOCK_BURST_SIZE_SETUP); + tmp = ~(SDCLK_SEL_MASK SDCLK_SEL_SHIFT); + tmp |= 2 SDCLK_SEL_SHIFT; + writew(tmp, host-ioaddr + SD_CLOCK_BURST_SIZE_SETUP); The else is default setting on pxa910 after reset. } } Philip and Mark ___ linux-arm-kernel mailing list linux-arm-ker...@lists.infradead.org http://lists.infradead.org/mailman/listinfo/linux-arm-kernel -- To unsubscribe from this list: send the line unsubscribe linux-mmc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: MMC runtime PM patches break libertas probe
On Fri, Jun 10, 2011 at 12:28 PM, Ohad Ben-Cohen o...@wizery.com wrote: Hi Zhangfei, On Fri, Jun 10, 2011 at 5:02 AM, zhangfei gao zhangfei@gmail.com wrote: Here is answer got from the sd8686 maintainer. For 8686, the SDIO state machine can only handle init sequence (CMD5, 5, 3, 7) from host once. If host sends another init sequence, it will not be able to handle CMD5 and causes the SDIO block to hang. Chips that are newer than 8686 will be able to handle multiple init sequence from host. Thanks for the reply ! So yes, for 8686, an IO reset is needed before host can send a new set of init sequence. But if we're powering down and up the device first, then the init sequence is considered the first one, and then we don't need an IO reset, right ? That was what we wondered about. Hi Ohad, If you power down and up the device, then IO reset is not needed and 8686 can process host init sequence correctly. CC Benson. Thanks, Ohad. -- To unsubscribe from this list: send the line unsubscribe linux-mmc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v4 1/5] mmc: support sdhci-pxav3.c
SDHCI driver for PXAV3 SoCs, such as MMP2, the driver based on sdhci-pltfm to handle resource etc. Signed-off-by: Zhangfei Gao zhangfei@marvell.com Signed-off-by: Philip Rakity prak...@marvell.com --- arch/arm/plat-pxa/include/plat/sdhci.h | 35 - drivers/mmc/host/Kconfig | 12 ++ drivers/mmc/host/Makefile |1 + drivers/mmc/host/sdhci-pxav3.c | 289 4 files changed, 332 insertions(+), 5 deletions(-) create mode 100644 drivers/mmc/host/sdhci-pxav3.c diff --git a/arch/arm/plat-pxa/include/plat/sdhci.h b/arch/arm/plat-pxa/include/plat/sdhci.h index 1ab332e..6873dc5 100644 --- a/arch/arm/plat-pxa/include/plat/sdhci.h +++ b/arch/arm/plat-pxa/include/plat/sdhci.h @@ -15,21 +15,46 @@ /* pxa specific flag */ /* Require clock free running */ -#define PXA_FLAG_DISABLE_CLOCK_GATING (10) - +#define PXA_FLAG_ENABLE_CLOCK_GATING (10) +/* card alwayes wired to host, like on-chip emmc */ +#define PXA_FLAG_CARD_PERMANENT(11) /* Board design supports 8-bit data on SD/SDIO BUS */ #define PXA_FLAG_SD_8_BIT_CAPABLE_SLOT (12) /* * struct pxa_sdhci_platdata() - Platform device data for PXA SDHCI - * @max_speed: the maximum speed supported - * @quirks: quirks of specific device * @flags: flags for platform requirement + * @clk_delay_cycles: + * mmp2: each step is roughly 100ps, 5bits width + * pxa910: each step is 1ns, 4bits width + * @clk_delay_sel: select clk_delay, used on pxa910 + * 0: choose feedback clk + * 1: choose feedback clk + delay value + * 2: choose internal clk + * @clk_delay_enable: enable clk_delay or not, used on pxa910 + * @ext_cd_gpio: gpio pin used for external CD line + * @ext_cd_gpio_invert: invert values for external CD gpio line + * @max_speed: the maximum speed supported + * @host_caps: Standard MMC host capabilities bit field. + * @quirks: quirks of platfrom + * @pm_caps: pm_caps of platfrom */ struct sdhci_pxa_platdata { + unsigned intflags; + unsigned intclk_delay_cycles; + unsigned intclk_delay_sel; + boolclk_delay_enable; + unsigned intext_cd_gpio; + boolext_cd_gpio_invert; unsigned intmax_speed; + unsigned inthost_caps; unsigned intquirks; - unsigned intflags; + unsigned intpm_caps; +}; + +struct sdhci_pxa { + u8 clk_enable; + u8 power_mode; }; #endif /* __PLAT_PXA_SDHCI_H */ diff --git a/drivers/mmc/host/Kconfig b/drivers/mmc/host/Kconfig index 74e77c9..6525a04 100644 --- a/drivers/mmc/host/Kconfig +++ b/drivers/mmc/host/Kconfig @@ -193,6 +193,18 @@ config MMC_SDHCI_PXA If unsure, say N. +config MMC_SDHCI_PXAV3 + tristate Marvell MMP2 SD Host Controller support (PXAV3) + select MMC_SDHCI + select MMC_SDHCI_PLTFM + default CPU_MMP2 + help + This selects the Marvell(R) PXAV3 SD Host Controller. + If you have a MMP2 platform with SD Host Controller + and a card slot, say Y or M here. + + If unsure, say N. + config MMC_SDHCI_SPEAR tristate SDHCI support on ST SPEAr platform depends on MMC_SDHCI PLAT_SPEAR diff --git a/drivers/mmc/host/Makefile b/drivers/mmc/host/Makefile index bf479ab..688cc52 100644 --- a/drivers/mmc/host/Makefile +++ b/drivers/mmc/host/Makefile @@ -10,6 +10,7 @@ obj-$(CONFIG_MMC_MXS) += mxs-mmc.o obj-$(CONFIG_MMC_SDHCI)+= sdhci.o obj-$(CONFIG_MMC_SDHCI_PCI)+= sdhci-pci.o obj-$(CONFIG_MMC_SDHCI_PXA)+= sdhci-pxa.o +obj-$(CONFIG_MMC_SDHCI_PXAV3) += sdhci-pxav3.o obj-$(CONFIG_MMC_SDHCI_S3C)+= sdhci-s3c.o obj-$(CONFIG_MMC_SDHCI_SPEAR) += sdhci-spear.o obj-$(CONFIG_MMC_WBSD) += wbsd.o diff --git a/drivers/mmc/host/sdhci-pxav3.c b/drivers/mmc/host/sdhci-pxav3.c new file mode 100644 index 000..901f00f --- /dev/null +++ b/drivers/mmc/host/sdhci-pxav3.c @@ -0,0 +1,289 @@ +/* + * Copyright (C) 2010 Marvell International Ltd. + * Zhangfei Gao zhangfei@marvell.com + * Kevin Wang dwa...@marvell.com + * Mingwei Wang mww...@marvell.com + * Philip Rakity prak...@marvell.com + * Mark Brown ma...@marvell.com + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ +#include linux/err.h +#include linux/init.h +#include linux/platform_device.h +#include linux/clk.h +#include linux/io.h +#include linux/gpio.h +#include linux/mmc/card.h +#include linux/mmc/host.h +#include plat/sdhci.h
[PATCH v4 2/5] mmc: support sdhci-pxav2.c
SDHCI driver for PXAV2 SoCs, such as pxa910, the driver based on sdhci-pltfm to handle resource etc. Signed-off-by: Zhangfei Gao zhangfei@marvell.com Signed-off-by: Jun Nie n...@marvell.com Signed-off-by: Qiming Wu w...@marvell.com --- drivers/mmc/host/Kconfig | 12 ++ drivers/mmc/host/Makefile |1 + drivers/mmc/host/sdhci-pxav2.c | 244 3 files changed, 257 insertions(+), 0 deletions(-) create mode 100644 drivers/mmc/host/sdhci-pxav2.c diff --git a/drivers/mmc/host/Kconfig b/drivers/mmc/host/Kconfig index 6525a04..97b8322 100644 --- a/drivers/mmc/host/Kconfig +++ b/drivers/mmc/host/Kconfig @@ -205,6 +205,18 @@ config MMC_SDHCI_PXAV3 If unsure, say N. +config MMC_SDHCI_PXAV2 + tristate Marvell PXA9XX SD Host Controller support (PXAV2) + select MMC_SDHCI + select MMC_SDHCI_PLTFM + default CPU_PXA910 + help + This selects the Marvell(R) PXAV2 SD Host Controller. + If you have a PXA9XX platform with SD Host Controller + and a card slot, say Y or M here. + + If unsure, say N. + config MMC_SDHCI_SPEAR tristate SDHCI support on ST SPEAr platform depends on MMC_SDHCI PLAT_SPEAR diff --git a/drivers/mmc/host/Makefile b/drivers/mmc/host/Makefile index 688cc52..99f7d79 100644 --- a/drivers/mmc/host/Makefile +++ b/drivers/mmc/host/Makefile @@ -11,6 +11,7 @@ obj-$(CONFIG_MMC_SDHCI) += sdhci.o obj-$(CONFIG_MMC_SDHCI_PCI)+= sdhci-pci.o obj-$(CONFIG_MMC_SDHCI_PXA)+= sdhci-pxa.o obj-$(CONFIG_MMC_SDHCI_PXAV3) += sdhci-pxav3.o +obj-$(CONFIG_MMC_SDHCI_PXAV2) += sdhci-pxav2.o obj-$(CONFIG_MMC_SDHCI_S3C)+= sdhci-s3c.o obj-$(CONFIG_MMC_SDHCI_SPEAR) += sdhci-spear.o obj-$(CONFIG_MMC_WBSD) += wbsd.o diff --git a/drivers/mmc/host/sdhci-pxav2.c b/drivers/mmc/host/sdhci-pxav2.c new file mode 100644 index 000..7a6fa8c --- /dev/null +++ b/drivers/mmc/host/sdhci-pxav2.c @@ -0,0 +1,244 @@ +/* + * Copyright (C) 2010 Marvell International Ltd. + * Zhangfei Gao zhangfei@marvell.com + * Kevin Wang dwa...@marvell.com + * Jun Nie n...@marvell.com + * Qiming Wu w...@marvell.com + * Philip Rakity prak...@marvell.com + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#include linux/err.h +#include linux/init.h +#include linux/platform_device.h +#include linux/clk.h +#include linux/io.h +#include linux/gpio.h +#include linux/mmc/card.h +#include linux/mmc/host.h +#include plat/sdhci.h +#include linux/slab.h +#include sdhci.h +#include sdhci-pltfm.h + +#define SD_FIFO_PARAM 0xe0 +#define DIS_PAD_SD_CLK_GATE0x0400 /* Turn on/off Dynamic SD Clock Gating */ +#define CLK_GATE_ON0x0200 /* Disable/enable Clock Gate */ +#define CLK_GATE_CTL 0x0100 /* Clock Gate Control */ +#define CLK_GATE_SETTING_BITS (DIS_PAD_SD_CLK_GATE | \ + CLK_GATE_ON | CLK_GATE_CTL) + +#define SD_CLOCK_BURST_SIZE_SETUP 0xe6 +#define SDCLK_SEL_SHIFT8 +#define SDCLK_SEL_MASK 0x3 +#define SDCLK_DELAY_SHIFT 10 +#define SDCLK_DELAY_MASK 0x3c + +#define SD_CE_ATA_20xea +#define MMC_CARD 0x1000 +#define MMC_WIDTH 0x0100 + +static void pxav2_set_private_registers(struct sdhci_host *host, u8 mask) +{ + struct platform_device *pdev = to_platform_device(mmc_dev(host-mmc)); + struct sdhci_pxa_platdata *pdata = pdev-dev.platform_data; + + if (mask == SDHCI_RESET_ALL) { + u16 tmp = 0; + + /* +* tune timing of read data/command when crc error happen +* no performance impact +*/ + if (pdata-clk_delay_sel == 1) { + tmp = readw(host-ioaddr + SD_CLOCK_BURST_SIZE_SETUP); + + tmp = ~(SDCLK_DELAY_MASK SDCLK_DELAY_SHIFT); + tmp |= (pdata-clk_delay_cycles SDCLK_DELAY_MASK) +SDCLK_DELAY_SHIFT; + tmp = ~(SDCLK_SEL_MASK SDCLK_SEL_SHIFT); + tmp |= (1 SDCLK_SEL_MASK) SDCLK_SEL_SHIFT; + + writew(tmp, host-ioaddr + SD_CLOCK_BURST_SIZE_SETUP); + } + + if (pdata-flags PXA_FLAG_ENABLE_CLOCK_GATING) { + tmp = readw(host-ioaddr + SD_FIFO_PARAM); + tmp = ~CLK_GATE_SETTING_BITS; + writew(tmp, host-ioaddr + SD_FIFO_PARAM
[PATCH v4 3/5] ARM: mmp2: update mmp2 mmc resource
mmp2 mmc driver name update to sdhci-pxav3 according to sdhci-pxav3.c Signed-off-by: Zhangfei Gao zhangfei@marvell.com --- arch/arm/mach-mmp/brownstone.c | 10 +- arch/arm/mach-mmp/jasper.c |2 +- arch/arm/mach-mmp/mmp2.c | 16 3 files changed, 18 insertions(+), 10 deletions(-) diff --git a/arch/arm/mach-mmp/brownstone.c b/arch/arm/mach-mmp/brownstone.c index 7bb78fd..c79162a 100644 --- a/arch/arm/mach-mmp/brownstone.c +++ b/arch/arm/mach-mmp/brownstone.c @@ -177,9 +177,16 @@ static struct i2c_board_info brownstone_twsi1_info[] = { }; static struct sdhci_pxa_platdata mmp2_sdh_platdata_mmc0 = { - .max_speed = 2500, + .clk_delay_cycles = 0x1f, }; +static struct sdhci_pxa_platdata mmp2_sdh_platdata_mmc2 = { + .clk_delay_cycles = 0x1f, + .flags = PXA_FLAG_CARD_PERMANENT + | PXA_FLAG_SD_8_BIT_CAPABLE_SLOT, +}; + + static void __init brownstone_init(void) { mfp_config(ARRAY_AND_SIZE(brownstone_pin_config)); @@ -189,6 +196,7 @@ static void __init brownstone_init(void) mmp2_add_uart(3); mmp2_add_twsi(1, NULL, ARRAY_AND_SIZE(brownstone_twsi1_info)); mmp2_add_sdhost(0, mmp2_sdh_platdata_mmc0); /* SD/MMC */ + mmp2_add_sdhost(2, mmp2_sdh_platdata_mmc2); /* eMMC */ /* enable 5v regulator */ platform_device_register(brownstone_v_5vp_device); diff --git a/arch/arm/mach-mmp/jasper.c b/arch/arm/mach-mmp/jasper.c index 24172a0..5d6421d 100644 --- a/arch/arm/mach-mmp/jasper.c +++ b/arch/arm/mach-mmp/jasper.c @@ -154,7 +154,7 @@ static struct i2c_board_info jasper_twsi1_info[] = { }; static struct sdhci_pxa_platdata mmp2_sdh_platdata_mmc0 = { - .max_speed = 2500, + .clk_delay_cycles = 0x1f, }; static void __init jasper_init(void) diff --git a/arch/arm/mach-mmp/mmp2.c b/arch/arm/mach-mmp/mmp2.c index 8e6c3ac..079c188 100644 --- a/arch/arm/mach-mmp/mmp2.c +++ b/arch/arm/mach-mmp/mmp2.c @@ -168,10 +168,10 @@ static struct clk_lookup mmp2_clkregs[] = { INIT_CLKREG(clk_twsi5, pxa2xx-i2c.4, NULL), INIT_CLKREG(clk_twsi6, pxa2xx-i2c.5, NULL), INIT_CLKREG(clk_nand, pxa3xx-nand, NULL), - INIT_CLKREG(clk_sdh0, sdhci-pxa.0, PXA-SDHCLK), - INIT_CLKREG(clk_sdh1, sdhci-pxa.1, PXA-SDHCLK), - INIT_CLKREG(clk_sdh2, sdhci-pxa.2, PXA-SDHCLK), - INIT_CLKREG(clk_sdh3, sdhci-pxa.3, PXA-SDHCLK), + INIT_CLKREG(clk_sdh0, sdhci-pxav3.0, PXA-SDHCLK), + INIT_CLKREG(clk_sdh1, sdhci-pxav3.1, PXA-SDHCLK), + INIT_CLKREG(clk_sdh2, sdhci-pxav3.2, PXA-SDHCLK), + INIT_CLKREG(clk_sdh3, sdhci-pxav3.3, PXA-SDHCLK), }; static int __init mmp2_init(void) @@ -222,8 +222,8 @@ MMP2_DEVICE(twsi4, pxa2xx-i2c, 3, TWSI4, 0xd4033000, 0x70); MMP2_DEVICE(twsi5, pxa2xx-i2c, 4, TWSI5, 0xd4033800, 0x70); MMP2_DEVICE(twsi6, pxa2xx-i2c, 5, TWSI6, 0xd4034000, 0x70); MMP2_DEVICE(nand, pxa3xx-nand, -1, NAND, 0xd4283000, 0x100, 28, 29); -MMP2_DEVICE(sdh0, sdhci-pxa, 0, MMC, 0xd428, 0x120); -MMP2_DEVICE(sdh1, sdhci-pxa, 1, MMC2, 0xd4280800, 0x120); -MMP2_DEVICE(sdh2, sdhci-pxa, 2, MMC3, 0xd4281000, 0x120); -MMP2_DEVICE(sdh3, sdhci-pxa, 3, MMC4, 0xd4281800, 0x120); +MMP2_DEVICE(sdh0, sdhci-pxav3, 0, MMC, 0xd428, 0x120); +MMP2_DEVICE(sdh1, sdhci-pxav3, 1, MMC2, 0xd4280800, 0x120); +MMP2_DEVICE(sdh2, sdhci-pxav3, 2, MMC3, 0xd4281000, 0x120); +MMP2_DEVICE(sdh3, sdhci-pxav3, 3, MMC4, 0xd4281800, 0x120); -- 1.7.0.4 -- To unsubscribe from this list: send the line unsubscribe linux-mmc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v3 2/4] mmc: support sdhci-pxav2.c
On Sat, Jun 4, 2011 at 8:04 AM, Philip Rakity prak...@marvell.com wrote: On Jun 3, 2011, at 11:42 AM, Philip Rakity wrote: On Jun 3, 2011, at 2:50 AM, Zhangfei Gao wrote: SDHCI driver for pxav2 SoCs, such as pxa910, the driver based on sdhci-pltfm to handle resource etc. Signed-off-by: Zhangfei Gao zhangfei@marvell.com Signed-off-by: Jun Nie n...@marvell.com Signed-off-by: Qiming Wu w...@marvell.com --- drivers/mmc/host/Kconfig | 11 ++ drivers/mmc/host/Makefile | 1 + drivers/mmc/host/sdhci-pxav2.c | 261 3 files changed, 273 insertions(+), 0 deletions(-) create mode 100644 drivers/mmc/host/sdhci-pxav2.c diff --git a/drivers/mmc/host/Kconfig b/drivers/mmc/host/Kconfig index 4ee869a..1a53d59 100644 --- a/drivers/mmc/host/Kconfig +++ b/drivers/mmc/host/Kconfig @@ -192,6 +192,17 @@ config MMC_SDHCI_PXAV3 If unsure, say N. +config MMC_SDHCI_PXAV2 + tristate Marvell PXAV2 SD Host Controller support + select MMC_SDHCI + select MMC_SDHCI_PLTFM + help + This selects the Marvell(R) PXAV2 SD Host Controller. + If you have a PXAV2 platform (such as pxa910) with SD Host Controller + and a card slot, say Y or M here. + + If unsure, say N. + config MMC_SDHCI_SPEAR tristate SDHCI support on ST SPEAr platform depends on MMC_SDHCI PLAT_SPEAR diff --git a/drivers/mmc/host/Makefile b/drivers/mmc/host/Makefile index 9131a27..cf95330 100644 --- a/drivers/mmc/host/Makefile +++ b/drivers/mmc/host/Makefile @@ -10,6 +10,7 @@ obj-$(CONFIG_MMC_MXS) += mxs-mmc.o obj-$(CONFIG_MMC_SDHCI) += sdhci.o obj-$(CONFIG_MMC_SDHCI_PCI) += sdhci-pci.o obj-$(CONFIG_MMC_SDHCI_PXAV3) += sdhci-pxav3.o +obj-$(CONFIG_MMC_SDHCI_PXAV2) += sdhci-pxav2.o obj-$(CONFIG_MMC_SDHCI_S3C) += sdhci-s3c.o obj-$(CONFIG_MMC_SDHCI_SPEAR) += sdhci-spear.o obj-$(CONFIG_MMC_WBSD) += wbsd.o diff --git a/drivers/mmc/host/sdhci-pxav2.c b/drivers/mmc/host/sdhci-pxav2.c new file mode 100644 index 000..759f526 --- /dev/null +++ b/drivers/mmc/host/sdhci-pxav2.c @@ -0,0 +1,261 @@ +/* + * Copyright (C) 2010 Marvell International Ltd. + * Zhangfei Gao zhangfei@marvell.com + * Kevin Wang dwa...@marvell.com + * Jun Nie n...@marvell.com + * Qiming Wu w...@marvell.com + * Philip Rakity prak...@marvell.com + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#include linux/err.h +#include linux/init.h +#include linux/platform_device.h +#include linux/clk.h +#include linux/io.h +#include linux/gpio.h +#include linux/mmc/card.h +#include linux/mmc/host.h +#include plat/sdhci.h +#include linux/slab.h +#include sdhci.h +#include sdhci-pltfm.h + +#define SD_FIFO_PARAM 0xe0 +#define DIS_PAD_SD_CLK_GATE 0x0400 /* Turn on/off Dynamic SD Clock Gating */ +#define CLK_GATE_ON 0x0200 /* Disable/enable Clock Gate */ +#define CLK_GATE_CTL 0x0100 /* Clock Gate Control */ +#define CLK_GATE_SETTING_BITS (DIS_PAD_SD_CLK_GATE | \ + CLK_GATE_ON | CLK_GATE_CTL) + +#define SD_CLOCK_BURST_SIZE_SETUP 0xe6 +#define SDCLK_SEL_SHIFT 8 +#define SDCLK_SEL_MASK 0x3 +#define SDCLK_DELAY_SHIFT 10 +#define SDCLK_DELAY_MASK 0x3c + +#define SDHCI_HOST_CONTROL 0x28 This definition should come from the sdhci.h include file since it is part of the sd host controller spec. Thanks, will remove. . +#define SDHCI_CTRL_4BITBUS 0x02 + +#define SD_CE_ATA_2 0xea +#define MMC_CARD 0x1000 +#define MMC_WIDTH 0x0100 + +static void pxav2_set_private_registers(struct sdhci_host *host, u8 mask) +{ + struct platform_device *pdev = to_platform_device(mmc_dev(host-mmc)); + struct sdhci_pxa_platdata *pdata = pdev-dev.platform_data; + + if (mask == SDHCI_RESET_ALL) { + u16 tmp = 0; + + /* + * tune timing of read data/command when crc error happen + * no performance impact + */ + if (pdata-clk_delay_sel == 1) { + tmp = readw(host-ioaddr + SD_CLOCK_BURST_SIZE_SETUP); + + tmp = ~(SDCLK_DELAY_MASK SDCLK_DELAY_SHIFT); + tmp |= (pdata-clk_delay_cycles SDCLK_DELAY_MASK) + SDCLK_DELAY_SHIFT; + tmp = ~(SDCLK_SEL_MASK SDCLK_SEL_SHIFT); + tmp |= (1 SDCLK_SEL_MASK
Re: [PATCH v2 1/3] mmc: support sdhci-mmp2
On Wed, Jun 8, 2011 at 7:51 AM, Philip Rakity prak...@marvell.com wrote: On May 29, 2011, at 10:42 PM, zhangfei gao wrote: There is a little room for simplification, I think: +static unsigned int mmp2_get_ro(struct sdhci_host *host) +{ + /* Micro SD does not support write-protect feature */ + return 0; +} You shouldn't need to provide an empty get_ro function, the default is that there is no write-protect. Thanks Arnd for review. The reason to put get_ro here is some board use micro sd, while some board design is general sd card. The micro sd do not use write-protect, while SDHCI_WRITE_PROTECT will return 1 in our controller, so it shows read only. So add one call back for the board with micro sd card via flag. The code sets get_ro is for all the controllers. Some board designs may connect the WP signal. The host-ops field should be filled in using information in the board file using a flag such as the example with PXA_FLAG_CARD_PERMANENT. eg if (pdata pdata-flags PXA_FLAG_NO_WP) { * etc } This method is used in v1, The method makes sdhci_ops non-const and have to dynamically alloc sdhci_ops, since host-ops is pointer. Will keep use const sdhci_ops, recommended by Arnd. -- To unsubscribe from this list: send the line unsubscribe linux-mmc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v3 0/3] provide sdhci driver for mmp2 and pxa910
On Sat, Jun 4, 2011 at 5:08 AM, Philip Rakity prak...@marvell.com wrote: Please update mmp2 and pxa defconfigs. The trend is replacing defconfig with device tree, it may not acceptable to update defconfig. regards, Philip On Jun 3, 2011, at 2:48 AM, zhangfei gao wrote: v2-v3, modify according to Arnd and Philip suggestion. Here are patches to provide separate sdhci driver for mmp2 and pxa910 based on sdhci-platfm. Rename to sdhci-pxav3.c and sdhci-pxav2.c Remove sdhci-pxa.c, which is used to share among pxa serious, since under this method, platform difference have to be put under arch/arm, which is not easy to track. As a result, mmp2 mmc resource should be updated accordingly. -- To unsubscribe from this list: send the line unsubscribe linux-mmc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH] mmc: support sdhci-mmp2
On Tue, May 31, 2011 at 4:47 AM, Philip Rakity prak...@marvell.com wrote: On May 30, 2011, at 6:15 AM, zhangfei gao wrote: On Sat, May 28, 2011 at 1:00 AM, Philip Rakity prak...@marvell.com wrote: Hi Zhangfei, comments below. (based on V1 patch but change to V2 affect (31) typo. Philip and Mark. Thanks for review. On May 23, 2011, at 6:21 AM, Zhangfei Gao wrote: Delete sdhci-pxa.c and replace with sdhci-mmp2.c specificlly for mmp2 Signed-off-by: Zhangfei Gao zhangfei@marvell.com --- arch/arm/plat-pxa/include/plat/sdhci.h | 43 - drivers/mmc/host/Kconfig | 9 +- drivers/mmc/host/Makefile | 2 +- drivers/mmc/host/sdhci-mmp2.c | 304 drivers/mmc/host/sdhci-pxa.c | 303 --- 5 files changed, 349 insertions(+), 312 deletions(-) create mode 100644 drivers/mmc/host/sdhci-mmp2.c delete mode 100644 drivers/mmc/host/sdhci-pxa.c diff --git a/arch/arm/plat-pxa/include/plat/sdhci.h b/arch/arm/plat-pxa/include/plat/sdhci.h index 1ab332e..92becc0 100644 --- a/arch/arm/plat-pxa/include/plat/sdhci.h +++ b/arch/arm/plat-pxa/include/plat/sdhci.h @@ -13,23 +13,58 @@ #ifndef __PLAT_PXA_SDHCI_H #define __PLAT_PXA_SDHCI_H +#include linux/mmc/sdhci.h +#include linux/platform_device.h + /* pxa specific flag */ /* Require clock free running */ #define PXA_FLAG_DISABLE_CLOCK_GATING (10) - +/* card alwayes wired to host, like on-chip emmc */ +#define PXA_FLAG_CARD_PERMANENT (11) /* Board design supports 8-bit data on SD/SDIO BUS */ #define PXA_FLAG_SD_8_BIT_CAPABLE_SLOT (12) +/* card not use wp, such as micro sd card */ +#define PXA_FLAG_CARD_NO_WP (31) do you mean (13) ? already update in v2. +struct sdhci_pxa; /* * struct pxa_sdhci_platdata() - Platform device data for PXA SDHCI - * @max_speed: the maximum speed supported - * @quirks: quirks of specific device * @flags: flags for platform requirement + * @clk_delay_cycles: + * mmp2: each step is roughly 100ps, 5bits width + * pxa910: each step is 1ns, 4bits width + * @clk_delay_sel: select clk_delay, used on pxa910 + * 0: choose feedback clk + * 1: choose feedback clk + delay value + * 2: choose internal clk + * @ext_cd_gpio: gpio pin used for external CD line + * @ext_cd_gpio_invert: invert values for external CD gpio line + * @clk_delay_enable: enable clk_delay or not, used on pxa910 + * @max_speed: the maximum speed supported + * @host_caps: Standard MMC host capabilities bit field. + * @quirks: quirks of platfrom + * @pm_caps: pm_caps of platfrom */ struct sdhci_pxa_platdata { + unsigned int flags; + unsigned int clk_delay_cycles; + unsigned int clk_delay_sel; + unsigned int ext_cd_gpio; + bool ext_cd_gpio_invert; + bool clk_delay_enable; move up 2 lines to be next to other clk_ values. fine. unsigned int max_speed; + unsigned int host_caps; unsigned int quirks; - unsigned int flags; + unsigned int pm_caps; +}; + +struct sdhci_pxa { + struct sdhci_pxa_platdata *pdata; + struct clk *clk; + struct sdhci_ops *ops; + + u8 clk_enable; + u8 power_mode; }; #endif /* __PLAT_PXA_SDHCI_H */ diff --git a/drivers/mmc/host/Kconfig b/drivers/mmc/host/Kconfig index 862235e..1e520e3 100644 --- a/drivers/mmc/host/Kconfig +++ b/drivers/mmc/host/Kconfig @@ -181,14 +181,15 @@ config MMC_SDHCI_S3C If unsure, say N. -config MMC_SDHCI_PXA - tristate Marvell PXA168/PXA910/MMP2 SD Host Controller support +config MMC_SDHCI_MMP2 + tristate Marvell MMP2 SD Host Controller support depends on ARCH_PXA || ARCH_MMP select MMC_SDHCI + select MMC_SDHCI_PLTFM select MMC_SDHCI_IO_ACCESSORS help - This selects the Marvell(R) PXA168/PXA910/MMP2 SD Host Controller. - If you have a PXA168/PXA910/MMP2 platform with SD Host Controller + This selects the Marvell(R) MMP2 SD Host Controller. + If you have a MMP2 platform with SD Host Controller and a card slot, say Y or M here. This needs to be specific to MMP2 -- depends on CPU_MMP2 ? code can be selected for pxa9xx and pxa168 where this code cannot work. deleting MMC_SDHCI_PXA breaks existing configs since it is renamed. would it better to leave this and mark it as obsolete but let it still compile mmp2 sd code? In some sense all of this is backwards. Once the SoC is known (pxa910 or mmp2), it knows that SDHCI controller it supports. It should set a config option like USES_MRVL_V3_SD_CONTROLLER. The Kconfig entry in mmc/host should depend on THAT selection to allow the user to enable the SD option. MMC_SDHCI_IO_ACCESSORS not needed Will take Arnd advice, remove dependency
Re: [PATCH v2 1/3] mmc: support sdhci-mmp2
On Mon, May 30, 2011 at 3:11 AM, Arnd Bergmann a...@arndb.de wrote: On Monday 30 May 2011 07:42:04 zhangfei gao wrote: On Fri, May 27, 2011 at 11:46 AM, Arnd Bergmann a...@arndb.de wrote: On Wednesday 25 May 2011, Zhangfei Gao wrote: +static unsigned int mmp2_get_ro(struct sdhci_host *host) +{ + /* Micro SD does not support write-protect feature */ + return 0; +} You shouldn't need to provide an empty get_ro function, the default is that there is no write-protect. Thanks Arnd for review. The reason to put get_ro here is some board use micro sd, while some board design is general sd card. The micro sd do not use write-protect, while SDHCI_WRITE_PROTECT will return 1 in our controller, so it shows read only. So add one call back for the board with micro sd card via flag. Ok, I see. + pxa = kzalloc(sizeof(struct sdhci_pxa), GFP_KERNEL); + if (!pxa) { + ret = -ENOMEM; + goto out; + } + pxa-ops = kzalloc(sizeof(struct sdhci_ops), GFP_KERNEL); + if (!pxa-ops) { + ret = -ENOMEM; + goto out; + } I think you really shouldn't allocate the sdhci_ops dynamically. In fact, it would be much better if we were able to mark them as const in all drivers. We found some issues when supporting multi-slot, each slot may have different ops. So use the method of allocating the sdhci_ops dynamically instead of using static ops. For example, emmc has 74_clocks call back, while mmc and sdio slot does not have such ops. If not dynamically allocate sdhci_ops, all slot ops may become same, and 74_clocks may be called for every slot. Also, some board may have get_ro, while other board may not, so transfer the ops via flags. Not sure whether it is worthy to add additional common files to share probe and remove function. Also the init the ops part are different. IMHO, we should try much harder to keep the ops constant. For the two examples you gave, I would probably put a flag into private data for the get_ro operation to signify that it's never read-only, and provide a second set of operations for emmc, so that in the probe function you check the type of device and then set the appropriate one. You could also do the same for all three cases: if (emmc) host-ops = sdhci_mmp2_emmc_ops; else if (!has_ro_switch) host-ops = sdhci_mmp2_rw_ops; else host-ops = sdhci_mmp2_default_ops; Thanks, will take this method to make the ops constant. + +#ifdef CONFIG_PM +static int sdhci_mmp2_suspend(struct platform_device *dev, pm_message_t state) +{ + struct sdhci_host *host = platform_get_drvdata(dev); + + return sdhci_suspend_host(host, state); +} + +static int sdhci_mmp2_resume(struct platform_device *dev) +{ + struct sdhci_host *host = platform_get_drvdata(dev); + + return sdhci_resume_host(host); +} +#else +#define sdhci_mmp2_suspend NULL +#define sdhci_mmp2_resume NULL +#endif Similarly, I think it would be good if sdhci-pltfm.c would simply export these functions so you could refer to them in your driver. There is no need to have identical copies in each variant. There are some additional code for suspend and resume, so sdhci_pltfm_suspend may not enough. For example, when enable wifi host sleep feature, additional register have to be configured. Well, not all drivers would have to use the common functions, but right now there are a number of identical copies, so it's certainly worth sharing. Then we use sdhci_pltfm_suspend first, and change to private suspend resume when supporting additional feature. Note that this comment wasn't directed at your patch as much as at the overall design of the sdhci sub-drivers. Arnd -- To unsubscribe from this list: send the line unsubscribe linux-mmc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v2 1/3] mmc: support sdhci-mmp2
On Fri, May 27, 2011 at 11:46 AM, Arnd Bergmann a...@arndb.de wrote: On Wednesday 25 May 2011, Zhangfei Gao wrote: Instead of sharing sdhci-pxa.c, use sdhci-mmp2.c specificlly for mmp2. sdhci-pxa.c is used to share among pxa serious, like pxa910, mmp2, etc. The platfrom difference are put under arch/arm, while is not easy to track. Signed-off-by: Zhangfei Gao zhangfei@marvell.com --- arch/arm/plat-pxa/include/plat/sdhci.h | 43 - drivers/mmc/host/Kconfig | 11 +- drivers/mmc/host/Makefile | 2 +- drivers/mmc/host/sdhci-mmp2.c | 303 drivers/mmc/host/sdhci-pxa.c | 303 5 files changed, 349 insertions(+), 313 deletions(-) create mode 100644 drivers/mmc/host/sdhci-mmp2.c delete mode 100644 drivers/mmc/host/sdhci-pxa.c Yes, looks good for the most part. I was rather confused by the fact that the old and new file are both 303 lines, so I assumed they would be identical, when they are really completely different. There is a little room for simplification, I think: +static unsigned int mmp2_get_ro(struct sdhci_host *host) +{ + /* Micro SD does not support write-protect feature */ + return 0; +} You shouldn't need to provide an empty get_ro function, the default is that there is no write-protect. Thanks Arnd for review. The reason to put get_ro here is some board use micro sd, while some board design is general sd card. The micro sd do not use write-protect, while SDHCI_WRITE_PROTECT will return 1 in our controller, so it shows read only. So add one call back for the board with micro sd card via flag. +static void mmp2_set_clock(struct sdhci_host *host, unsigned int clock) +{ + struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); + struct sdhci_pxa *pxa = pltfm_host-priv; + + if (clock) + mmp2_soc_set_timing(host, pxa-pdata); +} The mmp2_soc_set_timing() function is only called here, so you can easily merge the two into one, starting with if (!clock) return; OK, thanks, +static int __devinit sdhci_mmp2_probe(struct platform_device *pdev) +{ + struct sdhci_pltfm_host *pltfm_host; + struct sdhci_pxa_platdata *pdata = pdev-dev.platform_data; + struct device *dev = pdev-dev; + struct sdhci_host *host = NULL; + struct sdhci_pxa *pxa = NULL; + int ret; + struct clk *clk; The probe and release functions for mmp2 and pxa910 are almost identical. I'd suggest you leave them in sdhci-pxa.c as a library, and export them using EXPORT_SYMBOL_GPL. Then you can call them from the respective probe functions, e.g. static struct sdhci_mmp2_ops = { .set_clock = mmp2_set_clock, .set_uhs_signaling = mmp2_set_uhs_signaling, .get_ro = mmp2_get_ro, }; static int __devinit sdhci_mmp2_probe(struct platform_device *pdev) { unsigned int quirks = SDHCI_QUIRK_BROKEN_ADMA | SDHCI_QUIRK_BROKEN_TIMEOUT_VAL | SDHCI_QUIRK_32BIT_DMA_ADDR | SDHCI_QUIRK_32BIT_DMA_SIZE | SDHCI_QUIRK_32BIT_ADMA_SIZE | SDHCI_QUIRK_NO_ENDATTR_IN_NOPDESC; return sdhci_pxa_probe(pdev, quirks, sdhci_mmp2_ops); } + pxa = kzalloc(sizeof(struct sdhci_pxa), GFP_KERNEL); + if (!pxa) { + ret = -ENOMEM; + goto out; + } + pxa-ops = kzalloc(sizeof(struct sdhci_ops), GFP_KERNEL); + if (!pxa-ops) { + ret = -ENOMEM; + goto out; + } I think you really shouldn't allocate the sdhci_ops dynamically. In fact, it would be much better if we were able to mark them as const in all drivers. We found some issues when supporting multi-slot, each slot may have different ops. So use the method of allocating the sdhci_ops dynamically instead of using static ops. For example, emmc has 74_clocks call back, while mmc and sdio slot does not have such ops. If not dynamically allocate sdhci_ops, all slot ops may become same, and 74_clocks may be called for every slot. Also, some board may have get_ro, while other board may not, so transfer the ops via flags. Not sure whether it is worthy to add additional common files to share probe and remove function. Also the init the ops part are different. + +#ifdef CONFIG_PM +static int sdhci_mmp2_suspend(struct platform_device *dev, pm_message_t state) +{ + struct sdhci_host *host = platform_get_drvdata(dev); + + return sdhci_suspend_host(host, state); +} + +static int sdhci_mmp2_resume(struct platform_device *dev) +{ + struct sdhci_host *host = platform_get_drvdata(dev); + + return sdhci_resume_host(host); +} +#else +#define sdhci_mmp2_suspend NULL +#define sdhci_mmp2_resume NULL +#endif Similarly, I think it would be good if sdhci-pltfm.c would simply export these functions so you could refer to them
Re: [PATCH] mmc: support sdhci-mmp2
On Mon, May 23, 2011 at 11:01 AM, Arnd Bergmann a...@arndb.de wrote: On Monday 23 May 2011, Zhangfei Gao wrote: Delete sdhci-pxa.c and replace with sdhci-mmp2.c specificlly for mmp2 Signed-off-by: Zhangfei Gao zhangfei@marvell.com --- arch/arm/plat-pxa/include/plat/sdhci.h | 43 - drivers/mmc/host/Kconfig | 9 +- drivers/mmc/host/Makefile | 2 +- drivers/mmc/host/sdhci-mmp2.c | 304 drivers/mmc/host/sdhci-pxa.c | 303 --- 5 files changed, 349 insertions(+), 312 deletions(-) create mode 100644 drivers/mmc/host/sdhci-mmp2.c delete mode 100644 drivers/mmc/host/sdhci-pxa.c Hi Zhangfei, You should really try to improve your changelog texts. Instead of the one-line summary that describes what you do 'Delete sdhci-pxa.c and replace ...', please provide a paragraph explaining why you do it, and what the bigger plan is here. Thanks Arnd, will add more change log for explanation. Also, when renaming a file, please use 'git diff -M' or 'git format-patch -M' to detect renames and generate a diff for the changes you did to the file. Double checked same patch coming using 'git format-patch -M' or 'git format-patch' , since the two files changes a lot. Arnd -- To unsubscribe from this list: send the line unsubscribe linux-mmc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html -- To unsubscribe from this list: send the line unsubscribe linux-mmc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH] mmc: support sdhci-mmp2
On Tue, May 24, 2011 at 2:10 AM, Philip Rakity prak...@marvell.com wrote: code is missing hooks for 74 clock generation. Could we add the hook later in another patch, or could you help submit one patch to handle this. We test on mmp2 and ttc_dkb with toshiba and sandisk emmc, do not find issues without adding hook for 74 clock generation. On May 23, 2011, at 6:21 AM, Zhangfei Gao wrote: Delete sdhci-pxa.c and replace with sdhci-mmp2.c specificlly for mmp2 Signed-off-by: Zhangfei Gao zhangfei@marvell.com --- arch/arm/plat-pxa/include/plat/sdhci.h | 43 - drivers/mmc/host/Kconfig | 9 +- drivers/mmc/host/Makefile | 2 +- drivers/mmc/host/sdhci-mmp2.c | 304 drivers/mmc/host/sdhci-pxa.c | 303 --- 5 files changed, 349 insertions(+), 312 deletions(-) create mode 100644 drivers/mmc/host/sdhci-mmp2.c delete mode 100644 drivers/mmc/host/sdhci-pxa.c diff --git a/arch/arm/plat-pxa/include/plat/sdhci.h b/arch/arm/plat-pxa/include/plat/sdhci.h index 1ab332e..92becc0 100644 --- a/arch/arm/plat-pxa/include/plat/sdhci.h +++ b/arch/arm/plat-pxa/include/plat/sdhci.h @@ -13,23 +13,58 @@ #ifndef __PLAT_PXA_SDHCI_H #define __PLAT_PXA_SDHCI_H +#include linux/mmc/sdhci.h +#include linux/platform_device.h + /* pxa specific flag */ /* Require clock free running */ #define PXA_FLAG_DISABLE_CLOCK_GATING (10) - +/* card alwayes wired to host, like on-chip emmc */ +#define PXA_FLAG_CARD_PERMANENT (11) /* Board design supports 8-bit data on SD/SDIO BUS */ #define PXA_FLAG_SD_8_BIT_CAPABLE_SLOT (12) +/* card not use wp, such as micro sd card */ +#define PXA_FLAG_CARD_NO_WP (31) +struct sdhci_pxa; /* * struct pxa_sdhci_platdata() - Platform device data for PXA SDHCI - * @max_speed: the maximum speed supported - * @quirks: quirks of specific device * @flags: flags for platform requirement + * @clk_delay_cycles: + * mmp2: each step is roughly 100ps, 5bits width + * pxa910: each step is 1ns, 4bits width + * @clk_delay_sel: select clk_delay, used on pxa910 + * 0: choose feedback clk + * 1: choose feedback clk + delay value + * 2: choose internal clk + * @ext_cd_gpio: gpio pin used for external CD line + * @ext_cd_gpio_invert: invert values for external CD gpio line + * @clk_delay_enable: enable clk_delay or not, used on pxa910 + * @max_speed: the maximum speed supported + * @host_caps: Standard MMC host capabilities bit field. + * @quirks: quirks of platfrom + * @pm_caps: pm_caps of platfrom */ struct sdhci_pxa_platdata { + unsigned int flags; + unsigned int clk_delay_cycles; + unsigned int clk_delay_sel; + unsigned int ext_cd_gpio; + bool ext_cd_gpio_invert; + bool clk_delay_enable; unsigned int max_speed; + unsigned int host_caps; unsigned int quirks; - unsigned int flags; + unsigned int pm_caps; +}; + +struct sdhci_pxa { + struct sdhci_pxa_platdata *pdata; + struct clk *clk; + struct sdhci_ops *ops; + + u8 clk_enable; + u8 power_mode; }; #endif /* __PLAT_PXA_SDHCI_H */ diff --git a/drivers/mmc/host/Kconfig b/drivers/mmc/host/Kconfig index 862235e..1e520e3 100644 --- a/drivers/mmc/host/Kconfig +++ b/drivers/mmc/host/Kconfig @@ -181,14 +181,15 @@ config MMC_SDHCI_S3C If unsure, say N. -config MMC_SDHCI_PXA - tristate Marvell PXA168/PXA910/MMP2 SD Host Controller support +config MMC_SDHCI_MMP2 + tristate Marvell MMP2 SD Host Controller support depends on ARCH_PXA || ARCH_MMP select MMC_SDHCI + select MMC_SDHCI_PLTFM select MMC_SDHCI_IO_ACCESSORS help - This selects the Marvell(R) PXA168/PXA910/MMP2 SD Host Controller. - If you have a PXA168/PXA910/MMP2 platform with SD Host Controller + This selects the Marvell(R) MMP2 SD Host Controller. + If you have a MMP2 platform with SD Host Controller and a card slot, say Y or M here. If unsure, say N. diff --git a/drivers/mmc/host/Makefile b/drivers/mmc/host/Makefile index 4933004..f8650e0 100644 --- a/drivers/mmc/host/Makefile +++ b/drivers/mmc/host/Makefile @@ -9,7 +9,7 @@ obj-$(CONFIG_MMC_MXC) += mxcmmc.o obj-$(CONFIG_MMC_MXS) += mxs-mmc.o obj-$(CONFIG_MMC_SDHCI) += sdhci.o obj-$(CONFIG_MMC_SDHCI_PCI) += sdhci-pci.o -obj-$(CONFIG_MMC_SDHCI_PXA) += sdhci-pxa.o +obj-$(CONFIG_MMC_SDHCI_MMP2) += sdhci-mmp2.o obj-$(CONFIG_MMC_SDHCI_S3C) += sdhci-s3c.o obj-$(CONFIG_MMC_SDHCI_SPEAR) += sdhci-spear.o obj-$(CONFIG_MMC_WBSD) += wbsd.o diff --git a/drivers/mmc/host/sdhci-mmp2.c b/drivers/mmc/host/sdhci-mmp2.c new file mode 100644 index 000..566d525 --- /dev/null
[PATCH v2 0/3] provide sdhci driver for mmp2 and pxa910
Here are patches to provide separate sdhci driver for mmp2 and pxa910 based on sdhci-platfm. Remove sdhci-pxa.c, which is used to share among pxa serious, since under this method, platform difference have to be put under arch/arm, which is not easy to track. As a result, mmp2 mmc resource should be updated accordingly. The patches verified after Shawn's modification to sdhci-platfm.c. -- To unsubscribe from this list: send the line unsubscribe linux-mmc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v2 1/3] mmc: support sdhci-mmp2
Instead of sharing sdhci-pxa.c, use sdhci-mmp2.c specificlly for mmp2. sdhci-pxa.c is used to share among pxa serious, like pxa910, mmp2, etc. The platfrom difference are put under arch/arm, while is not easy to track. Signed-off-by: Zhangfei Gao zhangfei@marvell.com --- arch/arm/plat-pxa/include/plat/sdhci.h | 43 - drivers/mmc/host/Kconfig | 11 +- drivers/mmc/host/Makefile |2 +- drivers/mmc/host/sdhci-mmp2.c | 303 drivers/mmc/host/sdhci-pxa.c | 303 5 files changed, 349 insertions(+), 313 deletions(-) create mode 100644 drivers/mmc/host/sdhci-mmp2.c delete mode 100644 drivers/mmc/host/sdhci-pxa.c diff --git a/arch/arm/plat-pxa/include/plat/sdhci.h b/arch/arm/plat-pxa/include/plat/sdhci.h index 1ab332e..c23b6b5 100644 --- a/arch/arm/plat-pxa/include/plat/sdhci.h +++ b/arch/arm/plat-pxa/include/plat/sdhci.h @@ -13,23 +13,58 @@ #ifndef __PLAT_PXA_SDHCI_H #define __PLAT_PXA_SDHCI_H +#include linux/mmc/sdhci.h +#include linux/platform_device.h + /* pxa specific flag */ /* Require clock free running */ #define PXA_FLAG_DISABLE_CLOCK_GATING (10) - +/* card alwayes wired to host, like on-chip emmc */ +#define PXA_FLAG_CARD_PERMANENT(11) /* Board design supports 8-bit data on SD/SDIO BUS */ #define PXA_FLAG_SD_8_BIT_CAPABLE_SLOT (12) +/* card not use wp, such as micro sd card */ +#define PXA_FLAG_CARD_NO_WP(13) +struct sdhci_pxa; /* * struct pxa_sdhci_platdata() - Platform device data for PXA SDHCI - * @max_speed: the maximum speed supported - * @quirks: quirks of specific device * @flags: flags for platform requirement + * @clk_delay_cycles: + * mmp2: each step is roughly 100ps, 5bits width + * pxa910: each step is 1ns, 4bits width + * @clk_delay_sel: select clk_delay, used on pxa910 + * 0: choose feedback clk + * 1: choose feedback clk + delay value + * 2: choose internal clk + * @ext_cd_gpio: gpio pin used for external CD line + * @ext_cd_gpio_invert: invert values for external CD gpio line + * @clk_delay_enable: enable clk_delay or not, used on pxa910 + * @max_speed: the maximum speed supported + * @host_caps: Standard MMC host capabilities bit field. + * @quirks: quirks of platfrom + * @pm_caps: pm_caps of platfrom */ struct sdhci_pxa_platdata { + unsigned intflags; + unsigned intclk_delay_cycles; + unsigned intclk_delay_sel; + unsigned intext_cd_gpio; + boolext_cd_gpio_invert; + boolclk_delay_enable; unsigned intmax_speed; + unsigned inthost_caps; unsigned intquirks; - unsigned intflags; + unsigned intpm_caps; +}; + +struct sdhci_pxa { + struct sdhci_pxa_platdata *pdata; + struct clk *clk; + struct sdhci_ops*ops; + + u8 clk_enable; + u8 power_mode; }; #endif /* __PLAT_PXA_SDHCI_H */ diff --git a/drivers/mmc/host/Kconfig b/drivers/mmc/host/Kconfig index 862235e..513df18 100644 --- a/drivers/mmc/host/Kconfig +++ b/drivers/mmc/host/Kconfig @@ -181,14 +181,15 @@ config MMC_SDHCI_S3C If unsure, say N. -config MMC_SDHCI_PXA - tristate Marvell PXA168/PXA910/MMP2 SD Host Controller support - depends on ARCH_PXA || ARCH_MMP +config MMC_SDHCI_MMP2 + tristate Marvell MMP2 SD Host Controller support + depends on ARCH_MMP select MMC_SDHCI + select MMC_SDHCI_PLTFM select MMC_SDHCI_IO_ACCESSORS help - This selects the Marvell(R) PXA168/PXA910/MMP2 SD Host Controller. - If you have a PXA168/PXA910/MMP2 platform with SD Host Controller + This selects the Marvell(R) MMP2 SD Host Controller. + If you have a MMP2 platform with SD Host Controller and a card slot, say Y or M here. If unsure, say N. diff --git a/drivers/mmc/host/Makefile b/drivers/mmc/host/Makefile index 4933004..f8650e0 100644 --- a/drivers/mmc/host/Makefile +++ b/drivers/mmc/host/Makefile @@ -9,7 +9,7 @@ obj-$(CONFIG_MMC_MXC) += mxcmmc.o obj-$(CONFIG_MMC_MXS) += mxs-mmc.o obj-$(CONFIG_MMC_SDHCI)+= sdhci.o obj-$(CONFIG_MMC_SDHCI_PCI)+= sdhci-pci.o -obj-$(CONFIG_MMC_SDHCI_PXA)+= sdhci-pxa.o +obj-$(CONFIG_MMC_SDHCI_MMP2) += sdhci-mmp2.o obj-$(CONFIG_MMC_SDHCI_S3C)+= sdhci-s3c.o obj-$(CONFIG_MMC_SDHCI_SPEAR) += sdhci-spear.o obj-$(CONFIG_MMC_WBSD) += wbsd.o diff --git a/drivers/mmc/host/sdhci-mmp2.c b/drivers/mmc/host/sdhci-mmp2.c new file mode 100644 index 000..efb5751 --- /dev/null +++ b/drivers/mmc/host/sdhci-mmp2.c @@ -0,0 +1,303 @@ +/* + * Copyright (C) 2010 Marvell International Ltd. + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied
[PATCH v2 2/3] mmc: support sdhci-pxa910
SDHCI driver for pxa910 SoCs, the driver based on sdhci-pltfm to handle resource etc. Signed-off-by: Zhangfei Gao zhangfei@marvell.com Signed-off-by: Jun Nie n...@marvell.com Signed-off-by: Qiming Wu w...@marvell.com --- drivers/mmc/host/Kconfig| 13 ++ drivers/mmc/host/Makefile |1 + drivers/mmc/host/sdhci-pxa910.c | 297 +++ 3 files changed, 311 insertions(+), 0 deletions(-) create mode 100644 drivers/mmc/host/sdhci-pxa910.c diff --git a/drivers/mmc/host/Kconfig b/drivers/mmc/host/Kconfig index 513df18..865dc86 100644 --- a/drivers/mmc/host/Kconfig +++ b/drivers/mmc/host/Kconfig @@ -194,6 +194,19 @@ config MMC_SDHCI_MMP2 If unsure, say N. +config MMC_SDHCI_PXA910 + tristate Marvell PXA910 SD Host Controller support + depends on ARCH_MMP + select MMC_SDHCI + select MMC_SDHCI_PLTFM + select MMC_SDHCI_IO_ACCESSORS + help + This selects the Marvell(R) PXA910 SD Host Controller. + If you have a PXA910 platform with SD Host Controller + and a card slot, say Y or M here. + + If unsure, say N. + config MMC_SDHCI_SPEAR tristate SDHCI support on ST SPEAr platform depends on MMC_SDHCI PLAT_SPEAR diff --git a/drivers/mmc/host/Makefile b/drivers/mmc/host/Makefile index f8650e0..5b75609 100644 --- a/drivers/mmc/host/Makefile +++ b/drivers/mmc/host/Makefile @@ -10,6 +10,7 @@ obj-$(CONFIG_MMC_MXS) += mxs-mmc.o obj-$(CONFIG_MMC_SDHCI)+= sdhci.o obj-$(CONFIG_MMC_SDHCI_PCI)+= sdhci-pci.o obj-$(CONFIG_MMC_SDHCI_MMP2) += sdhci-mmp2.o +obj-$(CONFIG_MMC_SDHCI_PXA910) += sdhci-pxa910.o obj-$(CONFIG_MMC_SDHCI_S3C)+= sdhci-s3c.o obj-$(CONFIG_MMC_SDHCI_SPEAR) += sdhci-spear.o obj-$(CONFIG_MMC_WBSD) += wbsd.o diff --git a/drivers/mmc/host/sdhci-pxa910.c b/drivers/mmc/host/sdhci-pxa910.c new file mode 100644 index 000..56ef328 --- /dev/null +++ b/drivers/mmc/host/sdhci-pxa910.c @@ -0,0 +1,297 @@ +/* + * Copyright (C) 2010 Marvell International Ltd. + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#include linux/err.h +#include linux/init.h +#include linux/platform_device.h +#include linux/clk.h +#include linux/io.h +#include linux/gpio.h +#include linux/mmc/card.h +#include linux/mmc/host.h +#include plat/sdhci.h +#include linux/slab.h +#include sdhci.h +#include sdhci-pltfm.h + +#define SD_FIFO_PARAM 0xe0 +#define DIS_PAD_SD_CLK_GATE0x0400 /* Turn on/off Dynamic SD Clock Gating */ +#define CLK_GATE_ON0x0200 /* Disable/enable Clock Gate */ +#define CLK_GATE_CTL 0x0100 /* Clock Gate Control */ +#define CLK_GATE_SETTING_BITS (DIS_PAD_SD_CLK_GATE | \ + CLK_GATE_ON | CLK_GATE_CTL) + +#define SD_CLOCK_AND_BURST_SIZE_SETUP 0xe6 +#define SDCLK_SEL_SHIFT8 +#define SDCLK_SEL_MASK 0x3 +#define SDCLK_DELAY_SHIFT 10 +#define SDCLK_DELAY_MASK 0x3c + +#define SDHCI_HOST_CONTROL 0x28 +#define SDHCI_CTRL_4BITBUS0x02 + +#define SD_CE_ATA_20xea +#define MMC_CARD 0x1000 +#define MMC_WIDTH 0x0100 + +static void pxa910_sdh_specific_ctrl(struct sdhci_host *host, + struct sdhci_pxa_platdata *pdata) +{ + u16 tmp = 0; + + /* +* tune timing of read data/command when crc error happen +* no performance impact +*/ + if (pdata-clk_delay_sel == 1) { + tmp = readw(host-ioaddr + SD_CLOCK_AND_BURST_SIZE_SETUP); + + tmp = ~(SDCLK_DELAY_MASK SDCLK_DELAY_SHIFT); + tmp |= (pdata-clk_delay_cycles SDCLK_DELAY_MASK) +SDCLK_DELAY_SHIFT; + tmp = ~(SDCLK_SEL_MASK SDCLK_SEL_SHIFT); + tmp |= (1 SDCLK_SEL_MASK) SDCLK_SEL_SHIFT; + + writew(tmp, host-ioaddr + SD_CLOCK_AND_BURST_SIZE_SETUP); + } + + if (pdata-flags PXA_FLAG_DISABLE_CLOCK_GATING) { + tmp = readw(host-ioaddr + SD_FIFO_PARAM); + tmp = ~CLK_GATE_SETTING_BITS; + tmp |= CLK_GATE_SETTING_BITS; + writew(tmp, host-ioaddr + SD_FIFO_PARAM); + } +} + +static int pxa910_mmc_set_width(struct sdhci_host *host, int width) +{ + u8 ctrl; + u16 tmp; + + ctrl = readb(host-ioaddr + SDHCI_HOST_CONTROL); + tmp = readw(host-ioaddr + SD_CE_ATA_2); + if (width == MMC_BUS_WIDTH_8) { + ctrl = ~SDHCI_CTRL_4BITBUS; + tmp |= MMC_CARD | MMC_WIDTH