/* * Controller has no specific bits for HS200/HS. * Used BIT(4), BIT(5) for software programming.
*/ #define HS200_MODE BIT(4) #define HISPD_MODE BIT(5)
while (1) {
failed = ktime_after(ktime_get(), timeout);
ret = arasan_phy_read(host, offset, &val); if (ret) return -EBUSY; elseif (val & mask) return 0; if (failed) return -EBUSY;
}
}
/* Initialize the Arasan PHY */ staticint arasan_phy_init(struct sdhci_host *host)
{ int ret;
u8 val;
/* Program IOPADs and wait for calibration to be done */ if (arasan_phy_read(host, IPAD_CTRL1, &val) ||
arasan_phy_write(host, val | RETB_ENBL | PDB_ENBL, IPAD_CTRL1) ||
arasan_phy_read(host, IPAD_CTRL2, &val) ||
arasan_phy_write(host, val | RTRIM_EN, IPAD_CTRL2)) return -EBUSY;
ret = arasan_phy_sts_poll(host, IPAD_STS, CALDONE_MASK); if (ret) return -EBUSY;
/* Program CMD/Data lines */ if (arasan_phy_read(host, IOREN_CTRL1, &val) ||
arasan_phy_write(host, val | REN_CMND | REN_STRB, IOREN_CTRL1) ||
arasan_phy_read(host, IOPU_CTRL1, &val) ||
arasan_phy_write(host, val | PU_CMD, IOPU_CTRL1) ||
arasan_phy_read(host, CMD_CTRL, &val) ||
arasan_phy_write(host, val | PDB_CMND, CMD_CTRL) ||
arasan_phy_read(host, IOREN_CTRL2, &val) ||
arasan_phy_write(host, val | REN_DATA, IOREN_CTRL2) ||
arasan_phy_read(host, IOPU_CTRL2, &val) ||
arasan_phy_write(host, val | PU_DAT, IOPU_CTRL2) ||
arasan_phy_read(host, DATA_CTRL, &val) ||
arasan_phy_write(host, val | PDB_DATA, DATA_CTRL) ||
arasan_phy_read(host, STRB_CTRL, &val) ||
arasan_phy_write(host, val | PDB_STRB, STRB_CTRL) ||
arasan_phy_read(host, CLK_CTRL, &val) ||
arasan_phy_write(host, val | PDB_CLOCK, CLK_CTRL) ||
arasan_phy_read(host, CLKBUF_SEL, &val) ||
arasan_phy_write(host, val | MAX_CLK_BUF, CLKBUF_SEL) ||
arasan_phy_write(host, LEGACY_MODE, MODE_CTRL)) return -EBUSY; return 0;
}
/* Set Arasan PHY for different modes */ staticint arasan_phy_set(struct sdhci_host *host, u8 mode, u8 otap,
u8 drv_type, u8 itap, u8 trim, u8 clk)
{
u8 val; int ret;
if (mode == HISPD_MODE || mode == HS200_MODE)
ret = arasan_phy_write(host, 0x0, MODE_CTRL); else
ret = arasan_phy_write(host, mode, MODE_CTRL); if (ret) return ret; if (mode == HS400_MODE || mode == HS200_MODE) {
ret = arasan_phy_read(host, IPAD_CTRL1, &val); if (ret) return ret;
ret = arasan_phy_write(host, IOPAD(val, drv_type), IPAD_CTRL1); if (ret) return ret;
} if (mode == LEGACY_MODE) {
ret = arasan_phy_write(host, 0x0, OTAP_DELAY); if (ret) return ret;
ret = arasan_phy_write(host, 0x0, ITAP_DELAY);
} else {
ret = arasan_phy_write(host, OTAPDLY(otap), OTAP_DELAY); if (ret) return ret; if (mode != HS200_MODE)
ret = arasan_phy_write(host, ITAPDLY(itap), ITAP_DELAY); else
ret = arasan_phy_write(host, 0x0, ITAP_DELAY);
} if (ret) return ret; if (mode != LEGACY_MODE) {
ret = arasan_phy_write(host, trim, DLL_TRIM); if (ret) return ret;
}
ret = arasan_phy_write(host, 0, DLL_STATUS); if (ret) return ret; if (mode != LEGACY_MODE) {
ret = arasan_phy_write(host, FREQSEL(clk), DLL_STATUS); if (ret) return ret;
ret = arasan_phy_sts_poll(host, DLL_STATUS, DLL_RDY_MASK); if (ret) return -EBUSY;
} return 0;
}
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.