diff options
author | Weifeng Voon <weifeng.voon@intel.com> | 2016-08-12 17:02:51 +0300 |
---|---|---|
committer | Wolfram Sang <wsa@the-dreams.de> | 2016-08-26 00:42:07 +0200 |
commit | b6e67145f14903ca430e011db3b771d8de4c3d8a (patch) | |
tree | ad3a693c96e5b48f1449dec578cbf248b36dd1a9 /drivers/i2c/busses/i2c-designware-core.c | |
parent | 548e6695d16d201f390f7554ae7d0b5bb8690166 (diff) | |
download | linux-b6e67145f14903ca430e011db3b771d8de4c3d8a.tar.bz2 |
i2c: designware: Enable high speed mode
This patch enabled high speed mode. High speed mode can be turn on by
setting the clk_freq to 3400000. High speed HCNT and LCNT are needed
as there is no default value provided.
Signed-off-by: Weifeng Voon <weifeng.voon@intel.com>
Signed-off-by: Jarkko Nikula <jarkko.nikula@linux.intel.com>
Reviewed-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Signed-off-by: Wolfram Sang <wsa@the-dreams.de>
Diffstat (limited to 'drivers/i2c/busses/i2c-designware-core.c')
-rw-r--r-- | drivers/i2c/busses/i2c-designware-core.c | 26 |
1 files changed, 25 insertions, 1 deletions
diff --git a/drivers/i2c/busses/i2c-designware-core.c b/drivers/i2c/busses/i2c-designware-core.c index 07edff7a62e3..c5783ed9388d 100644 --- a/drivers/i2c/busses/i2c-designware-core.c +++ b/drivers/i2c/busses/i2c-designware-core.c @@ -42,6 +42,8 @@ #define DW_IC_SS_SCL_LCNT 0x18 #define DW_IC_FS_SCL_HCNT 0x1c #define DW_IC_FS_SCL_LCNT 0x20 +#define DW_IC_HS_SCL_HCNT 0x24 +#define DW_IC_HS_SCL_LCNT 0x28 #define DW_IC_INTR_STAT 0x2c #define DW_IC_INTR_MASK 0x30 #define DW_IC_RAW_INTR_STAT 0x34 @@ -95,6 +97,9 @@ #define DW_IC_TAR_10BITADDR_MASTER BIT(12) +#define DW_IC_COMP_PARAM_1_SPEED_MODE_HIGH (BIT(2) | BIT(3)) +#define DW_IC_COMP_PARAM_1_SPEED_MODE_MASK GENMASK(3, 2) + /* * status codes */ @@ -293,7 +298,7 @@ static unsigned long i2c_dw_clk_rate(struct dw_i2c_dev *dev) int i2c_dw_init(struct dw_i2c_dev *dev) { u32 hcnt, lcnt; - u32 reg; + u32 reg, comp_param1; u32 sda_falling_time, scl_falling_time; int ret; @@ -320,6 +325,8 @@ int i2c_dw_init(struct dw_i2c_dev *dev) return -ENODEV; } + comp_param1 = dw_readl(dev, DW_IC_COMP_PARAM_1); + /* Disable the adapter */ __i2c_dw_enable(dev, false); @@ -369,6 +376,23 @@ int i2c_dw_init(struct dw_i2c_dev *dev) dw_writel(dev, lcnt, DW_IC_FS_SCL_LCNT); dev_dbg(dev->dev, "Fast-mode HCNT:LCNT = %d:%d\n", hcnt, lcnt); + if ((dev->master_cfg & DW_IC_CON_SPEED_MASK) == + DW_IC_CON_SPEED_HIGH) { + if ((comp_param1 & DW_IC_COMP_PARAM_1_SPEED_MODE_MASK) + != DW_IC_COMP_PARAM_1_SPEED_MODE_HIGH) { + dev_err(dev->dev, "High Speed not supported!\n"); + dev->master_cfg &= ~DW_IC_CON_SPEED_MASK; + dev->master_cfg |= DW_IC_CON_SPEED_FAST; + } else if (dev->hs_hcnt && dev->hs_lcnt) { + hcnt = dev->hs_hcnt; + lcnt = dev->hs_lcnt; + dw_writel(dev, hcnt, DW_IC_HS_SCL_HCNT); + dw_writel(dev, lcnt, DW_IC_HS_SCL_LCNT); + dev_dbg(dev->dev, "HighSpeed-mode HCNT:LCNT = %d:%d\n", + hcnt, lcnt); + } + } + /* Configure SDA Hold Time if required */ if (dev->sda_hold_time) { reg = dw_readl(dev, DW_IC_COMP_VERSION); |