[PATCH v4] drm: bridge/dw_hdmi: add dw hdmi i2c bus adapter support

2015-09-28 Thread Vladimir Zapolskiy
Hi Doug,

On 28.09.2015 19:29, Doug Anderson wrote:
> Vladimir,
> 
> On Mon, Sep 21, 2015 at 8:07 AM, Vladimir Zapolskiy
>  wrote:
>> - do I2C bus controller reinitialization on every data transfer,
>>   this change hopefully solves some observed problems on RK3288 platform
> 
> My apologies, but this appears to be a bad idea...
> 
> We just discovered that this was the root cause of a bug.  If an HDCP
> transfer is happening then the soft reset messes things up.  In our
> tree we've moving things back to the way they were.  :(

therefore I do the same.

Since unfortunately I'm limited in testing your tree and RK3288
platform, probably it might be more productive, if you send any updates
on top of my changes -- I'll be capable to review/test them for
regressions on iMX6 in vanilla.

--
With best wishes,
Vladimir


[PATCH v4] drm: bridge/dw_hdmi: add dw hdmi i2c bus adapter support

2015-09-28 Thread Doug Anderson
Vladimir,

On Mon, Sep 21, 2015 at 8:07 AM, Vladimir Zapolskiy
 wrote:
> - do I2C bus controller reinitialization on every data transfer,
>   this change hopefully solves some observed problems on RK3288 platform

My apologies, but this appears to be a bad idea...

We just discovered that this was the root cause of a bug.  If an HDCP
transfer is happening then the soft reset messes things up.  In our
tree we've moving things back to the way they were.  :(

-Doug


[PATCH v4] drm: bridge/dw_hdmi: add dw hdmi i2c bus adapter support

2015-09-21 Thread Vladimir Zapolskiy
The change adds support of internal HDMI I2C master controller, this
subdevice is used by default, if "ddc-i2c-bus" DT property is omitted.

The main purpose of this functionality is to support reading EDID from
an HDMI monitor on boards, which don't have an I2C bus connected to
DDC pins.

The current implementation does not support "I2C Master Interface
Extended Read Mode" to read data addressed by non-zero segment
pointer, this means that if EDID has more than 1 extension blocks,
EDID reading operation won't succeed, in my practice all tested HDMI
monitors have at maximum one extension block.

Signed-off-by: Vladimir Zapolskiy 
---
The change is based on v4.3.0-rc2 and it is applicable to rmk/drm-dwhdmi-devel,
please let me know, if it should be rebased.

v3 of the change was

  Tested-by: Philipp Zabel 

Changes frov v3 to v4, thanks to Doug and Philipp for review:
- set speed mode after software reset in dw_hdmi_i2c_init()
- by default set standard speed mode instead of fast speed mode, on iMX6Q
  this configures SCL to 100 KHz, which is compliant with HDMI 1.3a spec
- do I2C bus controller reinitialization on every data transfer,
  this change hopefully solves some observed problems on RK3288 platform
- added short functional change description to dw_hdmi.txt

Changes from v2 to v3, thanks to Russell:
- moved register field value definitions to dw_hdmi.h
- made completions uninterruptible to avoid transfer retries if interrupted
- use one completion for both read and write transfers as in v1, operation_reg 
is removed
- redundant i2c->stat = 0 is removed from dw_hdmi_i2c_read/write()
- struct i2c_algorithm dw_hdmi_algorithm is qualified as const
- dw_hdmi_i2c_adapter() does not modify struct dw_hdmi on error path
- dw_hdmi_i2c_irq() does not modify hdmi->i2c->stat, if interrupt is not for 
I2CM
- spin lock is removed from dw_hdmi_i2c_irq()
- removed spin lock from dw_hdmi_i2c_xfer() around write to 
HDMI_IH_MUTE_I2CM_STAT0 register
- split loop over message array in dw_hdmi_i2c_xfer() to validation and 
transfer parts
- added a mutex to serialize I2C transfer requests, i2c->lock is completely 
removed
- removed if(len) check from dw_hdmi_i2c_write(), hardware supports only len>0 
transfers
- described extension blocks <= 1 limitation in the commit message
- a number of minor clean ups

Changes from v1 to v2:
- fixed a devm_kfree() signature
- split completions for read and write operations

 .../devicetree/bindings/drm/bridge/dw_hdmi.txt |   4 +-
 drivers/gpu/drm/bridge/dw_hdmi.c   | 258 -
 drivers/gpu/drm/bridge/dw_hdmi.h   |  19 ++
 3 files changed, 274 insertions(+), 7 deletions(-)

diff --git a/Documentation/devicetree/bindings/drm/bridge/dw_hdmi.txt 
b/Documentation/devicetree/bindings/drm/bridge/dw_hdmi.txt
index a905c14..55f5a7c 100644
--- a/Documentation/devicetree/bindings/drm/bridge/dw_hdmi.txt
+++ b/Documentation/devicetree/bindings/drm/bridge/dw_hdmi.txt
@@ -19,7 +19,9 @@ Required properties:

 Optional properties
 - reg-io-width: the width of the reg:1,4, default set to 1 if not present
-- ddc-i2c-bus: phandle of an I2C controller used for DDC EDID probing
+- ddc-i2c-bus: phandle of an I2C controller used for DDC EDID probing,
+  if the property is omitted, a functionally reduced I2C bus
+  controller on DW HDMI is probed
 - clocks, clock-names: phandle to the HDMI CEC clock, name should be "cec"

 Example:
diff --git a/drivers/gpu/drm/bridge/dw_hdmi.c b/drivers/gpu/drm/bridge/dw_hdmi.c
index 0083d4e..58dcacf 100644
--- a/drivers/gpu/drm/bridge/dw_hdmi.c
+++ b/drivers/gpu/drm/bridge/dw_hdmi.c
@@ -1,14 +1,15 @@
 /*
+ * DesignWare High-Definition Multimedia Interface (HDMI) driver
+ *
+ * Copyright (C) 2013-2015 Mentor Graphics Inc.
  * Copyright (C) 2011-2013 Freescale Semiconductor, Inc.
+ * Copyright (C) 2010, Guennadi Liakhovetski 
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
  * the Free Software Foundation; either version 2 of the License, or
  * (at your option) any later version.
  *
- * Designware High-Definition Multimedia Interface (HDMI) driver
- *
- * Copyright (C) 2010, Guennadi Liakhovetski 
  */
 #include 
 #include 
@@ -99,6 +100,17 @@ struct hdmi_data_info {
struct hdmi_vmode video_mode;
 };

+struct dw_hdmi_i2c {
+   struct i2c_adapter  adap;
+
+   struct mutexlock;
+   struct completion   cmp;
+   u8  stat;
+
+   u8  slave_reg;
+   boolis_regaddr;
+};
+
 struct dw_hdmi {
struct drm_connector connector;
struct drm_encoder *encoder;
@@ -108,6 +120,7 @@ struct dw_hdmi {
struct device *dev;
struct clk *isfr_clk;
struct clk *iahb_clk;
+   struct dw_hdmi_i2c *i2c;

struct hdmi_data_info hdmi_data;
const struct dw_hdmi_plat_data *plat_data;
@@ -184,6