mmc: dw-mmc: add the use_hold_reg in CMD register
Subsystems (2)
Jaehoon Chung
maintainerPATCH 5/5 mmc: dw-mmc: add the use_hold_reg in CMD register
This patch is added the use_hold_reg bit in CMD register.
In upper version than 2.40a, bit[29] of CMD register is used the use_hold_reg. Some SoC is affected by this bit.
(This bit means whether use hold register when send data and cmd.
And related with cclk_in_drv phase)
--- drivers/mmc/host/dw_mmc.c | 36 ++++++++++++++++++++++++++++++++++++ drivers/mmc/host/dw_mmc.h | 1 + include/linux/mmc/dw_mmc.h | 3 +++ 3 files changed, 40 insertions(+), 0 deletions(-)
drivers/mmc/host/dw_mmc.c +36 -0
@@ -265,11 +265,45 @@ static u32 dw_mci_prepare_command(struct mmc_host *mmc, struct mmc_command *cmd)static void dw_mci_start_command (struct dw_mci *host,struct mmc_command *cmd,u32 cmd_flags) { +struct dw_mci_slot *slot = host->cur_slot; +struct mmc_ios *ios = &slot->mmc->ios; + host->cmd = cmd;dev_vdbg (&host->dev,"start command: ARGR=0x%08x CMDR=0x%08x\n" , cmd->arg, cmd_flags); +if (host->quirks &DW_MCI_QUIRK_USE_CLKSEL_REG ) { +/* +* If use HOLD register and SDR12/SDSR25, +* CMD and DATA sent to card through HOLD register by default. +* But if mode is SDR50/DDR50/SDR104, +* only use the hold register when cclk_in_drv value is upper than 0. +*/ +switch (ios->timing) { +case MMC_TIMING_UHS_SDR50 : +case MMC_TIMING_UHS_DDR50 : +if (host->pdata->get_clk_drv) +if ((host->pdata->get_clk_drv (host) && + host->use_hold_reg)) { + cmd_flags |=SDMMC_CMD_USE_HOLD_REG ; +break ; + } + + cmd_flags &= ~SDMMC_CMD_USE_HOLD_REG ; +break ; +case MMC_TIMING_UHS_SDR104 : +case MMC_TIMING_UHS_SDR12 : +case MMC_TIMING_UHS_SDR25 : +if (host->use_hold_reg) { + cmd_flags |=SDMMC_CMD_USE_HOLD_REG ; +break ; + } +default : + cmd_flags &= ~SDMMC_CMD_USE_HOLD_REG ; + } + } +mci_writel (host,CMDARG , cmd->arg);wmb ();
@@ -2018,6 +2052,8 @@ int dw_mci_probe(struct dw_mci *host) host->data_shift =2 ; } + host->use_hold_reg = (mci_readl (host,HCON ) >>22 ) &0x1 ; +/* Reset all blocks */ if (!mci_wait_reset (&host->dev, host))return -ENODEV ;
drivers/mmc/host/dw_mmc.h +1 -0
@@ -111,6 +111,7 @@#define SDMMC_INT_ERROR 0xbfc2/* Command register defines */ #define SDMMC_CMD_START BIT(31) +#define SDMMC_CMD_USE_HOLD_REG BIT(29)#define SDMMC_CMD_CCS_EXP BIT(23)#define SDMMC_CMD_CEATA_RD BIT(22)#define SDMMC_CMD_UPD_CLK BIT(21)
include/linux/mmc/dw_mmc.h +3 -0
@@ -156,6 +156,7 @@ struct dw_mci {u32 fifoth_val;u16 verid;u16 data_offset; +bool use_hold_reg;struct device dev;struct dw_mci_board *pdata;struct dw_mci_slot *slot[MAX_MCI_SLOTS ];
@@ -201,6 +202,8 @@ struct dw_mci_dma_ops {#define DW_MCI_QUIRK_HIGHSPEED BIT(2)/* Unreliable card detection */ #define DW_MCI_QUIRK_BROKEN_CARD_DETECTION BIT(3) +/* To use the CLKSEL register for phase-shift */ +#define DW_MCI_QUIRK_USE_CLKSEL_REG BIT(4)struct dma_pdata ;
Signature · 1 line
1.7.4.1
Quoted 27 lines · Jaehoon Chung
This patch is added the
use_hold_regbit in CMD register.In upper version than 2.40a, bit[29] of CMD register is used the
use_hold_reg. Some SoC is affected by this bit.
(This bit means whether use hold register when send data and cmd.
And related withcclk_in_drvphase)Signed-off-by Jaehoon Chung <[email protected]>Signed-off-by Kyungmin Park <[email protected]>--- drivers/mmc/host/dw_mmc.c | 36 ++++++++++++++++++++++++++++++++++++ drivers/mmc/host/dw_mmc.h | 1 + include/linux/mmc/dw_mmc.h | 3 +++ 3 files changed, 40 insertions(+), 0 deletions(-)drivers/mmc/host/dw_mmc.c +3
-0@@ -265,11 +265,45 @@ static u32 dw_mci_prepare_command(struct mmc_host *mmc, struct mmc_command *cmd)static void dw_mci_start_command (struct dw_mci *host,struct mmc_command *cmd,u32 cmd_flags) { +struct dw_mci_slot *slot = host->cur_slot; +struct mmc_ios *ios = &slot->mmc->ios; + host->cmd = cmd;
drivers/mmc/host/dw_mmc.c static u32 dw_mci_prepare_command(struct mmc_host *mmc, struct mmc_command *cmd) · line 281
Quoted 10 lines
drivers/mmc/host/dw_mmc.c +6
-0dev_vdbg (&host->dev,"start command: ARGR=0x%08x CMDR=0x%08x\n" , cmd->arg, cmd_flags); +if (host->quirks &DW_MCI_QUIRK_USE_CLKSEL_REG ) { +/* +* If use HOLD register and SDR12/SDSR25, +* CMD and DATA sent to card through HOLD register by default. +* But if mode is SDR50/DDR50/SDR104, +* only use the hold register when cclk_in_drv value is upper than 0.
"greater" might be better than "upper" here.
drivers/mmc/host/dw_mmc.c static u32 dw_mci_prepare_command(struct mmc_host *mmc, struct mmc_command *cmd) · line 288
Quoted 7 lines
drivers/mmc/host/dw_mmc.c +7
-0+*/ +switch (ios->timing) { +case MMC_TIMING_UHS_SDR50 : +case MMC_TIMING_UHS_DDR50 : +if (host->pdata->get_clk_drv) +if ((host->pdata->get_clk_drv (host) && + host->use_hold_reg)) {
There's more brackets than necessary here in the second if, and the two if conditions could probably be combined to make it neater.
Jaehoon Chung
maintainerQuoted 32 lines · Will Newton
Quoted 31 lines · Jaehoon Chung
This patch is added the
use_hold_regbit in CMD register.In upper version than 2.40a, bit[29] of CMD register is used the
use_hold_reg. Some SoC is affected by this bit.
(This bit means whether use hold register when send data and cmd.
And related withcclk_in_drvphase)Signed-off-by Jaehoon Chung <[email protected]>Signed-off-by Kyungmin Park <[email protected]>--- drivers/mmc/host/dw_mmc.c | 36 ++++++++++++++++++++++++++++++++++++ drivers/mmc/host/dw_mmc.h | 1 + include/linux/mmc/dw_mmc.h | 3 +++ 3 files changed, 40 insertions(+), 0 deletions(-)drivers/mmc/host/dw_mmc.c +3
-0@@ -265,11 +265,45 @@ static u32 dw_mci_prepare_command(struct mmc_host *mmc, struct mmc_command *cmd)static void dw_mci_start_command (struct dw_mci *host,struct mmc_command *cmd,u32 cmd_flags) { +struct dw_mci_slot *slot = host->cur_slot; +struct mmc_ios *ios = &slot->mmc->ios; + host->cmd = cmd;dev_vdbg (&host->dev,"start command: ARGR=0x%08x CMDR=0x%08x\n" , cmd->arg, cmd_flags);
Quoted 8 lines
drivers/mmc/host/dw_mmc.c static u32 dw_mci_prepare_command(struct mmc_host *mmc, struct mmc_command *cmd) · line 281
Quoted 6 lines
drivers/mmc/host/dw_mmc.c +6
-0+if (host->quirks &DW_MCI_QUIRK_USE_CLKSEL_REG ) { +/* +* If use HOLD register and SDR12/SDSR25, +* CMD and DATA sent to card through HOLD register by default. +* But if mode is SDR50/DDR50/SDR104, +* only use the hold register when cclk_in_drv value is upper than 0. "greater" might be better than "upper" here.
will change.
Quoted 11 lines
drivers/mmc/host/dw_mmc.c static u32 dw_mci_prepare_command(struct mmc_host *mmc, struct mmc_command *cmd) · line 288
Quoted 8 lines
drivers/mmc/host/dw_mmc.c +7
-0+*/ +switch (ios->timing) { +case MMC_TIMING_UHS_SDR50 : +case MMC_TIMING_UHS_DDR50 : +if (host->pdata->get_clk_drv) +if ((host->pdata->get_clk_drv (host) && + host->use_hold_reg)) {There's more brackets than necessary here in the second if, and the two if conditions could probably be combined to make it neater.
Ok. I will fix.
Best Regards,
Jaehoon Chung
Quoted 5 lines
--
To unsubscribe from this list: send the line "unsubscribe linux-mmc" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html
Quoted 44 lines · Jaehoon Chung
This patch is added the
use_hold_regbit in CMD register.In upper version than 2.40a, bit[29] of CMD register is used the
use_hold_reg. Some SoC is affected by this bit.
(This bit means whether use hold register when send data and cmd.
And related withcclk_in_drvphase)Signed-off-by Jaehoon Chung <[email protected]>Signed-off-by Kyungmin Park <[email protected]>--- drivers/mmc/host/dw_mmc.c | 36 ++++++++++++++++++++++++++++++++++++ drivers/mmc/host/dw_mmc.h | 1 + include/linux/mmc/dw_mmc.h | 3 +++ 3 files changed, 40 insertions(+), 0 deletions(-)drivers/mmc/host/dw_mmc.c +16
-0@@ -265,11 +265,45 @@ static u32 dw_mci_prepare_command(struct mmc_host *mmc, struct mmc_command *cmd)static void dw_mci_start_command (struct dw_mci *host,struct mmc_command *cmd,u32 cmd_flags) { +struct dw_mci_slot *slot = host->cur_slot; +struct mmc_ios *ios = &slot->mmc->ios; + host->cmd = cmd;dev_vdbg (&host->dev,"start command: ARGR=0x%08x CMDR=0x%08x\n" , cmd->arg, cmd_flags); +if (host->quirks &DW_MCI_QUIRK_USE_CLKSEL_REG ) { +/* +* If use HOLD register and SDR12/SDSR25, +* CMD and DATA sent to card through HOLD register by default. +* But if mode is SDR50/DDR50/SDR104, +* only use the hold register when cclk_in_drv value is upper than 0. +*/ +switch (ios->timing) { +case MMC_TIMING_UHS_SDR50 : +case MMC_TIMING_UHS_DDR50 : +if (host->pdata->get_clk_drv) +if ((host->pdata->get_clk_drv (host) && + host->use_hold_reg)) {
drivers/mmc/host/dw_mmc.c static u32 dw_mci_prepare_command(struct mmc_host *mmc, struct mmc_command *cmd) · line 298
Quoted 10 lines
drivers/mmc/host/dw_mmc.c +10
-0+ cmd_flags |=SDMMC_CMD_USE_HOLD_REG ; +break ; + } + + cmd_flags &= ~SDMMC_CMD_USE_HOLD_REG ; +break ; +case MMC_TIMING_UHS_SDR104 : +case MMC_TIMING_UHS_SDR12 : +case MMC_TIMING_UHS_SDR25 : +if (host->use_hold_reg) {
Are there other conditions to be considered as well?
drivers/mmc/host/dw_mmc.c static u32 dw_mci_prepare_command(struct mmc_host *mmc, struct mmc_command *cmd) · line 305
Quoted 7 lines
drivers/mmc/host/dw_mmc.c +7
-0+ cmd_flags |=SDMMC_CMD_USE_HOLD_REG ; +break ; + } +default : + cmd_flags &= ~SDMMC_CMD_USE_HOLD_REG ; + } + }
If routine as a whole is moved to dw_mci_set_ios, it would be better. There is no need to execute whenever command starts.
Thanks,
Seungwon Jeon
Quoted 52 lines
drivers/mmc/host/dw_mmc.c +3
-0+mci_writel (host,CMDARG , cmd->arg);wmb ();@@ -2018,6 +2052,8 @@ int dw_mci_probe(struct dw_mci *host) host->data_shift =2 ; } + host->use_hold_reg = (mci_readl (host,HCON ) >>22 ) &0x1 ; +/* Reset all blocks */ if (!mci_wait_reset (&host->dev, host))return -ENODEV ;drivers/mmc/host/dw_mmc.h +1
-0@@ -111,6 +111,7 @@#define SDMMC_INT_ERROR 0xbfc2/* Command register defines */ #define SDMMC_CMD_START BIT(31) +#define SDMMC_CMD_USE_HOLD_REG BIT(29)#define SDMMC_CMD_CCS_EXP BIT(23)#define SDMMC_CMD_CEATA_RD BIT(22)#define SDMMC_CMD_UPD_CLK BIT(21)include/linux/mmc/dw_mmc.h +3
-1@@ -156,6 +156,7 @@ struct dw_mci {u32 fifoth_val;u16 verid;u16 data_offset; +bool use_hold_reg;struct device dev;struct dw_mci_board *pdata;struct dw_mci_slot *slot[MAX_MCI_SLOTS ];@@ -201,6 +202,8 @@ struct dw_mci_dma_ops {#define DW_MCI_QUIRK_HIGHSPEED BIT(2)/* Unreliable card detection */ #define DW_MCI_QUIRK_BROKEN_CARD_DETECTION BIT(3) +/* To use the CLKSEL register for phase-shift */ +#define DW_MCI_QUIRK_USE_CLKSEL_REG BIT(4)struct dma_pdata ; --1.7.4.1
--
To unsubscribe from this list: send the line "unsubscribe linux-mmc" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html
Jaehoon Chung
maintainerQuoted 48 lines · Seungwon Jeon
Quoted 47 lines · Jaehoon Chung
This patch is added the
use_hold_regbit in CMD register.In upper version than 2.40a, bit[29] of CMD register is used the
use_hold_reg. Some SoC is affected by this bit.
(This bit means whether use hold register when send data and cmd.
And related withcclk_in_drvphase)Signed-off-by Jaehoon Chung <[email protected]>Signed-off-by Kyungmin Park <[email protected]>--- drivers/mmc/host/dw_mmc.c | 36 ++++++++++++++++++++++++++++++++++++ drivers/mmc/host/dw_mmc.h | 1 + include/linux/mmc/dw_mmc.h | 3 +++ 3 files changed, 40 insertions(+), 0 deletions(-)drivers/mmc/host/dw_mmc.c +19
-0@@ -265,11 +265,45 @@ static u32 dw_mci_prepare_command(struct mmc_host *mmc, struct mmc_command *cmd)static void dw_mci_start_command (struct dw_mci *host,struct mmc_command *cmd,u32 cmd_flags) { +struct dw_mci_slot *slot = host->cur_slot; +struct mmc_ios *ios = &slot->mmc->ios; + host->cmd = cmd;dev_vdbg (&host->dev,"start command: ARGR=0x%08x CMDR=0x%08x\n" , cmd->arg, cmd_flags); +if (host->quirks &DW_MCI_QUIRK_USE_CLKSEL_REG ) { +/* +* If use HOLD register and SDR12/SDSR25, +* CMD and DATA sent to card through HOLD register by default. +* But if mode is SDR50/DDR50/SDR104, +* only use the hold register when cclk_in_drv value is upper than 0. +*/ +switch (ios->timing) { +case MMC_TIMING_UHS_SDR50 : +case MMC_TIMING_UHS_DDR50 : +if (host->pdata->get_clk_drv) +if ((host->pdata->get_clk_drv (host) && + host->use_hold_reg)) { + cmd_flags |=SDMMC_CMD_USE_HOLD_REG ; +break ; + }
Quoted 8 lines
drivers/mmc/host/dw_mmc.c static u32 dw_mci_prepare_command(struct mmc_host *mmc, struct mmc_command *cmd) · line 298
Quoted 7 lines
drivers/mmc/host/dw_mmc.c +7
-0+ + cmd_flags &= ~SDMMC_CMD_USE_HOLD_REG ; +break ; +case MMC_TIMING_UHS_SDR104 : +case MMC_TIMING_UHS_SDR12 : +case MMC_TIMING_UHS_SDR25 : +if (host->use_hold_reg) {Are there other conditions to be considered as well?
MMC_TIMING_UHS_SDR104 need to consider the cclk_in_drv. Below is right..i will fix this.
case MMC_TIMING_UHS_SDR_50: case MMC_TIMING_UHS_DDR_50: case MMC_TIMING_UHS_SDR_140: code... case MMC_TIMING_UHS_SDR_12: case MMC_TIMING_UHS_SDR_25: code..
And we could consider the high-speed/non-DDR mode. I will check the manual.
Quoted 10 lines
drivers/mmc/host/dw_mmc.c static u32 dw_mci_prepare_command(struct mmc_host *mmc, struct mmc_command *cmd) · line 305
Quoted 8 lines
drivers/mmc/host/dw_mmc.c +7
-0+ cmd_flags |=SDMMC_CMD_USE_HOLD_REG ; +break ; + } +default : + cmd_flags &= ~SDMMC_CMD_USE_HOLD_REG ; + } + }If routine as a whole is moved to
dw_mci_set_ios, it would be better. There is no need to execute whenever command starts.
As you mentioned, I will try to test after modify.
Best Regards,
Jaehoon Chung
Quoted 62 lines
Thanks,
Seungwon JeonQuoted 47 lines
drivers/mmc/host/dw_mmc.c +3
-0+mci_writel (host,CMDARG , cmd->arg);wmb ();@@ -2018,6 +2052,8 @@ int dw_mci_probe(struct dw_mci *host) host->data_shift =2 ; } + host->use_hold_reg = (mci_readl (host,HCON ) >>22 ) &0x1 ; +/* Reset all blocks */ if (!mci_wait_reset (&host->dev, host))return -ENODEV ;drivers/mmc/host/dw_mmc.h +1
-0@@ -111,6 +111,7 @@#define SDMMC_INT_ERROR 0xbfc2/* Command register defines */ #define SDMMC_CMD_START BIT(31) +#define SDMMC_CMD_USE_HOLD_REG BIT(29)#define SDMMC_CMD_CCS_EXP BIT(23)#define SDMMC_CMD_CEATA_RD BIT(22)#define SDMMC_CMD_UPD_CLK BIT(21)include/linux/mmc/dw_mmc.h +3
-1@@ -156,6 +156,7 @@ struct dw_mci {u32 fifoth_val;u16 verid;u16 data_offset; +bool use_hold_reg;struct device dev;struct dw_mci_board *pdata;struct dw_mci_slot *slot[MAX_MCI_SLOTS ];@@ -201,6 +202,8 @@ struct dw_mci_dma_ops {#define DW_MCI_QUIRK_HIGHSPEED BIT(2)/* Unreliable card detection */ #define DW_MCI_QUIRK_BROKEN_CARD_DETECTION BIT(3) +/* To use the CLKSEL register for phase-shift */ +#define DW_MCI_QUIRK_USE_CLKSEL_REG BIT(4)struct dma_pdata ; --Quoted 5 lines
1.7.4.1
--
To unsubscribe from this list: send the line "unsubscribe linux-mmc" in the body of a message to [email protected]
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 [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html