Re: [PATCH] drm/bridge: adv7511: fix spelling of driver name in Kconfig

2018-05-04 Thread Archit Taneja



On Friday 27 April 2018 03:11 AM, Laurent Pinchart wrote:

Hi Peter,

Thank you for the patch.

On Friday, 27 April 2018 00:36:44 EEST Peter Rosin wrote:

Could perhaps prevent some confusion.


queued to drm-misc-next

Thanks,
Archit



Signed-off-by: Peter Rosin 


Reviewed-by: Laurent Pinchart 


---
  drivers/gpu/drm/bridge/adv7511/Kconfig | 2 +-
  1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/bridge/adv7511/Kconfig
b/drivers/gpu/drm/bridge/adv7511/Kconfig index 592b9d2ec034..944e440c4fde
100644
--- a/drivers/gpu/drm/bridge/adv7511/Kconfig
+++ b/drivers/gpu/drm/bridge/adv7511/Kconfig
@@ -1,5 +1,5 @@
  config DRM_I2C_ADV7511
-   tristate "AV7511 encoder"
+   tristate "ADV7511 encoder"
depends on OF
select DRM_KMS_HELPER
select REGMAP_I2C





Re: [PATCH] drm/bridge: adv7511: fix spelling of driver name in Kconfig

2018-05-04 Thread Archit Taneja



On Friday 27 April 2018 03:11 AM, Laurent Pinchart wrote:

Hi Peter,

Thank you for the patch.

On Friday, 27 April 2018 00:36:44 EEST Peter Rosin wrote:

Could perhaps prevent some confusion.


queued to drm-misc-next

Thanks,
Archit



Signed-off-by: Peter Rosin 


Reviewed-by: Laurent Pinchart 


---
  drivers/gpu/drm/bridge/adv7511/Kconfig | 2 +-
  1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/bridge/adv7511/Kconfig
b/drivers/gpu/drm/bridge/adv7511/Kconfig index 592b9d2ec034..944e440c4fde
100644
--- a/drivers/gpu/drm/bridge/adv7511/Kconfig
+++ b/drivers/gpu/drm/bridge/adv7511/Kconfig
@@ -1,5 +1,5 @@
  config DRM_I2C_ADV7511
-   tristate "AV7511 encoder"
+   tristate "ADV7511 encoder"
depends on OF
select DRM_KMS_HELPER
select REGMAP_I2C





Re: [PATCH] gpu: drm: bridge: adv7511: Replace mdelay with usleep_range in adv7511_probe

2018-05-04 Thread Archit Taneja



On Friday 27 April 2018 03:46 AM, Laurent Pinchart wrote:

Hi Jia-Ju,

Thank you for the patch.

On Wednesday, 11 April 2018 11:33:42 EEST Jia-Ju Bai wrote:

adv7511_probe() is never called in atomic context.
This function is only set as ".probe" in struct i2c_driver.

Despite never getting called from atomic context, adv7511_probe()
calls mdelay() to busily wait.
This is not necessary and can be replaced with usleep_range() to
avoid busy waiting.

This is found by a static analysis tool named DCNS written by myself.
And I also manually check it.


Nice work ! Is the tool open-source ?


Signed-off-by: Jia-Ju Bai 
---
  drivers/gpu/drm/bridge/adv7511/adv7511_drv.c | 2 +-
  1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c
b/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c index b2431ae..2cf7fa1
100644
--- a/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c
+++ b/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c
@@ -1054,7 +1054,7 @@ static int adv7511_probe(struct i2c_client *i2c, const
struct i2c_device_id *id) }

if (adv7511->gpio_pd) {
-   mdelay(5);
+   usleep_range(5000, 6000);
gpiod_set_value_cansleep(adv7511->gpio_pd, 0);
}


The patch looks good to me.

Reviewed-by: Laurent Pinchart 


queued to drm-misc-next

Thanks,
Archit



Re: [PATCH] gpu: drm: bridge: adv7511: Replace mdelay with usleep_range in adv7511_probe

2018-05-04 Thread Archit Taneja



On Friday 27 April 2018 03:46 AM, Laurent Pinchart wrote:

Hi Jia-Ju,

Thank you for the patch.

On Wednesday, 11 April 2018 11:33:42 EEST Jia-Ju Bai wrote:

adv7511_probe() is never called in atomic context.
This function is only set as ".probe" in struct i2c_driver.

Despite never getting called from atomic context, adv7511_probe()
calls mdelay() to busily wait.
This is not necessary and can be replaced with usleep_range() to
avoid busy waiting.

This is found by a static analysis tool named DCNS written by myself.
And I also manually check it.


Nice work ! Is the tool open-source ?


Signed-off-by: Jia-Ju Bai 
---
  drivers/gpu/drm/bridge/adv7511/adv7511_drv.c | 2 +-
  1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c
b/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c index b2431ae..2cf7fa1
100644
--- a/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c
+++ b/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c
@@ -1054,7 +1054,7 @@ static int adv7511_probe(struct i2c_client *i2c, const
struct i2c_device_id *id) }

if (adv7511->gpio_pd) {
-   mdelay(5);
+   usleep_range(5000, 6000);
gpiod_set_value_cansleep(adv7511->gpio_pd, 0);
}


The patch looks good to me.

Reviewed-by: Laurent Pinchart 


queued to drm-misc-next

Thanks,
Archit



Re: [PATCH v4 2/5] dt-bindings: adv7511: Extend bindings to allow specifying slave map addresses

2018-04-25 Thread Archit Taneja



On Tuesday 13 February 2018 11:18 PM, Kieran Bingham wrote:

From: Kieran Bingham 

The ADV7511 has four 256-byte maps that can be accessed via the main I2C
ports. Each map has it own I2C address and acts as a standard slave
device on the I2C bus.

Extend the device tree node bindings to be able to override the default
addresses so that address conflicts with other devices on the same bus
may be resolved at the board description level.



Queued to drm-misc-next


Signed-off-by: Kieran Bingham 
Reviewed-by: Rob Herring 
Reviewed-by: Laurent Pinchart 
---
v2:
  - Fixed up reg: property description to account for multiple optional
addresses.
  - Minor reword to commit message to account for DT only change
  - Collected Robs RB tag

v3:
  - Split map register addresses into individual declarations.

v4:
  - Update commit title
  - Collect Laurent's RB tag
  - Fix nitpickings
  - Normalise I2C usage (I²C is harder to grep for)

  .../devicetree/bindings/display/bridge/adi,adv7511.txt | 18 --
  1 file changed, 16 insertions(+), 2 deletions(-)

diff --git a/Documentation/devicetree/bindings/display/bridge/adi,adv7511.txt 
b/Documentation/devicetree/bindings/display/bridge/adi,adv7511.txt
index 0047b1394c70..2c887536258c 100644
--- a/Documentation/devicetree/bindings/display/bridge/adi,adv7511.txt
+++ b/Documentation/devicetree/bindings/display/bridge/adi,adv7511.txt
@@ -14,7 +14,13 @@ Required properties:
"adi,adv7513"
"adi,adv7533"
  
-- reg: I2C slave address

+- reg: I2C slave addresses
+  The ADV7511 internal registers are split into four pages exposed through
+  different I2C addresses, creating four register maps. Each map has it own
+  I2C address and acts as a standard slave device on the I2C bus. The main
+  address is mandatory, others are optional and revert to defaults if not
+  specified.
+
  
  The ADV7511 supports a large number of input data formats that differ by their

  color depth, color format, clock mode, bit justification and random
@@ -70,6 +76,9 @@ Optional properties:
rather than generate its own timings for HDMI output.
  - clocks: from common clock binding: reference to the CEC clock.
  - clock-names: from common clock binding: must be "cec".
+- reg-names : Names of maps with programmable addresses.
+   It can contain any map needing a non-default address.
+   Possible maps names are : "main", "edid", "cec", "packet"
  
  Required nodes:
  
@@ -88,7 +97,12 @@ Example
  
  	adv7511w: hdmi@39 {

compatible = "adi,adv7511w";
-   reg = <39>;
+   /*
+* The EDID page will be accessible on address 0x66 on the I2C
+* bus. All other maps continue to use their default addresses.
+*/
+   reg = <0x39>, <0x66>;
+   reg-names = "main", "edid";
interrupt-parent = <>;
interrupts = <29 IRQ_TYPE_EDGE_FALLING>;
clocks = <_clock>;



Re: [PATCH v4 2/5] dt-bindings: adv7511: Extend bindings to allow specifying slave map addresses

2018-04-25 Thread Archit Taneja



On Tuesday 13 February 2018 11:18 PM, Kieran Bingham wrote:

From: Kieran Bingham 

The ADV7511 has four 256-byte maps that can be accessed via the main I2C
ports. Each map has it own I2C address and acts as a standard slave
device on the I2C bus.

Extend the device tree node bindings to be able to override the default
addresses so that address conflicts with other devices on the same bus
may be resolved at the board description level.



Queued to drm-misc-next


Signed-off-by: Kieran Bingham 
Reviewed-by: Rob Herring 
Reviewed-by: Laurent Pinchart 
---
v2:
  - Fixed up reg: property description to account for multiple optional
addresses.
  - Minor reword to commit message to account for DT only change
  - Collected Robs RB tag

v3:
  - Split map register addresses into individual declarations.

v4:
  - Update commit title
  - Collect Laurent's RB tag
  - Fix nitpickings
  - Normalise I2C usage (I²C is harder to grep for)

  .../devicetree/bindings/display/bridge/adi,adv7511.txt | 18 --
  1 file changed, 16 insertions(+), 2 deletions(-)

diff --git a/Documentation/devicetree/bindings/display/bridge/adi,adv7511.txt 
b/Documentation/devicetree/bindings/display/bridge/adi,adv7511.txt
index 0047b1394c70..2c887536258c 100644
--- a/Documentation/devicetree/bindings/display/bridge/adi,adv7511.txt
+++ b/Documentation/devicetree/bindings/display/bridge/adi,adv7511.txt
@@ -14,7 +14,13 @@ Required properties:
"adi,adv7513"
"adi,adv7533"
  
-- reg: I2C slave address

+- reg: I2C slave addresses
+  The ADV7511 internal registers are split into four pages exposed through
+  different I2C addresses, creating four register maps. Each map has it own
+  I2C address and acts as a standard slave device on the I2C bus. The main
+  address is mandatory, others are optional and revert to defaults if not
+  specified.
+
  
  The ADV7511 supports a large number of input data formats that differ by their

  color depth, color format, clock mode, bit justification and random
@@ -70,6 +76,9 @@ Optional properties:
rather than generate its own timings for HDMI output.
  - clocks: from common clock binding: reference to the CEC clock.
  - clock-names: from common clock binding: must be "cec".
+- reg-names : Names of maps with programmable addresses.
+   It can contain any map needing a non-default address.
+   Possible maps names are : "main", "edid", "cec", "packet"
  
  Required nodes:
  
@@ -88,7 +97,12 @@ Example
  
  	adv7511w: hdmi@39 {

compatible = "adi,adv7511w";
-   reg = <39>;
+   /*
+* The EDID page will be accessible on address 0x66 on the I2C
+* bus. All other maps continue to use their default addresses.
+*/
+   reg = <0x39>, <0x66>;
+   reg-names = "main", "edid";
interrupt-parent = <>;
interrupts = <29 IRQ_TYPE_EDGE_FALLING>;
clocks = <_clock>;



Re: [PATCH v4 5/5] drm: adv7511: Add support for i2c_new_secondary_device

2018-04-25 Thread Archit Taneja



On Tuesday 13 February 2018 11:18 PM, Kieran Bingham wrote:

From: Kieran Bingham 

The ADV7511 has four 256-byte maps that can be accessed via the main I2C
ports. Each map has it own I2C address and acts as a standard slave
device on the I2C bus.

Allow a device tree node to override the default addresses so that
address conflicts with other devices on the same bus may be resolved at
the board description level.


Queued to drm-misc-next



Signed-off-by: Kieran Bingham 
Reviewed-by: Laurent Pinchart 
---
v2:
  - Update missing edid-i2c address setting
  - Split out DT bindings
  - Rename and move the I2C default addresses to their own section

v3:
  - No change

v4:
  - Change registration order of packet/cec to fix error path and
simplify code change.
  - Collect Laurent's RB tag

  drivers/gpu/drm/bridge/adv7511/adv7511.h |  6 
  drivers/gpu/drm/bridge/adv7511/adv7511_drv.c | 42 ++--
  2 files changed, 33 insertions(+), 15 deletions(-)

diff --git a/drivers/gpu/drm/bridge/adv7511/adv7511.h 
b/drivers/gpu/drm/bridge/adv7511/adv7511.h
index d034b2cb5eee..73d8ccb97742 100644
--- a/drivers/gpu/drm/bridge/adv7511/adv7511.h
+++ b/drivers/gpu/drm/bridge/adv7511/adv7511.h
@@ -93,6 +93,11 @@
  #define ADV7511_REG_CHIP_ID_HIGH  0xf5
  #define ADV7511_REG_CHIP_ID_LOW   0xf6
  
+/* Hardware defined default addresses for I2C register maps */

+#define ADV7511_CEC_I2C_ADDR_DEFAULT   0x3c
+#define ADV7511_EDID_I2C_ADDR_DEFAULT  0x3f
+#define ADV7511_PACKET_I2C_ADDR_DEFAULT0x38
+
  #define ADV7511_CSC_ENABLEBIT(7)
  #define ADV7511_CSC_UPDATE_MODE   BIT(5)
  
@@ -321,6 +326,7 @@ enum adv7511_type {

  struct adv7511 {
struct i2c_client *i2c_main;
struct i2c_client *i2c_edid;
+   struct i2c_client *i2c_packet;
struct i2c_client *i2c_cec;
  
  	struct regmap *regmap;

diff --git a/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c 
b/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c
index efa29db5fc2b..802bc433f54a 100644
--- a/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c
+++ b/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c
@@ -586,7 +586,7 @@ static int adv7511_get_modes(struct adv7511 *adv7511,
/* Reading the EDID only works if the device is powered */
if (!adv7511->powered) {
unsigned int edid_i2c_addr =
-   (adv7511->i2c_main->addr << 1) + 4;
+   (adv7511->i2c_edid->addr << 1);
  
  		__adv7511_power_on(adv7511);
  
@@ -969,10 +969,10 @@ static int adv7511_init_cec_regmap(struct adv7511 *adv)

  {
int ret;
  
-	adv->i2c_cec = i2c_new_dummy(adv->i2c_main->adapter,

-adv->i2c_main->addr - 1);
+   adv->i2c_cec = i2c_new_secondary_device(adv->i2c_main, "cec",
+   ADV7511_CEC_I2C_ADDR_DEFAULT);
if (!adv->i2c_cec)
-   return -ENOMEM;
+   return -EINVAL;
i2c_set_clientdata(adv->i2c_cec, adv);
  
  	adv->regmap_cec = devm_regmap_init_i2c(adv->i2c_cec,

@@ -1082,8 +1082,6 @@ static int adv7511_probe(struct i2c_client *i2c, const 
struct i2c_device_id *id)
struct adv7511_link_config link_config;
struct adv7511 *adv7511;
struct device *dev = >dev;
-   unsigned int main_i2c_addr = i2c->addr << 1;
-   unsigned int edid_i2c_addr = main_i2c_addr + 4;
unsigned int val;
int ret;
  
@@ -1153,23 +1151,34 @@ static int adv7511_probe(struct i2c_client *i2c, const struct i2c_device_id *id)

if (ret)
goto uninit_regulators;
  
-	regmap_write(adv7511->regmap, ADV7511_REG_EDID_I2C_ADDR, edid_i2c_addr);

-   regmap_write(adv7511->regmap, ADV7511_REG_PACKET_I2C_ADDR,
-main_i2c_addr - 0xa);
-   regmap_write(adv7511->regmap, ADV7511_REG_CEC_I2C_ADDR,
-main_i2c_addr - 2);
-
adv7511_packet_disable(adv7511, 0x);
  
-	adv7511->i2c_edid = i2c_new_dummy(i2c->adapter, edid_i2c_addr >> 1);

+   adv7511->i2c_edid = i2c_new_secondary_device(i2c, "edid",
+   ADV7511_EDID_I2C_ADDR_DEFAULT);
if (!adv7511->i2c_edid) {
-   ret = -ENOMEM;
+   ret = -EINVAL;
goto uninit_regulators;
}
  
+	regmap_write(adv7511->regmap, ADV7511_REG_EDID_I2C_ADDR,

+adv7511->i2c_edid->addr << 1);
+
+   adv7511->i2c_packet = i2c_new_secondary_device(i2c, "packet",
+   ADV7511_PACKET_I2C_ADDR_DEFAULT);
+   if (!adv7511->i2c_packet) {
+   ret = -EINVAL;
+   goto err_i2c_unregister_edid;
+   }
+
+   regmap_write(adv7511->regmap, ADV7511_REG_PACKET_I2C_ADDR,
+   

Re: [PATCH v4 5/5] drm: adv7511: Add support for i2c_new_secondary_device

2018-04-25 Thread Archit Taneja



On Tuesday 13 February 2018 11:18 PM, Kieran Bingham wrote:

From: Kieran Bingham 

The ADV7511 has four 256-byte maps that can be accessed via the main I2C
ports. Each map has it own I2C address and acts as a standard slave
device on the I2C bus.

Allow a device tree node to override the default addresses so that
address conflicts with other devices on the same bus may be resolved at
the board description level.


Queued to drm-misc-next



Signed-off-by: Kieran Bingham 
Reviewed-by: Laurent Pinchart 
---
v2:
  - Update missing edid-i2c address setting
  - Split out DT bindings
  - Rename and move the I2C default addresses to their own section

v3:
  - No change

v4:
  - Change registration order of packet/cec to fix error path and
simplify code change.
  - Collect Laurent's RB tag

  drivers/gpu/drm/bridge/adv7511/adv7511.h |  6 
  drivers/gpu/drm/bridge/adv7511/adv7511_drv.c | 42 ++--
  2 files changed, 33 insertions(+), 15 deletions(-)

diff --git a/drivers/gpu/drm/bridge/adv7511/adv7511.h 
b/drivers/gpu/drm/bridge/adv7511/adv7511.h
index d034b2cb5eee..73d8ccb97742 100644
--- a/drivers/gpu/drm/bridge/adv7511/adv7511.h
+++ b/drivers/gpu/drm/bridge/adv7511/adv7511.h
@@ -93,6 +93,11 @@
  #define ADV7511_REG_CHIP_ID_HIGH  0xf5
  #define ADV7511_REG_CHIP_ID_LOW   0xf6
  
+/* Hardware defined default addresses for I2C register maps */

+#define ADV7511_CEC_I2C_ADDR_DEFAULT   0x3c
+#define ADV7511_EDID_I2C_ADDR_DEFAULT  0x3f
+#define ADV7511_PACKET_I2C_ADDR_DEFAULT0x38
+
  #define ADV7511_CSC_ENABLEBIT(7)
  #define ADV7511_CSC_UPDATE_MODE   BIT(5)
  
@@ -321,6 +326,7 @@ enum adv7511_type {

  struct adv7511 {
struct i2c_client *i2c_main;
struct i2c_client *i2c_edid;
+   struct i2c_client *i2c_packet;
struct i2c_client *i2c_cec;
  
  	struct regmap *regmap;

diff --git a/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c 
b/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c
index efa29db5fc2b..802bc433f54a 100644
--- a/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c
+++ b/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c
@@ -586,7 +586,7 @@ static int adv7511_get_modes(struct adv7511 *adv7511,
/* Reading the EDID only works if the device is powered */
if (!adv7511->powered) {
unsigned int edid_i2c_addr =
-   (adv7511->i2c_main->addr << 1) + 4;
+   (adv7511->i2c_edid->addr << 1);
  
  		__adv7511_power_on(adv7511);
  
@@ -969,10 +969,10 @@ static int adv7511_init_cec_regmap(struct adv7511 *adv)

  {
int ret;
  
-	adv->i2c_cec = i2c_new_dummy(adv->i2c_main->adapter,

-adv->i2c_main->addr - 1);
+   adv->i2c_cec = i2c_new_secondary_device(adv->i2c_main, "cec",
+   ADV7511_CEC_I2C_ADDR_DEFAULT);
if (!adv->i2c_cec)
-   return -ENOMEM;
+   return -EINVAL;
i2c_set_clientdata(adv->i2c_cec, adv);
  
  	adv->regmap_cec = devm_regmap_init_i2c(adv->i2c_cec,

@@ -1082,8 +1082,6 @@ static int adv7511_probe(struct i2c_client *i2c, const 
struct i2c_device_id *id)
struct adv7511_link_config link_config;
struct adv7511 *adv7511;
struct device *dev = >dev;
-   unsigned int main_i2c_addr = i2c->addr << 1;
-   unsigned int edid_i2c_addr = main_i2c_addr + 4;
unsigned int val;
int ret;
  
@@ -1153,23 +1151,34 @@ static int adv7511_probe(struct i2c_client *i2c, const struct i2c_device_id *id)

if (ret)
goto uninit_regulators;
  
-	regmap_write(adv7511->regmap, ADV7511_REG_EDID_I2C_ADDR, edid_i2c_addr);

-   regmap_write(adv7511->regmap, ADV7511_REG_PACKET_I2C_ADDR,
-main_i2c_addr - 0xa);
-   regmap_write(adv7511->regmap, ADV7511_REG_CEC_I2C_ADDR,
-main_i2c_addr - 2);
-
adv7511_packet_disable(adv7511, 0x);
  
-	adv7511->i2c_edid = i2c_new_dummy(i2c->adapter, edid_i2c_addr >> 1);

+   adv7511->i2c_edid = i2c_new_secondary_device(i2c, "edid",
+   ADV7511_EDID_I2C_ADDR_DEFAULT);
if (!adv7511->i2c_edid) {
-   ret = -ENOMEM;
+   ret = -EINVAL;
goto uninit_regulators;
}
  
+	regmap_write(adv7511->regmap, ADV7511_REG_EDID_I2C_ADDR,

+adv7511->i2c_edid->addr << 1);
+
+   adv7511->i2c_packet = i2c_new_secondary_device(i2c, "packet",
+   ADV7511_PACKET_I2C_ADDR_DEFAULT);
+   if (!adv7511->i2c_packet) {
+   ret = -EINVAL;
+   goto err_i2c_unregister_edid;
+   }
+
+   regmap_write(adv7511->regmap, ADV7511_REG_PACKET_I2C_ADDR,
+adv7511->i2c_packet->addr << 1);
+
ret = adv7511_init_cec_regmap(adv7511);
if (ret)
-   

Re: [PATCH] drm: clarify adjusted_mode documentation for bridges

2018-04-19 Thread Archit Taneja



On Thursday 19 April 2018 09:20 PM, Philippe CORNU wrote:

Hi Archit & Andrzej,

May I ask you please a short review of this documentation update.
Many thanks
Philippe :-)

On 04/09/2018 05:24 PM, Philippe Cornu wrote:

This patch clarifies the adjusted_mode documentation
for bridges.



Reviewed-by: Archit Taneja <arch...@codeaurora.org>


Signed-off-by: Philippe Cornu <philippe.co...@st.com>
Signed-off-by: Laurent Pinchart <laurent.pinchart+rene...@ideasonboard.com>
---
This patch follows discussions in:
- "drm: clarify adjusted_mode for a bridge connected to a crtc"
https://patchwork.freedesktop.org/patch/206801/
- "drm: bridge: Constify mode arguments to bridge .mode_set() operation"
https://patchwork.freedesktop.org/patch/215449/

   include/drm/drm_bridge.h | 16 
   include/drm/drm_crtc.h   | 11 +++
   2 files changed, 23 insertions(+), 4 deletions(-)

diff --git a/include/drm/drm_bridge.h b/include/drm/drm_bridge.h
index 3270fec46979..7d632c6a9214 100644
--- a/include/drm/drm_bridge.h
+++ b/include/drm/drm_bridge.h
@@ -178,6 +178,22 @@ struct drm_bridge_funcs {
 * then this would be _encoder_helper_funcs.mode_set. The display
 * pipe (i.e.  clocks and timing signals) is off when this function is
 * called.
+*
+* The adjusted_mode parameter corresponds to the mode output by the 
CRTC
+* for the first bridge in the chain. It can be different from the mode
+* parameter that contains the desired mode for the connector at the end
+* of the bridges chain, for instance when the first bridge in the chain
+* performs scaling. The adjusted mode is mostly useful for the first
+* bridge in the chain and is likely irrelevant for the other bridges.
+*
+* For atomic drivers the adjusted_mode is the mode stored in
+* _crtc_state.adjusted_mode.
+*
+* NOTE:
+*
+* If a need arises to store and access modes adjusted for other 
locations
+* than the connection between the CRTC and the first bridge, the DRM
+* framework will have to be extended with DRM bridge states.
 */
void (*mode_set)(struct drm_bridge *bridge,
 struct drm_display_mode *mode,
diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h
index a2d81d2907a9..65f749a9e9d3 100644
--- a/include/drm/drm_crtc.h
+++ b/include/drm/drm_crtc.h
@@ -134,10 +134,13 @@ struct drm_crtc_state {
 *
 * Internal display timings which can be used by the driver to handle
 * differences between the mode requested by userspace in @mode and what
-* is actually programmed into the hardware. It is purely driver
-* implementation defined what exactly this adjusted mode means. Usually
-* it is used to store the hardware display timings used between the
-* CRTC and encoder blocks.
+* is actually programmed into the hardware.
+*
+* For drivers using drm_bridge, this stores the hardware display 
timings
+* used between the CRTC and the first bridge. For other drivers, the
+* meaning of the adjusted_mode field is purely driver implementation
+* defined information, and will usually be used to store the hardware
+* display timings used between the CRTC and encoder blocks.
 */
struct drm_display_mode adjusted_mode;
   


Re: [PATCH] drm: clarify adjusted_mode documentation for bridges

2018-04-19 Thread Archit Taneja



On Thursday 19 April 2018 09:20 PM, Philippe CORNU wrote:

Hi Archit & Andrzej,

May I ask you please a short review of this documentation update.
Many thanks
Philippe :-)

On 04/09/2018 05:24 PM, Philippe Cornu wrote:

This patch clarifies the adjusted_mode documentation
for bridges.



Reviewed-by: Archit Taneja 


Signed-off-by: Philippe Cornu 
Signed-off-by: Laurent Pinchart 
---
This patch follows discussions in:
- "drm: clarify adjusted_mode for a bridge connected to a crtc"
https://patchwork.freedesktop.org/patch/206801/
- "drm: bridge: Constify mode arguments to bridge .mode_set() operation"
https://patchwork.freedesktop.org/patch/215449/

   include/drm/drm_bridge.h | 16 
   include/drm/drm_crtc.h   | 11 +++
   2 files changed, 23 insertions(+), 4 deletions(-)

diff --git a/include/drm/drm_bridge.h b/include/drm/drm_bridge.h
index 3270fec46979..7d632c6a9214 100644
--- a/include/drm/drm_bridge.h
+++ b/include/drm/drm_bridge.h
@@ -178,6 +178,22 @@ struct drm_bridge_funcs {
 * then this would be _encoder_helper_funcs.mode_set. The display
 * pipe (i.e.  clocks and timing signals) is off when this function is
 * called.
+*
+* The adjusted_mode parameter corresponds to the mode output by the 
CRTC
+* for the first bridge in the chain. It can be different from the mode
+* parameter that contains the desired mode for the connector at the end
+* of the bridges chain, for instance when the first bridge in the chain
+* performs scaling. The adjusted mode is mostly useful for the first
+* bridge in the chain and is likely irrelevant for the other bridges.
+*
+* For atomic drivers the adjusted_mode is the mode stored in
+* _crtc_state.adjusted_mode.
+*
+* NOTE:
+*
+* If a need arises to store and access modes adjusted for other 
locations
+* than the connection between the CRTC and the first bridge, the DRM
+* framework will have to be extended with DRM bridge states.
 */
void (*mode_set)(struct drm_bridge *bridge,
 struct drm_display_mode *mode,
diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h
index a2d81d2907a9..65f749a9e9d3 100644
--- a/include/drm/drm_crtc.h
+++ b/include/drm/drm_crtc.h
@@ -134,10 +134,13 @@ struct drm_crtc_state {
 *
 * Internal display timings which can be used by the driver to handle
 * differences between the mode requested by userspace in @mode and what
-* is actually programmed into the hardware. It is purely driver
-* implementation defined what exactly this adjusted mode means. Usually
-* it is used to store the hardware display timings used between the
-* CRTC and encoder blocks.
+* is actually programmed into the hardware.
+*
+* For drivers using drm_bridge, this stores the hardware display 
timings
+* used between the CRTC and the first bridge. For other drivers, the
+* meaning of the adjusted_mode field is purely driver implementation
+* defined information, and will usually be used to store the hardware
+* display timings used between the CRTC and encoder blocks.
 */
struct drm_display_mode adjusted_mode;
   


Re: [PATCH v2 4/6] drm/msm: Issue queued events when disabling crtc

2018-04-01 Thread Archit Taneja



On Thursday 29 March 2018 12:36 AM, Sean Paul wrote:

Ensure that any queued events are issued when disabling the crtc. This
avoids timeouts when we come back and wait for dependencies (like the
previous frame's flip_done).


Reviewed-by: Archit Taneja <arch...@codeaurora.org>



Changes in v2:
- None

Signed-off-by: Sean Paul <seanp...@chromium.org>
---
  drivers/gpu/drm/msm/disp/mdp5/mdp5_crtc.c | 9 +
  1 file changed, 9 insertions(+)

diff --git a/drivers/gpu/drm/msm/disp/mdp5/mdp5_crtc.c 
b/drivers/gpu/drm/msm/disp/mdp5/mdp5_crtc.c
index 76b96081916f..10271359789e 100644
--- a/drivers/gpu/drm/msm/disp/mdp5/mdp5_crtc.c
+++ b/drivers/gpu/drm/msm/disp/mdp5/mdp5_crtc.c
@@ -430,6 +430,7 @@ static void mdp5_crtc_atomic_disable(struct drm_crtc *crtc,
struct mdp5_crtc_state *mdp5_cstate = to_mdp5_crtc_state(crtc->state);
struct mdp5_kms *mdp5_kms = get_kms(crtc);
struct device *dev = _kms->pdev->dev;
+   unsigned long flags;
  
  	DBG("%s", crtc->name);
  
@@ -445,6 +446,14 @@ static void mdp5_crtc_atomic_disable(struct drm_crtc *crtc,

mdp_irq_unregister(_kms->base, _crtc->err);
pm_runtime_put_sync(dev);
  
+	if (crtc->state->event && !crtc->state->active) {

+   WARN_ON(mdp5_crtc->event);
+   spin_lock_irqsave(_kms->dev->event_lock, flags);
+   drm_crtc_send_vblank_event(crtc, crtc->state->event);
+   crtc->state->event = NULL;
+   spin_unlock_irqrestore(_kms->dev->event_lock, flags);
+   }
+
mdp5_crtc->enabled = false;
  }
  



Re: [PATCH v2 4/6] drm/msm: Issue queued events when disabling crtc

2018-04-01 Thread Archit Taneja



On Thursday 29 March 2018 12:36 AM, Sean Paul wrote:

Ensure that any queued events are issued when disabling the crtc. This
avoids timeouts when we come back and wait for dependencies (like the
previous frame's flip_done).


Reviewed-by: Archit Taneja 



Changes in v2:
- None

Signed-off-by: Sean Paul 
---
  drivers/gpu/drm/msm/disp/mdp5/mdp5_crtc.c | 9 +
  1 file changed, 9 insertions(+)

diff --git a/drivers/gpu/drm/msm/disp/mdp5/mdp5_crtc.c 
b/drivers/gpu/drm/msm/disp/mdp5/mdp5_crtc.c
index 76b96081916f..10271359789e 100644
--- a/drivers/gpu/drm/msm/disp/mdp5/mdp5_crtc.c
+++ b/drivers/gpu/drm/msm/disp/mdp5/mdp5_crtc.c
@@ -430,6 +430,7 @@ static void mdp5_crtc_atomic_disable(struct drm_crtc *crtc,
struct mdp5_crtc_state *mdp5_cstate = to_mdp5_crtc_state(crtc->state);
struct mdp5_kms *mdp5_kms = get_kms(crtc);
struct device *dev = _kms->pdev->dev;
+   unsigned long flags;
  
  	DBG("%s", crtc->name);
  
@@ -445,6 +446,14 @@ static void mdp5_crtc_atomic_disable(struct drm_crtc *crtc,

mdp_irq_unregister(_kms->base, _crtc->err);
pm_runtime_put_sync(dev);
  
+	if (crtc->state->event && !crtc->state->active) {

+   WARN_ON(mdp5_crtc->event);
+   spin_lock_irqsave(_kms->dev->event_lock, flags);
+   drm_crtc_send_vblank_event(crtc, crtc->state->event);
+   crtc->state->event = NULL;
+   spin_unlock_irqrestore(_kms->dev->event_lock, flags);
+   }
+
mdp5_crtc->enabled = false;
  }
  



Re: [PATCH v2 3/6] drm/msm: Mark the crtc->state->event consumed

2018-04-01 Thread Archit Taneja



On Thursday 29 March 2018 12:36 AM, Sean Paul wrote:

Don't leave the event != NULL once it's consumed, this is used a signal

s/used a/used as a ?

to the atomic helpers that the event will be handled by the driver.



Reviewed-by: Archit Taneja <arch...@codeaurora.org>


Changes in v2:
- None

Cc: Jeykumar Sankaran <jsa...@codeaurora.org>
Signed-off-by: Sean Paul <seanp...@chromium.org>
---
  drivers/gpu/drm/msm/disp/mdp4/mdp4_crtc.c | 1 +
  drivers/gpu/drm/msm/disp/mdp5/mdp5_crtc.c | 1 +
  2 files changed, 2 insertions(+)

diff --git a/drivers/gpu/drm/msm/disp/mdp4/mdp4_crtc.c 
b/drivers/gpu/drm/msm/disp/mdp4/mdp4_crtc.c
index 6e5e1aa54ce1..b001699297c4 100644
--- a/drivers/gpu/drm/msm/disp/mdp4/mdp4_crtc.c
+++ b/drivers/gpu/drm/msm/disp/mdp4/mdp4_crtc.c
@@ -351,6 +351,7 @@ static void mdp4_crtc_atomic_flush(struct drm_crtc *crtc,
  
  	spin_lock_irqsave(>event_lock, flags);

mdp4_crtc->event = crtc->state->event;
+   crtc->state->event = NULL;
spin_unlock_irqrestore(>event_lock, flags);
  
  	blend_setup(crtc);

diff --git a/drivers/gpu/drm/msm/disp/mdp5/mdp5_crtc.c 
b/drivers/gpu/drm/msm/disp/mdp5/mdp5_crtc.c
index 9893e43ba6c5..76b96081916f 100644
--- a/drivers/gpu/drm/msm/disp/mdp5/mdp5_crtc.c
+++ b/drivers/gpu/drm/msm/disp/mdp5/mdp5_crtc.c
@@ -708,6 +708,7 @@ static void mdp5_crtc_atomic_flush(struct drm_crtc *crtc,
  
  	spin_lock_irqsave(>event_lock, flags);

mdp5_crtc->event = crtc->state->event;
+   crtc->state->event = NULL;
spin_unlock_irqrestore(>event_lock, flags);
  
  	/*




Re: [PATCH v2 3/6] drm/msm: Mark the crtc->state->event consumed

2018-04-01 Thread Archit Taneja



On Thursday 29 March 2018 12:36 AM, Sean Paul wrote:

Don't leave the event != NULL once it's consumed, this is used a signal

s/used a/used as a ?

to the atomic helpers that the event will be handled by the driver.



Reviewed-by: Archit Taneja 


Changes in v2:
- None

Cc: Jeykumar Sankaran 
Signed-off-by: Sean Paul 
---
  drivers/gpu/drm/msm/disp/mdp4/mdp4_crtc.c | 1 +
  drivers/gpu/drm/msm/disp/mdp5/mdp5_crtc.c | 1 +
  2 files changed, 2 insertions(+)

diff --git a/drivers/gpu/drm/msm/disp/mdp4/mdp4_crtc.c 
b/drivers/gpu/drm/msm/disp/mdp4/mdp4_crtc.c
index 6e5e1aa54ce1..b001699297c4 100644
--- a/drivers/gpu/drm/msm/disp/mdp4/mdp4_crtc.c
+++ b/drivers/gpu/drm/msm/disp/mdp4/mdp4_crtc.c
@@ -351,6 +351,7 @@ static void mdp4_crtc_atomic_flush(struct drm_crtc *crtc,
  
  	spin_lock_irqsave(>event_lock, flags);

mdp4_crtc->event = crtc->state->event;
+   crtc->state->event = NULL;
spin_unlock_irqrestore(>event_lock, flags);
  
  	blend_setup(crtc);

diff --git a/drivers/gpu/drm/msm/disp/mdp5/mdp5_crtc.c 
b/drivers/gpu/drm/msm/disp/mdp5/mdp5_crtc.c
index 9893e43ba6c5..76b96081916f 100644
--- a/drivers/gpu/drm/msm/disp/mdp5/mdp5_crtc.c
+++ b/drivers/gpu/drm/msm/disp/mdp5/mdp5_crtc.c
@@ -708,6 +708,7 @@ static void mdp5_crtc_atomic_flush(struct drm_crtc *crtc,
  
  	spin_lock_irqsave(>event_lock, flags);

mdp5_crtc->event = crtc->state->event;
+   crtc->state->event = NULL;
spin_unlock_irqrestore(>event_lock, flags);
  
  	/*




Re: [PATCH v2 2/6] drm/msm: Refactor complete_commit() to look more the helpers

2018-04-01 Thread Archit Taneja



On Thursday 29 March 2018 12:36 AM, Sean Paul wrote:

Factor out the commit_tail() portions of complete_commit() into a
separate function to facilitate moving to the atomic helpers in future
patches.



Reviewed-by: Archit Taneja <arch...@codeaurora.org>


Changes in v2:
- None

Cc: Jeykumar Sankaran <jsa...@codeaurora.org>
Signed-off-by: Sean Paul <seanp...@chromium.org>
---
  drivers/gpu/drm/msm/msm_atomic.c | 25 -
  1 file changed, 16 insertions(+), 9 deletions(-)

diff --git a/drivers/gpu/drm/msm/msm_atomic.c b/drivers/gpu/drm/msm/msm_atomic.c
index e792158676aa..671a18ee977d 100644
--- a/drivers/gpu/drm/msm/msm_atomic.c
+++ b/drivers/gpu/drm/msm/msm_atomic.c
@@ -97,18 +97,12 @@ static void msm_atomic_wait_for_commit_done(struct 
drm_device *dev,
}
  }
  
-/* The (potentially) asynchronous part of the commit.  At this point

- * nothing can fail short of armageddon.
- */
-static void complete_commit(struct msm_commit *c, bool async)
+static void msm_atomic_commit_tail(struct drm_atomic_state *state)
  {
-   struct drm_atomic_state *state = c->state;
struct drm_device *dev = state->dev;
struct msm_drm_private *priv = dev->dev_private;
struct msm_kms *kms = priv->kms;
  
-	drm_atomic_helper_wait_for_fences(dev, state, false);

-
kms->funcs->prepare_commit(kms, state);
  
  	drm_atomic_helper_commit_modeset_disables(dev, state);

@@ -135,6 +129,19 @@ static void complete_commit(struct msm_commit *c, bool 
async)
drm_atomic_helper_cleanup_planes(dev, state);
  
  	kms->funcs->complete_commit(kms, state);

+}
+
+/* The (potentially) asynchronous part of the commit.  At this point
+ * nothing can fail short of armageddon.
+ */
+static void complete_commit(struct msm_commit *c)
+{
+   struct drm_atomic_state *state = c->state;
+   struct drm_device *dev = state->dev;
+
+   drm_atomic_helper_wait_for_fences(dev, state, false);
+
+   msm_atomic_commit_tail(state);
  
  	drm_atomic_state_put(state);
  
@@ -143,7 +150,7 @@ static void complete_commit(struct msm_commit *c, bool async)
  
  static void commit_worker(struct work_struct *work)

  {
-   complete_commit(container_of(work, struct msm_commit, work), true);
+   complete_commit(container_of(work, struct msm_commit, work));
  }
  
  /**

@@ -242,7 +249,7 @@ int msm_atomic_commit(struct drm_device *dev,
return 0;
}
  
-	complete_commit(c, false);

+   complete_commit(c);
  
  	return 0;
  



Re: [PATCH v2 2/6] drm/msm: Refactor complete_commit() to look more the helpers

2018-04-01 Thread Archit Taneja



On Thursday 29 March 2018 12:36 AM, Sean Paul wrote:

Factor out the commit_tail() portions of complete_commit() into a
separate function to facilitate moving to the atomic helpers in future
patches.



Reviewed-by: Archit Taneja 


Changes in v2:
- None

Cc: Jeykumar Sankaran 
Signed-off-by: Sean Paul 
---
  drivers/gpu/drm/msm/msm_atomic.c | 25 -
  1 file changed, 16 insertions(+), 9 deletions(-)

diff --git a/drivers/gpu/drm/msm/msm_atomic.c b/drivers/gpu/drm/msm/msm_atomic.c
index e792158676aa..671a18ee977d 100644
--- a/drivers/gpu/drm/msm/msm_atomic.c
+++ b/drivers/gpu/drm/msm/msm_atomic.c
@@ -97,18 +97,12 @@ static void msm_atomic_wait_for_commit_done(struct 
drm_device *dev,
}
  }
  
-/* The (potentially) asynchronous part of the commit.  At this point

- * nothing can fail short of armageddon.
- */
-static void complete_commit(struct msm_commit *c, bool async)
+static void msm_atomic_commit_tail(struct drm_atomic_state *state)
  {
-   struct drm_atomic_state *state = c->state;
struct drm_device *dev = state->dev;
struct msm_drm_private *priv = dev->dev_private;
struct msm_kms *kms = priv->kms;
  
-	drm_atomic_helper_wait_for_fences(dev, state, false);

-
kms->funcs->prepare_commit(kms, state);
  
  	drm_atomic_helper_commit_modeset_disables(dev, state);

@@ -135,6 +129,19 @@ static void complete_commit(struct msm_commit *c, bool 
async)
drm_atomic_helper_cleanup_planes(dev, state);
  
  	kms->funcs->complete_commit(kms, state);

+}
+
+/* The (potentially) asynchronous part of the commit.  At this point
+ * nothing can fail short of armageddon.
+ */
+static void complete_commit(struct msm_commit *c)
+{
+   struct drm_atomic_state *state = c->state;
+   struct drm_device *dev = state->dev;
+
+   drm_atomic_helper_wait_for_fences(dev, state, false);
+
+   msm_atomic_commit_tail(state);
  
  	drm_atomic_state_put(state);
  
@@ -143,7 +150,7 @@ static void complete_commit(struct msm_commit *c, bool async)
  
  static void commit_worker(struct work_struct *work)

  {
-   complete_commit(container_of(work, struct msm_commit, work), true);
+   complete_commit(container_of(work, struct msm_commit, work));
  }
  
  /**

@@ -242,7 +249,7 @@ int msm_atomic_commit(struct drm_device *dev,
return 0;
}
  
-	complete_commit(c, false);

+   complete_commit(c);
  
  	return 0;
  



Re: [PATCH v2 1/6] drm/msm: Use drm_private_obj/state instead of subclassing

2018-04-01 Thread Archit Taneja



On Thursday 29 March 2018 12:36 AM, Sean Paul wrote:

Now that we have private state handled by the core, we can use those
instead of rolling our own swap_state for private data.

Originally posted here: https://patchwork.freedesktop.org/patch/211361/

Changes in v2:
  - Use state->state in disp duplicate_state callback (Jeykumar)
Changes in v3:
  - Update comment describing msm_kms_state (Jeykumar)
Changes in v4:
  - Rebased on msm-next
  - Don't always use private state from atomic state (Archit)
  - Renamed some of the state accessors
  - Tested on mdp5 db410c
Changes in v5:
  - None

Cc: Jeykumar Sankaran <jsa...@codeaurora.org>
Cc: Archit Taneja <arch...@codeaurora.org>
Signed-off-by: Sean Paul <seanp...@chromium.org>
---
  drivers/gpu/drm/msm/disp/mdp5/mdp5_kms.c   | 77 ++-
  drivers/gpu/drm/msm/disp/mdp5/mdp5_kms.h   | 11 +--
  drivers/gpu/drm/msm/disp/mdp5/mdp5_mixer.c | 12 ++-
  drivers/gpu/drm/msm/disp/mdp5/mdp5_pipe.c  | 28 ---
  drivers/gpu/drm/msm/disp/mdp5/mdp5_smp.c   | 19 +++--
  drivers/gpu/drm/msm/disp/mdp5/mdp5_smp.h   |  4 +-
  drivers/gpu/drm/msm/msm_atomic.c   | 37 -
  drivers/gpu/drm/msm/msm_drv.c  | 87 +-
  drivers/gpu/drm/msm/msm_drv.h  |  3 -
  drivers/gpu/drm/msm/msm_kms.h  | 21 --
  10 files changed, 183 insertions(+), 116 deletions(-)

diff --git a/drivers/gpu/drm/msm/disp/mdp5/mdp5_kms.c 
b/drivers/gpu/drm/msm/disp/mdp5/mdp5_kms.c
index 6d8e3a9a6fc0..366670043190 100644
--- a/drivers/gpu/drm/msm/disp/mdp5/mdp5_kms.c
+++ b/drivers/gpu/drm/msm/disp/mdp5/mdp5_kms.c
@@ -70,60 +70,62 @@ static int mdp5_hw_init(struct msm_kms *kms)
return 0;
  }
  
-struct mdp5_state *mdp5_get_state(struct drm_atomic_state *s)

+struct mdp5_state *mdp5_state_from_atomic(struct drm_atomic_state *state)
  {
-   struct msm_drm_private *priv = s->dev->dev_private;
-   struct mdp5_kms *mdp5_kms = to_mdp5_kms(to_mdp_kms(priv->kms));
-   struct msm_kms_state *state = to_kms_state(s);
-   struct mdp5_state *new_state;
-   int ret;
+   struct msm_kms_state *kms_state = msm_kms_state_from_atomic(state);
  
-	if (state->state)

-   return state->state;
+   if (IS_ERR_OR_NULL(kms_state))
+   return (struct mdp5_state *)kms_state; /* casting ERR_PTR */
  
-	ret = drm_modeset_lock(_kms->state_lock, s->acquire_ctx);

-   if (ret)
-   return ERR_PTR(ret);
+   return kms_state->state;
+}
  
-	new_state = kmalloc(sizeof(*mdp5_kms->state), GFP_KERNEL);

-   if (!new_state)
-   return ERR_PTR(-ENOMEM);
+struct mdp5_state *mdp5_state_from_dev(struct drm_device *dev)
+{
+   struct msm_kms_state *kms_state = msm_kms_state_from_dev(dev);
  
-	/* Copy state: */

-   new_state->hwpipe = mdp5_kms->state->hwpipe;
-   new_state->hwmixer = mdp5_kms->state->hwmixer;
-   if (mdp5_kms->smp)
-   new_state->smp = mdp5_kms->state->smp;
+   if (IS_ERR_OR_NULL(kms_state))
+   return (struct mdp5_state *)kms_state; /* casting ERR_PTR */
  
-	state->state = new_state;

+   return kms_state->state;
+}
+
+static void *mdp5_duplicate_state(void *state)
+{
+   if (!state)
+   return kzalloc(sizeof(struct mdp5_state), GFP_KERNEL);
  
-	return new_state;

+   return kmemdup(state, sizeof(struct mdp5_state), GFP_KERNEL);
  }
  
-static void mdp5_swap_state(struct msm_kms *kms, struct drm_atomic_state *state)

+static void mdp5_destroy_state(void *state)
  {
-   struct mdp5_kms *mdp5_kms = to_mdp5_kms(to_mdp_kms(kms));
-   swap(to_kms_state(state)->state, mdp5_kms->state);
+   struct mdp5_state *mdp_state = (struct mdp5_state *)state;
+   kfree(mdp_state);
  }
  
-static void mdp5_prepare_commit(struct msm_kms *kms, struct drm_atomic_state *state)

+static void mdp5_prepare_commit(struct msm_kms *kms,
+   struct drm_atomic_state *old_state)
  {
struct mdp5_kms *mdp5_kms = to_mdp5_kms(to_mdp_kms(kms));
+   struct mdp5_state *mdp5_state = mdp5_state_from_dev(mdp5_kms->dev);
struct device *dev = _kms->pdev->dev;
  
  	pm_runtime_get_sync(dev);
  
  	if (mdp5_kms->smp)

-   mdp5_smp_prepare_commit(mdp5_kms->smp, _kms->state->smp);
+   mdp5_smp_prepare_commit(mdp5_kms->smp, _state->smp);
  }
  
-static void mdp5_complete_commit(struct msm_kms *kms, struct drm_atomic_state *state)

+static void mdp5_complete_commit(struct msm_kms *kms,
+struct drm_atomic_state *old_state)
  {
struct mdp5_kms *mdp5_kms = to_mdp5_kms(to_mdp_kms(kms));
+   struct mdp5_state *mdp5_state = mdp5_state_from_dev(mdp5_kms->dev);
struct device *dev = _kms->pdev->dev;
  
  	if (mdp5_kms->smp)

-   mdp5_smp_complete_commit(mdp5_kms->smp, _km

Re: [PATCH v2 1/6] drm/msm: Use drm_private_obj/state instead of subclassing

2018-04-01 Thread Archit Taneja



On Thursday 29 March 2018 12:36 AM, Sean Paul wrote:

Now that we have private state handled by the core, we can use those
instead of rolling our own swap_state for private data.

Originally posted here: https://patchwork.freedesktop.org/patch/211361/

Changes in v2:
  - Use state->state in disp duplicate_state callback (Jeykumar)
Changes in v3:
  - Update comment describing msm_kms_state (Jeykumar)
Changes in v4:
  - Rebased on msm-next
  - Don't always use private state from atomic state (Archit)
  - Renamed some of the state accessors
  - Tested on mdp5 db410c
Changes in v5:
  - None

Cc: Jeykumar Sankaran 
Cc: Archit Taneja 
Signed-off-by: Sean Paul 
---
  drivers/gpu/drm/msm/disp/mdp5/mdp5_kms.c   | 77 ++-
  drivers/gpu/drm/msm/disp/mdp5/mdp5_kms.h   | 11 +--
  drivers/gpu/drm/msm/disp/mdp5/mdp5_mixer.c | 12 ++-
  drivers/gpu/drm/msm/disp/mdp5/mdp5_pipe.c  | 28 ---
  drivers/gpu/drm/msm/disp/mdp5/mdp5_smp.c   | 19 +++--
  drivers/gpu/drm/msm/disp/mdp5/mdp5_smp.h   |  4 +-
  drivers/gpu/drm/msm/msm_atomic.c   | 37 -
  drivers/gpu/drm/msm/msm_drv.c  | 87 +-
  drivers/gpu/drm/msm/msm_drv.h  |  3 -
  drivers/gpu/drm/msm/msm_kms.h  | 21 --
  10 files changed, 183 insertions(+), 116 deletions(-)

diff --git a/drivers/gpu/drm/msm/disp/mdp5/mdp5_kms.c 
b/drivers/gpu/drm/msm/disp/mdp5/mdp5_kms.c
index 6d8e3a9a6fc0..366670043190 100644
--- a/drivers/gpu/drm/msm/disp/mdp5/mdp5_kms.c
+++ b/drivers/gpu/drm/msm/disp/mdp5/mdp5_kms.c
@@ -70,60 +70,62 @@ static int mdp5_hw_init(struct msm_kms *kms)
return 0;
  }
  
-struct mdp5_state *mdp5_get_state(struct drm_atomic_state *s)

+struct mdp5_state *mdp5_state_from_atomic(struct drm_atomic_state *state)
  {
-   struct msm_drm_private *priv = s->dev->dev_private;
-   struct mdp5_kms *mdp5_kms = to_mdp5_kms(to_mdp_kms(priv->kms));
-   struct msm_kms_state *state = to_kms_state(s);
-   struct mdp5_state *new_state;
-   int ret;
+   struct msm_kms_state *kms_state = msm_kms_state_from_atomic(state);
  
-	if (state->state)

-   return state->state;
+   if (IS_ERR_OR_NULL(kms_state))
+   return (struct mdp5_state *)kms_state; /* casting ERR_PTR */
  
-	ret = drm_modeset_lock(_kms->state_lock, s->acquire_ctx);

-   if (ret)
-   return ERR_PTR(ret);
+   return kms_state->state;
+}
  
-	new_state = kmalloc(sizeof(*mdp5_kms->state), GFP_KERNEL);

-   if (!new_state)
-   return ERR_PTR(-ENOMEM);
+struct mdp5_state *mdp5_state_from_dev(struct drm_device *dev)
+{
+   struct msm_kms_state *kms_state = msm_kms_state_from_dev(dev);
  
-	/* Copy state: */

-   new_state->hwpipe = mdp5_kms->state->hwpipe;
-   new_state->hwmixer = mdp5_kms->state->hwmixer;
-   if (mdp5_kms->smp)
-   new_state->smp = mdp5_kms->state->smp;
+   if (IS_ERR_OR_NULL(kms_state))
+   return (struct mdp5_state *)kms_state; /* casting ERR_PTR */
  
-	state->state = new_state;

+   return kms_state->state;
+}
+
+static void *mdp5_duplicate_state(void *state)
+{
+   if (!state)
+   return kzalloc(sizeof(struct mdp5_state), GFP_KERNEL);
  
-	return new_state;

+   return kmemdup(state, sizeof(struct mdp5_state), GFP_KERNEL);
  }
  
-static void mdp5_swap_state(struct msm_kms *kms, struct drm_atomic_state *state)

+static void mdp5_destroy_state(void *state)
  {
-   struct mdp5_kms *mdp5_kms = to_mdp5_kms(to_mdp_kms(kms));
-   swap(to_kms_state(state)->state, mdp5_kms->state);
+   struct mdp5_state *mdp_state = (struct mdp5_state *)state;
+   kfree(mdp_state);
  }
  
-static void mdp5_prepare_commit(struct msm_kms *kms, struct drm_atomic_state *state)

+static void mdp5_prepare_commit(struct msm_kms *kms,
+   struct drm_atomic_state *old_state)
  {
struct mdp5_kms *mdp5_kms = to_mdp5_kms(to_mdp_kms(kms));
+   struct mdp5_state *mdp5_state = mdp5_state_from_dev(mdp5_kms->dev);
struct device *dev = _kms->pdev->dev;
  
  	pm_runtime_get_sync(dev);
  
  	if (mdp5_kms->smp)

-   mdp5_smp_prepare_commit(mdp5_kms->smp, _kms->state->smp);
+   mdp5_smp_prepare_commit(mdp5_kms->smp, _state->smp);
  }
  
-static void mdp5_complete_commit(struct msm_kms *kms, struct drm_atomic_state *state)

+static void mdp5_complete_commit(struct msm_kms *kms,
+struct drm_atomic_state *old_state)
  {
struct mdp5_kms *mdp5_kms = to_mdp5_kms(to_mdp_kms(kms));
+   struct mdp5_state *mdp5_state = mdp5_state_from_dev(mdp5_kms->dev);
struct device *dev = _kms->pdev->dev;
  
  	if (mdp5_kms->smp)

-   mdp5_smp_complete_commit(mdp5_kms->smp, _kms->state->smp);
+   mdp5_smp_complete_commit(mdp5_kms-

Re: [PATCH] drm/msm/dsi: use correct enum in dsi_get_cmd_fmt

2018-03-24 Thread Archit Taneja



On Tuesday 20 March 2018 02:56 AM, Stefan Agner wrote:

The function dsi_get_cmd_fmt returns enum dsi_cmd_dst_format,
use the correct enum value also for MIPI_DSI_FMT_RGB666/_PACKED.

This has been discovered using clang:
   drivers/gpu/drm/msm/dsi/dsi_host.c:743:35: warning: implicit conversion
 from enumeration type 'enum dsi_vid_dst_format' to different
 enumeration type 'enum dsi_cmd_dst_format' [-Wenum-conversion]
   case MIPI_DSI_FMT_RGB666:   return VID_DST_FORMAT_RGB666;
   ~~ ^

Signed-off-by: Stefan Agner <ste...@agner.ch>


Reviewed-by: Archit Taneja <arch...@codeaurora.org>

Archit


---
  drivers/gpu/drm/msm/dsi/dsi_host.c | 2 +-
  1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/msm/dsi/dsi_host.c 
b/drivers/gpu/drm/msm/dsi/dsi_host.c
index 0f7324a686ca..d729b2b4b66d 100644
--- a/drivers/gpu/drm/msm/dsi/dsi_host.c
+++ b/drivers/gpu/drm/msm/dsi/dsi_host.c
@@ -740,7 +740,7 @@ static inline enum dsi_cmd_dst_format dsi_get_cmd_fmt(
switch (mipi_fmt) {
case MIPI_DSI_FMT_RGB888:   return CMD_DST_FORMAT_RGB888;
case MIPI_DSI_FMT_RGB666_PACKED:
-   case MIPI_DSI_FMT_RGB666:   return VID_DST_FORMAT_RGB666;
+   case MIPI_DSI_FMT_RGB666:   return CMD_DST_FORMAT_RGB666;
case MIPI_DSI_FMT_RGB565:   return CMD_DST_FORMAT_RGB565;
default:return CMD_DST_FORMAT_RGB888;
}



Re: [PATCH] drm/msm/dsi: use correct enum in dsi_get_cmd_fmt

2018-03-24 Thread Archit Taneja



On Tuesday 20 March 2018 02:56 AM, Stefan Agner wrote:

The function dsi_get_cmd_fmt returns enum dsi_cmd_dst_format,
use the correct enum value also for MIPI_DSI_FMT_RGB666/_PACKED.

This has been discovered using clang:
   drivers/gpu/drm/msm/dsi/dsi_host.c:743:35: warning: implicit conversion
 from enumeration type 'enum dsi_vid_dst_format' to different
 enumeration type 'enum dsi_cmd_dst_format' [-Wenum-conversion]
   case MIPI_DSI_FMT_RGB666:   return VID_DST_FORMAT_RGB666;
   ~~ ^

Signed-off-by: Stefan Agner 


Reviewed-by: Archit Taneja 

Archit


---
  drivers/gpu/drm/msm/dsi/dsi_host.c | 2 +-
  1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/msm/dsi/dsi_host.c 
b/drivers/gpu/drm/msm/dsi/dsi_host.c
index 0f7324a686ca..d729b2b4b66d 100644
--- a/drivers/gpu/drm/msm/dsi/dsi_host.c
+++ b/drivers/gpu/drm/msm/dsi/dsi_host.c
@@ -740,7 +740,7 @@ static inline enum dsi_cmd_dst_format dsi_get_cmd_fmt(
switch (mipi_fmt) {
case MIPI_DSI_FMT_RGB888:   return CMD_DST_FORMAT_RGB888;
case MIPI_DSI_FMT_RGB666_PACKED:
-   case MIPI_DSI_FMT_RGB666:   return VID_DST_FORMAT_RGB666;
+   case MIPI_DSI_FMT_RGB666:   return CMD_DST_FORMAT_RGB666;
case MIPI_DSI_FMT_RGB565:   return CMD_DST_FORMAT_RGB565;
default:return CMD_DST_FORMAT_RGB888;
}



Re: [PATCH 1/2] dt-bindings: analogix-dp: Add backlight-pwm-passthru

2018-03-16 Thread Archit Taneja



On Friday 16 March 2018 08:26 AM, Alexandru M Stan wrote:

Documentation for the optional backlight-pwm-passthru property.
Tells the EDP panel to folow the input pwm frequency instead


s/folow/follow

It would be nice if we could add the details you mentioned in
patch #0 in either this or the next patch.


of generating its own.


This is one of those bindings which is more a knob than a HW property,
but I can't think of any easy way to figure this out in SW. So, I guess
it's okay to have.

One thing I was wondering about was whether this prop should belong to
the eDP controller or the eDP panel. I don't have any strong opinion
about it, though.

Reviewed-by: Archit Taneja <arch...@codeaurora.org>

Thanks,
Archit




Signed-off-by: Alexandru M Stan <ams...@chromium.org>
---

  Documentation/devicetree/bindings/display/bridge/analogix_dp.txt | 4 
  1 file changed, 4 insertions(+)

diff --git a/Documentation/devicetree/bindings/display/bridge/analogix_dp.txt 
b/Documentation/devicetree/bindings/display/bridge/analogix_dp.txt
index 0c7473dd0e51..3c15242f6ce3 100644
--- a/Documentation/devicetree/bindings/display/bridge/analogix_dp.txt
+++ b/Documentation/devicetree/bindings/display/bridge/analogix_dp.txt
@@ -23,6 +23,10 @@ Required properties for dp-controller:
from general PHY binding: Should be "dp".
  
  Optional properties for dp-controller:

+   -backlight-pwm-passthru:
+   Directly pass the PWM frequency applied to the BL_PWM_DIM
+   pin to the backlight current source. Done via
+   EDP_BACKLIGHT_MODE_SET_REGISTER on DPCD.
-force-hpd:
Indicate driver need force hpd when hpd detect failed, this
is used for some eDP screen which don't have hpd signal.



Re: [PATCH 1/2] dt-bindings: analogix-dp: Add backlight-pwm-passthru

2018-03-16 Thread Archit Taneja



On Friday 16 March 2018 08:26 AM, Alexandru M Stan wrote:

Documentation for the optional backlight-pwm-passthru property.
Tells the EDP panel to folow the input pwm frequency instead


s/folow/follow

It would be nice if we could add the details you mentioned in
patch #0 in either this or the next patch.


of generating its own.


This is one of those bindings which is more a knob than a HW property,
but I can't think of any easy way to figure this out in SW. So, I guess
it's okay to have.

One thing I was wondering about was whether this prop should belong to
the eDP controller or the eDP panel. I don't have any strong opinion
about it, though.

Reviewed-by: Archit Taneja 

Thanks,
Archit




Signed-off-by: Alexandru M Stan 
---

  Documentation/devicetree/bindings/display/bridge/analogix_dp.txt | 4 
  1 file changed, 4 insertions(+)

diff --git a/Documentation/devicetree/bindings/display/bridge/analogix_dp.txt 
b/Documentation/devicetree/bindings/display/bridge/analogix_dp.txt
index 0c7473dd0e51..3c15242f6ce3 100644
--- a/Documentation/devicetree/bindings/display/bridge/analogix_dp.txt
+++ b/Documentation/devicetree/bindings/display/bridge/analogix_dp.txt
@@ -23,6 +23,10 @@ Required properties for dp-controller:
from general PHY binding: Should be "dp".
  
  Optional properties for dp-controller:

+   -backlight-pwm-passthru:
+   Directly pass the PWM frequency applied to the BL_PWM_DIM
+   pin to the backlight current source. Done via
+   EDP_BACKLIGHT_MODE_SET_REGISTER on DPCD.
-force-hpd:
Indicate driver need force hpd when hpd detect failed, this
is used for some eDP screen which don't have hpd signal.



Re: [PATCH v5 26/36] drm/bridge: analogix_dp: Properly disable aux chan retries on rockchip

2018-03-14 Thread Archit Taneja



On Saturday 10 March 2018 03:53 AM, Enric Balletbo i Serra wrote:

From: Douglas Anderson <diand...@chromium.org>

The comments in analogix_dp_init_aux() claim that we're disabling aux
channel retries, but then right below it for Rockchip it sets them to
3.  If we actually need 3 retries for Rockchip then we could adjust
the comment, but it seems more likely that we want the same retry
behavior across all platforms.


Reviewed-by: Archit Taneja <arch...@codeaurora.org>

Thanks,
Archit



Cc: Stéphane Marchesin <marc...@chromium.org>
Cc: 征增 王 <w...@rock-chips.com>
Signed-off-by: Douglas Anderson <diand...@chromium.org>
Signed-off-by: Sean Paul <seanp...@chromium.org>
Signed-off-by: Thierry Escande <thierry.esca...@collabora.com>
Signed-off-by: Enric Balletbo i Serra <enric.balle...@collabora.com>
Tested-by: Marek Szyprowski <m.szyprow...@samsung.com>
---

  drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c | 15 ---
  1 file changed, 8 insertions(+), 7 deletions(-)

diff --git a/drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c 
b/drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c
index 58e8a28e99aa..a5f2763d72e4 100644
--- a/drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c
+++ b/drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c
@@ -481,15 +481,16 @@ void analogix_dp_init_aux(struct analogix_dp_device *dp)
  
  	analogix_dp_reset_aux(dp);
  
-	/* Disable AUX transaction H/W retry */

+   /* AUX_BIT_PERIOD_EXPECTED_DELAY doesn't apply to Rockchip IP */
if (dp->plat_data && is_rockchip(dp->plat_data->dev_type))
-   reg = AUX_BIT_PERIOD_EXPECTED_DELAY(0) |
- AUX_HW_RETRY_COUNT_SEL(3) |
- AUX_HW_RETRY_INTERVAL_600_MICROSECONDS;
+   reg = 0;
else
-   reg = AUX_BIT_PERIOD_EXPECTED_DELAY(3) |
- AUX_HW_RETRY_COUNT_SEL(0) |
- AUX_HW_RETRY_INTERVAL_600_MICROSECONDS;
+   reg = AUX_BIT_PERIOD_EXPECTED_DELAY(3);
+
+   /* Disable AUX transaction H/W retry */
+   reg |= AUX_HW_RETRY_COUNT_SEL(0) |
+  AUX_HW_RETRY_INTERVAL_600_MICROSECONDS;
+
writel(reg, dp->reg_base + ANALOGIX_DP_AUX_HW_RETRY_CTL);
  
  	/* Receive AUX Channel DEFER commands equal to DEFFER_COUNT*64 */




Re: [PATCH v5 26/36] drm/bridge: analogix_dp: Properly disable aux chan retries on rockchip

2018-03-14 Thread Archit Taneja



On Saturday 10 March 2018 03:53 AM, Enric Balletbo i Serra wrote:

From: Douglas Anderson 

The comments in analogix_dp_init_aux() claim that we're disabling aux
channel retries, but then right below it for Rockchip it sets them to
3.  If we actually need 3 retries for Rockchip then we could adjust
the comment, but it seems more likely that we want the same retry
behavior across all platforms.


Reviewed-by: Archit Taneja 

Thanks,
Archit



Cc: Stéphane Marchesin 
Cc: 征增 王 
Signed-off-by: Douglas Anderson 
Signed-off-by: Sean Paul 
Signed-off-by: Thierry Escande 
Signed-off-by: Enric Balletbo i Serra 
Tested-by: Marek Szyprowski 
---

  drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c | 15 ---
  1 file changed, 8 insertions(+), 7 deletions(-)

diff --git a/drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c 
b/drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c
index 58e8a28e99aa..a5f2763d72e4 100644
--- a/drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c
+++ b/drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c
@@ -481,15 +481,16 @@ void analogix_dp_init_aux(struct analogix_dp_device *dp)
  
  	analogix_dp_reset_aux(dp);
  
-	/* Disable AUX transaction H/W retry */

+   /* AUX_BIT_PERIOD_EXPECTED_DELAY doesn't apply to Rockchip IP */
if (dp->plat_data && is_rockchip(dp->plat_data->dev_type))
-   reg = AUX_BIT_PERIOD_EXPECTED_DELAY(0) |
- AUX_HW_RETRY_COUNT_SEL(3) |
- AUX_HW_RETRY_INTERVAL_600_MICROSECONDS;
+   reg = 0;
else
-   reg = AUX_BIT_PERIOD_EXPECTED_DELAY(3) |
- AUX_HW_RETRY_COUNT_SEL(0) |
- AUX_HW_RETRY_INTERVAL_600_MICROSECONDS;
+   reg = AUX_BIT_PERIOD_EXPECTED_DELAY(3);
+
+   /* Disable AUX transaction H/W retry */
+   reg |= AUX_HW_RETRY_COUNT_SEL(0) |
+  AUX_HW_RETRY_INTERVAL_600_MICROSECONDS;
+
writel(reg, dp->reg_base + ANALOGIX_DP_AUX_HW_RETRY_CTL);
  
  	/* Receive AUX Channel DEFER commands equal to DEFFER_COUNT*64 */




Re: [PATCH v5 25/36] drm/bridge: analogix_dp: Properly log AUX CH errors

2018-03-14 Thread Archit Taneja



On Saturday 10 March 2018 03:53 AM, Enric Balletbo i Serra wrote:

From: Douglas Anderson <diand...@chromium.org>

The code in analogix_dp_transfer() that was supposed to print out:
   AUX CH error happened

Was actually dead code. That's because the previous check (whether
the interrupt status indicated any errors) would have hit for all
errors anyway.

Let's combine the two error checks so we can actually see AUX CH
errors.  We'll also downgrade the message to a warning since some of
these types of errors might be expected for some displays.  If this
gets too noisy we can downgrade again to debug.


Reviewed-by: Archit Taneja <arch...@codeaurora.org>

Thanks,
Archit



Cc: 征增 王 <w...@rock-chips.com>
Signed-off-by: Douglas Anderson <diand...@chromium.org>
Signed-off-by: Sean Paul <seanp...@chromium.org>
Signed-off-by: Thierry Escande <thierry.esca...@collabora.com>
Reviewed-by: Andrzej Hajda <a.ha...@samsung.com>
Signed-off-by: Enric Balletbo i Serra <enric.balle...@collabora.com>
Tested-by: Marek Szyprowski <m.szyprow...@samsung.com>
---

  drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c | 13 +
  1 file changed, 5 insertions(+), 8 deletions(-)

diff --git a/drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c 
b/drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c
index 4eae206ec31b..58e8a28e99aa 100644
--- a/drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c
+++ b/drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c
@@ -1105,6 +1105,7 @@ ssize_t analogix_dp_transfer(struct analogix_dp_device 
*dp,
 struct drm_dp_aux_msg *msg)
  {
u32 reg;
+   u32 status_reg;
u8 *buffer = msg->buffer;
unsigned int i;
int num_transferred = 0;
@@ -1193,16 +1194,12 @@ ssize_t analogix_dp_transfer(struct analogix_dp_device 
*dp,
  
  	/* Clear interrupt source for AUX CH access error */

reg = readl(dp->reg_base + ANALOGIX_DP_INT_STA);
-   if (reg & AUX_ERR) {
+   status_reg = readl(dp->reg_base + ANALOGIX_DP_AUX_CH_STA);
+   if ((reg & AUX_ERR) || (status_reg & AUX_STATUS_MASK)) {
writel(AUX_ERR, dp->reg_base + ANALOGIX_DP_INT_STA);
-   goto aux_error;
-   }
  
-	/* Check AUX CH error access status */

-   reg = readl(dp->reg_base + ANALOGIX_DP_AUX_CH_STA);
-   if ((reg & AUX_STATUS_MASK)) {
-   dev_err(dp->dev, "AUX CH error happened: %d\n\n",
-   reg & AUX_STATUS_MASK);
+   dev_warn(dp->dev, "AUX CH error happened: %#x (%d)\n",
+status_reg & AUX_STATUS_MASK, !!(reg & AUX_ERR));
goto aux_error;
}
  



Re: [PATCH v5 25/36] drm/bridge: analogix_dp: Properly log AUX CH errors

2018-03-14 Thread Archit Taneja



On Saturday 10 March 2018 03:53 AM, Enric Balletbo i Serra wrote:

From: Douglas Anderson 

The code in analogix_dp_transfer() that was supposed to print out:
   AUX CH error happened

Was actually dead code. That's because the previous check (whether
the interrupt status indicated any errors) would have hit for all
errors anyway.

Let's combine the two error checks so we can actually see AUX CH
errors.  We'll also downgrade the message to a warning since some of
these types of errors might be expected for some displays.  If this
gets too noisy we can downgrade again to debug.


Reviewed-by: Archit Taneja 

Thanks,
Archit



Cc: 征增 王 
Signed-off-by: Douglas Anderson 
Signed-off-by: Sean Paul 
Signed-off-by: Thierry Escande 
Reviewed-by: Andrzej Hajda 
Signed-off-by: Enric Balletbo i Serra 
Tested-by: Marek Szyprowski 
---

  drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c | 13 +
  1 file changed, 5 insertions(+), 8 deletions(-)

diff --git a/drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c 
b/drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c
index 4eae206ec31b..58e8a28e99aa 100644
--- a/drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c
+++ b/drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c
@@ -1105,6 +1105,7 @@ ssize_t analogix_dp_transfer(struct analogix_dp_device 
*dp,
 struct drm_dp_aux_msg *msg)
  {
u32 reg;
+   u32 status_reg;
u8 *buffer = msg->buffer;
unsigned int i;
int num_transferred = 0;
@@ -1193,16 +1194,12 @@ ssize_t analogix_dp_transfer(struct analogix_dp_device 
*dp,
  
  	/* Clear interrupt source for AUX CH access error */

reg = readl(dp->reg_base + ANALOGIX_DP_INT_STA);
-   if (reg & AUX_ERR) {
+   status_reg = readl(dp->reg_base + ANALOGIX_DP_AUX_CH_STA);
+   if ((reg & AUX_ERR) || (status_reg & AUX_STATUS_MASK)) {
writel(AUX_ERR, dp->reg_base + ANALOGIX_DP_INT_STA);
-   goto aux_error;
-   }
  
-	/* Check AUX CH error access status */

-   reg = readl(dp->reg_base + ANALOGIX_DP_AUX_CH_STA);
-   if ((reg & AUX_STATUS_MASK)) {
-   dev_err(dp->dev, "AUX CH error happened: %d\n\n",
-   reg & AUX_STATUS_MASK);
+   dev_warn(dp->dev, "AUX CH error happened: %#x (%d)\n",
+status_reg & AUX_STATUS_MASK, !!(reg & AUX_ERR));
goto aux_error;
}
  



Re: [PATCH v5 23/36] drm/bridge: analogix_dp: Move fast link training detect to set_bridge

2018-03-14 Thread Archit Taneja



On Saturday 10 March 2018 03:53 AM, Enric Balletbo i Serra wrote:

From: zain wang 

It's too early to detect fast link training, if other step after it
failed, we will set fast_link flag to 1, and retry set_bridge again. In
this case we will power down and power up panel power supply, and we
will do fast link training since we have set fast_link flag to 1. In
fact, we should do full link training now, not the fast link training.
So we should move the fast link detection at the end of set_bridge.


Is it possible to re-write this commit message? It's a bit hard to
follow.

Thanks,
Archit



Cc: Tomasz Figa 
Signed-off-by: zain wang 
Signed-off-by: Douglas Anderson 
Signed-off-by: Sean Paul 
Signed-off-by: Thierry Escande 
Reviewed-by: Andrzej Hajda 
Signed-off-by: Enric Balletbo i Serra 
Tested-by: Marek Szyprowski 
---

  drivers/gpu/drm/bridge/analogix/analogix_dp_core.c | 42 +-
  1 file changed, 26 insertions(+), 16 deletions(-)

diff --git a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c 
b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
index d76e1652b1fd..37b16643f14c 100644
--- a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
+++ b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
@@ -601,7 +601,7 @@ static int analogix_dp_process_equalizer_training(struct 
analogix_dp_device *dp)
  {
int lane, lane_count, retval;
u32 reg;
-   u8 link_align, link_status[2], adjust_request[2], spread;
+   u8 link_align, link_status[2], adjust_request[2];
  
  	usleep_range(400, 401);
  
@@ -645,20 +645,6 @@ static int analogix_dp_process_equalizer_training(struct analogix_dp_device *dp)

dev_dbg(dp->dev, "final lane count = %.2x\n",
dp->link_train.lane_count);
  
-		retval = drm_dp_dpcd_readb(>aux, DP_MAX_DOWNSPREAD,

-  );
-   if (retval != 1) {
-   dev_err(dp->dev, "failed to read downspread %d\n",
-   retval);
-   dp->fast_train_enable = false;
-   } else {
-   dp->fast_train_enable =
-   (spread & DP_NO_AUX_HANDSHAKE_LINK_TRAINING) ?
-   true : false;
-   }
-   dev_dbg(dp->dev, "fast link training %s\n",
-   dp->fast_train_enable ? "supported" : "unsupported");
-
dp->link_train.lt_state = FINISHED;
  
  		return 0;

@@ -996,6 +982,22 @@ static irqreturn_t analogix_dp_irq_thread(int irq, void 
*arg)
return IRQ_HANDLED;
  }
  
+static int analogix_dp_fast_link_train_detection(struct analogix_dp_device *dp)

+{
+   int ret;
+   u8 spread;
+
+   ret = drm_dp_dpcd_readb(>aux, DP_MAX_DOWNSPREAD, );
+   if (ret != 1) {
+   dev_err(dp->dev, "failed to read downspread %d\n", ret);
+   return ret;
+   }
+   dp->fast_train_enable = !!(spread & DP_NO_AUX_HANDSHAKE_LINK_TRAINING);
+   dev_dbg(dp->dev, "fast link training %s\n",
+   dp->fast_train_enable ? "supported" : "unsupported");
+   return 0;
+}
+
  static int analogix_dp_commit(struct analogix_dp_device *dp)
  {
int ret;
@@ -1038,8 +1040,16 @@ static int analogix_dp_commit(struct analogix_dp_device 
*dp)
if (ret)
return ret;
  
-	if (dp->psr_enable)

+   if (dp->psr_enable) {
ret = analogix_dp_enable_sink_psr(dp);
+   if (ret)
+   return ret;
+   }
+
+   /* Check whether panel supports fast training */
+   ret =  analogix_dp_fast_link_train_detection(dp);
+   if (ret)
+   dp->psr_enable = false;
  
  	return ret;

  }



Re: [PATCH v5 23/36] drm/bridge: analogix_dp: Move fast link training detect to set_bridge

2018-03-14 Thread Archit Taneja



On Saturday 10 March 2018 03:53 AM, Enric Balletbo i Serra wrote:

From: zain wang 

It's too early to detect fast link training, if other step after it
failed, we will set fast_link flag to 1, and retry set_bridge again. In
this case we will power down and power up panel power supply, and we
will do fast link training since we have set fast_link flag to 1. In
fact, we should do full link training now, not the fast link training.
So we should move the fast link detection at the end of set_bridge.


Is it possible to re-write this commit message? It's a bit hard to
follow.

Thanks,
Archit



Cc: Tomasz Figa 
Signed-off-by: zain wang 
Signed-off-by: Douglas Anderson 
Signed-off-by: Sean Paul 
Signed-off-by: Thierry Escande 
Reviewed-by: Andrzej Hajda 
Signed-off-by: Enric Balletbo i Serra 
Tested-by: Marek Szyprowski 
---

  drivers/gpu/drm/bridge/analogix/analogix_dp_core.c | 42 +-
  1 file changed, 26 insertions(+), 16 deletions(-)

diff --git a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c 
b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
index d76e1652b1fd..37b16643f14c 100644
--- a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
+++ b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
@@ -601,7 +601,7 @@ static int analogix_dp_process_equalizer_training(struct 
analogix_dp_device *dp)
  {
int lane, lane_count, retval;
u32 reg;
-   u8 link_align, link_status[2], adjust_request[2], spread;
+   u8 link_align, link_status[2], adjust_request[2];
  
  	usleep_range(400, 401);
  
@@ -645,20 +645,6 @@ static int analogix_dp_process_equalizer_training(struct analogix_dp_device *dp)

dev_dbg(dp->dev, "final lane count = %.2x\n",
dp->link_train.lane_count);
  
-		retval = drm_dp_dpcd_readb(>aux, DP_MAX_DOWNSPREAD,

-  );
-   if (retval != 1) {
-   dev_err(dp->dev, "failed to read downspread %d\n",
-   retval);
-   dp->fast_train_enable = false;
-   } else {
-   dp->fast_train_enable =
-   (spread & DP_NO_AUX_HANDSHAKE_LINK_TRAINING) ?
-   true : false;
-   }
-   dev_dbg(dp->dev, "fast link training %s\n",
-   dp->fast_train_enable ? "supported" : "unsupported");
-
dp->link_train.lt_state = FINISHED;
  
  		return 0;

@@ -996,6 +982,22 @@ static irqreturn_t analogix_dp_irq_thread(int irq, void 
*arg)
return IRQ_HANDLED;
  }
  
+static int analogix_dp_fast_link_train_detection(struct analogix_dp_device *dp)

+{
+   int ret;
+   u8 spread;
+
+   ret = drm_dp_dpcd_readb(>aux, DP_MAX_DOWNSPREAD, );
+   if (ret != 1) {
+   dev_err(dp->dev, "failed to read downspread %d\n", ret);
+   return ret;
+   }
+   dp->fast_train_enable = !!(spread & DP_NO_AUX_HANDSHAKE_LINK_TRAINING);
+   dev_dbg(dp->dev, "fast link training %s\n",
+   dp->fast_train_enable ? "supported" : "unsupported");
+   return 0;
+}
+
  static int analogix_dp_commit(struct analogix_dp_device *dp)
  {
int ret;
@@ -1038,8 +1040,16 @@ static int analogix_dp_commit(struct analogix_dp_device 
*dp)
if (ret)
return ret;
  
-	if (dp->psr_enable)

+   if (dp->psr_enable) {
ret = analogix_dp_enable_sink_psr(dp);
+   if (ret)
+   return ret;
+   }
+
+   /* Check whether panel supports fast training */
+   ret =  analogix_dp_fast_link_train_detection(dp);
+   if (ret)
+   dp->psr_enable = false;
  
  	return ret;

  }



Re: [PATCH v5 24/36] drm/bridge: analogix_dp: Reorder plat_data->power_off to happen sooner

2018-03-14 Thread Archit Taneja



On Saturday 10 March 2018 03:53 AM, Enric Balletbo i Serra wrote:

From: Douglas Anderson <diand...@chromium.org>

The current user of the analogix power_off is "analogix_dp-rockchip".
That driver does this:
- deactivate PSR
- turn off a clock

Both of these things (especially deactive PSR) should be done before
we turn the PHY power off and turn off analog power.  Let's move the
callback up.

Note that without this patch (and with
https://patchwork.kernel.org/patch/9553349/ [seanpaul: this patch was
not applied, but it seems like the race can still occur]), I experienced
an error in reboot testing where one thread was at:

   rockchip_drm_psr_deactivate
   rockchip_dp_powerdown
   analogix_dp_bridge_disable
   drm_bridge_disable

...and the other thread was at:

   analogix_dp_send_psr_spd
   analogix_dp_enable_psr
   analogix_dp_psr_set
   psr_flush_handler

The flush handler thread was finding AUX channel errors and eventually
reported "Failed to apply PSR", where I had a kgdb breakpoint. Presumably
the device would have eventually given up and shut down anyway, but it
seems better to fix the order to be more correct.



Reviewed-by: Archit Taneja <arch...@codeaurora.org>

Thanks,
Archit


Cc: Kristian H. Kristensen <hoegsb...@chromium.org>
Signed-off-by: Douglas Anderson <diand...@chromium.org>
Signed-off-by: Sean Paul <seanp...@chromium.org>
Signed-off-by: Thierry Escande <thierry.esca...@collabora.com>
Reviewed-by: Andrzej Hajda <a.ha...@samsung.com>
Signed-off-by: Enric Balletbo i Serra <enric.balle...@collabora.com>
Tested-by: Marek Szyprowski <m.szyprow...@samsung.com>
---

  drivers/gpu/drm/bridge/analogix/analogix_dp_core.c | 5 +++--
  1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c 
b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
index 37b16643f14c..eaf93cbd47a8 100644
--- a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
+++ b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
@@ -1337,12 +1337,13 @@ static void analogix_dp_bridge_disable(struct 
drm_bridge *bridge)
}
  
  	disable_irq(dp->irq);

-   analogix_dp_set_analog_power_down(dp, POWER_ALL, 1);
-   phy_power_off(dp->phy);
  
  	if (dp->plat_data->power_off)

dp->plat_data->power_off(dp->plat_data);
  
+	analogix_dp_set_analog_power_down(dp, POWER_ALL, 1);

+   phy_power_off(dp->phy);
+
clk_disable_unprepare(dp->clock);
  
  	pm_runtime_put_sync(dp->dev);




Re: [PATCH v5 24/36] drm/bridge: analogix_dp: Reorder plat_data->power_off to happen sooner

2018-03-14 Thread Archit Taneja



On Saturday 10 March 2018 03:53 AM, Enric Balletbo i Serra wrote:

From: Douglas Anderson 

The current user of the analogix power_off is "analogix_dp-rockchip".
That driver does this:
- deactivate PSR
- turn off a clock

Both of these things (especially deactive PSR) should be done before
we turn the PHY power off and turn off analog power.  Let's move the
callback up.

Note that without this patch (and with
https://patchwork.kernel.org/patch/9553349/ [seanpaul: this patch was
not applied, but it seems like the race can still occur]), I experienced
an error in reboot testing where one thread was at:

   rockchip_drm_psr_deactivate
   rockchip_dp_powerdown
   analogix_dp_bridge_disable
   drm_bridge_disable

...and the other thread was at:

   analogix_dp_send_psr_spd
   analogix_dp_enable_psr
   analogix_dp_psr_set
   psr_flush_handler

The flush handler thread was finding AUX channel errors and eventually
reported "Failed to apply PSR", where I had a kgdb breakpoint. Presumably
the device would have eventually given up and shut down anyway, but it
seems better to fix the order to be more correct.



Reviewed-by: Archit Taneja 

Thanks,
Archit


Cc: Kristian H. Kristensen 
Signed-off-by: Douglas Anderson 
Signed-off-by: Sean Paul 
Signed-off-by: Thierry Escande 
Reviewed-by: Andrzej Hajda 
Signed-off-by: Enric Balletbo i Serra 
Tested-by: Marek Szyprowski 
---

  drivers/gpu/drm/bridge/analogix/analogix_dp_core.c | 5 +++--
  1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c 
b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
index 37b16643f14c..eaf93cbd47a8 100644
--- a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
+++ b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
@@ -1337,12 +1337,13 @@ static void analogix_dp_bridge_disable(struct 
drm_bridge *bridge)
}
  
  	disable_irq(dp->irq);

-   analogix_dp_set_analog_power_down(dp, POWER_ALL, 1);
-   phy_power_off(dp->phy);
  
  	if (dp->plat_data->power_off)

dp->plat_data->power_off(dp->plat_data);
  
+	analogix_dp_set_analog_power_down(dp, POWER_ALL, 1);

+   phy_power_off(dp->phy);
+
clk_disable_unprepare(dp->clock);
  
  	pm_runtime_put_sync(dp->dev);




Re: [PATCH v5 22/36] drm/bridge: analogix_dp: Fix incorrect operations with register ANALOGIX_DP_FUNC_EN_1

2018-03-14 Thread Archit Taneja



On Saturday 10 March 2018 03:53 AM, Enric Balletbo i Serra wrote:

From: zain wang <w...@rock-chips.com>

Register ANALOGIX_DP_FUNC_EN_1(offset 0x18), Rockchip is different to
Exynos:

on Exynos edp phy,
BIT 7   MASTER_VID_FUNC_EN_N
BIT 6   reserved
BIT 5   SLAVE_VID_FUNC_EN_N

on Rockchip edp phy,
BIT 7   reserved
BIT 6   RK_VID_CAP_FUNC_EN_N
BIT 5   RK_VID_FIFO_FUNC_EN_N

So, we should do some private operations to Rockchip.


Reviewed-by: Archit Taneja <arch...@codeaurora.org>

Thanks,
Archit



Cc: Tomasz Figa <tf...@chromium.org>
Signed-off-by: zain wang <w...@rock-chips.com>
Signed-off-by: Sean Paul <seanp...@chromium.org>
Signed-off-by: Thierry Escande <thierry.esca...@collabora.com>
Reviewed-by: Andrzej Hajda <a.ha...@samsung.com>
Signed-off-by: Enric Balletbo i Serra <enric.balle...@collabora.com>
Tested-by: Marek Szyprowski <m.szyprow...@samsung.com>
---

  drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c | 19 ++-
  drivers/gpu/drm/bridge/analogix/analogix_dp_reg.h |  2 ++
  2 files changed, 16 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c 
b/drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c
index 02ab1aaa9993..4eae206ec31b 100644
--- a/drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c
+++ b/drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c
@@ -126,9 +126,14 @@ void analogix_dp_reset(struct analogix_dp_device *dp)
analogix_dp_stop_video(dp);
analogix_dp_enable_video_mute(dp, 0);
  
-	reg = MASTER_VID_FUNC_EN_N | SLAVE_VID_FUNC_EN_N |

-   AUD_FIFO_FUNC_EN_N | AUD_FUNC_EN_N |
-   HDCP_FUNC_EN_N | SW_FUNC_EN_N;
+   if (dp->plat_data && is_rockchip(dp->plat_data->dev_type))
+   reg = RK_VID_CAP_FUNC_EN_N | RK_VID_FIFO_FUNC_EN_N |
+   SW_FUNC_EN_N;
+   else
+   reg = MASTER_VID_FUNC_EN_N | SLAVE_VID_FUNC_EN_N |
+   AUD_FIFO_FUNC_EN_N | AUD_FUNC_EN_N |
+   HDCP_FUNC_EN_N | SW_FUNC_EN_N;
+
writel(reg, dp->reg_base + ANALOGIX_DP_FUNC_EN_1);
  
  	reg = SSC_FUNC_EN_N | AUX_FUNC_EN_N |

@@ -971,8 +976,12 @@ void analogix_dp_config_video_slave_mode(struct 
analogix_dp_device *dp)
u32 reg;
  
  	reg = readl(dp->reg_base + ANALOGIX_DP_FUNC_EN_1);

-   reg &= ~(MASTER_VID_FUNC_EN_N | SLAVE_VID_FUNC_EN_N);
-   reg |= MASTER_VID_FUNC_EN_N;
+   if (dp->plat_data && is_rockchip(dp->plat_data->dev_type)) {
+   reg &= ~(RK_VID_CAP_FUNC_EN_N | RK_VID_FIFO_FUNC_EN_N);
+   } else {
+   reg &= ~(MASTER_VID_FUNC_EN_N | SLAVE_VID_FUNC_EN_N);
+   reg |= MASTER_VID_FUNC_EN_N;
+   }
writel(reg, dp->reg_base + ANALOGIX_DP_FUNC_EN_1);
  
  	reg = readl(dp->reg_base + ANALOGIX_DP_VIDEO_CTL_10);

diff --git a/drivers/gpu/drm/bridge/analogix/analogix_dp_reg.h 
b/drivers/gpu/drm/bridge/analogix/analogix_dp_reg.h
index b633a4a5082a..0cf27c731727 100644
--- a/drivers/gpu/drm/bridge/analogix/analogix_dp_reg.h
+++ b/drivers/gpu/drm/bridge/analogix/analogix_dp_reg.h
@@ -127,7 +127,9 @@
  
  /* ANALOGIX_DP_FUNC_EN_1 */

  #define MASTER_VID_FUNC_EN_N  (0x1 << 7)
+#define RK_VID_CAP_FUNC_EN_N   (0x1 << 6)
  #define SLAVE_VID_FUNC_EN_N   (0x1 << 5)
+#define RK_VID_FIFO_FUNC_EN_N  (0x1 << 5)
  #define AUD_FIFO_FUNC_EN_N(0x1 << 4)
  #define AUD_FUNC_EN_N (0x1 << 3)
  #define HDCP_FUNC_EN_N(0x1 << 2)



Re: [PATCH v5 22/36] drm/bridge: analogix_dp: Fix incorrect operations with register ANALOGIX_DP_FUNC_EN_1

2018-03-14 Thread Archit Taneja



On Saturday 10 March 2018 03:53 AM, Enric Balletbo i Serra wrote:

From: zain wang 

Register ANALOGIX_DP_FUNC_EN_1(offset 0x18), Rockchip is different to
Exynos:

on Exynos edp phy,
BIT 7   MASTER_VID_FUNC_EN_N
BIT 6   reserved
BIT 5   SLAVE_VID_FUNC_EN_N

on Rockchip edp phy,
BIT 7   reserved
BIT 6   RK_VID_CAP_FUNC_EN_N
BIT 5   RK_VID_FIFO_FUNC_EN_N

So, we should do some private operations to Rockchip.


Reviewed-by: Archit Taneja 

Thanks,
Archit



Cc: Tomasz Figa 
Signed-off-by: zain wang 
Signed-off-by: Sean Paul 
Signed-off-by: Thierry Escande 
Reviewed-by: Andrzej Hajda 
Signed-off-by: Enric Balletbo i Serra 
Tested-by: Marek Szyprowski 
---

  drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c | 19 ++-
  drivers/gpu/drm/bridge/analogix/analogix_dp_reg.h |  2 ++
  2 files changed, 16 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c 
b/drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c
index 02ab1aaa9993..4eae206ec31b 100644
--- a/drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c
+++ b/drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c
@@ -126,9 +126,14 @@ void analogix_dp_reset(struct analogix_dp_device *dp)
analogix_dp_stop_video(dp);
analogix_dp_enable_video_mute(dp, 0);
  
-	reg = MASTER_VID_FUNC_EN_N | SLAVE_VID_FUNC_EN_N |

-   AUD_FIFO_FUNC_EN_N | AUD_FUNC_EN_N |
-   HDCP_FUNC_EN_N | SW_FUNC_EN_N;
+   if (dp->plat_data && is_rockchip(dp->plat_data->dev_type))
+   reg = RK_VID_CAP_FUNC_EN_N | RK_VID_FIFO_FUNC_EN_N |
+   SW_FUNC_EN_N;
+   else
+   reg = MASTER_VID_FUNC_EN_N | SLAVE_VID_FUNC_EN_N |
+   AUD_FIFO_FUNC_EN_N | AUD_FUNC_EN_N |
+   HDCP_FUNC_EN_N | SW_FUNC_EN_N;
+
writel(reg, dp->reg_base + ANALOGIX_DP_FUNC_EN_1);
  
  	reg = SSC_FUNC_EN_N | AUX_FUNC_EN_N |

@@ -971,8 +976,12 @@ void analogix_dp_config_video_slave_mode(struct 
analogix_dp_device *dp)
u32 reg;
  
  	reg = readl(dp->reg_base + ANALOGIX_DP_FUNC_EN_1);

-   reg &= ~(MASTER_VID_FUNC_EN_N | SLAVE_VID_FUNC_EN_N);
-   reg |= MASTER_VID_FUNC_EN_N;
+   if (dp->plat_data && is_rockchip(dp->plat_data->dev_type)) {
+   reg &= ~(RK_VID_CAP_FUNC_EN_N | RK_VID_FIFO_FUNC_EN_N);
+   } else {
+   reg &= ~(MASTER_VID_FUNC_EN_N | SLAVE_VID_FUNC_EN_N);
+   reg |= MASTER_VID_FUNC_EN_N;
+   }
writel(reg, dp->reg_base + ANALOGIX_DP_FUNC_EN_1);
  
  	reg = readl(dp->reg_base + ANALOGIX_DP_VIDEO_CTL_10);

diff --git a/drivers/gpu/drm/bridge/analogix/analogix_dp_reg.h 
b/drivers/gpu/drm/bridge/analogix/analogix_dp_reg.h
index b633a4a5082a..0cf27c731727 100644
--- a/drivers/gpu/drm/bridge/analogix/analogix_dp_reg.h
+++ b/drivers/gpu/drm/bridge/analogix/analogix_dp_reg.h
@@ -127,7 +127,9 @@
  
  /* ANALOGIX_DP_FUNC_EN_1 */

  #define MASTER_VID_FUNC_EN_N  (0x1 << 7)
+#define RK_VID_CAP_FUNC_EN_N   (0x1 << 6)
  #define SLAVE_VID_FUNC_EN_N   (0x1 << 5)
+#define RK_VID_FIFO_FUNC_EN_N  (0x1 << 5)
  #define AUD_FIFO_FUNC_EN_N(0x1 << 4)
  #define AUD_FUNC_EN_N (0x1 << 3)
  #define HDCP_FUNC_EN_N(0x1 << 2)



Re: [PATCH v5 20/36] drm/bridge: analogix_dp: Don't use ANALOGIX_DP_PLL_CTL to control pll

2018-03-14 Thread Archit Taneja



On Saturday 10 March 2018 03:53 AM, Enric Balletbo i Serra wrote:

From: zain wang <w...@rock-chips.com>

There is no register named ANALOGIX_DP_PLL_CTL in Rockchip edp phy reg
list.  We should use BIT_4 in ANALOGIX_DP_PD to control the pll power
instead of ANALOGIX_DP_PLL_CTL.



Reviewed-by: Archit Taneja <arch...@codeaurora.org>

Thanks,
Archit


Cc: Douglas Anderson <diand...@chromium.org>
Signed-off-by: zain wang <w...@rock-chips.com>
Signed-off-by: Sean Paul <seanp...@chromium.org>
Signed-off-by: Thierry Escande <thierry.esca...@collabora.com>
Reviewed-by: Andrzej Hajda <a.ha...@samsung.com>
Signed-off-by: Enric Balletbo i Serra <enric.balle...@collabora.com>
Tested-by: Marek Szyprowski <m.szyprow...@samsung.com>
---

  drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c | 20 
  1 file changed, 12 insertions(+), 8 deletions(-)

diff --git a/drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c 
b/drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c
index 7b7fd227e1f9..02ab1aaa9993 100644
--- a/drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c
+++ b/drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c
@@ -230,16 +230,20 @@ enum pll_status analogix_dp_get_pll_lock_status(struct 
analogix_dp_device *dp)
  void analogix_dp_set_pll_power_down(struct analogix_dp_device *dp, bool 
enable)
  {
u32 reg;
+   u32 mask = DP_PLL_PD;
+   u32 pd_addr = ANALOGIX_DP_PLL_CTL;
  
-	if (enable) {

-   reg = readl(dp->reg_base + ANALOGIX_DP_PLL_CTL);
-   reg |= DP_PLL_PD;
-   writel(reg, dp->reg_base + ANALOGIX_DP_PLL_CTL);
-   } else {
-   reg = readl(dp->reg_base + ANALOGIX_DP_PLL_CTL);
-   reg &= ~DP_PLL_PD;
-   writel(reg, dp->reg_base + ANALOGIX_DP_PLL_CTL);
+   if (dp->plat_data && is_rockchip(dp->plat_data->dev_type)) {
+   pd_addr = ANALOGIX_DP_PD;
+   mask = RK_PLL_PD;
}
+
+   reg = readl(dp->reg_base + pd_addr);
+   if (enable)
+   reg |= mask;
+   else
+   reg &= ~mask;
+   writel(reg, dp->reg_base + pd_addr);
  }
  
  void analogix_dp_set_analog_power_down(struct analogix_dp_device *dp,




Re: [PATCH v5 20/36] drm/bridge: analogix_dp: Don't use ANALOGIX_DP_PLL_CTL to control pll

2018-03-14 Thread Archit Taneja



On Saturday 10 March 2018 03:53 AM, Enric Balletbo i Serra wrote:

From: zain wang 

There is no register named ANALOGIX_DP_PLL_CTL in Rockchip edp phy reg
list.  We should use BIT_4 in ANALOGIX_DP_PD to control the pll power
instead of ANALOGIX_DP_PLL_CTL.



Reviewed-by: Archit Taneja 

Thanks,
Archit


Cc: Douglas Anderson 
Signed-off-by: zain wang 
Signed-off-by: Sean Paul 
Signed-off-by: Thierry Escande 
Reviewed-by: Andrzej Hajda 
Signed-off-by: Enric Balletbo i Serra 
Tested-by: Marek Szyprowski 
---

  drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c | 20 
  1 file changed, 12 insertions(+), 8 deletions(-)

diff --git a/drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c 
b/drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c
index 7b7fd227e1f9..02ab1aaa9993 100644
--- a/drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c
+++ b/drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c
@@ -230,16 +230,20 @@ enum pll_status analogix_dp_get_pll_lock_status(struct 
analogix_dp_device *dp)
  void analogix_dp_set_pll_power_down(struct analogix_dp_device *dp, bool 
enable)
  {
u32 reg;
+   u32 mask = DP_PLL_PD;
+   u32 pd_addr = ANALOGIX_DP_PLL_CTL;
  
-	if (enable) {

-   reg = readl(dp->reg_base + ANALOGIX_DP_PLL_CTL);
-   reg |= DP_PLL_PD;
-   writel(reg, dp->reg_base + ANALOGIX_DP_PLL_CTL);
-   } else {
-   reg = readl(dp->reg_base + ANALOGIX_DP_PLL_CTL);
-   reg &= ~DP_PLL_PD;
-   writel(reg, dp->reg_base + ANALOGIX_DP_PLL_CTL);
+   if (dp->plat_data && is_rockchip(dp->plat_data->dev_type)) {
+   pd_addr = ANALOGIX_DP_PD;
+   mask = RK_PLL_PD;
}
+
+   reg = readl(dp->reg_base + pd_addr);
+   if (enable)
+   reg |= mask;
+   else
+   reg &= ~mask;
+   writel(reg, dp->reg_base + pd_addr);
  }
  
  void analogix_dp_set_analog_power_down(struct analogix_dp_device *dp,




Re: [PATCH v5 21/36] drm/bridge: analogix_dp: Fix timeout of video streamclk config

2018-03-14 Thread Archit Taneja



On Saturday 10 March 2018 03:53 AM, Enric Balletbo i Serra wrote:

From: zain wang <w...@rock-chips.com>

The STRM_VALID bit in register ANALOGIX_DP_SYS_CTL_3 may be unstable,
so we may hit the error log "Timeout of video streamclk ok" since
checked this unstable bit.
In fact, we can go continue and the streamclk is ok if we wait enough time,
it does no effect on display.
Let's change this error to warn.


Reviewed-by: Archit Taneja <arch...@codeaurora.org>

Thanks,
Archit



Cc: Douglas Anderson <diand...@chromium.org>
Signed-off-by: zain wang <w...@rock-chips.com>
Signed-off-by: Sean Paul <seanp...@chromium.org>
Signed-off-by: Thierry Escande <thierry.esca...@collabora.com>
Reviewed-by: Andrzej Hajda <a.ha...@samsung.com>
Signed-off-by: Enric Balletbo i Serra <enric.balle...@collabora.com>
Tested-by: Marek Szyprowski <m.szyprow...@samsung.com>
---

  drivers/gpu/drm/bridge/analogix/analogix_dp_core.c | 5 +++--
  1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c 
b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
index 1f1cb624414d..d76e1652b1fd 100644
--- a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
+++ b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
@@ -921,8 +921,9 @@ static int analogix_dp_config_video(struct 
analogix_dp_device *dp)
done_count = 0;
}
if (timeout_loop > DP_TIMEOUT_LOOP_COUNT) {
-   dev_err(dp->dev, "Timeout of video streamclk ok\n");
-   return -ETIMEDOUT;
+   dev_warn(dp->dev,
+"Ignoring timeout of video streamclk ok\n");
+   break;
}
  
  		usleep_range(1000, 1001);




Re: [PATCH v5 21/36] drm/bridge: analogix_dp: Fix timeout of video streamclk config

2018-03-14 Thread Archit Taneja



On Saturday 10 March 2018 03:53 AM, Enric Balletbo i Serra wrote:

From: zain wang 

The STRM_VALID bit in register ANALOGIX_DP_SYS_CTL_3 may be unstable,
so we may hit the error log "Timeout of video streamclk ok" since
checked this unstable bit.
In fact, we can go continue and the streamclk is ok if we wait enough time,
it does no effect on display.
Let's change this error to warn.


Reviewed-by: Archit Taneja 

Thanks,
Archit



Cc: Douglas Anderson 
Signed-off-by: zain wang 
Signed-off-by: Sean Paul 
Signed-off-by: Thierry Escande 
Reviewed-by: Andrzej Hajda 
Signed-off-by: Enric Balletbo i Serra 
Tested-by: Marek Szyprowski 
---

  drivers/gpu/drm/bridge/analogix/analogix_dp_core.c | 5 +++--
  1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c 
b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
index 1f1cb624414d..d76e1652b1fd 100644
--- a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
+++ b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
@@ -921,8 +921,9 @@ static int analogix_dp_config_video(struct 
analogix_dp_device *dp)
done_count = 0;
}
if (timeout_loop > DP_TIMEOUT_LOOP_COUNT) {
-   dev_err(dp->dev, "Timeout of video streamclk ok\n");
-   return -ETIMEDOUT;
+   dev_warn(dp->dev,
+"Ignoring timeout of video streamclk ok\n");
+   break;
}
  
  		usleep_range(1000, 1001);




Re: [PATCH v5 19/36] drm/rockchip: Restore psr->state when enable/disable psr failed

2018-03-14 Thread Archit Taneja



On Saturday 10 March 2018 03:53 AM, Enric Balletbo i Serra wrote:

From: zain wang <w...@rock-chips.com>

If we failed disable psr, it would hang the display until next psr
cycle coming. So we should restore psr->state when it failed.



For the bridge part,

Reviewed-by: Archit Taneja <arch...@codeaurora.org>

Thanks,
Archit


Cc: Tomasz Figa <tf...@chromium.org>
Signed-off-by: zain wang <w...@rock-chips.com>
Signed-off-by: Douglas Anderson <diand...@chromium.org>
Signed-off-by: Sean Paul <seanp...@chromium.org>
Signed-off-by: Thierry Escande <thierry.esca...@collabora.com>
Signed-off-by: Enric Balletbo i Serra <enric.balle...@collabora.com>
Tested-by: Marek Szyprowski <m.szyprow...@samsung.com>
---

  drivers/gpu/drm/bridge/analogix/analogix_dp_core.c |  4 +++-
  drivers/gpu/drm/rockchip/analogix_dp-rockchip.c| 10 +-
  drivers/gpu/drm/rockchip/rockchip_drm_psr.c| 20 +---
  drivers/gpu/drm/rockchip/rockchip_drm_psr.h|  2 +-
  4 files changed, 22 insertions(+), 14 deletions(-)

diff --git a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c 
b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
index be6eddd0d0a7..1f1cb624414d 100644
--- a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
+++ b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
@@ -153,8 +153,10 @@ int analogix_dp_disable_psr(struct analogix_dp_device *dp)
psr_vsc.DB1 = 0;
  
  	ret = drm_dp_dpcd_writeb(>aux, DP_SET_POWER, DP_SET_POWER_D0);

-   if (ret != 1)
+   if (ret != 1) {
dev_err(dp->dev, "Failed to set DP Power0 %d\n", ret);
+   return ret;
+   }
  
  	return analogix_dp_send_psr_spd(dp, _vsc, false);

  }
diff --git a/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c 
b/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c
index 3e8bf79bea58..8c884f9ce713 100644
--- a/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c
+++ b/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c
@@ -77,13 +77,13 @@ struct rockchip_dp_device {
struct analogix_dp_plat_data plat_data;
  };
  
-static void analogix_dp_psr_set(struct drm_encoder *encoder, bool enabled)

+static int analogix_dp_psr_set(struct drm_encoder *encoder, bool enabled)
  {
struct rockchip_dp_device *dp = to_dp(encoder);
int ret;
  
  	if (!analogix_dp_psr_enabled(dp->adp))

-   return;
+   return 0;
  
  	DRM_DEV_DEBUG(dp->dev, "%s PSR...\n", enabled ? "Entry" : "Exit");
  
@@ -91,13 +91,13 @@ static void analogix_dp_psr_set(struct drm_encoder *encoder, bool enabled)

 PSR_WAIT_LINE_FLAG_TIMEOUT_MS);
if (ret) {
DRM_DEV_ERROR(dp->dev, "line flag interrupt did not arrive\n");
-   return;
+   return -ETIMEDOUT;
}
  
  	if (enabled)

-   analogix_dp_enable_psr(dp->adp);
+   return analogix_dp_enable_psr(dp->adp);
else
-   analogix_dp_disable_psr(dp->adp);
+   return analogix_dp_disable_psr(dp->adp);
  }
  
  static int rockchip_dp_pre_init(struct rockchip_dp_device *dp)

diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_psr.c 
b/drivers/gpu/drm/rockchip/rockchip_drm_psr.c
index b339ca943139..9376f4396b6b 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_psr.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_psr.c
@@ -36,7 +36,7 @@ struct psr_drv {
  
  	struct delayed_work	flush_work;
  
-	void (*set)(struct drm_encoder *encoder, bool enable);

+   int (*set)(struct drm_encoder *encoder, bool enable);
  };
  
  static struct psr_drv *find_psr_by_crtc(struct drm_crtc *crtc)

@@ -93,19 +93,25 @@ static void psr_set_state_locked(struct psr_drv *psr, enum 
psr_state state)
return;
}
  
-	psr->state = state;

-
/* Actually commit the state change to hardware */
-   switch (psr->state) {
+   switch (state) {
case PSR_ENABLE:
-   psr->set(psr->encoder, true);
+   if (psr->set(psr->encoder, true))
+   return;
break;
  
  	case PSR_DISABLE:

case PSR_FLUSH:
-   psr->set(psr->encoder, false);
+   if (psr->set(psr->encoder, false))
+   return;
break;
+
+   default:
+   pr_err("%s: Unknown state %d\n", __func__, state);
+   return;
}
+
+   psr->state = state;
  }
  
  static void psr_set_state(struct psr_drv *psr, enum psr_state state)

@@ -229,7 +235,7 @@ EXPORT_SYMBOL(rockchip_drm_psr_flush_all);
   * Zero on success, negative errno on failure.
   */
  int rockchip_drm_psr_register(struct drm_encoder *encoder,
-   void (*psr_set)(struct drm_encoder *, bool enable))
+   int (*psr_set)(str

Re: [PATCH v5 19/36] drm/rockchip: Restore psr->state when enable/disable psr failed

2018-03-14 Thread Archit Taneja



On Saturday 10 March 2018 03:53 AM, Enric Balletbo i Serra wrote:

From: zain wang 

If we failed disable psr, it would hang the display until next psr
cycle coming. So we should restore psr->state when it failed.



For the bridge part,

Reviewed-by: Archit Taneja 

Thanks,
Archit


Cc: Tomasz Figa 
Signed-off-by: zain wang 
Signed-off-by: Douglas Anderson 
Signed-off-by: Sean Paul 
Signed-off-by: Thierry Escande 
Signed-off-by: Enric Balletbo i Serra 
Tested-by: Marek Szyprowski 
---

  drivers/gpu/drm/bridge/analogix/analogix_dp_core.c |  4 +++-
  drivers/gpu/drm/rockchip/analogix_dp-rockchip.c| 10 +-
  drivers/gpu/drm/rockchip/rockchip_drm_psr.c| 20 +---
  drivers/gpu/drm/rockchip/rockchip_drm_psr.h|  2 +-
  4 files changed, 22 insertions(+), 14 deletions(-)

diff --git a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c 
b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
index be6eddd0d0a7..1f1cb624414d 100644
--- a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
+++ b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
@@ -153,8 +153,10 @@ int analogix_dp_disable_psr(struct analogix_dp_device *dp)
psr_vsc.DB1 = 0;
  
  	ret = drm_dp_dpcd_writeb(>aux, DP_SET_POWER, DP_SET_POWER_D0);

-   if (ret != 1)
+   if (ret != 1) {
dev_err(dp->dev, "Failed to set DP Power0 %d\n", ret);
+   return ret;
+   }
  
  	return analogix_dp_send_psr_spd(dp, _vsc, false);

  }
diff --git a/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c 
b/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c
index 3e8bf79bea58..8c884f9ce713 100644
--- a/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c
+++ b/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c
@@ -77,13 +77,13 @@ struct rockchip_dp_device {
struct analogix_dp_plat_data plat_data;
  };
  
-static void analogix_dp_psr_set(struct drm_encoder *encoder, bool enabled)

+static int analogix_dp_psr_set(struct drm_encoder *encoder, bool enabled)
  {
struct rockchip_dp_device *dp = to_dp(encoder);
int ret;
  
  	if (!analogix_dp_psr_enabled(dp->adp))

-   return;
+   return 0;
  
  	DRM_DEV_DEBUG(dp->dev, "%s PSR...\n", enabled ? "Entry" : "Exit");
  
@@ -91,13 +91,13 @@ static void analogix_dp_psr_set(struct drm_encoder *encoder, bool enabled)

 PSR_WAIT_LINE_FLAG_TIMEOUT_MS);
if (ret) {
DRM_DEV_ERROR(dp->dev, "line flag interrupt did not arrive\n");
-   return;
+   return -ETIMEDOUT;
}
  
  	if (enabled)

-   analogix_dp_enable_psr(dp->adp);
+   return analogix_dp_enable_psr(dp->adp);
else
-   analogix_dp_disable_psr(dp->adp);
+   return analogix_dp_disable_psr(dp->adp);
  }
  
  static int rockchip_dp_pre_init(struct rockchip_dp_device *dp)

diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_psr.c 
b/drivers/gpu/drm/rockchip/rockchip_drm_psr.c
index b339ca943139..9376f4396b6b 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_psr.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_psr.c
@@ -36,7 +36,7 @@ struct psr_drv {
  
  	struct delayed_work	flush_work;
  
-	void (*set)(struct drm_encoder *encoder, bool enable);

+   int (*set)(struct drm_encoder *encoder, bool enable);
  };
  
  static struct psr_drv *find_psr_by_crtc(struct drm_crtc *crtc)

@@ -93,19 +93,25 @@ static void psr_set_state_locked(struct psr_drv *psr, enum 
psr_state state)
return;
}
  
-	psr->state = state;

-
/* Actually commit the state change to hardware */
-   switch (psr->state) {
+   switch (state) {
case PSR_ENABLE:
-   psr->set(psr->encoder, true);
+   if (psr->set(psr->encoder, true))
+   return;
break;
  
  	case PSR_DISABLE:

case PSR_FLUSH:
-   psr->set(psr->encoder, false);
+   if (psr->set(psr->encoder, false))
+   return;
break;
+
+   default:
+   pr_err("%s: Unknown state %d\n", __func__, state);
+   return;
}
+
+   psr->state = state;
  }
  
  static void psr_set_state(struct psr_drv *psr, enum psr_state state)

@@ -229,7 +235,7 @@ EXPORT_SYMBOL(rockchip_drm_psr_flush_all);
   * Zero on success, negative errno on failure.
   */
  int rockchip_drm_psr_register(struct drm_encoder *encoder,
-   void (*psr_set)(struct drm_encoder *, bool enable))
+   int (*psr_set)(struct drm_encoder *, bool enable))
  {
struct rockchip_drm_private *drm_drv = encoder->dev->dev_private;
struct psr_drv *psr;
diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_psr.h 
b/drivers/gpu/drm/rockchip/rockchip_drm_psr.h
index b1ea0155e57c..06537

Re: [PATCH v5 18/36] drm/bridge: analogix_dp: Reset aux channel if an error occurred

2018-03-14 Thread Archit Taneja



On Saturday 10 March 2018 03:53 AM, Enric Balletbo i Serra wrote:

From: Lin Huang <h...@rock-chips.com>

AUX errors are caused by many different reasons. We may not know what
happened in aux channel on failure, so let's reset aux channel if some
errors occurred.

Cc: 征增 王 <w...@rock-chips.com>
Cc: Douglas Anderson <diand...@chromium.org>
Signed-off-by: Lin Huang <h...@rock-chips.com>
Signed-off-by: Sean Paul <seanp...@chromium.org>
Signed-off-by: Thierry Escande <thierry.esca...@collabora.com>
Reviewed-by: Andrzej Hajda <a.ha...@samsung.com>
Tested-by: Marek Szyprowski <m.szyprow...@samsung.com>
Signed-off-by: Enric Balletbo i Serra <enric.balle...@collabora.com>
---

  drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c | 18 ++
  1 file changed, 14 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c 
b/drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c
index dee1ba109b5f..7b7fd227e1f9 100644
--- a/drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c
+++ b/drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c
@@ -466,6 +466,10 @@ void analogix_dp_init_aux(struct analogix_dp_device *dp)
reg = RPLY_RECEIV | AUX_ERR;
writel(reg, dp->reg_base + ANALOGIX_DP_INT_STA);
  
+	analogix_dp_set_analog_power_down(dp, AUX_BLOCK, true);

+   usleep_range(10, 11);
+   analogix_dp_set_analog_power_down(dp, AUX_BLOCK, false);
+


Is this additional power on/off the analog power to the AUX block
required to reset it correctly? If so, could you mention that in the
commit message?


analogix_dp_reset_aux(dp);
  
  	/* Disable AUX transaction H/W retry */

@@ -1159,7 +1163,7 @@ ssize_t analogix_dp_transfer(struct analogix_dp_device 
*dp,
 reg, !(reg & AUX_EN), 25, 500 * 1000);
if (ret) {
dev_err(dp->dev, "AUX CH enable timeout!\n");
-   return -ETIMEDOUT;
+   goto aux_error;
}
  
  	/* TODO: Wait for an interrupt instead of looping? */

@@ -1168,7 +1172,7 @@ ssize_t analogix_dp_transfer(struct analogix_dp_device 
*dp,
 reg, reg & RPLY_RECEIV, 10, 20 * 1000);
if (ret) {
dev_err(dp->dev, "AUX CH cmd reply timeout!\n");
-   return -ETIMEDOUT;
+   goto aux_error;
}
  
  	/* Clear interrupt source for AUX CH command reply */

@@ -1178,7 +1182,7 @@ ssize_t analogix_dp_transfer(struct analogix_dp_device 
*dp,
reg = readl(dp->reg_base + ANALOGIX_DP_INT_STA);
if (reg & AUX_ERR) {
writel(AUX_ERR, dp->reg_base + ANALOGIX_DP_INT_STA);
-   return -EREMOTEIO;
+   goto aux_error;
}
  
  	/* Check AUX CH error access status */

@@ -1186,7 +1190,7 @@ ssize_t analogix_dp_transfer(struct analogix_dp_device 
*dp,
if ((reg & AUX_STATUS_MASK)) {
dev_err(dp->dev, "AUX CH error happened: %d\n\n",
reg & AUX_STATUS_MASK);
-   return -EREMOTEIO;
+   goto aux_error;
}
  
  	if (msg->request & DP_AUX_I2C_READ) {

@@ -1212,4 +1216,10 @@ ssize_t analogix_dp_transfer(struct analogix_dp_device 
*dp,
msg->reply = DP_AUX_NATIVE_REPLY_ACK;
  
  	return num_transferred > 0 ? num_transferred : -EBUSY;

+
+aux_error:
+   /* if aux err happen, reset aux */
+   analogix_dp_init_aux(dp);
+
+   return -EREMOTEIO;


A couple of ETIMEDOUTs have been replaced with EREMOTEIOs after this
change. Maybe we set it the error no in ret and return ret?

With those changes,

Reviewed-by: Archit Taneja <arch...@codeaurora.org>

Thanks,
Archit


  }



Re: [PATCH v5 18/36] drm/bridge: analogix_dp: Reset aux channel if an error occurred

2018-03-14 Thread Archit Taneja



On Saturday 10 March 2018 03:53 AM, Enric Balletbo i Serra wrote:

From: Lin Huang 

AUX errors are caused by many different reasons. We may not know what
happened in aux channel on failure, so let's reset aux channel if some
errors occurred.

Cc: 征增 王 
Cc: Douglas Anderson 
Signed-off-by: Lin Huang 
Signed-off-by: Sean Paul 
Signed-off-by: Thierry Escande 
Reviewed-by: Andrzej Hajda 
Tested-by: Marek Szyprowski 
Signed-off-by: Enric Balletbo i Serra 
---

  drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c | 18 ++
  1 file changed, 14 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c 
b/drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c
index dee1ba109b5f..7b7fd227e1f9 100644
--- a/drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c
+++ b/drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c
@@ -466,6 +466,10 @@ void analogix_dp_init_aux(struct analogix_dp_device *dp)
reg = RPLY_RECEIV | AUX_ERR;
writel(reg, dp->reg_base + ANALOGIX_DP_INT_STA);
  
+	analogix_dp_set_analog_power_down(dp, AUX_BLOCK, true);

+   usleep_range(10, 11);
+   analogix_dp_set_analog_power_down(dp, AUX_BLOCK, false);
+


Is this additional power on/off the analog power to the AUX block
required to reset it correctly? If so, could you mention that in the
commit message?


analogix_dp_reset_aux(dp);
  
  	/* Disable AUX transaction H/W retry */

@@ -1159,7 +1163,7 @@ ssize_t analogix_dp_transfer(struct analogix_dp_device 
*dp,
 reg, !(reg & AUX_EN), 25, 500 * 1000);
if (ret) {
dev_err(dp->dev, "AUX CH enable timeout!\n");
-   return -ETIMEDOUT;
+   goto aux_error;
}
  
  	/* TODO: Wait for an interrupt instead of looping? */

@@ -1168,7 +1172,7 @@ ssize_t analogix_dp_transfer(struct analogix_dp_device 
*dp,
 reg, reg & RPLY_RECEIV, 10, 20 * 1000);
if (ret) {
dev_err(dp->dev, "AUX CH cmd reply timeout!\n");
-   return -ETIMEDOUT;
+   goto aux_error;
}
  
  	/* Clear interrupt source for AUX CH command reply */

@@ -1178,7 +1182,7 @@ ssize_t analogix_dp_transfer(struct analogix_dp_device 
*dp,
reg = readl(dp->reg_base + ANALOGIX_DP_INT_STA);
if (reg & AUX_ERR) {
writel(AUX_ERR, dp->reg_base + ANALOGIX_DP_INT_STA);
-   return -EREMOTEIO;
+   goto aux_error;
}
  
  	/* Check AUX CH error access status */

@@ -1186,7 +1190,7 @@ ssize_t analogix_dp_transfer(struct analogix_dp_device 
*dp,
if ((reg & AUX_STATUS_MASK)) {
dev_err(dp->dev, "AUX CH error happened: %d\n\n",
reg & AUX_STATUS_MASK);
-   return -EREMOTEIO;
+   goto aux_error;
}
  
  	if (msg->request & DP_AUX_I2C_READ) {

@@ -1212,4 +1216,10 @@ ssize_t analogix_dp_transfer(struct analogix_dp_device 
*dp,
msg->reply = DP_AUX_NATIVE_REPLY_ACK;
  
  	return num_transferred > 0 ? num_transferred : -EBUSY;

+
+aux_error:
+   /* if aux err happen, reset aux */
+   analogix_dp_init_aux(dp);
+
+   return -EREMOTEIO;


A couple of ETIMEDOUTs have been replaced with EREMOTEIOs after this
change. Maybe we set it the error no in ret and return ret?

With those changes,

Reviewed-by: Archit Taneja 

Thanks,
Archit


  }



Re: [PATCH v5 17/36] drm/bridge: analogix_dp: Fix AUX_PD bit for Rockchip

2018-03-14 Thread Archit Taneja



On Saturday 10 March 2018 03:53 AM, Enric Balletbo i Serra wrote:

From: zain wang <w...@rock-chips.com>

There are some different bits between Rockchip and Exynos in register
"AUX_PD". This patch fixes the incorrect operations about it.


You mean the register ANALOGIX_DP_PHY_PD/ANALOGIX_DP_PD, right? AUX_PD
sounds like just one of the fields of the register.

With that,

Reviewed-by: Archit Taneja <arch...@codeaurora.org>

Thanks,
Archit



Cc: Douglas Anderson <diand...@chromium.org>
Signed-off-by: zain wang <w...@rock-chips.com>
Signed-off-by: Sean Paul <seanp...@chromium.org>
Signed-off-by: Thierry Escande <thierry.esca...@collabora.com>
Reviewed-by: Andrzej Hajda <a.ha...@samsung.com>
Signed-off-by: Enric Balletbo i Serra <enric.balle...@collabora.com>
Tested-by: Marek Szyprowski <m.szyprow...@samsung.com>
---

  drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c | 117 --
  drivers/gpu/drm/bridge/analogix/analogix_dp_reg.h |   2 +
  2 files changed, 65 insertions(+), 54 deletions(-)

diff --git a/drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c 
b/drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c
index bb72f8b0e603..dee1ba109b5f 100644
--- a/drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c
+++ b/drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c
@@ -248,76 +248,85 @@ void analogix_dp_set_analog_power_down(struct 
analogix_dp_device *dp,
  {
u32 reg;
u32 phy_pd_addr = ANALOGIX_DP_PHY_PD;
+   u32 mask;
  
  	if (dp->plat_data && is_rockchip(dp->plat_data->dev_type))

phy_pd_addr = ANALOGIX_DP_PD;
  
  	switch (block) {

case AUX_BLOCK:
-   if (enable) {
-   reg = readl(dp->reg_base + phy_pd_addr);
-   reg |= AUX_PD;
-   writel(reg, dp->reg_base + phy_pd_addr);
-   } else {
-   reg = readl(dp->reg_base + phy_pd_addr);
-   reg &= ~AUX_PD;
-   writel(reg, dp->reg_base + phy_pd_addr);
-   }
+   if (dp->plat_data && is_rockchip(dp->plat_data->dev_type))
+   mask = RK_AUX_PD;
+   else
+   mask = AUX_PD;
+
+   reg = readl(dp->reg_base + phy_pd_addr);
+   if (enable)
+   reg |= mask;
+   else
+   reg &= ~mask;
+   writel(reg, dp->reg_base + phy_pd_addr);
break;
case CH0_BLOCK:
-   if (enable) {
-   reg = readl(dp->reg_base + phy_pd_addr);
-   reg |= CH0_PD;
-   writel(reg, dp->reg_base + phy_pd_addr);
-   } else {
-   reg = readl(dp->reg_base + phy_pd_addr);
-   reg &= ~CH0_PD;
-   writel(reg, dp->reg_base + phy_pd_addr);
-   }
+   mask = CH0_PD;
+   reg = readl(dp->reg_base + phy_pd_addr);
+
+   if (enable)
+   reg |= mask;
+   else
+   reg &= ~mask;
+   writel(reg, dp->reg_base + phy_pd_addr);
break;
case CH1_BLOCK:
-   if (enable) {
-   reg = readl(dp->reg_base + phy_pd_addr);
-   reg |= CH1_PD;
-   writel(reg, dp->reg_base + phy_pd_addr);
-   } else {
-   reg = readl(dp->reg_base + phy_pd_addr);
-   reg &= ~CH1_PD;
-   writel(reg, dp->reg_base + phy_pd_addr);
-   }
+   mask = CH1_PD;
+   reg = readl(dp->reg_base + phy_pd_addr);
+
+   if (enable)
+   reg |= mask;
+   else
+   reg &= ~mask;
+   writel(reg, dp->reg_base + phy_pd_addr);
break;
case CH2_BLOCK:
-   if (enable) {
-   reg = readl(dp->reg_base + phy_pd_addr);
-   reg |= CH2_PD;
-   writel(reg, dp->reg_base + phy_pd_addr);
-   } else {
-   reg = readl(dp->reg_base + phy_pd_addr);
-   reg &= ~CH2_PD;
-   writel(reg, dp->reg_base + phy_pd_addr);
-   }
+   mask = CH2_PD;
+   reg = readl(dp->reg_base + phy_pd_addr);
+
+   if (enable)
+   reg |= mask;
+   else
+   reg &= ~mask;
+   writel(reg, dp->reg_base + phy_pd_addr);
break;
case CH3_BLOCK:
-   if (enable) {
-   reg = readl(dp->reg_base + 

Re: [PATCH v5 17/36] drm/bridge: analogix_dp: Fix AUX_PD bit for Rockchip

2018-03-14 Thread Archit Taneja



On Saturday 10 March 2018 03:53 AM, Enric Balletbo i Serra wrote:

From: zain wang 

There are some different bits between Rockchip and Exynos in register
"AUX_PD". This patch fixes the incorrect operations about it.


You mean the register ANALOGIX_DP_PHY_PD/ANALOGIX_DP_PD, right? AUX_PD
sounds like just one of the fields of the register.

With that,

Reviewed-by: Archit Taneja 

Thanks,
Archit



Cc: Douglas Anderson 
Signed-off-by: zain wang 
Signed-off-by: Sean Paul 
Signed-off-by: Thierry Escande 
Reviewed-by: Andrzej Hajda 
Signed-off-by: Enric Balletbo i Serra 
Tested-by: Marek Szyprowski 
---

  drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c | 117 --
  drivers/gpu/drm/bridge/analogix/analogix_dp_reg.h |   2 +
  2 files changed, 65 insertions(+), 54 deletions(-)

diff --git a/drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c 
b/drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c
index bb72f8b0e603..dee1ba109b5f 100644
--- a/drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c
+++ b/drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c
@@ -248,76 +248,85 @@ void analogix_dp_set_analog_power_down(struct 
analogix_dp_device *dp,
  {
u32 reg;
u32 phy_pd_addr = ANALOGIX_DP_PHY_PD;
+   u32 mask;
  
  	if (dp->plat_data && is_rockchip(dp->plat_data->dev_type))

phy_pd_addr = ANALOGIX_DP_PD;
  
  	switch (block) {

case AUX_BLOCK:
-   if (enable) {
-   reg = readl(dp->reg_base + phy_pd_addr);
-   reg |= AUX_PD;
-   writel(reg, dp->reg_base + phy_pd_addr);
-   } else {
-   reg = readl(dp->reg_base + phy_pd_addr);
-   reg &= ~AUX_PD;
-   writel(reg, dp->reg_base + phy_pd_addr);
-   }
+   if (dp->plat_data && is_rockchip(dp->plat_data->dev_type))
+   mask = RK_AUX_PD;
+   else
+   mask = AUX_PD;
+
+   reg = readl(dp->reg_base + phy_pd_addr);
+   if (enable)
+   reg |= mask;
+   else
+   reg &= ~mask;
+   writel(reg, dp->reg_base + phy_pd_addr);
break;
case CH0_BLOCK:
-   if (enable) {
-   reg = readl(dp->reg_base + phy_pd_addr);
-   reg |= CH0_PD;
-   writel(reg, dp->reg_base + phy_pd_addr);
-   } else {
-   reg = readl(dp->reg_base + phy_pd_addr);
-   reg &= ~CH0_PD;
-   writel(reg, dp->reg_base + phy_pd_addr);
-   }
+   mask = CH0_PD;
+   reg = readl(dp->reg_base + phy_pd_addr);
+
+   if (enable)
+   reg |= mask;
+   else
+   reg &= ~mask;
+   writel(reg, dp->reg_base + phy_pd_addr);
break;
case CH1_BLOCK:
-   if (enable) {
-   reg = readl(dp->reg_base + phy_pd_addr);
-   reg |= CH1_PD;
-   writel(reg, dp->reg_base + phy_pd_addr);
-   } else {
-   reg = readl(dp->reg_base + phy_pd_addr);
-   reg &= ~CH1_PD;
-   writel(reg, dp->reg_base + phy_pd_addr);
-   }
+   mask = CH1_PD;
+   reg = readl(dp->reg_base + phy_pd_addr);
+
+   if (enable)
+   reg |= mask;
+   else
+   reg &= ~mask;
+   writel(reg, dp->reg_base + phy_pd_addr);
break;
case CH2_BLOCK:
-   if (enable) {
-   reg = readl(dp->reg_base + phy_pd_addr);
-   reg |= CH2_PD;
-   writel(reg, dp->reg_base + phy_pd_addr);
-   } else {
-   reg = readl(dp->reg_base + phy_pd_addr);
-   reg &= ~CH2_PD;
-   writel(reg, dp->reg_base + phy_pd_addr);
-   }
+   mask = CH2_PD;
+   reg = readl(dp->reg_base + phy_pd_addr);
+
+   if (enable)
+   reg |= mask;
+   else
+   reg &= ~mask;
+   writel(reg, dp->reg_base + phy_pd_addr);
break;
case CH3_BLOCK:
-   if (enable) {
-   reg = readl(dp->reg_base + phy_pd_addr);
-   reg |= CH3_PD;
-   writel(reg, dp->reg_base + phy_pd_addr);
-   } else {
-   reg = readl(dp->reg_base + phy_pd_addr);
-   reg &= ~CH3_PD;
-  

Re: [PATCH v5 16/36] drm/bridge: analogix_dp: Check dpcd write/read status

2018-03-14 Thread Archit Taneja



On Saturday 10 March 2018 03:53 AM, Enric Balletbo i Serra wrote:

From: Lin Huang <h...@rock-chips.com>

We need to check the dpcd write/read return value to see whether the
write/read was successful



Reviewed-by: Archit Taneja <arch...@codeaurora.org>

Thanks,
Archit


Cc: Kristian H. Kristensen <hoegsb...@chromium.org>
Signed-off-by: Lin Huang <h...@rock-chips.com>
Signed-off-by: zain wang <w...@rock-chips.com>
Signed-off-by: Douglas Anderson <diand...@chromium.org>
Signed-off-by: Sean Paul <seanp...@chromium.org>
Signed-off-by: Thierry Escande <thierry.esca...@collabora.com>
Reviewed-by: Andrzej Hajda <a.ha...@samsung.com>
Signed-off-by: Enric Balletbo i Serra <enric.balle...@collabora.com>
Tested-by: Marek Szyprowski <m.szyprow...@samsung.com>
---

  drivers/gpu/drm/bridge/analogix/analogix_dp_core.c | 169 -
  1 file changed, 127 insertions(+), 42 deletions(-)

diff --git a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c 
b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
index 1eed35f9eb8d..be6eddd0d0a7 100644
--- a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
+++ b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
@@ -160,80 +160,137 @@ int analogix_dp_disable_psr(struct analogix_dp_device 
*dp)
  }
  EXPORT_SYMBOL_GPL(analogix_dp_disable_psr);
  
-static bool analogix_dp_detect_sink_psr(struct analogix_dp_device *dp)

+static int analogix_dp_detect_sink_psr(struct analogix_dp_device *dp)
  {
unsigned char psr_version;
+   int ret;
+
+   ret = drm_dp_dpcd_readb(>aux, DP_PSR_SUPPORT, _version);
+   if (ret != 1) {
+   dev_err(dp->dev, "failed to get PSR version, disable it\n");
+   return ret;
+   }
  
-	drm_dp_dpcd_readb(>aux, DP_PSR_SUPPORT, _version);

dev_dbg(dp->dev, "Panel PSR version : %x\n", psr_version);
  
-	return (psr_version & DP_PSR_IS_SUPPORTED) ? true : false;

+   dp->psr_enable = (psr_version & DP_PSR_IS_SUPPORTED) ? true : false;
+
+   return 0;
  }
  
-static void analogix_dp_enable_sink_psr(struct analogix_dp_device *dp)

+static int analogix_dp_enable_sink_psr(struct analogix_dp_device *dp)
  {
unsigned char psr_en;
+   int ret;
  
  	/* Disable psr function */

-   drm_dp_dpcd_readb(>aux, DP_PSR_EN_CFG, _en);
+   ret = drm_dp_dpcd_readb(>aux, DP_PSR_EN_CFG, _en);
+   if (ret != 1) {
+   dev_err(dp->dev, "failed to get psr config\n");
+   goto end;
+   }
+
psr_en &= ~DP_PSR_ENABLE;
-   drm_dp_dpcd_writeb(>aux, DP_PSR_EN_CFG, psr_en);
+   ret = drm_dp_dpcd_writeb(>aux, DP_PSR_EN_CFG, psr_en);
+   if (ret != 1) {
+   dev_err(dp->dev, "failed to disable panel psr\n");
+   goto end;
+   }
  
  	/* Main-Link transmitter remains active during PSR active states */

psr_en = DP_PSR_MAIN_LINK_ACTIVE | DP_PSR_CRC_VERIFICATION;
-   drm_dp_dpcd_writeb(>aux, DP_PSR_EN_CFG, psr_en);
+   ret = drm_dp_dpcd_writeb(>aux, DP_PSR_EN_CFG, psr_en);
+   if (ret != 1) {
+   dev_err(dp->dev, "failed to set panel psr\n");
+   goto end;
+   }
  
  	/* Enable psr function */

psr_en = DP_PSR_ENABLE | DP_PSR_MAIN_LINK_ACTIVE |
 DP_PSR_CRC_VERIFICATION;
-   drm_dp_dpcd_writeb(>aux, DP_PSR_EN_CFG, psr_en);
+   ret = drm_dp_dpcd_writeb(>aux, DP_PSR_EN_CFG, psr_en);
+   if (ret != 1) {
+   dev_err(dp->dev, "failed to set panel psr\n");
+   goto end;
+   }
  
  	analogix_dp_enable_psr_crc(dp);

+
+   return 0;
+end:
+   dev_err(dp->dev, "enable psr fail, force to disable psr\n");
+   dp->psr_enable = false;
+
+   return ret;
  }
  
-static void

+static int
  analogix_dp_enable_rx_to_enhanced_mode(struct analogix_dp_device *dp,
   bool enable)
  {
u8 data;
+   int ret;
  
-	drm_dp_dpcd_readb(>aux, DP_LANE_COUNT_SET, );

+   ret = drm_dp_dpcd_readb(>aux, DP_LANE_COUNT_SET, );
+   if (ret != 1)
+   return ret;
  
  	if (enable)

-   drm_dp_dpcd_writeb(>aux, DP_LANE_COUNT_SET,
-  DP_LANE_COUNT_ENHANCED_FRAME_EN |
-   DPCD_LANE_COUNT_SET(data));
+   ret = drm_dp_dpcd_writeb(>aux, DP_LANE_COUNT_SET,
+DP_LANE_COUNT_ENHANCED_FRAME_EN |
+DPCD_LANE_COUNT_SET(data));
else
-   drm_dp_dpcd_writeb(>aux, DP_LANE_COUNT_SET,
-  DPCD_LANE_COUNT_SET(data));
+   ret = drm_dp_dpcd_writeb(>aux, DP_LANE_COUNT_SET,
+DPCD_LANE_CO

Re: [PATCH v5 16/36] drm/bridge: analogix_dp: Check dpcd write/read status

2018-03-14 Thread Archit Taneja



On Saturday 10 March 2018 03:53 AM, Enric Balletbo i Serra wrote:

From: Lin Huang 

We need to check the dpcd write/read return value to see whether the
write/read was successful



Reviewed-by: Archit Taneja 

Thanks,
Archit


Cc: Kristian H. Kristensen 
Signed-off-by: Lin Huang 
Signed-off-by: zain wang 
Signed-off-by: Douglas Anderson 
Signed-off-by: Sean Paul 
Signed-off-by: Thierry Escande 
Reviewed-by: Andrzej Hajda 
Signed-off-by: Enric Balletbo i Serra 
Tested-by: Marek Szyprowski 
---

  drivers/gpu/drm/bridge/analogix/analogix_dp_core.c | 169 -
  1 file changed, 127 insertions(+), 42 deletions(-)

diff --git a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c 
b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
index 1eed35f9eb8d..be6eddd0d0a7 100644
--- a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
+++ b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
@@ -160,80 +160,137 @@ int analogix_dp_disable_psr(struct analogix_dp_device 
*dp)
  }
  EXPORT_SYMBOL_GPL(analogix_dp_disable_psr);
  
-static bool analogix_dp_detect_sink_psr(struct analogix_dp_device *dp)

+static int analogix_dp_detect_sink_psr(struct analogix_dp_device *dp)
  {
unsigned char psr_version;
+   int ret;
+
+   ret = drm_dp_dpcd_readb(>aux, DP_PSR_SUPPORT, _version);
+   if (ret != 1) {
+   dev_err(dp->dev, "failed to get PSR version, disable it\n");
+   return ret;
+   }
  
-	drm_dp_dpcd_readb(>aux, DP_PSR_SUPPORT, _version);

dev_dbg(dp->dev, "Panel PSR version : %x\n", psr_version);
  
-	return (psr_version & DP_PSR_IS_SUPPORTED) ? true : false;

+   dp->psr_enable = (psr_version & DP_PSR_IS_SUPPORTED) ? true : false;
+
+   return 0;
  }
  
-static void analogix_dp_enable_sink_psr(struct analogix_dp_device *dp)

+static int analogix_dp_enable_sink_psr(struct analogix_dp_device *dp)
  {
unsigned char psr_en;
+   int ret;
  
  	/* Disable psr function */

-   drm_dp_dpcd_readb(>aux, DP_PSR_EN_CFG, _en);
+   ret = drm_dp_dpcd_readb(>aux, DP_PSR_EN_CFG, _en);
+   if (ret != 1) {
+   dev_err(dp->dev, "failed to get psr config\n");
+   goto end;
+   }
+
psr_en &= ~DP_PSR_ENABLE;
-   drm_dp_dpcd_writeb(>aux, DP_PSR_EN_CFG, psr_en);
+   ret = drm_dp_dpcd_writeb(>aux, DP_PSR_EN_CFG, psr_en);
+   if (ret != 1) {
+   dev_err(dp->dev, "failed to disable panel psr\n");
+   goto end;
+   }
  
  	/* Main-Link transmitter remains active during PSR active states */

psr_en = DP_PSR_MAIN_LINK_ACTIVE | DP_PSR_CRC_VERIFICATION;
-   drm_dp_dpcd_writeb(>aux, DP_PSR_EN_CFG, psr_en);
+   ret = drm_dp_dpcd_writeb(>aux, DP_PSR_EN_CFG, psr_en);
+   if (ret != 1) {
+   dev_err(dp->dev, "failed to set panel psr\n");
+   goto end;
+   }
  
  	/* Enable psr function */

psr_en = DP_PSR_ENABLE | DP_PSR_MAIN_LINK_ACTIVE |
 DP_PSR_CRC_VERIFICATION;
-   drm_dp_dpcd_writeb(>aux, DP_PSR_EN_CFG, psr_en);
+   ret = drm_dp_dpcd_writeb(>aux, DP_PSR_EN_CFG, psr_en);
+   if (ret != 1) {
+   dev_err(dp->dev, "failed to set panel psr\n");
+   goto end;
+   }
  
  	analogix_dp_enable_psr_crc(dp);

+
+   return 0;
+end:
+   dev_err(dp->dev, "enable psr fail, force to disable psr\n");
+   dp->psr_enable = false;
+
+   return ret;
  }
  
-static void

+static int
  analogix_dp_enable_rx_to_enhanced_mode(struct analogix_dp_device *dp,
   bool enable)
  {
u8 data;
+   int ret;
  
-	drm_dp_dpcd_readb(>aux, DP_LANE_COUNT_SET, );

+   ret = drm_dp_dpcd_readb(>aux, DP_LANE_COUNT_SET, );
+   if (ret != 1)
+   return ret;
  
  	if (enable)

-   drm_dp_dpcd_writeb(>aux, DP_LANE_COUNT_SET,
-  DP_LANE_COUNT_ENHANCED_FRAME_EN |
-   DPCD_LANE_COUNT_SET(data));
+   ret = drm_dp_dpcd_writeb(>aux, DP_LANE_COUNT_SET,
+DP_LANE_COUNT_ENHANCED_FRAME_EN |
+DPCD_LANE_COUNT_SET(data));
else
-   drm_dp_dpcd_writeb(>aux, DP_LANE_COUNT_SET,
-  DPCD_LANE_COUNT_SET(data));
+   ret = drm_dp_dpcd_writeb(>aux, DP_LANE_COUNT_SET,
+DPCD_LANE_COUNT_SET(data));
+
+   return ret < 0 ? ret : 0;
  }
  
-static int analogix_dp_is_enhanced_mode_available(struct analogix_dp_device *dp)

+static int analogix_dp_is_enhanced_mode_available(struct analogix_dp_device 
*dp,
+ u8 *enhanced_mode_support)
  {
u8 data;
-   int retval;
+   int 

Re: [PATCH v5 15/36] drm/bridge: analogix_dp: Fix incorrect usage of enhanced mode

2018-03-14 Thread Archit Taneja



On Saturday 10 March 2018 03:53 AM, Enric Balletbo i Serra wrote:

From: zain wang <w...@rock-chips.com>

Enhanced mode is required by the eDP 1.2 specification, and not doing it
early could result in a period of time where we have a link transmitting
idle packets without it. Since there is no reason to disable it, we just
enable it at the beginning of link training and then keep it on all the
time.


Reviewed-by: Archit Taneja <arch...@codeaurora.org>

Thanks,
Archit



Cc: Tomasz Figa <tf...@chromium.org>
Signed-off-by: zain wang <w...@rock-chips.com>
Signed-off-by: Sean Paul <seanp...@chromium.org>
Signed-off-by: Thierry Escande <thierry.esca...@collabora.com>
Reviewed-by: Andrzej Hajda <a.ha...@samsung.com>
Signed-off-by: Enric Balletbo i Serra <enric.balle...@collabora.com>
Tested-by: Marek Szyprowski <m.szyprow...@samsung.com>
---

  drivers/gpu/drm/bridge/analogix/analogix_dp_core.c | 6 ++
  1 file changed, 2 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c 
b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
index 6cbde8473f58..1eed35f9eb8d 100644
--- a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
+++ b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
@@ -281,6 +281,8 @@ static int analogix_dp_link_start(struct analogix_dp_device 
*dp)
retval = drm_dp_dpcd_write(>aux, DP_LINK_BW_SET, buf, 2);
if (retval < 0)
return retval;
+   /* set enhanced mode if available */
+   analogix_dp_set_enhanced_mode(dp);
  
  	/* Set TX pre-emphasis to minimum */

for (lane = 0; lane < lane_count; lane++)
@@ -593,8 +595,6 @@ static int analogix_dp_process_equalizer_training(struct 
analogix_dp_device *dp)
dev_dbg(dp->dev, "fast link training %s\n",
dp->fast_train_enable ? "supported" : "unsupported");
  
-		/* set enhanced mode if available */

-   analogix_dp_set_enhanced_mode(dp);
dp->link_train.lt_state = FINISHED;
  
  		return 0;

@@ -940,8 +940,6 @@ static int analogix_dp_commit(struct analogix_dp_device *dp)
}
  
  	analogix_dp_enable_scramble(dp, 1);

-   analogix_dp_enable_rx_to_enhanced_mode(dp, 1);
-   analogix_dp_enable_enhanced_mode(dp, 1);
  
  	analogix_dp_init_video(dp);

ret = analogix_dp_config_video(dp);



Re: [PATCH v5 15/36] drm/bridge: analogix_dp: Fix incorrect usage of enhanced mode

2018-03-14 Thread Archit Taneja



On Saturday 10 March 2018 03:53 AM, Enric Balletbo i Serra wrote:

From: zain wang 

Enhanced mode is required by the eDP 1.2 specification, and not doing it
early could result in a period of time where we have a link transmitting
idle packets without it. Since there is no reason to disable it, we just
enable it at the beginning of link training and then keep it on all the
time.


Reviewed-by: Archit Taneja 

Thanks,
Archit



Cc: Tomasz Figa 
Signed-off-by: zain wang 
Signed-off-by: Sean Paul 
Signed-off-by: Thierry Escande 
Reviewed-by: Andrzej Hajda 
Signed-off-by: Enric Balletbo i Serra 
Tested-by: Marek Szyprowski 
---

  drivers/gpu/drm/bridge/analogix/analogix_dp_core.c | 6 ++
  1 file changed, 2 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c 
b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
index 6cbde8473f58..1eed35f9eb8d 100644
--- a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
+++ b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
@@ -281,6 +281,8 @@ static int analogix_dp_link_start(struct analogix_dp_device 
*dp)
retval = drm_dp_dpcd_write(>aux, DP_LINK_BW_SET, buf, 2);
if (retval < 0)
return retval;
+   /* set enhanced mode if available */
+   analogix_dp_set_enhanced_mode(dp);
  
  	/* Set TX pre-emphasis to minimum */

for (lane = 0; lane < lane_count; lane++)
@@ -593,8 +595,6 @@ static int analogix_dp_process_equalizer_training(struct 
analogix_dp_device *dp)
dev_dbg(dp->dev, "fast link training %s\n",
dp->fast_train_enable ? "supported" : "unsupported");
  
-		/* set enhanced mode if available */

-   analogix_dp_set_enhanced_mode(dp);
dp->link_train.lt_state = FINISHED;
  
  		return 0;

@@ -940,8 +940,6 @@ static int analogix_dp_commit(struct analogix_dp_device *dp)
}
  
  	analogix_dp_enable_scramble(dp, 1);

-   analogix_dp_enable_rx_to_enhanced_mode(dp, 1);
-   analogix_dp_enable_enhanced_mode(dp, 1);
  
  	analogix_dp_init_video(dp);

ret = analogix_dp_config_video(dp);



Re: [PATCH v5 14/36] drm/bridge: analogix_dp: Extend hpd check time to 100ms

2018-03-14 Thread Archit Taneja



On Saturday 10 March 2018 03:53 AM, Enric Balletbo i Serra wrote:

From: Lin Huang <h...@rock-chips.com>

There was a 1ms delay to detect the hpd signal, which is too short to
detect a short pulse. This patch extends this delay to 100ms.



Reviewed-by: Archit Taneja <arch...@codeaurora.org>

Thanks,
Archit


Cc: Stéphane Marchesin <marc...@chromium.org>
Cc: 征增 王 <w...@rock-chips.com>
Signed-off-by: Lin Huang <h...@rock-chips.com>
Signed-off-by: Sean Paul <seanp...@chromium.org>
Signed-off-by: Thierry Escande <thierry.esca...@collabora.com>
Reviewed-by: Andrzej Hajda <a.ha...@samsung.com>
Signed-off-by: Enric Balletbo i Serra <enric.balle...@collabora.com>
Tested-by: Marek Szyprowski <m.szyprow...@samsung.com>
---

  drivers/gpu/drm/bridge/analogix/analogix_dp_core.c | 2 +-
  1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c 
b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
index 3a222e7e46ee..6cbde8473f58 100644
--- a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
+++ b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
@@ -76,7 +76,7 @@ static int analogix_dp_detect_hpd(struct analogix_dp_device 
*dp)
return 0;
  
  		timeout_loop++;

-   usleep_range(10, 11);
+   usleep_range(1000, 1100);
}
  
  	/*




Re: [PATCH v5 14/36] drm/bridge: analogix_dp: Extend hpd check time to 100ms

2018-03-14 Thread Archit Taneja



On Saturday 10 March 2018 03:53 AM, Enric Balletbo i Serra wrote:

From: Lin Huang 

There was a 1ms delay to detect the hpd signal, which is too short to
detect a short pulse. This patch extends this delay to 100ms.



Reviewed-by: Archit Taneja 

Thanks,
Archit


Cc: Stéphane Marchesin 
Cc: 征增 王 
Signed-off-by: Lin Huang 
Signed-off-by: Sean Paul 
Signed-off-by: Thierry Escande 
Reviewed-by: Andrzej Hajda 
Signed-off-by: Enric Balletbo i Serra 
Tested-by: Marek Szyprowski 
---

  drivers/gpu/drm/bridge/analogix/analogix_dp_core.c | 2 +-
  1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c 
b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
index 3a222e7e46ee..6cbde8473f58 100644
--- a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
+++ b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
@@ -76,7 +76,7 @@ static int analogix_dp_detect_hpd(struct analogix_dp_device 
*dp)
return 0;
  
  		timeout_loop++;

-   usleep_range(10, 11);
+   usleep_range(1000, 1100);
}
  
  	/*




Re: [PATCH v5 13/36] drm/bridge: analogix_dp: Ensure edp is disabled when shutting down the panel

2018-03-14 Thread Archit Taneja



On Saturday 10 March 2018 03:53 AM, Enric Balletbo i Serra wrote:

From: Lin Huang <h...@rock-chips.com>

When panel is shut down, we should make sure edp can be disabled to avoid
undefined behavior.


Reviewed-by: Archit Taneja <arch...@codeaurora.org>

Thanks,
Archit



Cc: Stéphane Marchesin <marc...@chromium.org>
Signed-off-by: Lin Huang <h...@rock-chips.com>
Signed-off-by: zain wang <w...@rock-chips.com>
Signed-off-by: Sean Paul <seanp...@chromium.org>
Signed-off-by: Thierry Escande <thierry.esca...@collabora.com>
Reviewed-by: Andrzej Hajda <a.ha...@samsung.com>
Signed-off-by: Enric Balletbo i Serra <enric.balle...@collabora.com>
Tested-by: Marek Szyprowski <m.szyprow...@samsung.com>
---

  drivers/gpu/drm/bridge/analogix/analogix_dp_core.c | 11 +++
  1 file changed, 11 insertions(+)

diff --git a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c 
b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
index 92fb9a072cb6..3a222e7e46ee 100644
--- a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
+++ b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
@@ -1160,6 +1160,12 @@ static int analogix_dp_set_bridge(struct 
analogix_dp_device *dp)
  
  	pm_runtime_get_sync(dp->dev);
  
+	ret = clk_prepare_enable(dp->clock);

+   if (ret < 0) {
+   DRM_ERROR("Failed to prepare_enable the clock clk [%d]\n", ret);
+   goto out_dp_clk_pre;
+   }
+
if (dp->plat_data->power_on)
dp->plat_data->power_on(dp->plat_data);
  
@@ -1191,6 +1197,8 @@ static int analogix_dp_set_bridge(struct analogix_dp_device *dp)

phy_power_off(dp->phy);
if (dp->plat_data->power_off)
dp->plat_data->power_off(dp->plat_data);
+   clk_disable_unprepare(dp->clock);
+out_dp_clk_pre:
pm_runtime_put_sync(dp->dev);
  
  	return ret;

@@ -1233,11 +1241,14 @@ static void analogix_dp_bridge_disable(struct 
drm_bridge *bridge)
}
  
  	disable_irq(dp->irq);

+   analogix_dp_set_analog_power_down(dp, POWER_ALL, 1);
phy_power_off(dp->phy);
  
  	if (dp->plat_data->power_off)

dp->plat_data->power_off(dp->plat_data);
  
+	clk_disable_unprepare(dp->clock);

+
pm_runtime_put_sync(dp->dev);
  
  	ret = analogix_dp_prepare_panel(dp, false, true);




Re: [PATCH v5 13/36] drm/bridge: analogix_dp: Ensure edp is disabled when shutting down the panel

2018-03-14 Thread Archit Taneja



On Saturday 10 March 2018 03:53 AM, Enric Balletbo i Serra wrote:

From: Lin Huang 

When panel is shut down, we should make sure edp can be disabled to avoid
undefined behavior.


Reviewed-by: Archit Taneja 

Thanks,
Archit



Cc: Stéphane Marchesin 
Signed-off-by: Lin Huang 
Signed-off-by: zain wang 
Signed-off-by: Sean Paul 
Signed-off-by: Thierry Escande 
Reviewed-by: Andrzej Hajda 
Signed-off-by: Enric Balletbo i Serra 
Tested-by: Marek Szyprowski 
---

  drivers/gpu/drm/bridge/analogix/analogix_dp_core.c | 11 +++
  1 file changed, 11 insertions(+)

diff --git a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c 
b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
index 92fb9a072cb6..3a222e7e46ee 100644
--- a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
+++ b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
@@ -1160,6 +1160,12 @@ static int analogix_dp_set_bridge(struct 
analogix_dp_device *dp)
  
  	pm_runtime_get_sync(dp->dev);
  
+	ret = clk_prepare_enable(dp->clock);

+   if (ret < 0) {
+   DRM_ERROR("Failed to prepare_enable the clock clk [%d]\n", ret);
+   goto out_dp_clk_pre;
+   }
+
if (dp->plat_data->power_on)
dp->plat_data->power_on(dp->plat_data);
  
@@ -1191,6 +1197,8 @@ static int analogix_dp_set_bridge(struct analogix_dp_device *dp)

phy_power_off(dp->phy);
if (dp->plat_data->power_off)
dp->plat_data->power_off(dp->plat_data);
+   clk_disable_unprepare(dp->clock);
+out_dp_clk_pre:
pm_runtime_put_sync(dp->dev);
  
  	return ret;

@@ -1233,11 +1241,14 @@ static void analogix_dp_bridge_disable(struct 
drm_bridge *bridge)
}
  
  	disable_irq(dp->irq);

+   analogix_dp_set_analog_power_down(dp, POWER_ALL, 1);
phy_power_off(dp->phy);
  
  	if (dp->plat_data->power_off)

dp->plat_data->power_off(dp->plat_data);
  
+	clk_disable_unprepare(dp->clock);

+
pm_runtime_put_sync(dp->dev);
  
  	ret = analogix_dp_prepare_panel(dp, false, true);




Re: [PATCH v5 12/36] drm/bridge: analogix_dp: Set PD_INC_BG first when powering up edp phy

2018-03-14 Thread Archit Taneja



On Saturday 10 March 2018 03:53 AM, Enric Balletbo i Serra wrote:

From: zain wang <w...@rock-chips.com>

Following the correct power up sequence:
dp_pd=ff => dp_pd=7f => wait 10us => dp_pd=00



Reviewed-by: Archit Taneja <arch...@codeaurora.org>

Thanks,
Archit


Cc: Stéphane Marchesin <marc...@chromium.org>
Signed-off-by: zain wang <w...@rock-chips.com>
Signed-off-by: Sean Paul <seanp...@chromium.org>
Signed-off-by: Thierry Escande <thierry.esca...@collabora.com>
Signed-off-by: Enric Balletbo i Serra <enric.balle...@collabora.com>
Tested-by: Marek Szyprowski <m.szyprow...@samsung.com>
---

  drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c | 10 --
  drivers/gpu/drm/bridge/analogix/analogix_dp_reg.h |  3 +++
  2 files changed, 11 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c 
b/drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c
index b47c5af43560..bb72f8b0e603 100644
--- a/drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c
+++ b/drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c
@@ -321,10 +321,16 @@ void analogix_dp_set_analog_power_down(struct 
analogix_dp_device *dp,
break;
case POWER_ALL:
if (enable) {
-   reg = DP_PHY_PD | AUX_PD | CH3_PD | CH2_PD |
-   CH1_PD | CH0_PD;
+   reg = DP_ALL_PD;
writel(reg, dp->reg_base + phy_pd_addr);
} else {
+   reg = DP_ALL_PD;
+   writel(reg, dp->reg_base + phy_pd_addr);
+   usleep_range(10, 15);
+   reg &= ~DP_INC_BG;
+   writel(reg, dp->reg_base + phy_pd_addr);
+   usleep_range(10, 15);
+
writel(0x00, dp->reg_base + phy_pd_addr);
}
break;
diff --git a/drivers/gpu/drm/bridge/analogix/analogix_dp_reg.h 
b/drivers/gpu/drm/bridge/analogix/analogix_dp_reg.h
index 40200c652533..9602668669f4 100644
--- a/drivers/gpu/drm/bridge/analogix/analogix_dp_reg.h
+++ b/drivers/gpu/drm/bridge/analogix/analogix_dp_reg.h
@@ -342,12 +342,15 @@
  #define DP_PLL_REF_BIT_1_2500V(0x7 << 0)
  
  /* ANALOGIX_DP_PHY_PD */

+#define DP_INC_BG  (0x1 << 7)
+#define DP_EXP_BG  (0x1 << 6)
  #define DP_PHY_PD (0x1 << 5)
  #define AUX_PD(0x1 << 4)
  #define CH3_PD(0x1 << 3)
  #define CH2_PD(0x1 << 2)
  #define CH1_PD(0x1 << 1)
  #define CH0_PD(0x1 << 0)
+#define DP_ALL_PD  (0xff)
  
  /* ANALOGIX_DP_PHY_TEST */

  #define MACRO_RST (0x1 << 5)



Re: [PATCH v5 12/36] drm/bridge: analogix_dp: Set PD_INC_BG first when powering up edp phy

2018-03-14 Thread Archit Taneja



On Saturday 10 March 2018 03:53 AM, Enric Balletbo i Serra wrote:

From: zain wang 

Following the correct power up sequence:
dp_pd=ff => dp_pd=7f => wait 10us => dp_pd=00



Reviewed-by: Archit Taneja 

Thanks,
Archit


Cc: Stéphane Marchesin 
Signed-off-by: zain wang 
Signed-off-by: Sean Paul 
Signed-off-by: Thierry Escande 
Signed-off-by: Enric Balletbo i Serra 
Tested-by: Marek Szyprowski 
---

  drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c | 10 --
  drivers/gpu/drm/bridge/analogix/analogix_dp_reg.h |  3 +++
  2 files changed, 11 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c 
b/drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c
index b47c5af43560..bb72f8b0e603 100644
--- a/drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c
+++ b/drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c
@@ -321,10 +321,16 @@ void analogix_dp_set_analog_power_down(struct 
analogix_dp_device *dp,
break;
case POWER_ALL:
if (enable) {
-   reg = DP_PHY_PD | AUX_PD | CH3_PD | CH2_PD |
-   CH1_PD | CH0_PD;
+   reg = DP_ALL_PD;
writel(reg, dp->reg_base + phy_pd_addr);
} else {
+   reg = DP_ALL_PD;
+   writel(reg, dp->reg_base + phy_pd_addr);
+   usleep_range(10, 15);
+   reg &= ~DP_INC_BG;
+   writel(reg, dp->reg_base + phy_pd_addr);
+   usleep_range(10, 15);
+
writel(0x00, dp->reg_base + phy_pd_addr);
}
break;
diff --git a/drivers/gpu/drm/bridge/analogix/analogix_dp_reg.h 
b/drivers/gpu/drm/bridge/analogix/analogix_dp_reg.h
index 40200c652533..9602668669f4 100644
--- a/drivers/gpu/drm/bridge/analogix/analogix_dp_reg.h
+++ b/drivers/gpu/drm/bridge/analogix/analogix_dp_reg.h
@@ -342,12 +342,15 @@
  #define DP_PLL_REF_BIT_1_2500V(0x7 << 0)
  
  /* ANALOGIX_DP_PHY_PD */

+#define DP_INC_BG  (0x1 << 7)
+#define DP_EXP_BG  (0x1 << 6)
  #define DP_PHY_PD (0x1 << 5)
  #define AUX_PD(0x1 << 4)
  #define CH3_PD(0x1 << 3)
  #define CH2_PD(0x1 << 2)
  #define CH1_PD(0x1 << 1)
  #define CH0_PD(0x1 << 0)
+#define DP_ALL_PD  (0xff)
  
  /* ANALOGIX_DP_PHY_TEST */

  #define MACRO_RST (0x1 << 5)



Re: [PATCH v5 11/36] drm/bridge: analogix_dp: Wait for HPD signal before configuring link

2018-03-14 Thread Archit Taneja



On Saturday 10 March 2018 03:53 AM, Enric Balletbo i Serra wrote:

From: zain wang <w...@rock-chips.com>

According to DP spec v1.3 chap 3.5.1.2 Link Training, Link Policy Maker
must first detect that the HPD signal is asserted high by the Downstream
Device before establishing a link with it.


Reviewed-by: Archit Taneja <arch...@codeaurora.org>

Thanks,
Archit



Cc: Stéphane Marchesin <marc...@chromium.org>
Signed-off-by: zain wang <w...@rock-chips.com>
Signed-off-by: Sean Paul <seanp...@chromium.org>
Signed-off-by: Thierry Escande <thierry.esca...@collabora.com>
Signed-off-by: Enric Balletbo i Serra <enric.balle...@collabora.com>
Tested-by: Marek Szyprowski <m.szyprow...@samsung.com>
---

  drivers/gpu/drm/bridge/analogix/analogix_dp_core.c | 11 +++
  1 file changed, 11 insertions(+)

diff --git a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c 
b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
index c81733b8185e..92fb9a072cb6 100644
--- a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
+++ b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
@@ -1169,6 +1169,17 @@ static int analogix_dp_set_bridge(struct 
analogix_dp_device *dp)
if (ret)
goto out_dp_init;
  
+	/*

+* According to DP spec v1.3 chap 3.5.1.2 Link Training,
+* We should first make sure the HPD signal is asserted high by device
+* when we want to establish a link with it.
+*/
+   ret = analogix_dp_detect_hpd(dp);
+   if (ret) {
+   DRM_ERROR("failed to get hpd single ret = %d\n", ret);
+   goto out_dp_init;
+   }
+
ret = analogix_dp_commit(dp);
if (ret)
goto out_dp_init;



Re: [PATCH v5 11/36] drm/bridge: analogix_dp: Wait for HPD signal before configuring link

2018-03-14 Thread Archit Taneja



On Saturday 10 March 2018 03:53 AM, Enric Balletbo i Serra wrote:

From: zain wang 

According to DP spec v1.3 chap 3.5.1.2 Link Training, Link Policy Maker
must first detect that the HPD signal is asserted high by the Downstream
Device before establishing a link with it.


Reviewed-by: Archit Taneja 

Thanks,
Archit



Cc: Stéphane Marchesin 
Signed-off-by: zain wang 
Signed-off-by: Sean Paul 
Signed-off-by: Thierry Escande 
Signed-off-by: Enric Balletbo i Serra 
Tested-by: Marek Szyprowski 
---

  drivers/gpu/drm/bridge/analogix/analogix_dp_core.c | 11 +++
  1 file changed, 11 insertions(+)

diff --git a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c 
b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
index c81733b8185e..92fb9a072cb6 100644
--- a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
+++ b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
@@ -1169,6 +1169,17 @@ static int analogix_dp_set_bridge(struct 
analogix_dp_device *dp)
if (ret)
goto out_dp_init;
  
+	/*

+* According to DP spec v1.3 chap 3.5.1.2 Link Training,
+* We should first make sure the HPD signal is asserted high by device
+* when we want to establish a link with it.
+*/
+   ret = analogix_dp_detect_hpd(dp);
+   if (ret) {
+   DRM_ERROR("failed to get hpd single ret = %d\n", ret);
+   goto out_dp_init;
+   }
+
ret = analogix_dp_commit(dp);
if (ret)
goto out_dp_init;



Re: [PATCH v5 10/36] drm/bridge: analogix_dp: Retry bridge enable when it failed

2018-03-14 Thread Archit Taneja



On Saturday 10 March 2018 03:53 AM, Enric Balletbo i Serra wrote:

From: zain wang <w...@rock-chips.com>

When we enable bridge failed, we have to retry it, otherwise we would get
the abnormal display.



Reviewed-by: Archit Taneja <arch...@codeaurora.org>

Thanks,
Archit


Cc: Stéphane Marchesin <marc...@chromium.org>
Signed-off-by: zain wang <w...@rock-chips.com>
Signed-off-by: Sean Paul <seanp...@chromium.org>
Signed-off-by: Thierry Escande <thierry.esca...@collabora.com>
Reviewed-by: Andrzej Hajda <a.ha...@samsung.com>
Signed-off-by: Enric Balletbo i Serra <enric.balle...@collabora.com>
Tested-by: Marek Szyprowski <m.szyprow...@samsung.com>
---

  drivers/gpu/drm/bridge/analogix/analogix_dp_core.c | 65 +-
  drivers/gpu/drm/bridge/analogix/analogix_dp_core.h |  3 +-
  drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c  |  5 +-
  3 files changed, 56 insertions(+), 17 deletions(-)

diff --git a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c 
b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
index ea7a80a989c6..c81733b8185e 100644
--- a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
+++ b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
@@ -43,8 +43,10 @@ struct bridge_init {
struct device_node *node;
  };
  
-static void analogix_dp_init_dp(struct analogix_dp_device *dp)

+static int analogix_dp_init_dp(struct analogix_dp_device *dp)
  {
+   int ret;
+
analogix_dp_reset(dp);
  
  	analogix_dp_swreset(dp);

@@ -56,10 +58,13 @@ static void analogix_dp_init_dp(struct analogix_dp_device 
*dp)
analogix_dp_enable_sw_function(dp);
  
  	analogix_dp_config_interrupt(dp);

-   analogix_dp_init_analog_func(dp);
+   ret = analogix_dp_init_analog_func(dp);
+   if (ret)
+   return ret;
  
  	analogix_dp_init_hpd(dp);

analogix_dp_init_aux(dp);
+   return 0;
  }
  
  static int analogix_dp_detect_hpd(struct analogix_dp_device *dp)

@@ -918,7 +923,7 @@ static irqreturn_t analogix_dp_irq_thread(int irq, void 
*arg)
return IRQ_HANDLED;
  }
  
-static void analogix_dp_commit(struct analogix_dp_device *dp)

+static int analogix_dp_commit(struct analogix_dp_device *dp)
  {
int ret;
  
@@ -928,11 +933,10 @@ static void analogix_dp_commit(struct analogix_dp_device *dp)

DRM_ERROR("failed to disable the panel\n");
}
  
-	ret = readx_poll_timeout(analogix_dp_train_link, dp, ret, !ret, 100,

-DP_TIMEOUT_TRAINING_US * 5);
+   ret = analogix_dp_train_link(dp);
if (ret) {
dev_err(dp->dev, "unable to do link train, ret=%d\n", ret);
-   return;
+   return ret;
}
  
  	analogix_dp_enable_scramble(dp, 1);

@@ -953,6 +957,7 @@ static void analogix_dp_commit(struct analogix_dp_device 
*dp)
dp->psr_enable = analogix_dp_detect_sink_psr(dp);
if (dp->psr_enable)
analogix_dp_enable_sink_psr(dp);
+   return 0;
  }
  
  /*

@@ -1149,12 +1154,9 @@ static void analogix_dp_bridge_pre_enable(struct 
drm_bridge *bridge)
DRM_ERROR("failed to setup the panel ret = %d\n", ret);
  }
  
-static void analogix_dp_bridge_enable(struct drm_bridge *bridge)

+static int analogix_dp_set_bridge(struct analogix_dp_device *dp)
  {
-   struct analogix_dp_device *dp = bridge->driver_private;
-
-   if (dp->dpms_mode == DRM_MODE_DPMS_ON)
-   return;
+   int ret;
  
  	pm_runtime_get_sync(dp->dev);
  
@@ -1162,11 +1164,46 @@ static void analogix_dp_bridge_enable(struct drm_bridge *bridge)

dp->plat_data->power_on(dp->plat_data);
  
  	phy_power_on(dp->phy);

-   analogix_dp_init_dp(dp);
+
+   ret = analogix_dp_init_dp(dp);
+   if (ret)
+   goto out_dp_init;
+
+   ret = analogix_dp_commit(dp);
+   if (ret)
+   goto out_dp_init;
+
enable_irq(dp->irq);
-   analogix_dp_commit(dp);
+   return 0;
  
-	dp->dpms_mode = DRM_MODE_DPMS_ON;

+out_dp_init:
+   phy_power_off(dp->phy);
+   if (dp->plat_data->power_off)
+   dp->plat_data->power_off(dp->plat_data);
+   pm_runtime_put_sync(dp->dev);
+
+   return ret;
+}
+
+static void analogix_dp_bridge_enable(struct drm_bridge *bridge)
+{
+   struct analogix_dp_device *dp = bridge->driver_private;
+   int timeout_loop = 0;
+
+   if (dp->dpms_mode == DRM_MODE_DPMS_ON)
+   return;
+
+   while (timeout_loop < MAX_PLL_LOCK_LOOP) {
+   if (analogix_dp_set_bridge(dp) == 0) {
+   dp->dpms_mode = DRM_MODE_DPMS_ON;
+   return;
+   }
+   dev_err(dp->dev, "failed to set bridge, retry: %d\n",
+   timeout_loop);
+   timeout_loop++;
+   

Re: [PATCH v5 10/36] drm/bridge: analogix_dp: Retry bridge enable when it failed

2018-03-14 Thread Archit Taneja



On Saturday 10 March 2018 03:53 AM, Enric Balletbo i Serra wrote:

From: zain wang 

When we enable bridge failed, we have to retry it, otherwise we would get
the abnormal display.



Reviewed-by: Archit Taneja 

Thanks,
Archit


Cc: Stéphane Marchesin 
Signed-off-by: zain wang 
Signed-off-by: Sean Paul 
Signed-off-by: Thierry Escande 
Reviewed-by: Andrzej Hajda 
Signed-off-by: Enric Balletbo i Serra 
Tested-by: Marek Szyprowski 
---

  drivers/gpu/drm/bridge/analogix/analogix_dp_core.c | 65 +-
  drivers/gpu/drm/bridge/analogix/analogix_dp_core.h |  3 +-
  drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c  |  5 +-
  3 files changed, 56 insertions(+), 17 deletions(-)

diff --git a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c 
b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
index ea7a80a989c6..c81733b8185e 100644
--- a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
+++ b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
@@ -43,8 +43,10 @@ struct bridge_init {
struct device_node *node;
  };
  
-static void analogix_dp_init_dp(struct analogix_dp_device *dp)

+static int analogix_dp_init_dp(struct analogix_dp_device *dp)
  {
+   int ret;
+
analogix_dp_reset(dp);
  
  	analogix_dp_swreset(dp);

@@ -56,10 +58,13 @@ static void analogix_dp_init_dp(struct analogix_dp_device 
*dp)
analogix_dp_enable_sw_function(dp);
  
  	analogix_dp_config_interrupt(dp);

-   analogix_dp_init_analog_func(dp);
+   ret = analogix_dp_init_analog_func(dp);
+   if (ret)
+   return ret;
  
  	analogix_dp_init_hpd(dp);

analogix_dp_init_aux(dp);
+   return 0;
  }
  
  static int analogix_dp_detect_hpd(struct analogix_dp_device *dp)

@@ -918,7 +923,7 @@ static irqreturn_t analogix_dp_irq_thread(int irq, void 
*arg)
return IRQ_HANDLED;
  }
  
-static void analogix_dp_commit(struct analogix_dp_device *dp)

+static int analogix_dp_commit(struct analogix_dp_device *dp)
  {
int ret;
  
@@ -928,11 +933,10 @@ static void analogix_dp_commit(struct analogix_dp_device *dp)

DRM_ERROR("failed to disable the panel\n");
}
  
-	ret = readx_poll_timeout(analogix_dp_train_link, dp, ret, !ret, 100,

-DP_TIMEOUT_TRAINING_US * 5);
+   ret = analogix_dp_train_link(dp);
if (ret) {
dev_err(dp->dev, "unable to do link train, ret=%d\n", ret);
-   return;
+   return ret;
}
  
  	analogix_dp_enable_scramble(dp, 1);

@@ -953,6 +957,7 @@ static void analogix_dp_commit(struct analogix_dp_device 
*dp)
dp->psr_enable = analogix_dp_detect_sink_psr(dp);
if (dp->psr_enable)
analogix_dp_enable_sink_psr(dp);
+   return 0;
  }
  
  /*

@@ -1149,12 +1154,9 @@ static void analogix_dp_bridge_pre_enable(struct 
drm_bridge *bridge)
DRM_ERROR("failed to setup the panel ret = %d\n", ret);
  }
  
-static void analogix_dp_bridge_enable(struct drm_bridge *bridge)

+static int analogix_dp_set_bridge(struct analogix_dp_device *dp)
  {
-   struct analogix_dp_device *dp = bridge->driver_private;
-
-   if (dp->dpms_mode == DRM_MODE_DPMS_ON)
-   return;
+   int ret;
  
  	pm_runtime_get_sync(dp->dev);
  
@@ -1162,11 +1164,46 @@ static void analogix_dp_bridge_enable(struct drm_bridge *bridge)

dp->plat_data->power_on(dp->plat_data);
  
  	phy_power_on(dp->phy);

-   analogix_dp_init_dp(dp);
+
+   ret = analogix_dp_init_dp(dp);
+   if (ret)
+   goto out_dp_init;
+
+   ret = analogix_dp_commit(dp);
+   if (ret)
+   goto out_dp_init;
+
enable_irq(dp->irq);
-   analogix_dp_commit(dp);
+   return 0;
  
-	dp->dpms_mode = DRM_MODE_DPMS_ON;

+out_dp_init:
+   phy_power_off(dp->phy);
+   if (dp->plat_data->power_off)
+   dp->plat_data->power_off(dp->plat_data);
+   pm_runtime_put_sync(dp->dev);
+
+   return ret;
+}
+
+static void analogix_dp_bridge_enable(struct drm_bridge *bridge)
+{
+   struct analogix_dp_device *dp = bridge->driver_private;
+   int timeout_loop = 0;
+
+   if (dp->dpms_mode == DRM_MODE_DPMS_ON)
+   return;
+
+   while (timeout_loop < MAX_PLL_LOCK_LOOP) {
+   if (analogix_dp_set_bridge(dp) == 0) {
+   dp->dpms_mode = DRM_MODE_DPMS_ON;
+   return;
+   }
+   dev_err(dp->dev, "failed to set bridge, retry: %d\n",
+   timeout_loop);
+   timeout_loop++;
+   usleep_range(10, 11);
+   }
+   dev_err(dp->dev, "too many times retry set bridge, give it up\n");
  }
  
  static void analogix_dp_bridge_disable(struct drm_bridge *bridge)

diff --git a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.h 
b/dri

Re: [PATCH v5 09/36] drm/bridge: analogix_dp: Don't use fast link training when panel just powered up

2018-03-14 Thread Archit Taneja



On Saturday 10 March 2018 03:53 AM, Enric Balletbo i Serra wrote:

From: zain wang <w...@rock-chips.com>

Panel would reset its setting when it powers down. It would forget the last
succeeded link training setting. So we can't use the last successful link
training setting to do fast link training. Let's reset fast_train_enable in
analogix_dp_bridge_disable();



Reviewed-by: Archit Taneja <arch...@codeaurora.org>

Thanks,
Archit


Cc: Stéphane Marchesin <marc...@chromium.org>
Signed-off-by: zain wang <w...@rock-chips.com>
Signed-off-by: Sean Paul <seanp...@chromium.org>
Signed-off-by: Thierry Escande <thierry.esca...@collabora.com>
Signed-off-by: Enric Balletbo i Serra <enric.balle...@collabora.com>
Tested-by: Marek Szyprowski <m.szyprow...@samsung.com>
---

  drivers/gpu/drm/bridge/analogix/analogix_dp_core.c | 9 +
  drivers/gpu/drm/bridge/analogix/analogix_dp_core.h | 2 +-
  2 files changed, 6 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c 
b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
index f9661b410cb9..ea7a80a989c6 100644
--- a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
+++ b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
@@ -579,14 +579,14 @@ static int analogix_dp_process_equalizer_training(struct 
analogix_dp_device *dp)
if (retval != 1) {
dev_err(dp->dev, "failed to read downspread %d\n",
retval);
-   dp->fast_train_support = false;
+   dp->fast_train_enable = false;
} else {
-   dp->fast_train_support =
+   dp->fast_train_enable =
(spread & DP_NO_AUX_HANDSHAKE_LINK_TRAINING) ?
true : false;
}
dev_dbg(dp->dev, "fast link training %s\n",
-   dp->fast_train_support ? "supported" : "unsupported");
+   dp->fast_train_enable ? "supported" : "unsupported");
  
  		/* set enhanced mode if available */

analogix_dp_set_enhanced_mode(dp);
@@ -793,7 +793,7 @@ static int analogix_dp_fast_link_train(struct 
analogix_dp_device *dp)
  
  static int analogix_dp_train_link(struct analogix_dp_device *dp)

  {
-   if (dp->fast_train_support)
+   if (dp->fast_train_enable)
return analogix_dp_fast_link_train(dp);
  
  	return analogix_dp_full_link_train(dp, dp->video_info.max_lane_count,

@@ -1197,6 +1197,7 @@ static void analogix_dp_bridge_disable(struct drm_bridge 
*bridge)
DRM_ERROR("failed to setup the panel ret = %d\n", ret);
  
  	dp->psr_enable = false;

+   dp->fast_train_enable = false;
dp->dpms_mode = DRM_MODE_DPMS_OFF;
  }
  
diff --git a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.h b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.h

index 6a96ef7e6934..403ff853464b 100644
--- a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.h
+++ b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.h
@@ -173,7 +173,7 @@ struct analogix_dp_device {
int hpd_gpio;
boolforce_hpd;
boolpsr_enable;
-   boolfast_train_support;
+   boolfast_train_enable;
  
  	struct mutex		panel_lock;

boolpanel_is_modeset;



Re: [PATCH v5 09/36] drm/bridge: analogix_dp: Don't use fast link training when panel just powered up

2018-03-14 Thread Archit Taneja



On Saturday 10 March 2018 03:53 AM, Enric Balletbo i Serra wrote:

From: zain wang 

Panel would reset its setting when it powers down. It would forget the last
succeeded link training setting. So we can't use the last successful link
training setting to do fast link training. Let's reset fast_train_enable in
analogix_dp_bridge_disable();



Reviewed-by: Archit Taneja 

Thanks,
Archit


Cc: Stéphane Marchesin 
Signed-off-by: zain wang 
Signed-off-by: Sean Paul 
Signed-off-by: Thierry Escande 
Signed-off-by: Enric Balletbo i Serra 
Tested-by: Marek Szyprowski 
---

  drivers/gpu/drm/bridge/analogix/analogix_dp_core.c | 9 +
  drivers/gpu/drm/bridge/analogix/analogix_dp_core.h | 2 +-
  2 files changed, 6 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c 
b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
index f9661b410cb9..ea7a80a989c6 100644
--- a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
+++ b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
@@ -579,14 +579,14 @@ static int analogix_dp_process_equalizer_training(struct 
analogix_dp_device *dp)
if (retval != 1) {
dev_err(dp->dev, "failed to read downspread %d\n",
retval);
-   dp->fast_train_support = false;
+   dp->fast_train_enable = false;
} else {
-   dp->fast_train_support =
+   dp->fast_train_enable =
(spread & DP_NO_AUX_HANDSHAKE_LINK_TRAINING) ?
true : false;
}
dev_dbg(dp->dev, "fast link training %s\n",
-   dp->fast_train_support ? "supported" : "unsupported");
+   dp->fast_train_enable ? "supported" : "unsupported");
  
  		/* set enhanced mode if available */

analogix_dp_set_enhanced_mode(dp);
@@ -793,7 +793,7 @@ static int analogix_dp_fast_link_train(struct 
analogix_dp_device *dp)
  
  static int analogix_dp_train_link(struct analogix_dp_device *dp)

  {
-   if (dp->fast_train_support)
+   if (dp->fast_train_enable)
return analogix_dp_fast_link_train(dp);
  
  	return analogix_dp_full_link_train(dp, dp->video_info.max_lane_count,

@@ -1197,6 +1197,7 @@ static void analogix_dp_bridge_disable(struct drm_bridge 
*bridge)
DRM_ERROR("failed to setup the panel ret = %d\n", ret);
  
  	dp->psr_enable = false;

+   dp->fast_train_enable = false;
dp->dpms_mode = DRM_MODE_DPMS_OFF;
  }
  
diff --git a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.h b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.h

index 6a96ef7e6934..403ff853464b 100644
--- a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.h
+++ b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.h
@@ -173,7 +173,7 @@ struct analogix_dp_device {
int hpd_gpio;
boolforce_hpd;
boolpsr_enable;
-   boolfast_train_support;
+   boolfast_train_enable;
  
  	struct mutex		panel_lock;

boolpanel_is_modeset;



Re: [PATCH v5 08/36] drm/bridge: analogix_dp: Check AUX_EN status when doing AUX transfer

2018-03-14 Thread Archit Taneja



On Saturday 10 March 2018 03:52 AM, Enric Balletbo i Serra wrote:

From: Lin Huang <h...@rock-chips.com>

We should check AUX_EN bit to confirm the AUX CH operation is completed.



Reviewed-by: Archit Taneja <arch...@codeaurora.org>

Thanks,
Archit


Cc: Stéphane Marchesin <marc...@chromium.org>
Signed-off-by: Lin Huang <h...@rock-chips.com>
Signed-off-by: zain wang <w...@rock-chips.com>
Signed-off-by: Sean Paul <seanp...@chromium.org>
Signed-off-by: Thierry Escande <thierry.esca...@collabora.com>
Signed-off-by: Enric Balletbo i Serra <enric.balle...@collabora.com>
Tested-by: Marek Szyprowski <m.szyprow...@samsung.com>
---

  drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c | 25 +--
  1 file changed, 14 insertions(+), 11 deletions(-)

diff --git a/drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c 
b/drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c
index 9df2f3ef000c..e78c861b9e06 100644
--- a/drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c
+++ b/drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c
@@ -1073,9 +1073,9 @@ ssize_t analogix_dp_transfer(struct analogix_dp_device 
*dp,
  {
u32 reg;
u8 *buffer = msg->buffer;
-   int timeout_loop = 0;
unsigned int i;
int num_transferred = 0;
+   int ret;
  
  	/* Buffer size of AUX CH is 16 bytes */

if (WARN_ON(msg->size > 16))
@@ -1139,17 +1139,20 @@ ssize_t analogix_dp_transfer(struct analogix_dp_device 
*dp,
  
  	writel(reg, dp->reg_base + ANALOGIX_DP_AUX_CH_CTL_2);
  
-	/* Is AUX CH command reply received? */

+   ret = readx_poll_timeout(readl, dp->reg_base + ANALOGIX_DP_AUX_CH_CTL_2,
+reg, !(reg & AUX_EN), 25, 500 * 1000);
+   if (ret) {
+   dev_err(dp->dev, "AUX CH enable timeout!\n");
+   return -ETIMEDOUT;
+   }
+
/* TODO: Wait for an interrupt instead of looping? */
-   reg = readl(dp->reg_base + ANALOGIX_DP_INT_STA);
-   while (!(reg & RPLY_RECEIV)) {
-   timeout_loop++;
-   if (timeout_loop > DP_TIMEOUT_LOOP_COUNT) {
-   dev_err(dp->dev, "AUX CH command reply failed!\n");
-   return -ETIMEDOUT;
-   }
-   reg = readl(dp->reg_base + ANALOGIX_DP_INT_STA);
-   usleep_range(10, 11);
+   /* Is AUX CH command reply received? */
+   ret = readx_poll_timeout(readl, dp->reg_base + ANALOGIX_DP_INT_STA,
+reg, reg & RPLY_RECEIV, 10, 20 * 1000);
+   if (ret) {
+   dev_err(dp->dev, "AUX CH cmd reply timeout!\n");
+   return -ETIMEDOUT;
}
  
  	/* Clear interrupt source for AUX CH command reply */




Re: [PATCH v5 08/36] drm/bridge: analogix_dp: Check AUX_EN status when doing AUX transfer

2018-03-14 Thread Archit Taneja



On Saturday 10 March 2018 03:52 AM, Enric Balletbo i Serra wrote:

From: Lin Huang 

We should check AUX_EN bit to confirm the AUX CH operation is completed.



Reviewed-by: Archit Taneja 

Thanks,
Archit


Cc: Stéphane Marchesin 
Signed-off-by: Lin Huang 
Signed-off-by: zain wang 
Signed-off-by: Sean Paul 
Signed-off-by: Thierry Escande 
Signed-off-by: Enric Balletbo i Serra 
Tested-by: Marek Szyprowski 
---

  drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c | 25 +--
  1 file changed, 14 insertions(+), 11 deletions(-)

diff --git a/drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c 
b/drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c
index 9df2f3ef000c..e78c861b9e06 100644
--- a/drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c
+++ b/drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c
@@ -1073,9 +1073,9 @@ ssize_t analogix_dp_transfer(struct analogix_dp_device 
*dp,
  {
u32 reg;
u8 *buffer = msg->buffer;
-   int timeout_loop = 0;
unsigned int i;
int num_transferred = 0;
+   int ret;
  
  	/* Buffer size of AUX CH is 16 bytes */

if (WARN_ON(msg->size > 16))
@@ -1139,17 +1139,20 @@ ssize_t analogix_dp_transfer(struct analogix_dp_device 
*dp,
  
  	writel(reg, dp->reg_base + ANALOGIX_DP_AUX_CH_CTL_2);
  
-	/* Is AUX CH command reply received? */

+   ret = readx_poll_timeout(readl, dp->reg_base + ANALOGIX_DP_AUX_CH_CTL_2,
+reg, !(reg & AUX_EN), 25, 500 * 1000);
+   if (ret) {
+   dev_err(dp->dev, "AUX CH enable timeout!\n");
+   return -ETIMEDOUT;
+   }
+
/* TODO: Wait for an interrupt instead of looping? */
-   reg = readl(dp->reg_base + ANALOGIX_DP_INT_STA);
-   while (!(reg & RPLY_RECEIV)) {
-   timeout_loop++;
-   if (timeout_loop > DP_TIMEOUT_LOOP_COUNT) {
-   dev_err(dp->dev, "AUX CH command reply failed!\n");
-   return -ETIMEDOUT;
-   }
-   reg = readl(dp->reg_base + ANALOGIX_DP_INT_STA);
-   usleep_range(10, 11);
+   /* Is AUX CH command reply received? */
+   ret = readx_poll_timeout(readl, dp->reg_base + ANALOGIX_DP_INT_STA,
+reg, reg & RPLY_RECEIV, 10, 20 * 1000);
+   if (ret) {
+   dev_err(dp->dev, "AUX CH cmd reply timeout!\n");
+   return -ETIMEDOUT;
}
  
  	/* Clear interrupt source for AUX CH command reply */




Re: [PATCH v5 07/36] drm/bridge: analogix_dp: Move enable video into config_video()

2018-03-14 Thread Archit Taneja



On Saturday 10 March 2018 03:52 AM, Enric Balletbo i Serra wrote:

From: Lin Huang 

We need to enable video before analogix_dp_is_video_stream_on(), so
we can get the right video stream status.

Cc: 征增 王 
Cc: Stéphane Marchesin 
Signed-off-by: Lin Huang 
Signed-off-by: Sean Paul 
Signed-off-by: Thierry Escande 
Reviewed-by: Andrzej Hajda 
Signed-off-by: Enric Balletbo i Serra 
Tested-by: Marek Szyprowski 
---

  drivers/gpu/drm/bridge/analogix/analogix_dp_core.c | 11 +--
  1 file changed, 5 insertions(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c 
b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
index 5a2e35dc41e3..f9661b410cb9 100644
--- a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
+++ b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
@@ -819,11 +819,10 @@ static int analogix_dp_config_video(struct 
analogix_dp_device *dp)
if (analogix_dp_is_slave_video_stream_clock_on(dp) == 0)
break;
if (timeout_loop > DP_TIMEOUT_LOOP_COUNT) {
-   dev_err(dp->dev, "Timeout of video streamclk ok\n");
+   dev_err(dp->dev, "Timeout of slave video streamclk 
ok\n");
return -ETIMEDOUT;
}
-
-   usleep_range(1, 2);
+   usleep_range(1000, 1001);


Could we briefly explain in the commit message why we need to increase
the delay in the timeout loop? Is it a consequence of calling
analogix_dp_start_video() earlier, or is this the preferred time
mentioned in the specs?

Thanks,
Archit


}
  
  	/* Set to use the register calculated M/N video */

@@ -838,6 +837,9 @@ static int analogix_dp_config_video(struct 
analogix_dp_device *dp)
/* Configure video slave mode */
analogix_dp_enable_video_master(dp, 0);
  
+	/* Enable video */

+   analogix_dp_start_video(dp);
+
timeout_loop = 0;
  
  	for (;;) {

@@ -948,9 +950,6 @@ static void analogix_dp_commit(struct analogix_dp_device 
*dp)
DRM_ERROR("failed to enable the panel\n");
}
  
-	/* Enable video */

-   analogix_dp_start_video(dp);
-
dp->psr_enable = analogix_dp_detect_sink_psr(dp);
if (dp->psr_enable)
analogix_dp_enable_sink_psr(dp);



Re: [PATCH v5 07/36] drm/bridge: analogix_dp: Move enable video into config_video()

2018-03-14 Thread Archit Taneja



On Saturday 10 March 2018 03:52 AM, Enric Balletbo i Serra wrote:

From: Lin Huang 

We need to enable video before analogix_dp_is_video_stream_on(), so
we can get the right video stream status.

Cc: 征增 王 
Cc: Stéphane Marchesin 
Signed-off-by: Lin Huang 
Signed-off-by: Sean Paul 
Signed-off-by: Thierry Escande 
Reviewed-by: Andrzej Hajda 
Signed-off-by: Enric Balletbo i Serra 
Tested-by: Marek Szyprowski 
---

  drivers/gpu/drm/bridge/analogix/analogix_dp_core.c | 11 +--
  1 file changed, 5 insertions(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c 
b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
index 5a2e35dc41e3..f9661b410cb9 100644
--- a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
+++ b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
@@ -819,11 +819,10 @@ static int analogix_dp_config_video(struct 
analogix_dp_device *dp)
if (analogix_dp_is_slave_video_stream_clock_on(dp) == 0)
break;
if (timeout_loop > DP_TIMEOUT_LOOP_COUNT) {
-   dev_err(dp->dev, "Timeout of video streamclk ok\n");
+   dev_err(dp->dev, "Timeout of slave video streamclk 
ok\n");
return -ETIMEDOUT;
}
-
-   usleep_range(1, 2);
+   usleep_range(1000, 1001);


Could we briefly explain in the commit message why we need to increase
the delay in the timeout loop? Is it a consequence of calling
analogix_dp_start_video() earlier, or is this the preferred time
mentioned in the specs?

Thanks,
Archit


}
  
  	/* Set to use the register calculated M/N video */

@@ -838,6 +837,9 @@ static int analogix_dp_config_video(struct 
analogix_dp_device *dp)
/* Configure video slave mode */
analogix_dp_enable_video_master(dp, 0);
  
+	/* Enable video */

+   analogix_dp_start_video(dp);
+
timeout_loop = 0;
  
  	for (;;) {

@@ -948,9 +950,6 @@ static void analogix_dp_commit(struct analogix_dp_device 
*dp)
DRM_ERROR("failed to enable the panel\n");
}
  
-	/* Enable video */

-   analogix_dp_start_video(dp);
-
dp->psr_enable = analogix_dp_detect_sink_psr(dp);
if (dp->psr_enable)
analogix_dp_enable_sink_psr(dp);



Re: [PATCH v5 06/36] drm/rockchip: Only wait for panel ACK on PSR entry

2018-03-13 Thread Archit Taneja



On Saturday 10 March 2018 03:52 AM, Enric Balletbo i Serra wrote:

From: zain wang <w...@rock-chips.com>

We currently wait for the panel to mirror our intended PSR state
before continuing on both PSR enter and PSR exit. This is really
only important to do when we're entering PSR, since we want to
be sure the last frame we pushed is being served from the panel's
internal fb before shutting down the soc blocks (vop/analogix).

This patch changes the behavior such that we only wait for the
panel to complete the PSR transition when we're entering PSR, and
to skip verification when we're exiting.



With the subject fix:

Reviewed-by: Archit Taneja <arch...@codeaurora.org>

Thanks,
Archit


Cc: Stéphane Marchesin <marc...@chromium.org>
Cc: Sonny Rao <sonny...@chromium.org>
Signed-off-by: zain wang <w...@rock-chips.com>
Signed-off-by: Sean Paul <seanp...@chromium.org>
Signed-off-by: Thierry Escande <thierry.esca...@collabora.com>
Signed-off-by: Enric Balletbo i Serra <enric.balle...@collabora.com>
Tested-by: Marek Szyprowski <m.szyprow...@samsung.com>
---

  drivers/gpu/drm/bridge/analogix/analogix_dp_core.c | 4 ++--
  drivers/gpu/drm/bridge/analogix/analogix_dp_core.h | 2 +-
  drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c  | 5 -
  3 files changed, 7 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c 
b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
index 806c3878b3d6..5a2e35dc41e3 100644
--- a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
+++ b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
@@ -125,7 +125,7 @@ int analogix_dp_enable_psr(struct analogix_dp_device *dp)
psr_vsc.DB0 = 0;
psr_vsc.DB1 = EDP_VSC_PSR_STATE_ACTIVE | EDP_VSC_PSR_CRC_VALUES_VALID;
  
-	return analogix_dp_send_psr_spd(dp, _vsc);

+   return analogix_dp_send_psr_spd(dp, _vsc, true);
  }
  EXPORT_SYMBOL_GPL(analogix_dp_enable_psr);
  
@@ -151,7 +151,7 @@ int analogix_dp_disable_psr(struct analogix_dp_device *dp)

if (ret != 1)
dev_err(dp->dev, "Failed to set DP Power0 %d\n", ret);
  
-	return analogix_dp_send_psr_spd(dp, _vsc);

+   return analogix_dp_send_psr_spd(dp, _vsc, false);
  }
  EXPORT_SYMBOL_GPL(analogix_dp_disable_psr);
  
diff --git a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.h b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.h

index 920607d7eb3e..6a96ef7e6934 100644
--- a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.h
+++ b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.h
@@ -253,7 +253,7 @@ void analogix_dp_enable_scrambling(struct 
analogix_dp_device *dp);
  void analogix_dp_disable_scrambling(struct analogix_dp_device *dp);
  void analogix_dp_enable_psr_crc(struct analogix_dp_device *dp);
  int analogix_dp_send_psr_spd(struct analogix_dp_device *dp,
-struct edp_vsc_psr *vsc);
+struct edp_vsc_psr *vsc, bool blocking);
  ssize_t analogix_dp_transfer(struct analogix_dp_device *dp,
 struct drm_dp_aux_msg *msg);
  
diff --git a/drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c b/drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c

index 005a3f7005d2..9df2f3ef000c 100644
--- a/drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c
+++ b/drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c
@@ -1007,7 +1007,7 @@ static ssize_t analogix_dp_get_psr_status(struct 
analogix_dp_device *dp)
  }
  
  int analogix_dp_send_psr_spd(struct analogix_dp_device *dp,

-struct edp_vsc_psr *vsc)
+struct edp_vsc_psr *vsc, bool blocking)
  {
unsigned int val;
int ret;
@@ -1053,6 +1053,9 @@ int analogix_dp_send_psr_spd(struct analogix_dp_device 
*dp,
val |= IF_EN;
writel(val, dp->reg_base + ANALOGIX_DP_PKT_SEND_CTL);
  
+	if (!blocking)

+   return 0;
+
ret = readx_poll_timeout(analogix_dp_get_psr_status, dp, psr_status,
psr_status >= 0 &&
((vsc->DB1 && psr_status == DP_PSR_SINK_ACTIVE_RFB) ||



Re: [PATCH v5 06/36] drm/rockchip: Only wait for panel ACK on PSR entry

2018-03-13 Thread Archit Taneja



On Saturday 10 March 2018 03:52 AM, Enric Balletbo i Serra wrote:

From: zain wang 

We currently wait for the panel to mirror our intended PSR state
before continuing on both PSR enter and PSR exit. This is really
only important to do when we're entering PSR, since we want to
be sure the last frame we pushed is being served from the panel's
internal fb before shutting down the soc blocks (vop/analogix).

This patch changes the behavior such that we only wait for the
panel to complete the PSR transition when we're entering PSR, and
to skip verification when we're exiting.



With the subject fix:

Reviewed-by: Archit Taneja 

Thanks,
Archit


Cc: Stéphane Marchesin 
Cc: Sonny Rao 
Signed-off-by: zain wang 
Signed-off-by: Sean Paul 
Signed-off-by: Thierry Escande 
Signed-off-by: Enric Balletbo i Serra 
Tested-by: Marek Szyprowski 
---

  drivers/gpu/drm/bridge/analogix/analogix_dp_core.c | 4 ++--
  drivers/gpu/drm/bridge/analogix/analogix_dp_core.h | 2 +-
  drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c  | 5 -
  3 files changed, 7 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c 
b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
index 806c3878b3d6..5a2e35dc41e3 100644
--- a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
+++ b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
@@ -125,7 +125,7 @@ int analogix_dp_enable_psr(struct analogix_dp_device *dp)
psr_vsc.DB0 = 0;
psr_vsc.DB1 = EDP_VSC_PSR_STATE_ACTIVE | EDP_VSC_PSR_CRC_VALUES_VALID;
  
-	return analogix_dp_send_psr_spd(dp, _vsc);

+   return analogix_dp_send_psr_spd(dp, _vsc, true);
  }
  EXPORT_SYMBOL_GPL(analogix_dp_enable_psr);
  
@@ -151,7 +151,7 @@ int analogix_dp_disable_psr(struct analogix_dp_device *dp)

if (ret != 1)
dev_err(dp->dev, "Failed to set DP Power0 %d\n", ret);
  
-	return analogix_dp_send_psr_spd(dp, _vsc);

+   return analogix_dp_send_psr_spd(dp, _vsc, false);
  }
  EXPORT_SYMBOL_GPL(analogix_dp_disable_psr);
  
diff --git a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.h b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.h

index 920607d7eb3e..6a96ef7e6934 100644
--- a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.h
+++ b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.h
@@ -253,7 +253,7 @@ void analogix_dp_enable_scrambling(struct 
analogix_dp_device *dp);
  void analogix_dp_disable_scrambling(struct analogix_dp_device *dp);
  void analogix_dp_enable_psr_crc(struct analogix_dp_device *dp);
  int analogix_dp_send_psr_spd(struct analogix_dp_device *dp,
-struct edp_vsc_psr *vsc);
+struct edp_vsc_psr *vsc, bool blocking);
  ssize_t analogix_dp_transfer(struct analogix_dp_device *dp,
 struct drm_dp_aux_msg *msg);
  
diff --git a/drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c b/drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c

index 005a3f7005d2..9df2f3ef000c 100644
--- a/drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c
+++ b/drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c
@@ -1007,7 +1007,7 @@ static ssize_t analogix_dp_get_psr_status(struct 
analogix_dp_device *dp)
  }
  
  int analogix_dp_send_psr_spd(struct analogix_dp_device *dp,

-struct edp_vsc_psr *vsc)
+struct edp_vsc_psr *vsc, bool blocking)
  {
unsigned int val;
int ret;
@@ -1053,6 +1053,9 @@ int analogix_dp_send_psr_spd(struct analogix_dp_device 
*dp,
val |= IF_EN;
writel(val, dp->reg_base + ANALOGIX_DP_PKT_SEND_CTL);
  
+	if (!blocking)

+   return 0;
+
ret = readx_poll_timeout(analogix_dp_get_psr_status, dp, psr_status,
psr_status >= 0 &&
((vsc->DB1 && psr_status == DP_PSR_SINK_ACTIVE_RFB) ||



Re: [PATCH v5 05/36] drm/bridge: analogix_dp: add fast link train for eDP

2018-03-13 Thread Archit Taneja



On Saturday 10 March 2018 03:52 AM, Enric Balletbo i Serra wrote:

From: zain wang <w...@rock-chips.com>

We would meet a short black screen when exit PSR with the full link
training, In this case, we should use fast link train instead of full
link training.

Signed-off-by: zain wang <w...@rock-chips.com>
Signed-off-by: Sean Paul <seanp...@chromium.org>
Signed-off-by: Thierry Escande <thierry.esca...@collabora.com>
Signed-off-by: Enric Balletbo i Serra <enric.balle...@collabora.com>
Tested-by: Marek Szyprowski <m.szyprow...@samsung.com>
---

  drivers/gpu/drm/bridge/analogix/analogix_dp_core.c | 142 -
  drivers/gpu/drm/bridge/analogix/analogix_dp_core.h |   3 +
  2 files changed, 114 insertions(+), 31 deletions(-)

diff --git a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c 
b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
index ee00d3d920e0..806c3878b3d6 100644
--- a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
+++ b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
@@ -10,17 +10,18 @@
  * option) any later version.
  */
  
-#include 

-#include 
-#include 
  #include 
-#include 
+#include 
+#include 
+#include 
  #include 
+#include 
+#include 
+#include 
  #include 
  #include 
-#include 
-#include 
  #include 
+#include 


This re-ordering doesn't seem like it should be a part of this patch,
you can let it stay if it happens to cause conflicts with future
patches. Other than that:

Reviewed-by: Archit Taneja <arch...@codeaurora.org>

Thanks,
Archit

  
  #include 

  #include 
@@ -35,6 +36,8 @@
  
  #define to_dp(nm)	container_of(nm, struct analogix_dp_device, nm)
  
+static const bool verify_fast_training;

+
  struct bridge_init {
struct i2c_client *client;
struct device_node *node;
@@ -528,7 +531,7 @@ static int analogix_dp_process_equalizer_training(struct 
analogix_dp_device *dp)
  {
int lane, lane_count, retval;
u32 reg;
-   u8 link_align, link_status[2], adjust_request[2];
+   u8 link_align, link_status[2], adjust_request[2], spread;
  
  	usleep_range(400, 401);
  
@@ -571,6 +574,20 @@ static int analogix_dp_process_equalizer_training(struct analogix_dp_device *dp)

dev_dbg(dp->dev, "final lane count = %.2x\n",
dp->link_train.lane_count);
  
+		retval = drm_dp_dpcd_readb(>aux, DP_MAX_DOWNSPREAD,

+  );
+   if (retval != 1) {
+   dev_err(dp->dev, "failed to read downspread %d\n",
+   retval);
+   dp->fast_train_support = false;
+   } else {
+   dp->fast_train_support =
+   (spread & DP_NO_AUX_HANDSHAKE_LINK_TRAINING) ?
+   true : false;
+   }
+   dev_dbg(dp->dev, "fast link training %s\n",
+   dp->fast_train_support ? "supported" : "unsupported");
+
/* set enhanced mode if available */
analogix_dp_set_enhanced_mode(dp);
dp->link_train.lt_state = FINISHED;
@@ -627,10 +644,12 @@ static void analogix_dp_get_max_rx_lane_count(struct 
analogix_dp_device *dp,
*lane_count = DPCD_MAX_LANE_COUNT(data);
  }
  
-static void analogix_dp_init_training(struct analogix_dp_device *dp,

- enum link_lane_count_type max_lane,
- int max_rate)
+static int analogix_dp_full_link_train(struct analogix_dp_device *dp,
+  u32 max_lanes, u32 max_rate)
  {
+   int retval = 0;
+   bool training_finished = false;
+
/*
 * MACRO_RST must be applied after the PLL_LOCK to avoid
 * the DP inter pair skew issue for at least 10 us
@@ -656,18 +675,13 @@ static void analogix_dp_init_training(struct 
analogix_dp_device *dp,
}
  
  	/* Setup TX lane count & rate */

-   if (dp->link_train.lane_count > max_lane)
-   dp->link_train.lane_count = max_lane;
+   if (dp->link_train.lane_count > max_lanes)
+   dp->link_train.lane_count = max_lanes;
if (dp->link_train.link_rate > max_rate)
dp->link_train.link_rate = max_rate;
  
  	/* All DP analog module power up */

analogix_dp_set_analog_power_down(dp, POWER_ALL, 0);
-}
-
-static int analogix_dp_sw_link_training(struct analogix_dp_device *dp)
-{
-   int retval = 0, training_finished = 0;
  
  	dp->link_train.lt_state = START;
  
@@ -702,22 +716,88 @@ static int analogix_dp_sw_link_training(struct analogix_dp_device *dp)

return retval;
  }
  
-static int analogix_dp_set_link_train(struct analogix_dp_device *dp,

- u32 count, u32 bwtype)
+static i

Re: [PATCH v5 05/36] drm/bridge: analogix_dp: add fast link train for eDP

2018-03-13 Thread Archit Taneja



On Saturday 10 March 2018 03:52 AM, Enric Balletbo i Serra wrote:

From: zain wang 

We would meet a short black screen when exit PSR with the full link
training, In this case, we should use fast link train instead of full
link training.

Signed-off-by: zain wang 
Signed-off-by: Sean Paul 
Signed-off-by: Thierry Escande 
Signed-off-by: Enric Balletbo i Serra 
Tested-by: Marek Szyprowski 
---

  drivers/gpu/drm/bridge/analogix/analogix_dp_core.c | 142 -
  drivers/gpu/drm/bridge/analogix/analogix_dp_core.h |   3 +
  2 files changed, 114 insertions(+), 31 deletions(-)

diff --git a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c 
b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
index ee00d3d920e0..806c3878b3d6 100644
--- a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
+++ b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
@@ -10,17 +10,18 @@
  * option) any later version.
  */
  
-#include 

-#include 
-#include 
  #include 
-#include 
+#include 
+#include 
+#include 
  #include 
+#include 
+#include 
+#include 
  #include 
  #include 
-#include 
-#include 
  #include 
+#include 


This re-ordering doesn't seem like it should be a part of this patch,
you can let it stay if it happens to cause conflicts with future
patches. Other than that:

Reviewed-by: Archit Taneja 

Thanks,
Archit

  
  #include 

  #include 
@@ -35,6 +36,8 @@
  
  #define to_dp(nm)	container_of(nm, struct analogix_dp_device, nm)
  
+static const bool verify_fast_training;

+
  struct bridge_init {
struct i2c_client *client;
struct device_node *node;
@@ -528,7 +531,7 @@ static int analogix_dp_process_equalizer_training(struct 
analogix_dp_device *dp)
  {
int lane, lane_count, retval;
u32 reg;
-   u8 link_align, link_status[2], adjust_request[2];
+   u8 link_align, link_status[2], adjust_request[2], spread;
  
  	usleep_range(400, 401);
  
@@ -571,6 +574,20 @@ static int analogix_dp_process_equalizer_training(struct analogix_dp_device *dp)

dev_dbg(dp->dev, "final lane count = %.2x\n",
dp->link_train.lane_count);
  
+		retval = drm_dp_dpcd_readb(>aux, DP_MAX_DOWNSPREAD,

+  );
+   if (retval != 1) {
+   dev_err(dp->dev, "failed to read downspread %d\n",
+   retval);
+   dp->fast_train_support = false;
+   } else {
+   dp->fast_train_support =
+   (spread & DP_NO_AUX_HANDSHAKE_LINK_TRAINING) ?
+   true : false;
+   }
+   dev_dbg(dp->dev, "fast link training %s\n",
+   dp->fast_train_support ? "supported" : "unsupported");
+
/* set enhanced mode if available */
analogix_dp_set_enhanced_mode(dp);
dp->link_train.lt_state = FINISHED;
@@ -627,10 +644,12 @@ static void analogix_dp_get_max_rx_lane_count(struct 
analogix_dp_device *dp,
*lane_count = DPCD_MAX_LANE_COUNT(data);
  }
  
-static void analogix_dp_init_training(struct analogix_dp_device *dp,

- enum link_lane_count_type max_lane,
- int max_rate)
+static int analogix_dp_full_link_train(struct analogix_dp_device *dp,
+  u32 max_lanes, u32 max_rate)
  {
+   int retval = 0;
+   bool training_finished = false;
+
/*
 * MACRO_RST must be applied after the PLL_LOCK to avoid
 * the DP inter pair skew issue for at least 10 us
@@ -656,18 +675,13 @@ static void analogix_dp_init_training(struct 
analogix_dp_device *dp,
}
  
  	/* Setup TX lane count & rate */

-   if (dp->link_train.lane_count > max_lane)
-   dp->link_train.lane_count = max_lane;
+   if (dp->link_train.lane_count > max_lanes)
+   dp->link_train.lane_count = max_lanes;
if (dp->link_train.link_rate > max_rate)
dp->link_train.link_rate = max_rate;
  
  	/* All DP analog module power up */

analogix_dp_set_analog_power_down(dp, POWER_ALL, 0);
-}
-
-static int analogix_dp_sw_link_training(struct analogix_dp_device *dp)
-{
-   int retval = 0, training_finished = 0;
  
  	dp->link_train.lt_state = START;
  
@@ -702,22 +716,88 @@ static int analogix_dp_sw_link_training(struct analogix_dp_device *dp)

return retval;
  }
  
-static int analogix_dp_set_link_train(struct analogix_dp_device *dp,

- u32 count, u32 bwtype)
+static int analogix_dp_fast_link_train(struct analogix_dp_device *dp)
  {
-   int i;
-   int retval;
+   int i, ret;
+   u8 link_align, link_status[2];
+   enum pll_status status;
  
-	for (i = 0; i &l

Re: [PATCH v5 03/36] drm/bridge: analogix_dp: Don't change psr while bridge is disabled

2018-03-13 Thread Archit Taneja



On Saturday 10 March 2018 03:52 AM, Enric Balletbo i Serra wrote:

From: zain wang <w...@rock-chips.com>

There is a race between AUX CH bring-up and enabling bridge which will
cause link training to fail. To avoid hitting it, don't change psr state
while enabling the bridge.


Reviewed-by: Archit Taneja <arch...@codeaurora.org>


Cc: Tomeu Vizoso <tomeu.viz...@collabora.com>
Cc: Sean Paul <seanp...@chromium.org>
Signed-off-by: zain wang <w...@rock-chips.com>
Signed-off-by: Caesar Wang <w...@rock-chips.com>
[seanpaul fixed up the commit message a bit and renamed *_supported to 
*_enabled]
Signed-off-by: Sean Paul <seanp...@chromium.org>
Signed-off-by: Thierry Escande <thierry.esca...@collabora.com>
Signed-off-by: Enric Balletbo i Serra <enric.balle...@collabora.com>
Tested-by: Marek Szyprowski <m.szyprow...@samsung.com>
---

  drivers/gpu/drm/bridge/analogix/analogix_dp_core.c | 15 ---
  drivers/gpu/drm/bridge/analogix/analogix_dp_core.h |  2 +-
  drivers/gpu/drm/rockchip/analogix_dp-rockchip.c|  2 +-
  include/drm/bridge/analogix_dp.h   |  2 +-
  4 files changed, 11 insertions(+), 10 deletions(-)

diff --git a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c 
b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
index e738aa6de1af..ee00d3d920e0 100644
--- a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
+++ b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
@@ -98,18 +98,18 @@ static int analogix_dp_detect_hpd(struct analogix_dp_device 
*dp)
return 0;
  }
  
-int analogix_dp_psr_supported(struct analogix_dp_device *dp)

+int analogix_dp_psr_enabled(struct analogix_dp_device *dp)
  {
  
-	return dp->psr_support;

+   return dp->psr_enable;
  }
-EXPORT_SYMBOL_GPL(analogix_dp_psr_supported);
+EXPORT_SYMBOL_GPL(analogix_dp_psr_enabled);
  
  int analogix_dp_enable_psr(struct analogix_dp_device *dp)

  {
struct edp_vsc_psr psr_vsc;
  
-	if (!dp->psr_support)

+   if (!dp->psr_enable)
return 0;
  
  	/* Prepare VSC packet as per EDP 1.4 spec, Table 6.9 */

@@ -131,7 +131,7 @@ int analogix_dp_disable_psr(struct analogix_dp_device *dp)
struct edp_vsc_psr psr_vsc;
int ret;
  
-	if (!dp->psr_support)

+   if (!dp->psr_enable)
return 0;
  
  	/* Prepare VSC packet as per EDP 1.4 spec, Table 6.9 */

@@ -871,8 +871,8 @@ static void analogix_dp_commit(struct analogix_dp_device 
*dp)
/* Enable video */
analogix_dp_start_video(dp);
  
-	dp->psr_support = analogix_dp_detect_sink_psr(dp);

-   if (dp->psr_support)
+   dp->psr_enable = analogix_dp_detect_sink_psr(dp);
+   if (dp->psr_enable)
analogix_dp_enable_sink_psr(dp);
  }
  
@@ -1117,6 +1117,7 @@ static void analogix_dp_bridge_disable(struct drm_bridge *bridge)

if (ret)
DRM_ERROR("failed to setup the panel ret = %d\n", ret);
  
+	dp->psr_enable = false;

dp->dpms_mode = DRM_MODE_DPMS_OFF;
  }
  
diff --git a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.h b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.h

index b039b28d8fcc..e135a42cb19e 100644
--- a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.h
+++ b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.h
@@ -170,7 +170,7 @@ struct analogix_dp_device {
int dpms_mode;
int hpd_gpio;
boolforce_hpd;
-   boolpsr_support;
+   boolpsr_enable;
  
  	struct mutex		panel_lock;

boolpanel_is_modeset;
diff --git a/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c 
b/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c
index 36334839a3f8..3e8bf79bea58 100644
--- a/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c
+++ b/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c
@@ -82,7 +82,7 @@ static void analogix_dp_psr_set(struct drm_encoder *encoder, 
bool enabled)
struct rockchip_dp_device *dp = to_dp(encoder);
int ret;
  
-	if (!analogix_dp_psr_supported(dp->adp))

+   if (!analogix_dp_psr_enabled(dp->adp))
return;
  
  	DRM_DEV_DEBUG(dp->dev, "%s PSR...\n", enabled ? "Entry" : "Exit");

diff --git a/include/drm/bridge/analogix_dp.h b/include/drm/bridge/analogix_dp.h
index 711fff9b6803..e9a1116d2f8e 100644
--- a/include/drm/bridge/analogix_dp.h
+++ b/include/drm/bridge/analogix_dp.h
@@ -41,7 +41,7 @@ struct analogix_dp_plat_data {
 struct drm_connector *);
  };
  
-int analogix_dp_psr_supported(struct analogix_dp_device *dp);

+int analogix_dp_psr_enabled(struct analogix_dp_device *dp);
  int analogix_dp_enable_psr(struct analogix_dp_device *dp);
  int analogix_dp_disable_psr(struct analogix_dp_device *dp);
  



Re: [PATCH v5 03/36] drm/bridge: analogix_dp: Don't change psr while bridge is disabled

2018-03-13 Thread Archit Taneja



On Saturday 10 March 2018 03:52 AM, Enric Balletbo i Serra wrote:

From: zain wang 

There is a race between AUX CH bring-up and enabling bridge which will
cause link training to fail. To avoid hitting it, don't change psr state
while enabling the bridge.


Reviewed-by: Archit Taneja 


Cc: Tomeu Vizoso 
Cc: Sean Paul 
Signed-off-by: zain wang 
Signed-off-by: Caesar Wang 
[seanpaul fixed up the commit message a bit and renamed *_supported to 
*_enabled]
Signed-off-by: Sean Paul 
Signed-off-by: Thierry Escande 
Signed-off-by: Enric Balletbo i Serra 
Tested-by: Marek Szyprowski 
---

  drivers/gpu/drm/bridge/analogix/analogix_dp_core.c | 15 ---
  drivers/gpu/drm/bridge/analogix/analogix_dp_core.h |  2 +-
  drivers/gpu/drm/rockchip/analogix_dp-rockchip.c|  2 +-
  include/drm/bridge/analogix_dp.h   |  2 +-
  4 files changed, 11 insertions(+), 10 deletions(-)

diff --git a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c 
b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
index e738aa6de1af..ee00d3d920e0 100644
--- a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
+++ b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
@@ -98,18 +98,18 @@ static int analogix_dp_detect_hpd(struct analogix_dp_device 
*dp)
return 0;
  }
  
-int analogix_dp_psr_supported(struct analogix_dp_device *dp)

+int analogix_dp_psr_enabled(struct analogix_dp_device *dp)
  {
  
-	return dp->psr_support;

+   return dp->psr_enable;
  }
-EXPORT_SYMBOL_GPL(analogix_dp_psr_supported);
+EXPORT_SYMBOL_GPL(analogix_dp_psr_enabled);
  
  int analogix_dp_enable_psr(struct analogix_dp_device *dp)

  {
struct edp_vsc_psr psr_vsc;
  
-	if (!dp->psr_support)

+   if (!dp->psr_enable)
return 0;
  
  	/* Prepare VSC packet as per EDP 1.4 spec, Table 6.9 */

@@ -131,7 +131,7 @@ int analogix_dp_disable_psr(struct analogix_dp_device *dp)
struct edp_vsc_psr psr_vsc;
int ret;
  
-	if (!dp->psr_support)

+   if (!dp->psr_enable)
return 0;
  
  	/* Prepare VSC packet as per EDP 1.4 spec, Table 6.9 */

@@ -871,8 +871,8 @@ static void analogix_dp_commit(struct analogix_dp_device 
*dp)
/* Enable video */
analogix_dp_start_video(dp);
  
-	dp->psr_support = analogix_dp_detect_sink_psr(dp);

-   if (dp->psr_support)
+   dp->psr_enable = analogix_dp_detect_sink_psr(dp);
+   if (dp->psr_enable)
analogix_dp_enable_sink_psr(dp);
  }
  
@@ -1117,6 +1117,7 @@ static void analogix_dp_bridge_disable(struct drm_bridge *bridge)

if (ret)
DRM_ERROR("failed to setup the panel ret = %d\n", ret);
  
+	dp->psr_enable = false;

dp->dpms_mode = DRM_MODE_DPMS_OFF;
  }
  
diff --git a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.h b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.h

index b039b28d8fcc..e135a42cb19e 100644
--- a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.h
+++ b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.h
@@ -170,7 +170,7 @@ struct analogix_dp_device {
int dpms_mode;
int hpd_gpio;
boolforce_hpd;
-   boolpsr_support;
+   boolpsr_enable;
  
  	struct mutex		panel_lock;

boolpanel_is_modeset;
diff --git a/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c 
b/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c
index 36334839a3f8..3e8bf79bea58 100644
--- a/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c
+++ b/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c
@@ -82,7 +82,7 @@ static void analogix_dp_psr_set(struct drm_encoder *encoder, 
bool enabled)
struct rockchip_dp_device *dp = to_dp(encoder);
int ret;
  
-	if (!analogix_dp_psr_supported(dp->adp))

+   if (!analogix_dp_psr_enabled(dp->adp))
return;
  
  	DRM_DEV_DEBUG(dp->dev, "%s PSR...\n", enabled ? "Entry" : "Exit");

diff --git a/include/drm/bridge/analogix_dp.h b/include/drm/bridge/analogix_dp.h
index 711fff9b6803..e9a1116d2f8e 100644
--- a/include/drm/bridge/analogix_dp.h
+++ b/include/drm/bridge/analogix_dp.h
@@ -41,7 +41,7 @@ struct analogix_dp_plat_data {
 struct drm_connector *);
  };
  
-int analogix_dp_psr_supported(struct analogix_dp_device *dp);

+int analogix_dp_psr_enabled(struct analogix_dp_device *dp);
  int analogix_dp_enable_psr(struct analogix_dp_device *dp);
  int analogix_dp_disable_psr(struct analogix_dp_device *dp);
  



Re: [PATCH v5 01/36] drm/bridge: analogix_dp: detect Sink PSR state after configuring the PSR

2018-03-13 Thread Archit Taneja



On Saturday 10 March 2018 03:52 AM, Enric Balletbo i Serra wrote:

From: Yakir Yang <y...@rock-chips.com>

Make sure the request PSR state takes effect in analogix_dp_send_psr_spd()
function, or print the sink PSR error state if we failed to apply the
requested PSR setting.


Reviewed-by: Archit Taneja <arch...@codeaurora.org>



Cc: 征增 王 <w...@rock-chips.com>
Cc: Stéphane Marchesin <marc...@chromium.org>
Signed-off-by: Yakir Yang <y...@rock-chips.com>
[seanpaul changed timeout loop to a readx poll]
Signed-off-by: Sean Paul <seanp...@chromium.org>
Signed-off-by: Thierry Escande <thierry.esca...@collabora.com>
Signed-off-by: Enric Balletbo i Serra <enric.balle...@collabora.com>
Tested-by: Marek Szyprowski <m.szyprow...@samsung.com>
---

  drivers/gpu/drm/bridge/analogix/analogix_dp_core.c |  6 ++--
  drivers/gpu/drm/bridge/analogix/analogix_dp_core.h |  6 ++--
  drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c  | 35 +++---
  3 files changed, 37 insertions(+), 10 deletions(-)

diff --git a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c 
b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
index a693ab3078f0..e738aa6de1af 100644
--- a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
+++ b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
@@ -122,8 +122,7 @@ int analogix_dp_enable_psr(struct analogix_dp_device *dp)
psr_vsc.DB0 = 0;
psr_vsc.DB1 = EDP_VSC_PSR_STATE_ACTIVE | EDP_VSC_PSR_CRC_VALUES_VALID;
  
-	analogix_dp_send_psr_spd(dp, _vsc);

-   return 0;
+   return analogix_dp_send_psr_spd(dp, _vsc);
  }
  EXPORT_SYMBOL_GPL(analogix_dp_enable_psr);
  
@@ -149,8 +148,7 @@ int analogix_dp_disable_psr(struct analogix_dp_device *dp)

if (ret != 1)
dev_err(dp->dev, "Failed to set DP Power0 %d\n", ret);
  
-	analogix_dp_send_psr_spd(dp, _vsc);

-   return 0;
+   return analogix_dp_send_psr_spd(dp, _vsc);
  }
  EXPORT_SYMBOL_GPL(analogix_dp_disable_psr);
  
diff --git a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.h b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.h

index 5c6a28806129..b039b28d8fcc 100644
--- a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.h
+++ b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.h
@@ -20,6 +20,8 @@
  #define MAX_CR_LOOP 5
  #define MAX_EQ_LOOP 5
  
+#define DP_TIMEOUT_PSR_LOOP_MS			300

+
  /* DP_MAX_LANE_COUNT */
  #define DPCD_ENHANCED_FRAME_CAP(x)(((x) >> 7) & 0x1)
  #define DPCD_MAX_LANE_COUNT(x)((x) & 0x1f)
@@ -247,8 +249,8 @@ void analogix_dp_config_video_slave_mode(struct 
analogix_dp_device *dp);
  void analogix_dp_enable_scrambling(struct analogix_dp_device *dp);
  void analogix_dp_disable_scrambling(struct analogix_dp_device *dp);
  void analogix_dp_enable_psr_crc(struct analogix_dp_device *dp);
-void analogix_dp_send_psr_spd(struct analogix_dp_device *dp,
- struct edp_vsc_psr *vsc);
+int analogix_dp_send_psr_spd(struct analogix_dp_device *dp,
+struct edp_vsc_psr *vsc);
  ssize_t analogix_dp_transfer(struct analogix_dp_device *dp,
 struct drm_dp_aux_msg *msg);
  
diff --git a/drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c b/drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c

index 303083ad28e3..005a3f7005d2 100644
--- a/drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c
+++ b/drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c
@@ -10,10 +10,11 @@
   * option) any later version.
   */
  
-#include 

-#include 
  #include 
+#include 
  #include 
+#include 
+#include 
  
  #include 
  
@@ -992,10 +993,25 @@ void analogix_dp_enable_psr_crc(struct analogix_dp_device *dp)

writel(PSR_VID_CRC_ENABLE, dp->reg_base + ANALOGIX_DP_CRC_CON);
  }
  
-void analogix_dp_send_psr_spd(struct analogix_dp_device *dp,

- struct edp_vsc_psr *vsc)
+static ssize_t analogix_dp_get_psr_status(struct analogix_dp_device *dp)
+{
+   ssize_t val;
+   u8 status;
+
+   val = drm_dp_dpcd_readb(>aux, DP_PSR_STATUS, );
+   if (val < 0) {
+   dev_err(dp->dev, "PSR_STATUS read failed ret=%zd", val);
+   return val;
+   }
+   return status;
+}
+
+int analogix_dp_send_psr_spd(struct analogix_dp_device *dp,
+struct edp_vsc_psr *vsc)
  {
unsigned int val;
+   int ret;
+   ssize_t psr_status;
  
  	/* don't send info frame */

val = readl(dp->reg_base + ANALOGIX_DP_PKT_SEND_CTL);
@@ -1036,6 +1052,17 @@ void analogix_dp_send_psr_spd(struct analogix_dp_device 
*dp,
val = readl(dp->reg_base + ANALOGIX_DP_PKT_SEND_CTL);
val |= IF_EN;
writel(val, dp->reg_base + ANALOGIX_DP_PKT_SEND_CTL);
+
+   ret = readx_poll_timeout(analogix_dp_get_psr_status, dp, psr_status,
+   psr_status >= 0 &&
+   ((vs

Re: [PATCH v5 01/36] drm/bridge: analogix_dp: detect Sink PSR state after configuring the PSR

2018-03-13 Thread Archit Taneja



On Saturday 10 March 2018 03:52 AM, Enric Balletbo i Serra wrote:

From: Yakir Yang 

Make sure the request PSR state takes effect in analogix_dp_send_psr_spd()
function, or print the sink PSR error state if we failed to apply the
requested PSR setting.


Reviewed-by: Archit Taneja 



Cc: 征增 王 
Cc: Stéphane Marchesin 
Signed-off-by: Yakir Yang 
[seanpaul changed timeout loop to a readx poll]
Signed-off-by: Sean Paul 
Signed-off-by: Thierry Escande 
Signed-off-by: Enric Balletbo i Serra 
Tested-by: Marek Szyprowski 
---

  drivers/gpu/drm/bridge/analogix/analogix_dp_core.c |  6 ++--
  drivers/gpu/drm/bridge/analogix/analogix_dp_core.h |  6 ++--
  drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c  | 35 +++---
  3 files changed, 37 insertions(+), 10 deletions(-)

diff --git a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c 
b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
index a693ab3078f0..e738aa6de1af 100644
--- a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
+++ b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
@@ -122,8 +122,7 @@ int analogix_dp_enable_psr(struct analogix_dp_device *dp)
psr_vsc.DB0 = 0;
psr_vsc.DB1 = EDP_VSC_PSR_STATE_ACTIVE | EDP_VSC_PSR_CRC_VALUES_VALID;
  
-	analogix_dp_send_psr_spd(dp, _vsc);

-   return 0;
+   return analogix_dp_send_psr_spd(dp, _vsc);
  }
  EXPORT_SYMBOL_GPL(analogix_dp_enable_psr);
  
@@ -149,8 +148,7 @@ int analogix_dp_disable_psr(struct analogix_dp_device *dp)

if (ret != 1)
dev_err(dp->dev, "Failed to set DP Power0 %d\n", ret);
  
-	analogix_dp_send_psr_spd(dp, _vsc);

-   return 0;
+   return analogix_dp_send_psr_spd(dp, _vsc);
  }
  EXPORT_SYMBOL_GPL(analogix_dp_disable_psr);
  
diff --git a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.h b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.h

index 5c6a28806129..b039b28d8fcc 100644
--- a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.h
+++ b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.h
@@ -20,6 +20,8 @@
  #define MAX_CR_LOOP 5
  #define MAX_EQ_LOOP 5
  
+#define DP_TIMEOUT_PSR_LOOP_MS			300

+
  /* DP_MAX_LANE_COUNT */
  #define DPCD_ENHANCED_FRAME_CAP(x)(((x) >> 7) & 0x1)
  #define DPCD_MAX_LANE_COUNT(x)((x) & 0x1f)
@@ -247,8 +249,8 @@ void analogix_dp_config_video_slave_mode(struct 
analogix_dp_device *dp);
  void analogix_dp_enable_scrambling(struct analogix_dp_device *dp);
  void analogix_dp_disable_scrambling(struct analogix_dp_device *dp);
  void analogix_dp_enable_psr_crc(struct analogix_dp_device *dp);
-void analogix_dp_send_psr_spd(struct analogix_dp_device *dp,
- struct edp_vsc_psr *vsc);
+int analogix_dp_send_psr_spd(struct analogix_dp_device *dp,
+struct edp_vsc_psr *vsc);
  ssize_t analogix_dp_transfer(struct analogix_dp_device *dp,
 struct drm_dp_aux_msg *msg);
  
diff --git a/drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c b/drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c

index 303083ad28e3..005a3f7005d2 100644
--- a/drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c
+++ b/drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c
@@ -10,10 +10,11 @@
   * option) any later version.
   */
  
-#include 

-#include 
  #include 
+#include 
  #include 
+#include 
+#include 
  
  #include 
  
@@ -992,10 +993,25 @@ void analogix_dp_enable_psr_crc(struct analogix_dp_device *dp)

writel(PSR_VID_CRC_ENABLE, dp->reg_base + ANALOGIX_DP_CRC_CON);
  }
  
-void analogix_dp_send_psr_spd(struct analogix_dp_device *dp,

- struct edp_vsc_psr *vsc)
+static ssize_t analogix_dp_get_psr_status(struct analogix_dp_device *dp)
+{
+   ssize_t val;
+   u8 status;
+
+   val = drm_dp_dpcd_readb(>aux, DP_PSR_STATUS, );
+   if (val < 0) {
+   dev_err(dp->dev, "PSR_STATUS read failed ret=%zd", val);
+   return val;
+   }
+   return status;
+}
+
+int analogix_dp_send_psr_spd(struct analogix_dp_device *dp,
+struct edp_vsc_psr *vsc)
  {
unsigned int val;
+   int ret;
+   ssize_t psr_status;
  
  	/* don't send info frame */

val = readl(dp->reg_base + ANALOGIX_DP_PKT_SEND_CTL);
@@ -1036,6 +1052,17 @@ void analogix_dp_send_psr_spd(struct analogix_dp_device 
*dp,
val = readl(dp->reg_base + ANALOGIX_DP_PKT_SEND_CTL);
val |= IF_EN;
writel(val, dp->reg_base + ANALOGIX_DP_PKT_SEND_CTL);
+
+   ret = readx_poll_timeout(analogix_dp_get_psr_status, dp, psr_status,
+   psr_status >= 0 &&
+   ((vsc->DB1 && psr_status == DP_PSR_SINK_ACTIVE_RFB) ||
+   (!vsc->DB1 && psr_status == DP_PSR_SINK_INACTIVE)), 1500,
+   DP_TIMEOUT_PSR_LOOP_MS * 1000);
+   if (ret) {
+   dev_warn(dp->dev, "Failed to apply PSR %d\n&qu

Re: [PATCH v2 0/3] drm: Add LVDS decoder bridge

2018-03-09 Thread Archit Taneja

Hi,

On Friday 09 March 2018 07:21 PM, Jacopo Mondi wrote:

Hello,
after some discussion on the proposed bindings for generic lvds decoder and
Thine THC63LVD1024, I decided to drop the THC63 specific part and just live with
a transparent decoder that does not support any configuration from DT.

Dropping THC63 support to avoid discussion on how to better implement support
for a DRM bridge with 2 input ports and focus on LVDS mode propagation through
bridges as explained in v1 cover letter (for DRM people: please see [1] as why
I find difficult to implement support for bridges with multiple input endpoints)

Same base branch as v1, with same patches for V3M Eagle applied on top.
git://jmondi.org/linux v3m/v4.16-rc3/base

Thanks
j

v1 -> v2:
- Drop support for THC63LVD1024

[1] I had a quick at how to model a DRM bridge with multiple input
ports, and I see a blocker in how DRM identifies and matches bridges using
the devices node in place of the endpoint nodes.

As THC63LVD1024 supports up to 2 LVDS inputs and 2 LVDS outputs, I see only
a few ways to support that:
  1) register 2 drm bridges from the same driver (one for each input/output 
pair)
 but they would both be matches on the same device node when the preceding
 bridge calls "of_drm_find_bridge()".


I think this is the way to go. DRM doesn't say anywhere that we can't 
have 2 drm_bridge-s contained in a single device. About the issue with

of_drm_find_bridge(), if you set the 2 bridge's 'of_node' field to
the bridge1 and bridge2 nodes as shown below, wouldn't that suffice. 
From what I know, we don't necessarily need to set the bridge's of_node

to the device (i.e, thschip) itself.

thschip {
...
ports {
bridge1: port@0 {
...
};

bridge2: port@1 {
...
};
};
};


Thanks,
Archit


  2) register a single bridge with multiple "next bridges", but when the bridge
 gets attached I don't see a way on how to identify on which next bridge
 "drm_bridge_attach()" on, as it depends on the endpoint the current bridge
 has been attached on first, and we don't have that information.
  3) Register more instances of the same chip in DTS, one for each input/output
 pair. They gonna share supplies and gpios, and I don't like that.

I had a quick look at the currently in mainline bridges and none of them has
multiple input endpoints, except for HDMI audio endpoint, which I haven't found
in use in any DTS. I guess the problem has been already debated and maybe solved
in the past, so feel free to point me to other sources.

Jacopo Mondi (3):
   dt-bindings: display: bridge: Document LVDS to parallel decoder
   drm: bridge: Add LVDS decoder driver
   arm64: dts: renesas: Add LVDS decoder to R-Car V3M Eagle

  .../bindings/display/bridge/lvds-decoder.txt   |  42 ++
  arch/arm64/boot/dts/renesas/r8a77970-eagle.dts |  31 +++-
  drivers/gpu/drm/bridge/Kconfig |   8 ++
  drivers/gpu/drm/bridge/Makefile|   1 +
  drivers/gpu/drm/bridge/lvds-decoder.c  | 157 +
  5 files changed, 237 insertions(+), 2 deletions(-)
  create mode 100644 
Documentation/devicetree/bindings/display/bridge/lvds-decoder.txt
  create mode 100644 drivers/gpu/drm/bridge/lvds-decoder.c

--
2.7.4



Re: [PATCH v2 0/3] drm: Add LVDS decoder bridge

2018-03-09 Thread Archit Taneja

Hi,

On Friday 09 March 2018 07:21 PM, Jacopo Mondi wrote:

Hello,
after some discussion on the proposed bindings for generic lvds decoder and
Thine THC63LVD1024, I decided to drop the THC63 specific part and just live with
a transparent decoder that does not support any configuration from DT.

Dropping THC63 support to avoid discussion on how to better implement support
for a DRM bridge with 2 input ports and focus on LVDS mode propagation through
bridges as explained in v1 cover letter (for DRM people: please see [1] as why
I find difficult to implement support for bridges with multiple input endpoints)

Same base branch as v1, with same patches for V3M Eagle applied on top.
git://jmondi.org/linux v3m/v4.16-rc3/base

Thanks
j

v1 -> v2:
- Drop support for THC63LVD1024

[1] I had a quick at how to model a DRM bridge with multiple input
ports, and I see a blocker in how DRM identifies and matches bridges using
the devices node in place of the endpoint nodes.

As THC63LVD1024 supports up to 2 LVDS inputs and 2 LVDS outputs, I see only
a few ways to support that:
  1) register 2 drm bridges from the same driver (one for each input/output 
pair)
 but they would both be matches on the same device node when the preceding
 bridge calls "of_drm_find_bridge()".


I think this is the way to go. DRM doesn't say anywhere that we can't 
have 2 drm_bridge-s contained in a single device. About the issue with

of_drm_find_bridge(), if you set the 2 bridge's 'of_node' field to
the bridge1 and bridge2 nodes as shown below, wouldn't that suffice. 
From what I know, we don't necessarily need to set the bridge's of_node

to the device (i.e, thschip) itself.

thschip {
...
ports {
bridge1: port@0 {
...
};

bridge2: port@1 {
...
};
};
};


Thanks,
Archit


  2) register a single bridge with multiple "next bridges", but when the bridge
 gets attached I don't see a way on how to identify on which next bridge
 "drm_bridge_attach()" on, as it depends on the endpoint the current bridge
 has been attached on first, and we don't have that information.
  3) Register more instances of the same chip in DTS, one for each input/output
 pair. They gonna share supplies and gpios, and I don't like that.

I had a quick look at the currently in mainline bridges and none of them has
multiple input endpoints, except for HDMI audio endpoint, which I haven't found
in use in any DTS. I guess the problem has been already debated and maybe solved
in the past, so feel free to point me to other sources.

Jacopo Mondi (3):
   dt-bindings: display: bridge: Document LVDS to parallel decoder
   drm: bridge: Add LVDS decoder driver
   arm64: dts: renesas: Add LVDS decoder to R-Car V3M Eagle

  .../bindings/display/bridge/lvds-decoder.txt   |  42 ++
  arch/arm64/boot/dts/renesas/r8a77970-eagle.dts |  31 +++-
  drivers/gpu/drm/bridge/Kconfig |   8 ++
  drivers/gpu/drm/bridge/Makefile|   1 +
  drivers/gpu/drm/bridge/lvds-decoder.c  | 157 +
  5 files changed, 237 insertions(+), 2 deletions(-)
  create mode 100644 
Documentation/devicetree/bindings/display/bridge/lvds-decoder.txt
  create mode 100644 drivers/gpu/drm/bridge/lvds-decoder.c

--
2.7.4



Re: [PATCH] drm: bridge: dw-hdmi: Fix overflow workaround for Amlogic Meson GX SoCs

2018-03-06 Thread Archit Taneja

Hi,

On Tuesday 06 March 2018 03:23 PM, Neil Armstrong wrote:

Hi Architt,

On 23/02/2018 12:44, Neil Armstrong wrote:

The Amlogic Meson GX SoCs, embedded the v2.01a controller, has been also
identified needing this workaround.
This patch adds the corresponding version to enable a single iteration for
this specific version.

Fixes: be41fc55f1aa ("drm: bridge: dw-hdmi: Handle overflow workaround based on 
device version")
Signed-off-by: Neil Armstrong 
---
  drivers/gpu/drm/bridge/synopsys/dw-hdmi.c | 3 +++
  1 file changed, 3 insertions(+)

diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c 
b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
index a38db40..f5018f9 100644
--- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
+++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
@@ -1637,6 +1637,8 @@ static void dw_hdmi_clear_overflow(struct dw_hdmi *hdmi)
 * (and possibly on the platform). So far only i.MX6Q (v1.30a) and
 * i.MX6DL (v1.31a) have been identified as needing the workaround, with
 * 4 and 1 iterations respectively.
+* The Amlogic Meson GX SoCs (v2.01a) have been identifies as needing
+* the workaround with a single iteration.


s/identifies/identified


 */
  
  	switch (hdmi->version) {

@@ -1644,6 +1646,7 @@ static void dw_hdmi_clear_overflow(struct dw_hdmi *hdmi)
count = 4;
break;
case 0x131a:
+   case 0x201a:
count = 1;
break;
default:



This fixes a long time issue on Amlogic SoCs, is it ok for you ?


Looks good to me. Feel free to queue it to drm-misc-next.

Thanks,
Archit



Thanks,
Neil



Re: [PATCH] drm: bridge: dw-hdmi: Fix overflow workaround for Amlogic Meson GX SoCs

2018-03-06 Thread Archit Taneja

Hi,

On Tuesday 06 March 2018 03:23 PM, Neil Armstrong wrote:

Hi Architt,

On 23/02/2018 12:44, Neil Armstrong wrote:

The Amlogic Meson GX SoCs, embedded the v2.01a controller, has been also
identified needing this workaround.
This patch adds the corresponding version to enable a single iteration for
this specific version.

Fixes: be41fc55f1aa ("drm: bridge: dw-hdmi: Handle overflow workaround based on 
device version")
Signed-off-by: Neil Armstrong 
---
  drivers/gpu/drm/bridge/synopsys/dw-hdmi.c | 3 +++
  1 file changed, 3 insertions(+)

diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c 
b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
index a38db40..f5018f9 100644
--- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
+++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
@@ -1637,6 +1637,8 @@ static void dw_hdmi_clear_overflow(struct dw_hdmi *hdmi)
 * (and possibly on the platform). So far only i.MX6Q (v1.30a) and
 * i.MX6DL (v1.31a) have been identified as needing the workaround, with
 * 4 and 1 iterations respectively.
+* The Amlogic Meson GX SoCs (v2.01a) have been identifies as needing
+* the workaround with a single iteration.


s/identifies/identified


 */
  
  	switch (hdmi->version) {

@@ -1644,6 +1646,7 @@ static void dw_hdmi_clear_overflow(struct dw_hdmi *hdmi)
count = 4;
break;
case 0x131a:
+   case 0x201a:
count = 1;
break;
default:



This fixes a long time issue on Amlogic SoCs, is it ok for you ?


Looks good to me. Feel free to queue it to drm-misc-next.

Thanks,
Archit



Thanks,
Neil



Re: [PATCH v5 05/12] drm/bridge/synopsys: dw-hdmi: don't clobber drvdata

2018-02-15 Thread Archit Taneja



On Thursday 15 February 2018 01:38 AM, Jernej Skrabec wrote:

dw_hdmi shouldn't set drvdata since some drivers might need to store
it's own data there. Rework dw_hdmi in a way to return struct dw_hdmi
instead to store it in drvdata. This way drivers are responsible to
store and pass structure when needed.

Idea was taken from the following commit:
8242ecbd597d ("drm/bridge/synopsys: stop clobbering drvdata")


Reviewed-by: Archit Taneja <arch...@codeaurora.org>



Cc: p.za...@pengutronix.de
Cc: narmstr...@baylibre.com
Cc: laurent.pinch...@ideasonboard.com
Cc: h...@rock-chips.com
Cc: he...@sntech.de
Acked-by: Neil Armstrong <narmstr...@baylibre.com>
Signed-off-by: Jernej Skrabec <jernej.skra...@siol.net>
---
  drivers/gpu/drm/bridge/synopsys/dw-hdmi.c   | 31 -
  drivers/gpu/drm/imx/dw_hdmi-imx.c   | 13 +---
  drivers/gpu/drm/meson/meson_dw_hdmi.c   | 14 +
  drivers/gpu/drm/rcar-du/rcar_dw_hdmi.c  | 12 +--
  drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c | 13 +---
  include/drm/bridge/dw_hdmi.h| 13 ++--
  6 files changed, 60 insertions(+), 36 deletions(-)

diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c 
b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
index 7d80f4b56683..f9802399cc0d 100644
--- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
+++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
@@ -2543,8 +2543,6 @@ __dw_hdmi_probe(struct platform_device *pdev,
if (hdmi->i2c)
dw_hdmi_i2c_init(hdmi);
  
-	platform_set_drvdata(pdev, hdmi);

-
return hdmi;
  
  err_iahb:

@@ -2594,25 +2592,23 @@ static void __dw_hdmi_remove(struct dw_hdmi *hdmi)
  /* 
-
   * Probe/remove API, used from platforms based on the DRM bridge API.
   */
-int dw_hdmi_probe(struct platform_device *pdev,
- const struct dw_hdmi_plat_data *plat_data)
+struct dw_hdmi *dw_hdmi_probe(struct platform_device *pdev,
+ const struct dw_hdmi_plat_data *plat_data)
  {
struct dw_hdmi *hdmi;
  
  	hdmi = __dw_hdmi_probe(pdev, plat_data);

if (IS_ERR(hdmi))
-   return PTR_ERR(hdmi);
+   return hdmi;
  
  	drm_bridge_add(>bridge);
  
-	return 0;

+   return hdmi;
  }
  EXPORT_SYMBOL_GPL(dw_hdmi_probe);
  
-void dw_hdmi_remove(struct platform_device *pdev)

+void dw_hdmi_remove(struct dw_hdmi *hdmi)
  {
-   struct dw_hdmi *hdmi = platform_get_drvdata(pdev);
-
drm_bridge_remove(>bridge);
  
  	__dw_hdmi_remove(hdmi);

@@ -2622,31 +2618,30 @@ EXPORT_SYMBOL_GPL(dw_hdmi_remove);
  /* 
-
   * Bind/unbind API, used from platforms based on the component framework.
   */
-int dw_hdmi_bind(struct platform_device *pdev, struct drm_encoder *encoder,
-const struct dw_hdmi_plat_data *plat_data)
+struct dw_hdmi *dw_hdmi_bind(struct platform_device *pdev,
+struct drm_encoder *encoder,
+const struct dw_hdmi_plat_data *plat_data)
  {
struct dw_hdmi *hdmi;
int ret;
  
  	hdmi = __dw_hdmi_probe(pdev, plat_data);

if (IS_ERR(hdmi))
-   return PTR_ERR(hdmi);
+   return hdmi;
  
  	ret = drm_bridge_attach(encoder, >bridge, NULL);

if (ret) {
-   dw_hdmi_remove(pdev);
+   dw_hdmi_remove(hdmi);
DRM_ERROR("Failed to initialize bridge with drm\n");
-   return ret;
+   return ERR_PTR(ret);
}
  
-	return 0;

+   return hdmi;
  }
  EXPORT_SYMBOL_GPL(dw_hdmi_bind);
  
-void dw_hdmi_unbind(struct device *dev)

+void dw_hdmi_unbind(struct dw_hdmi *hdmi)
  {
-   struct dw_hdmi *hdmi = dev_get_drvdata(dev);
-
__dw_hdmi_remove(hdmi);
  }
  EXPORT_SYMBOL_GPL(dw_hdmi_unbind);
diff --git a/drivers/gpu/drm/imx/dw_hdmi-imx.c 
b/drivers/gpu/drm/imx/dw_hdmi-imx.c
index b62763aa8706..fe6becdcc29e 100644
--- a/drivers/gpu/drm/imx/dw_hdmi-imx.c
+++ b/drivers/gpu/drm/imx/dw_hdmi-imx.c
@@ -25,6 +25,7 @@
  struct imx_hdmi {
struct device *dev;
struct drm_encoder encoder;
+   struct dw_hdmi *hdmi;
struct regmap *regmap;
  };
  
@@ -239,14 +240,18 @@ static int dw_hdmi_imx_bind(struct device *dev, struct device *master,

drm_encoder_init(drm, encoder, _hdmi_imx_encoder_funcs,
 DRM_MODE_ENCODER_TMDS, NULL);
  
-	ret = dw_hdmi_bind(pdev, encoder, plat_data);

+   platform_set_drvdata(pdev, hdmi);
+
+   hdmi->hdmi = dw_hdmi_bind(pdev, encoder, plat_data);
  
  	/*

 * If dw_hdmi_bind() fails we'll never call dw_hdmi_unbind(),
 * which would have called the encoder cleanup.  Do it manually.
 */
-   if (ret)
+   if (IS_ERR(hdmi->hdmi)) {
+   ret = PTR_ERR(

Re: [PATCH v5 05/12] drm/bridge/synopsys: dw-hdmi: don't clobber drvdata

2018-02-15 Thread Archit Taneja



On Thursday 15 February 2018 01:38 AM, Jernej Skrabec wrote:

dw_hdmi shouldn't set drvdata since some drivers might need to store
it's own data there. Rework dw_hdmi in a way to return struct dw_hdmi
instead to store it in drvdata. This way drivers are responsible to
store and pass structure when needed.

Idea was taken from the following commit:
8242ecbd597d ("drm/bridge/synopsys: stop clobbering drvdata")


Reviewed-by: Archit Taneja 



Cc: p.za...@pengutronix.de
Cc: narmstr...@baylibre.com
Cc: laurent.pinch...@ideasonboard.com
Cc: h...@rock-chips.com
Cc: he...@sntech.de
Acked-by: Neil Armstrong 
Signed-off-by: Jernej Skrabec 
---
  drivers/gpu/drm/bridge/synopsys/dw-hdmi.c   | 31 -
  drivers/gpu/drm/imx/dw_hdmi-imx.c   | 13 +---
  drivers/gpu/drm/meson/meson_dw_hdmi.c   | 14 +
  drivers/gpu/drm/rcar-du/rcar_dw_hdmi.c  | 12 +--
  drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c | 13 +---
  include/drm/bridge/dw_hdmi.h| 13 ++--
  6 files changed, 60 insertions(+), 36 deletions(-)

diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c 
b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
index 7d80f4b56683..f9802399cc0d 100644
--- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
+++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
@@ -2543,8 +2543,6 @@ __dw_hdmi_probe(struct platform_device *pdev,
if (hdmi->i2c)
dw_hdmi_i2c_init(hdmi);
  
-	platform_set_drvdata(pdev, hdmi);

-
return hdmi;
  
  err_iahb:

@@ -2594,25 +2592,23 @@ static void __dw_hdmi_remove(struct dw_hdmi *hdmi)
  /* 
-
   * Probe/remove API, used from platforms based on the DRM bridge API.
   */
-int dw_hdmi_probe(struct platform_device *pdev,
- const struct dw_hdmi_plat_data *plat_data)
+struct dw_hdmi *dw_hdmi_probe(struct platform_device *pdev,
+ const struct dw_hdmi_plat_data *plat_data)
  {
struct dw_hdmi *hdmi;
  
  	hdmi = __dw_hdmi_probe(pdev, plat_data);

if (IS_ERR(hdmi))
-   return PTR_ERR(hdmi);
+   return hdmi;
  
  	drm_bridge_add(>bridge);
  
-	return 0;

+   return hdmi;
  }
  EXPORT_SYMBOL_GPL(dw_hdmi_probe);
  
-void dw_hdmi_remove(struct platform_device *pdev)

+void dw_hdmi_remove(struct dw_hdmi *hdmi)
  {
-   struct dw_hdmi *hdmi = platform_get_drvdata(pdev);
-
drm_bridge_remove(>bridge);
  
  	__dw_hdmi_remove(hdmi);

@@ -2622,31 +2618,30 @@ EXPORT_SYMBOL_GPL(dw_hdmi_remove);
  /* 
-
   * Bind/unbind API, used from platforms based on the component framework.
   */
-int dw_hdmi_bind(struct platform_device *pdev, struct drm_encoder *encoder,
-const struct dw_hdmi_plat_data *plat_data)
+struct dw_hdmi *dw_hdmi_bind(struct platform_device *pdev,
+struct drm_encoder *encoder,
+const struct dw_hdmi_plat_data *plat_data)
  {
struct dw_hdmi *hdmi;
int ret;
  
  	hdmi = __dw_hdmi_probe(pdev, plat_data);

if (IS_ERR(hdmi))
-   return PTR_ERR(hdmi);
+   return hdmi;
  
  	ret = drm_bridge_attach(encoder, >bridge, NULL);

if (ret) {
-   dw_hdmi_remove(pdev);
+   dw_hdmi_remove(hdmi);
DRM_ERROR("Failed to initialize bridge with drm\n");
-   return ret;
+   return ERR_PTR(ret);
}
  
-	return 0;

+   return hdmi;
  }
  EXPORT_SYMBOL_GPL(dw_hdmi_bind);
  
-void dw_hdmi_unbind(struct device *dev)

+void dw_hdmi_unbind(struct dw_hdmi *hdmi)
  {
-   struct dw_hdmi *hdmi = dev_get_drvdata(dev);
-
__dw_hdmi_remove(hdmi);
  }
  EXPORT_SYMBOL_GPL(dw_hdmi_unbind);
diff --git a/drivers/gpu/drm/imx/dw_hdmi-imx.c 
b/drivers/gpu/drm/imx/dw_hdmi-imx.c
index b62763aa8706..fe6becdcc29e 100644
--- a/drivers/gpu/drm/imx/dw_hdmi-imx.c
+++ b/drivers/gpu/drm/imx/dw_hdmi-imx.c
@@ -25,6 +25,7 @@
  struct imx_hdmi {
struct device *dev;
struct drm_encoder encoder;
+   struct dw_hdmi *hdmi;
struct regmap *regmap;
  };
  
@@ -239,14 +240,18 @@ static int dw_hdmi_imx_bind(struct device *dev, struct device *master,

drm_encoder_init(drm, encoder, _hdmi_imx_encoder_funcs,
 DRM_MODE_ENCODER_TMDS, NULL);
  
-	ret = dw_hdmi_bind(pdev, encoder, plat_data);

+   platform_set_drvdata(pdev, hdmi);
+
+   hdmi->hdmi = dw_hdmi_bind(pdev, encoder, plat_data);
  
  	/*

 * If dw_hdmi_bind() fails we'll never call dw_hdmi_unbind(),
 * which would have called the encoder cleanup.  Do it manually.
 */
-   if (ret)
+   if (IS_ERR(hdmi->hdmi)) {
+   ret = PTR_ERR(hdmi->hdmi);
drm_encoder_cleanup(encoder);
+   }
  
  	return

Re: [PATCH v5 04/12] drm/bridge/synopsys: dw-hdmi: Export some PHY related functions

2018-02-15 Thread Archit Taneja



On Thursday 15 February 2018 01:38 AM, Jernej Skrabec wrote:

Parts of PHY code could be useful also for custom PHYs. For example,
Allwinner A83T has custom PHY which is probably Synopsys gen2 PHY
with few additional memory mapped registers, so most of the Synopsys PHY
related code could be reused.

Functions exported here are actually not specific to Synopsys PHYs but
to DWC HDMI controller PHY interface. This means that even if the PHY is
completely custom, i.e. not designed by Synopsys, exported functions can
be useful.


Reviewed-by: Archit Taneja <arch...@codeaurora.org>



Reviewed-by: Neil Armstrong <narmstr...@baylibre.com>
Reviewed-by: Laurent Pinchart <laurent.pinch...@ideasonboard.com>
Signed-off-by: Jernej Skrabec <jernej.skra...@siol.net>
---
  drivers/gpu/drm/bridge/synopsys/dw-hdmi.c | 44 +--
  drivers/gpu/drm/meson/meson_dw_hdmi.c |  8 +++---
  include/drm/bridge/dw_hdmi.h  | 11 
  3 files changed, 45 insertions(+), 18 deletions(-)

diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c 
b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
index 7ca14d7325b5..7d80f4b56683 100644
--- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
+++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
@@ -1037,19 +1037,21 @@ static void dw_hdmi_phy_enable_svsret(struct dw_hdmi 
*hdmi, u8 enable)
 HDMI_PHY_CONF0_SVSRET_MASK);
  }
  
-static void dw_hdmi_phy_gen2_pddq(struct dw_hdmi *hdmi, u8 enable)

+void dw_hdmi_phy_gen2_pddq(struct dw_hdmi *hdmi, u8 enable)
  {
hdmi_mask_writeb(hdmi, enable, HDMI_PHY_CONF0,
 HDMI_PHY_CONF0_GEN2_PDDQ_OFFSET,
 HDMI_PHY_CONF0_GEN2_PDDQ_MASK);
  }
+EXPORT_SYMBOL_GPL(dw_hdmi_phy_gen2_pddq);
  
-static void dw_hdmi_phy_gen2_txpwron(struct dw_hdmi *hdmi, u8 enable)

+void dw_hdmi_phy_gen2_txpwron(struct dw_hdmi *hdmi, u8 enable)
  {
hdmi_mask_writeb(hdmi, enable, HDMI_PHY_CONF0,
 HDMI_PHY_CONF0_GEN2_TXPWRON_OFFSET,
 HDMI_PHY_CONF0_GEN2_TXPWRON_MASK);
  }
+EXPORT_SYMBOL_GPL(dw_hdmi_phy_gen2_txpwron);
  
  static void dw_hdmi_phy_sel_data_en_pol(struct dw_hdmi *hdmi, u8 enable)

  {
@@ -1065,6 +1067,22 @@ static void dw_hdmi_phy_sel_interface_control(struct 
dw_hdmi *hdmi, u8 enable)
 HDMI_PHY_CONF0_SELDIPIF_MASK);
  }
  
+void dw_hdmi_phy_reset(struct dw_hdmi *hdmi)

+{
+   /* PHY reset. The reset signal is active high on Gen2 PHYs. */
+   hdmi_writeb(hdmi, HDMI_MC_PHYRSTZ_PHYRSTZ, HDMI_MC_PHYRSTZ);
+   hdmi_writeb(hdmi, 0, HDMI_MC_PHYRSTZ);
+}
+EXPORT_SYMBOL_GPL(dw_hdmi_phy_reset);
+
+void dw_hdmi_phy_i2c_set_addr(struct dw_hdmi *hdmi, u8 address)
+{
+   hdmi_phy_test_clear(hdmi, 1);
+   hdmi_writeb(hdmi, address, HDMI_PHY_I2CM_SLAVE_ADDR);
+   hdmi_phy_test_clear(hdmi, 0);
+}
+EXPORT_SYMBOL_GPL(dw_hdmi_phy_i2c_set_addr);
+
  static void dw_hdmi_phy_power_off(struct dw_hdmi *hdmi)
  {
const struct dw_hdmi_phy_data *phy = hdmi->phy.data;
@@ -1203,16 +1221,11 @@ static int hdmi_phy_configure(struct dw_hdmi *hdmi)
if (phy->has_svsret)
dw_hdmi_phy_enable_svsret(hdmi, 1);
  
-	/* PHY reset. The reset signal is active high on Gen2 PHYs. */

-   hdmi_writeb(hdmi, HDMI_MC_PHYRSTZ_PHYRSTZ, HDMI_MC_PHYRSTZ);
-   hdmi_writeb(hdmi, 0, HDMI_MC_PHYRSTZ);
+   dw_hdmi_phy_reset(hdmi);
  
  	hdmi_writeb(hdmi, HDMI_MC_HEACPHY_RST_ASSERT, HDMI_MC_HEACPHY_RST);
  
-	hdmi_phy_test_clear(hdmi, 1);

-   hdmi_writeb(hdmi, HDMI_PHY_I2CM_SLAVE_ADDR_PHY_GEN2,
-   HDMI_PHY_I2CM_SLAVE_ADDR);
-   hdmi_phy_test_clear(hdmi, 0);
+   dw_hdmi_phy_i2c_set_addr(hdmi, HDMI_PHY_I2CM_SLAVE_ADDR_PHY_GEN2);
  
  	/* Write to the PHY as configured by the platform */

if (pdata->configure_phy)
@@ -1251,15 +1264,16 @@ static void dw_hdmi_phy_disable(struct dw_hdmi *hdmi, 
void *data)
dw_hdmi_phy_power_off(hdmi);
  }
  
-static enum drm_connector_status dw_hdmi_phy_read_hpd(struct dw_hdmi *hdmi,

- void *data)
+enum drm_connector_status dw_hdmi_phy_read_hpd(struct dw_hdmi *hdmi,
+  void *data)
  {
return hdmi_readb(hdmi, HDMI_PHY_STAT0) & HDMI_PHY_HPD ?
connector_status_connected : connector_status_disconnected;
  }
+EXPORT_SYMBOL_GPL(dw_hdmi_phy_read_hpd);
  
-static void dw_hdmi_phy_update_hpd(struct dw_hdmi *hdmi, void *data,

-  bool force, bool disabled, bool rxsense)
+void dw_hdmi_phy_update_hpd(struct dw_hdmi *hdmi, void *data,
+   bool force, bool disabled, bool rxsense)
  {
u8 old_mask = hdmi->phy_mask;
  
@@ -1271,8 +1285,9 @@ static void dw_hdmi_phy_update_hpd(struct dw_hdmi *hdmi, void *data,

if (old_mask != hdmi->phy_mask)
hdmi_writeb(hdmi, hdmi->phy

Re: [PATCH v5 04/12] drm/bridge/synopsys: dw-hdmi: Export some PHY related functions

2018-02-15 Thread Archit Taneja



On Thursday 15 February 2018 01:38 AM, Jernej Skrabec wrote:

Parts of PHY code could be useful also for custom PHYs. For example,
Allwinner A83T has custom PHY which is probably Synopsys gen2 PHY
with few additional memory mapped registers, so most of the Synopsys PHY
related code could be reused.

Functions exported here are actually not specific to Synopsys PHYs but
to DWC HDMI controller PHY interface. This means that even if the PHY is
completely custom, i.e. not designed by Synopsys, exported functions can
be useful.


Reviewed-by: Archit Taneja 



Reviewed-by: Neil Armstrong 
Reviewed-by: Laurent Pinchart 
Signed-off-by: Jernej Skrabec 
---
  drivers/gpu/drm/bridge/synopsys/dw-hdmi.c | 44 +--
  drivers/gpu/drm/meson/meson_dw_hdmi.c |  8 +++---
  include/drm/bridge/dw_hdmi.h  | 11 
  3 files changed, 45 insertions(+), 18 deletions(-)

diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c 
b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
index 7ca14d7325b5..7d80f4b56683 100644
--- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
+++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
@@ -1037,19 +1037,21 @@ static void dw_hdmi_phy_enable_svsret(struct dw_hdmi 
*hdmi, u8 enable)
 HDMI_PHY_CONF0_SVSRET_MASK);
  }
  
-static void dw_hdmi_phy_gen2_pddq(struct dw_hdmi *hdmi, u8 enable)

+void dw_hdmi_phy_gen2_pddq(struct dw_hdmi *hdmi, u8 enable)
  {
hdmi_mask_writeb(hdmi, enable, HDMI_PHY_CONF0,
 HDMI_PHY_CONF0_GEN2_PDDQ_OFFSET,
 HDMI_PHY_CONF0_GEN2_PDDQ_MASK);
  }
+EXPORT_SYMBOL_GPL(dw_hdmi_phy_gen2_pddq);
  
-static void dw_hdmi_phy_gen2_txpwron(struct dw_hdmi *hdmi, u8 enable)

+void dw_hdmi_phy_gen2_txpwron(struct dw_hdmi *hdmi, u8 enable)
  {
hdmi_mask_writeb(hdmi, enable, HDMI_PHY_CONF0,
 HDMI_PHY_CONF0_GEN2_TXPWRON_OFFSET,
 HDMI_PHY_CONF0_GEN2_TXPWRON_MASK);
  }
+EXPORT_SYMBOL_GPL(dw_hdmi_phy_gen2_txpwron);
  
  static void dw_hdmi_phy_sel_data_en_pol(struct dw_hdmi *hdmi, u8 enable)

  {
@@ -1065,6 +1067,22 @@ static void dw_hdmi_phy_sel_interface_control(struct 
dw_hdmi *hdmi, u8 enable)
 HDMI_PHY_CONF0_SELDIPIF_MASK);
  }
  
+void dw_hdmi_phy_reset(struct dw_hdmi *hdmi)

+{
+   /* PHY reset. The reset signal is active high on Gen2 PHYs. */
+   hdmi_writeb(hdmi, HDMI_MC_PHYRSTZ_PHYRSTZ, HDMI_MC_PHYRSTZ);
+   hdmi_writeb(hdmi, 0, HDMI_MC_PHYRSTZ);
+}
+EXPORT_SYMBOL_GPL(dw_hdmi_phy_reset);
+
+void dw_hdmi_phy_i2c_set_addr(struct dw_hdmi *hdmi, u8 address)
+{
+   hdmi_phy_test_clear(hdmi, 1);
+   hdmi_writeb(hdmi, address, HDMI_PHY_I2CM_SLAVE_ADDR);
+   hdmi_phy_test_clear(hdmi, 0);
+}
+EXPORT_SYMBOL_GPL(dw_hdmi_phy_i2c_set_addr);
+
  static void dw_hdmi_phy_power_off(struct dw_hdmi *hdmi)
  {
const struct dw_hdmi_phy_data *phy = hdmi->phy.data;
@@ -1203,16 +1221,11 @@ static int hdmi_phy_configure(struct dw_hdmi *hdmi)
if (phy->has_svsret)
dw_hdmi_phy_enable_svsret(hdmi, 1);
  
-	/* PHY reset. The reset signal is active high on Gen2 PHYs. */

-   hdmi_writeb(hdmi, HDMI_MC_PHYRSTZ_PHYRSTZ, HDMI_MC_PHYRSTZ);
-   hdmi_writeb(hdmi, 0, HDMI_MC_PHYRSTZ);
+   dw_hdmi_phy_reset(hdmi);
  
  	hdmi_writeb(hdmi, HDMI_MC_HEACPHY_RST_ASSERT, HDMI_MC_HEACPHY_RST);
  
-	hdmi_phy_test_clear(hdmi, 1);

-   hdmi_writeb(hdmi, HDMI_PHY_I2CM_SLAVE_ADDR_PHY_GEN2,
-   HDMI_PHY_I2CM_SLAVE_ADDR);
-   hdmi_phy_test_clear(hdmi, 0);
+   dw_hdmi_phy_i2c_set_addr(hdmi, HDMI_PHY_I2CM_SLAVE_ADDR_PHY_GEN2);
  
  	/* Write to the PHY as configured by the platform */

if (pdata->configure_phy)
@@ -1251,15 +1264,16 @@ static void dw_hdmi_phy_disable(struct dw_hdmi *hdmi, 
void *data)
dw_hdmi_phy_power_off(hdmi);
  }
  
-static enum drm_connector_status dw_hdmi_phy_read_hpd(struct dw_hdmi *hdmi,

- void *data)
+enum drm_connector_status dw_hdmi_phy_read_hpd(struct dw_hdmi *hdmi,
+  void *data)
  {
return hdmi_readb(hdmi, HDMI_PHY_STAT0) & HDMI_PHY_HPD ?
connector_status_connected : connector_status_disconnected;
  }
+EXPORT_SYMBOL_GPL(dw_hdmi_phy_read_hpd);
  
-static void dw_hdmi_phy_update_hpd(struct dw_hdmi *hdmi, void *data,

-  bool force, bool disabled, bool rxsense)
+void dw_hdmi_phy_update_hpd(struct dw_hdmi *hdmi, void *data,
+   bool force, bool disabled, bool rxsense)
  {
u8 old_mask = hdmi->phy_mask;
  
@@ -1271,8 +1285,9 @@ static void dw_hdmi_phy_update_hpd(struct dw_hdmi *hdmi, void *data,

if (old_mask != hdmi->phy_mask)
hdmi_writeb(hdmi, hdmi->phy_mask, HDMI_PHY_MASK0);
  }
+EXPORT_SYMBOL_GPL(dw_hdmi_phy_update_hpd);
  
-static void dw_hdmi_phy_setup_hpd(struct dw_hdmi *hd

Re: [PATCH v5 03/12] drm/bridge/synopsys: dw-hdmi: Enable workaround for v1.32a

2018-02-15 Thread Archit Taneja



On Thursday 15 February 2018 01:38 AM, Jernej Skrabec wrote:

Allwinner SoCs have dw hdmi controller v1.32a which exhibits same
magenta line issue as i.MX6Q and i.MX6DL. Enable workaround for it.

Tests show that one iteration is enough.

Acked-by: Laurent Pinchart <laurent.pinch...@ideasonboard.com>


Reviewed-by: Archit Taneja <arch...@codeaurora.org>


Signed-off-by: Jernej Skrabec <jernej.skra...@siol.net>
---
  drivers/gpu/drm/bridge/synopsys/dw-hdmi.c | 8 +---
  1 file changed, 5 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c 
b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
index a38db40ce990..7ca14d7325b5 100644
--- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
+++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
@@ -1634,9 +1634,10 @@ static void dw_hdmi_clear_overflow(struct dw_hdmi *hdmi)
 * then write one of the FC registers several times.
 *
 * The number of iterations matters and depends on the HDMI TX revision
-* (and possibly on the platform). So far only i.MX6Q (v1.30a) and
-* i.MX6DL (v1.31a) have been identified as needing the workaround, with
-* 4 and 1 iterations respectively.
+* (and possibly on the platform). So far i.MX6Q (v1.30a), i.MX6DL
+* (v1.31a) and multiple Allwinner SoCs (v1.32a) have been identified
+* as needing the workaround, with 4 iterations for v1.30a and 1
+* iteration for others.
 */
  
  	switch (hdmi->version) {

@@ -1644,6 +1645,7 @@ static void dw_hdmi_clear_overflow(struct dw_hdmi *hdmi)
count = 4;
break;
case 0x131a:
+   case 0x132a:
count = 1;
break;
default:



Re: [PATCH v5 03/12] drm/bridge/synopsys: dw-hdmi: Enable workaround for v1.32a

2018-02-15 Thread Archit Taneja



On Thursday 15 February 2018 01:38 AM, Jernej Skrabec wrote:

Allwinner SoCs have dw hdmi controller v1.32a which exhibits same
magenta line issue as i.MX6Q and i.MX6DL. Enable workaround for it.

Tests show that one iteration is enough.

Acked-by: Laurent Pinchart 


Reviewed-by: Archit Taneja 


Signed-off-by: Jernej Skrabec 
---
  drivers/gpu/drm/bridge/synopsys/dw-hdmi.c | 8 +---
  1 file changed, 5 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c 
b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
index a38db40ce990..7ca14d7325b5 100644
--- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
+++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
@@ -1634,9 +1634,10 @@ static void dw_hdmi_clear_overflow(struct dw_hdmi *hdmi)
 * then write one of the FC registers several times.
 *
 * The number of iterations matters and depends on the HDMI TX revision
-* (and possibly on the platform). So far only i.MX6Q (v1.30a) and
-* i.MX6DL (v1.31a) have been identified as needing the workaround, with
-* 4 and 1 iterations respectively.
+* (and possibly on the platform). So far i.MX6Q (v1.30a), i.MX6DL
+* (v1.31a) and multiple Allwinner SoCs (v1.32a) have been identified
+* as needing the workaround, with 4 iterations for v1.30a and 1
+* iteration for others.
 */
  
  	switch (hdmi->version) {

@@ -1644,6 +1645,7 @@ static void dw_hdmi_clear_overflow(struct dw_hdmi *hdmi)
count = 4;
break;
case 0x131a:
+   case 0x132a:
count = 1;
break;
default:



Re: [PATCH v2 1/2] drm/bridge/synopsys: dsi: Add a warning msg on dsi read requests

2018-01-30 Thread Archit Taneja



On 01/26/2018 06:14 AM, Brian Norris wrote:

On Thu, Jan 25, 2018 at 11:37:59AM +0100, Philippe Cornu wrote:

The dcs/generic dsi read feature is not yet implemented so it
is important to warn the host_transfer() caller in case of
read operation requests.

Signed-off-by: Philippe Cornu 


Awesome, thanks.

Reviewed-by: Brian Norris 



Queued to drm-misc-next.

Thanks,
Archit


---
  drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c | 6 ++
  1 file changed, 6 insertions(+)

diff --git a/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c 
b/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c
index daec7881be6d..72ecaeb40822 100644
--- a/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c
+++ b/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c
@@ -405,6 +405,12 @@ static ssize_t dw_mipi_dsi_host_transfer(struct 
mipi_dsi_host *host,
struct mipi_dsi_packet packet;
int ret;
  
+	if (msg->rx_buf || msg->rx_len) {

+   /* TODO dw drv improvements: implement read feature */
+   dev_warn(dsi->dev, "read operations not yet implemented\n");
+   return -EINVAL;
+   }
+
ret = mipi_dsi_create_packet(, msg);
if (ret) {
dev_err(dsi->dev, "failed to create packet: %d\n", ret);
--
2.15.1



--
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
a Linux Foundation Collaborative Project


Re: [PATCH v2 1/2] drm/bridge/synopsys: dsi: Add a warning msg on dsi read requests

2018-01-30 Thread Archit Taneja



On 01/26/2018 06:14 AM, Brian Norris wrote:

On Thu, Jan 25, 2018 at 11:37:59AM +0100, Philippe Cornu wrote:

The dcs/generic dsi read feature is not yet implemented so it
is important to warn the host_transfer() caller in case of
read operation requests.

Signed-off-by: Philippe Cornu 


Awesome, thanks.

Reviewed-by: Brian Norris 



Queued to drm-misc-next.

Thanks,
Archit


---
  drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c | 6 ++
  1 file changed, 6 insertions(+)

diff --git a/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c 
b/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c
index daec7881be6d..72ecaeb40822 100644
--- a/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c
+++ b/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c
@@ -405,6 +405,12 @@ static ssize_t dw_mipi_dsi_host_transfer(struct 
mipi_dsi_host *host,
struct mipi_dsi_packet packet;
int ret;
  
+	if (msg->rx_buf || msg->rx_len) {

+   /* TODO dw drv improvements: implement read feature */
+   dev_warn(dsi->dev, "read operations not yet implemented\n");
+   return -EINVAL;
+   }
+
ret = mipi_dsi_create_packet(, msg);
if (ret) {
dev_err(dsi->dev, "failed to create packet: %d\n", ret);
--
2.15.1



--
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
a Linux Foundation Collaborative Project


Re: [PATCH v2 2/2] drm/bridge/synopsys: dsi: Fix dsi_host_transfer() return value

2018-01-30 Thread Archit Taneja



On 01/26/2018 06:16 AM, Brian Norris wrote:

On Thu, Jan 25, 2018 at 11:38:00AM +0100, Philippe Cornu wrote:

The dw_mipi_dsi_host_transfer() must return the number of
bytes transmitted/received on success instead of 0.
Note: As the read feature is not implemented, only the
transmitted number of bytes is returned for the moment.

Signed-off-by: Philippe Cornu 


Assuming we're going with the current documented semantics (where we
return # of TX bytes for writes), then:

Reviewed-by: Brian Norris 

I believe Archit was suggesting maybe changing that sometime, but that's
no excuse for not matching documentation now.


Queued to drm-misc-next.

Thanks,
Archit




---
  drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c | 11 ++-
  1 file changed, 10 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c 
b/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c
index 72ecaeb40822..090bf62d1ea8 100644
--- a/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c
+++ b/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c
@@ -419,7 +419,16 @@ static ssize_t dw_mipi_dsi_host_transfer(struct 
mipi_dsi_host *host,
  
  	dw_mipi_message_config(dsi, msg);
  
-	return dw_mipi_dsi_write(dsi, );

+   ret = dw_mipi_dsi_write(dsi, );
+   if (ret)
+   return ret;
+
+   /*
+* TODO Only transmitted size is returned as actual driver does
+* not support dcs/generic reads. Please update return value when
+* delivering the read feature.
+*/
+   return packet.size;


You're really holding my hand here, I see :) Thanks I guess.


  }
  
  static const struct mipi_dsi_host_ops dw_mipi_dsi_host_ops = {

--
2.15.1



--
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
a Linux Foundation Collaborative Project


Re: [PATCH v2 2/2] drm/bridge/synopsys: dsi: Fix dsi_host_transfer() return value

2018-01-30 Thread Archit Taneja



On 01/26/2018 06:16 AM, Brian Norris wrote:

On Thu, Jan 25, 2018 at 11:38:00AM +0100, Philippe Cornu wrote:

The dw_mipi_dsi_host_transfer() must return the number of
bytes transmitted/received on success instead of 0.
Note: As the read feature is not implemented, only the
transmitted number of bytes is returned for the moment.

Signed-off-by: Philippe Cornu 


Assuming we're going with the current documented semantics (where we
return # of TX bytes for writes), then:

Reviewed-by: Brian Norris 

I believe Archit was suggesting maybe changing that sometime, but that's
no excuse for not matching documentation now.


Queued to drm-misc-next.

Thanks,
Archit




---
  drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c | 11 ++-
  1 file changed, 10 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c 
b/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c
index 72ecaeb40822..090bf62d1ea8 100644
--- a/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c
+++ b/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c
@@ -419,7 +419,16 @@ static ssize_t dw_mipi_dsi_host_transfer(struct 
mipi_dsi_host *host,
  
  	dw_mipi_message_config(dsi, msg);
  
-	return dw_mipi_dsi_write(dsi, );

+   ret = dw_mipi_dsi_write(dsi, );
+   if (ret)
+   return ret;
+
+   /*
+* TODO Only transmitted size is returned as actual driver does
+* not support dcs/generic reads. Please update return value when
+* delivering the read feature.
+*/
+   return packet.size;


You're really holding my hand here, I see :) Thanks I guess.


  }
  
  static const struct mipi_dsi_host_ops dw_mipi_dsi_host_ops = {

--
2.15.1



--
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
a Linux Foundation Collaborative Project


Re: [PATCH] drm/bridge/synopsys: dsi: use adjusted_mode in mode_set

2018-01-28 Thread Archit Taneja



On 01/26/2018 03:24 PM, Philippe CORNU wrote:

Hi Brian,
And a big thanks for your Tested-by

On 01/25/2018 11:47 PM, Brian Norris wrote:

On Thu, Jan 25, 2018 at 7:55 AM, Philippe Cornu  wrote:

The "adjusted_mode" clock value (ie the real pixel clock) is more
accurate than "mode" clock value (ie the panel/bridge requested
clock value). It offers a better preciseness for timing
computations and allows to reduce the extra dsi bandwidth in
burst mode (from ~20% to ~10-12%, hw platform dependant).

Signed-off-by: Philippe Cornu 
---
Note: This patch replaces "drm/bridge/synopsys: dsi: add optional pixel clock"


These two appear to be the same for my cases, but at least nothing breaks:



In drivers/gpu/drm/rockchip/rockchip_drm_vop.c function
vop_crtc_mode_fixup(), the adjusted_mode->clock (ie. vop px clk output =
dw dsi px clk input) is updated according to rockchip hw pll/dividers...

So you "may" have a different value in adjusted_mode->clock compare to
mode->clock. Maybe there is no difference for the panel you are using
because its px clock matches perfectly with rockchip hw pll/dividers...
or has been set to match with ;-)

I did a similar patch (see [1]) and it works "fine" on stm, the only
difference with the rockchip vop is that clk_round_rate() returns odd
values on stm so I used set/get_rate instead.

So now, both rockchip & stm crtc have an "adjusted_mode->clock" so it
makes sense to use it in dw dsi :)


Could you get the patch [1] queued on drm-misc-next? I can queue this patch
after it.

Thanks,
Archit



Philippe :-)

[1] https://patchwork.freedesktop.org/patch/200720/
"[PATCH] drm/stm: ltdc: use crtc_mode_fixup to update adjusted_mode clock"



Tested-by: Brian Norris 




___
linux-arm-kernel mailing list
linux-arm-ker...@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel



--
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
a Linux Foundation Collaborative Project


Re: [PATCH] drm/bridge/synopsys: dsi: use adjusted_mode in mode_set

2018-01-28 Thread Archit Taneja



On 01/26/2018 03:24 PM, Philippe CORNU wrote:

Hi Brian,
And a big thanks for your Tested-by

On 01/25/2018 11:47 PM, Brian Norris wrote:

On Thu, Jan 25, 2018 at 7:55 AM, Philippe Cornu  wrote:

The "adjusted_mode" clock value (ie the real pixel clock) is more
accurate than "mode" clock value (ie the panel/bridge requested
clock value). It offers a better preciseness for timing
computations and allows to reduce the extra dsi bandwidth in
burst mode (from ~20% to ~10-12%, hw platform dependant).

Signed-off-by: Philippe Cornu 
---
Note: This patch replaces "drm/bridge/synopsys: dsi: add optional pixel clock"


These two appear to be the same for my cases, but at least nothing breaks:



In drivers/gpu/drm/rockchip/rockchip_drm_vop.c function
vop_crtc_mode_fixup(), the adjusted_mode->clock (ie. vop px clk output =
dw dsi px clk input) is updated according to rockchip hw pll/dividers...

So you "may" have a different value in adjusted_mode->clock compare to
mode->clock. Maybe there is no difference for the panel you are using
because its px clock matches perfectly with rockchip hw pll/dividers...
or has been set to match with ;-)

I did a similar patch (see [1]) and it works "fine" on stm, the only
difference with the rockchip vop is that clk_round_rate() returns odd
values on stm so I used set/get_rate instead.

So now, both rockchip & stm crtc have an "adjusted_mode->clock" so it
makes sense to use it in dw dsi :)


Could you get the patch [1] queued on drm-misc-next? I can queue this patch
after it.

Thanks,
Archit



Philippe :-)

[1] https://patchwork.freedesktop.org/patch/200720/
"[PATCH] drm/stm: ltdc: use crtc_mode_fixup to update adjusted_mode clock"



Tested-by: Brian Norris 




___
linux-arm-kernel mailing list
linux-arm-ker...@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel



--
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
a Linux Foundation Collaborative Project


Re: [PATCH 2/2] drm: adv7511: Add support for i2c_new_secondary_device

2018-01-28 Thread Archit Taneja

Hi,

On 01/22/2018 06:20 PM, Kieran Bingham wrote:

The ADV7511 has four 256-byte maps that can be accessed via the main I²C
ports. Each map has it own I²C address and acts as a standard slave
device on the I²C bus.

Allow a device tree node to override the default addresses so that
address conflicts with other devices on the same bus may be resolved at
the board description level.

Signed-off-by: Kieran Bingham 
---
  .../bindings/display/bridge/adi,adv7511.txt| 10 +-
  drivers/gpu/drm/bridge/adv7511/adv7511.h   |  4 +++
  drivers/gpu/drm/bridge/adv7511/adv7511_drv.c   | 36 ++
  3 files changed, 37 insertions(+), 13 deletions(-)

diff --git a/Documentation/devicetree/bindings/display/bridge/adi,adv7511.txt 
b/Documentation/devicetree/bindings/display/bridge/adi,adv7511.txt
index 0047b1394c70..f6bb9f6d3f48 100644
--- a/Documentation/devicetree/bindings/display/bridge/adi,adv7511.txt
+++ b/Documentation/devicetree/bindings/display/bridge/adi,adv7511.txt
@@ -70,6 +70,9 @@ Optional properties:
rather than generate its own timings for HDMI output.
  - clocks: from common clock binding: reference to the CEC clock.
  - clock-names: from common clock binding: must be "cec".
+- reg-names : Names of maps with programmable addresses.
+   It can contain any map needing a non-default address.
+   Possible maps names are : "main", "edid", "cec", "packet"
  
  Required nodes:
  
@@ -88,7 +91,12 @@ Example
  
  	adv7511w: hdmi@39 {

compatible = "adi,adv7511w";
-   reg = <39>;
+   /*
+* The EDID page will be accessible on address 0x66 on the i2c
+* bus. All other maps continue to use their default addresses.
+*/
+   reg = <0x39 0x66>;
+   reg-names = "main", "edid";
interrupt-parent = <>;
interrupts = <29 IRQ_TYPE_EDGE_FALLING>;
clocks = <_clock>;
diff --git a/drivers/gpu/drm/bridge/adv7511/adv7511.h 
b/drivers/gpu/drm/bridge/adv7511/adv7511.h
index d034b2cb5eee..7d81ce3808e0 100644
--- a/drivers/gpu/drm/bridge/adv7511/adv7511.h
+++ b/drivers/gpu/drm/bridge/adv7511/adv7511.h
@@ -53,8 +53,10 @@
  #define ADV7511_REG_POWER 0x41
  #define ADV7511_REG_STATUS0x42
  #define ADV7511_REG_EDID_I2C_ADDR 0x43
+#define ADV7511_REG_EDID_I2C_ADDR_DEFAULT  0x3f
  #define ADV7511_REG_PACKET_ENABLE10x44
  #define ADV7511_REG_PACKET_I2C_ADDR   0x45
+#define ADV7511_REG_PACKET_I2C_ADDR_DEFAULT0x38
  #define ADV7511_REG_DSD_ENABLE0x46
  #define ADV7511_REG_VIDEO_INPUT_CFG2  0x48
  #define ADV7511_REG_INFOFRAME_UPDATE  0x4a
@@ -89,6 +91,7 @@
  #define ADV7511_REG_TMDS_CLOCK_INV0xde
  #define ADV7511_REG_ARC_CTRL  0xdf
  #define ADV7511_REG_CEC_I2C_ADDR  0xe1
+#define ADV7511_REG_CEC_I2C_ADDR_DEFAULT   0x3c


Minor comment: The defines above make look like new register
defines. It would be nice to remove the "REG_" from them, and
place them somewhere after the register definitions.


  #define ADV7511_REG_CEC_CTRL  0xe2
  #define ADV7511_REG_CHIP_ID_HIGH  0xf5
  #define ADV7511_REG_CHIP_ID_LOW   0xf6
@@ -322,6 +325,7 @@ struct adv7511 {
struct i2c_client *i2c_main;
struct i2c_client *i2c_edid;
struct i2c_client *i2c_cec;
+   struct i2c_client *i2c_packet;
  
  	struct regmap *regmap;

struct regmap *regmap_cec;
diff --git a/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c 
b/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c
index efa29db5fc2b..7ec33837752b 100644
--- a/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c
+++ b/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c
@@ -969,8 +969,8 @@ static int adv7511_init_cec_regmap(struct adv7511 *adv)
  {
int ret;
  
-	adv->i2c_cec = i2c_new_dummy(adv->i2c_main->adapter,

-adv->i2c_main->addr - 1);


This patch avoids deriving the CEC/EDID map addresses from the main map. I think this would break 
what the original patch tried to do:


d25a4cbba4b9da7c2d674b2f8ecf84af1b24988e
"drm/bridge: adv7511: add support for the 2nd chip"

Maybe the default macros can be a function of the main address?



+   adv->i2c_cec = i2c_new_secondary_device(adv->i2c_main, "cec",
+   ADV7511_REG_CEC_I2C_ADDR_DEFAULT);


Also, I'm a bit unclear on the default address values. For example, previously, 
the CEC
address was calculated as "adv->i2c_main->addr - 1", which is 0x38. The new 
CEC_I2C_ADDR_DEFAULT
define sets it to 0x3c.

Thanks,
Archit


if (!adv->i2c_cec)
return -ENOMEM;
i2c_set_clientdata(adv->i2c_cec, adv);
@@ -1082,8 +1082,6 @@ static int adv7511_probe(struct i2c_client *i2c, const 
struct i2c_device_id *id)

Re: [PATCH 2/2] drm: adv7511: Add support for i2c_new_secondary_device

2018-01-28 Thread Archit Taneja

Hi,

On 01/22/2018 06:20 PM, Kieran Bingham wrote:

The ADV7511 has four 256-byte maps that can be accessed via the main I²C
ports. Each map has it own I²C address and acts as a standard slave
device on the I²C bus.

Allow a device tree node to override the default addresses so that
address conflicts with other devices on the same bus may be resolved at
the board description level.

Signed-off-by: Kieran Bingham 
---
  .../bindings/display/bridge/adi,adv7511.txt| 10 +-
  drivers/gpu/drm/bridge/adv7511/adv7511.h   |  4 +++
  drivers/gpu/drm/bridge/adv7511/adv7511_drv.c   | 36 ++
  3 files changed, 37 insertions(+), 13 deletions(-)

diff --git a/Documentation/devicetree/bindings/display/bridge/adi,adv7511.txt 
b/Documentation/devicetree/bindings/display/bridge/adi,adv7511.txt
index 0047b1394c70..f6bb9f6d3f48 100644
--- a/Documentation/devicetree/bindings/display/bridge/adi,adv7511.txt
+++ b/Documentation/devicetree/bindings/display/bridge/adi,adv7511.txt
@@ -70,6 +70,9 @@ Optional properties:
rather than generate its own timings for HDMI output.
  - clocks: from common clock binding: reference to the CEC clock.
  - clock-names: from common clock binding: must be "cec".
+- reg-names : Names of maps with programmable addresses.
+   It can contain any map needing a non-default address.
+   Possible maps names are : "main", "edid", "cec", "packet"
  
  Required nodes:
  
@@ -88,7 +91,12 @@ Example
  
  	adv7511w: hdmi@39 {

compatible = "adi,adv7511w";
-   reg = <39>;
+   /*
+* The EDID page will be accessible on address 0x66 on the i2c
+* bus. All other maps continue to use their default addresses.
+*/
+   reg = <0x39 0x66>;
+   reg-names = "main", "edid";
interrupt-parent = <>;
interrupts = <29 IRQ_TYPE_EDGE_FALLING>;
clocks = <_clock>;
diff --git a/drivers/gpu/drm/bridge/adv7511/adv7511.h 
b/drivers/gpu/drm/bridge/adv7511/adv7511.h
index d034b2cb5eee..7d81ce3808e0 100644
--- a/drivers/gpu/drm/bridge/adv7511/adv7511.h
+++ b/drivers/gpu/drm/bridge/adv7511/adv7511.h
@@ -53,8 +53,10 @@
  #define ADV7511_REG_POWER 0x41
  #define ADV7511_REG_STATUS0x42
  #define ADV7511_REG_EDID_I2C_ADDR 0x43
+#define ADV7511_REG_EDID_I2C_ADDR_DEFAULT  0x3f
  #define ADV7511_REG_PACKET_ENABLE10x44
  #define ADV7511_REG_PACKET_I2C_ADDR   0x45
+#define ADV7511_REG_PACKET_I2C_ADDR_DEFAULT0x38
  #define ADV7511_REG_DSD_ENABLE0x46
  #define ADV7511_REG_VIDEO_INPUT_CFG2  0x48
  #define ADV7511_REG_INFOFRAME_UPDATE  0x4a
@@ -89,6 +91,7 @@
  #define ADV7511_REG_TMDS_CLOCK_INV0xde
  #define ADV7511_REG_ARC_CTRL  0xdf
  #define ADV7511_REG_CEC_I2C_ADDR  0xe1
+#define ADV7511_REG_CEC_I2C_ADDR_DEFAULT   0x3c


Minor comment: The defines above make look like new register
defines. It would be nice to remove the "REG_" from them, and
place them somewhere after the register definitions.


  #define ADV7511_REG_CEC_CTRL  0xe2
  #define ADV7511_REG_CHIP_ID_HIGH  0xf5
  #define ADV7511_REG_CHIP_ID_LOW   0xf6
@@ -322,6 +325,7 @@ struct adv7511 {
struct i2c_client *i2c_main;
struct i2c_client *i2c_edid;
struct i2c_client *i2c_cec;
+   struct i2c_client *i2c_packet;
  
  	struct regmap *regmap;

struct regmap *regmap_cec;
diff --git a/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c 
b/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c
index efa29db5fc2b..7ec33837752b 100644
--- a/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c
+++ b/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c
@@ -969,8 +969,8 @@ static int adv7511_init_cec_regmap(struct adv7511 *adv)
  {
int ret;
  
-	adv->i2c_cec = i2c_new_dummy(adv->i2c_main->adapter,

-adv->i2c_main->addr - 1);


This patch avoids deriving the CEC/EDID map addresses from the main map. I think this would break 
what the original patch tried to do:


d25a4cbba4b9da7c2d674b2f8ecf84af1b24988e
"drm/bridge: adv7511: add support for the 2nd chip"

Maybe the default macros can be a function of the main address?



+   adv->i2c_cec = i2c_new_secondary_device(adv->i2c_main, "cec",
+   ADV7511_REG_CEC_I2C_ADDR_DEFAULT);


Also, I'm a bit unclear on the default address values. For example, previously, 
the CEC
address was calculated as "adv->i2c_main->addr - 1", which is 0x38. The new 
CEC_I2C_ADDR_DEFAULT
define sets it to 0x3c.

Thanks,
Archit


if (!adv->i2c_cec)
return -ENOMEM;
i2c_set_clientdata(adv->i2c_cec, adv);
@@ -1082,8 +1082,6 @@ static int adv7511_probe(struct i2c_client *i2c, const 
struct i2c_device_id *id)
struct adv7511_link_config 

Re: [PATCH v2 1/2] drm/bridge/synopsys: dsi: use common mipi_dsi_create_packet()

2018-01-15 Thread Archit Taneja



On 01/10/2018 02:02 AM, Brian Norris wrote:

This takes care of 2 TODOs in this driver, by using the common DSI
packet-marshalling code instead of our custom short/long write code.
This both saves us some duplicated code and gets us free support for
command types that weren't already part of our switch block (e.g.,
MIPI_DSI_GENERIC_LONG_WRITE).

The code logic stays mostly intact, except that it becomes unnecessary
to split the short/long write functions, and we have to copy data a bit
more.

Along the way, I noticed that loop bounds were a little odd:

while (DIV_ROUND_UP(len, pld_data_bytes))

This really was just supposed to be 'len != 0', so I made that more
clear.

Tested on RK3399 with some pending refactoring patches by Nickey Yang,
to make the Rockchip DSI driver wrap this common driver.


Queued to drm-misc-next. Philippe's point about the return value of
mipi_dsi_device_transfer is addressed in a different patch.

Thanks,
Archit



Signed-off-by: Brian Norris 
Reviewed-by: Philippe Cornu 
Tested-by: Philippe Cornu 
---
v2:
  * remove "dcs" naming, since these commands handle generic DSI too, not
just DCS (thanks Philippe)
  * add Philippe's {Tested,Reviewed}-by
---
  drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c | 78 ++-
  1 file changed, 16 insertions(+), 62 deletions(-)

diff --git a/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c 
b/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c
index d9cca4fd66ec..ed91e32ee43a 100644
--- a/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c
+++ b/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c
@@ -136,10 +136,6 @@
 GEN_SW_0P_TX_LP)
  
  #define DSI_GEN_HDR			0x6c

-/* TODO These 2 defines will be reworked thanks to mipi_dsi_create_packet() */
-#define GEN_HDATA(data)(((data) & 0x) << 8)
-#define GEN_HTYPE(type)(((type) & 0xff) << 0)
-
  #define DSI_GEN_PLD_DATA  0x70
  
  #define DSI_CMD_PKT_STATUS		0x74

@@ -359,44 +355,15 @@ static int dw_mipi_dsi_gen_pkt_hdr_write(struct 
dw_mipi_dsi *dsi, u32 hdr_val)
return 0;
  }
  
-static int dw_mipi_dsi_dcs_short_write(struct dw_mipi_dsi *dsi,

-  const struct mipi_dsi_msg *msg)
-{
-   const u8 *tx_buf = msg->tx_buf;
-   u16 data = 0;
-   u32 val;
-
-   if (msg->tx_len > 0)
-   data |= tx_buf[0];
-   if (msg->tx_len > 1)
-   data |= tx_buf[1] << 8;
-
-   if (msg->tx_len > 2) {
-   dev_err(dsi->dev, "too long tx buf length %zu for short 
write\n",
-   msg->tx_len);
-   return -EINVAL;
-   }
-
-   val = GEN_HDATA(data) | GEN_HTYPE(msg->type);
-   return dw_mipi_dsi_gen_pkt_hdr_write(dsi, val);
-}
-
-static int dw_mipi_dsi_dcs_long_write(struct dw_mipi_dsi *dsi,
- const struct mipi_dsi_msg *msg)
+static int dw_mipi_dsi_write(struct dw_mipi_dsi *dsi,
+const struct mipi_dsi_packet *packet)
  {
-   const u8 *tx_buf = msg->tx_buf;
-   int len = msg->tx_len, pld_data_bytes = sizeof(u32), ret;
-   u32 hdr_val = GEN_HDATA(msg->tx_len) | GEN_HTYPE(msg->type);
+   const u8 *tx_buf = packet->payload;
+   int len = packet->payload_length, pld_data_bytes = sizeof(u32), ret;
u32 remainder;
u32 val;
  
-	if (msg->tx_len < 3) {

-   dev_err(dsi->dev, "wrong tx buf length %zu for long write\n",
-   msg->tx_len);
-   return -EINVAL;
-   }
-
-   while (DIV_ROUND_UP(len, pld_data_bytes)) {
+   while (len) {
if (len < pld_data_bytes) {
remainder = 0;
memcpy(, tx_buf, len);
@@ -419,40 +386,27 @@ static int dw_mipi_dsi_dcs_long_write(struct dw_mipi_dsi 
*dsi,
}
}
  
-	return dw_mipi_dsi_gen_pkt_hdr_write(dsi, hdr_val);

+   remainder = 0;
+   memcpy(, packet->header, sizeof(packet->header));
+   return dw_mipi_dsi_gen_pkt_hdr_write(dsi, remainder);
  }
  
  static ssize_t dw_mipi_dsi_host_transfer(struct mipi_dsi_host *host,

 const struct mipi_dsi_msg *msg)
  {
struct dw_mipi_dsi *dsi = host_to_dsi(host);
+   struct mipi_dsi_packet packet;
int ret;
  
-	/*

-* TODO dw drv improvements
-* use mipi_dsi_create_packet() instead of all following
-* functions and code (no switch cases, no
-* dw_mipi_dsi_dcs_short_write(), only the loop in long_write...)
-* and use packet.header...
-*/
-   dw_mipi_message_config(dsi, msg);
-
-   switch (msg->type) {
-   case MIPI_DSI_DCS_SHORT_WRITE:
-   case MIPI_DSI_DCS_SHORT_WRITE_PARAM:
-   case MIPI_DSI_SET_MAXIMUM_RETURN_PACKET_SIZE:
-   ret = 

Re: [PATCH v2 1/2] drm/bridge/synopsys: dsi: use common mipi_dsi_create_packet()

2018-01-15 Thread Archit Taneja



On 01/10/2018 02:02 AM, Brian Norris wrote:

This takes care of 2 TODOs in this driver, by using the common DSI
packet-marshalling code instead of our custom short/long write code.
This both saves us some duplicated code and gets us free support for
command types that weren't already part of our switch block (e.g.,
MIPI_DSI_GENERIC_LONG_WRITE).

The code logic stays mostly intact, except that it becomes unnecessary
to split the short/long write functions, and we have to copy data a bit
more.

Along the way, I noticed that loop bounds were a little odd:

while (DIV_ROUND_UP(len, pld_data_bytes))

This really was just supposed to be 'len != 0', so I made that more
clear.

Tested on RK3399 with some pending refactoring patches by Nickey Yang,
to make the Rockchip DSI driver wrap this common driver.


Queued to drm-misc-next. Philippe's point about the return value of
mipi_dsi_device_transfer is addressed in a different patch.

Thanks,
Archit



Signed-off-by: Brian Norris 
Reviewed-by: Philippe Cornu 
Tested-by: Philippe Cornu 
---
v2:
  * remove "dcs" naming, since these commands handle generic DSI too, not
just DCS (thanks Philippe)
  * add Philippe's {Tested,Reviewed}-by
---
  drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c | 78 ++-
  1 file changed, 16 insertions(+), 62 deletions(-)

diff --git a/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c 
b/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c
index d9cca4fd66ec..ed91e32ee43a 100644
--- a/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c
+++ b/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c
@@ -136,10 +136,6 @@
 GEN_SW_0P_TX_LP)
  
  #define DSI_GEN_HDR			0x6c

-/* TODO These 2 defines will be reworked thanks to mipi_dsi_create_packet() */
-#define GEN_HDATA(data)(((data) & 0x) << 8)
-#define GEN_HTYPE(type)(((type) & 0xff) << 0)
-
  #define DSI_GEN_PLD_DATA  0x70
  
  #define DSI_CMD_PKT_STATUS		0x74

@@ -359,44 +355,15 @@ static int dw_mipi_dsi_gen_pkt_hdr_write(struct 
dw_mipi_dsi *dsi, u32 hdr_val)
return 0;
  }
  
-static int dw_mipi_dsi_dcs_short_write(struct dw_mipi_dsi *dsi,

-  const struct mipi_dsi_msg *msg)
-{
-   const u8 *tx_buf = msg->tx_buf;
-   u16 data = 0;
-   u32 val;
-
-   if (msg->tx_len > 0)
-   data |= tx_buf[0];
-   if (msg->tx_len > 1)
-   data |= tx_buf[1] << 8;
-
-   if (msg->tx_len > 2) {
-   dev_err(dsi->dev, "too long tx buf length %zu for short 
write\n",
-   msg->tx_len);
-   return -EINVAL;
-   }
-
-   val = GEN_HDATA(data) | GEN_HTYPE(msg->type);
-   return dw_mipi_dsi_gen_pkt_hdr_write(dsi, val);
-}
-
-static int dw_mipi_dsi_dcs_long_write(struct dw_mipi_dsi *dsi,
- const struct mipi_dsi_msg *msg)
+static int dw_mipi_dsi_write(struct dw_mipi_dsi *dsi,
+const struct mipi_dsi_packet *packet)
  {
-   const u8 *tx_buf = msg->tx_buf;
-   int len = msg->tx_len, pld_data_bytes = sizeof(u32), ret;
-   u32 hdr_val = GEN_HDATA(msg->tx_len) | GEN_HTYPE(msg->type);
+   const u8 *tx_buf = packet->payload;
+   int len = packet->payload_length, pld_data_bytes = sizeof(u32), ret;
u32 remainder;
u32 val;
  
-	if (msg->tx_len < 3) {

-   dev_err(dsi->dev, "wrong tx buf length %zu for long write\n",
-   msg->tx_len);
-   return -EINVAL;
-   }
-
-   while (DIV_ROUND_UP(len, pld_data_bytes)) {
+   while (len) {
if (len < pld_data_bytes) {
remainder = 0;
memcpy(, tx_buf, len);
@@ -419,40 +386,27 @@ static int dw_mipi_dsi_dcs_long_write(struct dw_mipi_dsi 
*dsi,
}
}
  
-	return dw_mipi_dsi_gen_pkt_hdr_write(dsi, hdr_val);

+   remainder = 0;
+   memcpy(, packet->header, sizeof(packet->header));
+   return dw_mipi_dsi_gen_pkt_hdr_write(dsi, remainder);
  }
  
  static ssize_t dw_mipi_dsi_host_transfer(struct mipi_dsi_host *host,

 const struct mipi_dsi_msg *msg)
  {
struct dw_mipi_dsi *dsi = host_to_dsi(host);
+   struct mipi_dsi_packet packet;
int ret;
  
-	/*

-* TODO dw drv improvements
-* use mipi_dsi_create_packet() instead of all following
-* functions and code (no switch cases, no
-* dw_mipi_dsi_dcs_short_write(), only the loop in long_write...)
-* and use packet.header...
-*/
-   dw_mipi_message_config(dsi, msg);
-
-   switch (msg->type) {
-   case MIPI_DSI_DCS_SHORT_WRITE:
-   case MIPI_DSI_DCS_SHORT_WRITE_PARAM:
-   case MIPI_DSI_SET_MAXIMUM_RETURN_PACKET_SIZE:
-   ret = dw_mipi_dsi_dcs_short_write(dsi, msg);
-   break;
-   case MIPI_DSI_DCS_LONG_WRITE:
-  

Re: [PATCH v2 2/2] drm/bridge/synopsys: dsi: handle endianness correctly in dw_mipi_dsi_write()

2018-01-15 Thread Archit Taneja



On 01/10/2018 08:03 PM, Andrzej Hajda wrote:

On 09.01.2018 21:32, Brian Norris wrote:

We're filling the "remainder" word with little-endian data, then writing
it out to IO registers with endian-correcting writel(). That probably
won't work on big-endian systems.

Let's mark the "remainder" variable as LE32 (since we fill it with
memcpy()) and do the swapping explicitly.

Some of this function could be done more easily without memcpy(), but
the unaligned "remainder" case is a little hard to do without
potentially overrunning 'tx_buf', so I just applied the same solution in
all cases (memcpy() + le32_to_cpu()).

Tested only on a little-endian system.

Signed-off-by: Brian Norris 
---
  drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c | 18 +-
  1 file changed, 9 insertions(+), 9 deletions(-)

diff --git a/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c 
b/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c
index ed91e32ee43a..90f13df6f106 100644
--- a/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c
+++ b/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c
@@ -360,18 +360,18 @@ static int dw_mipi_dsi_write(struct dw_mipi_dsi *dsi,
  {
const u8 *tx_buf = packet->payload;
int len = packet->payload_length, pld_data_bytes = sizeof(u32), ret;
-   u32 remainder;
+   __le32 word;
u32 val;
  
  	while (len) {

if (len < pld_data_bytes) {
-   remainder = 0;
-   memcpy(, tx_buf, len);
-   dsi_write(dsi, DSI_GEN_PLD_DATA, remainder);
+   word = 0;
+   memcpy(, tx_buf, len);
+   dsi_write(dsi, DSI_GEN_PLD_DATA, le32_to_cpu(word));
len = 0;
} else {
-   memcpy(, tx_buf, pld_data_bytes);
-   dsi_write(dsi, DSI_GEN_PLD_DATA, remainder);
+   memcpy(, tx_buf, pld_data_bytes);
+   dsi_write(dsi, DSI_GEN_PLD_DATA, le32_to_cpu(word));
tx_buf += pld_data_bytes;
len -= pld_data_bytes;
}
@@ -386,9 +386,9 @@ static int dw_mipi_dsi_write(struct dw_mipi_dsi *dsi,
}
}
  
-	remainder = 0;

-   memcpy(, packet->header, sizeof(packet->header));
-   return dw_mipi_dsi_gen_pkt_hdr_write(dsi, remainder);
+   word = 0;
+   memcpy(, packet->header, sizeof(packet->header));
+   return dw_mipi_dsi_gen_pkt_hdr_write(dsi, le32_to_cpu(word));


You could create and use appropriate helper, lets say:

u32 le_to_cpup(const u8 *p, int count)
{
     __le32 r = 0;

     memcpy(, p, count);
     return le32_to_cpu(r);
}

With or without this change:
Reviewed-by: Andrzej Hajda 


Queued to drm-misc-next as is.

Thanks,
Archit



  --
Regards
Andrzej



  }
  
  static ssize_t dw_mipi_dsi_host_transfer(struct mipi_dsi_host *host,





--
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
a Linux Foundation Collaborative Project


Re: [PATCH v2 2/2] drm/bridge/synopsys: dsi: handle endianness correctly in dw_mipi_dsi_write()

2018-01-15 Thread Archit Taneja



On 01/10/2018 08:03 PM, Andrzej Hajda wrote:

On 09.01.2018 21:32, Brian Norris wrote:

We're filling the "remainder" word with little-endian data, then writing
it out to IO registers with endian-correcting writel(). That probably
won't work on big-endian systems.

Let's mark the "remainder" variable as LE32 (since we fill it with
memcpy()) and do the swapping explicitly.

Some of this function could be done more easily without memcpy(), but
the unaligned "remainder" case is a little hard to do without
potentially overrunning 'tx_buf', so I just applied the same solution in
all cases (memcpy() + le32_to_cpu()).

Tested only on a little-endian system.

Signed-off-by: Brian Norris 
---
  drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c | 18 +-
  1 file changed, 9 insertions(+), 9 deletions(-)

diff --git a/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c 
b/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c
index ed91e32ee43a..90f13df6f106 100644
--- a/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c
+++ b/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c
@@ -360,18 +360,18 @@ static int dw_mipi_dsi_write(struct dw_mipi_dsi *dsi,
  {
const u8 *tx_buf = packet->payload;
int len = packet->payload_length, pld_data_bytes = sizeof(u32), ret;
-   u32 remainder;
+   __le32 word;
u32 val;
  
  	while (len) {

if (len < pld_data_bytes) {
-   remainder = 0;
-   memcpy(, tx_buf, len);
-   dsi_write(dsi, DSI_GEN_PLD_DATA, remainder);
+   word = 0;
+   memcpy(, tx_buf, len);
+   dsi_write(dsi, DSI_GEN_PLD_DATA, le32_to_cpu(word));
len = 0;
} else {
-   memcpy(, tx_buf, pld_data_bytes);
-   dsi_write(dsi, DSI_GEN_PLD_DATA, remainder);
+   memcpy(, tx_buf, pld_data_bytes);
+   dsi_write(dsi, DSI_GEN_PLD_DATA, le32_to_cpu(word));
tx_buf += pld_data_bytes;
len -= pld_data_bytes;
}
@@ -386,9 +386,9 @@ static int dw_mipi_dsi_write(struct dw_mipi_dsi *dsi,
}
}
  
-	remainder = 0;

-   memcpy(, packet->header, sizeof(packet->header));
-   return dw_mipi_dsi_gen_pkt_hdr_write(dsi, remainder);
+   word = 0;
+   memcpy(, packet->header, sizeof(packet->header));
+   return dw_mipi_dsi_gen_pkt_hdr_write(dsi, le32_to_cpu(word));


You could create and use appropriate helper, lets say:

u32 le_to_cpup(const u8 *p, int count)
{
     __le32 r = 0;

     memcpy(, p, count);
     return le32_to_cpu(r);
}

With or without this change:
Reviewed-by: Andrzej Hajda 


Queued to drm-misc-next as is.

Thanks,
Archit



  --
Regards
Andrzej



  }
  
  static ssize_t dw_mipi_dsi_host_transfer(struct mipi_dsi_host *host,





--
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
a Linux Foundation Collaborative Project


Re: [PATCH v7 4/8] drm/rockchip: dw-mipi-dsi: Fix error handling path

2018-01-10 Thread Archit Taneja



On 01/09/2018 08:18 PM, Thierry Escande wrote:

From: Jeffy Chen 

Add missing pm_runtime_disable() in bind()'s error handling path.

Also cleanup encoder & connector in unbind().


I guess you'll need to drop this commit if this patch goes in first:

https://patchwork.kernel.org/patch/10106105/

Thanks,
Archit



Fixes: 80a9a059d4e4 ("drm/rockchip/dsi: add dw-mipi power domain support")
Signed-off-by: Jeffy Chen 
Signed-off-by: Thierry Escande 
---
  drivers/gpu/drm/rockchip/dw-mipi-dsi.c | 21 +
  1 file changed, 13 insertions(+), 8 deletions(-)

diff --git a/drivers/gpu/drm/rockchip/dw-mipi-dsi.c 
b/drivers/gpu/drm/rockchip/dw-mipi-dsi.c
index b1fe0639227e..78e6b7919bf7 100644
--- a/drivers/gpu/drm/rockchip/dw-mipi-dsi.c
+++ b/drivers/gpu/drm/rockchip/dw-mipi-dsi.c
@@ -1282,7 +1282,7 @@ static int dw_mipi_dsi_bind(struct device *dev, struct 
device *master,
ret = dw_mipi_dsi_register(drm, dsi);
if (ret) {
DRM_DEV_ERROR(dev, "Failed to register mipi_dsi: %d\n", ret);
-   goto err_pllref;
+   goto err_disable_pllref;
}
  
  	dsi->dsi_host.ops = _mipi_dsi_host_ops;

@@ -1290,24 +1290,25 @@ static int dw_mipi_dsi_bind(struct device *dev, struct 
device *master,
ret = mipi_dsi_host_register(>dsi_host);
if (ret) {
DRM_DEV_ERROR(dev, "Failed to register MIPI host: %d\n", ret);
-   goto err_cleanup;
+   goto err_disable_pm_runtime;
}
  
  	if (!dsi->panel) {

ret = -EPROBE_DEFER;
-   goto err_mipi_dsi_host;
+   goto err_unreg_mipi_dsi_host;
}
  
  	dev_set_drvdata(dev, dsi);

pm_runtime_enable(dev);
return 0;
  
-err_mipi_dsi_host:

+err_unreg_mipi_dsi_host:
mipi_dsi_host_unregister(>dsi_host);
-err_cleanup:
-   drm_encoder_cleanup(>encoder);
-   drm_connector_cleanup(>connector);
-err_pllref:
+err_disable_pm_runtime:
+   pm_runtime_disable(dev);
+   dsi->connector.funcs->destroy(>connector);
+   dsi->encoder.funcs->destroy(>encoder);
+err_disable_pllref:
clk_disable_unprepare(dsi->pllref_clk);
return ret;
  }
@@ -1319,6 +1320,10 @@ static void dw_mipi_dsi_unbind(struct device *dev, 
struct device *master,
  
  	mipi_dsi_host_unregister(>dsi_host);

pm_runtime_disable(dev);
+
+   dsi->connector.funcs->destroy(>connector);
+   dsi->encoder.funcs->destroy(>encoder);
+
clk_disable_unprepare(dsi->pllref_clk);
  }
  



--
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
a Linux Foundation Collaborative Project


Re: [PATCH v7 4/8] drm/rockchip: dw-mipi-dsi: Fix error handling path

2018-01-10 Thread Archit Taneja



On 01/09/2018 08:18 PM, Thierry Escande wrote:

From: Jeffy Chen 

Add missing pm_runtime_disable() in bind()'s error handling path.

Also cleanup encoder & connector in unbind().


I guess you'll need to drop this commit if this patch goes in first:

https://patchwork.kernel.org/patch/10106105/

Thanks,
Archit



Fixes: 80a9a059d4e4 ("drm/rockchip/dsi: add dw-mipi power domain support")
Signed-off-by: Jeffy Chen 
Signed-off-by: Thierry Escande 
---
  drivers/gpu/drm/rockchip/dw-mipi-dsi.c | 21 +
  1 file changed, 13 insertions(+), 8 deletions(-)

diff --git a/drivers/gpu/drm/rockchip/dw-mipi-dsi.c 
b/drivers/gpu/drm/rockchip/dw-mipi-dsi.c
index b1fe0639227e..78e6b7919bf7 100644
--- a/drivers/gpu/drm/rockchip/dw-mipi-dsi.c
+++ b/drivers/gpu/drm/rockchip/dw-mipi-dsi.c
@@ -1282,7 +1282,7 @@ static int dw_mipi_dsi_bind(struct device *dev, struct 
device *master,
ret = dw_mipi_dsi_register(drm, dsi);
if (ret) {
DRM_DEV_ERROR(dev, "Failed to register mipi_dsi: %d\n", ret);
-   goto err_pllref;
+   goto err_disable_pllref;
}
  
  	dsi->dsi_host.ops = _mipi_dsi_host_ops;

@@ -1290,24 +1290,25 @@ static int dw_mipi_dsi_bind(struct device *dev, struct 
device *master,
ret = mipi_dsi_host_register(>dsi_host);
if (ret) {
DRM_DEV_ERROR(dev, "Failed to register MIPI host: %d\n", ret);
-   goto err_cleanup;
+   goto err_disable_pm_runtime;
}
  
  	if (!dsi->panel) {

ret = -EPROBE_DEFER;
-   goto err_mipi_dsi_host;
+   goto err_unreg_mipi_dsi_host;
}
  
  	dev_set_drvdata(dev, dsi);

pm_runtime_enable(dev);
return 0;
  
-err_mipi_dsi_host:

+err_unreg_mipi_dsi_host:
mipi_dsi_host_unregister(>dsi_host);
-err_cleanup:
-   drm_encoder_cleanup(>encoder);
-   drm_connector_cleanup(>connector);
-err_pllref:
+err_disable_pm_runtime:
+   pm_runtime_disable(dev);
+   dsi->connector.funcs->destroy(>connector);
+   dsi->encoder.funcs->destroy(>encoder);
+err_disable_pllref:
clk_disable_unprepare(dsi->pllref_clk);
return ret;
  }
@@ -1319,6 +1320,10 @@ static void dw_mipi_dsi_unbind(struct device *dev, 
struct device *master,
  
  	mipi_dsi_host_unregister(>dsi_host);

pm_runtime_disable(dev);
+
+   dsi->connector.funcs->destroy(>connector);
+   dsi->encoder.funcs->destroy(>encoder);
+
clk_disable_unprepare(dsi->pllref_clk);
  }
  



--
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
a Linux Foundation Collaborative Project


Re: [PATCH v7 3/3] drm/rockchip: Add ROCKCHIP DW MIPI DSI controller driver

2018-01-10 Thread Archit Taneja



On 12/12/2017 06:40 AM, Nickey Yang wrote:

Add the ROCKCHIP DSI controller driver that uses the Synopsys DesignWare
MIPI DSI host controller bridge.


Reviewed-by: Archit Taneja <arch...@codeaurora.org>



Signed-off-by: Nickey Yang <nickey.y...@rock-chips.com>
Signed-off-by: Brian Norris <briannor...@chromium.org>
Reviewed-by: Brian Norris <briannor...@chromium.org>
Reviewed-by: Sean Paul <seanp...@chromium.org>
---
changes:

v2:
add err_pllref, remove unnecessary encoder.enable & disable
correct spelling mistakes
v3:
call dw_mipi_dsi_unbind() in dw_mipi_dsi_rockchip_unbind()
fix typo, use of_device_get_match_data(),
change some ‘bind()’ logic into 'probe()'
add 'dev_set_drvdata()'
v4:
   return -EINVAL when can not get best_freq
   add a clarifying comment when get vco
   add review tag
v5:
   keep our power domain enabled while touching GRF
v6:
   change func name dw_mipi_encoder_disable to
   dw_mipi_dsi_encoder_disable

  drivers/gpu/drm/rockchip/Kconfig|2 +-
  drivers/gpu/drm/rockchip/Makefile   |2 +-
  drivers/gpu/drm/rockchip/dw-mipi-dsi.c  | 1349 ---
  drivers/gpu/drm/rockchip/dw-mipi-dsi_rockchip.c |  785 +
  drivers/gpu/drm/rockchip/rockchip_drm_drv.c |2 +-
  drivers/gpu/drm/rockchip/rockchip_drm_drv.h |2 +-
  6 files changed, 789 insertions(+), 1353 deletions(-)
  delete mode 100644 drivers/gpu/drm/rockchip/dw-mipi-dsi.c
  create mode 100644 drivers/gpu/drm/rockchip/dw-mipi-dsi_rockchip.c

diff --git a/drivers/gpu/drm/rockchip/Kconfig b/drivers/gpu/drm/rockchip/Kconfig
index 0ccc762..9eb4795 100644
--- a/drivers/gpu/drm/rockchip/Kconfig
+++ b/drivers/gpu/drm/rockchip/Kconfig
@@ -7,7 +7,7 @@ config DRM_ROCKCHIP
select VIDEOMODE_HELPERS
select DRM_ANALOGIX_DP if ROCKCHIP_ANALOGIX_DP
select DRM_DW_HDMI if ROCKCHIP_DW_HDMI
-   select DRM_MIPI_DSI if ROCKCHIP_DW_MIPI_DSI
+   select DRM_DW_MIPI_DSI if ROCKCHIP_DW_MIPI_DSI
select SND_SOC_HDMI_CODEC if ROCKCHIP_CDN_DP && SND_SOC
help
  Choose this option if you have a Rockchip soc chipset.
diff --git a/drivers/gpu/drm/rockchip/Makefile 
b/drivers/gpu/drm/rockchip/Makefile
index a314e21..c05fe47 100644
--- a/drivers/gpu/drm/rockchip/Makefile
+++ b/drivers/gpu/drm/rockchip/Makefile
@@ -11,7 +11,7 @@ rockchipdrm-$(CONFIG_DRM_FBDEV_EMULATION) += 
rockchip_drm_fbdev.o
  rockchipdrm-$(CONFIG_ROCKCHIP_ANALOGIX_DP) += analogix_dp-rockchip.o
  rockchipdrm-$(CONFIG_ROCKCHIP_CDN_DP) += cdn-dp-core.o cdn-dp-reg.o
  rockchipdrm-$(CONFIG_ROCKCHIP_DW_HDMI) += dw_hdmi-rockchip.o
-rockchipdrm-$(CONFIG_ROCKCHIP_DW_MIPI_DSI) += dw-mipi-dsi.o
+rockchipdrm-$(CONFIG_ROCKCHIP_DW_MIPI_DSI) += dw-mipi-dsi_rockchip.o
  rockchipdrm-$(CONFIG_ROCKCHIP_INNO_HDMI) += inno_hdmi.o
  rockchipdrm-$(CONFIG_ROCKCHIP_LVDS) += rockchip_lvds.o
  
diff --git a/drivers/gpu/drm/rockchip/dw-mipi-dsi.c b/drivers/gpu/drm/rockchip/dw-mipi-dsi.c

deleted file mode 100644
index b15755b..000
--- a/drivers/gpu/drm/rockchip/dw-mipi-dsi.c
+++ /dev/null
@@ -1,1349 +0,0 @@
-/*
- * Copyright (c) 2016, Fuzhou Rockchip Electronics Co., Ltd
- *
- * 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.
- */
-#include 
-#include 
-#include 
-#include 
-#include 
-#include 
-#include 
-#include 
-#include 
-#include 
-#include 
-#include 
-#include 
-#include 
-#include 
-#include 
-#include 
-#include 
-
-#include "rockchip_drm_drv.h"
-#include "rockchip_drm_vop.h"
-
-#define DRIVER_NAME"dw-mipi-dsi"
-
-#define RK3288_GRF_SOC_CON60x025c
-#define RK3288_DSI0_SEL_VOP_LITBIT(6)
-#define RK3288_DSI1_SEL_VOP_LITBIT(9)
-
-#define RK3399_GRF_SOC_CON20   0x6250
-#define RK3399_DSI0_SEL_VOP_LITBIT(0)
-#define RK3399_DSI1_SEL_VOP_LITBIT(4)
-
-/* disable turnrequest, turndisable, forcetxstopmode, forcerxmode */
-#define RK3399_GRF_SOC_CON22   0x6258
-#define RK3399_GRF_DSI_MODE0x
-
-#define DSI_VERSION0x00
-#define DSI_PWR_UP 0x04
-#define RESET  0
-#define POWERUPBIT(0)
-
-#define DSI_CLKMGR_CFG 0x08
-#define TO_CLK_DIVIDSION(div)  (((div) & 0xff) << 8)
-#define TX_ESC_CLK_DIVIDSION(div)  (((div) & 0xff) << 0)
-
-#define DSI_DPI_VCID   0x0c
-#define DPI_VID(vid)   (((vid) & 0x3) << 0)
-
-#define DSI_DPI_COLOR_CODING   0x10
-#define EN18_LOOSELY   BIT(8)
-#define DPI_COLOR_CODING_16BIT_1   0x0
-#define DPI_COLOR_CODING_16BIT_2   0x1
-#define DPI_COLOR_

Re: [PATCH v7 3/3] drm/rockchip: Add ROCKCHIP DW MIPI DSI controller driver

2018-01-10 Thread Archit Taneja



On 12/12/2017 06:40 AM, Nickey Yang wrote:

Add the ROCKCHIP DSI controller driver that uses the Synopsys DesignWare
MIPI DSI host controller bridge.


Reviewed-by: Archit Taneja 



Signed-off-by: Nickey Yang 
Signed-off-by: Brian Norris 
Reviewed-by: Brian Norris 
Reviewed-by: Sean Paul 
---
changes:

v2:
add err_pllref, remove unnecessary encoder.enable & disable
correct spelling mistakes
v3:
call dw_mipi_dsi_unbind() in dw_mipi_dsi_rockchip_unbind()
fix typo, use of_device_get_match_data(),
change some ‘bind()’ logic into 'probe()'
add 'dev_set_drvdata()'
v4:
   return -EINVAL when can not get best_freq
   add a clarifying comment when get vco
   add review tag
v5:
   keep our power domain enabled while touching GRF
v6:
   change func name dw_mipi_encoder_disable to
   dw_mipi_dsi_encoder_disable

  drivers/gpu/drm/rockchip/Kconfig|2 +-
  drivers/gpu/drm/rockchip/Makefile   |2 +-
  drivers/gpu/drm/rockchip/dw-mipi-dsi.c  | 1349 ---
  drivers/gpu/drm/rockchip/dw-mipi-dsi_rockchip.c |  785 +
  drivers/gpu/drm/rockchip/rockchip_drm_drv.c |2 +-
  drivers/gpu/drm/rockchip/rockchip_drm_drv.h |2 +-
  6 files changed, 789 insertions(+), 1353 deletions(-)
  delete mode 100644 drivers/gpu/drm/rockchip/dw-mipi-dsi.c
  create mode 100644 drivers/gpu/drm/rockchip/dw-mipi-dsi_rockchip.c

diff --git a/drivers/gpu/drm/rockchip/Kconfig b/drivers/gpu/drm/rockchip/Kconfig
index 0ccc762..9eb4795 100644
--- a/drivers/gpu/drm/rockchip/Kconfig
+++ b/drivers/gpu/drm/rockchip/Kconfig
@@ -7,7 +7,7 @@ config DRM_ROCKCHIP
select VIDEOMODE_HELPERS
select DRM_ANALOGIX_DP if ROCKCHIP_ANALOGIX_DP
select DRM_DW_HDMI if ROCKCHIP_DW_HDMI
-   select DRM_MIPI_DSI if ROCKCHIP_DW_MIPI_DSI
+   select DRM_DW_MIPI_DSI if ROCKCHIP_DW_MIPI_DSI
select SND_SOC_HDMI_CODEC if ROCKCHIP_CDN_DP && SND_SOC
help
  Choose this option if you have a Rockchip soc chipset.
diff --git a/drivers/gpu/drm/rockchip/Makefile 
b/drivers/gpu/drm/rockchip/Makefile
index a314e21..c05fe47 100644
--- a/drivers/gpu/drm/rockchip/Makefile
+++ b/drivers/gpu/drm/rockchip/Makefile
@@ -11,7 +11,7 @@ rockchipdrm-$(CONFIG_DRM_FBDEV_EMULATION) += 
rockchip_drm_fbdev.o
  rockchipdrm-$(CONFIG_ROCKCHIP_ANALOGIX_DP) += analogix_dp-rockchip.o
  rockchipdrm-$(CONFIG_ROCKCHIP_CDN_DP) += cdn-dp-core.o cdn-dp-reg.o
  rockchipdrm-$(CONFIG_ROCKCHIP_DW_HDMI) += dw_hdmi-rockchip.o
-rockchipdrm-$(CONFIG_ROCKCHIP_DW_MIPI_DSI) += dw-mipi-dsi.o
+rockchipdrm-$(CONFIG_ROCKCHIP_DW_MIPI_DSI) += dw-mipi-dsi_rockchip.o
  rockchipdrm-$(CONFIG_ROCKCHIP_INNO_HDMI) += inno_hdmi.o
  rockchipdrm-$(CONFIG_ROCKCHIP_LVDS) += rockchip_lvds.o
  
diff --git a/drivers/gpu/drm/rockchip/dw-mipi-dsi.c b/drivers/gpu/drm/rockchip/dw-mipi-dsi.c

deleted file mode 100644
index b15755b..000
--- a/drivers/gpu/drm/rockchip/dw-mipi-dsi.c
+++ /dev/null
@@ -1,1349 +0,0 @@
-/*
- * Copyright (c) 2016, Fuzhou Rockchip Electronics Co., Ltd
- *
- * 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.
- */
-#include 
-#include 
-#include 
-#include 
-#include 
-#include 
-#include 
-#include 
-#include 
-#include 
-#include 
-#include 
-#include 
-#include 
-#include 
-#include 
-#include 
-#include 
-
-#include "rockchip_drm_drv.h"
-#include "rockchip_drm_vop.h"
-
-#define DRIVER_NAME"dw-mipi-dsi"
-
-#define RK3288_GRF_SOC_CON60x025c
-#define RK3288_DSI0_SEL_VOP_LITBIT(6)
-#define RK3288_DSI1_SEL_VOP_LITBIT(9)
-
-#define RK3399_GRF_SOC_CON20   0x6250
-#define RK3399_DSI0_SEL_VOP_LITBIT(0)
-#define RK3399_DSI1_SEL_VOP_LITBIT(4)
-
-/* disable turnrequest, turndisable, forcetxstopmode, forcerxmode */
-#define RK3399_GRF_SOC_CON22   0x6258
-#define RK3399_GRF_DSI_MODE0x
-
-#define DSI_VERSION0x00
-#define DSI_PWR_UP 0x04
-#define RESET  0
-#define POWERUPBIT(0)
-
-#define DSI_CLKMGR_CFG 0x08
-#define TO_CLK_DIVIDSION(div)  (((div) & 0xff) << 8)
-#define TX_ESC_CLK_DIVIDSION(div)  (((div) & 0xff) << 0)
-
-#define DSI_DPI_VCID   0x0c
-#define DPI_VID(vid)   (((vid) & 0x3) << 0)
-
-#define DSI_DPI_COLOR_CODING   0x10
-#define EN18_LOOSELY   BIT(8)
-#define DPI_COLOR_CODING_16BIT_1   0x0
-#define DPI_COLOR_CODING_16BIT_2   0x1
-#define DPI_COLOR_CODING_16BIT_3   0x2
-#define DPI_COLOR_CODING_18BIT_1   0x3
-#define DPI_COLOR_CODING_18BIT_2   0x4
-#define DPI_COLOR_CODING_24BIT

Re: [PATCH v7 00/10] rockchip: kevin: Enable edp display

2018-01-10 Thread Archit Taneja



On 01/09/2018 08:18 PM, Thierry Escande wrote:

Hi,

This patchset makes edp display work on Chromebook kevin.

This patchset has been originally posted by Jeffy Chen and the 2 first
commits from the previous version (v6) are already merged in mainline.
This v7 has been rebased on top of next-20180108 and a few conflicts
have been fixed as well.

v7:
Rebased on top of next-20180108 and fixed conflicts
Fixed a few warnings reported by checkpatch

Jeffy Chen (10):
   arm64: dts: rockchip: Enable edp disaplay on kevin
   drm/rockchip: analogix_dp: Remove unnecessary init code
   drm/bridge: analogix: Do not use device's drvdata
   drm/bridge: analogix_dp: Fix connector and encoder cleanup
   drm/rockchip: analogix_dp: Add a sanity check for
 rockchip_drm_psr_register()
   drm/rockchip: dw-mipi-dsi: Fix error handling path
   drm/rockchip: inno_hdmi: Fix error handling path
   drm/bridge/synopsys: dw-hdmi: Add missing bridge detach
   drm/bridge/synopsys: dw-hdmi: Do not use device's drvdata
   drm/rockchip: dw_hdmi: Fix error handling path



I think all the bridge related patches (#s 1, 2, 6 and 7)have
been reviewed.

I tried to build a kernel with just the 4 of these, and I get
a build error with patch #7 (drm/bridge/synopsys: dw-hdmi: Do not use
device's drvdata). Applying patch #8 (drm/rockchip: dw_hdmi: Fix error
handling path)
fixes this. Could you make these 2 patches independent of each other
so that the kernel builds successfully after each commit?

I don't know if the rest of the rockchip patches in the series
depend on the 4 bridge patches. If they do, the rockchip maintainer
can queue both rockchip and bridge patches. If not, I can pick up
the bridge patches.

Thanks,
Archit



  arch/arm64/boot/dts/rockchip/rk3399-gru-kevin.dts  | 29 +++
  arch/arm64/boot/dts/rockchip/rk3399-gru.dtsi   | 16 
  drivers/gpu/drm/bridge/analogix/analogix_dp_core.c | 52 +---
  drivers/gpu/drm/bridge/synopsys/dw-hdmi.c  | 53 ++--
  drivers/gpu/drm/exynos/exynos_dp.c | 29 ---
  drivers/gpu/drm/imx/dw_hdmi-imx.c  | 22 +++--
  drivers/gpu/drm/meson/meson_dw_hdmi.c  | 20 +++--
  drivers/gpu/drm/rcar-du/rcar_dw_hdmi.c | 14 +++-
  drivers/gpu/drm/rockchip/analogix_dp-rockchip.c| 95 +++---
  drivers/gpu/drm/rockchip/dw-mipi-dsi.c | 21 +++--
  drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c| 39 +
  drivers/gpu/drm/rockchip/inno_hdmi.c   | 22 +++--
  include/drm/bridge/analogix_dp.h   | 19 +++--
  include/drm/bridge/dw_hdmi.h   | 17 ++--
  14 files changed, 265 insertions(+), 183 deletions(-)



--
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
a Linux Foundation Collaborative Project


Re: [PATCH v7 00/10] rockchip: kevin: Enable edp display

2018-01-10 Thread Archit Taneja



On 01/09/2018 08:18 PM, Thierry Escande wrote:

Hi,

This patchset makes edp display work on Chromebook kevin.

This patchset has been originally posted by Jeffy Chen and the 2 first
commits from the previous version (v6) are already merged in mainline.
This v7 has been rebased on top of next-20180108 and a few conflicts
have been fixed as well.

v7:
Rebased on top of next-20180108 and fixed conflicts
Fixed a few warnings reported by checkpatch

Jeffy Chen (10):
   arm64: dts: rockchip: Enable edp disaplay on kevin
   drm/rockchip: analogix_dp: Remove unnecessary init code
   drm/bridge: analogix: Do not use device's drvdata
   drm/bridge: analogix_dp: Fix connector and encoder cleanup
   drm/rockchip: analogix_dp: Add a sanity check for
 rockchip_drm_psr_register()
   drm/rockchip: dw-mipi-dsi: Fix error handling path
   drm/rockchip: inno_hdmi: Fix error handling path
   drm/bridge/synopsys: dw-hdmi: Add missing bridge detach
   drm/bridge/synopsys: dw-hdmi: Do not use device's drvdata
   drm/rockchip: dw_hdmi: Fix error handling path



I think all the bridge related patches (#s 1, 2, 6 and 7)have
been reviewed.

I tried to build a kernel with just the 4 of these, and I get
a build error with patch #7 (drm/bridge/synopsys: dw-hdmi: Do not use
device's drvdata). Applying patch #8 (drm/rockchip: dw_hdmi: Fix error
handling path)
fixes this. Could you make these 2 patches independent of each other
so that the kernel builds successfully after each commit?

I don't know if the rest of the rockchip patches in the series
depend on the 4 bridge patches. If they do, the rockchip maintainer
can queue both rockchip and bridge patches. If not, I can pick up
the bridge patches.

Thanks,
Archit



  arch/arm64/boot/dts/rockchip/rk3399-gru-kevin.dts  | 29 +++
  arch/arm64/boot/dts/rockchip/rk3399-gru.dtsi   | 16 
  drivers/gpu/drm/bridge/analogix/analogix_dp_core.c | 52 +---
  drivers/gpu/drm/bridge/synopsys/dw-hdmi.c  | 53 ++--
  drivers/gpu/drm/exynos/exynos_dp.c | 29 ---
  drivers/gpu/drm/imx/dw_hdmi-imx.c  | 22 +++--
  drivers/gpu/drm/meson/meson_dw_hdmi.c  | 20 +++--
  drivers/gpu/drm/rcar-du/rcar_dw_hdmi.c | 14 +++-
  drivers/gpu/drm/rockchip/analogix_dp-rockchip.c| 95 +++---
  drivers/gpu/drm/rockchip/dw-mipi-dsi.c | 21 +++--
  drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c| 39 +
  drivers/gpu/drm/rockchip/inno_hdmi.c   | 22 +++--
  include/drm/bridge/analogix_dp.h   | 19 +++--
  include/drm/bridge/dw_hdmi.h   | 17 ++--
  14 files changed, 265 insertions(+), 183 deletions(-)



--
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
a Linux Foundation Collaborative Project


Re: [PATCH v7 7/8] drm/bridge/synopsys: dw-hdmi: Do not use device's drvdata

2018-01-10 Thread Archit Taneja



On 01/09/2018 08:18 PM, Thierry Escande wrote:

From: Jeffy Chen <jeffy.c...@rock-chips.com>

Let plat drivers own the drvdata, so that they could cleanup resources
in their unbind().

Signed-off-by: Jeffy Chen <jeffy.c...@rock-chips.com>
Signed-off-by: Thierry Escande <thierry.esca...@collabora.com>
Reviewed-by: Neil Armstrong <narmstr...@baylibre.com>


Reviewed-by: Archit Taneja <arch...@codeaurora.org>


---
  drivers/gpu/drm/bridge/synopsys/dw-hdmi.c   | 43 ++---
  drivers/gpu/drm/imx/dw_hdmi-imx.c   | 22 +--
  drivers/gpu/drm/meson/meson_dw_hdmi.c   | 20 ++
  drivers/gpu/drm/rcar-du/rcar_dw_hdmi.c  | 14 --
  drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c | 23 ---
  include/drm/bridge/dw_hdmi.h| 17 ++--
  6 files changed, 77 insertions(+), 62 deletions(-)

diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c 
b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
index 1cc63a18b7d5..f0380bcae513 100644
--- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
+++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
@@ -2073,7 +2073,7 @@ static irqreturn_t dw_hdmi_hardirq(int irq, void *dev_id)
return ret;
  }
  
-void __dw_hdmi_setup_rx_sense(struct dw_hdmi *hdmi, bool hpd, bool rx_sense)

+void dw_hdmi_setup_rx_sense(struct dw_hdmi *hdmi, bool hpd, bool rx_sense)
  {
mutex_lock(>mutex);
  
@@ -2099,13 +2099,6 @@ void __dw_hdmi_setup_rx_sense(struct dw_hdmi *hdmi, bool hpd, bool rx_sense)

}
mutex_unlock(>mutex);
  }
-
-void dw_hdmi_setup_rx_sense(struct device *dev, bool hpd, bool rx_sense)
-{
-   struct dw_hdmi *hdmi = dev_get_drvdata(dev);
-
-   __dw_hdmi_setup_rx_sense(hdmi, hpd, rx_sense);
-}
  EXPORT_SYMBOL_GPL(dw_hdmi_setup_rx_sense);
  
  static irqreturn_t dw_hdmi_irq(int irq, void *dev_id)

@@ -2141,9 +2134,8 @@ static irqreturn_t dw_hdmi_irq(int irq, void *dev_id)
 */
if (intr_stat &
(HDMI_IH_PHY_STAT0_RX_SENSE | HDMI_IH_PHY_STAT0_HPD)) {
-   __dw_hdmi_setup_rx_sense(hdmi,
-phy_stat & HDMI_PHY_HPD,
-phy_stat & HDMI_PHY_RX_SENSE);
+   dw_hdmi_setup_rx_sense(hdmi, phy_stat & HDMI_PHY_HPD,
+  phy_stat & HDMI_PHY_RX_SENSE);
  
  		if ((phy_stat & (HDMI_PHY_RX_SENSE | HDMI_PHY_HPD)) == 0)

cec_notifier_set_phys_addr(hdmi->cec_notifier,
@@ -2533,8 +2525,6 @@ __dw_hdmi_probe(struct platform_device *pdev,
if (hdmi->i2c)
dw_hdmi_i2c_init(hdmi);
  
-	platform_set_drvdata(pdev, hdmi);

-
return hdmi;
  
  err_iahb:

@@ -2584,25 +2574,23 @@ static void __dw_hdmi_remove(struct dw_hdmi *hdmi)
  /* 
-
   * Probe/remove API, used from platforms based on the DRM bridge API.
   */
-int dw_hdmi_probe(struct platform_device *pdev,
- const struct dw_hdmi_plat_data *plat_data)
+struct dw_hdmi *dw_hdmi_probe(struct platform_device *pdev,
+ const struct dw_hdmi_plat_data *plat_data)
  {
struct dw_hdmi *hdmi;
  
  	hdmi = __dw_hdmi_probe(pdev, plat_data);

if (IS_ERR(hdmi))
-   return PTR_ERR(hdmi);
+   return hdmi;
  
  	drm_bridge_add(>bridge);
  
-	return 0;

+   return hdmi;
  }
  EXPORT_SYMBOL_GPL(dw_hdmi_probe);
  
-void dw_hdmi_remove(struct platform_device *pdev)

+void dw_hdmi_remove(struct dw_hdmi *hdmi)
  {
-   struct dw_hdmi *hdmi = platform_get_drvdata(pdev);
-
drm_bridge_remove(>bridge);
  
  	__dw_hdmi_remove(hdmi);

@@ -2612,31 +2600,30 @@ EXPORT_SYMBOL_GPL(dw_hdmi_remove);
  /* 
-
   * Bind/unbind API, used from platforms based on the component framework.
   */
-int dw_hdmi_bind(struct platform_device *pdev, struct drm_encoder *encoder,
-const struct dw_hdmi_plat_data *plat_data)
+struct dw_hdmi *dw_hdmi_bind(struct platform_device *pdev,
+struct drm_encoder *encoder,
+const struct dw_hdmi_plat_data *plat_data)
  {
struct dw_hdmi *hdmi;
int ret;
  
  	hdmi = __dw_hdmi_probe(pdev, plat_data);

if (IS_ERR(hdmi))
-   return PTR_ERR(hdmi);
+   return hdmi;
  
  	ret = drm_bridge_attach(encoder, >bridge, NULL);

if (ret) {
__dw_hdmi_remove(hdmi);
DRM_ERROR("Failed to initialize bridge with drm\n");
-   return ret;
+   return ERR_PTR(ret);
}
  
-	return 0;

+   return hdmi;
  }
  EXPORT_SYMBOL_GPL(dw_hdmi_bind);
  
-void dw_hdmi_unbind(struct device *dev)

+void dw_hdmi_unbind(struct dw_hdmi *hdmi)
  {
-   struct dw_hdmi *hdmi = dev_get_d

Re: [PATCH v7 7/8] drm/bridge/synopsys: dw-hdmi: Do not use device's drvdata

2018-01-10 Thread Archit Taneja



On 01/09/2018 08:18 PM, Thierry Escande wrote:

From: Jeffy Chen 

Let plat drivers own the drvdata, so that they could cleanup resources
in their unbind().

Signed-off-by: Jeffy Chen 
Signed-off-by: Thierry Escande 
Reviewed-by: Neil Armstrong 


Reviewed-by: Archit Taneja 


---
  drivers/gpu/drm/bridge/synopsys/dw-hdmi.c   | 43 ++---
  drivers/gpu/drm/imx/dw_hdmi-imx.c   | 22 +--
  drivers/gpu/drm/meson/meson_dw_hdmi.c   | 20 ++
  drivers/gpu/drm/rcar-du/rcar_dw_hdmi.c  | 14 --
  drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c | 23 ---
  include/drm/bridge/dw_hdmi.h| 17 ++--
  6 files changed, 77 insertions(+), 62 deletions(-)

diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c 
b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
index 1cc63a18b7d5..f0380bcae513 100644
--- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
+++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
@@ -2073,7 +2073,7 @@ static irqreturn_t dw_hdmi_hardirq(int irq, void *dev_id)
return ret;
  }
  
-void __dw_hdmi_setup_rx_sense(struct dw_hdmi *hdmi, bool hpd, bool rx_sense)

+void dw_hdmi_setup_rx_sense(struct dw_hdmi *hdmi, bool hpd, bool rx_sense)
  {
mutex_lock(>mutex);
  
@@ -2099,13 +2099,6 @@ void __dw_hdmi_setup_rx_sense(struct dw_hdmi *hdmi, bool hpd, bool rx_sense)

}
mutex_unlock(>mutex);
  }
-
-void dw_hdmi_setup_rx_sense(struct device *dev, bool hpd, bool rx_sense)
-{
-   struct dw_hdmi *hdmi = dev_get_drvdata(dev);
-
-   __dw_hdmi_setup_rx_sense(hdmi, hpd, rx_sense);
-}
  EXPORT_SYMBOL_GPL(dw_hdmi_setup_rx_sense);
  
  static irqreturn_t dw_hdmi_irq(int irq, void *dev_id)

@@ -2141,9 +2134,8 @@ static irqreturn_t dw_hdmi_irq(int irq, void *dev_id)
 */
if (intr_stat &
(HDMI_IH_PHY_STAT0_RX_SENSE | HDMI_IH_PHY_STAT0_HPD)) {
-   __dw_hdmi_setup_rx_sense(hdmi,
-phy_stat & HDMI_PHY_HPD,
-phy_stat & HDMI_PHY_RX_SENSE);
+   dw_hdmi_setup_rx_sense(hdmi, phy_stat & HDMI_PHY_HPD,
+  phy_stat & HDMI_PHY_RX_SENSE);
  
  		if ((phy_stat & (HDMI_PHY_RX_SENSE | HDMI_PHY_HPD)) == 0)

cec_notifier_set_phys_addr(hdmi->cec_notifier,
@@ -2533,8 +2525,6 @@ __dw_hdmi_probe(struct platform_device *pdev,
if (hdmi->i2c)
dw_hdmi_i2c_init(hdmi);
  
-	platform_set_drvdata(pdev, hdmi);

-
return hdmi;
  
  err_iahb:

@@ -2584,25 +2574,23 @@ static void __dw_hdmi_remove(struct dw_hdmi *hdmi)
  /* 
-
   * Probe/remove API, used from platforms based on the DRM bridge API.
   */
-int dw_hdmi_probe(struct platform_device *pdev,
- const struct dw_hdmi_plat_data *plat_data)
+struct dw_hdmi *dw_hdmi_probe(struct platform_device *pdev,
+ const struct dw_hdmi_plat_data *plat_data)
  {
struct dw_hdmi *hdmi;
  
  	hdmi = __dw_hdmi_probe(pdev, plat_data);

if (IS_ERR(hdmi))
-   return PTR_ERR(hdmi);
+   return hdmi;
  
  	drm_bridge_add(>bridge);
  
-	return 0;

+   return hdmi;
  }
  EXPORT_SYMBOL_GPL(dw_hdmi_probe);
  
-void dw_hdmi_remove(struct platform_device *pdev)

+void dw_hdmi_remove(struct dw_hdmi *hdmi)
  {
-   struct dw_hdmi *hdmi = platform_get_drvdata(pdev);
-
drm_bridge_remove(>bridge);
  
  	__dw_hdmi_remove(hdmi);

@@ -2612,31 +2600,30 @@ EXPORT_SYMBOL_GPL(dw_hdmi_remove);
  /* 
-
   * Bind/unbind API, used from platforms based on the component framework.
   */
-int dw_hdmi_bind(struct platform_device *pdev, struct drm_encoder *encoder,
-const struct dw_hdmi_plat_data *plat_data)
+struct dw_hdmi *dw_hdmi_bind(struct platform_device *pdev,
+struct drm_encoder *encoder,
+const struct dw_hdmi_plat_data *plat_data)
  {
struct dw_hdmi *hdmi;
int ret;
  
  	hdmi = __dw_hdmi_probe(pdev, plat_data);

if (IS_ERR(hdmi))
-   return PTR_ERR(hdmi);
+   return hdmi;
  
  	ret = drm_bridge_attach(encoder, >bridge, NULL);

if (ret) {
__dw_hdmi_remove(hdmi);
DRM_ERROR("Failed to initialize bridge with drm\n");
-   return ret;
+   return ERR_PTR(ret);
}
  
-	return 0;

+   return hdmi;
  }
  EXPORT_SYMBOL_GPL(dw_hdmi_bind);
  
-void dw_hdmi_unbind(struct device *dev)

+void dw_hdmi_unbind(struct dw_hdmi *hdmi)
  {
-   struct dw_hdmi *hdmi = dev_get_drvdata(dev);
-
__dw_hdmi_remove(hdmi);
  }
  EXPORT_SYMBOL_GPL(dw_hdmi_unbind);
diff --git a/drivers/gpu/drm/imx/dw_hdmi-imx.c 
b/drivers/gpu/drm/im

  1   2   3   4   5   6   7   8   9   >