Message ID | 1573115572-13513-16-git-send-email-biju.das@bp.renesas.com (mailing list archive) |
---|---|
State | Accepted |
Headers | show |
Series | Add RZ/G1C SD/eMMC support | expand |
Hi! > From: Wolfram Sang <wsa+renesas@sang-engineering.com> > > commit 148634d24d4a7dc82a49efcf1a215e1d0695f62c upstream. > > Setting frequency to 0 is not enough, the clock explicitly has to be > disabled. Otherwise voltage switching (which needs SDCLK to be quiet) > fails for various cards. > > Because we now do the 'new_clock == 0' check right at the beginning, > the indentation level of the rest of the code can be decreased a > little. > { > u32 clk = 0, clock; > clk = 0 initialization is never used. > + for (clk = 0x80000080; new_clock >= (clock << 1); clk >>= 1) > + clock <<= 1; This is black magic. Where does 0x80000080 come from? Would it be possible to get some comment/explanation? > + /* 1/1 clock is option */ > + if ((host->pdata->flags & TMIO_MMC_CLK_ACTUAL) && ((clk >> 22) & 0x1)) > + clk |= 0xff; > > if (host->set_clk_div) > host->set_clk_div(host->pdev, (clk >> 22) & 1); What does bit 22 in clk mean? Should it go to temporary variable with explanation? (Also it is & 1 in one operation and & 0x1 in other operation). It seems that low bits of clk variable are used as an actual clock divider, with high bit doing something else. That is quite confusing... Best regards, Pavel
Hi Pavel, > > Subject: Re: [PATCH 4.4.y-cip 15/83] mmc: tmio: stop clock when 0Hz is > requested > > Hi! > > > From: Wolfram Sang <wsa+renesas@sang-engineering.com> > > > > commit 148634d24d4a7dc82a49efcf1a215e1d0695f62c upstream. > > > > Setting frequency to 0 is not enough, the clock explicitly has to be > > disabled. Otherwise voltage switching (which needs SDCLK to be quiet) > > fails for various cards. > > > > Because we now do the 'new_clock == 0' check right at the beginning, > > the indentation level of the rest of the code can be decreased a > > little. > > > { > > u32 clk = 0, clock; > > > > clk = 0 initialization is never used. > > > + for (clk = 0x80000080; new_clock >= (clock << 1); clk >>= 1) > > + clock <<= 1; > > This is black magic. Where does 0x80000080 come from? Would it be possible > to get some comment/explanation? > > > + /* 1/1 clock is option */ > > + if ((host->pdata->flags & TMIO_MMC_CLK_ACTUAL) && ((clk >> 22) > & 0x1)) > > + clk |= 0xff; > > > > if (host->set_clk_div) > > host->set_clk_div(host->pdev, (clk >> 22) & 1); > > What does bit 22 in clk mean? Should it go to temporary variable with > explanation? (Also it is & 1 in one operation and & 0x1 in other operation). > > It seems that low bits of clk variable are used as an actual clock divider, with > high bit doing something else. That is quite confusing... Yes I agree this could have been done with Macro. Not sure, may be because of HALA [SD Host/Ancillary Product License Agreement], it is defined as magic number at that time. Regards, Biju
diff --git a/drivers/mmc/host/tmio_mmc_pio.c b/drivers/mmc/host/tmio_mmc_pio.c index 99139b8..6c09b1d 100644 --- a/drivers/mmc/host/tmio_mmc_pio.c +++ b/drivers/mmc/host/tmio_mmc_pio.c @@ -166,25 +166,39 @@ static void tmio_mmc_clk_start(struct tmio_mmc_host *host) } } +static void tmio_mmc_clk_stop(struct tmio_mmc_host *host) +{ + if (host->pdata->flags & TMIO_MMC_HAVE_HIGH_REG) { + sd_ctrl_write16(host, CTL_CLK_AND_WAIT_CTL, 0x0000); + msleep(10); + } + + sd_ctrl_write16(host, CTL_SD_CARD_CLK_CTL, ~CLK_CTL_SCLKEN & + sd_ctrl_read16(host, CTL_SD_CARD_CLK_CTL)); + msleep(host->pdata->flags & TMIO_MMC_FAST_CLK_CHG ? 5 : 10); +} + static void tmio_mmc_set_clock(struct tmio_mmc_host *host, unsigned int new_clock) { u32 clk = 0, clock; - if (new_clock) { - if (host->clk_update) - clock = host->clk_update(host, new_clock) / 512; - else - clock = host->mmc->f_min; + if (new_clock == 0) { + tmio_mmc_clk_stop(host); + return; + } - for (clk = 0x80000080; new_clock >= (clock << 1); clk >>= 1) - clock <<= 1; + if (host->clk_update) + clock = host->clk_update(host, new_clock) / 512; + else + clock = host->mmc->f_min; - /* 1/1 clock is option */ - if ((host->pdata->flags & TMIO_MMC_CLK_ACTUAL) && - ((clk >> 22) & 0x1)) - clk |= 0xff; - } + for (clk = 0x80000080; new_clock >= (clock << 1); clk >>= 1) + clock <<= 1; + + /* 1/1 clock is option */ + if ((host->pdata->flags & TMIO_MMC_CLK_ACTUAL) && ((clk >> 22) & 0x1)) + clk |= 0xff; if (host->set_clk_div) host->set_clk_div(host->pdev, (clk >> 22) & 1); @@ -198,18 +212,6 @@ static void tmio_mmc_set_clock(struct tmio_mmc_host *host, tmio_mmc_clk_start(host); } -static void tmio_mmc_clk_stop(struct tmio_mmc_host *host) -{ - if (host->pdata->flags & TMIO_MMC_HAVE_HIGH_REG) { - sd_ctrl_write16(host, CTL_CLK_AND_WAIT_CTL, 0x0000); - msleep(10); - } - - sd_ctrl_write16(host, CTL_SD_CARD_CLK_CTL, ~CLK_CTL_SCLKEN & - sd_ctrl_read16(host, CTL_SD_CARD_CLK_CTL)); - msleep(host->pdata->flags & TMIO_MMC_FAST_CLK_CHG ? 5 : 10); -} - static void tmio_mmc_reset(struct tmio_mmc_host *host) { /* FIXME - should we set stop clock reg here */