Re: [PATCH] drm/bridge: analogix_dp: Don't return -EBUSY when msg->size is 0 in aux transaction

2017-02-20 Thread Zain Wang

Hi Tomasz,

在 2017/2/20 10:40, Tomasz Figa 写道:

Hi Zain,

On Mon, Feb 13, 2017 at 6:27 PM, zain wang <w...@rock-chips.com> wrote:

The analogix_dp_transfer() will return -EBUSY if num_transferred is zero.
But sometimes we will send a bare address packet to start the transaction,
like drm_dp_i2c_xfer() show:
 ..
 /* Send a bare address packet to start the transaction.
  * Zero sized messages specify an address only (bare
  * address) transaction.
  */
 msg.buffer = NULL;
 msg.size = 0;
 err = drm_dp_i2c_do_msg(aux, );
 ..

In this case, the msg->size is zero, so the num_transferred will be zero too.
We can't return -EBUSY here, let's we return num_transferred if num_transferred
equals msg->size.


Please see my question inline.


Signed-off-by: zain wang <w...@rock-chips.com>
---
  drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c | 2 +-
  1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c 
b/drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c
index 303083a..5384aca 100644
--- a/drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c
+++ b/drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c
@@ -1162,5 +1162,5 @@ ssize_t analogix_dp_transfer(struct analogix_dp_device 
*dp,
  (msg->request & ~DP_AUX_I2C_MOT) == DP_AUX_NATIVE_READ)
 msg->reply = DP_AUX_NATIVE_REPLY_ACK;

-   return num_transferred > 0 ? num_transferred : -EBUSY;
+   return (num_transferred == msg->size) ? num_transferred : -EBUSY;

I might be missing something but, looking at the code, I don't see any
possibility of num_transferred ever being different than msg->size. To
be honest, it doesn't seem to even make any sense keeping the local
variable there, because msg->size can be simply always returned, as
errors are handled by jumping to aux_error label.

Yeah, I agree with you.
The better way to fix this issue is to revert the changes 
https://patchwork.kernel.org/patch/9411711/

(returning num_transferred directly may be better here)

Maybe we can revert the changes above with some new comment.
@Sean, How do you think about Tomasz's comment?

Thanks
Zain


Best regards,
Tomasz






___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


Re: [PATCH] drm/bridge: analogix_dp: Don't return -EBUSY when msg->size is 0 in aux transaction

2017-02-20 Thread Zain Wang

Hi Sean,

Could you give some comments for this patch?

Thanks
Zain


在 2017/2/13 17:27, zain wang 写道:

The analogix_dp_transfer() will return -EBUSY if num_transferred is zero.
But sometimes we will send a bare address packet to start the transaction,
like drm_dp_i2c_xfer() show:
..
/* Send a bare address packet to start the transaction.
 * Zero sized messages specify an address only (bare
 * address) transaction.
 */
msg.buffer = NULL;
msg.size = 0;
err = drm_dp_i2c_do_msg(aux, );
..

In this case, the msg->size is zero, so the num_transferred will be zero too.
We can't return -EBUSY here, let's we return num_transferred if num_transferred
equals msg->size.

Signed-off-by: zain wang <w...@rock-chips.com>
---
  drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c | 2 +-
  1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c 
b/drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c
index 303083a..5384aca 100644
--- a/drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c
+++ b/drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c
@@ -1162,5 +1162,5 @@ ssize_t analogix_dp_transfer(struct analogix_dp_device 
*dp,
 (msg->request & ~DP_AUX_I2C_MOT) == DP_AUX_NATIVE_READ)
msg->reply = DP_AUX_NATIVE_REPLY_ACK;
  
-	return num_transferred > 0 ? num_transferred : -EBUSY;

+   return (num_transferred == msg->size) ? num_transferred : -EBUSY;
  }



___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH] drm/bridge: analogix_dp: Don't return -EBUSY when msg->size is 0 in aux transaction

2017-02-13 Thread zain wang
The analogix_dp_transfer() will return -EBUSY if num_transferred is zero.
But sometimes we will send a bare address packet to start the transaction,
like drm_dp_i2c_xfer() show:
..
/* Send a bare address packet to start the transaction.
 * Zero sized messages specify an address only (bare
 * address) transaction.
 */
msg.buffer = NULL;
msg.size = 0;
err = drm_dp_i2c_do_msg(aux, );
..

In this case, the msg->size is zero, so the num_transferred will be zero too.
We can't return -EBUSY here, let's we return num_transferred if num_transferred
equals msg->size.

Signed-off-by: zain wang <w...@rock-chips.com>
---
 drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c 
b/drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c
index 303083a..5384aca 100644
--- a/drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c
+++ b/drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c
@@ -1162,5 +1162,5 @@ ssize_t analogix_dp_transfer(struct analogix_dp_device 
*dp,
 (msg->request & ~DP_AUX_I2C_MOT) == DP_AUX_NATIVE_READ)
msg->reply = DP_AUX_NATIVE_REPLY_ACK;
 
-   return num_transferred > 0 ? num_transferred : -EBUSY;
+   return (num_transferred == msg->size) ? num_transferred : -EBUSY;
 }
-- 
1.9.1


___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH v2] drm/bridge: analogix: Don't return -EINVAL when panel not support PSR in PSR functions

2016-12-07 Thread zain wang
We will ignored PSR setting if panel not support it. So, in this case, we should
return from analogix_dp_enable/disable_psr() without any error code.
Let's retrun 0 instead of -EINVAL when panel not support PSR in
analogix_dp_enable/disable_psr().

Signed-off-by: zain wang 
---

Changes in v2:
- Remove dev_warn if panel not support PSR.

 drivers/gpu/drm/bridge/analogix/analogix_dp_core.c | 4 ++--
 1 file changed, 2 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 6e0447f..eb9bf87 100644
--- a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
+++ b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
@@ -112,7 +112,7 @@ int analogix_dp_enable_psr(struct device *dev)
struct edp_vsc_psr psr_vsc;

if (!dp->psr_support)
-   return -EINVAL;
+   return 0;

/* Prepare VSC packet as per EDP 1.4 spec, Table 6.9 */
memset(_vsc, 0, sizeof(psr_vsc));
@@ -135,7 +135,7 @@ int analogix_dp_disable_psr(struct device *dev)
struct edp_vsc_psr psr_vsc;

if (!dp->psr_support)
-   return -EINVAL;
+   return 0;

/* Prepare VSC packet as per EDP 1.4 spec, Table 6.9 */
memset(_vsc, 0, sizeof(psr_vsc));
-- 
1.9.1




[PATCH] drm/bridge: analogix: Don't return -EINVAL when panel not support PSR in PSR functions

2016-12-02 Thread zain wang
We will ignored PSR setting if panel not support it. So, in this case, we should
return from analogix_dp_enable/disable_psr() without any error code.
Let's retrun 0 instead of -EINVAL when panel not support PSR in
analogix_dp_enable/disable_psr().

Signed-off-by: zain wang 
---
 drivers/gpu/drm/bridge/analogix/analogix_dp_core.c | 6 --
 1 file changed, 4 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 6e0447f..0cb3695 100644
--- a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
+++ b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
@@ -112,7 +112,7 @@ int analogix_dp_enable_psr(struct device *dev)
struct edp_vsc_psr psr_vsc;

if (!dp->psr_support)
-   return -EINVAL;
+   return 0;

/* Prepare VSC packet as per EDP 1.4 spec, Table 6.9 */
memset(_vsc, 0, sizeof(psr_vsc));
@@ -135,7 +135,7 @@ int analogix_dp_disable_psr(struct device *dev)
struct edp_vsc_psr psr_vsc;

if (!dp->psr_support)
-   return -EINVAL;
+   return 0;

/* Prepare VSC packet as per EDP 1.4 spec, Table 6.9 */
memset(_vsc, 0, sizeof(psr_vsc));
@@ -878,6 +878,8 @@ static void analogix_dp_commit(struct analogix_dp_device 
*dp)
dp->psr_support = analogix_dp_detect_sink_psr(dp);
if (dp->psr_support)
analogix_dp_enable_sink_psr(dp);
+   else
+   dev_warn(dp->dev, "Sink not support PSR\n");
 }

 /*
-- 
1.9.1




[PATCH] drm/panel: simple: add 8bit-bps for Sharp lq123p1jx31

2016-11-19 Thread zain wang
Sharp lq123p1jx31 support 8bit bps.

Signed-off-by: zain wang 
---
 drivers/gpu/drm/panel/panel-simple.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/gpu/drm/panel/panel-simple.c 
b/drivers/gpu/drm/panel/panel-simple.c
index 113db3c..6b0c026 100644
--- a/drivers/gpu/drm/panel/panel-simple.c
+++ b/drivers/gpu/drm/panel/panel-simple.c
@@ -1409,6 +1409,7 @@ static const struct drm_display_mode 
sharp_lq123p1jx31_mode = {
 static const struct panel_desc sharp_lq123p1jx31 = {
.modes = _lq123p1jx31_mode,
.num_modes = 1,
+   .bpc = 8,
.size = {
.width = 259,
.height = 173,
-- 
1.9.1




[PATCH 6/6] drm: bridge/analogix: enable vop standby when entry PSR

2016-10-18 Thread Zain Wang
From: zain wang <w...@rock-chips.com>

make VOP standby when entry PSR to save some power.

Signed-off-by: zain wang 
---
 drivers/gpu/drm/rockchip/analogix_dp-rockchip.c | 29 ++---
 drivers/gpu/drm/rockchip/rockchip_drm_drv.h |  1 +
 drivers/gpu/drm/rockchip/rockchip_drm_vop.c | 19 
 3 files changed, 41 insertions(+), 8 deletions(-)

diff --git a/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c 
b/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c
index 1c2d756..e0f3ed3 100644
--- a/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c
+++ b/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c
@@ -113,6 +113,13 @@ static void analogix_dp_psr_work(struct work_struct *work)
if (!crtc)
return;

+   spin_lock_irqsave(>psr_lock, flags);
+   psr_state = dp->psr_state;
+   spin_unlock_irqrestore(>psr_lock, flags);
+
+   if (psr_state != EDP_VSC_PSR_STATE_ACTIVE)
+   rockchip_drm_vop_set_standby(crtc, false);
+
vact_end = crtc->mode.vtotal - crtc->mode.vsync_start + 
crtc->mode.vdisplay;

ret = rockchip_drm_wait_line_flag(dp->encoder.crtc, vact_end,
@@ -122,14 +129,20 @@ static void analogix_dp_psr_work(struct work_struct *work)
return;
}

-   spin_lock_irqsave(>psr_lock, flags);
-   psr_state = dp->psr_state;
-   spin_unlock_irqrestore(>psr_lock, flags);
-
-   if (psr_state == EDP_VSC_PSR_STATE_ACTIVE)
-   analogix_dp_enable_psr(dp->dev);
-   else
-   analogix_dp_disable_psr(dp->dev);
+   if (psr_state == EDP_VSC_PSR_STATE_ACTIVE) {
+   ret = analogix_dp_enable_psr(dp->dev);
+   if (ret) {
+   dev_err(dp->dev, "failed to enable psr\n");
+   return;
+   }
+   rockchip_drm_vop_set_standby(crtc, true);
+   } else {
+   ret = analogix_dp_disable_psr(dp->dev);
+   if (ret) {
+   dev_err(dp->dev, "failed to disable psr\n");
+   return;
+   }
+   }
 }

 static int rockchip_dp_pre_init(struct rockchip_dp_device *dp)
diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_drv.h 
b/drivers/gpu/drm/rockchip/rockchip_drm_drv.h
index fb6226c..7149c69 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_drv.h
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_drv.h
@@ -74,5 +74,6 @@ void rockchip_drm_dma_detach_device(struct drm_device 
*drm_dev,
struct device *dev);
 int rockchip_drm_wait_line_flag(struct drm_crtc *crtc, unsigned int line_num,
unsigned int mstimeout);
+void rockchip_drm_vop_set_standby(struct drm_crtc *crtc, bool enabled);

 #endif /* _ROCKCHIP_DRM_DRV_H_ */
diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c 
b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
index 1740a0b..13eabda 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
@@ -1478,6 +1478,25 @@ int rockchip_drm_wait_line_flag(struct drm_crtc *crtc, 
unsigned int line_num,
 }
 EXPORT_SYMBOL(rockchip_drm_wait_line_flag);

+void rockchip_drm_vop_set_standby(struct drm_crtc *crtc, bool enabled)
+{
+   struct vop *vop = to_vop(crtc);
+
+   if (!crtc || !vop->is_enabled)
+   return;
+
+   spin_lock(>reg_lock);
+
+   if (enabled)
+   VOP_CTRL_SET(vop, standby, 1);
+   else
+   VOP_CTRL_SET(vop, standby, 0);
+
+   spin_unlock(>reg_lock);
+
+}
+EXPORT_SYMBOL(rockchip_drm_vop_set_standby);
+
 static int vop_bind(struct device *dev, struct device *master, void *data)
 {
struct platform_device *pdev = to_platform_device(dev);
-- 
1.9.1




[PATCH v3 5/6] drm: bridge/analogix: add fast link train for eDP

2016-10-18 Thread Zain Wang
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 
---
 drivers/gpu/drm/bridge/analogix/analogix_dp_core.c | 89 +-
 drivers/gpu/drm/bridge/analogix/analogix_dp_core.h |  1 +
 2 files changed, 86 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 561b644..0516621 100644
--- a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
+++ b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
@@ -21,6 +21,7 @@
 #include 
 #include 
 #include 
+#include 

 #include 
 #include 
@@ -35,6 +36,8 @@

 #define to_dp(nm)  container_of(nm, struct analogix_dp_device, nm)

+static const int FAST_LINK_VERIFICATION = false;
+
 struct bridge_init {
struct i2c_client *client;
struct device_node *node;
@@ -244,6 +247,7 @@ static int analogix_dp_link_start(struct analogix_dp_device 
*dp)
usleep_range(90, 120);
}

+
/* Set training pattern 1 */
analogix_dp_set_training_pattern(dp, TRAINING_PTN1);

@@ -481,7 +485,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);

@@ -524,6 +528,12 @@ 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);

+   drm_dp_dpcd_readb(>aux, DP_MAX_DOWNSPREAD, );
+   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;
@@ -655,6 +665,75 @@ static int analogix_dp_sw_link_training(struct 
analogix_dp_device *dp)
return retval;
 }

+static int analogix_dp_full_link_train(struct analogix_dp_device *dp,
+   u32 count, u32 bwtype)
+{
+   analogix_dp_init_training(dp, count, bwtype);
+   return analogix_dp_sw_link_training(dp);
+}
+
+static int analogix_dp_fast_link_train(struct analogix_dp_device *dp)
+{
+   int lane;
+   int retval;
+   u8 link_align, link_status[2];
+   enum pll_status status;
+
+   analogix_dp_reset_macro(dp);
+
+   analogix_dp_set_link_bandwidth(dp, dp->link_train.link_rate);
+   analogix_dp_set_lane_count(dp, dp->link_train.lane_count);
+
+   for (lane = 0; lane < dp->link_train.lane_count; lane++) {
+   analogix_dp_set_lane_link_training(dp,
+   dp->link_train.training_lane[lane], lane);
+   }
+
+   retval = readx_poll_timeout(analogix_dp_get_pll_lock_status, dp, status,
+   status != PLL_UNLOCKED,
+   120, 120 * DP_TIMEOUT_LOOP_COUNT);
+
+   if (retval)
+   return retval;
+
+   /* source Set training pattern 1 */
+   analogix_dp_set_training_pattern(dp, TRAINING_PTN1);
+   usleep_range(500, 600);
+
+   analogix_dp_set_training_pattern(dp, TRAINING_PTN2);
+   usleep_range(500, 600);
+
+   /* TODO: enhanced_mode?*/
+   analogix_dp_set_training_pattern(dp, DP_NONE);
+
+   if (FAST_LINK_VERIFICATION) {
+   retval = drm_dp_dpcd_readb(>aux,
+  DP_LANE_ALIGN_STATUS_UPDATED,
+  _align);
+   if (retval < 0)
+   return retval;
+
+   retval = drm_dp_dpcd_read(>aux, DP_LANE0_1_STATUS,
+ link_status, 2);
+   if (retval < 0)
+   return retval;
+
+   if (analogix_dp_clock_recovery_ok(link_status,
+ dp->link_train.lane_count)) {
+   analogix_dp_reduce_link_rate(dp);
+   return -EIO;
+   }
+
+   if (analogix_dp_channel_eq_ok(link_status, link_align,
+ dp->link_train.lane_count)) {
+   analogix_dp_reduce_link_rate(dp);
+   return -EIO;
+   }
+   }
+
+   return 0;
+}
+
 static int analogix_dp_set_link_train(struct analogix_dp_devi

[PATCH v3 4/6] drm: bridge/analogix: switch Main-link and eDP PHY when enable/disable psr

2016-10-18 Thread Zain Wang
From: zain wang <w...@rock-chips.com>

turn off Main-link and power down eDP PHY when enable psr,
turn on Main-link and power up eDP PHY when disable psr.

Signed-off-by: zain wang 
---

Changes in v3:
- detecting PSR state at enable/disable_psr() avoid to make link training
  when sink in not PSR State.

Changes in v2:
- misc changes

 drivers/gpu/drm/bridge/analogix/analogix_dp_core.c | 123 +
 1 file changed, 76 insertions(+), 47 deletions(-)

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

-int analogix_dp_enable_psr(struct device *dev)
-{
-   struct analogix_dp_device *dp = dev_get_drvdata(dev);
-   struct edp_vsc_psr psr_vsc;
-
-   if (!dp->psr_support)
-   return -EINVAL;
-
-   /* Prepare VSC packet as per EDP 1.4 spec, Table 6.9 */
-   memset(_vsc, 0, sizeof(psr_vsc));
-   psr_vsc.sdp_header.HB0 = 0;
-   psr_vsc.sdp_header.HB1 = 0x7;
-   psr_vsc.sdp_header.HB2 = 0x2;
-   psr_vsc.sdp_header.HB3 = 0x8;
-
-   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);
-}
-EXPORT_SYMBOL_GPL(analogix_dp_enable_psr);
-
-int analogix_dp_disable_psr(struct device *dev)
-{
-   struct analogix_dp_device *dp = dev_get_drvdata(dev);
-   struct edp_vsc_psr psr_vsc;
-
-   if (!dp->psr_support)
-   return -EINVAL;
-
-   /* Prepare VSC packet as per EDP 1.4 spec, Table 6.9 */
-   memset(_vsc, 0, sizeof(psr_vsc));
-   psr_vsc.sdp_header.HB0 = 0;
-   psr_vsc.sdp_header.HB1 = 0x7;
-   psr_vsc.sdp_header.HB2 = 0x2;
-   psr_vsc.sdp_header.HB3 = 0x8;
-
-   psr_vsc.DB0 = 0;
-   psr_vsc.DB1 = 0;
-
-   return analogix_dp_send_psr_spd(dp, _vsc);
-}
-EXPORT_SYMBOL_GPL(analogix_dp_disable_psr);
-
 static bool analogix_dp_detect_sink_psr(struct analogix_dp_device *dp)
 {
unsigned char psr_version;
@@ -162,12 +118,11 @@ static void analogix_dp_enable_sink_psr(struct 
analogix_dp_device *dp)
drm_dp_dpcd_writeb(>aux, DP_PSR_EN_CFG, psr_en);

/* Main-Link transmitter remains active during PSR active states */
-   psr_en = DP_PSR_MAIN_LINK_ACTIVE | DP_PSR_CRC_VERIFICATION;
+   psr_en = DP_PSR_CRC_VERIFICATION;
drm_dp_dpcd_writeb(>aux, DP_PSR_EN_CFG, psr_en);

/* Enable psr function */
-   psr_en = DP_PSR_ENABLE | DP_PSR_MAIN_LINK_ACTIVE |
-DP_PSR_CRC_VERIFICATION;
+   psr_en = DP_PSR_ENABLE | DP_PSR_CRC_VERIFICATION;
drm_dp_dpcd_writeb(>aux, DP_PSR_EN_CFG, psr_en);

analogix_dp_enable_psr_crc(dp);
@@ -870,6 +825,80 @@ static void analogix_dp_commit(struct analogix_dp_device 
*dp)
analogix_dp_enable_sink_psr(dp);
 }

+int analogix_dp_enable_psr(struct device *dev)
+{
+   struct analogix_dp_device *dp = dev_get_drvdata(dev);
+   struct edp_vsc_psr psr_vsc;
+   int retval;
+   u8 sink;
+
+   if (!dp->psr_support)
+   return -EINVAL;
+
+   drm_dp_dpcd_readb(>aux, DP_PSR_STATUS, );
+   if (sink == DP_PSR_SINK_ACTIVE_RFB)
+   return 0;
+
+   /* Prepare VSC packet as per EDP 1.4 spec, Table 6.9 */
+   memset(_vsc, 0, sizeof(psr_vsc));
+   psr_vsc.sdp_header.HB0 = 0;
+   psr_vsc.sdp_header.HB1 = 0x7;
+   psr_vsc.sdp_header.HB2 = 0x2;
+   psr_vsc.sdp_header.HB3 = 0x8;
+
+   psr_vsc.DB0 = 0;
+   psr_vsc.DB1 = EDP_VSC_PSR_STATE_ACTIVE | EDP_VSC_PSR_CRC_VALUES_VALID;
+
+   retval = analogix_dp_send_psr_spd(dp, _vsc);
+
+   if (!retval) {
+   /* Power down the eDP PHY */
+   analogix_dp_set_analog_power_down(dp, POWER_ALL, true);
+   }
+
+   return retval;
+}
+EXPORT_SYMBOL_GPL(analogix_dp_enable_psr);
+
+int analogix_dp_disable_psr(struct device *dev)
+{
+   struct analogix_dp_device *dp = dev_get_drvdata(dev);
+   struct edp_vsc_psr psr_vsc;
+   int ret;
+   u8 sink;
+
+   if (!dp->psr_support)
+   return -EINVAL;
+
+   /* Power up the eDP PHY */
+   analogix_dp_set_analog_power_down(dp, POWER_ALL, false);
+
+   drm_dp_dpcd_readb(>aux, DP_PSR_STATUS, );
+   if (sink == DP_PSR_SINK_INACTIVE)
+   return 0;
+
+   ret = drm_dp_dpcd_writeb(>aux, DP_SET_POWER, DP_SET_POWER_D0);
+   if (ret < 0) {
+   dev_err(dp->dev, "Failed to set DP Power0\n");
+   }
+
+   analogix_dp_set_link_train(dp, dp->video_info.max_lane_count,
+  dp->video_info.max_link_rate);
+
+   /* Prepare VSC packet as per EDP 1.4

[PATCH v3 3/6] drm/bridge: analogix_dp: detect Sink PSR state after configuring the PSR

2016-10-18 Thread Zain Wang
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.

Signed-off-by: zain wang 
Signed-off-by: Yakir Yang 
---

Changes in v3: None
Changes in v2: None

 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  | 25 --
 drivers/gpu/drm/rockchip/analogix_dp-rockchip.c|  6 --
 4 files changed, 33 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 bcae4dd..7faad93 100644
--- a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
+++ b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
@@ -124,8 +124,7 @@ int analogix_dp_enable_psr(struct device *dev)
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);

@@ -147,8 +146,7 @@ int analogix_dp_disable_psr(struct device *dev)
psr_vsc.DB0 = 0;
psr_vsc.DB1 = 0;

-   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 5c6a288..cdc0535 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 msecs_to_jiffies(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 cd37ac0..9e1177c 100644
--- a/drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c
+++ b/drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c
@@ -992,10 +992,12 @@ 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)
+int analogix_dp_send_psr_spd(struct analogix_dp_device *dp,
+struct edp_vsc_psr *vsc)
 {
+   unsigned long timeout;
unsigned int val;
+   u8 sink;

/* don't send info frame */
val = readl(dp->reg_base + ANALOGIX_DP_PKT_SEND_CTL);
@@ -1036,6 +1038,25 @@ 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);
+
+   timeout = jiffies + DP_TIMEOUT_PSR_LOOP_MS;
+   while (time_before(jiffies, timeout)) {
+   val = drm_dp_dpcd_readb(>aux, DP_PSR_STATUS, );
+   if (val != 1) {
+   dev_err(dp->dev, "PSR_STATUS read failed ret=%d", val);
+   return -EBUSY;
+   }
+
+   if ((vsc->DB1 && sink == DP_PSR_SINK_ACTIVE_RFB) ||
+   (!vsc->DB1 && sink == DP_PSR_SINK_INACTIVE))
+   return 0;
+
+   usleep_range(1000, 1500);
+   }
+
+   dev_warn(dp->dev, "Failed to apply PSR, sink state was [%x]", sink);
+
+   return -ETIMEDOUT;
 }

 ssize_t analogix_dp_transfer(struct analogix_dp_device *dp,
diff --git a/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c 
b/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c
index e5471e7..1c2d756 100644
--- a/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c
+++ b/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c
@@ -105,7 +105,7 @@ static void analogix_dp_psr_work(struct work_struct *work)
struct rockchip_dp_device *dp =
containe

[PATCH v3 2/6] drm/bridge: remove dp init from analogix_dp_bind

2016-10-18 Thread Zain Wang
From: zain wang <w...@rock-chips.com>

phy_power_on() and analogix_dp_init_dp would be called in bridge_eanble,
so remove them from analogix_dp_bind to be clear.

Signed-off-by: zain wang 
---

Changes in v3:
- remove changes before
- remove phy_power_on() and analogix_dp_init_dp from analogix_dp_bind().

Changes in v2: None

 drivers/gpu/drm/bridge/analogix/analogix_dp_core.c | 4 
 1 file changed, 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 001b075..bcae4dd 100644
--- a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
+++ b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
@@ -1389,10 +1389,6 @@ int analogix_dp_bind(struct device *dev, struct 
drm_device *drm_dev,

pm_runtime_enable(dev);

-   phy_power_on(dp->phy);
-
-   analogix_dp_init_dp(dp);
-
ret = devm_request_threaded_irq(>dev, dp->irq,
analogix_dp_hardirq,
analogix_dp_irq_thread,
-- 
1.9.1




[PATCH v3 1/6] drm/bridge: analogix_dp: set psr activate/deactivate when enable/disable bridge

2016-10-18 Thread Zain Wang
From: zain wang <w...@rock-chips.com>

There's a race between when bridge_disable and when vop_crtc_disable are called.
If the flush timer triggers a new psr work between these, we will operate eDP
without power shutdowned by bridge_disable.
In this case, moving activate/deactivate to enable/disable bridge to avoid it.

Signed-off-by: zain wang 
---

Changes in v3:
- remove changes before.
- move psr activat/deactivate to enable/disable bridge.

Changes in v2:
- add spin_lock to protect dpms_mode


 drivers/gpu/drm/rockchip/analogix_dp-rockchip.c |  4 ++--
 drivers/gpu/drm/rockchip/rockchip_drm_psr.c | 30 -
 drivers/gpu/drm/rockchip/rockchip_drm_psr.h |  4 ++--
 drivers/gpu/drm/rockchip/rockchip_drm_vop.c |  4 
 4 files changed, 28 insertions(+), 14 deletions(-)

diff --git a/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c 
b/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c
index 8548e82..e5471e7 100644
--- a/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c
+++ b/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c
@@ -159,7 +159,7 @@ static int rockchip_dp_poweron(struct analogix_dp_plat_data 
*plat_data)
return ret;
}

-   return 0;
+   return rockchip_drm_psr_activate(>encoder);
 }

 static int rockchip_dp_powerdown(struct analogix_dp_plat_data *plat_data)
@@ -168,7 +168,7 @@ static int rockchip_dp_powerdown(struct 
analogix_dp_plat_data *plat_data)

clk_disable_unprepare(dp->pclk);

-   return 0;
+   return rockchip_drm_psr_deactivate(>encoder);
 }

 static int rockchip_dp_get_modes(struct analogix_dp_plat_data *plat_data,
diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_psr.c 
b/drivers/gpu/drm/rockchip/rockchip_drm_psr.c
index a553e18..4c379e9 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_psr.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_psr.c
@@ -57,6 +57,24 @@ out:
return psr;
 }

+static struct psr_drv *find_psr_by_encoder(struct drm_encoder *encoder)
+{
+   struct rockchip_drm_private *drm_drv = encoder->dev->dev_private;
+   struct psr_drv *psr;
+   unsigned long flags;
+
+   spin_lock_irqsave(_drv->psr_list_lock, flags);
+   list_for_each_entry(psr, _drv->psr_list, list) {
+   if (psr->encoder == encoder)
+   goto out;
+   }
+   psr = ERR_PTR(-ENODEV);
+
+out:
+   spin_unlock_irqrestore(_drv->psr_list_lock, flags);
+   return psr;
+}
+
 static void psr_set_state_locked(struct psr_drv *psr, enum psr_state state)
 {
/*
@@ -115,14 +133,14 @@ static void psr_flush_handler(unsigned long data)

 /**
  * rockchip_drm_psr_activate - activate PSR on the given pipe
- * @crtc: CRTC to obtain the PSR encoder
+ * @encoder: encoder to obtain the PSR encoder
  *
  * Returns:
  * Zero on success, negative errno on failure.
  */
-int rockchip_drm_psr_activate(struct drm_crtc *crtc)
+int rockchip_drm_psr_activate(struct drm_encoder *encoder)
 {
-   struct psr_drv *psr = find_psr_by_crtc(crtc);
+   struct psr_drv *psr = find_psr_by_encoder(encoder);
unsigned long flags;

if (IS_ERR(psr))
@@ -138,14 +156,14 @@ EXPORT_SYMBOL(rockchip_drm_psr_activate);

 /**
  * rockchip_drm_psr_deactivate - deactivate PSR on the given pipe
- * @crtc: CRTC to obtain the PSR encoder
+ * @encoder: encoder to obtain the PSR encoder
  *
  * Returns:
  * Zero on success, negative errno on failure.
  */
-int rockchip_drm_psr_deactivate(struct drm_crtc *crtc)
+int rockchip_drm_psr_deactivate(struct drm_encoder *encoder)
 {
-   struct psr_drv *psr = find_psr_by_crtc(crtc);
+   struct psr_drv *psr = find_psr_by_encoder(encoder);
unsigned long flags;

if (IS_ERR(psr))
diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_psr.h 
b/drivers/gpu/drm/rockchip/rockchip_drm_psr.h
index b420cf1..b1ea015 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_psr.h
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_psr.h
@@ -18,8 +18,8 @@
 void rockchip_drm_psr_flush_all(struct drm_device *dev);
 int rockchip_drm_psr_flush(struct drm_crtc *crtc);

-int rockchip_drm_psr_activate(struct drm_crtc *crtc);
-int rockchip_drm_psr_deactivate(struct drm_crtc *crtc);
+int rockchip_drm_psr_activate(struct drm_encoder *encoder);
+int rockchip_drm_psr_deactivate(struct drm_encoder *encoder);

 int rockchip_drm_psr_register(struct drm_encoder *encoder,
void (*psr_set)(struct drm_encoder *, bool enable));
diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c 
b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
index c7eba30..1740a0b 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
@@ -566,8 +566,6 @@ static void vop_crtc_disable(struct drm_crtc *crtc)

WARN_ON(vop->event);

-   rockchip_drm_psr_deactivate(>crtc);
-
/*
 * We need to make sure that all windows are disabled before we
 * disable that crtc. Otherwis

[PATCH v3 0/6] Misc changes to Rockchip PSR drivers

2016-10-18 Thread Zain Wang
This serise of patches works for saving power on eDP PHY and VOP during PSR.

BR,
- Zain

Changes in v3:
- add new patch to support fast link training.
- add new patch to make VOP standby when entry PSR.
- Misc changes.

Changes in v2:
- add spin_lock to protect dpms_mode
- misc changes.

Yakir Yang (1):
  drm/bridge: analogix_dp: detect Sink PSR state after configuring the
PSR

zain wang (5):
  drm/bridge: analogix_dp: set psr activate/deactivate when
enable/disable bridge
  drm/bridge: remove dp init from analogix_dp_bind
  drm: bridge/analogix: switch Main-link and eDP PHY when enable/disable
psr
  drm: bridge/analogix: add fast link train for eDP
  drm: bridge/analogix: enable vop standby when entry PSR

 drivers/gpu/drm/bridge/analogix/analogix_dp_core.c | 218 +++--
 drivers/gpu/drm/bridge/analogix/analogix_dp_core.h |   7 +-
 drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c  |  25 ++-
 drivers/gpu/drm/rockchip/analogix_dp-rockchip.c|  33 +++-
 drivers/gpu/drm/rockchip/rockchip_drm_drv.h|   1 +
 drivers/gpu/drm/rockchip/rockchip_drm_psr.c|  30 ++-
 drivers/gpu/drm/rockchip/rockchip_drm_psr.h|   4 +-
 drivers/gpu/drm/rockchip/rockchip_drm_vop.c|  23 ++-
 8 files changed, 259 insertions(+), 82 deletions(-)

-- 
1.9.1




[PATCH v2 4/4] drm: bridge/analogix: switch Main-link and eDP PHY when enable/disable psr

2016-09-30 Thread zain wang
turn off Main-link and power down eDP PHY when enable psr,
turn on Main-link and power up eDP PHY when disable psr.

Signed-off-by: zain wang 

---

Changes in v2:
- misc changes

 drivers/gpu/drm/bridge/analogix/analogix_dp_core.c | 124 -
 1 file changed, 70 insertions(+), 54 deletions(-)

diff --git a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c 
b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
index bf87891..58fa1c1 100644
--- a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
+++ b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
@@ -120,57 +120,6 @@ static int analogix_dp_get_dpms_mode(struct 
analogix_dp_device *dp)
return mode;
 }

-
-int analogix_dp_enable_psr(struct device *dev)
-{
-   struct analogix_dp_device *dp = dev_get_drvdata(dev);
-   struct edp_vsc_psr psr_vsc;
-
-   if (!dp->psr_support)
-   return -EINVAL;
-
-   if (analogix_dp_get_dpms_mode(dp) != DRM_MODE_DPMS_ON)
-   return -EBUSY;
-
-   /* Prepare VSC packet as per EDP 1.4 spec, Table 6.9 */
-   memset(_vsc, 0, sizeof(psr_vsc));
-   psr_vsc.sdp_header.HB0 = 0;
-   psr_vsc.sdp_header.HB1 = 0x7;
-   psr_vsc.sdp_header.HB2 = 0x2;
-   psr_vsc.sdp_header.HB3 = 0x8;
-
-   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);
-}
-EXPORT_SYMBOL_GPL(analogix_dp_enable_psr);
-
-int analogix_dp_disable_psr(struct device *dev)
-{
-   struct analogix_dp_device *dp = dev_get_drvdata(dev);
-   struct edp_vsc_psr psr_vsc;
-
-   if (!dp->psr_support)
-   return -EINVAL;
-
-   if (analogix_dp_get_dpms_mode(dp) != DRM_MODE_DPMS_ON)
-   return -EBUSY;
-
-   /* Prepare VSC packet as per EDP 1.4 spec, Table 6.9 */
-   memset(_vsc, 0, sizeof(psr_vsc));
-   psr_vsc.sdp_header.HB0 = 0;
-   psr_vsc.sdp_header.HB1 = 0x7;
-   psr_vsc.sdp_header.HB2 = 0x2;
-   psr_vsc.sdp_header.HB3 = 0x8;
-
-   psr_vsc.DB0 = 0;
-   psr_vsc.DB1 = 0;
-
-   return analogix_dp_send_psr_spd(dp, _vsc);
-}
-EXPORT_SYMBOL_GPL(analogix_dp_disable_psr);
-
 static bool analogix_dp_detect_sink_psr(struct analogix_dp_device *dp)
 {
unsigned char psr_version;
@@ -191,12 +140,11 @@ static void analogix_dp_enable_sink_psr(struct 
analogix_dp_device *dp)
drm_dp_dpcd_writeb(>aux, DP_PSR_EN_CFG, psr_en);

/* Main-Link transmitter remains active during PSR active states */
-   psr_en = DP_PSR_MAIN_LINK_ACTIVE | DP_PSR_CRC_VERIFICATION;
+   psr_en = DP_PSR_CRC_VERIFICATION;
drm_dp_dpcd_writeb(>aux, DP_PSR_EN_CFG, psr_en);

/* Enable psr function */
-   psr_en = DP_PSR_ENABLE | DP_PSR_MAIN_LINK_ACTIVE |
-DP_PSR_CRC_VERIFICATION;
+   psr_en = DP_PSR_ENABLE | DP_PSR_CRC_VERIFICATION;
drm_dp_dpcd_writeb(>aux, DP_PSR_EN_CFG, psr_en);

analogix_dp_enable_psr_crc(dp);
@@ -899,6 +847,74 @@ static void analogix_dp_commit(struct analogix_dp_device 
*dp)
analogix_dp_enable_sink_psr(dp);
 }

+int analogix_dp_enable_psr(struct device *dev)
+{
+   struct analogix_dp_device *dp = dev_get_drvdata(dev);
+   struct edp_vsc_psr psr_vsc;
+
+   if (!dp->psr_support)
+   return -EINVAL;
+
+   if (analogix_dp_get_dpms_mode(dp) != DRM_MODE_DPMS_ON)
+   return -EBUSY;
+
+   /* Prepare VSC packet as per EDP 1.4 spec, Table 6.9 */
+   memset(_vsc, 0, sizeof(psr_vsc));
+   psr_vsc.sdp_header.HB0 = 0;
+   psr_vsc.sdp_header.HB1 = 0x7;
+   psr_vsc.sdp_header.HB2 = 0x2;
+   psr_vsc.sdp_header.HB3 = 0x8;
+
+   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);
+
+   /* Power down the eDP PHY */
+   analogix_dp_set_analog_power_down(dp, POWER_ALL, true);
+
+   return 0;
+}
+EXPORT_SYMBOL_GPL(analogix_dp_enable_psr);
+
+int analogix_dp_disable_psr(struct device *dev)
+{
+   struct analogix_dp_device *dp = dev_get_drvdata(dev);
+   struct edp_vsc_psr psr_vsc;
+   int ret;
+
+   if (!dp->psr_support)
+   return -EINVAL;
+
+   if (analogix_dp_get_dpms_mode(dp) != DRM_MODE_DPMS_ON)
+   return -EBUSY;
+
+   /* Power up the eDP PHY */
+   analogix_dp_set_analog_power_down(dp, POWER_ALL, false);
+
+   ret = drm_dp_dpcd_writeb(>aux, DP_SET_POWER, DP_SET_POWER_D0);
+   if (ret < 0) {
+   dev_err(dp->dev, "Failed to set DP Power0\n");
+   }
+
+   analogix_dp_set_link_train(dp, dp->video_info.max_lane_count,
+  dp->video_info.max_link_rate);
+
+   /* Prepare VSC packet as per EDP 1.4 spec, Table 6.9 */
+   memset(_vsc, 0, sizeof(psr_vsc));
+   psr_vsc.sdp_header.HB0 = 0;
+   psr_vsc.sdp_header.H

[PATCH v2 3/4] drm/bridge: analogix_dp: detect Sink PSR state after configuring the PSR

2016-09-30 Thread zain wang
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.

Signed-off-by: Yakir Yang 
Signed-off-by: Zain Wang 

---

Changes in v2: None

 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  | 25 --
 drivers/gpu/drm/rockchip/analogix_dp-rockchip.c|  8 ---
 4 files changed, 34 insertions(+), 11 deletions(-)

diff --git a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c 
b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
index 1bd190e..bf87891 100644
--- a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
+++ b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
@@ -142,8 +142,7 @@ int analogix_dp_enable_psr(struct device *dev)
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);

@@ -168,8 +167,7 @@ int analogix_dp_disable_psr(struct device *dev)
psr_vsc.DB0 = 0;
psr_vsc.DB1 = 0;

-   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 776c844..553c411 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 msecs_to_jiffies(300)
+
 /* DP_MAX_LANE_COUNT */
 #define DPCD_ENHANCED_FRAME_CAP(x) (((x) >> 7) & 0x1)
 #define DPCD_MAX_LANE_COUNT(x) ((x) & 0x1f)
@@ -248,8 +250,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 cd37ac0..9e1177c 100644
--- a/drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c
+++ b/drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c
@@ -992,10 +992,12 @@ 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)
+int analogix_dp_send_psr_spd(struct analogix_dp_device *dp,
+struct edp_vsc_psr *vsc)
 {
+   unsigned long timeout;
unsigned int val;
+   u8 sink;

/* don't send info frame */
val = readl(dp->reg_base + ANALOGIX_DP_PKT_SEND_CTL);
@@ -1036,6 +1038,25 @@ 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);
+
+   timeout = jiffies + DP_TIMEOUT_PSR_LOOP_MS;
+   while (time_before(jiffies, timeout)) {
+   val = drm_dp_dpcd_readb(>aux, DP_PSR_STATUS, );
+   if (val != 1) {
+   dev_err(dp->dev, "PSR_STATUS read failed ret=%d", val);
+   return -EBUSY;
+   }
+
+   if ((vsc->DB1 && sink == DP_PSR_SINK_ACTIVE_RFB) ||
+   (!vsc->DB1 && sink == DP_PSR_SINK_INACTIVE))
+   return 0;
+
+   usleep_range(1000, 1500);
+   }
+
+   dev_warn(dp->dev, "Failed to apply PSR, sink state was [%x]", sink);
+
+   return -ETIMEDOUT;
 }

 ssize_t analogix_dp_transfer(struct analogix_dp_device *dp,
diff --git a/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c 
b/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c
index e83be15..dc106d0 100644
--- a/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c
+++ b/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c
@@ -102,10 +102,10 @@ static void analogix_dp_psr_work(struct work_struct *work)
struct rockchip_dp_device *dp =
container_of(work, ty

[PATCH v2 2/4] drm/bridge: analogix_dp: get sync PM when init eDP

2016-09-30 Thread zain wang
Signed-off-by: zain wang 

---

Changes in v2: None

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

diff --git a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c 
b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
index b4ce16a..1bd190e 100644
--- a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
+++ b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
@@ -1411,10 +1411,12 @@ int analogix_dp_bind(struct device *dev, struct 
drm_device *drm_dev,
}

pm_runtime_enable(dev);
+   pm_runtime_get_sync(dev);

phy_power_on(dp->phy);

analogix_dp_init_dp(dp);
+   pm_runtime_put_sync(dev);

ret = devm_request_threaded_irq(>dev, dp->irq,
analogix_dp_hardirq,
-- 
1.9.1




[PATCH v2 1/4] drm/bridge: analogix_dp: prevent runing enable_psr when disabled bridge.

2016-09-30 Thread zain wang
When disabled bridge, analogix_dp_enable_psr() may run due to timer was set
by rockchip_drm_do_flush(), in this case we should return -EBUSY.

Signed-off-by: zain wang 

---

Changes in v2:
- add spin_lock to protect dpms_mode

 drivers/gpu/drm/bridge/analogix/analogix_dp_core.c | 43 +++---
 drivers/gpu/drm/bridge/analogix/analogix_dp_core.h |  1 +
 2 files changed, 38 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 0f2e423..b4ce16a 100644
--- a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
+++ b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
@@ -98,6 +98,29 @@ static int analogix_dp_detect_hpd(struct analogix_dp_device 
*dp)
return 0;
 }

+static void analogix_dp_set_dpms_mode(struct analogix_dp_device *dp, int mode)
+{
+   unsigned long flags;
+
+   spin_lock_irqsave(>dpms_mode_lock, flags);
+   dp->dpms_mode = mode;
+   spin_unlock_irqrestore(>dpms_mode_lock, flags);
+
+}
+
+static int analogix_dp_get_dpms_mode(struct analogix_dp_device *dp)
+{
+   unsigned long flags;
+   int mode;
+
+   spin_lock_irqsave(>dpms_mode_lock, flags);
+   mode = dp->dpms_mode;
+   spin_unlock_irqrestore(>dpms_mode_lock, flags);
+
+   return mode;
+}
+
+
 int analogix_dp_enable_psr(struct device *dev)
 {
struct analogix_dp_device *dp = dev_get_drvdata(dev);
@@ -106,6 +129,9 @@ int analogix_dp_enable_psr(struct device *dev)
if (!dp->psr_support)
return -EINVAL;

+   if (analogix_dp_get_dpms_mode(dp) != DRM_MODE_DPMS_ON)
+   return -EBUSY;
+
/* Prepare VSC packet as per EDP 1.4 spec, Table 6.9 */
memset(_vsc, 0, sizeof(psr_vsc));
psr_vsc.sdp_header.HB0 = 0;
@@ -129,6 +155,9 @@ int analogix_dp_disable_psr(struct device *dev)
if (!dp->psr_support)
return -EINVAL;

+   if (analogix_dp_get_dpms_mode(dp) != DRM_MODE_DPMS_ON)
+   return -EBUSY;
+
/* Prepare VSC packet as per EDP 1.4 spec, Table 6.9 */
memset(_vsc, 0, sizeof(psr_vsc));
psr_vsc.sdp_header.HB0 = 0;
@@ -1073,7 +1102,7 @@ static void analogix_dp_bridge_enable(struct drm_bridge 
*bridge)
 {
struct analogix_dp_device *dp = bridge->driver_private;

-   if (dp->dpms_mode == DRM_MODE_DPMS_ON)
+   if (analogix_dp_get_dpms_mode(dp) == DRM_MODE_DPMS_ON)
return;

pm_runtime_get_sync(dp->dev);
@@ -1086,7 +1115,7 @@ static void analogix_dp_bridge_enable(struct drm_bridge 
*bridge)
enable_irq(dp->irq);
analogix_dp_commit(dp);

-   dp->dpms_mode = DRM_MODE_DPMS_ON;
+   analogix_dp_set_dpms_mode(dp, DRM_MODE_DPMS_ON);
 }

 static void analogix_dp_bridge_disable(struct drm_bridge *bridge)
@@ -1094,9 +1123,11 @@ static void analogix_dp_bridge_disable(struct drm_bridge 
*bridge)
struct analogix_dp_device *dp = bridge->driver_private;
int ret;

-   if (dp->dpms_mode != DRM_MODE_DPMS_ON)
+   if (analogix_dp_get_dpms_mode(dp) != DRM_MODE_DPMS_ON)
return;

+   analogix_dp_set_dpms_mode(dp, DRM_MODE_DPMS_OFF);
+
if (dp->plat_data->panel) {
if (drm_panel_disable(dp->plat_data->panel)) {
DRM_ERROR("failed to disable the panel\n");
@@ -1115,8 +1146,6 @@ static void analogix_dp_bridge_disable(struct drm_bridge 
*bridge)
ret = analogix_dp_prepare_panel(dp, false, true);
if (ret)
DRM_ERROR("failed to setup the panel ret = %d\n", ret);
-
-   dp->dpms_mode = DRM_MODE_DPMS_OFF;
 }

 static void analogix_dp_bridge_mode_set(struct drm_bridge *bridge,
@@ -1299,7 +1328,9 @@ int analogix_dp_bind(struct device *dev, struct 
drm_device *drm_dev,
dev_set_drvdata(dev, dp);

dp->dev = >dev;
-   dp->dpms_mode = DRM_MODE_DPMS_OFF;
+
+   spin_lock_init(>dpms_mode_lock);
+   analogix_dp_set_dpms_mode(dp, DRM_MODE_DPMS_OFF);

mutex_init(>panel_lock);
dp->panel_is_modeset = false;
diff --git a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.h 
b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.h
index 5c6a288..776c844 100644
--- a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.h
+++ b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.h
@@ -166,6 +166,7 @@ struct analogix_dp_device {
struct link_train   link_train;
struct phy  *phy;
int dpms_mode;
+   spinlock_t  dpms_mode_lock;
int hpd_gpio;
boolforce_hpd;
boolpsr_support;
-- 
1.9.1




[PATCH v2 0/4] Misc changes to Rockchip PSR drivers

2016-09-30 Thread zain wang

1. prevent runing enable_psr when disabled bridge
2. get sync PM when init eDP
3. detect Sink PSR state after configuring the PSR
4. switch Main-Link and eDP phy when enable/disable psr

BR,
- Zain

Changes in v2:
- add spin_lock to protect dpms_mode
- misc changes

Yakir Yang (1):
  drm/bridge: analogix_dp: detect Sink PSR state after configuring the
PSR

zain wang (3):
  drm/bridge: analogix_dp: prevent runing enable_psr when disabled
bridge.
  drm/bridge: analogix_dp: get sync PM when init eDP
  drm: bridge/analogix: switch Main-link and eDP PHY when enable/disable
psr

 drivers/gpu/drm/bridge/analogix/analogix_dp_core.c | 137 ++---
 drivers/gpu/drm/bridge/analogix/analogix_dp_core.h |   7 +-
 drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c  |  25 +++-
 drivers/gpu/drm/rockchip/analogix_dp-rockchip.c|   8 +-
 4 files changed, 125 insertions(+), 52 deletions(-)

-- 
1.9.1




[PATCH v1 4/4] drm: bridge/analogix: switch Main-link and eDP PHY when enable/disable psr

2016-09-29 Thread zain wang
turn off Main-link and power down eDP PHY when enable psr,
turn on Main-link and power up eDP PHY when disable psr.

Signed-off-by: zain wang 

---

 drivers/gpu/drm/bridge/analogix/analogix_dp_core.c | 105 ++---
 1 file changed, 52 insertions(+), 53 deletions(-)

diff --git a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c 
b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
index 7177f5f..1bc98ab 100644
--- a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
+++ b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
@@ -98,56 +98,6 @@ static int analogix_dp_detect_hpd(struct analogix_dp_device 
*dp)
return 0;
 }

-int analogix_dp_enable_psr(struct device *dev)
-{
-   struct analogix_dp_device *dp = dev_get_drvdata(dev);
-   struct edp_vsc_psr psr_vsc;
-
-   if (!dp->psr_support)
-   return -EINVAL;
-
-   if (dp->dpms_mode != DRM_MODE_DPMS_ON)
-   return -EBUSY;
-
-   /* Prepare VSC packet as per EDP 1.4 spec, Table 6.9 */
-   memset(_vsc, 0, sizeof(psr_vsc));
-   psr_vsc.sdp_header.HB0 = 0;
-   psr_vsc.sdp_header.HB1 = 0x7;
-   psr_vsc.sdp_header.HB2 = 0x2;
-   psr_vsc.sdp_header.HB3 = 0x8;
-
-   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);
-}
-EXPORT_SYMBOL_GPL(analogix_dp_enable_psr);
-
-int analogix_dp_disable_psr(struct device *dev)
-{
-   struct analogix_dp_device *dp = dev_get_drvdata(dev);
-   struct edp_vsc_psr psr_vsc;
-
-   if (!dp->psr_support)
-   return -EINVAL;
-
-   if (dp->dpms_mode != DRM_MODE_DPMS_ON)
-   return -EBUSY;
-
-   /* Prepare VSC packet as per EDP 1.4 spec, Table 6.9 */
-   memset(_vsc, 0, sizeof(psr_vsc));
-   psr_vsc.sdp_header.HB0 = 0;
-   psr_vsc.sdp_header.HB1 = 0x7;
-   psr_vsc.sdp_header.HB2 = 0x2;
-   psr_vsc.sdp_header.HB3 = 0x8;
-
-   psr_vsc.DB0 = 0;
-   psr_vsc.DB1 = 0;
-
-   return analogix_dp_send_psr_spd(dp, _vsc);
-}
-EXPORT_SYMBOL_GPL(analogix_dp_disable_psr);
-
 static bool analogix_dp_detect_sink_psr(struct analogix_dp_device *dp)
 {
unsigned char psr_version;
@@ -168,12 +118,11 @@ static void analogix_dp_enable_sink_psr(struct 
analogix_dp_device *dp)
drm_dp_dpcd_writeb(>aux, DP_PSR_EN_CFG, psr_en);

/* Main-Link transmitter remains active during PSR active states */
-   psr_en = DP_PSR_MAIN_LINK_ACTIVE | DP_PSR_CRC_VERIFICATION;
+   psr_en = DP_PSR_CRC_VERIFICATION;
drm_dp_dpcd_writeb(>aux, DP_PSR_EN_CFG, psr_en);

/* Enable psr function */
-   psr_en = DP_PSR_ENABLE | DP_PSR_MAIN_LINK_ACTIVE |
-DP_PSR_CRC_VERIFICATION;
+   psr_en = DP_PSR_ENABLE | DP_PSR_CRC_VERIFICATION;
drm_dp_dpcd_writeb(>aux, DP_PSR_EN_CFG, psr_en);

analogix_dp_enable_psr_crc(dp);
@@ -876,6 +825,56 @@ static void analogix_dp_commit(struct analogix_dp_device 
*dp)
analogix_dp_enable_sink_psr(dp);
 }

+int analogix_dp_enable_psr(struct device *dev)
+{
+   struct analogix_dp_device *dp = dev_get_drvdata(dev);
+   struct edp_vsc_psr psr_vsc;
+
+   if (!dp->psr_support)
+   return -EINVAL;
+
+   if (dp->dpms_mode != DRM_MODE_DPMS_ON)
+   return -EBUSY;
+
+   /* Prepare VSC packet as per EDP 1.4 spec, Table 6.9 */
+   memset(_vsc, 0, sizeof(psr_vsc));
+   psr_vsc.sdp_header.HB0 = 0;
+   psr_vsc.sdp_header.HB1 = 0x7;
+   psr_vsc.sdp_header.HB2 = 0x2;
+   psr_vsc.sdp_header.HB3 = 0x8;
+
+   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);
+}
+EXPORT_SYMBOL_GPL(analogix_dp_enable_psr);
+
+int analogix_dp_disable_psr(struct device *dev)
+{
+   struct analogix_dp_device *dp = dev_get_drvdata(dev);
+   struct edp_vsc_psr psr_vsc;
+
+   if (!dp->psr_support)
+   return -EINVAL;
+
+   if (dp->dpms_mode != DRM_MODE_DPMS_ON)
+   return -EBUSY;
+
+   /* Prepare VSC packet as per EDP 1.4 spec, Table 6.9 */
+   memset(_vsc, 0, sizeof(psr_vsc));
+   psr_vsc.sdp_header.HB0 = 0;
+   psr_vsc.sdp_header.HB1 = 0x7;
+   psr_vsc.sdp_header.HB2 = 0x2;
+   psr_vsc.sdp_header.HB3 = 0x8;
+
+   psr_vsc.DB0 = 0;
+   psr_vsc.DB1 = 0;
+
+   return analogix_dp_send_psr_spd(dp, _vsc);
+}
+EXPORT_SYMBOL_GPL(analogix_dp_disable_psr);
+
 /*
  * This function is a bit of a catch-all for panel preparation, hopefully
  * simplifying the logic of functions that need to prepare/unprepare the panel
-- 
1.9.1




[PATCH v1 3/4] drm/bridge: analogix_dp: detect Sink PSR state after configuring the PSR

2016-09-29 Thread zain wang
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.

Signed-off-by: Yakir Yang 
Signed-off-by: Zain Wang 

---

 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  | 25 --
 drivers/gpu/drm/rockchip/analogix_dp-rockchip.c|  8 ---
 4 files changed, 34 insertions(+), 11 deletions(-)

diff --git a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c 
b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
index 026ec91..7177f5f 100644
--- a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
+++ b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
@@ -119,8 +119,7 @@ int analogix_dp_enable_psr(struct device *dev)
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);

@@ -145,8 +144,7 @@ int analogix_dp_disable_psr(struct device *dev)
psr_vsc.DB0 = 0;
psr_vsc.DB1 = 0;

-   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 5c6a288..cdc0535 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 msecs_to_jiffies(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 cd37ac0..9e1177c 100644
--- a/drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c
+++ b/drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c
@@ -992,10 +992,12 @@ 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)
+int analogix_dp_send_psr_spd(struct analogix_dp_device *dp,
+struct edp_vsc_psr *vsc)
 {
+   unsigned long timeout;
unsigned int val;
+   u8 sink;

/* don't send info frame */
val = readl(dp->reg_base + ANALOGIX_DP_PKT_SEND_CTL);
@@ -1036,6 +1038,25 @@ 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);
+
+   timeout = jiffies + DP_TIMEOUT_PSR_LOOP_MS;
+   while (time_before(jiffies, timeout)) {
+   val = drm_dp_dpcd_readb(>aux, DP_PSR_STATUS, );
+   if (val != 1) {
+   dev_err(dp->dev, "PSR_STATUS read failed ret=%d", val);
+   return -EBUSY;
+   }
+
+   if ((vsc->DB1 && sink == DP_PSR_SINK_ACTIVE_RFB) ||
+   (!vsc->DB1 && sink == DP_PSR_SINK_INACTIVE))
+   return 0;
+
+   usleep_range(1000, 1500);
+   }
+
+   dev_warn(dp->dev, "Failed to apply PSR, sink state was [%x]", sink);
+
+   return -ETIMEDOUT;
 }

 ssize_t analogix_dp_transfer(struct analogix_dp_device *dp,
diff --git a/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c 
b/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c
index e83be15..dc106d0 100644
--- a/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c
+++ b/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c
@@ -102,10 +102,10 @@ static void analogix_dp_psr_work(struct work_struct *work)
struct rockchip_dp_device *dp =
container_of(work, typeof(*dp), psr_work);

[PATCH v1 2/4] drm/bridge: analogix_dp: get sync PM when init eDP

2016-09-29 Thread zain wang
Signed-off-by: zain wang 

---

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

diff --git a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c 
b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
index 206529a..026ec91 100644
--- a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
+++ b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
@@ -1386,10 +1386,12 @@ int analogix_dp_bind(struct device *dev, struct 
drm_device *drm_dev,
}

pm_runtime_enable(dev);
+   pm_runtime_get_sync(dev);

phy_power_on(dp->phy);

analogix_dp_init_dp(dp);
+   pm_runtime_put_sync(dev);

ret = devm_request_threaded_irq(>dev, dp->irq,
analogix_dp_hardirq,
-- 
1.9.1




[PATCH v1 1/4] drm/bridge: analogix_dp: prevent runing enable_psr when disabled bridge.

2016-09-29 Thread zain wang
When disabled bridge, analogix_dp_enable_psr() may run due to timer was set
by rockchip_drm_do_flush(), in this case we should return -EBUSY.

Signed-off-by: zain wang 

---

 drivers/gpu/drm/bridge/analogix/analogix_dp_core.c | 10 --
 1 file changed, 8 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 0f2e423..206529a 100644
--- a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
+++ b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
@@ -106,6 +106,9 @@ int analogix_dp_enable_psr(struct device *dev)
if (!dp->psr_support)
return -EINVAL;

+   if (dp->dpms_mode != DRM_MODE_DPMS_ON)
+   return -EBUSY;
+
/* Prepare VSC packet as per EDP 1.4 spec, Table 6.9 */
memset(_vsc, 0, sizeof(psr_vsc));
psr_vsc.sdp_header.HB0 = 0;
@@ -129,6 +132,9 @@ int analogix_dp_disable_psr(struct device *dev)
if (!dp->psr_support)
return -EINVAL;

+   if (dp->dpms_mode != DRM_MODE_DPMS_ON)
+   return -EBUSY;
+
/* Prepare VSC packet as per EDP 1.4 spec, Table 6.9 */
memset(_vsc, 0, sizeof(psr_vsc));
psr_vsc.sdp_header.HB0 = 0;
@@ -1097,6 +1103,8 @@ static void analogix_dp_bridge_disable(struct drm_bridge 
*bridge)
if (dp->dpms_mode != DRM_MODE_DPMS_ON)
return;

+   dp->dpms_mode = DRM_MODE_DPMS_OFF;
+
if (dp->plat_data->panel) {
if (drm_panel_disable(dp->plat_data->panel)) {
DRM_ERROR("failed to disable the panel\n");
@@ -1115,8 +1123,6 @@ static void analogix_dp_bridge_disable(struct drm_bridge 
*bridge)
ret = analogix_dp_prepare_panel(dp, false, true);
if (ret)
DRM_ERROR("failed to setup the panel ret = %d\n", ret);
-
-   dp->dpms_mode = DRM_MODE_DPMS_OFF;
 }

 static void analogix_dp_bridge_mode_set(struct drm_bridge *bridge,
-- 
1.9.1




[PATCH v1 0/4] Misc changes to Rockchip PSR drivers

2016-09-29 Thread zain wang

1. prevent runing enable_psr when disabled bridge
2. get sync PM when init eDP
3. detect Sink PSR state after configuring the PSR
4. switch Main-Link and eDP phy when enable/disable psr

BR,
- Zain


Yakir Yang (1):
  drm/bridge: analogix_dp: detect Sink PSR state after configuring the
PSR

zain wang (3):
  drm/bridge: analogix_dp: prevent runing enable_psr when disabled
bridge.
  drm/bridge: analogix_dp: get sync PM when init eDP
  drm: bridge/analogix: switch Main-link and eDP PHY when enable/disable
psr

 drivers/gpu/drm/bridge/analogix/analogix_dp_core.c | 107 +++--
 drivers/gpu/drm/bridge/analogix/analogix_dp_core.h |   6 +-
 drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c  |  25 -
 drivers/gpu/drm/rockchip/analogix_dp-rockchip.c|   8 +-
 4 files changed, 88 insertions(+), 58 deletions(-)

-- 
1.9.1