/* * The higher 16-bit of this register is used for write protection * only if BIT(x + 16) set to 1 the BIT(x) can be written.
*/ #define HIWORD_UPDATE(val, mask, shift) \
((val) << (shift) | (mask) << ((shift) + 16))
/* * In order for tuning delays to be accurate we need to be * pretty spot on for the DLL range, so warn if we're too * far off. Also warn if we're above the 200 MHz max. Don't * warn for really slow rates since we won't be tuning then.
*/ if ((rate > 50000000 && diff > 15000000) || (rate > 200000000))
dev_warn(&phy->dev, "Unsupported rate: %lu\n", rate);
}
/* * According to the user manual, calpad calibration * cycle takes more than 2us without the minimal recommended * value, so we may need a little margin here
*/
udelay(3);
regmap_write(rk_phy->reg_base,
rk_phy->reg_offset + GRF_EMMCPHY_CON6,
HIWORD_UPDATE(PHYCTRL_PDB_PWR_ON,
PHYCTRL_PDB_MASK,
PHYCTRL_PDB_SHIFT));
/* * According to the user manual, it asks driver to wait 5us for * calpad busy trimming. However it is documented that this value is * PVT(A.K.A process,voltage and temperature) relevant, so some * failure cases are found which indicates we should be more tolerant * to calpad busy trimming.
*/
ret = regmap_read_poll_timeout(rk_phy->reg_base,
rk_phy->reg_offset + GRF_EMMCPHY_STATUS,
caldone, PHYCTRL_IS_CALDONE(caldone),
0, 50); if (ret) {
pr_err("%s: caldone failed, ret=%d\n", __func__, ret); return ret;
}
/* Set the frequency of the DLL operation */
regmap_write(rk_phy->reg_base,
rk_phy->reg_offset + GRF_EMMCPHY_CON0,
HIWORD_UPDATE(freqsel, PHYCTRL_FREQSEL_MASK,
PHYCTRL_FREQSEL_SHIFT));
/* Turn on the DLL */
regmap_write(rk_phy->reg_base,
rk_phy->reg_offset + GRF_EMMCPHY_CON6,
HIWORD_UPDATE(PHYCTRL_ENDLL_ENABLE,
PHYCTRL_ENDLL_MASK,
PHYCTRL_ENDLL_SHIFT));
/* * We turned on the DLL even though the rate was 0 because we the * clock might be turned on later. ...but we can't wait for the DLL * to lock when the rate is 0 because it will never lock with no * input clock. * * Technically we should be checking the lock later when the clock * is turned on, but for now we won't.
*/ if (rate == 0) return 0;
/* * After enabling analog DLL circuits docs say that we need 10.2 us if * our source clock is at 50 MHz and that lock time scales linearly * with clock speed. If we are powering on the PHY and the card clock * is super slow (like 100 kHZ) this could take as long as 5.1 ms as * per the math: 10.2 us * (50000000 Hz / 100000 Hz) => 5.1 ms * Hopefully we won't be running at 100 kHz, but we should still make * sure we wait long enough. * * NOTE: There appear to be corner cases where the DLL seems to take * extra long to lock for reasons that aren't understood. In some * extreme cases we've seen it take up to over 10ms (!). We'll be * generous and give it 50ms.
*/
ret = regmap_read_poll_timeout(rk_phy->reg_base,
rk_phy->reg_offset + GRF_EMMCPHY_STATUS,
dllrdy, PHYCTRL_IS_DLLRDY(dllrdy),
0, 50 * USEC_PER_MSEC); if (ret) {
pr_err("%s: dllrdy failed. ret=%d\n", __func__, ret); return ret;
}
return 0;
}
staticint rockchip_emmc_phy_init(struct phy *phy)
{ struct rockchip_emmc_phy *rk_phy = phy_get_drvdata(phy); int ret = 0;
/* * We purposely get the clock here and not in probe to avoid the * circular dependency problem. We expect: * - PHY driver to probe * - SDHCI driver to start probe * - SDHCI driver to register it's clock * - SDHCI driver to get the PHY * - SDHCI driver to init the PHY * * The clock is optional, using clk_get_optional() to get the clock * and do error processing if the return value != NULL * * NOTE: we don't do anything special for EPROBE_DEFER here. Given the * above expected use case, EPROBE_DEFER isn't sensible to expect, so * it's just like any other error.
*/
rk_phy->emmcclk = clk_get_optional(&phy->dev, "emmcclk"); if (IS_ERR(rk_phy->emmcclk)) {
ret = PTR_ERR(rk_phy->emmcclk);
dev_err(&phy->dev, "Error getting emmcclk: %d\n", ret);
rk_phy->emmcclk = NULL;
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.