* [PATCH v2 4/5] mmc: dw-mmc: add the use_hold_reg in CMD register @ 2012-08-28 7:55 Jaehoon Chung 2012-08-28 13:58 ` Thomas Abraham 2012-08-29 1:21 ` Seungwon Jeon 0 siblings, 2 replies; 7+ messages in thread From: Jaehoon Chung @ 2012-08-28 7:55 UTC (permalink / raw) To: linux-mmc Cc: Chris Ball, Kyungmin Park, Will Newton, James Hogan, Thomas Abraham, Seungwon Jeon 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) Now i known that HOLD-register is using only Exynos-SoC. But hold-register is supported basically feature at Synopsys-IP. If Other SoC is used hold regster, we can change the _CLKSEL_REG_. Signed-off-by: Jaehoon Chung <jh80.chung@samsung.com> Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com> --- 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(-) diff --git a/drivers/mmc/host/dw_mmc.c b/drivers/mmc/host/dw_mmc.c index 437fdf8..3642455 100644 --- a/drivers/mmc/host/dw_mmc.c +++ b/drivers/mmc/host/dw_mmc.c @@ -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 regster by default. + * But if mode is SDR50/DDR50/SDR104, + * only use the hold register when cclk_in_drv value is greater than 0. + */ + switch (ios->timing) { + case MMC_TIMING_UHS_SDR50: + case MMC_TIMING_UHS_DDR50: + case MMC_TIMING_UHS_SDR104: + if (host->pdata->get_clk_drv && + 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_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(); @@ -2015,6 +2049,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; diff --git a/drivers/mmc/host/dw_mmc.h b/drivers/mmc/host/dw_mmc.h index b6a1a78..cc905ee 100644 --- a/drivers/mmc/host/dw_mmc.h +++ b/drivers/mmc/host/dw_mmc.h @@ -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) diff --git a/include/linux/mmc/dw_mmc.h b/include/linux/mmc/dw_mmc.h index f20979c..803a80d 100644 --- a/include/linux/mmc/dw_mmc.h +++ b/include/linux/mmc/dw_mmc.h @@ -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 ^ permalink raw reply related [flat|nested] 7+ messages in thread
* Re: [PATCH v2 4/5] mmc: dw-mmc: add the use_hold_reg in CMD register 2012-08-28 7:55 [PATCH v2 4/5] mmc: dw-mmc: add the use_hold_reg in CMD register Jaehoon Chung @ 2012-08-28 13:58 ` Thomas Abraham 2012-08-29 1:47 ` Jaehoon Chung 2012-08-29 1:21 ` Seungwon Jeon 1 sibling, 1 reply; 7+ messages in thread From: Thomas Abraham @ 2012-08-28 13:58 UTC (permalink / raw) To: Jaehoon Chung Cc: linux-mmc, Chris Ball, Kyungmin Park, Will Newton, James Hogan, Seungwon Jeon On 28 August 2012 13:25, Jaehoon Chung <jh80.chung@samsung.com> wrote: > 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) > > Now i known that HOLD-register is using only Exynos-SoC. > But hold-register is supported basically feature at Synopsys-IP. > If Other SoC is used hold regster, we can change the _CLKSEL_REG_. > > Signed-off-by: Jaehoon Chung <jh80.chung@samsung.com> > Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com> > --- > 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(-) > > diff --git a/drivers/mmc/host/dw_mmc.c b/drivers/mmc/host/dw_mmc.c > index 437fdf8..3642455 100644 > --- a/drivers/mmc/host/dw_mmc.c > +++ b/drivers/mmc/host/dw_mmc.c > @@ -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 regster by default. > + * But if mode is SDR50/DDR50/SDR104, > + * only use the hold register when cclk_in_drv value is greater than 0. > + */ > + switch (ios->timing) { > + case MMC_TIMING_UHS_SDR50: > + case MMC_TIMING_UHS_DDR50: > + case MMC_TIMING_UHS_SDR104: > + if (host->pdata->get_clk_drv && > + 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_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(); > > @@ -2015,6 +2049,8 @@ int dw_mci_probe(struct dw_mci *host) > host->data_shift = 2; > } > > + host->use_hold_reg = (mci_readl(host, HCON) >> 22) & 0x1; > + The presence of DW_MCI_QUIRK_USE_CLKSEL_REG quirk should be sufficient condition to know if HOLD_REG bit is supported on not. The setting of host->use_hold_reg as above creates a dependency on the boot loader to setup the controller appropriately. Thanks, Thomas. > /* Reset all blocks */ > if (!mci_wait_reset(&host->dev, host)) > return -ENODEV; > diff --git a/drivers/mmc/host/dw_mmc.h b/drivers/mmc/host/dw_mmc.h > index b6a1a78..cc905ee 100644 > --- a/drivers/mmc/host/dw_mmc.h > +++ b/drivers/mmc/host/dw_mmc.h > @@ -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) > diff --git a/include/linux/mmc/dw_mmc.h b/include/linux/mmc/dw_mmc.h > index f20979c..803a80d 100644 > --- a/include/linux/mmc/dw_mmc.h > +++ b/include/linux/mmc/dw_mmc.h > @@ -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 ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH v2 4/5] mmc: dw-mmc: add the use_hold_reg in CMD register 2012-08-28 13:58 ` Thomas Abraham @ 2012-08-29 1:47 ` Jaehoon Chung 0 siblings, 0 replies; 7+ messages in thread From: Jaehoon Chung @ 2012-08-29 1:47 UTC (permalink / raw) To: Thomas Abraham Cc: Jaehoon Chung, linux-mmc, Chris Ball, Kyungmin Park, Will Newton, James Hogan, Seungwon Jeon On 08/28/2012 10:58 PM, Thomas Abraham wrote: > On 28 August 2012 13:25, Jaehoon Chung <jh80.chung@samsung.com> wrote: >> 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) >> >> Now i known that HOLD-register is using only Exynos-SoC. >> But hold-register is supported basically feature at Synopsys-IP. >> If Other SoC is used hold regster, we can change the _CLKSEL_REG_. >> >> Signed-off-by: Jaehoon Chung <jh80.chung@samsung.com> >> Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com> >> --- >> 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(-) >> >> diff --git a/drivers/mmc/host/dw_mmc.c b/drivers/mmc/host/dw_mmc.c >> index 437fdf8..3642455 100644 >> --- a/drivers/mmc/host/dw_mmc.c >> +++ b/drivers/mmc/host/dw_mmc.c >> @@ -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 regster by default. >> + * But if mode is SDR50/DDR50/SDR104, >> + * only use the hold register when cclk_in_drv value is greater than 0. >> + */ >> + switch (ios->timing) { >> + case MMC_TIMING_UHS_SDR50: >> + case MMC_TIMING_UHS_DDR50: >> + case MMC_TIMING_UHS_SDR104: >> + if (host->pdata->get_clk_drv && >> + 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_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(); >> >> @@ -2015,6 +2049,8 @@ int dw_mci_probe(struct dw_mci *host) >> host->data_shift = 2; >> } >> >> + host->use_hold_reg = (mci_readl(host, HCON) >> 22) & 0x1; >> + > > The presence of DW_MCI_QUIRK_USE_CLKSEL_REG quirk should be sufficient > condition to know if HOLD_REG bit is supported on not. The setting of > host->use_hold_reg as above creates a dependency on the boot loader to > setup the controller appropriately. Dependency on the bootloader? I known that HCON's type is read only. It didn't have any dependency with bootloader. > > Thanks, > Thomas. > > >> /* Reset all blocks */ >> if (!mci_wait_reset(&host->dev, host)) >> return -ENODEV; >> diff --git a/drivers/mmc/host/dw_mmc.h b/drivers/mmc/host/dw_mmc.h >> index b6a1a78..cc905ee 100644 >> --- a/drivers/mmc/host/dw_mmc.h >> +++ b/drivers/mmc/host/dw_mmc.h >> @@ -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) >> diff --git a/include/linux/mmc/dw_mmc.h b/include/linux/mmc/dw_mmc.h >> index f20979c..803a80d 100644 >> --- a/include/linux/mmc/dw_mmc.h >> +++ b/include/linux/mmc/dw_mmc.h >> @@ -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 majordomo@vger.kernel.org > More majordomo info at http://vger.kernel.org/majordomo-info.html > ^ permalink raw reply [flat|nested] 7+ messages in thread
* RE: [PATCH v2 4/5] mmc: dw-mmc: add the use_hold_reg in CMD register 2012-08-28 7:55 [PATCH v2 4/5] mmc: dw-mmc: add the use_hold_reg in CMD register Jaehoon Chung 2012-08-28 13:58 ` Thomas Abraham @ 2012-08-29 1:21 ` Seungwon Jeon 2012-08-29 2:09 ` Jaehoon Chung 1 sibling, 1 reply; 7+ messages in thread From: Seungwon Jeon @ 2012-08-29 1:21 UTC (permalink / raw) To: 'Jaehoon Chung', 'linux-mmc' Cc: 'Chris Ball', 'Kyungmin Park', 'Will Newton', 'James Hogan', 'Thomas Abraham' On Tuesday, August 28, 2012, Jaehoon Chung <jh80.chung@samsung.com> wrote: > 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) > > Now i known that HOLD-register is using only Exynos-SoC. > But hold-register is supported basically feature at Synopsys-IP. > If Other SoC is used hold regster, we can change the _CLKSEL_REG_. > > Signed-off-by: Jaehoon Chung <jh80.chung@samsung.com> > Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com> > --- > 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(-) > > diff --git a/drivers/mmc/host/dw_mmc.c b/drivers/mmc/host/dw_mmc.c > index 437fdf8..3642455 100644 > --- a/drivers/mmc/host/dw_mmc.c > +++ b/drivers/mmc/host/dw_mmc.c > @@ -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) { What is this quirk for? Could you explain? > + /* > + * If use HOLD register and SDR12/SDSR25, > + * CMD and DATA sent to card through HOLD regster by default. > + * But if mode is SDR50/DDR50/SDR104, > + * only use the hold register when cclk_in_drv value is greater than 0. > + */ > + switch (ios->timing) { > + case MMC_TIMING_UHS_SDR50: > + case MMC_TIMING_UHS_DDR50: > + case MMC_TIMING_UHS_SDR104: > + if (host->pdata->get_clk_drv && > + 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_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; > + } > + } > + Considering MMC_TIMING_MMC_HS, MMC_TIMING_SD_HS is omitted. Didn't you consider moving this whole routine to dw_mci_set_ios? When deciding the timing, once seems to be enough. Thanks, Seungwon Jeon > mci_writel(host, CMDARG, cmd->arg); > wmb(); > > @@ -2015,6 +2049,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; > diff --git a/drivers/mmc/host/dw_mmc.h b/drivers/mmc/host/dw_mmc.h > index b6a1a78..cc905ee 100644 > --- a/drivers/mmc/host/dw_mmc.h > +++ b/drivers/mmc/host/dw_mmc.h > @@ -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) > diff --git a/include/linux/mmc/dw_mmc.h b/include/linux/mmc/dw_mmc.h > index f20979c..803a80d 100644 > --- a/include/linux/mmc/dw_mmc.h > +++ b/include/linux/mmc/dw_mmc.h > @@ -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 ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH v2 4/5] mmc: dw-mmc: add the use_hold_reg in CMD register 2012-08-29 1:21 ` Seungwon Jeon @ 2012-08-29 2:09 ` Jaehoon Chung 2012-08-30 1:36 ` Seungwon Jeon 0 siblings, 1 reply; 7+ messages in thread From: Jaehoon Chung @ 2012-08-29 2:09 UTC (permalink / raw) To: Seungwon Jeon Cc: 'Jaehoon Chung', 'linux-mmc', 'Chris Ball', 'Kyungmin Park', 'Will Newton', 'James Hogan', 'Thomas Abraham' On 08/29/2012 10:21 AM, Seungwon Jeon wrote: > On Tuesday, August 28, 2012, Jaehoon Chung <jh80.chung@samsung.com> wrote: >> 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) >> >> Now i known that HOLD-register is using only Exynos-SoC. >> But hold-register is supported basically feature at Synopsys-IP. >> If Other SoC is used hold regster, we can change the _CLKSEL_REG_. >> >> Signed-off-by: Jaehoon Chung <jh80.chung@samsung.com> >> Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com> >> --- >> 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(-) >> >> diff --git a/drivers/mmc/host/dw_mmc.c b/drivers/mmc/host/dw_mmc.c >> index 437fdf8..3642455 100644 >> --- a/drivers/mmc/host/dw_mmc.c >> +++ b/drivers/mmc/host/dw_mmc.c >> @@ -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) { > What is this quirk for? CLKSEL register is only used at the Exynos-SoC. I didn't know which SoC is used. I added the quirks for Exynos using the CLKSEL register. > Could you explain? > >> + /* >> + * If use HOLD register and SDR12/SDSR25, >> + * CMD and DATA sent to card through HOLD regster by default. >> + * But if mode is SDR50/DDR50/SDR104, >> + * only use the hold register when cclk_in_drv value is greater than 0. >> + */ >> + switch (ios->timing) { >> + case MMC_TIMING_UHS_SDR50: >> + case MMC_TIMING_UHS_DDR50: >> + case MMC_TIMING_UHS_SDR104: >> + if (host->pdata->get_clk_drv && >> + 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_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; >> + } >> + } >> + > Considering MMC_TIMING_MMC_HS, MMC_TIMING_SD_HS is omitted. Sorry, i will fix. > Didn't you consider moving this whole routine to dw_mci_set_ios? > When deciding the timing, once seems to be enough. Well, i considered that move the code into dw_mci_set_ios(). But cmd_flags is set before sending the command at every time. Finally, hold_regs bit must be also set at every time. We can prevent to set the cmd_flags at every time. Best Regards, Jaehoon Chung > > Thanks, > Seungwon Jeon > >> mci_writel(host, CMDARG, cmd->arg); >> wmb(); >> >> @@ -2015,6 +2049,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; >> diff --git a/drivers/mmc/host/dw_mmc.h b/drivers/mmc/host/dw_mmc.h >> index b6a1a78..cc905ee 100644 >> --- a/drivers/mmc/host/dw_mmc.h >> +++ b/drivers/mmc/host/dw_mmc.h >> @@ -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) >> diff --git a/include/linux/mmc/dw_mmc.h b/include/linux/mmc/dw_mmc.h >> index f20979c..803a80d 100644 >> --- a/include/linux/mmc/dw_mmc.h >> +++ b/include/linux/mmc/dw_mmc.h >> @@ -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 majordomo@vger.kernel.org > More majordomo info at http://vger.kernel.org/majordomo-info.html > ^ permalink raw reply [flat|nested] 7+ messages in thread
* RE: [PATCH v2 4/5] mmc: dw-mmc: add the use_hold_reg in CMD register 2012-08-29 2:09 ` Jaehoon Chung @ 2012-08-30 1:36 ` Seungwon Jeon 2012-08-30 1:58 ` Jaehoon Chung 0 siblings, 1 reply; 7+ messages in thread From: Seungwon Jeon @ 2012-08-30 1:36 UTC (permalink / raw) To: 'Jaehoon Chung' Cc: 'linux-mmc', 'Chris Ball', 'Kyungmin Park', 'Will Newton', 'James Hogan', 'Thomas Abraham' On Tuesday, August 29, 2012, Jaehoon Chung <jh80.chung@samsung.com> wrote: > On 08/29/2012 10:21 AM, Seungwon Jeon wrote: > > On Tuesday, August 28, 2012, Jaehoon Chung <jh80.chung@samsung.com> wrote: > >> 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) > >> > >> Now i known that HOLD-register is using only Exynos-SoC. > >> But hold-register is supported basically feature at Synopsys-IP. > >> If Other SoC is used hold regster, we can change the _CLKSEL_REG_. > >> > >> Signed-off-by: Jaehoon Chung <jh80.chung@samsung.com> > >> Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com> > >> --- > >> 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(-) > >> > >> diff --git a/drivers/mmc/host/dw_mmc.c b/drivers/mmc/host/dw_mmc.c > >> index 437fdf8..3642455 100644 > >> --- a/drivers/mmc/host/dw_mmc.c > >> +++ b/drivers/mmc/host/dw_mmc.c > >> @@ -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) { > > What is this quirk for? > CLKSEL register is only used at the Exynos-SoC. > I didn't know which SoC is used. I added the quirks for Exynos using the CLKSEL register. You wrapped the access to the CLKSEL register by callback function? CLKSEL is just implementation for Synopsys's phase-shift technique in Exynos We don't need to consider this register. Perhaps, below conditions for hold_reg are only for Exynos? Which manual did you refer to? > > Could you explain? > > > >> + /* > >> + * If use HOLD register and SDR12/SDSR25, > >> + * CMD and DATA sent to card through HOLD regster by default. > >> + * But if mode is SDR50/DDR50/SDR104, > >> + * only use the hold register when cclk_in_drv value is greater than 0. > >> + */ > >> + switch (ios->timing) { > >> + case MMC_TIMING_UHS_SDR50: > >> + case MMC_TIMING_UHS_DDR50: > >> + case MMC_TIMING_UHS_SDR104: > >> + if (host->pdata->get_clk_drv && > >> + 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_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; > >> + } > >> + } > >> + > > Considering MMC_TIMING_MMC_HS, MMC_TIMING_SD_HS is omitted. > Sorry, i will fix. > > Didn't you consider moving this whole routine to dw_mci_set_ios? > > When deciding the timing, once seems to be enough. > Well, i considered that move the code into dw_mci_set_ios(). > But cmd_flags is set before sending the command at every time. > Finally, hold_regs bit must be also set at every time. > We can prevent to set the cmd_flags at every time. Yes, use_hold_regs shoud be set to CMD, whenever sending command. But cmd_flags for use_hold_reg can be set a time. Thanks, Seungwon Jeon > > Best Regards, > Jaehoon Chung > > > > Thanks, > > Seungwon Jeon > > > >> mci_writel(host, CMDARG, cmd->arg); > >> wmb(); > >> > >> @@ -2015,6 +2049,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; > >> diff --git a/drivers/mmc/host/dw_mmc.h b/drivers/mmc/host/dw_mmc.h > >> index b6a1a78..cc905ee 100644 > >> --- a/drivers/mmc/host/dw_mmc.h > >> +++ b/drivers/mmc/host/dw_mmc.h > >> @@ -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) > >> diff --git a/include/linux/mmc/dw_mmc.h b/include/linux/mmc/dw_mmc.h > >> index f20979c..803a80d 100644 > >> --- a/include/linux/mmc/dw_mmc.h > >> +++ b/include/linux/mmc/dw_mmc.h > >> @@ -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 majordomo@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 majordomo@vger.kernel.org > More majordomo info at http://vger.kernel.org/majordomo-info.html ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH v2 4/5] mmc: dw-mmc: add the use_hold_reg in CMD register 2012-08-30 1:36 ` Seungwon Jeon @ 2012-08-30 1:58 ` Jaehoon Chung 0 siblings, 0 replies; 7+ messages in thread From: Jaehoon Chung @ 2012-08-30 1:58 UTC (permalink / raw) To: Seungwon Jeon Cc: 'linux-mmc', 'Chris Ball', 'Kyungmin Park', 'Will Newton', 'James Hogan', 'Thomas Abraham' On 08/30/2012 10:36 AM, Seungwon Jeon wrote: > On Tuesday, August 29, 2012, Jaehoon Chung <jh80.chung@samsung.com> wrote: >> On 08/29/2012 10:21 AM, Seungwon Jeon wrote: >>> On Tuesday, August 28, 2012, Jaehoon Chung <jh80.chung@samsung.com> wrote: >>>> 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) >>>> >>>> Now i known that HOLD-register is using only Exynos-SoC. >>>> But hold-register is supported basically feature at Synopsys-IP. >>>> If Other SoC is used hold regster, we can change the _CLKSEL_REG_. >>>> >>>> Signed-off-by: Jaehoon Chung <jh80.chung@samsung.com> >>>> Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com> >>>> --- >>>> 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(-) >>>> >>>> diff --git a/drivers/mmc/host/dw_mmc.c b/drivers/mmc/host/dw_mmc.c >>>> index 437fdf8..3642455 100644 >>>> --- a/drivers/mmc/host/dw_mmc.c >>>> +++ b/drivers/mmc/host/dw_mmc.c >>>> @@ -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) { >>> What is this quirk for? >> CLKSEL register is only used at the Exynos-SoC. >> I didn't know which SoC is used. I added the quirks for Exynos using the CLKSEL register. The quirks could be removed. > You wrapped the access to the CLKSEL register by callback function? > CLKSEL is just implementation for Synopsys's phase-shift technique in Exynos Right, CLKSEL register is used at EXYNOS. But it could be presented other clock-phase method at other-SoC > We don't need to consider this register. > Perhaps, below conditions for hold_reg are only for Exynos? No, that's generic condition that synopsys manual is mentioned. > Which manual did you refer to? i refer to dwc_mobile_storage(version 2.50a). Best regards, Jaehoon Chung > >>> Could you explain? >>> >>>> + /* >>>> + * If use HOLD register and SDR12/SDSR25, >>>> + * CMD and DATA sent to card through HOLD regster by default. >>>> + * But if mode is SDR50/DDR50/SDR104, >>>> + * only use the hold register when cclk_in_drv value is greater than 0. >>>> + */ >>>> + switch (ios->timing) { >>>> + case MMC_TIMING_UHS_SDR50: >>>> + case MMC_TIMING_UHS_DDR50: >>>> + case MMC_TIMING_UHS_SDR104: >>>> + if (host->pdata->get_clk_drv && >>>> + 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_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; >>>> + } >>>> + } >>>> + >>> Considering MMC_TIMING_MMC_HS, MMC_TIMING_SD_HS is omitted. >> Sorry, i will fix. >>> Didn't you consider moving this whole routine to dw_mci_set_ios? >>> When deciding the timing, once seems to be enough. >> Well, i considered that move the code into dw_mci_set_ios(). >> But cmd_flags is set before sending the command at every time. >> Finally, hold_regs bit must be also set at every time. >> We can prevent to set the cmd_flags at every time. > Yes, use_hold_regs shoud be set to CMD, whenever sending command. > But cmd_flags for use_hold_reg can be set a time. > > Thanks, > Seungwon Jeon > >> >> Best Regards, >> Jaehoon Chung >>> >>> Thanks, >>> Seungwon Jeon >>> >>>> mci_writel(host, CMDARG, cmd->arg); >>>> wmb(); >>>> >>>> @@ -2015,6 +2049,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; >>>> diff --git a/drivers/mmc/host/dw_mmc.h b/drivers/mmc/host/dw_mmc.h >>>> index b6a1a78..cc905ee 100644 >>>> --- a/drivers/mmc/host/dw_mmc.h >>>> +++ b/drivers/mmc/host/dw_mmc.h >>>> @@ -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) >>>> diff --git a/include/linux/mmc/dw_mmc.h b/include/linux/mmc/dw_mmc.h >>>> index f20979c..803a80d 100644 >>>> --- a/include/linux/mmc/dw_mmc.h >>>> +++ b/include/linux/mmc/dw_mmc.h >>>> @@ -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 majordomo@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 majordomo@vger.kernel.org >> More majordomo info at http://vger.kernel.org/majordomo-info.html > > ^ permalink raw reply [flat|nested] 7+ messages in thread
end of thread, other threads:[~2012-08-30 1:58 UTC | newest] Thread overview: 7+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2012-08-28 7:55 [PATCH v2 4/5] mmc: dw-mmc: add the use_hold_reg in CMD register Jaehoon Chung 2012-08-28 13:58 ` Thomas Abraham 2012-08-29 1:47 ` Jaehoon Chung 2012-08-29 1:21 ` Seungwon Jeon 2012-08-29 2:09 ` Jaehoon Chung 2012-08-30 1:36 ` Seungwon Jeon 2012-08-30 1:58 ` Jaehoon Chung
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox