diff mbox

mmc: dw_mmc: add busmode selection support

Message ID 1343042200-19524-1-git-send-email-girish.shivananjappa@linaro.org
State New
Headers show

Commit Message

Girish K S July 23, 2012, 11:16 a.m. UTC
Synopsis Designware host controller has suppport for open
drain mode selection. During the mmc card initialization the
host controller can select the open-drain bit to allow the device
initialization in the open-drain mode. Once the device enters
the standby mode this bit can be reset to enter push-pull mode.

Signed-off-by: Girish K S <girish.shivananjappa@linaro.org>
---
 drivers/mmc/host/dw_mmc.c |   14 ++++++++++++++
 drivers/mmc/host/dw_mmc.h |    1 +
 2 files changed, 15 insertions(+), 0 deletions(-)

Comments

Jaehoon Chung July 24, 2012, 11:09 a.m. UTC | #1
Hi Girish,

Well..just tested on my board.
this patch didn't work.(eMMC card didn't initialize)
meaning of ios->bus_mode and synosys's bus_mode is same?
How did you test this patch?

Best Regards,
Jaehoon Chung

On 07/23/2012 08:16 PM, Girish K S wrote:
> Synopsis Designware host controller has suppport for open
> drain mode selection. During the mmc card initialization the
> host controller can select the open-drain bit to allow the device
> initialization in the open-drain mode. Once the device enters
> the standby mode this bit can be reset to enter push-pull mode.
> 
> Signed-off-by: Girish K S <girish.shivananjappa@linaro.org>
> ---
>  drivers/mmc/host/dw_mmc.c |   14 ++++++++++++++
>  drivers/mmc/host/dw_mmc.h |    1 +
>  2 files changed, 15 insertions(+), 0 deletions(-)
> 
> diff --git a/drivers/mmc/host/dw_mmc.c b/drivers/mmc/host/dw_mmc.c
> index 72dc3cd..da11e5a 100644
> --- a/drivers/mmc/host/dw_mmc.c
> +++ b/drivers/mmc/host/dw_mmc.c
> @@ -773,6 +773,18 @@ static void dw_mci_request(struct mmc_host *mmc, struct mmc_request *mrq)
>  	spin_unlock_bh(&host->lock);
>  }
>  
> +static void dw_mci_set_busmode(struct dw_mci_slot *slot)
> +{
> +	struct mmc_ios *ios = &slot->mmc->ios;
> +	u32 reg;
> +
> +	reg = mci_readl(slot->host, CTRL);
> +	if (ios->bus_mode == MMC_BUSMODE_OPENDRAIN)
> +		mci_writel(slot->host, CTRL, reg | SDMMC_CTRL_ENABLE_OD);
> +	else
> +		mci_writel(slot->host, CTRL, reg & ~SDMMC_CTRL_ENABLE_OD);
> +}
> +
>  static void dw_mci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
>  {
>  	struct dw_mci_slot *slot = mmc_priv(mmc);
> @@ -818,6 +830,8 @@ static void dw_mci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
>  	default:
>  		break;
>  	}
> +
> +	dw_mci_set_busmode(slot);
>  }
>  
>  static int dw_mci_get_ro(struct mmc_host *mmc)
> diff --git a/drivers/mmc/host/dw_mmc.h b/drivers/mmc/host/dw_mmc.h
> index 15c27e1..1a53fb2 100644
> --- a/drivers/mmc/host/dw_mmc.h
> +++ b/drivers/mmc/host/dw_mmc.h
> @@ -67,6 +67,7 @@
>  
>  /* Control register defines */
>  #define SDMMC_CTRL_USE_IDMAC		BIT(25)
> +#define SDMMC_CTRL_ENABLE_OD		BIT(24)
>  #define SDMMC_CTRL_CEATA_INT_EN		BIT(11)
>  #define SDMMC_CTRL_SEND_AS_CCSD		BIT(10)
>  #define SDMMC_CTRL_SEND_CCSD		BIT(9)
>
Girish K S July 24, 2012, 11:36 a.m. UTC | #2
On 24 July 2012 16:39, Jaehoon Chung <jh80.chung@samsung.com> wrote:
> Hi Girish,
>
> Well..just tested on my board.
> this patch didn't work.(eMMC card didn't initialize)
> meaning of ios->bus_mode and synosys's bus_mode is same?
> How did you test this patch?
Tested it on exynos5 board using dt patches of thomas (with some
modification to his patch)
>
> Best Regards,
> Jaehoon Chung
>
> On 07/23/2012 08:16 PM, Girish K S wrote:
>> Synopsis Designware host controller has suppport for open
>> drain mode selection. During the mmc card initialization the
>> host controller can select the open-drain bit to allow the device
>> initialization in the open-drain mode. Once the device enters
>> the standby mode this bit can be reset to enter push-pull mode.
>>
>> Signed-off-by: Girish K S <girish.shivananjappa@linaro.org>
>> ---
>>  drivers/mmc/host/dw_mmc.c |   14 ++++++++++++++
>>  drivers/mmc/host/dw_mmc.h |    1 +
>>  2 files changed, 15 insertions(+), 0 deletions(-)
>>
>> diff --git a/drivers/mmc/host/dw_mmc.c b/drivers/mmc/host/dw_mmc.c
>> index 72dc3cd..da11e5a 100644
>> --- a/drivers/mmc/host/dw_mmc.c
>> +++ b/drivers/mmc/host/dw_mmc.c
>> @@ -773,6 +773,18 @@ static void dw_mci_request(struct mmc_host *mmc, struct mmc_request *mrq)
>>       spin_unlock_bh(&host->lock);
>>  }
>>
>> +static void dw_mci_set_busmode(struct dw_mci_slot *slot)
>> +{
>> +     struct mmc_ios *ios = &slot->mmc->ios;
>> +     u32 reg;
>> +
>> +     reg = mci_readl(slot->host, CTRL);
>> +     if (ios->bus_mode == MMC_BUSMODE_OPENDRAIN)
>> +             mci_writel(slot->host, CTRL, reg | SDMMC_CTRL_ENABLE_OD);
>> +     else
>> +             mci_writel(slot->host, CTRL, reg & ~SDMMC_CTRL_ENABLE_OD);
>> +}
>> +
>>  static void dw_mci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
>>  {
>>       struct dw_mci_slot *slot = mmc_priv(mmc);
>> @@ -818,6 +830,8 @@ static void dw_mci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
>>       default:
>>               break;
>>       }
>> +
>> +     dw_mci_set_busmode(slot);
>>  }
>>
>>  static int dw_mci_get_ro(struct mmc_host *mmc)
>> diff --git a/drivers/mmc/host/dw_mmc.h b/drivers/mmc/host/dw_mmc.h
>> index 15c27e1..1a53fb2 100644
>> --- a/drivers/mmc/host/dw_mmc.h
>> +++ b/drivers/mmc/host/dw_mmc.h
>> @@ -67,6 +67,7 @@
>>
>>  /* Control register defines */
>>  #define SDMMC_CTRL_USE_IDMAC         BIT(25)
>> +#define SDMMC_CTRL_ENABLE_OD         BIT(24)
>>  #define SDMMC_CTRL_CEATA_INT_EN              BIT(11)
>>  #define SDMMC_CTRL_SEND_AS_CCSD              BIT(10)
>>  #define SDMMC_CTRL_SEND_CCSD         BIT(9)
>>
>
>
Girish K S July 24, 2012, 11:43 a.m. UTC | #3
On 24 July 2012 17:06, Girish K S <girish.shivananjappa@linaro.org> wrote:
> On 24 July 2012 16:39, Jaehoon Chung <jh80.chung@samsung.com> wrote:
>> Hi Girish,
>>
>> Well..just tested on my board.
>> this patch didn't work.(eMMC card didn't initialize)
>> meaning of ios->bus_mode and synosys's bus_mode is same?
Yes it is same. synopsys spec says this is specific to MMC
initialization. when the card core sets this mode during
initialization. the host has to set this bit
>> How did you test this patch?
> Tested it on exynos5 board using dt patches of thomas (with some
> modification to his patch)
>>
>> Best Regards,
>> Jaehoon Chung
>>
>> On 07/23/2012 08:16 PM, Girish K S wrote:
>>> Synopsis Designware host controller has suppport for open
>>> drain mode selection. During the mmc card initialization the
>>> host controller can select the open-drain bit to allow the device
>>> initialization in the open-drain mode. Once the device enters
>>> the standby mode this bit can be reset to enter push-pull mode.
>>>
>>> Signed-off-by: Girish K S <girish.shivananjappa@linaro.org>
>>> ---
>>>  drivers/mmc/host/dw_mmc.c |   14 ++++++++++++++
>>>  drivers/mmc/host/dw_mmc.h |    1 +
>>>  2 files changed, 15 insertions(+), 0 deletions(-)
>>>
>>> diff --git a/drivers/mmc/host/dw_mmc.c b/drivers/mmc/host/dw_mmc.c
>>> index 72dc3cd..da11e5a 100644
>>> --- a/drivers/mmc/host/dw_mmc.c
>>> +++ b/drivers/mmc/host/dw_mmc.c
>>> @@ -773,6 +773,18 @@ static void dw_mci_request(struct mmc_host *mmc, struct mmc_request *mrq)
>>>       spin_unlock_bh(&host->lock);
>>>  }
>>>
>>> +static void dw_mci_set_busmode(struct dw_mci_slot *slot)
>>> +{
>>> +     struct mmc_ios *ios = &slot->mmc->ios;
>>> +     u32 reg;
>>> +
>>> +     reg = mci_readl(slot->host, CTRL);
>>> +     if (ios->bus_mode == MMC_BUSMODE_OPENDRAIN)
>>> +             mci_writel(slot->host, CTRL, reg | SDMMC_CTRL_ENABLE_OD);
>>> +     else
>>> +             mci_writel(slot->host, CTRL, reg & ~SDMMC_CTRL_ENABLE_OD);
>>> +}
>>> +
>>>  static void dw_mci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
>>>  {
>>>       struct dw_mci_slot *slot = mmc_priv(mmc);
>>> @@ -818,6 +830,8 @@ static void dw_mci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
>>>       default:
>>>               break;
>>>       }
>>> +
>>> +     dw_mci_set_busmode(slot);
>>>  }
>>>
>>>  static int dw_mci_get_ro(struct mmc_host *mmc)
>>> diff --git a/drivers/mmc/host/dw_mmc.h b/drivers/mmc/host/dw_mmc.h
>>> index 15c27e1..1a53fb2 100644
>>> --- a/drivers/mmc/host/dw_mmc.h
>>> +++ b/drivers/mmc/host/dw_mmc.h
>>> @@ -67,6 +67,7 @@
>>>
>>>  /* Control register defines */
>>>  #define SDMMC_CTRL_USE_IDMAC         BIT(25)
>>> +#define SDMMC_CTRL_ENABLE_OD         BIT(24)
>>>  #define SDMMC_CTRL_CEATA_INT_EN              BIT(11)
>>>  #define SDMMC_CTRL_SEND_AS_CCSD              BIT(10)
>>>  #define SDMMC_CTRL_SEND_CCSD         BIT(9)
>>>
>>
>>
Jaehoon Chung July 24, 2012, 1:07 p.m. UTC | #4
Hi Girish,

Right, it be mentioned about the open-drain mode in synopsys spec.
But if didn't work on other board, there is some problem.
We can consider the location of set_busmode() .

Best Regards,
Jaehoon Chung

2012/7/24 Girish K S <girish.shivananjappa@linaro.org>:
> On 24 July 2012 17:06, Girish K S <girish.shivananjappa@linaro.org> wrote:
>> On 24 July 2012 16:39, Jaehoon Chung <jh80.chung@samsung.com> wrote:
>>> Hi Girish,
>>>
>>> Well..just tested on my board.
>>> this patch didn't work.(eMMC card didn't initialize)
>>> meaning of ios->bus_mode and synosys's bus_mode is same?
> Yes it is same. synopsys spec says this is specific to MMC
> initialization. when the card core sets this mode during
> initialization. the host has to set this bit
>>> How did you test this patch?
>> Tested it on exynos5 board using dt patches of thomas (with some
>> modification to his patch)
>>>
>>> Best Regards,
>>> Jaehoon Chung
>>>
>>> On 07/23/2012 08:16 PM, Girish K S wrote:
>>>> Synopsis Designware host controller has suppport for open
>>>> drain mode selection. During the mmc card initialization the
>>>> host controller can select the open-drain bit to allow the device
>>>> initialization in the open-drain mode. Once the device enters
>>>> the standby mode this bit can be reset to enter push-pull mode.
>>>>
>>>> Signed-off-by: Girish K S <girish.shivananjappa@linaro.org>
>>>> ---
>>>>  drivers/mmc/host/dw_mmc.c |   14 ++++++++++++++
>>>>  drivers/mmc/host/dw_mmc.h |    1 +
>>>>  2 files changed, 15 insertions(+), 0 deletions(-)
>>>>
>>>> diff --git a/drivers/mmc/host/dw_mmc.c b/drivers/mmc/host/dw_mmc.c
>>>> index 72dc3cd..da11e5a 100644
>>>> --- a/drivers/mmc/host/dw_mmc.c
>>>> +++ b/drivers/mmc/host/dw_mmc.c
>>>> @@ -773,6 +773,18 @@ static void dw_mci_request(struct mmc_host *mmc, struct mmc_request *mrq)
>>>>       spin_unlock_bh(&host->lock);
>>>>  }
>>>>
>>>> +static void dw_mci_set_busmode(struct dw_mci_slot *slot)
>>>> +{
>>>> +     struct mmc_ios *ios = &slot->mmc->ios;
>>>> +     u32 reg;
>>>> +
>>>> +     reg = mci_readl(slot->host, CTRL);
>>>> +     if (ios->bus_mode == MMC_BUSMODE_OPENDRAIN)
>>>> +             mci_writel(slot->host, CTRL, reg | SDMMC_CTRL_ENABLE_OD);
>>>> +     else
>>>> +             mci_writel(slot->host, CTRL, reg & ~SDMMC_CTRL_ENABLE_OD);
>>>> +}
>>>> +
>>>>  static void dw_mci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
>>>>  {
>>>>       struct dw_mci_slot *slot = mmc_priv(mmc);
>>>> @@ -818,6 +830,8 @@ static void dw_mci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
>>>>       default:
>>>>               break;
>>>>       }
>>>> +
>>>> +     dw_mci_set_busmode(slot);
>>>>  }
>>>>
>>>>  static int dw_mci_get_ro(struct mmc_host *mmc)
>>>> diff --git a/drivers/mmc/host/dw_mmc.h b/drivers/mmc/host/dw_mmc.h
>>>> index 15c27e1..1a53fb2 100644
>>>> --- a/drivers/mmc/host/dw_mmc.h
>>>> +++ b/drivers/mmc/host/dw_mmc.h
>>>> @@ -67,6 +67,7 @@
>>>>
>>>>  /* Control register defines */
>>>>  #define SDMMC_CTRL_USE_IDMAC         BIT(25)
>>>> +#define SDMMC_CTRL_ENABLE_OD         BIT(24)
>>>>  #define SDMMC_CTRL_CEATA_INT_EN              BIT(11)
>>>>  #define SDMMC_CTRL_SEND_AS_CCSD              BIT(10)
>>>>  #define SDMMC_CTRL_SEND_CCSD         BIT(9)
>>>>
>>>
>>>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-mmc" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
Girish K S July 24, 2012, 1:09 p.m. UTC | #5
On 24 July 2012 18:37, Jae hoon Chung <jh80.chung@gmail.com> wrote:
> Hi Girish,
>
> Right, it be mentioned about the open-drain mode in synopsys spec.
> But if didn't work on other board, there is some problem.
> We can consider the location of set_busmode() .
may i know the board on which you are testing. i will try to use the
same and simulate the problem
>
> Best Regards,
> Jaehoon Chung
>
> 2012/7/24 Girish K S <girish.shivananjappa@linaro.org>:
>> On 24 July 2012 17:06, Girish K S <girish.shivananjappa@linaro.org> wrote:
>>> On 24 July 2012 16:39, Jaehoon Chung <jh80.chung@samsung.com> wrote:
>>>> Hi Girish,
>>>>
>>>> Well..just tested on my board.
>>>> this patch didn't work.(eMMC card didn't initialize)
>>>> meaning of ios->bus_mode and synosys's bus_mode is same?
>> Yes it is same. synopsys spec says this is specific to MMC
>> initialization. when the card core sets this mode during
>> initialization. the host has to set this bit
>>>> How did you test this patch?
>>> Tested it on exynos5 board using dt patches of thomas (with some
>>> modification to his patch)
>>>>
>>>> Best Regards,
>>>> Jaehoon Chung
>>>>
>>>> On 07/23/2012 08:16 PM, Girish K S wrote:
>>>>> Synopsis Designware host controller has suppport for open
>>>>> drain mode selection. During the mmc card initialization the
>>>>> host controller can select the open-drain bit to allow the device
>>>>> initialization in the open-drain mode. Once the device enters
>>>>> the standby mode this bit can be reset to enter push-pull mode.
>>>>>
>>>>> Signed-off-by: Girish K S <girish.shivananjappa@linaro.org>
>>>>> ---
>>>>>  drivers/mmc/host/dw_mmc.c |   14 ++++++++++++++
>>>>>  drivers/mmc/host/dw_mmc.h |    1 +
>>>>>  2 files changed, 15 insertions(+), 0 deletions(-)
>>>>>
>>>>> diff --git a/drivers/mmc/host/dw_mmc.c b/drivers/mmc/host/dw_mmc.c
>>>>> index 72dc3cd..da11e5a 100644
>>>>> --- a/drivers/mmc/host/dw_mmc.c
>>>>> +++ b/drivers/mmc/host/dw_mmc.c
>>>>> @@ -773,6 +773,18 @@ static void dw_mci_request(struct mmc_host *mmc, struct mmc_request *mrq)
>>>>>       spin_unlock_bh(&host->lock);
>>>>>  }
>>>>>
>>>>> +static void dw_mci_set_busmode(struct dw_mci_slot *slot)
>>>>> +{
>>>>> +     struct mmc_ios *ios = &slot->mmc->ios;
>>>>> +     u32 reg;
>>>>> +
>>>>> +     reg = mci_readl(slot->host, CTRL);
>>>>> +     if (ios->bus_mode == MMC_BUSMODE_OPENDRAIN)
>>>>> +             mci_writel(slot->host, CTRL, reg | SDMMC_CTRL_ENABLE_OD);
>>>>> +     else
>>>>> +             mci_writel(slot->host, CTRL, reg & ~SDMMC_CTRL_ENABLE_OD);
>>>>> +}
>>>>> +
>>>>>  static void dw_mci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
>>>>>  {
>>>>>       struct dw_mci_slot *slot = mmc_priv(mmc);
>>>>> @@ -818,6 +830,8 @@ static void dw_mci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
>>>>>       default:
>>>>>               break;
>>>>>       }
>>>>> +
>>>>> +     dw_mci_set_busmode(slot);
>>>>>  }
>>>>>
>>>>>  static int dw_mci_get_ro(struct mmc_host *mmc)
>>>>> diff --git a/drivers/mmc/host/dw_mmc.h b/drivers/mmc/host/dw_mmc.h
>>>>> index 15c27e1..1a53fb2 100644
>>>>> --- a/drivers/mmc/host/dw_mmc.h
>>>>> +++ b/drivers/mmc/host/dw_mmc.h
>>>>> @@ -67,6 +67,7 @@
>>>>>
>>>>>  /* Control register defines */
>>>>>  #define SDMMC_CTRL_USE_IDMAC         BIT(25)
>>>>> +#define SDMMC_CTRL_ENABLE_OD         BIT(24)
>>>>>  #define SDMMC_CTRL_CEATA_INT_EN              BIT(11)
>>>>>  #define SDMMC_CTRL_SEND_AS_CCSD              BIT(10)
>>>>>  #define SDMMC_CTRL_SEND_CCSD         BIT(9)
>>>>>
>>>>
>>>>
>> --
>> To unsubscribe from this list: send the line "unsubscribe linux-mmc" in
>> the body of a message to majordomo@vger.kernel.org
>> More majordomo info at  http://vger.kernel.org/majordomo-info.html
Jaehoon Chung July 24, 2012, 1:44 p.m. UTC | #6
2012/7/24 Girish K S <girish.shivananjappa@linaro.org>:
> On 24 July 2012 18:37, Jae hoon Chung <jh80.chung@gmail.com> wrote:
>> Hi Girish,
>>
>> Right, it be mentioned about the open-drain mode in synopsys spec.
>> But if didn't work on other board, there is some problem.
>> We can consider the location of set_busmode() .
> may i know the board on which you are testing. i will try to use the
> same and simulate the problem
Exynos4 board and eMMC4.5 card, Synopsys IP version is 2.40a
>>
>> Best Regards,
>> Jaehoon Chung
>>
>> 2012/7/24 Girish K S <girish.shivananjappa@linaro.org>:
>>> On 24 July 2012 17:06, Girish K S <girish.shivananjappa@linaro.org> wrote:
>>>> On 24 July 2012 16:39, Jaehoon Chung <jh80.chung@samsung.com> wrote:
>>>>> Hi Girish,
>>>>>
>>>>> Well..just tested on my board.
>>>>> this patch didn't work.(eMMC card didn't initialize)
>>>>> meaning of ios->bus_mode and synosys's bus_mode is same?
>>> Yes it is same. synopsys spec says this is specific to MMC
>>> initialization. when the card core sets this mode during
>>> initialization. the host has to set this bit
>>>>> How did you test this patch?
>>>> Tested it on exynos5 board using dt patches of thomas (with some
>>>> modification to his patch)
>>>>>
>>>>> Best Regards,
>>>>> Jaehoon Chung
>>>>>
>>>>> On 07/23/2012 08:16 PM, Girish K S wrote:
>>>>>> Synopsis Designware host controller has suppport for open
>>>>>> drain mode selection. During the mmc card initialization the
>>>>>> host controller can select the open-drain bit to allow the device
>>>>>> initialization in the open-drain mode. Once the device enters
>>>>>> the standby mode this bit can be reset to enter push-pull mode.
>>>>>>
>>>>>> Signed-off-by: Girish K S <girish.shivananjappa@linaro.org>
>>>>>> ---
>>>>>>  drivers/mmc/host/dw_mmc.c |   14 ++++++++++++++
>>>>>>  drivers/mmc/host/dw_mmc.h |    1 +
>>>>>>  2 files changed, 15 insertions(+), 0 deletions(-)
>>>>>>
>>>>>> diff --git a/drivers/mmc/host/dw_mmc.c b/drivers/mmc/host/dw_mmc.c
>>>>>> index 72dc3cd..da11e5a 100644
>>>>>> --- a/drivers/mmc/host/dw_mmc.c
>>>>>> +++ b/drivers/mmc/host/dw_mmc.c
>>>>>> @@ -773,6 +773,18 @@ static void dw_mci_request(struct mmc_host *mmc, struct mmc_request *mrq)
>>>>>>       spin_unlock_bh(&host->lock);
>>>>>>  }
>>>>>>
>>>>>> +static void dw_mci_set_busmode(struct dw_mci_slot *slot)
>>>>>> +{
>>>>>> +     struct mmc_ios *ios = &slot->mmc->ios;
>>>>>> +     u32 reg;
>>>>>> +
>>>>>> +     reg = mci_readl(slot->host, CTRL);
>>>>>> +     if (ios->bus_mode == MMC_BUSMODE_OPENDRAIN)
>>>>>> +             mci_writel(slot->host, CTRL, reg | SDMMC_CTRL_ENABLE_OD);
>>>>>> +     else
>>>>>> +             mci_writel(slot->host, CTRL, reg & ~SDMMC_CTRL_ENABLE_OD);
>>>>>> +}
>>>>>> +
>>>>>>  static void dw_mci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
>>>>>>  {
>>>>>>       struct dw_mci_slot *slot = mmc_priv(mmc);
>>>>>> @@ -818,6 +830,8 @@ static void dw_mci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
>>>>>>       default:
>>>>>>               break;
>>>>>>       }
>>>>>> +
>>>>>> +     dw_mci_set_busmode(slot);
>>>>>>  }
>>>>>>
>>>>>>  static int dw_mci_get_ro(struct mmc_host *mmc)
>>>>>> diff --git a/drivers/mmc/host/dw_mmc.h b/drivers/mmc/host/dw_mmc.h
>>>>>> index 15c27e1..1a53fb2 100644
>>>>>> --- a/drivers/mmc/host/dw_mmc.h
>>>>>> +++ b/drivers/mmc/host/dw_mmc.h
>>>>>> @@ -67,6 +67,7 @@
>>>>>>
>>>>>>  /* Control register defines */
>>>>>>  #define SDMMC_CTRL_USE_IDMAC         BIT(25)
>>>>>> +#define SDMMC_CTRL_ENABLE_OD         BIT(24)
>>>>>>  #define SDMMC_CTRL_CEATA_INT_EN              BIT(11)
>>>>>>  #define SDMMC_CTRL_SEND_AS_CCSD              BIT(10)
>>>>>>  #define SDMMC_CTRL_SEND_CCSD         BIT(9)
>>>>>>
>>>>>
>>>>>
>>> --
>>> To unsubscribe from this list: send the line "unsubscribe linux-mmc" in
>>> the body of a message to majordomo@vger.kernel.org
>>> More majordomo info at  http://vger.kernel.org/majordomo-info.html
Girish K S July 25, 2012, 1:22 p.m. UTC | #7
On 24 July 2012 19:14, Jae hoon Chung <jh80.chung@gmail.com> wrote:
> 2012/7/24 Girish K S <girish.shivananjappa@linaro.org>:
>> On 24 July 2012 18:37, Jae hoon Chung <jh80.chung@gmail.com> wrote:
>>> Hi Girish,
>>>
>>> Right, it be mentioned about the open-drain mode in synopsys spec.
>>> But if didn't work on other board, there is some problem.
>>> We can consider the location of set_busmode() .
>> may i know the board on which you are testing. i will try to use the
>> same and simulate the problem
> Exynos4 board and eMMC4.5 card, Synopsys IP version is 2.40a
Just now i tested it on exynos4 board/ eMMC 4.4 card Synopsis 2.40a
host controller. Everything works fine. this patch doesnt have any
side effect on the exynos4 board
please check from ur end. might be some other issue.
>>>
>>> Best Regards,
>>> Jaehoon Chung
>>>
>>> 2012/7/24 Girish K S <girish.shivananjappa@linaro.org>:
>>>> On 24 July 2012 17:06, Girish K S <girish.shivananjappa@linaro.org> wrote:
>>>>> On 24 July 2012 16:39, Jaehoon Chung <jh80.chung@samsung.com> wrote:
>>>>>> Hi Girish,
>>>>>>
>>>>>> Well..just tested on my board.
>>>>>> this patch didn't work.(eMMC card didn't initialize)
>>>>>> meaning of ios->bus_mode and synosys's bus_mode is same?
>>>> Yes it is same. synopsys spec says this is specific to MMC
>>>> initialization. when the card core sets this mode during
>>>> initialization. the host has to set this bit
>>>>>> How did you test this patch?
>>>>> Tested it on exynos5 board using dt patches of thomas (with some
>>>>> modification to his patch)
>>>>>>
>>>>>> Best Regards,
>>>>>> Jaehoon Chung
>>>>>>
>>>>>> On 07/23/2012 08:16 PM, Girish K S wrote:
>>>>>>> Synopsis Designware host controller has suppport for open
>>>>>>> drain mode selection. During the mmc card initialization the
>>>>>>> host controller can select the open-drain bit to allow the device
>>>>>>> initialization in the open-drain mode. Once the device enters
>>>>>>> the standby mode this bit can be reset to enter push-pull mode.
>>>>>>>
>>>>>>> Signed-off-by: Girish K S <girish.shivananjappa@linaro.org>
>>>>>>> ---
>>>>>>>  drivers/mmc/host/dw_mmc.c |   14 ++++++++++++++
>>>>>>>  drivers/mmc/host/dw_mmc.h |    1 +
>>>>>>>  2 files changed, 15 insertions(+), 0 deletions(-)
>>>>>>>
>>>>>>> diff --git a/drivers/mmc/host/dw_mmc.c b/drivers/mmc/host/dw_mmc.c
>>>>>>> index 72dc3cd..da11e5a 100644
>>>>>>> --- a/drivers/mmc/host/dw_mmc.c
>>>>>>> +++ b/drivers/mmc/host/dw_mmc.c
>>>>>>> @@ -773,6 +773,18 @@ static void dw_mci_request(struct mmc_host *mmc, struct mmc_request *mrq)
>>>>>>>       spin_unlock_bh(&host->lock);
>>>>>>>  }
>>>>>>>
>>>>>>> +static void dw_mci_set_busmode(struct dw_mci_slot *slot)
>>>>>>> +{
>>>>>>> +     struct mmc_ios *ios = &slot->mmc->ios;
>>>>>>> +     u32 reg;
>>>>>>> +
>>>>>>> +     reg = mci_readl(slot->host, CTRL);
>>>>>>> +     if (ios->bus_mode == MMC_BUSMODE_OPENDRAIN)
>>>>>>> +             mci_writel(slot->host, CTRL, reg | SDMMC_CTRL_ENABLE_OD);
>>>>>>> +     else
>>>>>>> +             mci_writel(slot->host, CTRL, reg & ~SDMMC_CTRL_ENABLE_OD);
>>>>>>> +}
>>>>>>> +
>>>>>>>  static void dw_mci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
>>>>>>>  {
>>>>>>>       struct dw_mci_slot *slot = mmc_priv(mmc);
>>>>>>> @@ -818,6 +830,8 @@ static void dw_mci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
>>>>>>>       default:
>>>>>>>               break;
>>>>>>>       }
>>>>>>> +
>>>>>>> +     dw_mci_set_busmode(slot);
>>>>>>>  }
>>>>>>>
>>>>>>>  static int dw_mci_get_ro(struct mmc_host *mmc)
>>>>>>> diff --git a/drivers/mmc/host/dw_mmc.h b/drivers/mmc/host/dw_mmc.h
>>>>>>> index 15c27e1..1a53fb2 100644
>>>>>>> --- a/drivers/mmc/host/dw_mmc.h
>>>>>>> +++ b/drivers/mmc/host/dw_mmc.h
>>>>>>> @@ -67,6 +67,7 @@
>>>>>>>
>>>>>>>  /* Control register defines */
>>>>>>>  #define SDMMC_CTRL_USE_IDMAC         BIT(25)
>>>>>>> +#define SDMMC_CTRL_ENABLE_OD         BIT(24)
>>>>>>>  #define SDMMC_CTRL_CEATA_INT_EN              BIT(11)
>>>>>>>  #define SDMMC_CTRL_SEND_AS_CCSD              BIT(10)
>>>>>>>  #define SDMMC_CTRL_SEND_CCSD         BIT(9)
>>>>>>>
>>>>>>
>>>>>>
>>>> --
>>>> To unsubscribe from this list: send the line "unsubscribe linux-mmc" in
>>>> the body of a message to majordomo@vger.kernel.org
>>>> More majordomo info at  http://vger.kernel.org/majordomo-info.html
Girish K S July 26, 2012, 3:41 a.m. UTC | #8
On 24 July 2012 18:37, Jae hoon Chung <jh80.chung@gmail.com> wrote:
> Hi Girish,
>
> Right, it be mentioned about the open-drain mode in synopsys spec.
> But if didn't work on other board, there is some problem.
> We can consider the location of set_busmode() .
Sure. Currently i am setting the bus mode after sending the command
during the clock setting. since the bus mode has affect on the cmd
line i will try to move the location of calling bus mode before
setting the clock.
you can just check whether card gets detected by moving the set mode
function just below the switch statement of bus width.
On my board irrespective of the set bus mode location it works fine
>
> Best Regards,
> Jaehoon Chung
>
> 2012/7/24 Girish K S <girish.shivananjappa@linaro.org>:
>> On 24 July 2012 17:06, Girish K S <girish.shivananjappa@linaro.org> wrote:
>>> On 24 July 2012 16:39, Jaehoon Chung <jh80.chung@samsung.com> wrote:
>>>> Hi Girish,
>>>>
>>>> Well..just tested on my board.
>>>> this patch didn't work.(eMMC card didn't initialize)
>>>> meaning of ios->bus_mode and synosys's bus_mode is same?
>> Yes it is same. synopsys spec says this is specific to MMC
>> initialization. when the card core sets this mode during
>> initialization. the host has to set this bit
>>>> How did you test this patch?
>>> Tested it on exynos5 board using dt patches of thomas (with some
>>> modification to his patch)
>>>>
>>>> Best Regards,
>>>> Jaehoon Chung
>>>>
>>>> On 07/23/2012 08:16 PM, Girish K S wrote:
>>>>> Synopsis Designware host controller has suppport for open
>>>>> drain mode selection. During the mmc card initialization the
>>>>> host controller can select the open-drain bit to allow the device
>>>>> initialization in the open-drain mode. Once the device enters
>>>>> the standby mode this bit can be reset to enter push-pull mode.
>>>>>
>>>>> Signed-off-by: Girish K S <girish.shivananjappa@linaro.org>
>>>>> ---
>>>>>  drivers/mmc/host/dw_mmc.c |   14 ++++++++++++++
>>>>>  drivers/mmc/host/dw_mmc.h |    1 +
>>>>>  2 files changed, 15 insertions(+), 0 deletions(-)
>>>>>
>>>>> diff --git a/drivers/mmc/host/dw_mmc.c b/drivers/mmc/host/dw_mmc.c
>>>>> index 72dc3cd..da11e5a 100644
>>>>> --- a/drivers/mmc/host/dw_mmc.c
>>>>> +++ b/drivers/mmc/host/dw_mmc.c
>>>>> @@ -773,6 +773,18 @@ static void dw_mci_request(struct mmc_host *mmc, struct mmc_request *mrq)
>>>>>       spin_unlock_bh(&host->lock);
>>>>>  }
>>>>>
>>>>> +static void dw_mci_set_busmode(struct dw_mci_slot *slot)
>>>>> +{
>>>>> +     struct mmc_ios *ios = &slot->mmc->ios;
>>>>> +     u32 reg;
>>>>> +
>>>>> +     reg = mci_readl(slot->host, CTRL);
>>>>> +     if (ios->bus_mode == MMC_BUSMODE_OPENDRAIN)
>>>>> +             mci_writel(slot->host, CTRL, reg | SDMMC_CTRL_ENABLE_OD);
>>>>> +     else
>>>>> +             mci_writel(slot->host, CTRL, reg & ~SDMMC_CTRL_ENABLE_OD);
>>>>> +}
>>>>> +
>>>>>  static void dw_mci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
>>>>>  {
>>>>>       struct dw_mci_slot *slot = mmc_priv(mmc);
>>>>> @@ -818,6 +830,8 @@ static void dw_mci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
>>>>>       default:
>>>>>               break;
>>>>>       }
>>>>> +
>>>>> +     dw_mci_set_busmode(slot);
>>>>>  }
>>>>>
>>>>>  static int dw_mci_get_ro(struct mmc_host *mmc)
>>>>> diff --git a/drivers/mmc/host/dw_mmc.h b/drivers/mmc/host/dw_mmc.h
>>>>> index 15c27e1..1a53fb2 100644
>>>>> --- a/drivers/mmc/host/dw_mmc.h
>>>>> +++ b/drivers/mmc/host/dw_mmc.h
>>>>> @@ -67,6 +67,7 @@
>>>>>
>>>>>  /* Control register defines */
>>>>>  #define SDMMC_CTRL_USE_IDMAC         BIT(25)
>>>>> +#define SDMMC_CTRL_ENABLE_OD         BIT(24)
>>>>>  #define SDMMC_CTRL_CEATA_INT_EN              BIT(11)
>>>>>  #define SDMMC_CTRL_SEND_AS_CCSD              BIT(10)
>>>>>  #define SDMMC_CTRL_SEND_CCSD         BIT(9)
>>>>>
>>>>
>>>>
>> --
>> To unsubscribe from this list: send the line "unsubscribe linux-mmc" in
>> the body of a message to majordomo@vger.kernel.org
>> More majordomo info at  http://vger.kernel.org/majordomo-info.html
Jaehoon Chung July 26, 2012, 6 a.m. UTC | #9
Hi Girish,

I re-tested the your patch.
How about locating into dw_mci_setup_bus()?

And if compare the previously and current busmode,
I think host needs not to re-write at register.
For example,
if (slot->bus_mode == ios->bus_mode)
	return;

Then this patch looks good to me.

Best Regards,
Jaehoon Chung

On 07/26/2012 12:41 PM, Girish K S wrote:
> On 24 July 2012 18:37, Jae hoon Chung <jh80.chung@gmail.com> wrote:
>> Hi Girish,
>>
>> Right, it be mentioned about the open-drain mode in synopsys spec.
>> But if didn't work on other board, there is some problem.
>> We can consider the location of set_busmode() .
> Sure. Currently i am setting the bus mode after sending the command
> during the clock setting. since the bus mode has affect on the cmd
> line i will try to move the location of calling bus mode before
> setting the clock.
> you can just check whether card gets detected by moving the set mode
> function just below the switch statement of bus width.
> On my board irrespective of the set bus mode location it works fine
>>
>> Best Regards,
>> Jaehoon Chung
>>
>> 2012/7/24 Girish K S <girish.shivananjappa@linaro.org>:
>>> On 24 July 2012 17:06, Girish K S <girish.shivananjappa@linaro.org> wrote:
>>>> On 24 July 2012 16:39, Jaehoon Chung <jh80.chung@samsung.com> wrote:
>>>>> Hi Girish,
>>>>>
>>>>> Well..just tested on my board.
>>>>> this patch didn't work.(eMMC card didn't initialize)
>>>>> meaning of ios->bus_mode and synosys's bus_mode is same?
>>> Yes it is same. synopsys spec says this is specific to MMC
>>> initialization. when the card core sets this mode during
>>> initialization. the host has to set this bit
>>>>> How did you test this patch?
>>>> Tested it on exynos5 board using dt patches of thomas (with some
>>>> modification to his patch)
>>>>>
>>>>> Best Regards,
>>>>> Jaehoon Chung
>>>>>
>>>>> On 07/23/2012 08:16 PM, Girish K S wrote:
>>>>>> Synopsis Designware host controller has suppport for open
>>>>>> drain mode selection. During the mmc card initialization the
>>>>>> host controller can select the open-drain bit to allow the device
>>>>>> initialization in the open-drain mode. Once the device enters
>>>>>> the standby mode this bit can be reset to enter push-pull mode.
>>>>>>
>>>>>> Signed-off-by: Girish K S <girish.shivananjappa@linaro.org>
>>>>>> ---
>>>>>>  drivers/mmc/host/dw_mmc.c |   14 ++++++++++++++
>>>>>>  drivers/mmc/host/dw_mmc.h |    1 +
>>>>>>  2 files changed, 15 insertions(+), 0 deletions(-)
>>>>>>
>>>>>> diff --git a/drivers/mmc/host/dw_mmc.c b/drivers/mmc/host/dw_mmc.c
>>>>>> index 72dc3cd..da11e5a 100644
>>>>>> --- a/drivers/mmc/host/dw_mmc.c
>>>>>> +++ b/drivers/mmc/host/dw_mmc.c
>>>>>> @@ -773,6 +773,18 @@ static void dw_mci_request(struct mmc_host *mmc, struct mmc_request *mrq)
>>>>>>       spin_unlock_bh(&host->lock);
>>>>>>  }
>>>>>>
>>>>>> +static void dw_mci_set_busmode(struct dw_mci_slot *slot)
>>>>>> +{
>>>>>> +     struct mmc_ios *ios = &slot->mmc->ios;
>>>>>> +     u32 reg;
>>>>>> +
>>>>>> +     reg = mci_readl(slot->host, CTRL);
>>>>>> +     if (ios->bus_mode == MMC_BUSMODE_OPENDRAIN)
>>>>>> +             mci_writel(slot->host, CTRL, reg | SDMMC_CTRL_ENABLE_OD);
>>>>>> +     else
>>>>>> +             mci_writel(slot->host, CTRL, reg & ~SDMMC_CTRL_ENABLE_OD);
>>>>>> +}
>>>>>> +
>>>>>>  static void dw_mci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
>>>>>>  {
>>>>>>       struct dw_mci_slot *slot = mmc_priv(mmc);
>>>>>> @@ -818,6 +830,8 @@ static void dw_mci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
>>>>>>       default:
>>>>>>               break;
>>>>>>       }
>>>>>> +
>>>>>> +     dw_mci_set_busmode(slot);
>>>>>>  }
>>>>>>
>>>>>>  static int dw_mci_get_ro(struct mmc_host *mmc)
>>>>>> diff --git a/drivers/mmc/host/dw_mmc.h b/drivers/mmc/host/dw_mmc.h
>>>>>> index 15c27e1..1a53fb2 100644
>>>>>> --- a/drivers/mmc/host/dw_mmc.h
>>>>>> +++ b/drivers/mmc/host/dw_mmc.h
>>>>>> @@ -67,6 +67,7 @@
>>>>>>
>>>>>>  /* Control register defines */
>>>>>>  #define SDMMC_CTRL_USE_IDMAC         BIT(25)
>>>>>> +#define SDMMC_CTRL_ENABLE_OD         BIT(24)
>>>>>>  #define SDMMC_CTRL_CEATA_INT_EN              BIT(11)
>>>>>>  #define SDMMC_CTRL_SEND_AS_CCSD              BIT(10)
>>>>>>  #define SDMMC_CTRL_SEND_CCSD         BIT(9)
>>>>>>
>>>>>
>>>>>
>>> --
>>> To unsubscribe from this list: send the line "unsubscribe linux-mmc" in
>>> the body of a message to majordomo@vger.kernel.org
>>> More majordomo info at  http://vger.kernel.org/majordomo-info.html
>
Girish K S July 26, 2012, 6:19 a.m. UTC | #10
On 26 July 2012 11:30, Jaehoon Chung <jh80.chung@samsung.com> wrote:
> Hi Girish,
>
> I re-tested the your patch.
> How about locating into dw_mci_setup_bus()?
>
> And if compare the previously and current busmode,
> I think host needs not to re-write at register.
> For example,
> if (slot->bus_mode == ios->bus_mode)
>         return;
>
> Then this patch looks good to me.
Thanks Jaehoon. I will try to test the same and let you know. if
relocation is fine then i will send a patch
>
> Best Regards,
> Jaehoon Chung
>
> On 07/26/2012 12:41 PM, Girish K S wrote:
>> On 24 July 2012 18:37, Jae hoon Chung <jh80.chung@gmail.com> wrote:
>>> Hi Girish,
>>>
>>> Right, it be mentioned about the open-drain mode in synopsys spec.
>>> But if didn't work on other board, there is some problem.
>>> We can consider the location of set_busmode() .
>> Sure. Currently i am setting the bus mode after sending the command
>> during the clock setting. since the bus mode has affect on the cmd
>> line i will try to move the location of calling bus mode before
>> setting the clock.
>> you can just check whether card gets detected by moving the set mode
>> function just below the switch statement of bus width.
>> On my board irrespective of the set bus mode location it works fine
>>>
>>> Best Regards,
>>> Jaehoon Chung
>>>
>>> 2012/7/24 Girish K S <girish.shivananjappa@linaro.org>:
>>>> On 24 July 2012 17:06, Girish K S <girish.shivananjappa@linaro.org> wrote:
>>>>> On 24 July 2012 16:39, Jaehoon Chung <jh80.chung@samsung.com> wrote:
>>>>>> Hi Girish,
>>>>>>
>>>>>> Well..just tested on my board.
>>>>>> this patch didn't work.(eMMC card didn't initialize)
>>>>>> meaning of ios->bus_mode and synosys's bus_mode is same?
>>>> Yes it is same. synopsys spec says this is specific to MMC
>>>> initialization. when the card core sets this mode during
>>>> initialization. the host has to set this bit
>>>>>> How did you test this patch?
>>>>> Tested it on exynos5 board using dt patches of thomas (with some
>>>>> modification to his patch)
>>>>>>
>>>>>> Best Regards,
>>>>>> Jaehoon Chung
>>>>>>
>>>>>> On 07/23/2012 08:16 PM, Girish K S wrote:
>>>>>>> Synopsis Designware host controller has suppport for open
>>>>>>> drain mode selection. During the mmc card initialization the
>>>>>>> host controller can select the open-drain bit to allow the device
>>>>>>> initialization in the open-drain mode. Once the device enters
>>>>>>> the standby mode this bit can be reset to enter push-pull mode.
>>>>>>>
>>>>>>> Signed-off-by: Girish K S <girish.shivananjappa@linaro.org>
>>>>>>> ---
>>>>>>>  drivers/mmc/host/dw_mmc.c |   14 ++++++++++++++
>>>>>>>  drivers/mmc/host/dw_mmc.h |    1 +
>>>>>>>  2 files changed, 15 insertions(+), 0 deletions(-)
>>>>>>>
>>>>>>> diff --git a/drivers/mmc/host/dw_mmc.c b/drivers/mmc/host/dw_mmc.c
>>>>>>> index 72dc3cd..da11e5a 100644
>>>>>>> --- a/drivers/mmc/host/dw_mmc.c
>>>>>>> +++ b/drivers/mmc/host/dw_mmc.c
>>>>>>> @@ -773,6 +773,18 @@ static void dw_mci_request(struct mmc_host *mmc, struct mmc_request *mrq)
>>>>>>>       spin_unlock_bh(&host->lock);
>>>>>>>  }
>>>>>>>
>>>>>>> +static void dw_mci_set_busmode(struct dw_mci_slot *slot)
>>>>>>> +{
>>>>>>> +     struct mmc_ios *ios = &slot->mmc->ios;
>>>>>>> +     u32 reg;
>>>>>>> +
>>>>>>> +     reg = mci_readl(slot->host, CTRL);
>>>>>>> +     if (ios->bus_mode == MMC_BUSMODE_OPENDRAIN)
>>>>>>> +             mci_writel(slot->host, CTRL, reg | SDMMC_CTRL_ENABLE_OD);
>>>>>>> +     else
>>>>>>> +             mci_writel(slot->host, CTRL, reg & ~SDMMC_CTRL_ENABLE_OD);
>>>>>>> +}
>>>>>>> +
>>>>>>>  static void dw_mci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
>>>>>>>  {
>>>>>>>       struct dw_mci_slot *slot = mmc_priv(mmc);
>>>>>>> @@ -818,6 +830,8 @@ static void dw_mci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
>>>>>>>       default:
>>>>>>>               break;
>>>>>>>       }
>>>>>>> +
>>>>>>> +     dw_mci_set_busmode(slot);
>>>>>>>  }
>>>>>>>
>>>>>>>  static int dw_mci_get_ro(struct mmc_host *mmc)
>>>>>>> diff --git a/drivers/mmc/host/dw_mmc.h b/drivers/mmc/host/dw_mmc.h
>>>>>>> index 15c27e1..1a53fb2 100644
>>>>>>> --- a/drivers/mmc/host/dw_mmc.h
>>>>>>> +++ b/drivers/mmc/host/dw_mmc.h
>>>>>>> @@ -67,6 +67,7 @@
>>>>>>>
>>>>>>>  /* Control register defines */
>>>>>>>  #define SDMMC_CTRL_USE_IDMAC         BIT(25)
>>>>>>> +#define SDMMC_CTRL_ENABLE_OD         BIT(24)
>>>>>>>  #define SDMMC_CTRL_CEATA_INT_EN              BIT(11)
>>>>>>>  #define SDMMC_CTRL_SEND_AS_CCSD              BIT(10)
>>>>>>>  #define SDMMC_CTRL_SEND_CCSD         BIT(9)
>>>>>>>
>>>>>>
>>>>>>
>>>> --
>>>> To unsubscribe from this list: send the line "unsubscribe linux-mmc" in
>>>> the body of a message to majordomo@vger.kernel.org
>>>> More majordomo info at  http://vger.kernel.org/majordomo-info.html
>>
>
>
diff mbox

Patch

diff --git a/drivers/mmc/host/dw_mmc.c b/drivers/mmc/host/dw_mmc.c
index 72dc3cd..da11e5a 100644
--- a/drivers/mmc/host/dw_mmc.c
+++ b/drivers/mmc/host/dw_mmc.c
@@ -773,6 +773,18 @@  static void dw_mci_request(struct mmc_host *mmc, struct mmc_request *mrq)
 	spin_unlock_bh(&host->lock);
 }
 
+static void dw_mci_set_busmode(struct dw_mci_slot *slot)
+{
+	struct mmc_ios *ios = &slot->mmc->ios;
+	u32 reg;
+
+	reg = mci_readl(slot->host, CTRL);
+	if (ios->bus_mode == MMC_BUSMODE_OPENDRAIN)
+		mci_writel(slot->host, CTRL, reg | SDMMC_CTRL_ENABLE_OD);
+	else
+		mci_writel(slot->host, CTRL, reg & ~SDMMC_CTRL_ENABLE_OD);
+}
+
 static void dw_mci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
 {
 	struct dw_mci_slot *slot = mmc_priv(mmc);
@@ -818,6 +830,8 @@  static void dw_mci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
 	default:
 		break;
 	}
+
+	dw_mci_set_busmode(slot);
 }
 
 static int dw_mci_get_ro(struct mmc_host *mmc)
diff --git a/drivers/mmc/host/dw_mmc.h b/drivers/mmc/host/dw_mmc.h
index 15c27e1..1a53fb2 100644
--- a/drivers/mmc/host/dw_mmc.h
+++ b/drivers/mmc/host/dw_mmc.h
@@ -67,6 +67,7 @@ 
 
 /* Control register defines */
 #define SDMMC_CTRL_USE_IDMAC		BIT(25)
+#define SDMMC_CTRL_ENABLE_OD		BIT(24)
 #define SDMMC_CTRL_CEATA_INT_EN		BIT(11)
 #define SDMMC_CTRL_SEND_AS_CCSD		BIT(10)
 #define SDMMC_CTRL_SEND_CCSD		BIT(9)