mirror of
https://github.com/AsahiLinux/u-boot
synced 2024-11-25 06:00:43 +00:00
i2c: mv_i2c.c: Enable runtime speed selection (standard vs fast mode)
This patch adds runtime speed configuration to the mv_i2c driver. Currently standard (max 100kHz) and fast mode (max 400kHz) are supported. Signed-off-by: Stefan Roese <sr@denx.de> Cc: Nadav Haklai <nadavh@marvell.com> Cc: Kostya Porotchkin <kostap@marvell.com> Cc: Wilson Ding <dingwei@marvell.com> Cc: Victor Gu <xigu@marvell.com> Cc: Hua Jing <jinghua@marvell.com> Cc: Terry Zhou <bjzhou@marvell.com> Cc: Hanna Hawa <hannah@marvell.com> Cc: Haim Boot <hayim@marvell.com> Cc: Heiko Schocher <hs@denx.de>
This commit is contained in:
parent
0c0f719ad2
commit
9ad5a00712
2 changed files with 38 additions and 7 deletions
|
@ -68,6 +68,10 @@ __weak void i2c_clk_enable(void)
|
|||
*/
|
||||
static void i2c_reset(struct mv_i2c *base)
|
||||
{
|
||||
u32 icr_mode;
|
||||
|
||||
/* Save bus mode (standard or fast speed) for later use */
|
||||
icr_mode = readl(&base->icr) & ICR_MODE_MASK;
|
||||
writel(readl(&base->icr) & ~ICR_IUE, &base->icr); /* disable unit */
|
||||
writel(readl(&base->icr) | ICR_UR, &base->icr); /* reset the unit */
|
||||
udelay(100);
|
||||
|
@ -76,7 +80,8 @@ static void i2c_reset(struct mv_i2c *base)
|
|||
i2c_clk_enable();
|
||||
|
||||
writel(CONFIG_SYS_I2C_SLAVE, &base->isar); /* set our slave address */
|
||||
writel(I2C_ICR_INIT, &base->icr); /* set control reg values */
|
||||
/* set control reg values */
|
||||
writel(I2C_ICR_INIT | icr_mode, &base->icr);
|
||||
writel(I2C_ISR_INIT, &base->isr); /* set clear interrupt bits */
|
||||
writel(readl(&base->icr) | ICR_IUE, &base->icr); /* enable unit */
|
||||
udelay(100);
|
||||
|
@ -416,6 +421,8 @@ unsigned int i2c_get_bus_num(void)
|
|||
/* API Functions */
|
||||
void i2c_init(int speed, int slaveaddr)
|
||||
{
|
||||
u32 val;
|
||||
|
||||
#ifdef CONFIG_I2C_MULTI_BUS
|
||||
current_bus = 0;
|
||||
base_glob = (struct mv_i2c *)i2c_regs[current_bus];
|
||||
|
@ -423,6 +430,12 @@ void i2c_init(int speed, int slaveaddr)
|
|||
base_glob = (struct mv_i2c *)CONFIG_MV_I2C_REG;
|
||||
#endif
|
||||
|
||||
if (speed > 100000)
|
||||
val = ICR_FM;
|
||||
else
|
||||
val = ICR_SM;
|
||||
clrsetbits_le32(&base_glob->icr, ICR_MODE_MASK, val);
|
||||
|
||||
i2c_board_init(base_glob);
|
||||
}
|
||||
|
||||
|
@ -543,6 +556,20 @@ static int mv_i2c_xfer(struct udevice *bus, struct i2c_msg *msg, int nmsgs)
|
|||
omsg->len, dmsg->buf, dmsg->len);
|
||||
}
|
||||
|
||||
static int mv_i2c_set_bus_speed(struct udevice *bus, unsigned int speed)
|
||||
{
|
||||
struct mv_i2c_priv *priv = dev_get_priv(bus);
|
||||
u32 val;
|
||||
|
||||
if (speed > 100000)
|
||||
val = ICR_FM;
|
||||
else
|
||||
val = ICR_SM;
|
||||
clrsetbits_le32(&priv->base->icr, ICR_MODE_MASK, val);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int mv_i2c_probe(struct udevice *bus)
|
||||
{
|
||||
struct mv_i2c_priv *priv = dev_get_priv(bus);
|
||||
|
@ -554,6 +581,7 @@ static int mv_i2c_probe(struct udevice *bus)
|
|||
|
||||
static const struct dm_i2c_ops mv_i2c_ops = {
|
||||
.xfer = mv_i2c_xfer,
|
||||
.set_bus_speed = mv_i2c_set_bus_speed,
|
||||
};
|
||||
|
||||
static const struct udevice_id mv_i2c_ids[] = {
|
||||
|
|
|
@ -23,12 +23,7 @@ extern void i2c_clk_enable(void);
|
|||
#define I2C_READ 0
|
||||
#define I2C_WRITE 1
|
||||
|
||||
#if (CONFIG_SYS_I2C_SPEED == 400000)
|
||||
#define I2C_ICR_INIT (ICR_FM | ICR_BEIE | ICR_IRFIE | ICR_ITEIE | ICR_GCD \
|
||||
| ICR_SCLE)
|
||||
#else
|
||||
#define I2C_ICR_INIT (ICR_BEIE | ICR_IRFIE | ICR_ITEIE | ICR_GCD | ICR_SCLE)
|
||||
#endif
|
||||
|
||||
#define I2C_ISR_INIT 0x7FF
|
||||
/* ----- Control register bits ---------------------------------------- */
|
||||
|
@ -48,7 +43,15 @@ extern void i2c_clk_enable(void);
|
|||
#define ICR_ALDIE 0x1000 /* enable arbitration interrupt */
|
||||
#define ICR_SADIE 0x2000 /* slave address detected int enable */
|
||||
#define ICR_UR 0x4000 /* unit reset */
|
||||
#define ICR_FM 0x8000 /* Fast Mode */
|
||||
#ifdef CONFIG_ARMADA_3700
|
||||
#define ICR_SM 0x00000 /* Standard Mode */
|
||||
#define ICR_FM 0x10000 /* Fast Mode */
|
||||
#define ICR_MODE_MASK 0x30000 /* Mode mask */
|
||||
#else
|
||||
#define ICR_SM 0x00000 /* Standard Mode */
|
||||
#define ICR_FM 0x08000 /* Fast Mode */
|
||||
#define ICR_MODE_MASK 0x18000 /* Mode mask */
|
||||
#endif
|
||||
|
||||
/* ----- Status register bits ----------------------------------------- */
|
||||
|
||||
|
|
Loading…
Reference in a new issue