mirror of
https://github.com/Fishwaldo/u-boot.git
synced 2025-06-26 16:41:42 +00:00
Merge branch 'CR_6570_SDBOOT_u-boot_william.qiu' into 'jh7110-master'
CR_6570: mmc: starfive: add HS200 support See merge request sdk/u-boot!62
This commit is contained in:
commit
f1ad44f525
4 changed files with 113 additions and 2 deletions
|
@ -20,6 +20,14 @@ extern "C" {
|
|||
#define GPIO_DOEN_MASK 0x3f
|
||||
#define GPIO_DOUT_MASK 0x7f
|
||||
#define GPIO_DIN_MASK 0x7f
|
||||
#define GPIO_DS_MASK 0x06
|
||||
#define GPIO_DS_SHIFT 1
|
||||
#define GPIO_SLEW_MASK BIT(5)
|
||||
#define GPIO_SLEW_SHIFT 5
|
||||
#define GPIO_PULL_MASK 0x18
|
||||
#define GPIO_PULL_SHIFT 3
|
||||
#define GPIO_PULL_UP 1
|
||||
#define GPIO_PULL_DOWN 2
|
||||
|
||||
#define NR_GPIOS 64
|
||||
|
||||
|
@ -38,8 +46,10 @@ enum gpio_state {
|
|||
#define GPIO_DOUT 0x40
|
||||
#define GPIO_DIN 0x80
|
||||
#define GPIO_EN 0xdc
|
||||
#define GPIO_LOW_IE 0x100
|
||||
#define GPIO_LOW_IE 0x100
|
||||
#define GPIO_HIGH_IE 0x104
|
||||
#define GPIO_CONFIG 0x120
|
||||
|
||||
|
||||
/* Details about a GPIO bank */
|
||||
struct starfive_gpio_platdata {
|
||||
|
@ -61,6 +71,18 @@ struct starfive_gpio_platdata {
|
|||
GPIO_DIN_MASK << GPIO_SHIFT(gpi),\
|
||||
((gpio+2) & GPIO_DIN_MASK) << GPIO_SHIFT(gpi))
|
||||
|
||||
#define SYS_IOMUX_SET_DS(gpio, ds) \
|
||||
clrsetbits_le32(SYS_IOMUX_BASE + GPIO_CONFIG + gpio * 4, \
|
||||
GPIO_DS_MASK, (ds) << GPIO_DS_SHIFT)
|
||||
|
||||
#define SYS_IOMUX_SET_SLEW(gpio, slew) \
|
||||
clrsetbits_le32(SYS_IOMUX_BASE + GPIO_CONFIG + gpio * 4, \
|
||||
GPIO_SLEW_MASK, (slew) << GPIO_SLEW_SHIFT)
|
||||
|
||||
#define SYS_IOMUX_SET_PULL(gpio, pull) \
|
||||
clrsetbits_le32(SYS_IOMUX_BASE + GPIO_CONFIG + gpio * 4, \
|
||||
GPIO_PULL_MASK, (pull) << GPIO_PULL_SHIFT)
|
||||
|
||||
#define SYS_IOMUX_COMPLEX(gpio, gpi, gpo, oen) do {\
|
||||
SYS_IOMUX_DOEN(gpio, oen);\
|
||||
SYS_IOMUX_DOUT(gpio, gpo);\
|
||||
|
|
|
@ -72,6 +72,8 @@ CONFIG_CLK_CCF=y
|
|||
CONFIG_CLK_COMPOSITE_CCF=y
|
||||
CONFIG_SPL_CLK_JH7110=y
|
||||
CONFIG_SYS_I2C_DW=y
|
||||
CONFIG_MMC_HS200_SUPPORT=y
|
||||
CONFIG_SPL_MMC_HS200_SUPPORT=y
|
||||
CONFIG_MMC_DW=y
|
||||
CONFIG_MMC_DW_SNPS=y
|
||||
CONFIG_SF_DEFAULT_MODE=0x0
|
||||
|
|
|
@ -21,6 +21,19 @@
|
|||
|
||||
#define PAGE_SIZE 4096
|
||||
|
||||
static inline int __test_and_clear_bit_1(int nr, void *addr)
|
||||
{
|
||||
int mask, retval;
|
||||
unsigned int *a = (unsigned int *)addr;
|
||||
|
||||
a += nr >> 5;
|
||||
mask = 1 << (nr & 0x1f);
|
||||
retval = (mask & *a) != 0;
|
||||
*a &= ~mask;
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
static int dwmci_wait_reset(struct dwmci_host *host, u32 value)
|
||||
{
|
||||
unsigned long timeout = 1000;
|
||||
|
@ -317,6 +330,9 @@ static int dwmci_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd,
|
|||
if (cmd->resp_type & MMC_RSP_CRC)
|
||||
flags |= DWMCI_CMD_CHECK_CRC;
|
||||
|
||||
if (__test_and_clear_bit_1(DW_MMC_CARD_NEED_INIT, &host->flags))
|
||||
flags |= DWMCI_CMD_SEND_INIT;
|
||||
|
||||
flags |= (cmd->cmdidx | DWMCI_CMD_START | DWMCI_CMD_USE_HOLD_REG);
|
||||
|
||||
debug("Sending CMD%d\n",cmd->cmdidx);
|
||||
|
@ -522,6 +538,64 @@ static int dwmci_set_ios(struct mmc *mmc)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static void dw_mci_hs_set_bits(struct dwmci_host *host, u32 smpl_phase)
|
||||
{
|
||||
/* change driver phase and sample phase */
|
||||
u32 mask = 0x1f;
|
||||
u32 reg_value;
|
||||
|
||||
reg_value = dwmci_readl(host, DWMCI_UHS_REG_EXT);
|
||||
|
||||
/* In UHS_REG_EXT, only 5 bits valid in DRV_PHASE and SMPL_PHASE */
|
||||
reg_value &= ~(mask << 16);
|
||||
reg_value |= (smpl_phase << 16);
|
||||
dwmci_writel(host, DWMCI_UHS_REG_EXT, reg_value);
|
||||
|
||||
/* We should delay 1ms wait for timing setting finished. */
|
||||
udelay(1000);
|
||||
}
|
||||
|
||||
static int dwmci_execute_tuning(struct udevice *dev, uint opcode)
|
||||
{
|
||||
struct mmc *mmc = mmc_get_mmc_dev(dev);
|
||||
struct dwmci_host *host = mmc->priv;
|
||||
int err = -1;
|
||||
int smpl_phase, smpl_raise = -1, smpl_fall = -1;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < 32; ++i) {
|
||||
smpl_phase = i;
|
||||
dw_mci_hs_set_bits(host, smpl_phase);
|
||||
dwmci_writel(host, DWMCI_RINTSTS, DWMCI_INTMSK_ALL);
|
||||
|
||||
err = mmc_send_tuning(mmc, opcode, NULL);
|
||||
|
||||
if (!err && smpl_raise < 0) {
|
||||
smpl_raise = i;
|
||||
} else if (err && smpl_raise >= 0) {
|
||||
smpl_fall = i - 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (i >= 32 && smpl_raise >= 0)
|
||||
smpl_fall = 31;
|
||||
|
||||
if (smpl_raise < 0) {
|
||||
pr_err("No valid delay chain! use default\n");
|
||||
dw_mci_hs_set_bits(host, 0);
|
||||
err = -EINVAL;
|
||||
} else {
|
||||
smpl_phase = (smpl_raise + smpl_fall) / 2;
|
||||
dw_mci_hs_set_bits(host, smpl_phase);
|
||||
pr_debug("Found valid delay chain! use it [delay=%d]\n", smpl_phase);
|
||||
err = 0;
|
||||
}
|
||||
|
||||
dwmci_writel(host, DWMCI_RINTSTS, DWMCI_INTMSK_ALL);
|
||||
return err;
|
||||
}
|
||||
|
||||
static int dwmci_init(struct mmc *mmc)
|
||||
{
|
||||
struct dwmci_host *host = mmc->priv;
|
||||
|
@ -536,6 +610,8 @@ static int dwmci_init(struct mmc *mmc)
|
|||
return -EIO;
|
||||
}
|
||||
|
||||
host->flags = 1 << DW_MMC_CARD_NEED_INIT;
|
||||
|
||||
/* Enumerate at 400KHz */
|
||||
dwmci_setup_bus(host, mmc->cfg->f_min);
|
||||
|
||||
|
@ -577,6 +653,7 @@ int dwmci_probe(struct udevice *dev)
|
|||
const struct dm_mmc_ops dm_dwmci_ops = {
|
||||
.send_cmd = dwmci_send_cmd,
|
||||
.set_ios = dwmci_set_ios,
|
||||
.execute_tuning = dwmci_execute_tuning,
|
||||
};
|
||||
|
||||
#else
|
||||
|
@ -608,7 +685,7 @@ void dwmci_setup_cfg(struct mmc_config *cfg, struct dwmci_host *host,
|
|||
cfg->host_caps |= MMC_MODE_4BIT;
|
||||
cfg->host_caps &= ~MMC_MODE_8BIT;
|
||||
}
|
||||
cfg->host_caps |= MMC_MODE_HS | MMC_MODE_HS_52MHz;
|
||||
cfg->host_caps |= MMC_MODE_HS_52MHz | MMC_MODE_HS200;
|
||||
|
||||
cfg->b_max = CONFIG_SYS_MMC_MAX_BLK_COUNT;
|
||||
}
|
||||
|
|
|
@ -49,6 +49,7 @@
|
|||
#define DWMCI_IDINTEN 0x090
|
||||
#define DWMCI_DSCADDR 0x094
|
||||
#define DWMCI_BUFADDR 0x098
|
||||
#define DWMCI_UHS_REG_EXT 0x108
|
||||
#define DWMCI_DATA 0x200
|
||||
|
||||
/* Interrupt Mask register */
|
||||
|
@ -91,6 +92,7 @@
|
|||
#define DWMCI_CMD_RW (1 << 10)
|
||||
#define DWMCI_CMD_SEND_STOP (1 << 12)
|
||||
#define DWMCI_CMD_ABORT_STOP (1 << 14)
|
||||
#define DWMCI_CMD_SEND_INIT (1 << 15)
|
||||
#define DWMCI_CMD_PRV_DAT_WAIT (1 << 13)
|
||||
#define DWMCI_CMD_UPD_CLK (1 << 21)
|
||||
#define DWMCI_CMD_USE_HOLD_REG (1 << 29)
|
||||
|
@ -197,6 +199,14 @@ struct dwmci_host {
|
|||
|
||||
/* use fifo mode to read and write data */
|
||||
bool fifo_mode;
|
||||
|
||||
/* Starfive: porting from kernel 5.15, fix mmc device power-up sequence */
|
||||
unsigned int flags;
|
||||
#define DW_MMC_CARD_PRESENT 0
|
||||
#define DW_MMC_CARD_NEED_INIT 1
|
||||
#define DW_MMC_CARD_NO_LOW_PWR 2
|
||||
#define DW_MMC_CARD_NO_USE_HOLD 3
|
||||
#define DW_MMC_CARD_NEEDS_POLL 4
|
||||
};
|
||||
|
||||
struct dwmci_idmac {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue