Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit b6e67145 authored by Weifeng Voon's avatar Weifeng Voon Committed by Wolfram Sang
Browse files

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: default avatarWeifeng Voon <weifeng.voon@intel.com>
Signed-off-by: default avatarJarkko Nikula <jarkko.nikula@linux.intel.com>
Reviewed-by: default avatarAndy Shevchenko <andriy.shevchenko@linux.intel.com>
Signed-off-by: default avatarWolfram Sang <wsa@the-dreams.de>
parent 548e6695
Loading
Loading
Loading
Loading
+25 −1
Original line number Diff line number Diff line
@@ -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);
+1 −0
Original line number Diff line number Diff line
@@ -26,6 +26,7 @@
#define DW_IC_CON_MASTER		0x1
#define DW_IC_CON_SPEED_STD		0x2
#define DW_IC_CON_SPEED_FAST		0x4
#define DW_IC_CON_SPEED_HIGH		0x6
#define DW_IC_CON_SPEED_MASK		0x6
#define DW_IC_CON_10BITADDR_MASTER	0x10
#define DW_IC_CON_RESTART_EN		0x20
+11 −5
Original line number Diff line number Diff line
@@ -197,12 +197,12 @@ static int dw_i2c_plat_probe(struct platform_device *pdev)

	/*
	 * Only standard mode at 100kHz, fast mode at 400kHz,
	 * and fast mode plus at 1MHz are supported.
	 * fast mode plus at 1MHz and high speed mode at 3.4MHz are supported.
	 */
	if (dev->clk_freq != 100000 && dev->clk_freq != 400000
	    && dev->clk_freq != 1000000) {
	    && dev->clk_freq != 1000000 && dev->clk_freq != 3400000) {
		dev_err(&pdev->dev,
			"Only 100kHz, 400kHz and 1MHz are supported");
			"Only 100kHz, 400kHz, 1MHz and 3.4MHz supported");
		return -EINVAL;
	}

@@ -221,10 +221,16 @@ static int dw_i2c_plat_probe(struct platform_device *pdev)
	dev->master_cfg = DW_IC_CON_MASTER | DW_IC_CON_SLAVE_DISABLE |
			  DW_IC_CON_RESTART_EN;

	if (dev->clk_freq == 100000)
	switch (dev->clk_freq) {
	case 100000:
		dev->master_cfg |= DW_IC_CON_SPEED_STD;
	else
		break;
	case 3400000:
		dev->master_cfg |= DW_IC_CON_SPEED_HIGH;
		break;
	default:
		dev->master_cfg |= DW_IC_CON_SPEED_FAST;
	}

	dev->clk = devm_clk_get(&pdev->dev, NULL);
	if (!i2c_dw_plat_prepare_clk(dev, true)) {