linux-i2c.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v2 1/2] i2c-designware: make HCNT/LCNT values configurable
@ 2013-08-19 12:07 Mika Westerberg
  2013-08-19 12:07 ` [PATCH v2 2/2] i2c-designware: get SDA hold time, HCNT and LCNT configuration from ACPI Mika Westerberg
       [not found] ` <1376914074-31103-1-git-send-email-mika.westerberg-VuQAYsv1563Yd54FQh9/CA@public.gmane.org>
  0 siblings, 2 replies; 5+ messages in thread
From: Mika Westerberg @ 2013-08-19 12:07 UTC (permalink / raw)
  To: linux-kernel-u79uwXL29TY76Z2rM5mHXA
  Cc: Wolfram Sang, Christian Ruppert, Shinya Kuribayashi,
	linux-i2c-u79uwXL29TY76Z2rM5mHXA, Mika Westerberg

The DesignWare I2C controller has high count (HCNT) and low count (LCNT)
registers for each of the I2C speed modes (standard and fast). These
registers are programmed based on the input clock speed in the driver.

The current code calculates these values based on the input clock speed and
tries hard to meet the I2C bus timing requirements. This could result
non-optimal values with regarding to the bus speed. For example on Intel
BayTrail we get bus speed of 315.41kHz which is ~20% slower than we would
expect (400kHz) in fast mode (even though the timing requirements are met).

This patch makes it possible for the platform code to pass more optimal
HCNT/LCNT values to the core driver if they are known beforehand. If these
are not set we use the calculated and more conservative values.

Signed-off-by: Mika Westerberg <mika.westerberg-VuQAYsv1563Yd54FQh9/CA@public.gmane.org>
---
Changes to the previous version:
 * Updated changelog
 * Reduce indentation as suggested by Shinya Kuribayashi

 drivers/i2c/busses/i2c-designware-core.c | 11 +++++++++++
 drivers/i2c/busses/i2c-designware-core.h | 12 ++++++++++++
 2 files changed, 23 insertions(+)

diff --git a/drivers/i2c/busses/i2c-designware-core.c b/drivers/i2c/busses/i2c-designware-core.c
index ad46616..c73eaea 100644
--- a/drivers/i2c/busses/i2c-designware-core.c
+++ b/drivers/i2c/busses/i2c-designware-core.c
@@ -317,6 +317,12 @@ int i2c_dw_init(struct dw_i2c_dev *dev)
 				47,	/* tLOW = 4.7 us */
 				3,	/* tf = 0.3 us */
 				0);	/* No offset */
+
+	/* Allow platforms to specify the ideal HCNT and LCNT values */
+	if (dev->ss_hcnt && dev->ss_lcnt) {
+		hcnt = dev->ss_hcnt;
+		lcnt = dev->ss_lcnt;
+	}
 	dw_writel(dev, hcnt, DW_IC_SS_SCL_HCNT);
 	dw_writel(dev, lcnt, DW_IC_SS_SCL_LCNT);
 	dev_dbg(dev->dev, "Standard-mode HCNT:LCNT = %d:%d\n", hcnt, lcnt);
@@ -331,6 +337,11 @@ int i2c_dw_init(struct dw_i2c_dev *dev)
 				13,	/* tLOW = 1.3 us */
 				3,	/* tf = 0.3 us */
 				0);	/* No offset */
+
+	if (dev->fs_hcnt && dev->fs_lcnt) {
+		hcnt = dev->fs_hcnt;
+		lcnt = dev->fs_lcnt;
+	}
 	dw_writel(dev, hcnt, DW_IC_FS_SCL_HCNT);
 	dw_writel(dev, lcnt, DW_IC_FS_SCL_LCNT);
 	dev_dbg(dev->dev, "Fast-mode HCNT:LCNT = %d:%d\n", hcnt, lcnt);
diff --git a/drivers/i2c/busses/i2c-designware-core.h b/drivers/i2c/busses/i2c-designware-core.h
index 912aa22..e8a7565 100644
--- a/drivers/i2c/busses/i2c-designware-core.h
+++ b/drivers/i2c/busses/i2c-designware-core.h
@@ -61,6 +61,14 @@
  * @tx_fifo_depth: depth of the hardware tx fifo
  * @rx_fifo_depth: depth of the hardware rx fifo
  * @rx_outstanding: current master-rx elements in tx fifo
+ * @ss_hcnt: standard speed HCNT value
+ * @ss_lcnt: standard speed LCNT value
+ * @fs_hcnt: fast speed HCNT value
+ * @fs_lcnt: fast speed LCNT value
+ *
+ * HCNT and LCNT parameters can be used if the platform knows more accurate
+ * values than the one computed based only on the input clock frequency.
+ * Leave them to be %0 if not used.
  */
 struct dw_i2c_dev {
 	struct device		*dev;
@@ -91,6 +99,10 @@ struct dw_i2c_dev {
 	unsigned int		rx_fifo_depth;
 	int			rx_outstanding;
 	u32			sda_hold_time;
+	u16			ss_hcnt;
+	u16			ss_lcnt;
+	u16			fs_hcnt;
+	u16			fs_lcnt;
 };
 
 #define ACCESS_SWAP		0x00000001
-- 
1.8.4.rc2

^ permalink raw reply related	[flat|nested] 5+ messages in thread

* [PATCH v2 2/2] i2c-designware: get SDA hold time, HCNT and LCNT configuration from ACPI
  2013-08-19 12:07 [PATCH v2 1/2] i2c-designware: make HCNT/LCNT values configurable Mika Westerberg
@ 2013-08-19 12:07 ` Mika Westerberg
       [not found]   ` <1376914074-31103-2-git-send-email-mika.westerberg-VuQAYsv1563Yd54FQh9/CA@public.gmane.org>
       [not found] ` <1376914074-31103-1-git-send-email-mika.westerberg-VuQAYsv1563Yd54FQh9/CA@public.gmane.org>
  1 sibling, 1 reply; 5+ messages in thread
From: Mika Westerberg @ 2013-08-19 12:07 UTC (permalink / raw)
  To: linux-kernel
  Cc: Wolfram Sang, Christian Ruppert, Shinya Kuribayashi, linux-i2c,
	Mika Westerberg

Some Intel LPSS I2C devices make the SDA hold time and *CNT parameters
available via SSCN (standard mode) and FMCN (fast mode) ACPI methods.

Implement support for this so that we check whether an ACPI method exists
and if it does, fill in the SDA hold time and *CNT values to the device
private structure for core to use.

Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
---
Changes to the previous version:
 * Combined SDA hold time and *CNT value setting to be in a single patch

 drivers/i2c/busses/i2c-designware-platdrv.c | 34 +++++++++++++++++++++++++++++
 1 file changed, 34 insertions(+)

diff --git a/drivers/i2c/busses/i2c-designware-platdrv.c b/drivers/i2c/busses/i2c-designware-platdrv.c
index 4c5fada..0d8b946 100644
--- a/drivers/i2c/busses/i2c-designware-platdrv.c
+++ b/drivers/i2c/busses/i2c-designware-platdrv.c
@@ -54,9 +54,33 @@ static u32 i2c_dw_get_clk_rate_khz(struct dw_i2c_dev *dev)
 }
 
 #ifdef CONFIG_ACPI
+static void dw_i2c_acpi_params(struct platform_device *pdev, char method[],
+			       u16 *hcnt, u16 *lcnt, u32 *sda_hold)
+{
+	struct acpi_buffer buf = { ACPI_ALLOCATE_BUFFER };
+	acpi_handle handle = ACPI_HANDLE(&pdev->dev);
+	union acpi_object *obj;
+
+	if (ACPI_FAILURE(acpi_evaluate_object(handle, method, NULL, &buf)))
+		return;
+
+	obj = (union acpi_object *)buf.pointer;
+	if (obj->type == ACPI_TYPE_PACKAGE && obj->package.count == 3) {
+		const union acpi_object *objs = obj->package.elements;
+
+		*hcnt = (u16)objs[0].integer.value;
+		*lcnt = (u16)objs[1].integer.value;
+		if (sda_hold)
+			*sda_hold = (u32)objs[2].integer.value;
+	}
+
+	kfree(buf.pointer);
+}
+
 static int dw_i2c_acpi_configure(struct platform_device *pdev)
 {
 	struct dw_i2c_dev *dev = platform_get_drvdata(pdev);
+	bool fs_mode = dev->master_cfg & DW_IC_CON_SPEED_FAST;
 
 	if (!ACPI_HANDLE(&pdev->dev))
 		return -ENODEV;
@@ -64,6 +88,16 @@ static int dw_i2c_acpi_configure(struct platform_device *pdev)
 	dev->adapter.nr = -1;
 	dev->tx_fifo_depth = 32;
 	dev->rx_fifo_depth = 32;
+
+	/*
+	 * Try to get SDA hold time and *CNT values from an ACPI method if
+	 * it exists for both supported speed modes.
+	 */
+	dw_i2c_acpi_params(pdev, "SSCN", &dev->ss_hcnt, &dev->ss_lcnt,
+			   fs_mode ? NULL : &dev->sda_hold_time);
+	dw_i2c_acpi_params(pdev, "FMCN", &dev->fs_hcnt, &dev->fs_lcnt,
+			   fs_mode ? &dev->sda_hold_time : NULL);
+
 	return 0;
 }
 
-- 
1.8.4.rc2

^ permalink raw reply related	[flat|nested] 5+ messages in thread

* Re: [PATCH v2 1/2] i2c-designware: make HCNT/LCNT values configurable
       [not found] ` <1376914074-31103-1-git-send-email-mika.westerberg-VuQAYsv1563Yd54FQh9/CA@public.gmane.org>
@ 2013-08-19 12:40   ` Shinya Kuribayashi
  2013-08-28  9:10   ` Wolfram Sang
  1 sibling, 0 replies; 5+ messages in thread
From: Shinya Kuribayashi @ 2013-08-19 12:40 UTC (permalink / raw)
  To: mika.westerberg-VuQAYsv1563Yd54FQh9/CA
  Cc: linux-kernel-u79uwXL29TY76Z2rM5mHXA, wsa-z923LK4zBo2bacvFa/9K2g,
	christian.ruppert-ux6zf3SgZrrQT0dZR+AlfA,
	linux-i2c-u79uwXL29TY76Z2rM5mHXA

On 8/19/13 9:07 PM, Mika Westerberg wrote:
> The DesignWare I2C controller has high count (HCNT) and low count (LCNT)
> registers for each of the I2C speed modes (standard and fast). These
> registers are programmed based on the input clock speed in the driver.
>
> The current code calculates these values based on the input clock speed and
> tries hard to meet the I2C bus timing requirements. This could result
> non-optimal values with regarding to the bus speed. For example on Intel
> BayTrail we get bus speed of 315.41kHz which is ~20% slower than we would
> expect (400kHz) in fast mode (even though the timing requirements are met).
>
> This patch makes it possible for the platform code to pass more optimal
> HCNT/LCNT values to the core driver if they are known beforehand. If these
> are not set we use the calculated and more conservative values.
>
> Signed-off-by: Mika Westerberg <mika.westerberg-VuQAYsv1563Yd54FQh9/CA@public.gmane.org>

Looks good, thanks.

Acked-by: Shinya Kuribayashi <skuribay-e+AXbWqSrlAAvxtiuMwx3w@public.gmane.org>

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH v2 1/2] i2c-designware: make HCNT/LCNT values configurable
       [not found] ` <1376914074-31103-1-git-send-email-mika.westerberg-VuQAYsv1563Yd54FQh9/CA@public.gmane.org>
  2013-08-19 12:40   ` [PATCH v2 1/2] i2c-designware: make HCNT/LCNT values configurable Shinya Kuribayashi
@ 2013-08-28  9:10   ` Wolfram Sang
  1 sibling, 0 replies; 5+ messages in thread
From: Wolfram Sang @ 2013-08-28  9:10 UTC (permalink / raw)
  To: Mika Westerberg
  Cc: linux-kernel-u79uwXL29TY76Z2rM5mHXA, Christian Ruppert,
	Shinya Kuribayashi, linux-i2c-u79uwXL29TY76Z2rM5mHXA

[-- Attachment #1: Type: text/plain, Size: 1030 bytes --]

On Mon, Aug 19, 2013 at 03:07:53PM +0300, Mika Westerberg wrote:
> The DesignWare I2C controller has high count (HCNT) and low count (LCNT)
> registers for each of the I2C speed modes (standard and fast). These
> registers are programmed based on the input clock speed in the driver.
> 
> The current code calculates these values based on the input clock speed and
> tries hard to meet the I2C bus timing requirements. This could result
> non-optimal values with regarding to the bus speed. For example on Intel
> BayTrail we get bus speed of 315.41kHz which is ~20% slower than we would
> expect (400kHz) in fast mode (even though the timing requirements are met).
> 
> This patch makes it possible for the platform code to pass more optimal
> HCNT/LCNT values to the core driver if they are known beforehand. If these
> are not set we use the calculated and more conservative values.
> 
> Signed-off-by: Mika Westerberg <mika.westerberg-VuQAYsv1563Yd54FQh9/CA@public.gmane.org>

Applied to for-next, thanks!


[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 836 bytes --]

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH v2 2/2] i2c-designware: get SDA hold time, HCNT and LCNT configuration from ACPI
       [not found]   ` <1376914074-31103-2-git-send-email-mika.westerberg-VuQAYsv1563Yd54FQh9/CA@public.gmane.org>
@ 2013-08-28  9:10     ` Wolfram Sang
  0 siblings, 0 replies; 5+ messages in thread
From: Wolfram Sang @ 2013-08-28  9:10 UTC (permalink / raw)
  To: Mika Westerberg
  Cc: linux-kernel-u79uwXL29TY76Z2rM5mHXA, Christian Ruppert,
	Shinya Kuribayashi, linux-i2c-u79uwXL29TY76Z2rM5mHXA

[-- Attachment #1: Type: text/plain, Size: 537 bytes --]

On Mon, Aug 19, 2013 at 03:07:54PM +0300, Mika Westerberg wrote:
> Some Intel LPSS I2C devices make the SDA hold time and *CNT parameters
> available via SSCN (standard mode) and FMCN (fast mode) ACPI methods.
> 
> Implement support for this so that we check whether an ACPI method exists
> and if it does, fill in the SDA hold time and *CNT values to the device
> private structure for core to use.
> 
> Signed-off-by: Mika Westerberg <mika.westerberg-VuQAYsv1563Yd54FQh9/CA@public.gmane.org>

Applied to for-next, thanks!


[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 836 bytes --]

^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2013-08-28  9:10 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2013-08-19 12:07 [PATCH v2 1/2] i2c-designware: make HCNT/LCNT values configurable Mika Westerberg
2013-08-19 12:07 ` [PATCH v2 2/2] i2c-designware: get SDA hold time, HCNT and LCNT configuration from ACPI Mika Westerberg
     [not found]   ` <1376914074-31103-2-git-send-email-mika.westerberg-VuQAYsv1563Yd54FQh9/CA@public.gmane.org>
2013-08-28  9:10     ` Wolfram Sang
     [not found] ` <1376914074-31103-1-git-send-email-mika.westerberg-VuQAYsv1563Yd54FQh9/CA@public.gmane.org>
2013-08-19 12:40   ` [PATCH v2 1/2] i2c-designware: make HCNT/LCNT values configurable Shinya Kuribayashi
2013-08-28  9:10   ` Wolfram Sang

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).