Re: [PATCH v6 5/5] drm/rockchip: support dp training outside dp firmware

2018-05-22 Thread hl

Hi Enric,


On Wednesday, May 23, 2018 01:06 AM, Enric Balletbo Serra wrote:

Lin,

2018-05-22 9:41 GMT+02:00 Enric Balletbo Serra <eballe...@gmail.com>:

Hi Lin

2018-05-22 3:08 GMT+02:00 hl <h...@rock-chips.com>:

Hi Enric,




On Monday, May 21, 2018 11:22 PM, Enric Balletbo Serra wrote:

Hi Lin,

2018-05-21 11:37 GMT+02:00 Lin Huang <h...@rock-chips.com>:

DP firmware uses fixed phy config values to do training, but some
boards need to adjust these values to fit for their unique hardware
design. So get phy config values from dts and use software link training
instead of relying on firmware, if software training fail, keep firmware
training as a fallback if sw training fails.

Signed-off-by: Chris Zhong <z...@rock-chips.com>
Signed-off-by: Lin Huang <h...@rock-chips.com>
Reviewed-by: Sean Paul <seanp...@chromium.org>
---
Changes in v2:
- update patch following Enric suggest
Changes in v3:
- use variable fw_training instead sw_training_success
- base on DP SPCE, if training fail use lower link rate to retry training
Changes in v4:
- improve cdn_dp_get_lower_link_rate() and cdn_dp_software_train_link()
follow Sean suggest
Changes in v5:
- fix some whitespcae issue
Changes in v6:
- None

   drivers/gpu/drm/rockchip/Makefile   |   3 +-
   drivers/gpu/drm/rockchip/cdn-dp-core.c  |  24 +-
   drivers/gpu/drm/rockchip/cdn-dp-core.h  |   2 +
   drivers/gpu/drm/rockchip/cdn-dp-link-training.c | 420

   drivers/gpu/drm/rockchip/cdn-dp-reg.c   |  31 +-
   drivers/gpu/drm/rockchip/cdn-dp-reg.h   |  38 ++-
   6 files changed, 505 insertions(+), 13 deletions(-)
   create mode 100644 drivers/gpu/drm/rockchip/cdn-dp-link-training.c

diff --git a/drivers/gpu/drm/rockchip/Makefile
b/drivers/gpu/drm/rockchip/Makefile
index a314e21..b932f62 100644
--- a/drivers/gpu/drm/rockchip/Makefile
+++ b/drivers/gpu/drm/rockchip/Makefile
@@ -9,7 +9,8 @@ rockchipdrm-y := rockchip_drm_drv.o rockchip_drm_fb.o \
   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_CDN_DP) += cdn-dp-core.o cdn-dp-reg.o \
+   cdn-dp-link-training.o
   rockchipdrm-$(CONFIG_ROCKCHIP_DW_HDMI) += dw_hdmi-rockchip.o
   rockchipdrm-$(CONFIG_ROCKCHIP_DW_MIPI_DSI) += dw-mipi-dsi.o
   rockchipdrm-$(CONFIG_ROCKCHIP_INNO_HDMI) += inno_hdmi.o
diff --git a/drivers/gpu/drm/rockchip/cdn-dp-core.c
b/drivers/gpu/drm/rockchip/cdn-dp-core.c
index cce64c1..d9d0d4d 100644
--- a/drivers/gpu/drm/rockchip/cdn-dp-core.c
+++ b/drivers/gpu/drm/rockchip/cdn-dp-core.c
@@ -629,11 +629,13 @@ static void cdn_dp_encoder_enable(struct
drm_encoder *encoder)
  goto out;
  }
  }
-
-   ret = cdn_dp_set_video_status(dp, CONTROL_VIDEO_IDLE);
-   if (ret) {
-   DRM_DEV_ERROR(dp->dev, "Failed to idle video %d\n", ret);
-   goto out;
+   if (dp->use_fw_training == true) {

You don't need to compare to true. Simply do:

if (dp->use_fw_training)


+   ret = cdn_dp_set_video_status(dp, CONTROL_VIDEO_IDLE);
+   if (ret) {
+   DRM_DEV_ERROR(dp->dev,
+ "Failed to idle video %d\n", ret);
+   goto out;
+   }
  }

  ret = cdn_dp_config_video(dp);
@@ -642,11 +644,15 @@ static void cdn_dp_encoder_enable(struct
drm_encoder *encoder)
  goto out;
  }

-   ret = cdn_dp_set_video_status(dp, CONTROL_VIDEO_VALID);
-   if (ret) {
-   DRM_DEV_ERROR(dp->dev, "Failed to valid video %d\n",
ret);
-   goto out;
+   if (dp->use_fw_training == true) {

if (dp->use_fw_training)


+   ret = cdn_dp_set_video_status(dp, CONTROL_VIDEO_VALID);
+   if (ret) {
+   DRM_DEV_ERROR(dp->dev,
+   "Failed to valid video %d\n", ret);
+   goto out;
+   }
  }
+
   out:
  mutex_unlock(>lock);
   }
diff --git a/drivers/gpu/drm/rockchip/cdn-dp-core.h
b/drivers/gpu/drm/rockchip/cdn-dp-core.h
index 46159b2..77a9793 100644
--- a/drivers/gpu/drm/rockchip/cdn-dp-core.h
+++ b/drivers/gpu/drm/rockchip/cdn-dp-core.h
@@ -84,6 +84,7 @@ struct cdn_dp_device {
  bool connected;
  bool active;
  bool suspended;
+   bool use_fw_training;

  const struct firmware *fw;  /* cdn dp firmware */
  unsigned int fw_version;/* cdn fw version */
@@ -106,6 +107,7 @@ struct cdn_dp_device {
  u8 ports;
  u8 lanes;
  int active_port;
+   u8 train_set[4];

  u8 dpcd[DP_RECEIVER_CAP_SIZE];
  bool sink_ha

Re: [PATCH v6 5/5] drm/rockchip: support dp training outside dp firmware

2018-05-22 Thread hl

Hi Enric,


On Wednesday, May 23, 2018 01:06 AM, Enric Balletbo Serra wrote:

Lin,

2018-05-22 9:41 GMT+02:00 Enric Balletbo Serra :

Hi Lin

2018-05-22 3:08 GMT+02:00 hl :

Hi Enric,




On Monday, May 21, 2018 11:22 PM, Enric Balletbo Serra wrote:

Hi Lin,

2018-05-21 11:37 GMT+02:00 Lin Huang :

DP firmware uses fixed phy config values to do training, but some
boards need to adjust these values to fit for their unique hardware
design. So get phy config values from dts and use software link training
instead of relying on firmware, if software training fail, keep firmware
training as a fallback if sw training fails.

Signed-off-by: Chris Zhong 
Signed-off-by: Lin Huang 
Reviewed-by: Sean Paul 
---
Changes in v2:
- update patch following Enric suggest
Changes in v3:
- use variable fw_training instead sw_training_success
- base on DP SPCE, if training fail use lower link rate to retry training
Changes in v4:
- improve cdn_dp_get_lower_link_rate() and cdn_dp_software_train_link()
follow Sean suggest
Changes in v5:
- fix some whitespcae issue
Changes in v6:
- None

   drivers/gpu/drm/rockchip/Makefile   |   3 +-
   drivers/gpu/drm/rockchip/cdn-dp-core.c  |  24 +-
   drivers/gpu/drm/rockchip/cdn-dp-core.h  |   2 +
   drivers/gpu/drm/rockchip/cdn-dp-link-training.c | 420

   drivers/gpu/drm/rockchip/cdn-dp-reg.c   |  31 +-
   drivers/gpu/drm/rockchip/cdn-dp-reg.h   |  38 ++-
   6 files changed, 505 insertions(+), 13 deletions(-)
   create mode 100644 drivers/gpu/drm/rockchip/cdn-dp-link-training.c

diff --git a/drivers/gpu/drm/rockchip/Makefile
b/drivers/gpu/drm/rockchip/Makefile
index a314e21..b932f62 100644
--- a/drivers/gpu/drm/rockchip/Makefile
+++ b/drivers/gpu/drm/rockchip/Makefile
@@ -9,7 +9,8 @@ rockchipdrm-y := rockchip_drm_drv.o rockchip_drm_fb.o \
   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_CDN_DP) += cdn-dp-core.o cdn-dp-reg.o \
+   cdn-dp-link-training.o
   rockchipdrm-$(CONFIG_ROCKCHIP_DW_HDMI) += dw_hdmi-rockchip.o
   rockchipdrm-$(CONFIG_ROCKCHIP_DW_MIPI_DSI) += dw-mipi-dsi.o
   rockchipdrm-$(CONFIG_ROCKCHIP_INNO_HDMI) += inno_hdmi.o
diff --git a/drivers/gpu/drm/rockchip/cdn-dp-core.c
b/drivers/gpu/drm/rockchip/cdn-dp-core.c
index cce64c1..d9d0d4d 100644
--- a/drivers/gpu/drm/rockchip/cdn-dp-core.c
+++ b/drivers/gpu/drm/rockchip/cdn-dp-core.c
@@ -629,11 +629,13 @@ static void cdn_dp_encoder_enable(struct
drm_encoder *encoder)
  goto out;
  }
  }
-
-   ret = cdn_dp_set_video_status(dp, CONTROL_VIDEO_IDLE);
-   if (ret) {
-   DRM_DEV_ERROR(dp->dev, "Failed to idle video %d\n", ret);
-   goto out;
+   if (dp->use_fw_training == true) {

You don't need to compare to true. Simply do:

if (dp->use_fw_training)


+   ret = cdn_dp_set_video_status(dp, CONTROL_VIDEO_IDLE);
+   if (ret) {
+   DRM_DEV_ERROR(dp->dev,
+ "Failed to idle video %d\n", ret);
+   goto out;
+   }
  }

  ret = cdn_dp_config_video(dp);
@@ -642,11 +644,15 @@ static void cdn_dp_encoder_enable(struct
drm_encoder *encoder)
  goto out;
  }

-   ret = cdn_dp_set_video_status(dp, CONTROL_VIDEO_VALID);
-   if (ret) {
-   DRM_DEV_ERROR(dp->dev, "Failed to valid video %d\n",
ret);
-   goto out;
+   if (dp->use_fw_training == true) {

if (dp->use_fw_training)


+   ret = cdn_dp_set_video_status(dp, CONTROL_VIDEO_VALID);
+   if (ret) {
+   DRM_DEV_ERROR(dp->dev,
+   "Failed to valid video %d\n", ret);
+   goto out;
+   }
  }
+
   out:
  mutex_unlock(>lock);
   }
diff --git a/drivers/gpu/drm/rockchip/cdn-dp-core.h
b/drivers/gpu/drm/rockchip/cdn-dp-core.h
index 46159b2..77a9793 100644
--- a/drivers/gpu/drm/rockchip/cdn-dp-core.h
+++ b/drivers/gpu/drm/rockchip/cdn-dp-core.h
@@ -84,6 +84,7 @@ struct cdn_dp_device {
  bool connected;
  bool active;
  bool suspended;
+   bool use_fw_training;

  const struct firmware *fw;  /* cdn dp firmware */
  unsigned int fw_version;/* cdn fw version */
@@ -106,6 +107,7 @@ struct cdn_dp_device {
  u8 ports;
  u8 lanes;
  int active_port;
+   u8 train_set[4];

  u8 dpcd[DP_RECEIVER_CAP_SIZE];
  bool sink_has_audio;
diff --git a/drivers/gpu/drm/rockchip/cdn-dp-link-training.c
b/drivers/gpu/drm/rockchip/cdn-dp-link-training.c
new file mode 100644
index 000..73c3290

Re: [PATCH v6 5/5] drm/rockchip: support dp training outside dp firmware

2018-05-21 Thread hl

Hi Enric,



On Monday, May 21, 2018 11:22 PM, Enric Balletbo Serra wrote:

Hi Lin,

2018-05-21 11:37 GMT+02:00 Lin Huang :

DP firmware uses fixed phy config values to do training, but some
boards need to adjust these values to fit for their unique hardware
design. So get phy config values from dts and use software link training
instead of relying on firmware, if software training fail, keep firmware
training as a fallback if sw training fails.

Signed-off-by: Chris Zhong 
Signed-off-by: Lin Huang 
Reviewed-by: Sean Paul 
---
Changes in v2:
- update patch following Enric suggest
Changes in v3:
- use variable fw_training instead sw_training_success
- base on DP SPCE, if training fail use lower link rate to retry training
Changes in v4:
- improve cdn_dp_get_lower_link_rate() and cdn_dp_software_train_link() follow 
Sean suggest
Changes in v5:
- fix some whitespcae issue
Changes in v6:
- None

  drivers/gpu/drm/rockchip/Makefile   |   3 +-
  drivers/gpu/drm/rockchip/cdn-dp-core.c  |  24 +-
  drivers/gpu/drm/rockchip/cdn-dp-core.h  |   2 +
  drivers/gpu/drm/rockchip/cdn-dp-link-training.c | 420 
  drivers/gpu/drm/rockchip/cdn-dp-reg.c   |  31 +-
  drivers/gpu/drm/rockchip/cdn-dp-reg.h   |  38 ++-
  6 files changed, 505 insertions(+), 13 deletions(-)
  create mode 100644 drivers/gpu/drm/rockchip/cdn-dp-link-training.c

diff --git a/drivers/gpu/drm/rockchip/Makefile 
b/drivers/gpu/drm/rockchip/Makefile
index a314e21..b932f62 100644
--- a/drivers/gpu/drm/rockchip/Makefile
+++ b/drivers/gpu/drm/rockchip/Makefile
@@ -9,7 +9,8 @@ rockchipdrm-y := rockchip_drm_drv.o rockchip_drm_fb.o \
  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_CDN_DP) += cdn-dp-core.o cdn-dp-reg.o \
+   cdn-dp-link-training.o
  rockchipdrm-$(CONFIG_ROCKCHIP_DW_HDMI) += dw_hdmi-rockchip.o
  rockchipdrm-$(CONFIG_ROCKCHIP_DW_MIPI_DSI) += dw-mipi-dsi.o
  rockchipdrm-$(CONFIG_ROCKCHIP_INNO_HDMI) += inno_hdmi.o
diff --git a/drivers/gpu/drm/rockchip/cdn-dp-core.c 
b/drivers/gpu/drm/rockchip/cdn-dp-core.c
index cce64c1..d9d0d4d 100644
--- a/drivers/gpu/drm/rockchip/cdn-dp-core.c
+++ b/drivers/gpu/drm/rockchip/cdn-dp-core.c
@@ -629,11 +629,13 @@ static void cdn_dp_encoder_enable(struct drm_encoder 
*encoder)
 goto out;
 }
 }
-
-   ret = cdn_dp_set_video_status(dp, CONTROL_VIDEO_IDLE);
-   if (ret) {
-   DRM_DEV_ERROR(dp->dev, "Failed to idle video %d\n", ret);
-   goto out;
+   if (dp->use_fw_training == true) {

You don't need to compare to true. Simply do:

if (dp->use_fw_training)


+   ret = cdn_dp_set_video_status(dp, CONTROL_VIDEO_IDLE);
+   if (ret) {
+   DRM_DEV_ERROR(dp->dev,
+ "Failed to idle video %d\n", ret);
+   goto out;
+   }
 }

 ret = cdn_dp_config_video(dp);
@@ -642,11 +644,15 @@ static void cdn_dp_encoder_enable(struct drm_encoder 
*encoder)
 goto out;
 }

-   ret = cdn_dp_set_video_status(dp, CONTROL_VIDEO_VALID);
-   if (ret) {
-   DRM_DEV_ERROR(dp->dev, "Failed to valid video %d\n", ret);
-   goto out;
+   if (dp->use_fw_training == true) {

if (dp->use_fw_training)


+   ret = cdn_dp_set_video_status(dp, CONTROL_VIDEO_VALID);
+   if (ret) {
+   DRM_DEV_ERROR(dp->dev,
+   "Failed to valid video %d\n", ret);
+   goto out;
+   }
 }
+
  out:
 mutex_unlock(>lock);
  }
diff --git a/drivers/gpu/drm/rockchip/cdn-dp-core.h 
b/drivers/gpu/drm/rockchip/cdn-dp-core.h
index 46159b2..77a9793 100644
--- a/drivers/gpu/drm/rockchip/cdn-dp-core.h
+++ b/drivers/gpu/drm/rockchip/cdn-dp-core.h
@@ -84,6 +84,7 @@ struct cdn_dp_device {
 bool connected;
 bool active;
 bool suspended;
+   bool use_fw_training;

 const struct firmware *fw;  /* cdn dp firmware */
 unsigned int fw_version;/* cdn fw version */
@@ -106,6 +107,7 @@ struct cdn_dp_device {
 u8 ports;
 u8 lanes;
 int active_port;
+   u8 train_set[4];

 u8 dpcd[DP_RECEIVER_CAP_SIZE];
 bool sink_has_audio;
diff --git a/drivers/gpu/drm/rockchip/cdn-dp-link-training.c 
b/drivers/gpu/drm/rockchip/cdn-dp-link-training.c
new file mode 100644
index 000..73c3290
--- /dev/null
+++ b/drivers/gpu/drm/rockchip/cdn-dp-link-training.c
@@ -0,0 +1,420 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) Fuzhou Rockchip Electronics Co.Ltd
+ * 

Re: [PATCH v6 5/5] drm/rockchip: support dp training outside dp firmware

2018-05-21 Thread hl

Hi Enric,



On Monday, May 21, 2018 11:22 PM, Enric Balletbo Serra wrote:

Hi Lin,

2018-05-21 11:37 GMT+02:00 Lin Huang :

DP firmware uses fixed phy config values to do training, but some
boards need to adjust these values to fit for their unique hardware
design. So get phy config values from dts and use software link training
instead of relying on firmware, if software training fail, keep firmware
training as a fallback if sw training fails.

Signed-off-by: Chris Zhong 
Signed-off-by: Lin Huang 
Reviewed-by: Sean Paul 
---
Changes in v2:
- update patch following Enric suggest
Changes in v3:
- use variable fw_training instead sw_training_success
- base on DP SPCE, if training fail use lower link rate to retry training
Changes in v4:
- improve cdn_dp_get_lower_link_rate() and cdn_dp_software_train_link() follow 
Sean suggest
Changes in v5:
- fix some whitespcae issue
Changes in v6:
- None

  drivers/gpu/drm/rockchip/Makefile   |   3 +-
  drivers/gpu/drm/rockchip/cdn-dp-core.c  |  24 +-
  drivers/gpu/drm/rockchip/cdn-dp-core.h  |   2 +
  drivers/gpu/drm/rockchip/cdn-dp-link-training.c | 420 
  drivers/gpu/drm/rockchip/cdn-dp-reg.c   |  31 +-
  drivers/gpu/drm/rockchip/cdn-dp-reg.h   |  38 ++-
  6 files changed, 505 insertions(+), 13 deletions(-)
  create mode 100644 drivers/gpu/drm/rockchip/cdn-dp-link-training.c

diff --git a/drivers/gpu/drm/rockchip/Makefile 
b/drivers/gpu/drm/rockchip/Makefile
index a314e21..b932f62 100644
--- a/drivers/gpu/drm/rockchip/Makefile
+++ b/drivers/gpu/drm/rockchip/Makefile
@@ -9,7 +9,8 @@ rockchipdrm-y := rockchip_drm_drv.o rockchip_drm_fb.o \
  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_CDN_DP) += cdn-dp-core.o cdn-dp-reg.o \
+   cdn-dp-link-training.o
  rockchipdrm-$(CONFIG_ROCKCHIP_DW_HDMI) += dw_hdmi-rockchip.o
  rockchipdrm-$(CONFIG_ROCKCHIP_DW_MIPI_DSI) += dw-mipi-dsi.o
  rockchipdrm-$(CONFIG_ROCKCHIP_INNO_HDMI) += inno_hdmi.o
diff --git a/drivers/gpu/drm/rockchip/cdn-dp-core.c 
b/drivers/gpu/drm/rockchip/cdn-dp-core.c
index cce64c1..d9d0d4d 100644
--- a/drivers/gpu/drm/rockchip/cdn-dp-core.c
+++ b/drivers/gpu/drm/rockchip/cdn-dp-core.c
@@ -629,11 +629,13 @@ static void cdn_dp_encoder_enable(struct drm_encoder 
*encoder)
 goto out;
 }
 }
-
-   ret = cdn_dp_set_video_status(dp, CONTROL_VIDEO_IDLE);
-   if (ret) {
-   DRM_DEV_ERROR(dp->dev, "Failed to idle video %d\n", ret);
-   goto out;
+   if (dp->use_fw_training == true) {

You don't need to compare to true. Simply do:

if (dp->use_fw_training)


+   ret = cdn_dp_set_video_status(dp, CONTROL_VIDEO_IDLE);
+   if (ret) {
+   DRM_DEV_ERROR(dp->dev,
+ "Failed to idle video %d\n", ret);
+   goto out;
+   }
 }

 ret = cdn_dp_config_video(dp);
@@ -642,11 +644,15 @@ static void cdn_dp_encoder_enable(struct drm_encoder 
*encoder)
 goto out;
 }

-   ret = cdn_dp_set_video_status(dp, CONTROL_VIDEO_VALID);
-   if (ret) {
-   DRM_DEV_ERROR(dp->dev, "Failed to valid video %d\n", ret);
-   goto out;
+   if (dp->use_fw_training == true) {

if (dp->use_fw_training)


+   ret = cdn_dp_set_video_status(dp, CONTROL_VIDEO_VALID);
+   if (ret) {
+   DRM_DEV_ERROR(dp->dev,
+   "Failed to valid video %d\n", ret);
+   goto out;
+   }
 }
+
  out:
 mutex_unlock(>lock);
  }
diff --git a/drivers/gpu/drm/rockchip/cdn-dp-core.h 
b/drivers/gpu/drm/rockchip/cdn-dp-core.h
index 46159b2..77a9793 100644
--- a/drivers/gpu/drm/rockchip/cdn-dp-core.h
+++ b/drivers/gpu/drm/rockchip/cdn-dp-core.h
@@ -84,6 +84,7 @@ struct cdn_dp_device {
 bool connected;
 bool active;
 bool suspended;
+   bool use_fw_training;

 const struct firmware *fw;  /* cdn dp firmware */
 unsigned int fw_version;/* cdn fw version */
@@ -106,6 +107,7 @@ struct cdn_dp_device {
 u8 ports;
 u8 lanes;
 int active_port;
+   u8 train_set[4];

 u8 dpcd[DP_RECEIVER_CAP_SIZE];
 bool sink_has_audio;
diff --git a/drivers/gpu/drm/rockchip/cdn-dp-link-training.c 
b/drivers/gpu/drm/rockchip/cdn-dp-link-training.c
new file mode 100644
index 000..73c3290
--- /dev/null
+++ b/drivers/gpu/drm/rockchip/cdn-dp-link-training.c
@@ -0,0 +1,420 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) Fuzhou Rockchip Electronics Co.Ltd
+ * Author: Chris Zhong 
+ */
+
+#include 
+#include 
+#include 
+#include 
+
+#include 

Re: [PATCH v5 4/4] drm/rockchip: support dp training outside dp firmware

2018-05-17 Thread hl


+ Kishon

On Thursday, May 17, 2018 09:51 PM, Sean Paul wrote:

On Thu, May 17, 2018 at 05:18:00PM +0800, Lin Huang wrote:

DP firmware uses fixed phy config values to do training, but some
boards need to adjust these values to fit for their unique hardware
design. So get phy config values from dts and use software link training
instead of relying on firmware, if software training fail, keep firmware
training as a fallback if sw training fails.

Signed-off-by: Chris Zhong 
Signed-off-by: Lin Huang 
---
Changes in v2:
- update patch following Enric suggest
Changes in v3:
- use variable fw_training instead sw_training_success
- base on DP SPCE, if training fail use lower link rate to retry training
Changes in v4:
- improve cdn_dp_get_lower_link_rate() and cdn_dp_software_train_link() follow 
Sean suggest
Changes in v5:
- fix some whitespcae issue

  drivers/gpu/drm/rockchip/Makefile   |   3 +-
  drivers/gpu/drm/rockchip/cdn-dp-core.c  |  24 +-
  drivers/gpu/drm/rockchip/cdn-dp-core.h  |   2 +
  drivers/gpu/drm/rockchip/cdn-dp-link-training.c | 420 
  drivers/gpu/drm/rockchip/cdn-dp-reg.c   |  31 +-
  drivers/gpu/drm/rockchip/cdn-dp-reg.h   |  38 ++-
  6 files changed, 505 insertions(+), 13 deletions(-)
  create mode 100644 drivers/gpu/drm/rockchip/cdn-dp-link-training.c

diff --git a/drivers/gpu/drm/rockchip/Makefile 
b/drivers/gpu/drm/rockchip/Makefile
index a314e21..b932f62 100644
--- a/drivers/gpu/drm/rockchip/Makefile
+++ b/drivers/gpu/drm/rockchip/Makefile
@@ -9,7 +9,8 @@ rockchipdrm-y := rockchip_drm_drv.o rockchip_drm_fb.o \
  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_CDN_DP) += cdn-dp-core.o cdn-dp-reg.o \
+   cdn-dp-link-training.o
  rockchipdrm-$(CONFIG_ROCKCHIP_DW_HDMI) += dw_hdmi-rockchip.o
  rockchipdrm-$(CONFIG_ROCKCHIP_DW_MIPI_DSI) += dw-mipi-dsi.o
  rockchipdrm-$(CONFIG_ROCKCHIP_INNO_HDMI) += inno_hdmi.o
diff --git a/drivers/gpu/drm/rockchip/cdn-dp-core.c 
b/drivers/gpu/drm/rockchip/cdn-dp-core.c
index cce64c1..d9d0d4d 100644
--- a/drivers/gpu/drm/rockchip/cdn-dp-core.c
+++ b/drivers/gpu/drm/rockchip/cdn-dp-core.c
@@ -629,11 +629,13 @@ static void cdn_dp_encoder_enable(struct drm_encoder 
*encoder)
goto out;
}
}
-
-   ret = cdn_dp_set_video_status(dp, CONTROL_VIDEO_IDLE);
-   if (ret) {
-   DRM_DEV_ERROR(dp->dev, "Failed to idle video %d\n", ret);
-   goto out;
+   if (dp->use_fw_training == true) {
+   ret = cdn_dp_set_video_status(dp, CONTROL_VIDEO_IDLE);
+   if (ret) {
+   DRM_DEV_ERROR(dp->dev,
+ "Failed to idle video %d\n", ret);
+   goto out;
+   }
}
  
  	ret = cdn_dp_config_video(dp);

@@ -642,11 +644,15 @@ static void cdn_dp_encoder_enable(struct drm_encoder 
*encoder)
goto out;
}
  
-	ret = cdn_dp_set_video_status(dp, CONTROL_VIDEO_VALID);

-   if (ret) {
-   DRM_DEV_ERROR(dp->dev, "Failed to valid video %d\n", ret);
-   goto out;
+   if (dp->use_fw_training == true) {
+   ret = cdn_dp_set_video_status(dp, CONTROL_VIDEO_VALID);
+   if (ret) {
+   DRM_DEV_ERROR(dp->dev,
+   "Failed to valid video %d\n", ret);
+   goto out;
+   }
}
+
  out:
mutex_unlock(>lock);
  }
diff --git a/drivers/gpu/drm/rockchip/cdn-dp-core.h 
b/drivers/gpu/drm/rockchip/cdn-dp-core.h
index 46159b2..77a9793 100644
--- a/drivers/gpu/drm/rockchip/cdn-dp-core.h
+++ b/drivers/gpu/drm/rockchip/cdn-dp-core.h
@@ -84,6 +84,7 @@ struct cdn_dp_device {
bool connected;
bool active;
bool suspended;
+   bool use_fw_training;
  
  	const struct firmware *fw;	/* cdn dp firmware */

unsigned int fw_version;/* cdn fw version */
@@ -106,6 +107,7 @@ struct cdn_dp_device {
u8 ports;
u8 lanes;
int active_port;
+   u8 train_set[4];
  
  	u8 dpcd[DP_RECEIVER_CAP_SIZE];

bool sink_has_audio;
diff --git a/drivers/gpu/drm/rockchip/cdn-dp-link-training.c 
b/drivers/gpu/drm/rockchip/cdn-dp-link-training.c
new file mode 100644
index 000..73c3290
--- /dev/null
+++ b/drivers/gpu/drm/rockchip/cdn-dp-link-training.c
@@ -0,0 +1,420 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) Fuzhou Rockchip Electronics Co.Ltd
+ * Author: Chris Zhong 
+ */
+
+#include 
+#include 
+#include 
+#include 
+
+#include "cdn-dp-core.h"
+#include "cdn-dp-reg.h"
+
+static void cdn_dp_set_signal_levels(struct cdn_dp_device *dp)
+{
+   

Re: [PATCH v5 4/4] drm/rockchip: support dp training outside dp firmware

2018-05-17 Thread hl


+ Kishon

On Thursday, May 17, 2018 09:51 PM, Sean Paul wrote:

On Thu, May 17, 2018 at 05:18:00PM +0800, Lin Huang wrote:

DP firmware uses fixed phy config values to do training, but some
boards need to adjust these values to fit for their unique hardware
design. So get phy config values from dts and use software link training
instead of relying on firmware, if software training fail, keep firmware
training as a fallback if sw training fails.

Signed-off-by: Chris Zhong 
Signed-off-by: Lin Huang 
---
Changes in v2:
- update patch following Enric suggest
Changes in v3:
- use variable fw_training instead sw_training_success
- base on DP SPCE, if training fail use lower link rate to retry training
Changes in v4:
- improve cdn_dp_get_lower_link_rate() and cdn_dp_software_train_link() follow 
Sean suggest
Changes in v5:
- fix some whitespcae issue

  drivers/gpu/drm/rockchip/Makefile   |   3 +-
  drivers/gpu/drm/rockchip/cdn-dp-core.c  |  24 +-
  drivers/gpu/drm/rockchip/cdn-dp-core.h  |   2 +
  drivers/gpu/drm/rockchip/cdn-dp-link-training.c | 420 
  drivers/gpu/drm/rockchip/cdn-dp-reg.c   |  31 +-
  drivers/gpu/drm/rockchip/cdn-dp-reg.h   |  38 ++-
  6 files changed, 505 insertions(+), 13 deletions(-)
  create mode 100644 drivers/gpu/drm/rockchip/cdn-dp-link-training.c

diff --git a/drivers/gpu/drm/rockchip/Makefile 
b/drivers/gpu/drm/rockchip/Makefile
index a314e21..b932f62 100644
--- a/drivers/gpu/drm/rockchip/Makefile
+++ b/drivers/gpu/drm/rockchip/Makefile
@@ -9,7 +9,8 @@ rockchipdrm-y := rockchip_drm_drv.o rockchip_drm_fb.o \
  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_CDN_DP) += cdn-dp-core.o cdn-dp-reg.o \
+   cdn-dp-link-training.o
  rockchipdrm-$(CONFIG_ROCKCHIP_DW_HDMI) += dw_hdmi-rockchip.o
  rockchipdrm-$(CONFIG_ROCKCHIP_DW_MIPI_DSI) += dw-mipi-dsi.o
  rockchipdrm-$(CONFIG_ROCKCHIP_INNO_HDMI) += inno_hdmi.o
diff --git a/drivers/gpu/drm/rockchip/cdn-dp-core.c 
b/drivers/gpu/drm/rockchip/cdn-dp-core.c
index cce64c1..d9d0d4d 100644
--- a/drivers/gpu/drm/rockchip/cdn-dp-core.c
+++ b/drivers/gpu/drm/rockchip/cdn-dp-core.c
@@ -629,11 +629,13 @@ static void cdn_dp_encoder_enable(struct drm_encoder 
*encoder)
goto out;
}
}
-
-   ret = cdn_dp_set_video_status(dp, CONTROL_VIDEO_IDLE);
-   if (ret) {
-   DRM_DEV_ERROR(dp->dev, "Failed to idle video %d\n", ret);
-   goto out;
+   if (dp->use_fw_training == true) {
+   ret = cdn_dp_set_video_status(dp, CONTROL_VIDEO_IDLE);
+   if (ret) {
+   DRM_DEV_ERROR(dp->dev,
+ "Failed to idle video %d\n", ret);
+   goto out;
+   }
}
  
  	ret = cdn_dp_config_video(dp);

@@ -642,11 +644,15 @@ static void cdn_dp_encoder_enable(struct drm_encoder 
*encoder)
goto out;
}
  
-	ret = cdn_dp_set_video_status(dp, CONTROL_VIDEO_VALID);

-   if (ret) {
-   DRM_DEV_ERROR(dp->dev, "Failed to valid video %d\n", ret);
-   goto out;
+   if (dp->use_fw_training == true) {
+   ret = cdn_dp_set_video_status(dp, CONTROL_VIDEO_VALID);
+   if (ret) {
+   DRM_DEV_ERROR(dp->dev,
+   "Failed to valid video %d\n", ret);
+   goto out;
+   }
}
+
  out:
mutex_unlock(>lock);
  }
diff --git a/drivers/gpu/drm/rockchip/cdn-dp-core.h 
b/drivers/gpu/drm/rockchip/cdn-dp-core.h
index 46159b2..77a9793 100644
--- a/drivers/gpu/drm/rockchip/cdn-dp-core.h
+++ b/drivers/gpu/drm/rockchip/cdn-dp-core.h
@@ -84,6 +84,7 @@ struct cdn_dp_device {
bool connected;
bool active;
bool suspended;
+   bool use_fw_training;
  
  	const struct firmware *fw;	/* cdn dp firmware */

unsigned int fw_version;/* cdn fw version */
@@ -106,6 +107,7 @@ struct cdn_dp_device {
u8 ports;
u8 lanes;
int active_port;
+   u8 train_set[4];
  
  	u8 dpcd[DP_RECEIVER_CAP_SIZE];

bool sink_has_audio;
diff --git a/drivers/gpu/drm/rockchip/cdn-dp-link-training.c 
b/drivers/gpu/drm/rockchip/cdn-dp-link-training.c
new file mode 100644
index 000..73c3290
--- /dev/null
+++ b/drivers/gpu/drm/rockchip/cdn-dp-link-training.c
@@ -0,0 +1,420 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) Fuzhou Rockchip Electronics Co.Ltd
+ * Author: Chris Zhong 
+ */
+
+#include 
+#include 
+#include 
+#include 
+
+#include "cdn-dp-core.h"
+#include "cdn-dp-reg.h"
+
+static void cdn_dp_set_signal_levels(struct cdn_dp_device *dp)
+{
+   struct cdn_dp_port *port = dp->port[dp->active_port];
+   

Re: [PATCH 4/4] drm/rockchip: support dp training outside dp firmware

2018-05-09 Thread hl



On Monday, May 07, 2018 07:29 PM, Enric Balletbo Serra wrote:

Hi Lin,

Thanks for the patch.

2018-05-04 10:08 GMT+02:00 Lin Huang :

DP firware use fix phy config value to do training, but some

s/fiware/firmware/


board need to adjust these value to fit for their hardware design,
so we use new phy config to do training outside firmware to meet
this situation, if there have new phy config pass from dts, it will
use training outside firmware.


maybe you can rewrite all this in a better way.

ooi, which boards needs this?



Signed-off-by: Chris Zhong 
Signed-off-by: Lin Huang 
---
  drivers/gpu/drm/rockchip/Makefile   |   3 +-
  drivers/gpu/drm/rockchip/cdn-dp-core.c  |  23 +-
  drivers/gpu/drm/rockchip/cdn-dp-core.h  |   2 +
  drivers/gpu/drm/rockchip/cdn-dp-link-training.c | 398 
  drivers/gpu/drm/rockchip/cdn-dp-reg.c   |  33 +-
  drivers/gpu/drm/rockchip/cdn-dp-reg.h   |  38 ++-
  6 files changed, 480 insertions(+), 17 deletions(-)
  create mode 100644 drivers/gpu/drm/rockchip/cdn-dp-link-training.c

diff --git a/drivers/gpu/drm/rockchip/Makefile 
b/drivers/gpu/drm/rockchip/Makefile
index a314e21..b932f62 100644
--- a/drivers/gpu/drm/rockchip/Makefile
+++ b/drivers/gpu/drm/rockchip/Makefile
@@ -9,7 +9,8 @@ rockchipdrm-y := rockchip_drm_drv.o rockchip_drm_fb.o \
  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_CDN_DP) += cdn-dp-core.o cdn-dp-reg.o \
+   cdn-dp-link-training.o
  rockchipdrm-$(CONFIG_ROCKCHIP_DW_HDMI) += dw_hdmi-rockchip.o
  rockchipdrm-$(CONFIG_ROCKCHIP_DW_MIPI_DSI) += dw-mipi-dsi.o
  rockchipdrm-$(CONFIG_ROCKCHIP_INNO_HDMI) += inno_hdmi.o
diff --git a/drivers/gpu/drm/rockchip/cdn-dp-core.c 
b/drivers/gpu/drm/rockchip/cdn-dp-core.c
index 268c190..a2a4208 100644
--- a/drivers/gpu/drm/rockchip/cdn-dp-core.c
+++ b/drivers/gpu/drm/rockchip/cdn-dp-core.c
@@ -629,11 +629,13 @@ static void cdn_dp_encoder_enable(struct drm_encoder 
*encoder)
 goto out;
 }
 }
-
-   ret = cdn_dp_set_video_status(dp, CONTROL_VIDEO_IDLE);
-   if (ret) {
-   DRM_DEV_ERROR(dp->dev, "Failed to idle video %d\n", ret);
-   goto out;
+   if (dp->sw_training_success == false) {
+   ret = cdn_dp_set_video_status(dp, CONTROL_VIDEO_IDLE);
+   if (ret) {
+   DRM_DEV_ERROR(dp->dev,
+ "Failed to idle video %d\n", ret);
+   goto out;
+   }
 }

 ret = cdn_dp_config_video(dp);
@@ -642,11 +644,14 @@ static void cdn_dp_encoder_enable(struct drm_encoder 
*encoder)
 goto out;
 }

-   ret = cdn_dp_set_video_status(dp, CONTROL_VIDEO_VALID);
-   if (ret) {
-   DRM_DEV_ERROR(dp->dev, "Failed to valid video %d\n", ret);
-   goto out;
+   if (dp->sw_training_success == false) {
+   ret = cdn_dp_set_video_status(dp, CONTROL_VIDEO_VALID);
+   if (ret) {
+   DRM_DEV_ERROR(dp->dev, "Failed to valid video %d\n", 
ret);
+   goto out;
+   }
 }
+
  out:
 mutex_unlock(>lock);
  }
diff --git a/drivers/gpu/drm/rockchip/cdn-dp-core.h 
b/drivers/gpu/drm/rockchip/cdn-dp-core.h
index 46159b2..c6050ab 100644
--- a/drivers/gpu/drm/rockchip/cdn-dp-core.h
+++ b/drivers/gpu/drm/rockchip/cdn-dp-core.h
@@ -84,6 +84,7 @@ struct cdn_dp_device {
 bool connected;
 bool active;
 bool suspended;
+   bool sw_training_success;

 const struct firmware *fw;  /* cdn dp firmware */
 unsigned int fw_version;/* cdn fw version */
@@ -106,6 +107,7 @@ struct cdn_dp_device {
 u8 ports;
 u8 lanes;
 int active_port;
+   u8 train_set[4];

 u8 dpcd[DP_RECEIVER_CAP_SIZE];
 bool sink_has_audio;
diff --git a/drivers/gpu/drm/rockchip/cdn-dp-link-training.c 
b/drivers/gpu/drm/rockchip/cdn-dp-link-training.c
new file mode 100644
index 000..558c945
--- /dev/null
+++ b/drivers/gpu/drm/rockchip/cdn-dp-link-training.c
@@ -0,0 +1,398 @@
+/* SPDX-License-Identifier: GPL-2.0 */

For a C source file the format is:
(https://www.kernel.org/doc/html/latest/process/license-rules.html)

// SPDX-License-Identifier: 

Thanks for pointing it, will fix it.

+/*
+ * Copyright (C) Fuzhou Rockchip Electronics Co.Ltd
+ * Author: Chris Zhong 
+ */
+
+#include 

Why you need this include?


+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+

In fact, I think that there are other includes that can be removed,
please review.


+#include 

Re: [PATCH 4/4] drm/rockchip: support dp training outside dp firmware

2018-05-09 Thread hl



On Monday, May 07, 2018 07:29 PM, Enric Balletbo Serra wrote:

Hi Lin,

Thanks for the patch.

2018-05-04 10:08 GMT+02:00 Lin Huang :

DP firware use fix phy config value to do training, but some

s/fiware/firmware/


board need to adjust these value to fit for their hardware design,
so we use new phy config to do training outside firmware to meet
this situation, if there have new phy config pass from dts, it will
use training outside firmware.


maybe you can rewrite all this in a better way.

ooi, which boards needs this?



Signed-off-by: Chris Zhong 
Signed-off-by: Lin Huang 
---
  drivers/gpu/drm/rockchip/Makefile   |   3 +-
  drivers/gpu/drm/rockchip/cdn-dp-core.c  |  23 +-
  drivers/gpu/drm/rockchip/cdn-dp-core.h  |   2 +
  drivers/gpu/drm/rockchip/cdn-dp-link-training.c | 398 
  drivers/gpu/drm/rockchip/cdn-dp-reg.c   |  33 +-
  drivers/gpu/drm/rockchip/cdn-dp-reg.h   |  38 ++-
  6 files changed, 480 insertions(+), 17 deletions(-)
  create mode 100644 drivers/gpu/drm/rockchip/cdn-dp-link-training.c

diff --git a/drivers/gpu/drm/rockchip/Makefile 
b/drivers/gpu/drm/rockchip/Makefile
index a314e21..b932f62 100644
--- a/drivers/gpu/drm/rockchip/Makefile
+++ b/drivers/gpu/drm/rockchip/Makefile
@@ -9,7 +9,8 @@ rockchipdrm-y := rockchip_drm_drv.o rockchip_drm_fb.o \
  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_CDN_DP) += cdn-dp-core.o cdn-dp-reg.o \
+   cdn-dp-link-training.o
  rockchipdrm-$(CONFIG_ROCKCHIP_DW_HDMI) += dw_hdmi-rockchip.o
  rockchipdrm-$(CONFIG_ROCKCHIP_DW_MIPI_DSI) += dw-mipi-dsi.o
  rockchipdrm-$(CONFIG_ROCKCHIP_INNO_HDMI) += inno_hdmi.o
diff --git a/drivers/gpu/drm/rockchip/cdn-dp-core.c 
b/drivers/gpu/drm/rockchip/cdn-dp-core.c
index 268c190..a2a4208 100644
--- a/drivers/gpu/drm/rockchip/cdn-dp-core.c
+++ b/drivers/gpu/drm/rockchip/cdn-dp-core.c
@@ -629,11 +629,13 @@ static void cdn_dp_encoder_enable(struct drm_encoder 
*encoder)
 goto out;
 }
 }
-
-   ret = cdn_dp_set_video_status(dp, CONTROL_VIDEO_IDLE);
-   if (ret) {
-   DRM_DEV_ERROR(dp->dev, "Failed to idle video %d\n", ret);
-   goto out;
+   if (dp->sw_training_success == false) {
+   ret = cdn_dp_set_video_status(dp, CONTROL_VIDEO_IDLE);
+   if (ret) {
+   DRM_DEV_ERROR(dp->dev,
+ "Failed to idle video %d\n", ret);
+   goto out;
+   }
 }

 ret = cdn_dp_config_video(dp);
@@ -642,11 +644,14 @@ static void cdn_dp_encoder_enable(struct drm_encoder 
*encoder)
 goto out;
 }

-   ret = cdn_dp_set_video_status(dp, CONTROL_VIDEO_VALID);
-   if (ret) {
-   DRM_DEV_ERROR(dp->dev, "Failed to valid video %d\n", ret);
-   goto out;
+   if (dp->sw_training_success == false) {
+   ret = cdn_dp_set_video_status(dp, CONTROL_VIDEO_VALID);
+   if (ret) {
+   DRM_DEV_ERROR(dp->dev, "Failed to valid video %d\n", 
ret);
+   goto out;
+   }
 }
+
  out:
 mutex_unlock(>lock);
  }
diff --git a/drivers/gpu/drm/rockchip/cdn-dp-core.h 
b/drivers/gpu/drm/rockchip/cdn-dp-core.h
index 46159b2..c6050ab 100644
--- a/drivers/gpu/drm/rockchip/cdn-dp-core.h
+++ b/drivers/gpu/drm/rockchip/cdn-dp-core.h
@@ -84,6 +84,7 @@ struct cdn_dp_device {
 bool connected;
 bool active;
 bool suspended;
+   bool sw_training_success;

 const struct firmware *fw;  /* cdn dp firmware */
 unsigned int fw_version;/* cdn fw version */
@@ -106,6 +107,7 @@ struct cdn_dp_device {
 u8 ports;
 u8 lanes;
 int active_port;
+   u8 train_set[4];

 u8 dpcd[DP_RECEIVER_CAP_SIZE];
 bool sink_has_audio;
diff --git a/drivers/gpu/drm/rockchip/cdn-dp-link-training.c 
b/drivers/gpu/drm/rockchip/cdn-dp-link-training.c
new file mode 100644
index 000..558c945
--- /dev/null
+++ b/drivers/gpu/drm/rockchip/cdn-dp-link-training.c
@@ -0,0 +1,398 @@
+/* SPDX-License-Identifier: GPL-2.0 */

For a C source file the format is:
(https://www.kernel.org/doc/html/latest/process/license-rules.html)

// SPDX-License-Identifier: 

Thanks for pointing it, will fix it.

+/*
+ * Copyright (C) Fuzhou Rockchip Electronics Co.Ltd
+ * Author: Chris Zhong 
+ */
+
+#include 

Why you need this include?


+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+

In fact, I think that there are other includes that can be removed,
please review.


+#include "cdn-dp-core.h"
+#include "cdn-dp-reg.h"
+
+static void 

Re: [PATCH 2/4] phy: rockchip-typec: support variable phy config value

2018-05-08 Thread hl



On Monday, May 07, 2018 09:59 PM, Enric Balletbo Serra wrote:

Hi Lin,

Thanks for the patch, apart from the new build warnings introduced
some more comments below.

2018-05-04 10:08 GMT+02:00 Lin Huang :

the phy config values used to fix in dp firmware, but some boards
need change these values to do training and get the better eye diagram
result. So support that in phy driver.

Signed-off-by: Chris Zhong 
Signed-off-by: Lin Huang 
---
  drivers/phy/rockchip/phy-rockchip-typec.c | 286 +++---
  include/soc/rockchip/rockchip_phy_typec.h |  72 
  2 files changed, 259 insertions(+), 99 deletions(-)
  create mode 100644 include/soc/rockchip/rockchip_phy_typec.h

diff --git a/drivers/phy/rockchip/phy-rockchip-typec.c 
b/drivers/phy/rockchip/phy-rockchip-typec.c
index 76a4b58..831a93b 100644
--- a/drivers/phy/rockchip/phy-rockchip-typec.c
+++ b/drivers/phy/rockchip/phy-rockchip-typec.c
@@ -63,6 +63,7 @@

  #include 
  #include 
+#include 

  #define CMN_SSM_BANDGAP(0x21 << 2)
  #define CMN_SSM_BIAS   (0x22 << 2)
@@ -323,23 +324,31 @@
   * clock 0: PLL 0 div 1
   * clock 1: PLL 1 div 2
   */
-#define CLK_PLL_CONFIG 0X30
+#define CLK_PLL1_DIV1  0x20
+#define CLK_PLL1_DIV2  0x30
  #define CLK_PLL_MASK   0x33

  #define CMN_READY  BIT(0)

+#define DP_PLL_CLOCK_ENABLE_ACKBIT(3)
  #define DP_PLL_CLOCK_ENABLEBIT(2)
+#define DP_PLL_ENABLE_ACK  BIT(1)
  #define DP_PLL_ENABLE  BIT(0)
  #define DP_PLL_DATA_RATE_RBR   ((2 << 12) | (4 << 8))
  #define DP_PLL_DATA_RATE_HBR   ((2 << 12) | (4 << 8))
  #define DP_PLL_DATA_RATE_HBR2  ((1 << 12) | (2 << 8))
+#define DP_PLL_DATA_RATE_MASK  0xff00

-#define DP_MODE_A0 BIT(4)
-#define DP_MODE_A2 BIT(6)
-#define DP_MODE_ENTER_A0   0xc101
-#define DP_MODE_ENTER_A2   0xc104
+#define DP_MODE_MASK   0xf
+#define DP_MODE_ENTER_A0   BIT(0)
+#define DP_MODE_ENTER_A2   BIT(2)
+#define DP_MODE_ENTER_A3   BIT(3)
+#define DP_MODE_A0_ACK BIT(4)
+#define DP_MODE_A2_ACK BIT(6)
+#define DP_MODE_A3_ACK BIT(7)
+#define DP_LINK_RESET_DEASSERTED   BIT(8)

-#define PHY_MODE_SET_TIMEOUT   10
+#define PHY_MODE_SET_TIMEOUT   100


Why do you need to increase this timeout? Is because the software link
training timed out using the old value?

That for debug, will fix it in next version.




  #define PIN_ASSIGN_C_E 0x51d9
  #define PIN_ASSIGN_D_F 0x5100
@@ -349,51 +358,7 @@
  #define MODE_DFP_USB   BIT(1)
  #define MODE_DFP_DPBIT(2)

-struct usb3phy_reg {
-   u32 offset;
-   u32 enable_bit;
-   u32 write_enable;
-};
-
-/**
- * struct rockchip_usb3phy_port_cfg: usb3-phy port configuration.
- * @reg: the base address for usb3-phy config.
- * @typec_conn_dir: the register of type-c connector direction.
- * @usb3tousb2_en: the register of type-c force usb2 to usb2 enable.
- * @external_psm: the register of type-c phy external psm clock.
- * @pipe_status: the register of type-c phy pipe status.
- * @usb3_host_disable: the register of type-c usb3 host disable.
- * @usb3_host_port: the register of type-c usb3 host port.
- * @uphy_dp_sel: the register of type-c phy DP select control.
- */
-struct rockchip_usb3phy_port_cfg {
-   unsigned int reg;
-   struct usb3phy_reg typec_conn_dir;
-   struct usb3phy_reg usb3tousb2_en;
-   struct usb3phy_reg external_psm;
-   struct usb3phy_reg pipe_status;
-   struct usb3phy_reg usb3_host_disable;
-   struct usb3phy_reg usb3_host_port;
-   struct usb3phy_reg uphy_dp_sel;
-};
-
-struct rockchip_typec_phy {
-   struct device *dev;
-   void __iomem *base;
-   struct extcon_dev *extcon;
-   struct regmap *grf_regs;
-   struct clk *clk_core;
-   struct clk *clk_ref;
-   struct reset_control *uphy_rst;
-   struct reset_control *pipe_rst;
-   struct reset_control *tcphy_rst;
-   const struct rockchip_usb3phy_port_cfg *port_cfgs;
-   /* mutex to protect access to individual PHYs */
-   struct mutex lock;
-
-   bool flip;
-   u8 mode;
-};
+#define DEFAULT_RATE   162000


DEFAULT_RATE seems a very common name for me, maybe add a prefix?

Okay, will fix it.




  struct phy_reg {
 u16 value;
@@ -417,15 +382,15 @@ struct phy_reg usb3_pll_cfg[] = {
 { 0x8,  CMN_DIAG_PLL0_LF_PROG },
  };

-struct phy_reg dp_pll_cfg[] = {
+struct phy_reg dp_pll_rbr_cfg[] = {
 { 0xf0, CMN_PLL1_VCOCAL_INIT },
 { 0x18, CMN_PLL1_VCOCAL_ITER },
 { 0x30b9,   

Re: [PATCH 2/4] phy: rockchip-typec: support variable phy config value

2018-05-08 Thread hl



On Monday, May 07, 2018 09:59 PM, Enric Balletbo Serra wrote:

Hi Lin,

Thanks for the patch, apart from the new build warnings introduced
some more comments below.

2018-05-04 10:08 GMT+02:00 Lin Huang :

the phy config values used to fix in dp firmware, but some boards
need change these values to do training and get the better eye diagram
result. So support that in phy driver.

Signed-off-by: Chris Zhong 
Signed-off-by: Lin Huang 
---
  drivers/phy/rockchip/phy-rockchip-typec.c | 286 +++---
  include/soc/rockchip/rockchip_phy_typec.h |  72 
  2 files changed, 259 insertions(+), 99 deletions(-)
  create mode 100644 include/soc/rockchip/rockchip_phy_typec.h

diff --git a/drivers/phy/rockchip/phy-rockchip-typec.c 
b/drivers/phy/rockchip/phy-rockchip-typec.c
index 76a4b58..831a93b 100644
--- a/drivers/phy/rockchip/phy-rockchip-typec.c
+++ b/drivers/phy/rockchip/phy-rockchip-typec.c
@@ -63,6 +63,7 @@

  #include 
  #include 
+#include 

  #define CMN_SSM_BANDGAP(0x21 << 2)
  #define CMN_SSM_BIAS   (0x22 << 2)
@@ -323,23 +324,31 @@
   * clock 0: PLL 0 div 1
   * clock 1: PLL 1 div 2
   */
-#define CLK_PLL_CONFIG 0X30
+#define CLK_PLL1_DIV1  0x20
+#define CLK_PLL1_DIV2  0x30
  #define CLK_PLL_MASK   0x33

  #define CMN_READY  BIT(0)

+#define DP_PLL_CLOCK_ENABLE_ACKBIT(3)
  #define DP_PLL_CLOCK_ENABLEBIT(2)
+#define DP_PLL_ENABLE_ACK  BIT(1)
  #define DP_PLL_ENABLE  BIT(0)
  #define DP_PLL_DATA_RATE_RBR   ((2 << 12) | (4 << 8))
  #define DP_PLL_DATA_RATE_HBR   ((2 << 12) | (4 << 8))
  #define DP_PLL_DATA_RATE_HBR2  ((1 << 12) | (2 << 8))
+#define DP_PLL_DATA_RATE_MASK  0xff00

-#define DP_MODE_A0 BIT(4)
-#define DP_MODE_A2 BIT(6)
-#define DP_MODE_ENTER_A0   0xc101
-#define DP_MODE_ENTER_A2   0xc104
+#define DP_MODE_MASK   0xf
+#define DP_MODE_ENTER_A0   BIT(0)
+#define DP_MODE_ENTER_A2   BIT(2)
+#define DP_MODE_ENTER_A3   BIT(3)
+#define DP_MODE_A0_ACK BIT(4)
+#define DP_MODE_A2_ACK BIT(6)
+#define DP_MODE_A3_ACK BIT(7)
+#define DP_LINK_RESET_DEASSERTED   BIT(8)

-#define PHY_MODE_SET_TIMEOUT   10
+#define PHY_MODE_SET_TIMEOUT   100


Why do you need to increase this timeout? Is because the software link
training timed out using the old value?

That for debug, will fix it in next version.




  #define PIN_ASSIGN_C_E 0x51d9
  #define PIN_ASSIGN_D_F 0x5100
@@ -349,51 +358,7 @@
  #define MODE_DFP_USB   BIT(1)
  #define MODE_DFP_DPBIT(2)

-struct usb3phy_reg {
-   u32 offset;
-   u32 enable_bit;
-   u32 write_enable;
-};
-
-/**
- * struct rockchip_usb3phy_port_cfg: usb3-phy port configuration.
- * @reg: the base address for usb3-phy config.
- * @typec_conn_dir: the register of type-c connector direction.
- * @usb3tousb2_en: the register of type-c force usb2 to usb2 enable.
- * @external_psm: the register of type-c phy external psm clock.
- * @pipe_status: the register of type-c phy pipe status.
- * @usb3_host_disable: the register of type-c usb3 host disable.
- * @usb3_host_port: the register of type-c usb3 host port.
- * @uphy_dp_sel: the register of type-c phy DP select control.
- */
-struct rockchip_usb3phy_port_cfg {
-   unsigned int reg;
-   struct usb3phy_reg typec_conn_dir;
-   struct usb3phy_reg usb3tousb2_en;
-   struct usb3phy_reg external_psm;
-   struct usb3phy_reg pipe_status;
-   struct usb3phy_reg usb3_host_disable;
-   struct usb3phy_reg usb3_host_port;
-   struct usb3phy_reg uphy_dp_sel;
-};
-
-struct rockchip_typec_phy {
-   struct device *dev;
-   void __iomem *base;
-   struct extcon_dev *extcon;
-   struct regmap *grf_regs;
-   struct clk *clk_core;
-   struct clk *clk_ref;
-   struct reset_control *uphy_rst;
-   struct reset_control *pipe_rst;
-   struct reset_control *tcphy_rst;
-   const struct rockchip_usb3phy_port_cfg *port_cfgs;
-   /* mutex to protect access to individual PHYs */
-   struct mutex lock;
-
-   bool flip;
-   u8 mode;
-};
+#define DEFAULT_RATE   162000


DEFAULT_RATE seems a very common name for me, maybe add a prefix?

Okay, will fix it.




  struct phy_reg {
 u16 value;
@@ -417,15 +382,15 @@ struct phy_reg usb3_pll_cfg[] = {
 { 0x8,  CMN_DIAG_PLL0_LF_PROG },
  };

-struct phy_reg dp_pll_cfg[] = {
+struct phy_reg dp_pll_rbr_cfg[] = {
 { 0xf0, CMN_PLL1_VCOCAL_INIT },
 { 0x18, CMN_PLL1_VCOCAL_ITER },
 { 0x30b9,   CMN_PLL1_VCOCAL_START },
-   { 0x21c,CMN_PLL1_INTDIV },
+   { 

Re: [PATCH 1/4] drm/rockchip: add transfer function for cdn-dp

2018-05-08 Thread hl

Hi Enric,


On Monday, May 07, 2018 07:27 PM, Enric Balletbo Serra wrote:

Hi Lin,

I am interested in these patches, could you cc me on newer versions? Thanks.

Some comments below.

Sure, will cc to you next version.


2018-05-04 10:08 GMT+02:00 Lin Huang :

From: Chris Zhong 

We may support training outside firmware, so we need support
dpcd read/write to get the message or do some setting with
display.

Signed-off-by: Chris Zhong 
Signed-off-by: Lin Huang 
---
  drivers/gpu/drm/rockchip/cdn-dp-core.c | 55 
  drivers/gpu/drm/rockchip/cdn-dp-core.h |  1 +
  drivers/gpu/drm/rockchip/cdn-dp-reg.c  | 66 +-
  drivers/gpu/drm/rockchip/cdn-dp-reg.h  | 14 ++--
  4 files changed, 119 insertions(+), 17 deletions(-)


In general, for this patch and all the other patches in the series I
saw that checkpatch spits out some warnings, could you fix these and
ideally run checkpatch with the --strict --subjective option?

Okay.



diff --git a/drivers/gpu/drm/rockchip/cdn-dp-core.c 
b/drivers/gpu/drm/rockchip/cdn-dp-core.c
index c6fbdcd..268c190 100644
--- a/drivers/gpu/drm/rockchip/cdn-dp-core.c
+++ b/drivers/gpu/drm/rockchip/cdn-dp-core.c
@@ -176,8 +176,8 @@ static int cdn_dp_get_sink_count(struct cdn_dp_device *dp, 
u8 *sink_count)
 u8 value;

 *sink_count = 0;
-   ret = cdn_dp_dpcd_read(dp, DP_SINK_COUNT, , 1);
-   if (ret)
+   ret = drm_dp_dpcd_read(>aux, DP_SINK_COUNT, , 1);
+   if (ret < 0)
 return ret;

 *sink_count = DP_GET_SINK_COUNT(value);
@@ -374,9 +374,9 @@ static int cdn_dp_get_sink_capability(struct cdn_dp_device 
*dp)
 if (!cdn_dp_check_sink_connection(dp))
 return -ENODEV;

-   ret = cdn_dp_dpcd_read(dp, DP_DPCD_REV, dp->dpcd,
-  DP_RECEIVER_CAP_SIZE);
-   if (ret) {
+   ret = drm_dp_dpcd_read(>aux, DP_DPCD_REV, dp->dpcd,
+  sizeof(dp->dpcd));
+   if (ret < 0) {
 DRM_DEV_ERROR(dp->dev, "Failed to get caps %d\n", ret);
 return ret;
 }
@@ -582,8 +582,8 @@ static bool cdn_dp_check_link_status(struct cdn_dp_device 
*dp)
 if (!port || !dp->link.rate || !dp->link.num_lanes)
 return false;

-   if (cdn_dp_dpcd_read(dp, DP_LANE0_1_STATUS, link_status,
-DP_LINK_STATUS_SIZE)) {
+   if (drm_dp_dpcd_read_link_status(>aux, link_status) !=
+   DP_LINK_STATUS_SIZE) {
 DRM_ERROR("Failed to get link status\n");
 return false;
 }
@@ -1012,6 +1012,40 @@ static int cdn_dp_pd_event(struct notifier_block *nb,
 return NOTIFY_DONE;
  }

+static ssize_t cdn_dp_aux_transfer(struct drm_dp_aux *aux,
+  struct drm_dp_aux_msg *msg)
+{
+   struct cdn_dp_device *dp = container_of(aux, struct cdn_dp_device, aux);
+   int ret;
+   u8 status;
+
+   switch (msg->request & ~DP_AUX_I2C_MOT) {
+   case DP_AUX_NATIVE_WRITE:
+   case DP_AUX_I2C_WRITE:
+   case DP_AUX_I2C_WRITE_STATUS_UPDATE:
+   ret = cdn_dp_dpcd_write(dp, msg->address, msg->buffer,
+   msg->size);
+   break;
+   case DP_AUX_NATIVE_READ:
+   case DP_AUX_I2C_READ:
+   ret = cdn_dp_dpcd_read(dp, msg->address, msg->buffer,
+  msg->size);
+   break;
+   default:
+   return -EINVAL;
+   }
+
+   status = cdn_dp_get_aux_status(dp);
+   if (status == AUX_STAUS_ACK)
+   msg->reply = DP_AUX_NATIVE_REPLY_ACK;
+   else if (status == AUX_STAUS_NACK)
+   msg->reply = DP_AUX_NATIVE_REPLY_NACK;
+   else if (status == AUX_STAUS_DEFER)
+   msg->reply = DP_AUX_NATIVE_REPLY_DEFER;
+

I think that you would mean STATUS instead of STAUS on these defines.

What happens if the status is AUX_STATUS_SINK_ERROR or AUX_STATUS_BUS_ERROR?

drm_dp_i2c_do_msg() will mark it as invalid i2c relay and return error.



+   return ret;
+}
+
  static int cdn_dp_bind(struct device *dev, struct device *master, void *data)
  {
 struct cdn_dp_device *dp = dev_get_drvdata(dev);
@@ -1030,6 +1064,13 @@ static int cdn_dp_bind(struct device *dev, struct device 
*master, void *data)
 dp->active = false;
 dp->active_port = -1;
 dp->fw_loaded = false;
+   dp->aux.name = "DP-AUX";
+   dp->aux.transfer = cdn_dp_aux_transfer;
+   dp->aux.dev = dev;
+
+   ret = drm_dp_aux_register(>aux);
+   if (ret)
+   return ret;

 INIT_WORK(>event_work, cdn_dp_pd_event_work);

diff --git a/drivers/gpu/drm/rockchip/cdn-dp-core.h 
b/drivers/gpu/drm/rockchip/cdn-dp-core.h
index f57e296..46159b2 100644
--- a/drivers/gpu/drm/rockchip/cdn-dp-core.h
+++ 

Re: [PATCH 1/4] drm/rockchip: add transfer function for cdn-dp

2018-05-08 Thread hl

Hi Enric,


On Monday, May 07, 2018 07:27 PM, Enric Balletbo Serra wrote:

Hi Lin,

I am interested in these patches, could you cc me on newer versions? Thanks.

Some comments below.

Sure, will cc to you next version.


2018-05-04 10:08 GMT+02:00 Lin Huang :

From: Chris Zhong 

We may support training outside firmware, so we need support
dpcd read/write to get the message or do some setting with
display.

Signed-off-by: Chris Zhong 
Signed-off-by: Lin Huang 
---
  drivers/gpu/drm/rockchip/cdn-dp-core.c | 55 
  drivers/gpu/drm/rockchip/cdn-dp-core.h |  1 +
  drivers/gpu/drm/rockchip/cdn-dp-reg.c  | 66 +-
  drivers/gpu/drm/rockchip/cdn-dp-reg.h  | 14 ++--
  4 files changed, 119 insertions(+), 17 deletions(-)


In general, for this patch and all the other patches in the series I
saw that checkpatch spits out some warnings, could you fix these and
ideally run checkpatch with the --strict --subjective option?

Okay.



diff --git a/drivers/gpu/drm/rockchip/cdn-dp-core.c 
b/drivers/gpu/drm/rockchip/cdn-dp-core.c
index c6fbdcd..268c190 100644
--- a/drivers/gpu/drm/rockchip/cdn-dp-core.c
+++ b/drivers/gpu/drm/rockchip/cdn-dp-core.c
@@ -176,8 +176,8 @@ static int cdn_dp_get_sink_count(struct cdn_dp_device *dp, 
u8 *sink_count)
 u8 value;

 *sink_count = 0;
-   ret = cdn_dp_dpcd_read(dp, DP_SINK_COUNT, , 1);
-   if (ret)
+   ret = drm_dp_dpcd_read(>aux, DP_SINK_COUNT, , 1);
+   if (ret < 0)
 return ret;

 *sink_count = DP_GET_SINK_COUNT(value);
@@ -374,9 +374,9 @@ static int cdn_dp_get_sink_capability(struct cdn_dp_device 
*dp)
 if (!cdn_dp_check_sink_connection(dp))
 return -ENODEV;

-   ret = cdn_dp_dpcd_read(dp, DP_DPCD_REV, dp->dpcd,
-  DP_RECEIVER_CAP_SIZE);
-   if (ret) {
+   ret = drm_dp_dpcd_read(>aux, DP_DPCD_REV, dp->dpcd,
+  sizeof(dp->dpcd));
+   if (ret < 0) {
 DRM_DEV_ERROR(dp->dev, "Failed to get caps %d\n", ret);
 return ret;
 }
@@ -582,8 +582,8 @@ static bool cdn_dp_check_link_status(struct cdn_dp_device 
*dp)
 if (!port || !dp->link.rate || !dp->link.num_lanes)
 return false;

-   if (cdn_dp_dpcd_read(dp, DP_LANE0_1_STATUS, link_status,
-DP_LINK_STATUS_SIZE)) {
+   if (drm_dp_dpcd_read_link_status(>aux, link_status) !=
+   DP_LINK_STATUS_SIZE) {
 DRM_ERROR("Failed to get link status\n");
 return false;
 }
@@ -1012,6 +1012,40 @@ static int cdn_dp_pd_event(struct notifier_block *nb,
 return NOTIFY_DONE;
  }

+static ssize_t cdn_dp_aux_transfer(struct drm_dp_aux *aux,
+  struct drm_dp_aux_msg *msg)
+{
+   struct cdn_dp_device *dp = container_of(aux, struct cdn_dp_device, aux);
+   int ret;
+   u8 status;
+
+   switch (msg->request & ~DP_AUX_I2C_MOT) {
+   case DP_AUX_NATIVE_WRITE:
+   case DP_AUX_I2C_WRITE:
+   case DP_AUX_I2C_WRITE_STATUS_UPDATE:
+   ret = cdn_dp_dpcd_write(dp, msg->address, msg->buffer,
+   msg->size);
+   break;
+   case DP_AUX_NATIVE_READ:
+   case DP_AUX_I2C_READ:
+   ret = cdn_dp_dpcd_read(dp, msg->address, msg->buffer,
+  msg->size);
+   break;
+   default:
+   return -EINVAL;
+   }
+
+   status = cdn_dp_get_aux_status(dp);
+   if (status == AUX_STAUS_ACK)
+   msg->reply = DP_AUX_NATIVE_REPLY_ACK;
+   else if (status == AUX_STAUS_NACK)
+   msg->reply = DP_AUX_NATIVE_REPLY_NACK;
+   else if (status == AUX_STAUS_DEFER)
+   msg->reply = DP_AUX_NATIVE_REPLY_DEFER;
+

I think that you would mean STATUS instead of STAUS on these defines.

What happens if the status is AUX_STATUS_SINK_ERROR or AUX_STATUS_BUS_ERROR?

drm_dp_i2c_do_msg() will mark it as invalid i2c relay and return error.



+   return ret;
+}
+
  static int cdn_dp_bind(struct device *dev, struct device *master, void *data)
  {
 struct cdn_dp_device *dp = dev_get_drvdata(dev);
@@ -1030,6 +1064,13 @@ static int cdn_dp_bind(struct device *dev, struct device 
*master, void *data)
 dp->active = false;
 dp->active_port = -1;
 dp->fw_loaded = false;
+   dp->aux.name = "DP-AUX";
+   dp->aux.transfer = cdn_dp_aux_transfer;
+   dp->aux.dev = dev;
+
+   ret = drm_dp_aux_register(>aux);
+   if (ret)
+   return ret;

 INIT_WORK(>event_work, cdn_dp_pd_event_work);

diff --git a/drivers/gpu/drm/rockchip/cdn-dp-core.h 
b/drivers/gpu/drm/rockchip/cdn-dp-core.h
index f57e296..46159b2 100644
--- a/drivers/gpu/drm/rockchip/cdn-dp-core.h
+++ b/drivers/gpu/drm/rockchip/cdn-dp-core.h
@@ -78,6 +78,7 @@ struct cdn_dp_device {
 struct 

Re: [PATCH v4 1/3] drm/panel: refactor INNOLUX P079ZCA panel driver

2018-03-21 Thread hl

Hi


On Tuesday, March 20, 2018 06:20 PM, Emil Velikov wrote:

On 20 March 2018 at 06:24, hl <h...@rock-chips.com> wrote:

Hi Emil,



On Monday, March 19, 2018 09:09 PM, Emil Velikov wrote:

On 15 March 2018 at 02:35, hl <h...@rock-chips.com> wrote:

Hi Emil,



On Wednesday, March 14, 2018 08:02 PM, Emil Velikov wrote:

Hi Lin,

On 14 March 2018 at 09:12, Lin Huang <h...@rock-chips.com> wrote:

From: huang lin <h...@rock-chips.com>

Refactor Innolux P079ZCA panel driver, let it support
multi panel.

Change-Id: If89be5e56dba8cb498e2d50c1bbeb0e8016123a2
Signed-off-by: Lin Huang <h...@rock-chips.com>
---
Changes in v2:
- Change regulator property name to meet the panel datasheet
Changes in v3:
- this patch only refactor P079ZCA panel to support multi panel,
support
P097PFG panel in another patch
Changes in v4:
- Modify the patch which suggest by Thierry


Thanks for splitting this up. I think there's another piece that fell
through the cracks.
I'm not deeply familiar with the driver, so just sharing some quick
notes.



struct innolux_panel {
   struct drm_panel base;
   struct mipi_dsi_device *link;
+   const struct panel_desc *desc;

   struct backlight_device *backlight;
-   struct regulator *supply;
+   struct regulator *vddi;
+   struct regulator *avdd;
+   struct regulator *avee;

These two seem are new addition, as opposed to a dummy refactor.
Are they optional, does one need them for the existing panel (separate
patch?) or only for the new one (squash with the new panel code)?



   struct gpio_desc *enable_gpio;

   bool prepared;
@@ -77,9 +93,9 @@ static int innolux_panel_unprepare(struct drm_panel
*panel)
   /* T8: 80ms - 1000ms */
   msleep(80);

-   err = regulator_disable(innolux->supply);
-   if (err < 0)
-   return err;

Good call on dropping the early return here.



@@ -207,19 +248,28 @@ static const struct drm_panel_funcs
innolux_panel_funcs = {
-   innolux->supply = devm_regulator_get(dev, "power");
-   if (IS_ERR(innolux->supply))
-   return PTR_ERR(innolux->supply);
+   innolux = devm_kzalloc(dev, sizeof(*innolux), GFP_KERNEL);
+   if (!innolux)
+   return -ENOMEM;
+
+   innolux->desc = desc;
+   innolux->vddi = devm_regulator_get(dev, "power");
+   innolux->avdd = devm_regulator_get(dev, "avdd");
+   innolux->avee = devm_regulator_get(dev, "avee");


AFAICT devm_regulator_get returns a pointer which is unsuitable to be
passed into regulator_{enable,disable}.
Hence, the IS_ERR check should stay. If any of the regulators are
optional, you want to call regulator_{enable,disable} only as
applicable.


devm_regulator_get() will use dummy_regulator if there not regulator pass
to
driver, so it not affect regulator_{enable, disable}.

One of us is getting confused here:
devm_regulator_get does not _use_ a regulator, it returns a pointer to
a regulator, right?

According to the 4.16-rc6 codebase - one error
returns a ERR_PTR [1].

devm_regulator_get() will not reurn a ERR_PTR,  it will pass NORMAL_GET mode
to
_regulator_get() when you call devm_regulator_get(), and with following
code:


Just before the _regulator_get() call we have "return ERR_PTR(-ENOMEM);"
See 
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/drivers/regulator/devres.c?h=v4.16-rc6#n34
Okay, i got what you concern now, yes, you are right, i will keep IS_ERR 
checking here.



With the pointer dereferenced in regulator_enable [2], without a
IS_ERR check, hence thing will go boom(?)


These three regulator are
optional,
the p079zca will use "power" and ,
so i think it better not to check ERR here.


What should happen if p079zca is missing "power" or p097pgf - "avdd" and
"avee"?
Obviously the latter two should be introduced with the p097pgf support.

i think it need dts to make sure configure the power node correct, if
missing
"power" node fo p079zca or "avdd" "avee" node for p097pgf, the panel can
not work, but do not affcet other driver, the kernel do not crash(as i
explain before and i also test it).


If you know it won't work just don't continue? And yes, it will crash ;-)
Either way, if you don't like my feedback so be it.

HTH
Emil
P.S. As a non native English speaker to another - spell checker helps a lot ;-)








Re: [PATCH v4 1/3] drm/panel: refactor INNOLUX P079ZCA panel driver

2018-03-21 Thread hl

Hi


On Tuesday, March 20, 2018 06:20 PM, Emil Velikov wrote:

On 20 March 2018 at 06:24, hl  wrote:

Hi Emil,



On Monday, March 19, 2018 09:09 PM, Emil Velikov wrote:

On 15 March 2018 at 02:35, hl  wrote:

Hi Emil,



On Wednesday, March 14, 2018 08:02 PM, Emil Velikov wrote:

Hi Lin,

On 14 March 2018 at 09:12, Lin Huang  wrote:

From: huang lin 

Refactor Innolux P079ZCA panel driver, let it support
multi panel.

Change-Id: If89be5e56dba8cb498e2d50c1bbeb0e8016123a2
Signed-off-by: Lin Huang 
---
Changes in v2:
- Change regulator property name to meet the panel datasheet
Changes in v3:
- this patch only refactor P079ZCA panel to support multi panel,
support
P097PFG panel in another patch
Changes in v4:
- Modify the patch which suggest by Thierry


Thanks for splitting this up. I think there's another piece that fell
through the cracks.
I'm not deeply familiar with the driver, so just sharing some quick
notes.



struct innolux_panel {
   struct drm_panel base;
   struct mipi_dsi_device *link;
+   const struct panel_desc *desc;

   struct backlight_device *backlight;
-   struct regulator *supply;
+   struct regulator *vddi;
+   struct regulator *avdd;
+   struct regulator *avee;

These two seem are new addition, as opposed to a dummy refactor.
Are they optional, does one need them for the existing panel (separate
patch?) or only for the new one (squash with the new panel code)?



   struct gpio_desc *enable_gpio;

   bool prepared;
@@ -77,9 +93,9 @@ static int innolux_panel_unprepare(struct drm_panel
*panel)
   /* T8: 80ms - 1000ms */
   msleep(80);

-   err = regulator_disable(innolux->supply);
-   if (err < 0)
-   return err;

Good call on dropping the early return here.



@@ -207,19 +248,28 @@ static const struct drm_panel_funcs
innolux_panel_funcs = {
-   innolux->supply = devm_regulator_get(dev, "power");
-   if (IS_ERR(innolux->supply))
-   return PTR_ERR(innolux->supply);
+   innolux = devm_kzalloc(dev, sizeof(*innolux), GFP_KERNEL);
+   if (!innolux)
+   return -ENOMEM;
+
+   innolux->desc = desc;
+   innolux->vddi = devm_regulator_get(dev, "power");
+   innolux->avdd = devm_regulator_get(dev, "avdd");
+   innolux->avee = devm_regulator_get(dev, "avee");


AFAICT devm_regulator_get returns a pointer which is unsuitable to be
passed into regulator_{enable,disable}.
Hence, the IS_ERR check should stay. If any of the regulators are
optional, you want to call regulator_{enable,disable} only as
applicable.


devm_regulator_get() will use dummy_regulator if there not regulator pass
to
driver, so it not affect regulator_{enable, disable}.

One of us is getting confused here:
devm_regulator_get does not _use_ a regulator, it returns a pointer to
a regulator, right?

According to the 4.16-rc6 codebase - one error
returns a ERR_PTR [1].

devm_regulator_get() will not reurn a ERR_PTR,  it will pass NORMAL_GET mode
to
_regulator_get() when you call devm_regulator_get(), and with following
code:


Just before the _regulator_get() call we have "return ERR_PTR(-ENOMEM);"
See 
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/drivers/regulator/devres.c?h=v4.16-rc6#n34
Okay, i got what you concern now, yes, you are right, i will keep IS_ERR 
checking here.



With the pointer dereferenced in regulator_enable [2], without a
IS_ERR check, hence thing will go boom(?)


These three regulator are
optional,
the p079zca will use "power" and ,
so i think it better not to check ERR here.


What should happen if p079zca is missing "power" or p097pgf - "avdd" and
"avee"?
Obviously the latter two should be introduced with the p097pgf support.

i think it need dts to make sure configure the power node correct, if
missing
"power" node fo p079zca or "avdd" "avee" node for p097pgf, the panel can
not work, but do not affcet other driver, the kernel do not crash(as i
explain before and i also test it).


If you know it won't work just don't continue? And yes, it will crash ;-)
Either way, if you don't like my feedback so be it.

HTH
Emil
P.S. As a non native English speaker to another - spell checker helps a lot ;-)








Re: [PATCH v4 1/3] drm/panel: refactor INNOLUX P079ZCA panel driver

2018-03-20 Thread hl

Hi Emil,


On Monday, March 19, 2018 09:09 PM, Emil Velikov wrote:

On 15 March 2018 at 02:35, hl <h...@rock-chips.com> wrote:

Hi Emil,



On Wednesday, March 14, 2018 08:02 PM, Emil Velikov wrote:

Hi Lin,

On 14 March 2018 at 09:12, Lin Huang <h...@rock-chips.com> wrote:

From: huang lin <h...@rock-chips.com>

Refactor Innolux P079ZCA panel driver, let it support
multi panel.

Change-Id: If89be5e56dba8cb498e2d50c1bbeb0e8016123a2
Signed-off-by: Lin Huang <h...@rock-chips.com>
---
Changes in v2:
- Change regulator property name to meet the panel datasheet
Changes in v3:
- this patch only refactor P079ZCA panel to support multi panel, support
P097PFG panel in another patch
Changes in v4:
- Modify the patch which suggest by Thierry


Thanks for splitting this up. I think there's another piece that fell
through the cracks.
I'm not deeply familiar with the driver, so just sharing some quick notes.



   struct innolux_panel {
  struct drm_panel base;
  struct mipi_dsi_device *link;
+   const struct panel_desc *desc;

  struct backlight_device *backlight;
-   struct regulator *supply;
+   struct regulator *vddi;
+   struct regulator *avdd;
+   struct regulator *avee;

These two seem are new addition, as opposed to a dummy refactor.
Are they optional, does one need them for the existing panel (separate
patch?) or only for the new one (squash with the new panel code)?



  struct gpio_desc *enable_gpio;

  bool prepared;
@@ -77,9 +93,9 @@ static int innolux_panel_unprepare(struct drm_panel
*panel)
  /* T8: 80ms - 1000ms */
  msleep(80);

-   err = regulator_disable(innolux->supply);
-   if (err < 0)
-   return err;

Good call on dropping the early return here.



@@ -207,19 +248,28 @@ static const struct drm_panel_funcs
innolux_panel_funcs = {
-   innolux->supply = devm_regulator_get(dev, "power");
-   if (IS_ERR(innolux->supply))
-   return PTR_ERR(innolux->supply);
+   innolux = devm_kzalloc(dev, sizeof(*innolux), GFP_KERNEL);
+   if (!innolux)
+   return -ENOMEM;
+
+   innolux->desc = desc;
+   innolux->vddi = devm_regulator_get(dev, "power");
+   innolux->avdd = devm_regulator_get(dev, "avdd");
+   innolux->avee = devm_regulator_get(dev, "avee");


AFAICT devm_regulator_get returns a pointer which is unsuitable to be
passed into regulator_{enable,disable}.
Hence, the IS_ERR check should stay. If any of the regulators are
optional, you want to call regulator_{enable,disable} only as
applicable.


devm_regulator_get() will use dummy_regulator if there not regulator pass to
driver, so it not affect regulator_{enable, disable}.

One of us is getting confused here:
devm_regulator_get does not _use_ a regulator, it returns a pointer to
a regulator, right?

According to the 4.16-rc6 codebase - one error
returns a ERR_PTR [1].
devm_regulator_get() will not reurn a ERR_PTR,  it will pass NORMAL_GET 
mode to
_regulator_get() when you call devm_regulator_get(), and with following 
code:



rdev = regulator_dev_lookup(dev, id);
    if (IS_ERR(rdev)) {
.
..
    switch (get_type) {
        case NORMAL_GET:
            /*
             * Assume that a regulator is physically present and
             * enabled, even if it isn't hooked up, and just
             * provide a dummy.
             */
            dev_warn(dev,
                 "%s supply %s not found, using dummy regulator\n",
                 devname, id);
            rdev = dummy_regulator_rdev;
            get_device(>dev);
            break;
...
...
}

regulator = create_regulator(rdev, dev, id);
...

it wil get a dummy_regulator for it.




With the pointer dereferenced in regulator_enable [2], without a
IS_ERR check, hence thing will go boom(?)


These three regulator are
optional,
the p079zca will use "power" and ,
so i think it better not to check ERR here.


What should happen if p079zca is missing "power" or p097pgf - "avdd" and "avee"?
Obviously the latter two should be introduced with the p097pgf support.
i think it need dts to make sure configure the power node correct, if 
missing

"power" node fo p079zca or "avdd" "avee" node for p097pgf, the panel can
not work, but do not affcet other driver, the kernel do not crash(as i 
explain before and i also test it).


HTH
Emil

[1] 
https://elixir.bootlin.com/linux/v4.16-rc6/source/drivers/regulator/devres.c#L27
[2] 
https://elixir.bootlin.com/linux/v4.16-rc6/source/drivers/regulator/core.c#L2189








Re: [PATCH v4 1/3] drm/panel: refactor INNOLUX P079ZCA panel driver

2018-03-20 Thread hl

Hi Emil,


On Monday, March 19, 2018 09:09 PM, Emil Velikov wrote:

On 15 March 2018 at 02:35, hl  wrote:

Hi Emil,



On Wednesday, March 14, 2018 08:02 PM, Emil Velikov wrote:

Hi Lin,

On 14 March 2018 at 09:12, Lin Huang  wrote:

From: huang lin 

Refactor Innolux P079ZCA panel driver, let it support
multi panel.

Change-Id: If89be5e56dba8cb498e2d50c1bbeb0e8016123a2
Signed-off-by: Lin Huang 
---
Changes in v2:
- Change regulator property name to meet the panel datasheet
Changes in v3:
- this patch only refactor P079ZCA panel to support multi panel, support
P097PFG panel in another patch
Changes in v4:
- Modify the patch which suggest by Thierry


Thanks for splitting this up. I think there's another piece that fell
through the cracks.
I'm not deeply familiar with the driver, so just sharing some quick notes.



   struct innolux_panel {
  struct drm_panel base;
  struct mipi_dsi_device *link;
+   const struct panel_desc *desc;

  struct backlight_device *backlight;
-   struct regulator *supply;
+   struct regulator *vddi;
+   struct regulator *avdd;
+   struct regulator *avee;

These two seem are new addition, as opposed to a dummy refactor.
Are they optional, does one need them for the existing panel (separate
patch?) or only for the new one (squash with the new panel code)?



  struct gpio_desc *enable_gpio;

  bool prepared;
@@ -77,9 +93,9 @@ static int innolux_panel_unprepare(struct drm_panel
*panel)
  /* T8: 80ms - 1000ms */
  msleep(80);

-   err = regulator_disable(innolux->supply);
-   if (err < 0)
-   return err;

Good call on dropping the early return here.



@@ -207,19 +248,28 @@ static const struct drm_panel_funcs
innolux_panel_funcs = {
-   innolux->supply = devm_regulator_get(dev, "power");
-   if (IS_ERR(innolux->supply))
-   return PTR_ERR(innolux->supply);
+   innolux = devm_kzalloc(dev, sizeof(*innolux), GFP_KERNEL);
+   if (!innolux)
+   return -ENOMEM;
+
+   innolux->desc = desc;
+   innolux->vddi = devm_regulator_get(dev, "power");
+   innolux->avdd = devm_regulator_get(dev, "avdd");
+   innolux->avee = devm_regulator_get(dev, "avee");


AFAICT devm_regulator_get returns a pointer which is unsuitable to be
passed into regulator_{enable,disable}.
Hence, the IS_ERR check should stay. If any of the regulators are
optional, you want to call regulator_{enable,disable} only as
applicable.


devm_regulator_get() will use dummy_regulator if there not regulator pass to
driver, so it not affect regulator_{enable, disable}.

One of us is getting confused here:
devm_regulator_get does not _use_ a regulator, it returns a pointer to
a regulator, right?

According to the 4.16-rc6 codebase - one error
returns a ERR_PTR [1].
devm_regulator_get() will not reurn a ERR_PTR,  it will pass NORMAL_GET 
mode to
_regulator_get() when you call devm_regulator_get(), and with following 
code:



rdev = regulator_dev_lookup(dev, id);
    if (IS_ERR(rdev)) {
.
..
    switch (get_type) {
        case NORMAL_GET:
            /*
             * Assume that a regulator is physically present and
             * enabled, even if it isn't hooked up, and just
             * provide a dummy.
             */
            dev_warn(dev,
                 "%s supply %s not found, using dummy regulator\n",
                 devname, id);
            rdev = dummy_regulator_rdev;
            get_device(>dev);
            break;
...
...
}

regulator = create_regulator(rdev, dev, id);
...

it wil get a dummy_regulator for it.




With the pointer dereferenced in regulator_enable [2], without a
IS_ERR check, hence thing will go boom(?)


These three regulator are
optional,
the p079zca will use "power" and ,
so i think it better not to check ERR here.


What should happen if p079zca is missing "power" or p097pgf - "avdd" and "avee"?
Obviously the latter two should be introduced with the p097pgf support.
i think it need dts to make sure configure the power node correct, if 
missing

"power" node fo p079zca or "avdd" "avee" node for p097pgf, the panel can
not work, but do not affcet other driver, the kernel do not crash(as i 
explain before and i also test it).


HTH
Emil

[1] 
https://elixir.bootlin.com/linux/v4.16-rc6/source/drivers/regulator/devres.c#L27
[2] 
https://elixir.bootlin.com/linux/v4.16-rc6/source/drivers/regulator/core.c#L2189








Re: [PATCH v4 1/3] drm/panel: refactor INNOLUX P079ZCA panel driver

2018-03-14 Thread hl

Hi Emil,


On Wednesday, March 14, 2018 08:02 PM, Emil Velikov wrote:

Hi Lin,

On 14 March 2018 at 09:12, Lin Huang  wrote:

From: huang lin 

Refactor Innolux P079ZCA panel driver, let it support
multi panel.

Change-Id: If89be5e56dba8cb498e2d50c1bbeb0e8016123a2
Signed-off-by: Lin Huang 
---
Changes in v2:
- Change regulator property name to meet the panel datasheet
Changes in v3:
- this patch only refactor P079ZCA panel to support multi panel, support 
P097PFG panel in another patch
Changes in v4:
- Modify the patch which suggest by Thierry


Thanks for splitting this up. I think there's another piece that fell
through the cracks.
I'm not deeply familiar with the driver, so just sharing some quick notes.



  struct innolux_panel {
 struct drm_panel base;
 struct mipi_dsi_device *link;
+   const struct panel_desc *desc;

 struct backlight_device *backlight;
-   struct regulator *supply;
+   struct regulator *vddi;
+   struct regulator *avdd;
+   struct regulator *avee;

These two seem are new addition, as opposed to a dummy refactor.
Are they optional, does one need them for the existing panel (separate
patch?) or only for the new one (squash with the new panel code)?



 struct gpio_desc *enable_gpio;

 bool prepared;
@@ -77,9 +93,9 @@ static int innolux_panel_unprepare(struct drm_panel *panel)
 /* T8: 80ms - 1000ms */
 msleep(80);

-   err = regulator_disable(innolux->supply);
-   if (err < 0)
-   return err;

Good call on dropping the early return here.



@@ -207,19 +248,28 @@ static const struct drm_panel_funcs innolux_panel_funcs = 
{
-   innolux->supply = devm_regulator_get(dev, "power");
-   if (IS_ERR(innolux->supply))
-   return PTR_ERR(innolux->supply);
+   innolux = devm_kzalloc(dev, sizeof(*innolux), GFP_KERNEL);
+   if (!innolux)
+   return -ENOMEM;
+
+   innolux->desc = desc;
+   innolux->vddi = devm_regulator_get(dev, "power");
+   innolux->avdd = devm_regulator_get(dev, "avdd");
+   innolux->avee = devm_regulator_get(dev, "avee");


AFAICT devm_regulator_get returns a pointer which is unsuitable to be
passed into regulator_{enable,disable}.
Hence, the IS_ERR check should stay. If any of the regulators are
optional, you want to call regulator_{enable,disable} only as
applicable.


devm_regulator_get() will use dummy_regulator if there not regulator pass to 
driver,
so it not affect regulator_{enable, disable}. These three regulator are 
optional,
the p079zca will use "power" and p097pgf will use "avdd" and "avee",
so i think it better not to check ERR here.




@@ -318,5 +377,6 @@ static struct mipi_dsi_driver innolux_panel_driver = {
  module_mipi_dsi_driver(innolux_panel_driver);

  MODULE_AUTHOR("Chris Zhong ");
+MODULE_AUTHOR("Lin Huang ");

I don't think refactoring existing code classify as being the module author.
Then again, I could be wrong.

HTH
Emil








Re: [PATCH v4 1/3] drm/panel: refactor INNOLUX P079ZCA panel driver

2018-03-14 Thread hl

Hi Emil,


On Wednesday, March 14, 2018 08:02 PM, Emil Velikov wrote:

Hi Lin,

On 14 March 2018 at 09:12, Lin Huang  wrote:

From: huang lin 

Refactor Innolux P079ZCA panel driver, let it support
multi panel.

Change-Id: If89be5e56dba8cb498e2d50c1bbeb0e8016123a2
Signed-off-by: Lin Huang 
---
Changes in v2:
- Change regulator property name to meet the panel datasheet
Changes in v3:
- this patch only refactor P079ZCA panel to support multi panel, support 
P097PFG panel in another patch
Changes in v4:
- Modify the patch which suggest by Thierry


Thanks for splitting this up. I think there's another piece that fell
through the cracks.
I'm not deeply familiar with the driver, so just sharing some quick notes.



  struct innolux_panel {
 struct drm_panel base;
 struct mipi_dsi_device *link;
+   const struct panel_desc *desc;

 struct backlight_device *backlight;
-   struct regulator *supply;
+   struct regulator *vddi;
+   struct regulator *avdd;
+   struct regulator *avee;

These two seem are new addition, as opposed to a dummy refactor.
Are they optional, does one need them for the existing panel (separate
patch?) or only for the new one (squash with the new panel code)?



 struct gpio_desc *enable_gpio;

 bool prepared;
@@ -77,9 +93,9 @@ static int innolux_panel_unprepare(struct drm_panel *panel)
 /* T8: 80ms - 1000ms */
 msleep(80);

-   err = regulator_disable(innolux->supply);
-   if (err < 0)
-   return err;

Good call on dropping the early return here.



@@ -207,19 +248,28 @@ static const struct drm_panel_funcs innolux_panel_funcs = 
{
-   innolux->supply = devm_regulator_get(dev, "power");
-   if (IS_ERR(innolux->supply))
-   return PTR_ERR(innolux->supply);
+   innolux = devm_kzalloc(dev, sizeof(*innolux), GFP_KERNEL);
+   if (!innolux)
+   return -ENOMEM;
+
+   innolux->desc = desc;
+   innolux->vddi = devm_regulator_get(dev, "power");
+   innolux->avdd = devm_regulator_get(dev, "avdd");
+   innolux->avee = devm_regulator_get(dev, "avee");


AFAICT devm_regulator_get returns a pointer which is unsuitable to be
passed into regulator_{enable,disable}.
Hence, the IS_ERR check should stay. If any of the regulators are
optional, you want to call regulator_{enable,disable} only as
applicable.


devm_regulator_get() will use dummy_regulator if there not regulator pass to 
driver,
so it not affect regulator_{enable, disable}. These three regulator are 
optional,
the p079zca will use "power" and p097pgf will use "avdd" and "avee",
so i think it better not to check ERR here.




@@ -318,5 +377,6 @@ static struct mipi_dsi_driver innolux_panel_driver = {
  module_mipi_dsi_driver(innolux_panel_driver);

  MODULE_AUTHOR("Chris Zhong ");
+MODULE_AUTHOR("Lin Huang ");

I don't think refactoring existing code classify as being the module author.
Then again, I could be wrong.

HTH
Emil








Re: [RESEND PATCH v3 1/3] drm/panel: refactor INNOLUX P079ZCA panel driver

2018-03-12 Thread hl

Hi Thierry Reding,


On Monday, March 12, 2018 05:21 PM, Thierry Reding wrote:

On Mon, Dec 04, 2017 at 03:17:48PM +0800, Lin Huang wrote:

Refactor Innolux P079ZCA panel driver, let it support
multi panel.

Signed-off-by: Lin Huang 
---
Changes in v2:
- Change regulator property name to meet the panel datasheet
Changes in v3:
- this patch only refactor P079ZCA panel to support multi panel, support 
P097PFG panel in another patch

  drivers/gpu/drm/panel/panel-innolux-p079zca.c | 147 ++
  1 file changed, 105 insertions(+), 42 deletions(-)

diff --git a/drivers/gpu/drm/panel/panel-innolux-p079zca.c 
b/drivers/gpu/drm/panel/panel-innolux-p079zca.c
index 6ba9344..1597744 100644
--- a/drivers/gpu/drm/panel/panel-innolux-p079zca.c
+++ b/drivers/gpu/drm/panel/panel-innolux-p079zca.c
@@ -20,12 +20,32 @@
  
  #include 
  
+struct panel_desc {

+   const struct drm_display_mode *modes;
+   unsigned int bpc;
+   struct {
+   unsigned int width;
+   unsigned int height;
+   } size;
+};
+
+struct panel_desc_dsi {
+   struct panel_desc desc;
+
+   unsigned long flags;
+   enum mipi_dsi_pixel_format format;
+   unsigned int lanes;
+};

There's no need for the two layers here. Just move everything from
struct panel_desc_dsi into struct panel_desc.

Okay, will fix it.



+
  struct innolux_panel {
struct drm_panel base;
struct mipi_dsi_device *link;
+   const struct panel_desc_dsi *dsi_desc;

And then this can just become:

const struct panel_desc *desc;

The _dsi suffix is redundant because this driver is exclusively for DSI
devices.


Got it.

-static int innolux_panel_add(struct innolux_panel *innolux)
+static int innolux_panel_add(struct mipi_dsi_device *dsi,
+const struct panel_desc_dsi *desc)
  {
-   struct device *dev = >link->dev;
+   struct innolux_panel *innolux;
+   struct device *dev = >dev;
struct device_node *np;
int err;
  
-	innolux->supply = devm_regulator_get(dev, "power");

-   if (IS_ERR(innolux->supply))
-   return PTR_ERR(innolux->supply);
+   innolux = devm_kzalloc(dev, sizeof(*innolux), GFP_KERNEL);
+   if (!innolux)
+   return -ENOMEM;
+
+   innolux->dsi_desc = desc;
+   innolux->vddi = devm_regulator_get(dev, "power");
+   if (IS_ERR(innolux->vddi))
+   return PTR_ERR(innolux->vddi);
+
+   innolux->avdd = devm_regulator_get(dev, "avdd");
+   if (IS_ERR(innolux->avdd))
+   return PTR_ERR(innolux->avdd);
+
+   innolux->avee = devm_regulator_get(dev, "avee");
+   if (IS_ERR(innolux->avee))
+   return PTR_ERR(innolux->avee);

According to the device tree bindings these regulators are all optional.
Now devm_regulator_get() will return a dummy regulator if one has not
been specified in DT, so this seems like it should work fine, even for
existing DTBs that don't have the avdd and avee regulators. However, the
DT bindings seem to be wrong, because these are in fact required
regulators.
Actually, the vddi is request, and avdd and avee is optional, i will 
only check

vddi error later.
  
  	innolux->enable_gpio = devm_gpiod_get_optional(dev, "enable",

   GPIOD_OUT_HIGH);
@@ -243,14 +306,16 @@ static int innolux_panel_add(struct innolux_panel 
*innolux)
  
  	drm_panel_init(>base);

innolux->base.funcs = _panel_funcs;
-   innolux->base.dev = >link->dev;
+   innolux->base.dev = dev;
  
  	err = drm_panel_add(>base);

if (err < 0)
goto put_backlight;
  
-	return 0;

+   dev_set_drvdata(dev, innolux);
+   innolux->link = dsi;
  
+	return 0;

  put_backlight:
put_device(>backlight->dev);
  
@@ -267,28 +332,25 @@ static void innolux_panel_del(struct innolux_panel *innolux)
  
  static int innolux_panel_probe(struct mipi_dsi_device *dsi)

  {
-   struct innolux_panel *innolux;
-   int err;
  
-	dsi->lanes = 4;

-   dsi->format = MIPI_DSI_FMT_RGB888;
-   dsi->mode_flags = MIPI_DSI_MODE_VIDEO | MIPI_DSI_MODE_VIDEO_SYNC_PULSE |
- MIPI_DSI_MODE_LPM;
-
-   innolux = devm_kzalloc(>dev, sizeof(*innolux), GFP_KERNEL);
-   if (!innolux)
-   return -ENOMEM;
+   const struct panel_desc_dsi *dsi_desc;
+   const struct of_device_id *id;
+   int err;
  
-	mipi_dsi_set_drvdata(dsi, innolux);

+   id = of_match_node(innolux_of_match, dsi->dev.of_node);
+   if (!id)
+   return -ENODEV;
  
-	innolux->link = dsi;

+   dsi_desc = id->data;
+   dsi->mode_flags = dsi_desc->flags;
+   dsi->format = dsi_desc->format;
+   dsi->lanes = dsi_desc->lanes;
  
-	err = innolux_panel_add(innolux);

+   err = innolux_panel_add(dsi, dsi_desc);
if (err < 0)
return err;
  
-	err = mipi_dsi_attach(dsi);

-   return err;
+  

Re: [RESEND PATCH v3 1/3] drm/panel: refactor INNOLUX P079ZCA panel driver

2018-03-12 Thread hl

Hi Thierry Reding,


On Monday, March 12, 2018 05:21 PM, Thierry Reding wrote:

On Mon, Dec 04, 2017 at 03:17:48PM +0800, Lin Huang wrote:

Refactor Innolux P079ZCA panel driver, let it support
multi panel.

Signed-off-by: Lin Huang 
---
Changes in v2:
- Change regulator property name to meet the panel datasheet
Changes in v3:
- this patch only refactor P079ZCA panel to support multi panel, support 
P097PFG panel in another patch

  drivers/gpu/drm/panel/panel-innolux-p079zca.c | 147 ++
  1 file changed, 105 insertions(+), 42 deletions(-)

diff --git a/drivers/gpu/drm/panel/panel-innolux-p079zca.c 
b/drivers/gpu/drm/panel/panel-innolux-p079zca.c
index 6ba9344..1597744 100644
--- a/drivers/gpu/drm/panel/panel-innolux-p079zca.c
+++ b/drivers/gpu/drm/panel/panel-innolux-p079zca.c
@@ -20,12 +20,32 @@
  
  #include 
  
+struct panel_desc {

+   const struct drm_display_mode *modes;
+   unsigned int bpc;
+   struct {
+   unsigned int width;
+   unsigned int height;
+   } size;
+};
+
+struct panel_desc_dsi {
+   struct panel_desc desc;
+
+   unsigned long flags;
+   enum mipi_dsi_pixel_format format;
+   unsigned int lanes;
+};

There's no need for the two layers here. Just move everything from
struct panel_desc_dsi into struct panel_desc.

Okay, will fix it.



+
  struct innolux_panel {
struct drm_panel base;
struct mipi_dsi_device *link;
+   const struct panel_desc_dsi *dsi_desc;

And then this can just become:

const struct panel_desc *desc;

The _dsi suffix is redundant because this driver is exclusively for DSI
devices.


Got it.

-static int innolux_panel_add(struct innolux_panel *innolux)
+static int innolux_panel_add(struct mipi_dsi_device *dsi,
+const struct panel_desc_dsi *desc)
  {
-   struct device *dev = >link->dev;
+   struct innolux_panel *innolux;
+   struct device *dev = >dev;
struct device_node *np;
int err;
  
-	innolux->supply = devm_regulator_get(dev, "power");

-   if (IS_ERR(innolux->supply))
-   return PTR_ERR(innolux->supply);
+   innolux = devm_kzalloc(dev, sizeof(*innolux), GFP_KERNEL);
+   if (!innolux)
+   return -ENOMEM;
+
+   innolux->dsi_desc = desc;
+   innolux->vddi = devm_regulator_get(dev, "power");
+   if (IS_ERR(innolux->vddi))
+   return PTR_ERR(innolux->vddi);
+
+   innolux->avdd = devm_regulator_get(dev, "avdd");
+   if (IS_ERR(innolux->avdd))
+   return PTR_ERR(innolux->avdd);
+
+   innolux->avee = devm_regulator_get(dev, "avee");
+   if (IS_ERR(innolux->avee))
+   return PTR_ERR(innolux->avee);

According to the device tree bindings these regulators are all optional.
Now devm_regulator_get() will return a dummy regulator if one has not
been specified in DT, so this seems like it should work fine, even for
existing DTBs that don't have the avdd and avee regulators. However, the
DT bindings seem to be wrong, because these are in fact required
regulators.
Actually, the vddi is request, and avdd and avee is optional, i will 
only check

vddi error later.
  
  	innolux->enable_gpio = devm_gpiod_get_optional(dev, "enable",

   GPIOD_OUT_HIGH);
@@ -243,14 +306,16 @@ static int innolux_panel_add(struct innolux_panel 
*innolux)
  
  	drm_panel_init(>base);

innolux->base.funcs = _panel_funcs;
-   innolux->base.dev = >link->dev;
+   innolux->base.dev = dev;
  
  	err = drm_panel_add(>base);

if (err < 0)
goto put_backlight;
  
-	return 0;

+   dev_set_drvdata(dev, innolux);
+   innolux->link = dsi;
  
+	return 0;

  put_backlight:
put_device(>backlight->dev);
  
@@ -267,28 +332,25 @@ static void innolux_panel_del(struct innolux_panel *innolux)
  
  static int innolux_panel_probe(struct mipi_dsi_device *dsi)

  {
-   struct innolux_panel *innolux;
-   int err;
  
-	dsi->lanes = 4;

-   dsi->format = MIPI_DSI_FMT_RGB888;
-   dsi->mode_flags = MIPI_DSI_MODE_VIDEO | MIPI_DSI_MODE_VIDEO_SYNC_PULSE |
- MIPI_DSI_MODE_LPM;
-
-   innolux = devm_kzalloc(>dev, sizeof(*innolux), GFP_KERNEL);
-   if (!innolux)
-   return -ENOMEM;
+   const struct panel_desc_dsi *dsi_desc;
+   const struct of_device_id *id;
+   int err;
  
-	mipi_dsi_set_drvdata(dsi, innolux);

+   id = of_match_node(innolux_of_match, dsi->dev.of_node);
+   if (!id)
+   return -ENODEV;
  
-	innolux->link = dsi;

+   dsi_desc = id->data;
+   dsi->mode_flags = dsi_desc->flags;
+   dsi->format = dsi_desc->format;
+   dsi->lanes = dsi_desc->lanes;
  
-	err = innolux_panel_add(innolux);

+   err = innolux_panel_add(dsi, dsi_desc);
if (err < 0)
return err;
  
-	err = mipi_dsi_attach(dsi);

-   return err;
+   return 

Re: [RFC] pwm-backlight: Allow backlight to remain disabled on boot

2018-01-04 Thread hl

Hi


On Thursday, January 04, 2018 04:22 PM, Peter Ujfalusi wrote:

Hi,

On 2018-01-04 04:18, hl wrote:

Hi All,

     Since many panel power sequence request backlight stay disable

before panel power ready, but with now pwm-backlight drvier, it default to

enable backlight when pwm-backlight probe, it mess up the panel power
sequence.

So we need this patch. This patch have been fly for a long time, does
anyone have plan

to merge it?

you should not need this anymore since we have:
892c7788c724backlight: pwm_bl: Fix GPIO out for unimplemented
.get_direction()

d1b812945750 backlight: pwm_bl: Check the PWM state for initial
backlight power state

7613c922315e backlight: pwm_bl: Move the checks for initial power state
to a separate function

With these in place the backlight will be kept disabled if it was
disabled during boot _if_ you have booted via DT _and_ you have a
phandle pointing to the backlight node (implying that the backlight is
managed by the display driver).

Oh, thanks for reminding me.




On Thursday, July 31, 2014 07:42 PM, Thierry Reding wrote:

From: Thierry Reding <tred...@nvidia.com>

The default for backlight devices is to be enabled immediately when
registering with the backlight core. This can be useful for setups that
use a simple framebuffer device and where the backlight cannot otherwise
be hooked up to the panel.

However, when dealing with more complex setups, such as those of recent
ARM SoCs, this can be problematic. Since the backlight is usually setup
separately from the display controller, the probe order is not usually
deterministic. That can lead to situations where the backlight will be
powered up and the panel will show an uninitialized framebuffer.

Furthermore, subsystems such as DRM have advanced functionality to set
the power mode of a panel. In order to allow such setups to power up the
panel at exactly the right moment, a way is needed to prevent the
backlight core from powering the backlight up automatically when it is
registered.

This commit introduces a new boot_off field in the platform data (and
also implements getting the same information from device tree). When set
the initial backlight power mode will be set to "off".

Signed-off-by: Thierry Reding <tred...@nvidia.com>
---
I've been meaning to send this for a while but was always holding back
because of the indoctrination that this type of configuration shouldn't
be part of device tree. However this issue was recently raised again in
the context of power up sequences for display panels. As described above
the issue is that panel datasheets recommend that the backlight attached
to a panel be turned on at the very last step to avoid visual glitches
during the panel's power up sequence. With the current implementation it
is typical for the backlight to be probed before the display panel. That
has, in many cases, the side-effect of enabling the backlight, therefore
making the screen content visible before it's actually initialized.

Some panels come up with random garbage when uninitialized, others show
all white. With some luck the panel will be all black and users won't
really notice.

This patch is an attempt to enable boards to override the default of
turning on the backlight for the pwm-backlight driver. I'm not sure if
there was a specific reason to turn on the backlight by default when
this driver was initially written, but the fact is that since it has
pretty much always been like this we can't really go and change the
default, otherwise a lot of people may end up with no backlight and no
clue as to how to enable it. So the only reasonable thing we can do is
to keep the old behaviour and give new boards a way to override it if
they know that some other part of the stack will enable it at the right
moment.

   .../devicetree/bindings/video/backlight/pwm-backlight.txt | 1 +
   drivers/video/backlight/pwm_bl.c  |
8 
   include/linux/pwm_backlight.h |
2 ++
   3 files changed, 11 insertions(+)

diff --git
a/Documentation/devicetree/bindings/video/backlight/pwm-backlight.txt
b/Documentation/devicetree/bindings/video/backlight/pwm-backlight.txt
index 764db86d441a..65e001a1733d 100644
--- a/Documentation/devicetree/bindings/video/backlight/pwm-backlight.txt
+++ b/Documentation/devicetree/bindings/video/backlight/pwm-backlight.txt
@@ -17,6 +17,7 @@ Optional properties:
  "pwms" property (see PWM binding[0])
     - enable-gpios: contains a single GPIO specifier for the GPIO
which enables
     and disables the backlight (see GPIO binding[1])
+  - backlight-boot-off: keep the backlight disabled on boot
     [0]: Documentation/devicetree/bindings/pwm/pwm.txt
   [1]: Documentation/devicetree/bindings/gpio/gpio.txt
diff --git a/drivers/video/backlight/pwm_bl.c
b/drivers/video/backlight/pwm_bl.c
index d7a3d13e72ec..62adfc9d37a7 100644
--- a/drivers/video/backli

Re: [RFC] pwm-backlight: Allow backlight to remain disabled on boot

2018-01-04 Thread hl

Hi


On Thursday, January 04, 2018 04:22 PM, Peter Ujfalusi wrote:

Hi,

On 2018-01-04 04:18, hl wrote:

Hi All,

     Since many panel power sequence request backlight stay disable

before panel power ready, but with now pwm-backlight drvier, it default to

enable backlight when pwm-backlight probe, it mess up the panel power
sequence.

So we need this patch. This patch have been fly for a long time, does
anyone have plan

to merge it?

you should not need this anymore since we have:
892c7788c724backlight: pwm_bl: Fix GPIO out for unimplemented
.get_direction()

d1b812945750 backlight: pwm_bl: Check the PWM state for initial
backlight power state

7613c922315e backlight: pwm_bl: Move the checks for initial power state
to a separate function

With these in place the backlight will be kept disabled if it was
disabled during boot _if_ you have booted via DT _and_ you have a
phandle pointing to the backlight node (implying that the backlight is
managed by the display driver).

Oh, thanks for reminding me.




On Thursday, July 31, 2014 07:42 PM, Thierry Reding wrote:

From: Thierry Reding 

The default for backlight devices is to be enabled immediately when
registering with the backlight core. This can be useful for setups that
use a simple framebuffer device and where the backlight cannot otherwise
be hooked up to the panel.

However, when dealing with more complex setups, such as those of recent
ARM SoCs, this can be problematic. Since the backlight is usually setup
separately from the display controller, the probe order is not usually
deterministic. That can lead to situations where the backlight will be
powered up and the panel will show an uninitialized framebuffer.

Furthermore, subsystems such as DRM have advanced functionality to set
the power mode of a panel. In order to allow such setups to power up the
panel at exactly the right moment, a way is needed to prevent the
backlight core from powering the backlight up automatically when it is
registered.

This commit introduces a new boot_off field in the platform data (and
also implements getting the same information from device tree). When set
the initial backlight power mode will be set to "off".

Signed-off-by: Thierry Reding 
---
I've been meaning to send this for a while but was always holding back
because of the indoctrination that this type of configuration shouldn't
be part of device tree. However this issue was recently raised again in
the context of power up sequences for display panels. As described above
the issue is that panel datasheets recommend that the backlight attached
to a panel be turned on at the very last step to avoid visual glitches
during the panel's power up sequence. With the current implementation it
is typical for the backlight to be probed before the display panel. That
has, in many cases, the side-effect of enabling the backlight, therefore
making the screen content visible before it's actually initialized.

Some panels come up with random garbage when uninitialized, others show
all white. With some luck the panel will be all black and users won't
really notice.

This patch is an attempt to enable boards to override the default of
turning on the backlight for the pwm-backlight driver. I'm not sure if
there was a specific reason to turn on the backlight by default when
this driver was initially written, but the fact is that since it has
pretty much always been like this we can't really go and change the
default, otherwise a lot of people may end up with no backlight and no
clue as to how to enable it. So the only reasonable thing we can do is
to keep the old behaviour and give new boards a way to override it if
they know that some other part of the stack will enable it at the right
moment.

   .../devicetree/bindings/video/backlight/pwm-backlight.txt | 1 +
   drivers/video/backlight/pwm_bl.c  |
8 
   include/linux/pwm_backlight.h |
2 ++
   3 files changed, 11 insertions(+)

diff --git
a/Documentation/devicetree/bindings/video/backlight/pwm-backlight.txt
b/Documentation/devicetree/bindings/video/backlight/pwm-backlight.txt
index 764db86d441a..65e001a1733d 100644
--- a/Documentation/devicetree/bindings/video/backlight/pwm-backlight.txt
+++ b/Documentation/devicetree/bindings/video/backlight/pwm-backlight.txt
@@ -17,6 +17,7 @@ Optional properties:
  "pwms" property (see PWM binding[0])
     - enable-gpios: contains a single GPIO specifier for the GPIO
which enables
     and disables the backlight (see GPIO binding[1])
+  - backlight-boot-off: keep the backlight disabled on boot
     [0]: Documentation/devicetree/bindings/pwm/pwm.txt
   [1]: Documentation/devicetree/bindings/gpio/gpio.txt
diff --git a/drivers/video/backlight/pwm_bl.c
b/drivers/video/backlight/pwm_bl.c
index d7a3d13e72ec..62adfc9d37a7 100644
--- a/drivers/video/backlight/pwm_bl.c
+++ b/drivers/video/backlight/pwm_bl.c
@@ -17

Re: [RFC] pwm-backlight: Allow backlight to remain disabled on boot

2018-01-03 Thread hl

Hi All,

    Since many panel power sequence request backlight stay disable

before panel power ready, but with now pwm-backlight drvier, it default to

enable backlight when pwm-backlight probe, it mess up the panel power 
sequence.


So we need this patch. This patch have been fly for a long time, does 
anyone have plan


to merge it?


On Thursday, July 31, 2014 07:42 PM, Thierry Reding wrote:

From: Thierry Reding 

The default for backlight devices is to be enabled immediately when
registering with the backlight core. This can be useful for setups that
use a simple framebuffer device and where the backlight cannot otherwise
be hooked up to the panel.

However, when dealing with more complex setups, such as those of recent
ARM SoCs, this can be problematic. Since the backlight is usually setup
separately from the display controller, the probe order is not usually
deterministic. That can lead to situations where the backlight will be
powered up and the panel will show an uninitialized framebuffer.

Furthermore, subsystems such as DRM have advanced functionality to set
the power mode of a panel. In order to allow such setups to power up the
panel at exactly the right moment, a way is needed to prevent the
backlight core from powering the backlight up automatically when it is
registered.

This commit introduces a new boot_off field in the platform data (and
also implements getting the same information from device tree). When set
the initial backlight power mode will be set to "off".

Signed-off-by: Thierry Reding 
---
I've been meaning to send this for a while but was always holding back
because of the indoctrination that this type of configuration shouldn't
be part of device tree. However this issue was recently raised again in
the context of power up sequences for display panels. As described above
the issue is that panel datasheets recommend that the backlight attached
to a panel be turned on at the very last step to avoid visual glitches
during the panel's power up sequence. With the current implementation it
is typical for the backlight to be probed before the display panel. That
has, in many cases, the side-effect of enabling the backlight, therefore
making the screen content visible before it's actually initialized.

Some panels come up with random garbage when uninitialized, others show
all white. With some luck the panel will be all black and users won't
really notice.

This patch is an attempt to enable boards to override the default of
turning on the backlight for the pwm-backlight driver. I'm not sure if
there was a specific reason to turn on the backlight by default when
this driver was initially written, but the fact is that since it has
pretty much always been like this we can't really go and change the
default, otherwise a lot of people may end up with no backlight and no
clue as to how to enable it. So the only reasonable thing we can do is
to keep the old behaviour and give new boards a way to override it if
they know that some other part of the stack will enable it at the right
moment.

  .../devicetree/bindings/video/backlight/pwm-backlight.txt | 1 +
  drivers/video/backlight/pwm_bl.c  | 8 
  include/linux/pwm_backlight.h | 2 ++
  3 files changed, 11 insertions(+)

diff --git 
a/Documentation/devicetree/bindings/video/backlight/pwm-backlight.txt 
b/Documentation/devicetree/bindings/video/backlight/pwm-backlight.txt
index 764db86d441a..65e001a1733d 100644
--- a/Documentation/devicetree/bindings/video/backlight/pwm-backlight.txt
+++ b/Documentation/devicetree/bindings/video/backlight/pwm-backlight.txt
@@ -17,6 +17,7 @@ Optional properties:
 "pwms" property (see PWM binding[0])
- enable-gpios: contains a single GPIO specifier for the GPIO which enables
and disables the backlight (see GPIO binding[1])
+  - backlight-boot-off: keep the backlight disabled on boot
  
  [0]: Documentation/devicetree/bindings/pwm/pwm.txt

  [1]: Documentation/devicetree/bindings/gpio/gpio.txt
diff --git a/drivers/video/backlight/pwm_bl.c b/drivers/video/backlight/pwm_bl.c
index d7a3d13e72ec..62adfc9d37a7 100644
--- a/drivers/video/backlight/pwm_bl.c
+++ b/drivers/video/backlight/pwm_bl.c
@@ -173,6 +173,8 @@ static int pwm_backlight_parse_dt(struct device *dev,
data->max_brightness--;
}
  
+	data->boot_off = of_property_read_bool(node, "backlight-boot-off");

+
return 0;
  }
  
@@ -317,6 +319,12 @@ static int pwm_backlight_probe(struct platform_device *pdev)

}
  
  	bl->props.brightness = data->dft_brightness;

+
+   if (data->boot_off)
+   bl->props.power = FB_BLANK_POWERDOWN;
+   else
+   bl->props.power = FB_BLANK_UNBLANK;
+
backlight_update_status(bl);
  
  	platform_set_drvdata(pdev, bl);

diff --git a/include/linux/pwm_backlight.h b/include/linux/pwm_backlight.h

Re: [RFC] pwm-backlight: Allow backlight to remain disabled on boot

2018-01-03 Thread hl

Hi All,

    Since many panel power sequence request backlight stay disable

before panel power ready, but with now pwm-backlight drvier, it default to

enable backlight when pwm-backlight probe, it mess up the panel power 
sequence.


So we need this patch. This patch have been fly for a long time, does 
anyone have plan


to merge it?


On Thursday, July 31, 2014 07:42 PM, Thierry Reding wrote:

From: Thierry Reding 

The default for backlight devices is to be enabled immediately when
registering with the backlight core. This can be useful for setups that
use a simple framebuffer device and where the backlight cannot otherwise
be hooked up to the panel.

However, when dealing with more complex setups, such as those of recent
ARM SoCs, this can be problematic. Since the backlight is usually setup
separately from the display controller, the probe order is not usually
deterministic. That can lead to situations where the backlight will be
powered up and the panel will show an uninitialized framebuffer.

Furthermore, subsystems such as DRM have advanced functionality to set
the power mode of a panel. In order to allow such setups to power up the
panel at exactly the right moment, a way is needed to prevent the
backlight core from powering the backlight up automatically when it is
registered.

This commit introduces a new boot_off field in the platform data (and
also implements getting the same information from device tree). When set
the initial backlight power mode will be set to "off".

Signed-off-by: Thierry Reding 
---
I've been meaning to send this for a while but was always holding back
because of the indoctrination that this type of configuration shouldn't
be part of device tree. However this issue was recently raised again in
the context of power up sequences for display panels. As described above
the issue is that panel datasheets recommend that the backlight attached
to a panel be turned on at the very last step to avoid visual glitches
during the panel's power up sequence. With the current implementation it
is typical for the backlight to be probed before the display panel. That
has, in many cases, the side-effect of enabling the backlight, therefore
making the screen content visible before it's actually initialized.

Some panels come up with random garbage when uninitialized, others show
all white. With some luck the panel will be all black and users won't
really notice.

This patch is an attempt to enable boards to override the default of
turning on the backlight for the pwm-backlight driver. I'm not sure if
there was a specific reason to turn on the backlight by default when
this driver was initially written, but the fact is that since it has
pretty much always been like this we can't really go and change the
default, otherwise a lot of people may end up with no backlight and no
clue as to how to enable it. So the only reasonable thing we can do is
to keep the old behaviour and give new boards a way to override it if
they know that some other part of the stack will enable it at the right
moment.

  .../devicetree/bindings/video/backlight/pwm-backlight.txt | 1 +
  drivers/video/backlight/pwm_bl.c  | 8 
  include/linux/pwm_backlight.h | 2 ++
  3 files changed, 11 insertions(+)

diff --git 
a/Documentation/devicetree/bindings/video/backlight/pwm-backlight.txt 
b/Documentation/devicetree/bindings/video/backlight/pwm-backlight.txt
index 764db86d441a..65e001a1733d 100644
--- a/Documentation/devicetree/bindings/video/backlight/pwm-backlight.txt
+++ b/Documentation/devicetree/bindings/video/backlight/pwm-backlight.txt
@@ -17,6 +17,7 @@ Optional properties:
 "pwms" property (see PWM binding[0])
- enable-gpios: contains a single GPIO specifier for the GPIO which enables
and disables the backlight (see GPIO binding[1])
+  - backlight-boot-off: keep the backlight disabled on boot
  
  [0]: Documentation/devicetree/bindings/pwm/pwm.txt

  [1]: Documentation/devicetree/bindings/gpio/gpio.txt
diff --git a/drivers/video/backlight/pwm_bl.c b/drivers/video/backlight/pwm_bl.c
index d7a3d13e72ec..62adfc9d37a7 100644
--- a/drivers/video/backlight/pwm_bl.c
+++ b/drivers/video/backlight/pwm_bl.c
@@ -173,6 +173,8 @@ static int pwm_backlight_parse_dt(struct device *dev,
data->max_brightness--;
}
  
+	data->boot_off = of_property_read_bool(node, "backlight-boot-off");

+
return 0;
  }
  
@@ -317,6 +319,12 @@ static int pwm_backlight_probe(struct platform_device *pdev)

}
  
  	bl->props.brightness = data->dft_brightness;

+
+   if (data->boot_off)
+   bl->props.power = FB_BLANK_POWERDOWN;
+   else
+   bl->props.power = FB_BLANK_UNBLANK;
+
backlight_update_status(bl);
  
  	platform_set_drvdata(pdev, bl);

diff --git a/include/linux/pwm_backlight.h b/include/linux/pwm_backlight.h
index efdd9227a49c..1fc14989da4a 100644

Re: [PATCH] drm/panel: support Innolux P097PFG panel

2017-12-03 Thread hl

Hi Emil,


On Saturday, December 02, 2017 01:55 AM, Emil Velikov wrote:

On 30 November 2017 at 06:13, Lin Huang  wrote:

Support Innolux P097PFG 9.7" 1536x2048 TFT LCD panel,
it refactor Innolux P079ZCA panel driver, let it support
multi panel, and add support P097PFG panel in this driver.


Couple of drive-by suggestions:

Split the refactor vs new hw?

Sorry,  i don't get what you mean.



  MODULE_DESCRIPTION("Innolux P079ZCA panel driver");

Update this reference alongside the ones in Kconfig?

Okay, will fix it next version.


-Emil








Re: [PATCH] drm/panel: support Innolux P097PFG panel

2017-12-03 Thread hl

Hi Emil,


On Saturday, December 02, 2017 01:55 AM, Emil Velikov wrote:

On 30 November 2017 at 06:13, Lin Huang  wrote:

Support Innolux P097PFG 9.7" 1536x2048 TFT LCD panel,
it refactor Innolux P079ZCA panel driver, let it support
multi panel, and add support P097PFG panel in this driver.


Couple of drive-by suggestions:

Split the refactor vs new hw?

Sorry,  i don't get what you mean.



  MODULE_DESCRIPTION("Innolux P079ZCA panel driver");

Update this reference alongside the ones in Kconfig?

Okay, will fix it next version.


-Emil








Re: [RESENT PATCH] drm/panel: support Innolux P097PFG panel

2017-11-30 Thread hl

Hi


On Friday, December 01, 2017 10:54 AM, Brian Norris wrote:

One more comment:

On Thu, Nov 30, 2017 at 02:14:40PM +0800, Lin Huang wrote:

Support Innolux P097PFG 9.7" 1536x2048 TFT LCD panel,
it refactor Innolux P079ZCA panel driver, let it support
multi panel, and add support P097PFG panel in this driver.

Signed-off-by: Lin Huang 

---
  drivers/gpu/drm/panel/panel-innolux-p079zca.c | 178 --
  1 file changed, 136 insertions(+), 42 deletions(-)

diff --git a/drivers/gpu/drm/panel/panel-innolux-p079zca.c 
b/drivers/gpu/drm/panel/panel-innolux-p079zca.c
index 6ba9344..a40798f 100644
--- a/drivers/gpu/drm/panel/panel-innolux-p079zca.c
+++ b/drivers/gpu/drm/panel/panel-innolux-p079zca.c

...


@@ -209,20 +284,39 @@ static const struct drm_panel_funcs innolux_panel_funcs = 
{
  };
  
  static const struct of_device_id innolux_of_match[] = {

-   { .compatible = "innolux,p079zca", },
-   { }
+   { .compatible = "innolux,p079zca",
+ .data = _p079zca_panel_desc
+   },
+   { .compatible = "innolux,p097pfg",
+ .data = _p097pfg_panel_desc
+   }
  };
  MODULE_DEVICE_TABLE(of, innolux_of_match);
  
-static int innolux_panel_add(struct innolux_panel *innolux)

+static int innolux_panel_add(struct mipi_dsi_device *dsi,
+const struct panel_desc_dsi *desc)
  {
-   struct device *dev = >link->dev;
+   struct innolux_panel *innolux;
+   struct device *dev = >dev;
struct device_node *np;
int err;
  
-	innolux->supply = devm_regulator_get(dev, "power");

-   if (IS_ERR(innolux->supply))
-   return PTR_ERR(innolux->supply);
+   innolux = devm_kzalloc(dev, sizeof(*innolux), GFP_KERNEL);
+   if (!innolux)
+   return -ENOMEM;
+
+   innolux->dsi_desc = desc;
+   innolux->vddi = devm_regulator_get_optional(dev, "power");
+   if (IS_ERR(innolux->vddi))
+   return PTR_ERR(innolux->vddi);
+
+   innolux->avdd = devm_regulator_get(dev, "ppvarp");

This name ("ppvarp" and the "ppvarn" below) are names from our board
schematics, not from the panel datasheet. I would think these should be
"vdd" and "vee", like your variable names.

Okay, will fix it next version.


Brian


+   if (IS_ERR(innolux->avdd))
+   return PTR_ERR(innolux->avdd);
+
+   innolux->avee = devm_regulator_get(dev, "ppvarn");
+   if (IS_ERR(innolux->avee))
+   return PTR_ERR(innolux->avee);
  
  	innolux->enable_gpio = devm_gpiod_get_optional(dev, "enable",

   GPIOD_OUT_HIGH);

...








Re: [RESENT PATCH] drm/panel: support Innolux P097PFG panel

2017-11-30 Thread hl

Hi


On Friday, December 01, 2017 10:54 AM, Brian Norris wrote:

One more comment:

On Thu, Nov 30, 2017 at 02:14:40PM +0800, Lin Huang wrote:

Support Innolux P097PFG 9.7" 1536x2048 TFT LCD panel,
it refactor Innolux P079ZCA panel driver, let it support
multi panel, and add support P097PFG panel in this driver.

Signed-off-by: Lin Huang 

---
  drivers/gpu/drm/panel/panel-innolux-p079zca.c | 178 --
  1 file changed, 136 insertions(+), 42 deletions(-)

diff --git a/drivers/gpu/drm/panel/panel-innolux-p079zca.c 
b/drivers/gpu/drm/panel/panel-innolux-p079zca.c
index 6ba9344..a40798f 100644
--- a/drivers/gpu/drm/panel/panel-innolux-p079zca.c
+++ b/drivers/gpu/drm/panel/panel-innolux-p079zca.c

...


@@ -209,20 +284,39 @@ static const struct drm_panel_funcs innolux_panel_funcs = 
{
  };
  
  static const struct of_device_id innolux_of_match[] = {

-   { .compatible = "innolux,p079zca", },
-   { }
+   { .compatible = "innolux,p079zca",
+ .data = _p079zca_panel_desc
+   },
+   { .compatible = "innolux,p097pfg",
+ .data = _p097pfg_panel_desc
+   }
  };
  MODULE_DEVICE_TABLE(of, innolux_of_match);
  
-static int innolux_panel_add(struct innolux_panel *innolux)

+static int innolux_panel_add(struct mipi_dsi_device *dsi,
+const struct panel_desc_dsi *desc)
  {
-   struct device *dev = >link->dev;
+   struct innolux_panel *innolux;
+   struct device *dev = >dev;
struct device_node *np;
int err;
  
-	innolux->supply = devm_regulator_get(dev, "power");

-   if (IS_ERR(innolux->supply))
-   return PTR_ERR(innolux->supply);
+   innolux = devm_kzalloc(dev, sizeof(*innolux), GFP_KERNEL);
+   if (!innolux)
+   return -ENOMEM;
+
+   innolux->dsi_desc = desc;
+   innolux->vddi = devm_regulator_get_optional(dev, "power");
+   if (IS_ERR(innolux->vddi))
+   return PTR_ERR(innolux->vddi);
+
+   innolux->avdd = devm_regulator_get(dev, "ppvarp");

This name ("ppvarp" and the "ppvarn" below) are names from our board
schematics, not from the panel datasheet. I would think these should be
"vdd" and "vee", like your variable names.

Okay, will fix it next version.


Brian


+   if (IS_ERR(innolux->avdd))
+   return PTR_ERR(innolux->avdd);
+
+   innolux->avee = devm_regulator_get(dev, "ppvarn");
+   if (IS_ERR(innolux->avee))
+   return PTR_ERR(innolux->avee);
  
  	innolux->enable_gpio = devm_gpiod_get_optional(dev, "enable",

   GPIOD_OUT_HIGH);

...








Re: [PATCH v2 2/2] devicetree: i2c-hid: Add reset property

2017-11-05 Thread hl



On Saturday, November 04, 2017 12:35 PM, Brian Norris wrote:

On Mon, Oct 30, 2017 at 8:03 PM, Lin Huang  wrote:

Document a "reset" and "assert-reset-us", it can be used for
driver control reset property. And reuse post-power-on-delay-ms
for deassert reset delay.

Signed-off-by: Lin Huang 
---
  Documentation/devicetree/bindings/input/hid-over-i2c.txt | 4 +++-
  1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/Documentation/devicetree/bindings/input/hid-over-i2c.txt 
b/Documentation/devicetree/bindings/input/hid-over-i2c.txt
index 28e8bd8..6ab0eed 100644
--- a/Documentation/devicetree/bindings/input/hid-over-i2c.txt
+++ b/Documentation/devicetree/bindings/input/hid-over-i2c.txt
@@ -31,7 +31,9 @@ device-specific compatible properties, which should be used 
in addition to the

  - vdd-supply: phandle of the regulator that provides the supply voltage.
  - post-power-on-delay-ms: time required by the device after enabling its 
regulators
-  before it is ready for communication. Must be used with 'vdd-supply'.
+  or deassert reset pin before it is ready for communication.
+- reset: phandle of the gpio that provides for hid reset pin.
+- assert-reset-us: the device require reset assert time.

If there was any point in adding the device-specific description
around "wacom,w9013"...then you should probably mention these
properties there too. The idea was to document possible properties
here (where you're adding them already), and to note the property
names under the devices (or so far, just 1 device) that support them.
Or IOW, you need an addition like this:

  - compatible:
* "wacom,w9013" (Wacom W9013 digitizer). Supports:
  - vdd-supply
  - post-power-on-delay-ms
+- reset-gpios
+- assert-reset-us

 Okay, got it, will fix it next version.


Brian








Re: [PATCH v2 2/2] devicetree: i2c-hid: Add reset property

2017-11-05 Thread hl



On Saturday, November 04, 2017 12:35 PM, Brian Norris wrote:

On Mon, Oct 30, 2017 at 8:03 PM, Lin Huang  wrote:

Document a "reset" and "assert-reset-us", it can be used for
driver control reset property. And reuse post-power-on-delay-ms
for deassert reset delay.

Signed-off-by: Lin Huang 
---
  Documentation/devicetree/bindings/input/hid-over-i2c.txt | 4 +++-
  1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/Documentation/devicetree/bindings/input/hid-over-i2c.txt 
b/Documentation/devicetree/bindings/input/hid-over-i2c.txt
index 28e8bd8..6ab0eed 100644
--- a/Documentation/devicetree/bindings/input/hid-over-i2c.txt
+++ b/Documentation/devicetree/bindings/input/hid-over-i2c.txt
@@ -31,7 +31,9 @@ device-specific compatible properties, which should be used 
in addition to the

  - vdd-supply: phandle of the regulator that provides the supply voltage.
  - post-power-on-delay-ms: time required by the device after enabling its 
regulators
-  before it is ready for communication. Must be used with 'vdd-supply'.
+  or deassert reset pin before it is ready for communication.
+- reset: phandle of the gpio that provides for hid reset pin.
+- assert-reset-us: the device require reset assert time.

If there was any point in adding the device-specific description
around "wacom,w9013"...then you should probably mention these
properties there too. The idea was to document possible properties
here (where you're adding them already), and to note the property
names under the devices (or so far, just 1 device) that support them.
Or IOW, you need an addition like this:

  - compatible:
* "wacom,w9013" (Wacom W9013 digitizer). Supports:
  - vdd-supply
  - post-power-on-delay-ms
+- reset-gpios
+- assert-reset-us

 Okay, got it, will fix it next version.


Brian








Re: [PATCH 1/7] drm/rockchip/dsi: correct Feedback divider setting

2017-09-20 Thread hl



On Wednesday, September 20, 2017 06:08 PM, John Keeping wrote:

On Tue, Sep 19, 2017 at 01:27:40PM -0700, Sean Paul wrote:

On Tue, Sep 19, 2017 at 11:19:01AM -0700, Brian Norris wrote:

Hi Sean,

On Tue, Sep 19, 2017 at 11:00:25AM -0700, Sean Paul wrote:

On Mon, Sep 18, 2017 at 05:05:33PM +0800, Nickey Yang wrote:

This patch correct Feedback divider setting:
1、Set Feedback divider [8:5] when HIGH_PROGRAM_EN
2、Due to the use of a "by 2 pre-scaler," the range of the
feedback multiplication Feedback divider is limited to even
division numbers, and Feedback divider must be greater than
12, less than 1000.
3、Make the previously configured Feedback divider(LSB)
factors effective

Signed-off-by: Nickey Yang 
---
  drivers/gpu/drm/rockchip/dw-mipi-dsi.c | 83 ++
  1 file changed, 54 insertions(+), 29 deletions(-)

diff --git a/drivers/gpu/drm/rockchip/dw-mipi-dsi.c 
b/drivers/gpu/drm/rockchip/dw-mipi-dsi.c
index 9a20b9d..52698b7 100644
--- a/drivers/gpu/drm/rockchip/dw-mipi-dsi.c
+++ b/drivers/gpu/drm/rockchip/dw-mipi-dsi.c
@@ -228,7 +228,7 @@
  #define LOW_PROGRAM_EN0
  #define HIGH_PROGRAM_EN   BIT(7)
  #define LOOP_DIV_LOW_SEL(val) (((val) - 1) & 0x1f)
-#define LOOP_DIV_HIGH_SEL(val) val) - 1) >> 5) & 0x1f)
+#define LOOP_DIV_HIGH_SEL(val) val) - 1) >> 5) & 0xf)
  #define PLL_LOOP_DIV_EN   BIT(5)
  #define PLL_INPUT_DIV_EN  BIT(4)
  
@@ -461,6 +461,7 @@ static int dw_mipi_dsi_phy_init(struct dw_mipi_dsi *dsi)

dw_mipi_dsi_phy_write(dsi, 0x17, INPUT_DIVIDER(dsi->input_div));
dw_mipi_dsi_phy_write(dsi, 0x18, LOOP_DIV_LOW_SEL(dsi->feedback_div) |
 LOW_PROGRAM_EN);
+   dw_mipi_dsi_phy_write(dsi, 0x19, PLL_LOOP_DIV_EN | PLL_INPUT_DIV_EN);

You do the same write 2 lines down. Are both needed? It would be nice if the
register names were also defined, so this is easier to read.

If I'm reading correctly, I think this is what Nickey meant by:

"3、Make the previously configured Feedback divider(LSB)
factors effective"

. My reading of the databook is that this step finalizes the previous
two writes (to test code 0x17 and 0x18).

Given this was buggy (?) previously, it does seem like having some extra
language to document this could help. Register names (or "test codes",
per the docs?) could help, but additionally, maybe a few more comments.


Ah, yeah, thanks for the explanation. It's not clear that this latches the
values above. I think register names and comments would be immensely helpful.

According to the databook, 0x19 controls whether the loop/input dividers
are derived from the hsfreqrange configuration or use the values in 0x17
and 0x18.  I can't see why writing the same value to this register
multiple times is necessary.
According to databook, set 0x19 to 0x30 make the previously configured 
N(0x17) and M(0x18)
factors effective, 0x18 need to be setted by twice, since we need to set 
0x18 LSB and MSB separately,
As we test, after set 0x18 LSB, if we do not set 0x19 immediately to 
make the configrued effective,
when we set 0x18 MSB, the 0x18 LSB value will gone, and we will get 
wrong pll frequency. Anyway,

I think should add some comment here to clear that.



dw_mipi_dsi_phy_write(dsi, 0x18, LOOP_DIV_HIGH_SEL(dsi->feedback_div) |
 HIGH_PROGRAM_EN);
dw_mipi_dsi_phy_write(dsi, 0x19, PLL_LOOP_DIV_EN | PLL_INPUT_DIV_EN);

[...]

___
Linux-rockchip mailing list
linux-rockc...@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-rockchip





Re: [PATCH 1/7] drm/rockchip/dsi: correct Feedback divider setting

2017-09-20 Thread hl



On Wednesday, September 20, 2017 06:08 PM, John Keeping wrote:

On Tue, Sep 19, 2017 at 01:27:40PM -0700, Sean Paul wrote:

On Tue, Sep 19, 2017 at 11:19:01AM -0700, Brian Norris wrote:

Hi Sean,

On Tue, Sep 19, 2017 at 11:00:25AM -0700, Sean Paul wrote:

On Mon, Sep 18, 2017 at 05:05:33PM +0800, Nickey Yang wrote:

This patch correct Feedback divider setting:
1、Set Feedback divider [8:5] when HIGH_PROGRAM_EN
2、Due to the use of a "by 2 pre-scaler," the range of the
feedback multiplication Feedback divider is limited to even
division numbers, and Feedback divider must be greater than
12, less than 1000.
3、Make the previously configured Feedback divider(LSB)
factors effective

Signed-off-by: Nickey Yang 
---
  drivers/gpu/drm/rockchip/dw-mipi-dsi.c | 83 ++
  1 file changed, 54 insertions(+), 29 deletions(-)

diff --git a/drivers/gpu/drm/rockchip/dw-mipi-dsi.c 
b/drivers/gpu/drm/rockchip/dw-mipi-dsi.c
index 9a20b9d..52698b7 100644
--- a/drivers/gpu/drm/rockchip/dw-mipi-dsi.c
+++ b/drivers/gpu/drm/rockchip/dw-mipi-dsi.c
@@ -228,7 +228,7 @@
  #define LOW_PROGRAM_EN0
  #define HIGH_PROGRAM_EN   BIT(7)
  #define LOOP_DIV_LOW_SEL(val) (((val) - 1) & 0x1f)
-#define LOOP_DIV_HIGH_SEL(val) val) - 1) >> 5) & 0x1f)
+#define LOOP_DIV_HIGH_SEL(val) val) - 1) >> 5) & 0xf)
  #define PLL_LOOP_DIV_EN   BIT(5)
  #define PLL_INPUT_DIV_EN  BIT(4)
  
@@ -461,6 +461,7 @@ static int dw_mipi_dsi_phy_init(struct dw_mipi_dsi *dsi)

dw_mipi_dsi_phy_write(dsi, 0x17, INPUT_DIVIDER(dsi->input_div));
dw_mipi_dsi_phy_write(dsi, 0x18, LOOP_DIV_LOW_SEL(dsi->feedback_div) |
 LOW_PROGRAM_EN);
+   dw_mipi_dsi_phy_write(dsi, 0x19, PLL_LOOP_DIV_EN | PLL_INPUT_DIV_EN);

You do the same write 2 lines down. Are both needed? It would be nice if the
register names were also defined, so this is easier to read.

If I'm reading correctly, I think this is what Nickey meant by:

"3、Make the previously configured Feedback divider(LSB)
factors effective"

. My reading of the databook is that this step finalizes the previous
two writes (to test code 0x17 and 0x18).

Given this was buggy (?) previously, it does seem like having some extra
language to document this could help. Register names (or "test codes",
per the docs?) could help, but additionally, maybe a few more comments.


Ah, yeah, thanks for the explanation. It's not clear that this latches the
values above. I think register names and comments would be immensely helpful.

According to the databook, 0x19 controls whether the loop/input dividers
are derived from the hsfreqrange configuration or use the values in 0x17
and 0x18.  I can't see why writing the same value to this register
multiple times is necessary.
According to databook, set 0x19 to 0x30 make the previously configured 
N(0x17) and M(0x18)
factors effective, 0x18 need to be setted by twice, since we need to set 
0x18 LSB and MSB separately,
As we test, after set 0x18 LSB, if we do not set 0x19 immediately to 
make the configrued effective,
when we set 0x18 MSB, the 0x18 LSB value will gone, and we will get 
wrong pll frequency. Anyway,

I think should add some comment here to clear that.



dw_mipi_dsi_phy_write(dsi, 0x18, LOOP_DIV_HIGH_SEL(dsi->feedback_div) |
 HIGH_PROGRAM_EN);
dw_mipi_dsi_phy_write(dsi, 0x19, PLL_LOOP_DIV_EN | PLL_INPUT_DIV_EN);

[...]

___
Linux-rockchip mailing list
linux-rockc...@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-rockchip





Re: [PATCH v2 1/2] ASoC: codec: use enable pin to control dmic start and stop

2017-09-04 Thread hl



On Monday, September 04, 2017 06:03 PM, Arnaud Pouliquen wrote:

Hello Lin,

Sorry for this late answer.
I'm not maintainer, just a contributor... but as some update seems
strange for me, so i prefer to highlight it to clarify them.

On 08/17/2017 04:24 AM, Lin Huang wrote:

From: huang lin 

on some board use enable pin to control dmic start and stop,
so add this feature in dmic driver.

Please, Could you give data-sheet reference of your DMIC, to help me
to understand your use-case?

Signed-off-by: Lin Huang 
---
  sound/soc/codecs/Kconfig |  2 +-
  sound/soc/codecs/dmic.c  | 46 ++
  2 files changed, 47 insertions(+), 1 deletion(-)

diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig
index 010811e..d98233b 100644
--- a/sound/soc/codecs/Kconfig
+++ b/sound/soc/codecs/Kconfig
@@ -71,7 +71,7 @@ config SND_SOC_ALL_CODECS
select SND_SOC_DA732X if I2C
select SND_SOC_DA9055 if I2C
select SND_SOC_DIO2125
-   select SND_SOC_DMIC
+   select SND_SOC_DMIC if GPIOLIB

Dependency also for DMIC without GPIO to handle gating?

select SND_SOC_ES8316 if I2C
select SND_SOC_ES8328_SPI if SPI_MASTER
select SND_SOC_ES8328_I2C if I2C
diff --git a/sound/soc/codecs/dmic.c b/sound/soc/codecs/dmic.c
index 12e07f9..b88a1ee 100644
--- a/sound/soc/codecs/dmic.c
+++ b/sound/soc/codecs/dmic.c
@@ -19,6 +19,8 @@
   *
   */
  
+#include 

+#include 
  #include 
  #include 
  #include 
@@ -27,6 +29,34 @@
  #include 
  #include 
  
+static int dmic_daiops_trigger(struct snd_pcm_substream *substream,

+   int cmd, struct snd_soc_dai *dai)
+{
+   struct gpio_desc *dmic_en = snd_soc_dai_get_drvdata(dai);
+
+   if (!dmic_en)
+   return 0;
+
+   switch (cmd) {
+   case SNDRV_PCM_TRIGGER_START:
+   case SNDRV_PCM_TRIGGER_RESUME:
+   case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
+   gpiod_set_value(dmic_en, 1);
+   break;
+   case SNDRV_PCM_TRIGGER_STOP:
+   case SNDRV_PCM_TRIGGER_SUSPEND:
+   case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
+   gpiod_set_value(dmic_en, 0);
+   break;
+   }
+
+   return 0;
+}
+
+static const struct snd_soc_dai_ops dmic_dai_ops = {
+   .trigger= dmic_daiops_trigger,
+};
+

should it be handle by trigger or DAPM?




  static struct snd_soc_dai_driver dmic_dai = {
.name = "dmic-hifi",
.capture = {
@@ -38,8 +68,23 @@ static struct snd_soc_dai_driver dmic_dai = {
| SNDRV_PCM_FMTBIT_S24_LE
| SNDRV_PCM_FMTBIT_S16_LE,
},
+   .ops= _dai_ops,
  };
  
+static int dmic_codec_probe(struct snd_soc_codec *codec)

+{
+   struct gpio_desc *dmic_en;
+
+   dmic_en = devm_gpiod_get_optional(codec->dev,
+   "dmicen", GPIOD_OUT_LOW);

Hypothesis here is that GPIO is always set to low? seems too limiting.
Yes, you are right, maybe i can set it to 
devm_gpiod_get_optional(codec->dev, "dmicen", GPIOD_ASIS);


Regards
Arnaud

+   if (IS_ERR(dmic_en))
+   return PTR_ERR(dmic_en);
+
+   snd_soc_codec_set_drvdata(codec, dmic_en);
+
+   return 0;
+}
+
  static const struct snd_soc_dapm_widget dmic_dapm_widgets[] = {
SND_SOC_DAPM_AIF_OUT("DMIC AIF", "Capture", 0,
 SND_SOC_NOPM, 0, 0),
@@ -51,6 +96,7 @@ static const struct snd_soc_dapm_route intercon[] = {
  };
  
  static const struct snd_soc_codec_driver soc_dmic = {

+   .probe = dmic_codec_probe,
.component_driver = {
.dapm_widgets   = dmic_dapm_widgets,
.num_dapm_widgets   = ARRAY_SIZE(dmic_dapm_widgets),









Re: [PATCH v2 1/2] ASoC: codec: use enable pin to control dmic start and stop

2017-09-04 Thread hl



On Monday, September 04, 2017 06:03 PM, Arnaud Pouliquen wrote:

Hello Lin,

Sorry for this late answer.
I'm not maintainer, just a contributor... but as some update seems
strange for me, so i prefer to highlight it to clarify them.

On 08/17/2017 04:24 AM, Lin Huang wrote:

From: huang lin 

on some board use enable pin to control dmic start and stop,
so add this feature in dmic driver.

Please, Could you give data-sheet reference of your DMIC, to help me
to understand your use-case?

Signed-off-by: Lin Huang 
---
  sound/soc/codecs/Kconfig |  2 +-
  sound/soc/codecs/dmic.c  | 46 ++
  2 files changed, 47 insertions(+), 1 deletion(-)

diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig
index 010811e..d98233b 100644
--- a/sound/soc/codecs/Kconfig
+++ b/sound/soc/codecs/Kconfig
@@ -71,7 +71,7 @@ config SND_SOC_ALL_CODECS
select SND_SOC_DA732X if I2C
select SND_SOC_DA9055 if I2C
select SND_SOC_DIO2125
-   select SND_SOC_DMIC
+   select SND_SOC_DMIC if GPIOLIB

Dependency also for DMIC without GPIO to handle gating?

select SND_SOC_ES8316 if I2C
select SND_SOC_ES8328_SPI if SPI_MASTER
select SND_SOC_ES8328_I2C if I2C
diff --git a/sound/soc/codecs/dmic.c b/sound/soc/codecs/dmic.c
index 12e07f9..b88a1ee 100644
--- a/sound/soc/codecs/dmic.c
+++ b/sound/soc/codecs/dmic.c
@@ -19,6 +19,8 @@
   *
   */
  
+#include 

+#include 
  #include 
  #include 
  #include 
@@ -27,6 +29,34 @@
  #include 
  #include 
  
+static int dmic_daiops_trigger(struct snd_pcm_substream *substream,

+   int cmd, struct snd_soc_dai *dai)
+{
+   struct gpio_desc *dmic_en = snd_soc_dai_get_drvdata(dai);
+
+   if (!dmic_en)
+   return 0;
+
+   switch (cmd) {
+   case SNDRV_PCM_TRIGGER_START:
+   case SNDRV_PCM_TRIGGER_RESUME:
+   case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
+   gpiod_set_value(dmic_en, 1);
+   break;
+   case SNDRV_PCM_TRIGGER_STOP:
+   case SNDRV_PCM_TRIGGER_SUSPEND:
+   case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
+   gpiod_set_value(dmic_en, 0);
+   break;
+   }
+
+   return 0;
+}
+
+static const struct snd_soc_dai_ops dmic_dai_ops = {
+   .trigger= dmic_daiops_trigger,
+};
+

should it be handle by trigger or DAPM?




  static struct snd_soc_dai_driver dmic_dai = {
.name = "dmic-hifi",
.capture = {
@@ -38,8 +68,23 @@ static struct snd_soc_dai_driver dmic_dai = {
| SNDRV_PCM_FMTBIT_S24_LE
| SNDRV_PCM_FMTBIT_S16_LE,
},
+   .ops= _dai_ops,
  };
  
+static int dmic_codec_probe(struct snd_soc_codec *codec)

+{
+   struct gpio_desc *dmic_en;
+
+   dmic_en = devm_gpiod_get_optional(codec->dev,
+   "dmicen", GPIOD_OUT_LOW);

Hypothesis here is that GPIO is always set to low? seems too limiting.
Yes, you are right, maybe i can set it to 
devm_gpiod_get_optional(codec->dev, "dmicen", GPIOD_ASIS);


Regards
Arnaud

+   if (IS_ERR(dmic_en))
+   return PTR_ERR(dmic_en);
+
+   snd_soc_codec_set_drvdata(codec, dmic_en);
+
+   return 0;
+}
+
  static const struct snd_soc_dapm_widget dmic_dapm_widgets[] = {
SND_SOC_DAPM_AIF_OUT("DMIC AIF", "Capture", 0,
 SND_SOC_NOPM, 0, 0),
@@ -51,6 +96,7 @@ static const struct snd_soc_dapm_route intercon[] = {
  };
  
  static const struct snd_soc_codec_driver soc_dmic = {

+   .probe = dmic_codec_probe,
.component_driver = {
.dapm_widgets   = dmic_dapm_widgets,
.num_dapm_widgets   = ARRAY_SIZE(dmic_dapm_widgets),









Re: [PATCH 1/2] ASoC: codec: use enable pin to control dmic start and stop

2017-08-16 Thread hl



On Wednesday, August 16, 2017 10:50 PM, Mark Brown wrote:

On Fri, Aug 11, 2017 at 03:31:28PM +0800, Lin Huang wrote:

on some board use enable pin to control dmic start and stop,
so add this feature in dmic driver.

This doens't apply against current code, please check and resend.

Oh, Thanks for pointing it, have send new version patches.




Re: [PATCH 1/2] ASoC: codec: use enable pin to control dmic start and stop

2017-08-16 Thread hl



On Wednesday, August 16, 2017 10:50 PM, Mark Brown wrote:

On Fri, Aug 11, 2017 at 03:31:28PM +0800, Lin Huang wrote:

on some board use enable pin to control dmic start and stop,
so add this feature in dmic driver.

This doens't apply against current code, please check and resend.

Oh, Thanks for pointing it, have send new version patches.




Re: [PATCH] clk: rockchip: fix the incorrect pclk_edp div width for RK3399

2017-01-17 Thread hl

Tested-by: Lin Huang 

On 2017年01月18日 12:20, Xing Zheng wrote:

The range of the  pclk_edp_div_con is [13:8] and 6 bits, not 5.

Reported-by: Lin Huang 
Signed-off-by: Xing Zheng 
---

  drivers/clk/rockchip/clk-rk3399.c | 2 +-
  1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/clk/rockchip/clk-rk3399.c 
b/drivers/clk/rockchip/clk-rk3399.c
index 3490887..73121b14 100644
--- a/drivers/clk/rockchip/clk-rk3399.c
+++ b/drivers/clk/rockchip/clk-rk3399.c
@@ -1132,7 +1132,7 @@ static struct rockchip_clk_branch rk3399_clk_branches[] 
__initdata = {
RK3399_CLKGATE_CON(11), 8, GFLAGS),
  
  	COMPOSITE(PCLK_EDP, "pclk_edp", mux_pll_src_cpll_gpll_p, 0,

-   RK3399_CLKSEL_CON(44), 15, 1, MFLAGS, 8, 5, DFLAGS,
+   RK3399_CLKSEL_CON(44), 15, 1, MFLAGS, 8, 6, DFLAGS,
RK3399_CLKGATE_CON(11), 11, GFLAGS),
GATE(PCLK_EDP_NOC, "pclk_edp_noc", "pclk_edp", CLK_IGNORE_UNUSED,
RK3399_CLKGATE_CON(32), 12, GFLAGS),


--
Lin Huang




Re: [PATCH] clk: rockchip: fix the incorrect pclk_edp div width for RK3399

2017-01-17 Thread hl

Tested-by: Lin Huang 

On 2017年01月18日 12:20, Xing Zheng wrote:

The range of the  pclk_edp_div_con is [13:8] and 6 bits, not 5.

Reported-by: Lin Huang 
Signed-off-by: Xing Zheng 
---

  drivers/clk/rockchip/clk-rk3399.c | 2 +-
  1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/clk/rockchip/clk-rk3399.c 
b/drivers/clk/rockchip/clk-rk3399.c
index 3490887..73121b14 100644
--- a/drivers/clk/rockchip/clk-rk3399.c
+++ b/drivers/clk/rockchip/clk-rk3399.c
@@ -1132,7 +1132,7 @@ static struct rockchip_clk_branch rk3399_clk_branches[] 
__initdata = {
RK3399_CLKGATE_CON(11), 8, GFLAGS),
  
  	COMPOSITE(PCLK_EDP, "pclk_edp", mux_pll_src_cpll_gpll_p, 0,

-   RK3399_CLKSEL_CON(44), 15, 1, MFLAGS, 8, 5, DFLAGS,
+   RK3399_CLKSEL_CON(44), 15, 1, MFLAGS, 8, 6, DFLAGS,
RK3399_CLKGATE_CON(11), 11, GFLAGS),
GATE(PCLK_EDP_NOC, "pclk_edp_noc", "pclk_edp", CLK_IGNORE_UNUSED,
RK3399_CLKGATE_CON(32), 12, GFLAGS),


--
Lin Huang




Re: [PATCH v1 & v6 1/2] PM/devfreq: add suspend frequency support

2016-11-24 Thread hl

Hi Chanwoo Choi,


On 2016年11月24日 16:16, Chanwoo Choi wrote:

Hi Lin,

On 2016년 11월 24일 16:34, hl wrote:

Hi Chanwoo Choi,

 I think the dev_pm_opp_get_suspend_opp() have implement most of
the funtion, all we need is just define the node in dts, like following:

_opp_table {
 opp06 {
 opp-suspend;
 };
};

Two approaches use the 'opp-suspend' property.

I think that the method to support suspend-opp have to
guarantee following conditions:
- Support the all of devfreq's governors.
As MyungJoo Ham suggestion, i will set the suspend frequency in 
devfreq_suspend_device(),

which will ingore governor.

- Devfreq framework have the responsibility to change the
   frequency/voltage for suspend-opp. If we uses the
   new devfreq_suspend(), each devfreq device don't care
   how to support the suspend-opp. Just the developer of each
   devfreq device need to add 'opp-suspend' propet to OPP entry in DT file.
Why should support change the voltage in devfreq framework, i think it 
shuold be handle in
specific driver, i think the devfreq only handle it can get the right 
frequency, then pass it to
specific driver, i think the voltage should handle in the 
devfreq->profile->target();

Best Regards,
Chanwoo Choi


so i think my way semm more simple.

On 2016年11月24日 15:10, Chanwoo Choi wrote:

+ Tobias Jakobi,

Hi Lin,

We need to discuss how to support the suspend-opp of devfreq device.
Now, there are two patch thread for suspend-opp of devfreq.

The Lin's approach modify the devfreq_suspend_device() to support suspend-opp.
The Tobias's approach[1] add new devfreq_suspend() and then call it on 
dpm_suspend()
when entering the suspend state.

[1] [RFC 0/4] PM / devfreq: draft for OPP suspend impl
- https://patchwork.kernel.org/patch/9443323/
- https://patchwork.kernel.org/patch/9443325/
- https://patchwork.kernel.org/patch/9443329/
- https://patchwork.kernel.org/patch/9443331/

I think we need to discuss it together.

Regards,
Chanwoo Choi

On 2016년 11월 24일 15:45, hl wrote:

Hi MyungJoo Ham,

On 2016年11月24日 14:14, MyungJoo Ham wrote:

On Thu, Nov 24, 2016 at 11:18 AM, hl <h...@rock-chips.com> wrote:

Hi MyungJoo Ham,

[]

We still need to sync the all status even i call target() in
devfreq_suspend/resume_device
directly, so still need update_devfreq() other setp except
devfreq->governor->get_target_freq(devfreq, );

And i think it better to be governor behaviors, for userspace they may not
want to change
the suspend frequency like other governor, the frequency should decide by
the user, if they
want this function, they should like other governor to rigister a
devfreq_monitor_suspend().
What do you think about my rev6 patch?

If I understand the intention correctly, this is for the stability of
the device due to the behavior or bootloader/SoC-initializer, which
has nothing to do with governors.

Even if users are using userspace, as long as they set the custom
frequencies lower than the default, they have the possibility of
being unstable as ondemand is going to have.


To reuse the update_devfreq() code, you may do something like:

static int _update_freq(struct devfreq *devfreq, bool is_suspending)
{
  /* original contents of update_freq with if statement with is_suspending 
wrapping get_target_freq */
}
int update_freq(struct devfreq *devfreq)
{
 return _update_freq(devfreq, false);
}


There should be other good non-invasive methods that are not governoe-specific 
as well.


Thanks for your suggestion, i will update the new version soon.

Cheers,
MyungJoo




___
Linux-rockchip mailing list
linux-rockc...@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-rockchip

--
Lin Huang










--
Lin Huang




Re: [PATCH v1 & v6 1/2] PM/devfreq: add suspend frequency support

2016-11-24 Thread hl

Hi Chanwoo Choi,


On 2016年11月24日 16:16, Chanwoo Choi wrote:

Hi Lin,

On 2016년 11월 24일 16:34, hl wrote:

Hi Chanwoo Choi,

 I think the dev_pm_opp_get_suspend_opp() have implement most of
the funtion, all we need is just define the node in dts, like following:

_opp_table {
 opp06 {
 opp-suspend;
 };
};

Two approaches use the 'opp-suspend' property.

I think that the method to support suspend-opp have to
guarantee following conditions:
- Support the all of devfreq's governors.
As MyungJoo Ham suggestion, i will set the suspend frequency in 
devfreq_suspend_device(),

which will ingore governor.

- Devfreq framework have the responsibility to change the
   frequency/voltage for suspend-opp. If we uses the
   new devfreq_suspend(), each devfreq device don't care
   how to support the suspend-opp. Just the developer of each
   devfreq device need to add 'opp-suspend' propet to OPP entry in DT file.
Why should support change the voltage in devfreq framework, i think it 
shuold be handle in
specific driver, i think the devfreq only handle it can get the right 
frequency, then pass it to
specific driver, i think the voltage should handle in the 
devfreq->profile->target();

Best Regards,
Chanwoo Choi


so i think my way semm more simple.

On 2016年11月24日 15:10, Chanwoo Choi wrote:

+ Tobias Jakobi,

Hi Lin,

We need to discuss how to support the suspend-opp of devfreq device.
Now, there are two patch thread for suspend-opp of devfreq.

The Lin's approach modify the devfreq_suspend_device() to support suspend-opp.
The Tobias's approach[1] add new devfreq_suspend() and then call it on 
dpm_suspend()
when entering the suspend state.

[1] [RFC 0/4] PM / devfreq: draft for OPP suspend impl
- https://patchwork.kernel.org/patch/9443323/
- https://patchwork.kernel.org/patch/9443325/
- https://patchwork.kernel.org/patch/9443329/
- https://patchwork.kernel.org/patch/9443331/

I think we need to discuss it together.

Regards,
Chanwoo Choi

On 2016년 11월 24일 15:45, hl wrote:

Hi MyungJoo Ham,

On 2016年11月24日 14:14, MyungJoo Ham wrote:

On Thu, Nov 24, 2016 at 11:18 AM, hl  wrote:

Hi MyungJoo Ham,

[]

We still need to sync the all status even i call target() in
devfreq_suspend/resume_device
directly, so still need update_devfreq() other setp except
devfreq->governor->get_target_freq(devfreq, );

And i think it better to be governor behaviors, for userspace they may not
want to change
the suspend frequency like other governor, the frequency should decide by
the user, if they
want this function, they should like other governor to rigister a
devfreq_monitor_suspend().
What do you think about my rev6 patch?

If I understand the intention correctly, this is for the stability of
the device due to the behavior or bootloader/SoC-initializer, which
has nothing to do with governors.

Even if users are using userspace, as long as they set the custom
frequencies lower than the default, they have the possibility of
being unstable as ondemand is going to have.


To reuse the update_devfreq() code, you may do something like:

static int _update_freq(struct devfreq *devfreq, bool is_suspending)
{
  /* original contents of update_freq with if statement with is_suspending 
wrapping get_target_freq */
}
int update_freq(struct devfreq *devfreq)
{
 return _update_freq(devfreq, false);
}


There should be other good non-invasive methods that are not governoe-specific 
as well.


Thanks for your suggestion, i will update the new version soon.

Cheers,
MyungJoo




___
Linux-rockchip mailing list
linux-rockc...@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-rockchip

--
Lin Huang










--
Lin Huang




Re: [PATCH v1 & v6 1/2] PM/devfreq: add suspend frequency support

2016-11-23 Thread hl

Hi Chanwoo Choi,

I think the dev_pm_opp_get_suspend_opp() have implement most of
the funtion, all we need is just define the node in dts, like following:

_opp_table {
opp06 {
opp-suspend;
};
};

so i think my way semm more simple.

On 2016年11月24日 15:10, Chanwoo Choi wrote:

+ Tobias Jakobi,

Hi Lin,

We need to discuss how to support the suspend-opp of devfreq device.
Now, there are two patch thread for suspend-opp of devfreq.

The Lin's approach modify the devfreq_suspend_device() to support suspend-opp.
The Tobias's approach[1] add new devfreq_suspend() and then call it on 
dpm_suspend()
when entering the suspend state.

[1] [RFC 0/4] PM / devfreq: draft for OPP suspend impl
- https://patchwork.kernel.org/patch/9443323/
- https://patchwork.kernel.org/patch/9443325/
- https://patchwork.kernel.org/patch/9443329/
- https://patchwork.kernel.org/patch/9443331/

I think we need to discuss it together.

Regards,
Chanwoo Choi

On 2016년 11월 24일 15:45, hl wrote:

Hi MyungJoo Ham,

On 2016年11月24日 14:14, MyungJoo Ham wrote:

On Thu, Nov 24, 2016 at 11:18 AM, hl <h...@rock-chips.com> wrote:

Hi MyungJoo Ham,

[]

We still need to sync the all status even i call target() in
devfreq_suspend/resume_device
directly, so still need update_devfreq() other setp except
devfreq->governor->get_target_freq(devfreq, );

And i think it better to be governor behaviors, for userspace they may not
want to change
the suspend frequency like other governor, the frequency should decide by
the user, if they
want this function, they should like other governor to rigister a
devfreq_monitor_suspend().
What do you think about my rev6 patch?

If I understand the intention correctly, this is for the stability of
the device due to the behavior or bootloader/SoC-initializer, which
has nothing to do with governors.

Even if users are using userspace, as long as they set the custom
frequencies lower than the default, they have the possibility of
being unstable as ondemand is going to have.


To reuse the update_devfreq() code, you may do something like:

static int _update_freq(struct devfreq *devfreq, bool is_suspending)
{
 /* original contents of update_freq with if statement with is_suspending 
wrapping get_target_freq */
}
int update_freq(struct devfreq *devfreq)
{
return _update_freq(devfreq, false);
}


There should be other good non-invasive methods that are not governoe-specific 
as well.


Thanks for your suggestion, i will update the new version soon.

Cheers,
MyungJoo




___
Linux-rockchip mailing list
linux-rockc...@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-rockchip

--
Lin Huang







--
Lin Huang




Re: [PATCH v1 & v6 1/2] PM/devfreq: add suspend frequency support

2016-11-23 Thread hl

Hi Chanwoo Choi,

I think the dev_pm_opp_get_suspend_opp() have implement most of
the funtion, all we need is just define the node in dts, like following:

_opp_table {
opp06 {
opp-suspend;
};
};

so i think my way semm more simple.

On 2016年11月24日 15:10, Chanwoo Choi wrote:

+ Tobias Jakobi,

Hi Lin,

We need to discuss how to support the suspend-opp of devfreq device.
Now, there are two patch thread for suspend-opp of devfreq.

The Lin's approach modify the devfreq_suspend_device() to support suspend-opp.
The Tobias's approach[1] add new devfreq_suspend() and then call it on 
dpm_suspend()
when entering the suspend state.

[1] [RFC 0/4] PM / devfreq: draft for OPP suspend impl
- https://patchwork.kernel.org/patch/9443323/
- https://patchwork.kernel.org/patch/9443325/
- https://patchwork.kernel.org/patch/9443329/
- https://patchwork.kernel.org/patch/9443331/

I think we need to discuss it together.

Regards,
Chanwoo Choi

On 2016년 11월 24일 15:45, hl wrote:

Hi MyungJoo Ham,

On 2016年11月24日 14:14, MyungJoo Ham wrote:

On Thu, Nov 24, 2016 at 11:18 AM, hl  wrote:

Hi MyungJoo Ham,

[]

We still need to sync the all status even i call target() in
devfreq_suspend/resume_device
directly, so still need update_devfreq() other setp except
devfreq->governor->get_target_freq(devfreq, );

And i think it better to be governor behaviors, for userspace they may not
want to change
the suspend frequency like other governor, the frequency should decide by
the user, if they
want this function, they should like other governor to rigister a
devfreq_monitor_suspend().
What do you think about my rev6 patch?

If I understand the intention correctly, this is for the stability of
the device due to the behavior or bootloader/SoC-initializer, which
has nothing to do with governors.

Even if users are using userspace, as long as they set the custom
frequencies lower than the default, they have the possibility of
being unstable as ondemand is going to have.


To reuse the update_devfreq() code, you may do something like:

static int _update_freq(struct devfreq *devfreq, bool is_suspending)
{
 /* original contents of update_freq with if statement with is_suspending 
wrapping get_target_freq */
}
int update_freq(struct devfreq *devfreq)
{
return _update_freq(devfreq, false);
}


There should be other good non-invasive methods that are not governoe-specific 
as well.


Thanks for your suggestion, i will update the new version soon.

Cheers,
MyungJoo




___
Linux-rockchip mailing list
linux-rockc...@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-rockchip

--
Lin Huang







--
Lin Huang




Re: [PATCH v4] PM/devfreq: add suspend frequency support

2016-11-08 Thread hl

Hi Chanwoo Choi,

On 2016年11月08日 17:32, Chanwoo Choi wrote:

Hi Lin,

On 2016년 11월 08일 18:11, Lin Huang wrote:

Add suspend frequency support and if needed set it to
the frequency obtained from the suspend opp (can be defined
using opp-v2 bindings and is optional).

Signed-off-by: Lin Huang 
---
Changes in v2:
- use update_devfreq() instead devfreq_update_status()
Changes in v3:
- fix build error
Changes in v4:
- move dev_pm_opp_get_suspend_opp() to devfreq_add_device()

  drivers/devfreq/devfreq.c | 15 +--
  drivers/devfreq/governor_simpleondemand.c |  9 +
  include/linux/devfreq.h   |  9 +
  3 files changed, 31 insertions(+), 2 deletions(-)

diff --git a/drivers/devfreq/devfreq.c b/drivers/devfreq/devfreq.c
index bf3ea76..d9d56e1 100644
--- a/drivers/devfreq/devfreq.c
+++ b/drivers/devfreq/devfreq.c
@@ -363,7 +363,10 @@ void devfreq_monitor_suspend(struct devfreq *devfreq)
mutex_unlock(>lock);
return;
}
-
+   if (devfreq->suspend_freq) {
+   update_devfreq(devfreq);
+   devfreq->suspend_flag = true;

You don't need the additional variable (devfreq->suspend_flag).
When adding the devfreq on devfreq_add_device(),
you can initialize the devfreq->suspend_freq as zero(0).

You can check whether devfreq->suspend_freq is 0 or not
without the new suspend_flag.


+   }
devfreq_update_status(devfreq, devfreq->previous_freq);
devfreq->stop_polling = true;
mutex_unlock(>lock);
@@ -394,7 +397,8 @@ void devfreq_monitor_resume(struct devfreq *devfreq)
  
  	devfreq->last_stat_updated = jiffies;

devfreq->stop_polling = false;
-
+   if (devfreq->suspend_freq)
+   devfreq->suspend_flag = false;

ditto. You don't need to add this code.


if (devfreq->profile->get_cur_freq &&
!devfreq->profile->get_cur_freq(devfreq->dev.parent, ))
devfreq->previous_freq = freq;
@@ -528,6 +532,7 @@ struct devfreq *devfreq_add_device(struct device *dev,
struct devfreq *devfreq;
struct devfreq_governor *governor;
int err = 0;
+   struct dev_pm_opp *suspend_opp;
  
  	if (!dev || !profile || !governor_name) {

dev_err(dev, "%s: Invalid parameters.\n", __func__);
@@ -563,6 +568,12 @@ struct devfreq *devfreq_add_device(struct device *dev,
devfreq->data = data;
devfreq->nb.notifier_call = devfreq_notifier_call;
  
+	rcu_read_lock();

+   suspend_opp = dev_pm_opp_get_suspend_opp(dev);
+   if (suspend_opp)
+   devfreq->suspend_freq = dev_pm_opp_get_freq(suspend_opp);
+   rcu_read_unlock();
+
if (!devfreq->profile->max_state && !devfreq->profile->freq_table) {
mutex_unlock(>lock);
devfreq_set_freq_table(devfreq);
diff --git a/drivers/devfreq/governor_simpleondemand.c 
b/drivers/devfreq/governor_simpleondemand.c
index ae72ba5..84b3ce1 100644
--- a/drivers/devfreq/governor_simpleondemand.c
+++ b/drivers/devfreq/governor_simpleondemand.c
@@ -29,6 +29,15 @@ static int devfreq_simple_ondemand_func(struct devfreq *df,
struct devfreq_simple_ondemand_data *data = df->data;
unsigned long max = (df->max_freq) ? df->max_freq : UINT_MAX;
  
+	/*

+* if devfreq in suspend status and have suspend_freq,
+* the frequency need to set to suspend_freq
+*/
+   if (df->suspend_flag) {
+   *freq = df->suspend_freq;
+   return 0;
+   }

You can check it as following:

if (df->suspend_freq != 0)
*freq = df->suspend_freq;
If i do like this, it will always return suspend frequency, since 
devfreq->suspend_freq will be assigned value
if we define it on dts. But what we want is only in suspend status we 
return the suspend frequency.



+
err = devfreq_update_stats(df);
if (err)
return err;
diff --git a/include/linux/devfreq.h b/include/linux/devfreq.h
index 2de4e2e..c463ae1 100644
--- a/include/linux/devfreq.h
+++ b/include/linux/devfreq.h
@@ -172,6 +172,7 @@ struct devfreq {
struct delayed_work work;
  
  	unsigned long previous_freq;

+   unsigned long suspend_freq;
struct devfreq_dev_status last_status;
  
  	void *data; /* private data for governors */

@@ -179,6 +180,7 @@ struct devfreq {
unsigned long min_freq;
unsigned long max_freq;
bool stop_polling;
+   bool suspend_flag;

You don't need to add new variable.

  
  	/* information for device frequency transition */

unsigned int total_trans;
@@ -214,6 +216,8 @@ extern int devfreq_resume_device(struct devfreq *devfreq);
  /* Helper functions for devfreq user device driver with OPP. */
  extern struct dev_pm_opp *devfreq_recommended_opp(struct device *dev,
   unsigned long *freq, u32 flags);
+extern void devfreq_opp_get_suspend_opp(struct 

Re: [PATCH v4] PM/devfreq: add suspend frequency support

2016-11-08 Thread hl

Hi Chanwoo Choi,

On 2016年11月08日 17:32, Chanwoo Choi wrote:

Hi Lin,

On 2016년 11월 08일 18:11, Lin Huang wrote:

Add suspend frequency support and if needed set it to
the frequency obtained from the suspend opp (can be defined
using opp-v2 bindings and is optional).

Signed-off-by: Lin Huang 
---
Changes in v2:
- use update_devfreq() instead devfreq_update_status()
Changes in v3:
- fix build error
Changes in v4:
- move dev_pm_opp_get_suspend_opp() to devfreq_add_device()

  drivers/devfreq/devfreq.c | 15 +--
  drivers/devfreq/governor_simpleondemand.c |  9 +
  include/linux/devfreq.h   |  9 +
  3 files changed, 31 insertions(+), 2 deletions(-)

diff --git a/drivers/devfreq/devfreq.c b/drivers/devfreq/devfreq.c
index bf3ea76..d9d56e1 100644
--- a/drivers/devfreq/devfreq.c
+++ b/drivers/devfreq/devfreq.c
@@ -363,7 +363,10 @@ void devfreq_monitor_suspend(struct devfreq *devfreq)
mutex_unlock(>lock);
return;
}
-
+   if (devfreq->suspend_freq) {
+   update_devfreq(devfreq);
+   devfreq->suspend_flag = true;

You don't need the additional variable (devfreq->suspend_flag).
When adding the devfreq on devfreq_add_device(),
you can initialize the devfreq->suspend_freq as zero(0).

You can check whether devfreq->suspend_freq is 0 or not
without the new suspend_flag.


+   }
devfreq_update_status(devfreq, devfreq->previous_freq);
devfreq->stop_polling = true;
mutex_unlock(>lock);
@@ -394,7 +397,8 @@ void devfreq_monitor_resume(struct devfreq *devfreq)
  
  	devfreq->last_stat_updated = jiffies;

devfreq->stop_polling = false;
-
+   if (devfreq->suspend_freq)
+   devfreq->suspend_flag = false;

ditto. You don't need to add this code.


if (devfreq->profile->get_cur_freq &&
!devfreq->profile->get_cur_freq(devfreq->dev.parent, ))
devfreq->previous_freq = freq;
@@ -528,6 +532,7 @@ struct devfreq *devfreq_add_device(struct device *dev,
struct devfreq *devfreq;
struct devfreq_governor *governor;
int err = 0;
+   struct dev_pm_opp *suspend_opp;
  
  	if (!dev || !profile || !governor_name) {

dev_err(dev, "%s: Invalid parameters.\n", __func__);
@@ -563,6 +568,12 @@ struct devfreq *devfreq_add_device(struct device *dev,
devfreq->data = data;
devfreq->nb.notifier_call = devfreq_notifier_call;
  
+	rcu_read_lock();

+   suspend_opp = dev_pm_opp_get_suspend_opp(dev);
+   if (suspend_opp)
+   devfreq->suspend_freq = dev_pm_opp_get_freq(suspend_opp);
+   rcu_read_unlock();
+
if (!devfreq->profile->max_state && !devfreq->profile->freq_table) {
mutex_unlock(>lock);
devfreq_set_freq_table(devfreq);
diff --git a/drivers/devfreq/governor_simpleondemand.c 
b/drivers/devfreq/governor_simpleondemand.c
index ae72ba5..84b3ce1 100644
--- a/drivers/devfreq/governor_simpleondemand.c
+++ b/drivers/devfreq/governor_simpleondemand.c
@@ -29,6 +29,15 @@ static int devfreq_simple_ondemand_func(struct devfreq *df,
struct devfreq_simple_ondemand_data *data = df->data;
unsigned long max = (df->max_freq) ? df->max_freq : UINT_MAX;
  
+	/*

+* if devfreq in suspend status and have suspend_freq,
+* the frequency need to set to suspend_freq
+*/
+   if (df->suspend_flag) {
+   *freq = df->suspend_freq;
+   return 0;
+   }

You can check it as following:

if (df->suspend_freq != 0)
*freq = df->suspend_freq;
If i do like this, it will always return suspend frequency, since 
devfreq->suspend_freq will be assigned value
if we define it on dts. But what we want is only in suspend status we 
return the suspend frequency.



+
err = devfreq_update_stats(df);
if (err)
return err;
diff --git a/include/linux/devfreq.h b/include/linux/devfreq.h
index 2de4e2e..c463ae1 100644
--- a/include/linux/devfreq.h
+++ b/include/linux/devfreq.h
@@ -172,6 +172,7 @@ struct devfreq {
struct delayed_work work;
  
  	unsigned long previous_freq;

+   unsigned long suspend_freq;
struct devfreq_dev_status last_status;
  
  	void *data; /* private data for governors */

@@ -179,6 +180,7 @@ struct devfreq {
unsigned long min_freq;
unsigned long max_freq;
bool stop_polling;
+   bool suspend_flag;

You don't need to add new variable.

  
  	/* information for device frequency transition */

unsigned int total_trans;
@@ -214,6 +216,8 @@ extern int devfreq_resume_device(struct devfreq *devfreq);
  /* Helper functions for devfreq user device driver with OPP. */
  extern struct dev_pm_opp *devfreq_recommended_opp(struct device *dev,
   unsigned long *freq, u32 flags);
+extern void devfreq_opp_get_suspend_opp(struct device *dev,
+

Re: [PATCH v2 1/2] PM/devfreq: add suspend frequency support

2016-11-03 Thread hl

Hi All,
Miss something in this patch, just ignored it, sorry about that.

On 2016年11月03日 14:16, Lin Huang wrote:

Add suspend frequency support and if needed set it to
the frequency obtained from the suspend opp (can be defined
using opp-v2 bindings and is optional).

Change-Id: Iaa0d3848d63d9ce03f65ea76f263e4685a4c295e
Signed-off-by: Lin Huang 
---
Changes in v2:
- use update_devfreq() instead devfreq_update_status()

  drivers/devfreq/devfreq.c | 17 -
  include/linux/devfreq.h   |  9 +
  2 files changed, 25 insertions(+), 1 deletion(-)

diff --git a/drivers/devfreq/devfreq.c b/drivers/devfreq/devfreq.c
index bf3ea76..0a76282 100644
--- a/drivers/devfreq/devfreq.c
+++ b/drivers/devfreq/devfreq.c
@@ -364,7 +364,10 @@ void devfreq_monitor_suspend(struct devfreq *devfreq)
return;
}
  
-	devfreq_update_status(devfreq, devfreq->previous_freq);

+   if (devfreq->suspend_freq)
+   update_devfreq(devfreq, devfreq->suspend_freq);
+   else
+   devfreq_update_status(devfreq, devfreq->previous_freq);
devfreq->stop_polling = true;
mutex_unlock(>lock);
cancel_delayed_work_sync(>work);
@@ -1251,6 +1254,18 @@ struct dev_pm_opp *devfreq_recommended_opp(struct device 
*dev,
  }
  EXPORT_SYMBOL(devfreq_recommended_opp);
  
+void devfreq_opp_get_suspend_opp(struct device *dev, struct devfreq *devfreq)

+{
+   struct dev_pm_opp *suspend_opp;
+
+   rcu_read_lock();
+   suspend_opp = dev_pm_opp_get_suspend_opp(dev);
+   if (suspend_opp)
+   devfreq->suspend_freq = dev_pm_opp_get_freq(suspend_opp);
+   rcu_read_unlock();
+}
+EXPORT_SYMBOL(devfreq_opp_get_suspend_opp);
+
  /**
   * devfreq_register_opp_notifier() - Helper function to get devfreq notified
   *   for any changes in the OPP availability
diff --git a/include/linux/devfreq.h b/include/linux/devfreq.h
index 2de4e2e..c785ad9 100644
--- a/include/linux/devfreq.h
+++ b/include/linux/devfreq.h
@@ -88,6 +88,7 @@ struct devfreq_dev_status {
   */
  struct devfreq_dev_profile {
unsigned long initial_freq;
+   unsigned long suspend_freq;
unsigned int polling_ms;
  
  	int (*target)(struct device *dev, unsigned long *freq, u32 flags);

@@ -172,6 +173,7 @@ struct devfreq {
struct delayed_work work;
  
  	unsigned long previous_freq;

+   unsigned long suspend_freq;
struct devfreq_dev_status last_status;
  
  	void *data; /* private data for governors */

@@ -214,6 +216,8 @@ extern void devm_devfreq_remove_device(struct device *dev,
  /* Helper functions for devfreq user device driver with OPP. */
  extern struct dev_pm_opp *devfreq_recommended_opp(struct device *dev,
   unsigned long *freq, u32 flags);
+extern void devfreq_opp_get_suspend_opp(struct device *dev,
+   struct devfreq *devfreq);
  extern int devfreq_register_opp_notifier(struct device *dev,
 struct devfreq *devfreq);
  extern int devfreq_unregister_opp_notifier(struct device *dev,
@@ -348,6 +352,11 @@ static inline struct dev_pm_opp 
*devfreq_recommended_opp(struct device *dev,
return ERR_PTR(-EINVAL);
  }
  
+static inline void devfreq_opp_get_suspend_opp(struct device *dev,

+  struct devfreq *devfreq)
+{
+}
+
  static inline int devfreq_register_opp_notifier(struct device *dev,
 struct devfreq *devfreq)
  {


--
Lin Huang




Re: [PATCH v2 1/2] PM/devfreq: add suspend frequency support

2016-11-03 Thread hl

Hi All,
Miss something in this patch, just ignored it, sorry about that.

On 2016年11月03日 14:16, Lin Huang wrote:

Add suspend frequency support and if needed set it to
the frequency obtained from the suspend opp (can be defined
using opp-v2 bindings and is optional).

Change-Id: Iaa0d3848d63d9ce03f65ea76f263e4685a4c295e
Signed-off-by: Lin Huang 
---
Changes in v2:
- use update_devfreq() instead devfreq_update_status()

  drivers/devfreq/devfreq.c | 17 -
  include/linux/devfreq.h   |  9 +
  2 files changed, 25 insertions(+), 1 deletion(-)

diff --git a/drivers/devfreq/devfreq.c b/drivers/devfreq/devfreq.c
index bf3ea76..0a76282 100644
--- a/drivers/devfreq/devfreq.c
+++ b/drivers/devfreq/devfreq.c
@@ -364,7 +364,10 @@ void devfreq_monitor_suspend(struct devfreq *devfreq)
return;
}
  
-	devfreq_update_status(devfreq, devfreq->previous_freq);

+   if (devfreq->suspend_freq)
+   update_devfreq(devfreq, devfreq->suspend_freq);
+   else
+   devfreq_update_status(devfreq, devfreq->previous_freq);
devfreq->stop_polling = true;
mutex_unlock(>lock);
cancel_delayed_work_sync(>work);
@@ -1251,6 +1254,18 @@ struct dev_pm_opp *devfreq_recommended_opp(struct device 
*dev,
  }
  EXPORT_SYMBOL(devfreq_recommended_opp);
  
+void devfreq_opp_get_suspend_opp(struct device *dev, struct devfreq *devfreq)

+{
+   struct dev_pm_opp *suspend_opp;
+
+   rcu_read_lock();
+   suspend_opp = dev_pm_opp_get_suspend_opp(dev);
+   if (suspend_opp)
+   devfreq->suspend_freq = dev_pm_opp_get_freq(suspend_opp);
+   rcu_read_unlock();
+}
+EXPORT_SYMBOL(devfreq_opp_get_suspend_opp);
+
  /**
   * devfreq_register_opp_notifier() - Helper function to get devfreq notified
   *   for any changes in the OPP availability
diff --git a/include/linux/devfreq.h b/include/linux/devfreq.h
index 2de4e2e..c785ad9 100644
--- a/include/linux/devfreq.h
+++ b/include/linux/devfreq.h
@@ -88,6 +88,7 @@ struct devfreq_dev_status {
   */
  struct devfreq_dev_profile {
unsigned long initial_freq;
+   unsigned long suspend_freq;
unsigned int polling_ms;
  
  	int (*target)(struct device *dev, unsigned long *freq, u32 flags);

@@ -172,6 +173,7 @@ struct devfreq {
struct delayed_work work;
  
  	unsigned long previous_freq;

+   unsigned long suspend_freq;
struct devfreq_dev_status last_status;
  
  	void *data; /* private data for governors */

@@ -214,6 +216,8 @@ extern void devm_devfreq_remove_device(struct device *dev,
  /* Helper functions for devfreq user device driver with OPP. */
  extern struct dev_pm_opp *devfreq_recommended_opp(struct device *dev,
   unsigned long *freq, u32 flags);
+extern void devfreq_opp_get_suspend_opp(struct device *dev,
+   struct devfreq *devfreq);
  extern int devfreq_register_opp_notifier(struct device *dev,
 struct devfreq *devfreq);
  extern int devfreq_unregister_opp_notifier(struct device *dev,
@@ -348,6 +352,11 @@ static inline struct dev_pm_opp 
*devfreq_recommended_opp(struct device *dev,
return ERR_PTR(-EINVAL);
  }
  
+static inline void devfreq_opp_get_suspend_opp(struct device *dev,

+  struct devfreq *devfreq)
+{
+}
+
  static inline int devfreq_register_opp_notifier(struct device *dev,
 struct devfreq *devfreq)
  {


--
Lin Huang




Re: [PATCH v10 5/5] drm/rockchip: Add dmc notifier in vop driver

2016-09-06 Thread hl

Hi

On 2016年09月07日 02:55, Sean Paul wrote:

On Tue, Sep 6, 2016 at 2:15 PM, hl <h...@rock-chips.com> wrote:

Hi Sean,


On 2016年09月07日 01:18, Sean Paul wrote:

On Mon, Sep 5, 2016 at 1:06 AM, Lin Huang <h...@rock-chips.com> wrote:

when in ddr frequency scaling process, vop can not do enable or
disable operation, since in dcf we check vop clock to see whether
vop work. If vop work, dcf do ddr frequency scaling when vop
in vblank status, and we need to read vop register to check whether
vop go into vblank status. If vop not work, dcf can do ddr frequency
any time. So when do ddr frequency scaling, you disabled or enable
vop, there may two bad thing happen: 1, the panel flicker(when vop from
disable status change to enable). 2, kernel hang (when vop from enable
status change to disable, dcf need to read vblank status, but if you
disable
vop clock, it can not get the status, it will lead soc dead) So we need
register to devfreq notifier, and we can get the dmc status. Also, when
there have two vop enabled, we need to disable dmc, since dcf only base
on one vop vblank time, so the other panel will flicker when do ddr
frequency scaling.

Signed-off-by: Lin Huang <h...@rock-chips.com>
Reviewed-by: Chanwoo Choi <cw00.c...@samsung.com>
---
Changes in v10:
- None

Changes in v9:
- None

Changes in v8:
- None

Changes in v7:
- None

Changes in v6:
- fix a build error

Changes in v5:
- improve some nits

Changes in v4:
- register notifier to devfreq_register_notifier
- use DEVFREQ_PRECHANGE and DEVFREQ_POSTCHANGE to get dmc status
- when two vop enable, disable dmc
- when two vop back to one vop, enable dmc

Changes in v3:
- when do vop eanble/disable, dmc will wait until it finish

Changes in v2:
- None

Changes in v1:
- use wait_event instead usleep

   drivers/gpu/drm/rockchip/rockchip_drm_vop.c | 116

   1 file changed, 116 insertions(+)

diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
index efbc41a..a73f3aa 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
@@ -19,6 +19,8 @@
   #include 
   #include 

+#include 
+#include 
   #include 
   #include 
   #include 
@@ -118,6 +120,13 @@ struct vop {

  const struct vop_data *data;

+   struct devfreq *devfreq;
+   struct devfreq_event_dev *devfreq_event_dev;
+   struct notifier_block dmc_nb;
+   int dmc_in_process;
+   int vop_switch_status;
+   wait_queue_head_t wait_dmc_queue;
+   wait_queue_head_t wait_vop_switch_queue;
  uint32_t *regsbak;
  void __iomem *regs;

@@ -428,11 +437,47 @@ static void vop_dsp_hold_valid_irq_disable(struct
vop *vop)
  spin_unlock_irqrestore(>irq_lock, flags);
   }

+static int dmc_notify(struct notifier_block *nb, unsigned long event,
+ void *data)
+{
+   struct vop *vop = container_of(nb, struct vop, dmc_nb);
+
+   if (event == DEVFREQ_PRECHANGE) {
+   /*
+* check if vop in enable or disable process,
+* if yes, wait until it finishes, use 200ms as
+* timeout.
+*/
+   if (!wait_event_timeout(vop->wait_vop_switch_queue,
+   !vop->vop_switch_status, HZ / 5))
+   dev_warn(vop->dev,
+"Timeout waiting for vop swtich
status\n");
+   vop->dmc_in_process = 1;
+   } else if (event == DEVFREQ_POSTCHANGE) {
+   vop->dmc_in_process = 0;
+   wake_up(>wait_dmc_queue);
+   }
+
+   return NOTIFY_OK;
+}
+
   static int vop_enable(struct drm_crtc *crtc)
   {
  struct vop *vop = to_vop(crtc);
+   int num_enabled_crtc = 0;
  int ret;

+   /*
+* if in dmc scaling frequency process, wait until it finishes
+* use 200ms as timeout time.
+*/
+   if (!wait_event_timeout(vop->wait_dmc_queue,
+   !vop->dmc_in_process, HZ / 5))
+   dev_warn(vop->dev,
+"Timeout waiting for dmc when vop enable\n");
+


This wait_event_timeout code is terribly racey (same goes above and
below).

   No i use the vop_switch_status and dmc_in_progress to handle the vop and
dmc racey,


So what happens if dmc_in_progress becomes 1 right here, or anywhere
during vop_enable()?
In dmc_notify(), i will check the vop_switch_status, so in the 
vop_enable() and vop_crtc_disable(),

the dmc_in_progress can not change value.

Sean





I assume this can fix the racey now. I do not better a idea now.




+   vop->vop_switch_status = 1;
+
  ret = pm_runtime_get_sync(vop->dev);
  if (ret < 0) {
  dev_err(vop->dev, "failed to get pm runtime: %d\n",
ret);
@@ -479,6 +524,21 @@ static int vop_enable

Re: [PATCH v10 5/5] drm/rockchip: Add dmc notifier in vop driver

2016-09-06 Thread hl

Hi

On 2016年09月07日 02:55, Sean Paul wrote:

On Tue, Sep 6, 2016 at 2:15 PM, hl  wrote:

Hi Sean,


On 2016年09月07日 01:18, Sean Paul wrote:

On Mon, Sep 5, 2016 at 1:06 AM, Lin Huang  wrote:

when in ddr frequency scaling process, vop can not do enable or
disable operation, since in dcf we check vop clock to see whether
vop work. If vop work, dcf do ddr frequency scaling when vop
in vblank status, and we need to read vop register to check whether
vop go into vblank status. If vop not work, dcf can do ddr frequency
any time. So when do ddr frequency scaling, you disabled or enable
vop, there may two bad thing happen: 1, the panel flicker(when vop from
disable status change to enable). 2, kernel hang (when vop from enable
status change to disable, dcf need to read vblank status, but if you
disable
vop clock, it can not get the status, it will lead soc dead) So we need
register to devfreq notifier, and we can get the dmc status. Also, when
there have two vop enabled, we need to disable dmc, since dcf only base
on one vop vblank time, so the other panel will flicker when do ddr
frequency scaling.

Signed-off-by: Lin Huang 
Reviewed-by: Chanwoo Choi 
---
Changes in v10:
- None

Changes in v9:
- None

Changes in v8:
- None

Changes in v7:
- None

Changes in v6:
- fix a build error

Changes in v5:
- improve some nits

Changes in v4:
- register notifier to devfreq_register_notifier
- use DEVFREQ_PRECHANGE and DEVFREQ_POSTCHANGE to get dmc status
- when two vop enable, disable dmc
- when two vop back to one vop, enable dmc

Changes in v3:
- when do vop eanble/disable, dmc will wait until it finish

Changes in v2:
- None

Changes in v1:
- use wait_event instead usleep

   drivers/gpu/drm/rockchip/rockchip_drm_vop.c | 116

   1 file changed, 116 insertions(+)

diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
index efbc41a..a73f3aa 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
@@ -19,6 +19,8 @@
   #include 
   #include 

+#include 
+#include 
   #include 
   #include 
   #include 
@@ -118,6 +120,13 @@ struct vop {

  const struct vop_data *data;

+   struct devfreq *devfreq;
+   struct devfreq_event_dev *devfreq_event_dev;
+   struct notifier_block dmc_nb;
+   int dmc_in_process;
+   int vop_switch_status;
+   wait_queue_head_t wait_dmc_queue;
+   wait_queue_head_t wait_vop_switch_queue;
  uint32_t *regsbak;
  void __iomem *regs;

@@ -428,11 +437,47 @@ static void vop_dsp_hold_valid_irq_disable(struct
vop *vop)
  spin_unlock_irqrestore(>irq_lock, flags);
   }

+static int dmc_notify(struct notifier_block *nb, unsigned long event,
+ void *data)
+{
+   struct vop *vop = container_of(nb, struct vop, dmc_nb);
+
+   if (event == DEVFREQ_PRECHANGE) {
+   /*
+* check if vop in enable or disable process,
+* if yes, wait until it finishes, use 200ms as
+* timeout.
+*/
+   if (!wait_event_timeout(vop->wait_vop_switch_queue,
+   !vop->vop_switch_status, HZ / 5))
+   dev_warn(vop->dev,
+"Timeout waiting for vop swtich
status\n");
+   vop->dmc_in_process = 1;
+   } else if (event == DEVFREQ_POSTCHANGE) {
+   vop->dmc_in_process = 0;
+   wake_up(>wait_dmc_queue);
+   }
+
+   return NOTIFY_OK;
+}
+
   static int vop_enable(struct drm_crtc *crtc)
   {
  struct vop *vop = to_vop(crtc);
+   int num_enabled_crtc = 0;
  int ret;

+   /*
+* if in dmc scaling frequency process, wait until it finishes
+* use 200ms as timeout time.
+*/
+   if (!wait_event_timeout(vop->wait_dmc_queue,
+   !vop->dmc_in_process, HZ / 5))
+   dev_warn(vop->dev,
+"Timeout waiting for dmc when vop enable\n");
+


This wait_event_timeout code is terribly racey (same goes above and
below).

   No i use the vop_switch_status and dmc_in_progress to handle the vop and
dmc racey,


So what happens if dmc_in_progress becomes 1 right here, or anywhere
during vop_enable()?
In dmc_notify(), i will check the vop_switch_status, so in the 
vop_enable() and vop_crtc_disable(),

the dmc_in_progress can not change value.

Sean





I assume this can fix the racey now. I do not better a idea now.




+   vop->vop_switch_status = 1;
+
  ret = pm_runtime_get_sync(vop->dev);
  if (ret < 0) {
  dev_err(vop->dev, "failed to get pm runtime: %d\n",
ret);
@@ -479,6 +524,21 @@ static int vop_enable(struct drm_crtc *crtc)

  drm_crtc_vblank_on(crtc);

+   vop->vop_switch_status = 0;
+   w

Re: [PATCH v10 5/5] drm/rockchip: Add dmc notifier in vop driver

2016-09-06 Thread hl

Hi Sean,

On 2016年09月07日 01:18, Sean Paul wrote:

On Mon, Sep 5, 2016 at 1:06 AM, Lin Huang  wrote:

when in ddr frequency scaling process, vop can not do enable or
disable operation, since in dcf we check vop clock to see whether
vop work. If vop work, dcf do ddr frequency scaling when vop
in vblank status, and we need to read vop register to check whether
vop go into vblank status. If vop not work, dcf can do ddr frequency
any time. So when do ddr frequency scaling, you disabled or enable
vop, there may two bad thing happen: 1, the panel flicker(when vop from
disable status change to enable). 2, kernel hang (when vop from enable
status change to disable, dcf need to read vblank status, but if you disable
vop clock, it can not get the status, it will lead soc dead) So we need
register to devfreq notifier, and we can get the dmc status. Also, when
there have two vop enabled, we need to disable dmc, since dcf only base
on one vop vblank time, so the other panel will flicker when do ddr
frequency scaling.

Signed-off-by: Lin Huang 
Reviewed-by: Chanwoo Choi 
---
Changes in v10:
- None

Changes in v9:
- None

Changes in v8:
- None

Changes in v7:
- None

Changes in v6:
- fix a build error

Changes in v5:
- improve some nits

Changes in v4:
- register notifier to devfreq_register_notifier
- use DEVFREQ_PRECHANGE and DEVFREQ_POSTCHANGE to get dmc status
- when two vop enable, disable dmc
- when two vop back to one vop, enable dmc

Changes in v3:
- when do vop eanble/disable, dmc will wait until it finish

Changes in v2:
- None

Changes in v1:
- use wait_event instead usleep

  drivers/gpu/drm/rockchip/rockchip_drm_vop.c | 116 
  1 file changed, 116 insertions(+)

diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c 
b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
index efbc41a..a73f3aa 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
@@ -19,6 +19,8 @@
  #include 
  #include 

+#include 
+#include 
  #include 
  #include 
  #include 
@@ -118,6 +120,13 @@ struct vop {

 const struct vop_data *data;

+   struct devfreq *devfreq;
+   struct devfreq_event_dev *devfreq_event_dev;
+   struct notifier_block dmc_nb;
+   int dmc_in_process;
+   int vop_switch_status;
+   wait_queue_head_t wait_dmc_queue;
+   wait_queue_head_t wait_vop_switch_queue;
 uint32_t *regsbak;
 void __iomem *regs;

@@ -428,11 +437,47 @@ static void vop_dsp_hold_valid_irq_disable(struct vop 
*vop)
 spin_unlock_irqrestore(>irq_lock, flags);
  }

+static int dmc_notify(struct notifier_block *nb, unsigned long event,
+ void *data)
+{
+   struct vop *vop = container_of(nb, struct vop, dmc_nb);
+
+   if (event == DEVFREQ_PRECHANGE) {
+   /*
+* check if vop in enable or disable process,
+* if yes, wait until it finishes, use 200ms as
+* timeout.
+*/
+   if (!wait_event_timeout(vop->wait_vop_switch_queue,
+   !vop->vop_switch_status, HZ / 5))
+   dev_warn(vop->dev,
+"Timeout waiting for vop swtich status\n");
+   vop->dmc_in_process = 1;
+   } else if (event == DEVFREQ_POSTCHANGE) {
+   vop->dmc_in_process = 0;
+   wake_up(>wait_dmc_queue);
+   }
+
+   return NOTIFY_OK;
+}
+
  static int vop_enable(struct drm_crtc *crtc)
  {
 struct vop *vop = to_vop(crtc);
+   int num_enabled_crtc = 0;
 int ret;

+   /*
+* if in dmc scaling frequency process, wait until it finishes
+* use 200ms as timeout time.
+*/
+   if (!wait_event_timeout(vop->wait_dmc_queue,
+   !vop->dmc_in_process, HZ / 5))
+   dev_warn(vop->dev,
+"Timeout waiting for dmc when vop enable\n");
+


This wait_event_timeout code is terribly racey (same goes above and below).
  No i use the vop_switch_status and dmc_in_progress to handle the vop 
and dmc racey,

   I assume this can fix the racey now. I do not better a idea now.




+   vop->vop_switch_status = 1;
+
 ret = pm_runtime_get_sync(vop->dev);
 if (ret < 0) {
 dev_err(vop->dev, "failed to get pm runtime: %d\n", ret);
@@ -479,6 +524,21 @@ static int vop_enable(struct drm_crtc *crtc)

 drm_crtc_vblank_on(crtc);

+   vop->vop_switch_status = 0;
+   wake_up(>wait_vop_switch_queue);
+
+   /* check how many VOPs in use now */
+   drm_for_each_crtc(crtc, vop->drm_dev) {
+   if (crtc->state->enable)

I think you really want to check active, instead of enable.

Okay, i will check it, thanks.



+   num_enabled_crtc++;
+   }
+
+   /* if enable two vop, need to disable dmc */
+  

Re: [PATCH v10 5/5] drm/rockchip: Add dmc notifier in vop driver

2016-09-06 Thread hl

Hi Sean,

On 2016年09月07日 01:18, Sean Paul wrote:

On Mon, Sep 5, 2016 at 1:06 AM, Lin Huang  wrote:

when in ddr frequency scaling process, vop can not do enable or
disable operation, since in dcf we check vop clock to see whether
vop work. If vop work, dcf do ddr frequency scaling when vop
in vblank status, and we need to read vop register to check whether
vop go into vblank status. If vop not work, dcf can do ddr frequency
any time. So when do ddr frequency scaling, you disabled or enable
vop, there may two bad thing happen: 1, the panel flicker(when vop from
disable status change to enable). 2, kernel hang (when vop from enable
status change to disable, dcf need to read vblank status, but if you disable
vop clock, it can not get the status, it will lead soc dead) So we need
register to devfreq notifier, and we can get the dmc status. Also, when
there have two vop enabled, we need to disable dmc, since dcf only base
on one vop vblank time, so the other panel will flicker when do ddr
frequency scaling.

Signed-off-by: Lin Huang 
Reviewed-by: Chanwoo Choi 
---
Changes in v10:
- None

Changes in v9:
- None

Changes in v8:
- None

Changes in v7:
- None

Changes in v6:
- fix a build error

Changes in v5:
- improve some nits

Changes in v4:
- register notifier to devfreq_register_notifier
- use DEVFREQ_PRECHANGE and DEVFREQ_POSTCHANGE to get dmc status
- when two vop enable, disable dmc
- when two vop back to one vop, enable dmc

Changes in v3:
- when do vop eanble/disable, dmc will wait until it finish

Changes in v2:
- None

Changes in v1:
- use wait_event instead usleep

  drivers/gpu/drm/rockchip/rockchip_drm_vop.c | 116 
  1 file changed, 116 insertions(+)

diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c 
b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
index efbc41a..a73f3aa 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
@@ -19,6 +19,8 @@
  #include 
  #include 

+#include 
+#include 
  #include 
  #include 
  #include 
@@ -118,6 +120,13 @@ struct vop {

 const struct vop_data *data;

+   struct devfreq *devfreq;
+   struct devfreq_event_dev *devfreq_event_dev;
+   struct notifier_block dmc_nb;
+   int dmc_in_process;
+   int vop_switch_status;
+   wait_queue_head_t wait_dmc_queue;
+   wait_queue_head_t wait_vop_switch_queue;
 uint32_t *regsbak;
 void __iomem *regs;

@@ -428,11 +437,47 @@ static void vop_dsp_hold_valid_irq_disable(struct vop 
*vop)
 spin_unlock_irqrestore(>irq_lock, flags);
  }

+static int dmc_notify(struct notifier_block *nb, unsigned long event,
+ void *data)
+{
+   struct vop *vop = container_of(nb, struct vop, dmc_nb);
+
+   if (event == DEVFREQ_PRECHANGE) {
+   /*
+* check if vop in enable or disable process,
+* if yes, wait until it finishes, use 200ms as
+* timeout.
+*/
+   if (!wait_event_timeout(vop->wait_vop_switch_queue,
+   !vop->vop_switch_status, HZ / 5))
+   dev_warn(vop->dev,
+"Timeout waiting for vop swtich status\n");
+   vop->dmc_in_process = 1;
+   } else if (event == DEVFREQ_POSTCHANGE) {
+   vop->dmc_in_process = 0;
+   wake_up(>wait_dmc_queue);
+   }
+
+   return NOTIFY_OK;
+}
+
  static int vop_enable(struct drm_crtc *crtc)
  {
 struct vop *vop = to_vop(crtc);
+   int num_enabled_crtc = 0;
 int ret;

+   /*
+* if in dmc scaling frequency process, wait until it finishes
+* use 200ms as timeout time.
+*/
+   if (!wait_event_timeout(vop->wait_dmc_queue,
+   !vop->dmc_in_process, HZ / 5))
+   dev_warn(vop->dev,
+"Timeout waiting for dmc when vop enable\n");
+


This wait_event_timeout code is terribly racey (same goes above and below).
  No i use the vop_switch_status and dmc_in_progress to handle the vop 
and dmc racey,

   I assume this can fix the racey now. I do not better a idea now.




+   vop->vop_switch_status = 1;
+
 ret = pm_runtime_get_sync(vop->dev);
 if (ret < 0) {
 dev_err(vop->dev, "failed to get pm runtime: %d\n", ret);
@@ -479,6 +524,21 @@ static int vop_enable(struct drm_crtc *crtc)

 drm_crtc_vblank_on(crtc);

+   vop->vop_switch_status = 0;
+   wake_up(>wait_vop_switch_queue);
+
+   /* check how many VOPs in use now */
+   drm_for_each_crtc(crtc, vop->drm_dev) {
+   if (crtc->state->enable)

I think you really want to check active, instead of enable.

Okay, i will check it, thanks.



+   num_enabled_crtc++;
+   }
+
+   /* if enable two vop, need to disable dmc */
+   if ((num_enabled_crtc > 1) && vop->devfreq) {
+   

Re: [PATCH v6 6/8] Documentation: bindings: add dt documentation for rk3399 dmc

2016-08-23 Thread hl

Hi Chanwoo Choi,


On 2016年08月23日 13:05, Chanwoo Choi wrote:

Hi Lin,

On 2016년 08월 22일 07:16, hl wrote:

Hi Chanwoo Choi,

On 2016年08月17日 12:50, Chanwoo Choi wrote:

Hi Lin,

On 2016년 08월 17일 07:36, Lin Huang wrote:

This patch adds the documentation for rockchip rk3399 dmc driver.

Signed-off-by: Lin Huang <h...@rock-chips.com>
---
Changes in v6:
-Add more detail in Documentation

Changes in v5:
-None

Changes in v4:
-None

Changes in v3:
-None

Changes in v2:
-None

Changes in v1:
-None
   .../devicetree/bindings/devfreq/rk3399_dmc.txt | 84 
++
   1 file changed, 84 insertions(+)
   create mode 100644 Documentation/devicetree/bindings/devfreq/rk3399_dmc.txt

diff --git a/Documentation/devicetree/bindings/devfreq/rk3399_dmc.txt 
b/Documentation/devicetree/bindings/devfreq/rk3399_dmc.txt
new file mode 100644
index 000..e73067c
--- /dev/null
+++ b/Documentation/devicetree/bindings/devfreq/rk3399_dmc.txt
@@ -0,0 +1,84 @@
+* Rockchip rk3399 DMC(Dynamic Memory Controller) device
+
+Required properties:
+- compatible: Must be "rockchip,rk3399-dmc".
+- devfreq-events: Node to get ddr loading, Refer to
+  Documentation/devicetree/bindings/devfreq/rockchip-dif.txt
+- interrupts: The interrupt number to the cpu. The interrupt specifier format
+  depends on the interrupt controller. it should be dcf interrupts,
+  when ddr dvfs finish, it will happen.

If possible, you better to keep the indentation with other properties.
s/it->It, dcf->DCF, ddr->DDR



+- clocks: Phandles for clock specified in "clock-names" property
+- clock-names : The name of clock used by the DFI, must be "pclk_ddr_mon";
+- operating-points-v2: Refer to Documentation/devicetree/bindings/power/opp.txt
+   for details.

ditto.


+- center-supply: Dmc supply node.

s/Dmc/DMC becaue DMC an abbreviation.


+- status: Marks the node enabled/disabled.
+
+Optional properties:
+- ddr_timing: ddr timing need to pass to arm trust firmware
+- upthreshold: the upthreshold to simpleondeamnd policy
+- downdifferential: The downdifferential to simpleondeamnd policy
+
+Example:
+ddr_timing: ddr_timing {
+compatible = "rockchip,ddr-timing";

I can't find the 'rockchip,ddr-timing' driver on linux-next git repo (20160816).
If ddr_timing includes the only properties for ddr_timing,
I recommend you make the separate a .dtsi file including
the ddr timing configuration. I add the reference and an example on below.


+ddr3_speed_bin = <21>;
+pd_idle = <0>;
+sr_idle = <0>;
+sr_mc_gate_idle = <0>;
+srpd_lite_idle= <0>;
+standby_idle = <0>;
+dram_dll_dis_freq = <300>;
+phy_dll_dis_freq = <125>;
+
+ddr3_odt_dis_freq = <333>;
+ddr3_drv = ;
+ddr3_odt = ;
+phy_ddr3_ca_drv = ;
+phy_ddr3_dq_drv = ;
+phy_ddr3_odt = ;
+
+lpddr3_odt_dis_freq = <333>;
+lpddr3_drv = ;
+lpddr3_odt = ;
+phy_lpddr3_ca_drv = ;
+phy_lpddr3_dq_drv = ;
+phy_lpddr3_odt = ;
+
+lpddr4_odt_dis_freq = <333>;
+lpddr4_drv = ;
+lpddr4_dq_odt = ;
+lpddr4_ca_odt = ;
+phy_lpddr4_ca_drv = ;
+phy_lpddr4_ck_cs_drv = ;
+phy_lpddr4_dq_drv = ;
+phy_lpddr4_odt = ;
+};
+
+dmc_opp_table: dmc_opp_table {
+compatible = "operating-points-v2";
+
+opp00 {
+opp-hz = /bits/ 64 <3>;
+opp-microvolt = <90>;
+};
+opp01 {
+opp-hz = /bits/ 64 <66600>;
+opp-microvolt = <90>;
+};
+};
+
+dmc: dmc {
+compatible = "rockchip,rk3399-dmc";
+devfreq-events = <>;
+interrupts = ;
+clocks = < SCLK_DDRCLK>;
+clock-names = "dmc_clk";
+ddr_timing = <_timing>;

You can use the following '#include' instead of 'ddr_timing'
because the ddr_timing is not a device driver. Instead,
the rk3399-dmc must need the ddr timing configuration.

 #include "rk3399-dmc-timing-conf.dtsi"

You can refer the similar usage case[1].
The *.conf.dtsi is used on exynos3250 tmu dt node[2].

[1] arch/arm/boot/dts/exynos4412-tmu-sensor-conf.dtsi
[2] arch/arm/boot/dts/exynos3250.dtsi, 224 line.


+operating-points-v2 = <_opp_table>;
+center-supply = <_centerlogic>;
+upthreshold = <15>;
+downdifferential = <10>;
+status = "disabled";
+};
+


For example,
I think that you can add the following timing .dtsi file.
- arch/arm/boot/dts/rk3399-dmc-timing-conf.dtsi

/*
   * Device tree sources for RK3399 DDR timing configuration
   *
   * Copyright (c) 2016 Lin Huang <h...@rock-chips.com>
   *
   * This program is free software

Re: [PATCH v6 6/8] Documentation: bindings: add dt documentation for rk3399 dmc

2016-08-23 Thread hl

Hi Chanwoo Choi,


On 2016年08月23日 13:05, Chanwoo Choi wrote:

Hi Lin,

On 2016년 08월 22일 07:16, hl wrote:

Hi Chanwoo Choi,

On 2016年08月17日 12:50, Chanwoo Choi wrote:

Hi Lin,

On 2016년 08월 17일 07:36, Lin Huang wrote:

This patch adds the documentation for rockchip rk3399 dmc driver.

Signed-off-by: Lin Huang 
---
Changes in v6:
-Add more detail in Documentation

Changes in v5:
-None

Changes in v4:
-None

Changes in v3:
-None

Changes in v2:
-None

Changes in v1:
-None
   .../devicetree/bindings/devfreq/rk3399_dmc.txt | 84 
++
   1 file changed, 84 insertions(+)
   create mode 100644 Documentation/devicetree/bindings/devfreq/rk3399_dmc.txt

diff --git a/Documentation/devicetree/bindings/devfreq/rk3399_dmc.txt 
b/Documentation/devicetree/bindings/devfreq/rk3399_dmc.txt
new file mode 100644
index 000..e73067c
--- /dev/null
+++ b/Documentation/devicetree/bindings/devfreq/rk3399_dmc.txt
@@ -0,0 +1,84 @@
+* Rockchip rk3399 DMC(Dynamic Memory Controller) device
+
+Required properties:
+- compatible: Must be "rockchip,rk3399-dmc".
+- devfreq-events: Node to get ddr loading, Refer to
+  Documentation/devicetree/bindings/devfreq/rockchip-dif.txt
+- interrupts: The interrupt number to the cpu. The interrupt specifier format
+  depends on the interrupt controller. it should be dcf interrupts,
+  when ddr dvfs finish, it will happen.

If possible, you better to keep the indentation with other properties.
s/it->It, dcf->DCF, ddr->DDR



+- clocks: Phandles for clock specified in "clock-names" property
+- clock-names : The name of clock used by the DFI, must be "pclk_ddr_mon";
+- operating-points-v2: Refer to Documentation/devicetree/bindings/power/opp.txt
+   for details.

ditto.


+- center-supply: Dmc supply node.

s/Dmc/DMC becaue DMC an abbreviation.


+- status: Marks the node enabled/disabled.
+
+Optional properties:
+- ddr_timing: ddr timing need to pass to arm trust firmware
+- upthreshold: the upthreshold to simpleondeamnd policy
+- downdifferential: The downdifferential to simpleondeamnd policy
+
+Example:
+ddr_timing: ddr_timing {
+compatible = "rockchip,ddr-timing";

I can't find the 'rockchip,ddr-timing' driver on linux-next git repo (20160816).
If ddr_timing includes the only properties for ddr_timing,
I recommend you make the separate a .dtsi file including
the ddr timing configuration. I add the reference and an example on below.


+ddr3_speed_bin = <21>;
+pd_idle = <0>;
+sr_idle = <0>;
+sr_mc_gate_idle = <0>;
+srpd_lite_idle= <0>;
+standby_idle = <0>;
+dram_dll_dis_freq = <300>;
+phy_dll_dis_freq = <125>;
+
+ddr3_odt_dis_freq = <333>;
+ddr3_drv = ;
+ddr3_odt = ;
+phy_ddr3_ca_drv = ;
+phy_ddr3_dq_drv = ;
+phy_ddr3_odt = ;
+
+lpddr3_odt_dis_freq = <333>;
+lpddr3_drv = ;
+lpddr3_odt = ;
+phy_lpddr3_ca_drv = ;
+phy_lpddr3_dq_drv = ;
+phy_lpddr3_odt = ;
+
+lpddr4_odt_dis_freq = <333>;
+lpddr4_drv = ;
+lpddr4_dq_odt = ;
+lpddr4_ca_odt = ;
+phy_lpddr4_ca_drv = ;
+phy_lpddr4_ck_cs_drv = ;
+phy_lpddr4_dq_drv = ;
+phy_lpddr4_odt = ;
+};
+
+dmc_opp_table: dmc_opp_table {
+compatible = "operating-points-v2";
+
+opp00 {
+opp-hz = /bits/ 64 <3>;
+opp-microvolt = <90>;
+};
+opp01 {
+opp-hz = /bits/ 64 <66600>;
+opp-microvolt = <90>;
+};
+};
+
+dmc: dmc {
+compatible = "rockchip,rk3399-dmc";
+devfreq-events = <>;
+interrupts = ;
+clocks = < SCLK_DDRCLK>;
+clock-names = "dmc_clk";
+ddr_timing = <_timing>;

You can use the following '#include' instead of 'ddr_timing'
because the ddr_timing is not a device driver. Instead,
the rk3399-dmc must need the ddr timing configuration.

 #include "rk3399-dmc-timing-conf.dtsi"

You can refer the similar usage case[1].
The *.conf.dtsi is used on exynos3250 tmu dt node[2].

[1] arch/arm/boot/dts/exynos4412-tmu-sensor-conf.dtsi
[2] arch/arm/boot/dts/exynos3250.dtsi, 224 line.


+operating-points-v2 = <_opp_table>;
+center-supply = <_centerlogic>;
+upthreshold = <15>;
+downdifferential = <10>;
+status = "disabled";
+};
+


For example,
I think that you can add the following timing .dtsi file.
- arch/arm/boot/dts/rk3399-dmc-timing-conf.dtsi

/*
   * Device tree sources for RK3399 DDR timing configuration
   *
   * Copyright (c) 2016 Lin Huang 
   *
   * This program is free software; you can redistribute it and/or modify
   * it under t

Re: [PATCH v6 6/8] Documentation: bindings: add dt documentation for rk3399 dmc

2016-08-21 Thread hl

Hi Chanwoo Choi,

On 2016年08月17日 12:50, Chanwoo Choi wrote:

Hi Lin,

On 2016년 08월 17일 07:36, Lin Huang wrote:

This patch adds the documentation for rockchip rk3399 dmc driver.

Signed-off-by: Lin Huang 
---
Changes in v6:
-Add more detail in Documentation

Changes in v5:
-None

Changes in v4:
-None

Changes in v3:
-None

Changes in v2:
-None

Changes in v1:
-None
  .../devicetree/bindings/devfreq/rk3399_dmc.txt | 84 ++
  1 file changed, 84 insertions(+)
  create mode 100644 Documentation/devicetree/bindings/devfreq/rk3399_dmc.txt

diff --git a/Documentation/devicetree/bindings/devfreq/rk3399_dmc.txt 
b/Documentation/devicetree/bindings/devfreq/rk3399_dmc.txt
new file mode 100644
index 000..e73067c
--- /dev/null
+++ b/Documentation/devicetree/bindings/devfreq/rk3399_dmc.txt
@@ -0,0 +1,84 @@
+* Rockchip rk3399 DMC(Dynamic Memory Controller) device
+
+Required properties:
+- compatible: Must be "rockchip,rk3399-dmc".
+- devfreq-events: Node to get ddr loading, Refer to
+ Documentation/devicetree/bindings/devfreq/rockchip-dif.txt
+- interrupts: The interrupt number to the cpu. The interrupt specifier format
+ depends on the interrupt controller. it should be dcf interrupts,
+ when ddr dvfs finish, it will happen.

If possible, you better to keep the indentation with other properties.
s/it->It, dcf->DCF, ddr->DDR



+- clocks: Phandles for clock specified in "clock-names" property
+- clock-names : The name of clock used by the DFI, must be "pclk_ddr_mon";
+- operating-points-v2: Refer to Documentation/devicetree/bindings/power/opp.txt
+  for details.

ditto.


+- center-supply: Dmc supply node.

s/Dmc/DMC becaue DMC an abbreviation.


+- status: Marks the node enabled/disabled.
+
+Optional properties:
+- ddr_timing: ddr timing need to pass to arm trust firmware
+- upthreshold: the upthreshold to simpleondeamnd policy
+- downdifferential: The downdifferential to simpleondeamnd policy
+
+Example:
+   ddr_timing: ddr_timing {
+   compatible = "rockchip,ddr-timing";

I can't find the 'rockchip,ddr-timing' driver on linux-next git repo (20160816).
If ddr_timing includes the only properties for ddr_timing,
I recommend you make the separate a .dtsi file including
the ddr timing configuration. I add the reference and an example on below.


+   ddr3_speed_bin = <21>;
+   pd_idle = <0>;
+   sr_idle = <0>;
+   sr_mc_gate_idle = <0>;
+   srpd_lite_idle  = <0>;
+   standby_idle = <0>;
+   dram_dll_dis_freq = <300>;
+   phy_dll_dis_freq = <125>;
+
+   ddr3_odt_dis_freq = <333>;
+   ddr3_drv = ;
+   ddr3_odt = ;
+   phy_ddr3_ca_drv = ;
+   phy_ddr3_dq_drv = ;
+   phy_ddr3_odt = ;
+
+   lpddr3_odt_dis_freq = <333>;
+   lpddr3_drv = ;
+   lpddr3_odt = ;
+   phy_lpddr3_ca_drv = ;
+   phy_lpddr3_dq_drv = ;
+   phy_lpddr3_odt = ;
+
+   lpddr4_odt_dis_freq = <333>;
+   lpddr4_drv = ;
+   lpddr4_dq_odt = ;
+   lpddr4_ca_odt = ;
+   phy_lpddr4_ca_drv = ;
+   phy_lpddr4_ck_cs_drv = ;
+   phy_lpddr4_dq_drv = ;
+   phy_lpddr4_odt = ;
+   };
+
+   dmc_opp_table: dmc_opp_table {
+   compatible = "operating-points-v2";
+
+   opp00 {
+   opp-hz = /bits/ 64 <3>;
+   opp-microvolt = <90>;
+   };
+   opp01 {
+   opp-hz = /bits/ 64 <66600>;
+   opp-microvolt = <90>;
+   };
+   };
+
+   dmc: dmc {
+   compatible = "rockchip,rk3399-dmc";
+   devfreq-events = <>;
+   interrupts = ;
+   clocks = < SCLK_DDRCLK>;
+   clock-names = "dmc_clk";
+   ddr_timing = <_timing>;

You can use the following '#include' instead of 'ddr_timing'
because the ddr_timing is not a device driver. Instead,
the rk3399-dmc must need the ddr timing configuration.

#include "rk3399-dmc-timing-conf.dtsi"

You can refer the similar usage case[1].
The *.conf.dtsi is used on exynos3250 tmu dt node[2].

[1] arch/arm/boot/dts/exynos4412-tmu-sensor-conf.dtsi
[2] arch/arm/boot/dts/exynos3250.dtsi, 224 line.


+   operating-points-v2 = <_opp_table>;
+   center-supply = <_centerlogic>;
+   upthreshold = <15>;
+   downdifferential = <10>;
+   status = "disabled";
+   };
+


For example,
I think that you can add the following timing .dtsi file.
- arch/arm/boot/dts/rk3399-dmc-timing-conf.dtsi

/*
  * Device tree sources for RK3399 DDR timing configuration
  *
  * Copyright (c) 2016 Lin Huang 

Re: [PATCH v6 6/8] Documentation: bindings: add dt documentation for rk3399 dmc

2016-08-21 Thread hl

Hi Chanwoo Choi,

On 2016年08月17日 12:50, Chanwoo Choi wrote:

Hi Lin,

On 2016년 08월 17일 07:36, Lin Huang wrote:

This patch adds the documentation for rockchip rk3399 dmc driver.

Signed-off-by: Lin Huang 
---
Changes in v6:
-Add more detail in Documentation

Changes in v5:
-None

Changes in v4:
-None

Changes in v3:
-None

Changes in v2:
-None

Changes in v1:
-None
  .../devicetree/bindings/devfreq/rk3399_dmc.txt | 84 ++
  1 file changed, 84 insertions(+)
  create mode 100644 Documentation/devicetree/bindings/devfreq/rk3399_dmc.txt

diff --git a/Documentation/devicetree/bindings/devfreq/rk3399_dmc.txt 
b/Documentation/devicetree/bindings/devfreq/rk3399_dmc.txt
new file mode 100644
index 000..e73067c
--- /dev/null
+++ b/Documentation/devicetree/bindings/devfreq/rk3399_dmc.txt
@@ -0,0 +1,84 @@
+* Rockchip rk3399 DMC(Dynamic Memory Controller) device
+
+Required properties:
+- compatible: Must be "rockchip,rk3399-dmc".
+- devfreq-events: Node to get ddr loading, Refer to
+ Documentation/devicetree/bindings/devfreq/rockchip-dif.txt
+- interrupts: The interrupt number to the cpu. The interrupt specifier format
+ depends on the interrupt controller. it should be dcf interrupts,
+ when ddr dvfs finish, it will happen.

If possible, you better to keep the indentation with other properties.
s/it->It, dcf->DCF, ddr->DDR



+- clocks: Phandles for clock specified in "clock-names" property
+- clock-names : The name of clock used by the DFI, must be "pclk_ddr_mon";
+- operating-points-v2: Refer to Documentation/devicetree/bindings/power/opp.txt
+  for details.

ditto.


+- center-supply: Dmc supply node.

s/Dmc/DMC becaue DMC an abbreviation.


+- status: Marks the node enabled/disabled.
+
+Optional properties:
+- ddr_timing: ddr timing need to pass to arm trust firmware
+- upthreshold: the upthreshold to simpleondeamnd policy
+- downdifferential: The downdifferential to simpleondeamnd policy
+
+Example:
+   ddr_timing: ddr_timing {
+   compatible = "rockchip,ddr-timing";

I can't find the 'rockchip,ddr-timing' driver on linux-next git repo (20160816).
If ddr_timing includes the only properties for ddr_timing,
I recommend you make the separate a .dtsi file including
the ddr timing configuration. I add the reference and an example on below.


+   ddr3_speed_bin = <21>;
+   pd_idle = <0>;
+   sr_idle = <0>;
+   sr_mc_gate_idle = <0>;
+   srpd_lite_idle  = <0>;
+   standby_idle = <0>;
+   dram_dll_dis_freq = <300>;
+   phy_dll_dis_freq = <125>;
+
+   ddr3_odt_dis_freq = <333>;
+   ddr3_drv = ;
+   ddr3_odt = ;
+   phy_ddr3_ca_drv = ;
+   phy_ddr3_dq_drv = ;
+   phy_ddr3_odt = ;
+
+   lpddr3_odt_dis_freq = <333>;
+   lpddr3_drv = ;
+   lpddr3_odt = ;
+   phy_lpddr3_ca_drv = ;
+   phy_lpddr3_dq_drv = ;
+   phy_lpddr3_odt = ;
+
+   lpddr4_odt_dis_freq = <333>;
+   lpddr4_drv = ;
+   lpddr4_dq_odt = ;
+   lpddr4_ca_odt = ;
+   phy_lpddr4_ca_drv = ;
+   phy_lpddr4_ck_cs_drv = ;
+   phy_lpddr4_dq_drv = ;
+   phy_lpddr4_odt = ;
+   };
+
+   dmc_opp_table: dmc_opp_table {
+   compatible = "operating-points-v2";
+
+   opp00 {
+   opp-hz = /bits/ 64 <3>;
+   opp-microvolt = <90>;
+   };
+   opp01 {
+   opp-hz = /bits/ 64 <66600>;
+   opp-microvolt = <90>;
+   };
+   };
+
+   dmc: dmc {
+   compatible = "rockchip,rk3399-dmc";
+   devfreq-events = <>;
+   interrupts = ;
+   clocks = < SCLK_DDRCLK>;
+   clock-names = "dmc_clk";
+   ddr_timing = <_timing>;

You can use the following '#include' instead of 'ddr_timing'
because the ddr_timing is not a device driver. Instead,
the rk3399-dmc must need the ddr timing configuration.

#include "rk3399-dmc-timing-conf.dtsi"

You can refer the similar usage case[1].
The *.conf.dtsi is used on exynos3250 tmu dt node[2].

[1] arch/arm/boot/dts/exynos4412-tmu-sensor-conf.dtsi
[2] arch/arm/boot/dts/exynos3250.dtsi, 224 line.


+   operating-points-v2 = <_opp_table>;
+   center-supply = <_centerlogic>;
+   upthreshold = <15>;
+   downdifferential = <10>;
+   status = "disabled";
+   };
+


For example,
I think that you can add the following timing .dtsi file.
- arch/arm/boot/dts/rk3399-dmc-timing-conf.dtsi

/*
  * Device tree sources for RK3399 DDR timing configuration
  *
  * Copyright (c) 2016 Lin Huang 
  *
  * This program is free software; 

Re: [PATCH v6 8/8] drm/rockchip: Add dmc notifier in vop driver

2016-08-17 Thread hl


Hi,

On 2016年08月18日 02:14, Sean Paul wrote:

On Tue, Aug 16, 2016 at 3:36 PM, Lin Huang  wrote:

when in ddr frequency scaling process, vop can not do
enable or disable operation, since dcf will base on vop vblank
time to do frequency scaling and need to get vop irq if there
have vop enabled.

I'm a little confused by this. Does this mean you need vblank irq to
be enabled all the time when vop is enabled? We regularly disable it
when there aren't new fbs coming in.

maybe the commit message lead to misunderstanding, in dcf it will
read the vop register to check whether is it in vblank status, if 
not, it

will wait until it into vblank status. When vop enable, we need the vop
clock enable, so we can read the vop register.




So need register to devfreq notifier, and we can
get the dmc status.
Also, when there have two vop enabled, we need
to disable dmc, since dcf only base on one vop vblank time, so the
other panel will flicker when do ddr frequency scaling.

Signed-off-by: Lin Huang 
Reviewed-by: Chanwoo Choi 
---
Changes in v6:
- fix a build error

Changes in v5:
- improve some nits

Changes in v4:
- register notifier to devfreq_register_notifier
- use DEVFREQ_PRECHANGE and DEVFREQ_POSTCHANGE to get dmc status
- when two vop enable, disable dmc
- when two vop back to one vop, enable dmc

Changes in v3:
- when do vop eanble/disable, dmc will wait until it finish

Changes in v2:
- None

Changes in v1:
- use wait_event instead usleep

  drivers/gpu/drm/rockchip/rockchip_drm_vop.c | 121 +++-
  1 file changed, 119 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c 
b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
index 31744fe..199529e 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
@@ -12,6 +12,8 @@
   * GNU General Public License for more details.
   */

+#include 
+#include 
  #include 
  #include 
  #include 
@@ -118,6 +120,13 @@ struct vop {

 const struct vop_data *data;

+   struct devfreq *devfreq;
+   struct devfreq_event_dev *devfreq_event_dev;
+   struct notifier_block dmc_nb;
+   int dmc_in_process;
+   int vop_switch_status;
+   wait_queue_head_t wait_dmc_queue;
+   wait_queue_head_t wait_vop_switch_queue;
 uint32_t *regsbak;
 void __iomem *regs;

@@ -428,21 +437,56 @@ static void vop_dsp_hold_valid_irq_disable(struct vop 
*vop)
 spin_unlock_irqrestore(>irq_lock, flags);
  }

+static int dmc_notify(struct notifier_block *nb, unsigned long event,
+ void *data)
+{
+   struct vop *vop = container_of(nb, struct vop, dmc_nb);
+
+   if (event == DEVFREQ_PRECHANGE) {
+   /*
+* check if vop in enable or disable process,
+* if yes, wait until it finishes, use 200ms as
+* timeout.
+*/
+   if (!wait_event_timeout(vop->wait_vop_switch_queue,
+   !vop->vop_switch_status, HZ / 5))
+   dev_warn(vop->dev,
+"Timeout waiting for vop swtich status\n");
+   vop->dmc_in_process = 1;
+   } else if (event == DEVFREQ_POSTCHANGE) {
+   vop->dmc_in_process = 0;
+   wake_up(>wait_dmc_queue);
+   }
+
+   return NOTIFY_OK;
+}
+
  static void vop_enable(struct drm_crtc *crtc)
  {
 struct vop *vop = to_vop(crtc);
+   int num_enabled_crtc = 0;
 int ret;

+   /*
+* if in dmc scaling frequency process, wait until it finishes
+* use 100ms as timeout time.
+*/
+   if (!wait_event_timeout(vop->wait_dmc_queue,
+   !vop->dmc_in_process, HZ / 5))
+   dev_warn(vop->dev,
+"Timeout waiting for dmc when vop enable\n");
+
+   vop->vop_switch_status = 1;
 ret = pm_runtime_get_sync(vop->dev);
 if (ret < 0) {
 dev_err(vop->dev, "failed to get pm runtime: %d\n", ret);
-   return;
+   goto err;
 }

 ret = clk_enable(vop->hclk);
 if (ret < 0) {
 dev_err(vop->dev, "failed to enable hclk - %d\n", ret);
-   return;
+   goto err;
 }

 ret = clk_enable(vop->dclk);
@@ -485,6 +529,21 @@ static void vop_enable(struct drm_crtc *crtc)

 drm_crtc_vblank_on(crtc);

+   vop->vop_switch_status = 0;
+   wake_up(>wait_vop_switch_queue);
+
+   /* check how many vop we use now */
+   drm_for_each_crtc(crtc, vop->drm_dev) {
+   if (crtc->state->enable)
+   num_enabled_crtc++;
+   }
+
+   /* if enable two vop, need to disable dmc */
+   if ((num_enabled_crtc > 1) && vop->devfreq) {
+   if (vop->devfreq_event_dev)
+  

Re: [PATCH v6 8/8] drm/rockchip: Add dmc notifier in vop driver

2016-08-17 Thread hl


Hi,

On 2016年08月18日 02:14, Sean Paul wrote:

On Tue, Aug 16, 2016 at 3:36 PM, Lin Huang  wrote:

when in ddr frequency scaling process, vop can not do
enable or disable operation, since dcf will base on vop vblank
time to do frequency scaling and need to get vop irq if there
have vop enabled.

I'm a little confused by this. Does this mean you need vblank irq to
be enabled all the time when vop is enabled? We regularly disable it
when there aren't new fbs coming in.

maybe the commit message lead to misunderstanding, in dcf it will
read the vop register to check whether is it in vblank status, if 
not, it

will wait until it into vblank status. When vop enable, we need the vop
clock enable, so we can read the vop register.




So need register to devfreq notifier, and we can
get the dmc status.
Also, when there have two vop enabled, we need
to disable dmc, since dcf only base on one vop vblank time, so the
other panel will flicker when do ddr frequency scaling.

Signed-off-by: Lin Huang 
Reviewed-by: Chanwoo Choi 
---
Changes in v6:
- fix a build error

Changes in v5:
- improve some nits

Changes in v4:
- register notifier to devfreq_register_notifier
- use DEVFREQ_PRECHANGE and DEVFREQ_POSTCHANGE to get dmc status
- when two vop enable, disable dmc
- when two vop back to one vop, enable dmc

Changes in v3:
- when do vop eanble/disable, dmc will wait until it finish

Changes in v2:
- None

Changes in v1:
- use wait_event instead usleep

  drivers/gpu/drm/rockchip/rockchip_drm_vop.c | 121 +++-
  1 file changed, 119 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c 
b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
index 31744fe..199529e 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
@@ -12,6 +12,8 @@
   * GNU General Public License for more details.
   */

+#include 
+#include 
  #include 
  #include 
  #include 
@@ -118,6 +120,13 @@ struct vop {

 const struct vop_data *data;

+   struct devfreq *devfreq;
+   struct devfreq_event_dev *devfreq_event_dev;
+   struct notifier_block dmc_nb;
+   int dmc_in_process;
+   int vop_switch_status;
+   wait_queue_head_t wait_dmc_queue;
+   wait_queue_head_t wait_vop_switch_queue;
 uint32_t *regsbak;
 void __iomem *regs;

@@ -428,21 +437,56 @@ static void vop_dsp_hold_valid_irq_disable(struct vop 
*vop)
 spin_unlock_irqrestore(>irq_lock, flags);
  }

+static int dmc_notify(struct notifier_block *nb, unsigned long event,
+ void *data)
+{
+   struct vop *vop = container_of(nb, struct vop, dmc_nb);
+
+   if (event == DEVFREQ_PRECHANGE) {
+   /*
+* check if vop in enable or disable process,
+* if yes, wait until it finishes, use 200ms as
+* timeout.
+*/
+   if (!wait_event_timeout(vop->wait_vop_switch_queue,
+   !vop->vop_switch_status, HZ / 5))
+   dev_warn(vop->dev,
+"Timeout waiting for vop swtich status\n");
+   vop->dmc_in_process = 1;
+   } else if (event == DEVFREQ_POSTCHANGE) {
+   vop->dmc_in_process = 0;
+   wake_up(>wait_dmc_queue);
+   }
+
+   return NOTIFY_OK;
+}
+
  static void vop_enable(struct drm_crtc *crtc)
  {
 struct vop *vop = to_vop(crtc);
+   int num_enabled_crtc = 0;
 int ret;

+   /*
+* if in dmc scaling frequency process, wait until it finishes
+* use 100ms as timeout time.
+*/
+   if (!wait_event_timeout(vop->wait_dmc_queue,
+   !vop->dmc_in_process, HZ / 5))
+   dev_warn(vop->dev,
+"Timeout waiting for dmc when vop enable\n");
+
+   vop->vop_switch_status = 1;
 ret = pm_runtime_get_sync(vop->dev);
 if (ret < 0) {
 dev_err(vop->dev, "failed to get pm runtime: %d\n", ret);
-   return;
+   goto err;
 }

 ret = clk_enable(vop->hclk);
 if (ret < 0) {
 dev_err(vop->dev, "failed to enable hclk - %d\n", ret);
-   return;
+   goto err;
 }

 ret = clk_enable(vop->dclk);
@@ -485,6 +529,21 @@ static void vop_enable(struct drm_crtc *crtc)

 drm_crtc_vblank_on(crtc);

+   vop->vop_switch_status = 0;
+   wake_up(>wait_vop_switch_queue);
+
+   /* check how many vop we use now */
+   drm_for_each_crtc(crtc, vop->drm_dev) {
+   if (crtc->state->enable)
+   num_enabled_crtc++;
+   }
+
+   /* if enable two vop, need to disable dmc */
+   if ((num_enabled_crtc > 1) && vop->devfreq) {
+   if (vop->devfreq_event_dev)
+   devfreq_event_disable_edev(vop->devfreq_event_dev);
+   

Re: [PATCH v4 1/7] clk: rockchip: add clock flag parameter when register pll

2016-08-05 Thread hl

Hi Heiko,

On 2016年08月05日 06:37, Heiko Stuebner wrote:

Am Freitag, 29. Juli 2016, 15:56:55 schrieb Lin Huang:

From: Heiko Stübner 

add clock flag parameter so we can pass specific clock flag
(like CLK_GET_RATE_NOCACHE etc..)to pll driver.

Signed-off-by: Heiko Stübner 
Signed-off-by: Lin Huang 

applied to my clock branch for 4.9 after some minor edits on the commit
message.
 I can not found your clock branch for 4.9, can you share me the patch 
ID, i want

cherry-pick it to my downstream branch.


Thanks
Heiko






Re: [PATCH v4 1/7] clk: rockchip: add clock flag parameter when register pll

2016-08-05 Thread hl

Hi Heiko,

On 2016年08月05日 06:37, Heiko Stuebner wrote:

Am Freitag, 29. Juli 2016, 15:56:55 schrieb Lin Huang:

From: Heiko Stübner 

add clock flag parameter so we can pass specific clock flag
(like CLK_GET_RATE_NOCACHE etc..)to pll driver.

Signed-off-by: Heiko Stübner 
Signed-off-by: Lin Huang 

applied to my clock branch for 4.9 after some minor edits on the commit
message.
 I can not found your clock branch for 4.9, can you share me the patch 
ID, i want

cherry-pick it to my downstream branch.


Thanks
Heiko






Re: [PATCH v4 6/7] PM / devfreq: rockchip: add devfreq driver for rk3399 dmc

2016-08-03 Thread hl


Hi Chanwoo Choi,
On 2016年08月02日 12:21, Chanwoo Choi wrote:

Hi Lin,

On the next version, I'd like you to add the 'linux...@vger.kernel.org'
because devfreq is a subsystem of power management.

Sure, will do it next version.

On 2016년 08월 02일 10:03, hl wrote:

Hi Chanwoo Choi,

 Thanks for reviewing so carefully. And i have some question:

On 2016年08月01日 18:28, Chanwoo Choi wrote:

Hi Lin,

As I mentioned on patch5, you better to make the documentation as following:
- Documentation/devicetree/bindings/devfreq/rk3399_dmc.txt
And, I add the comments.


On 2016년 07월 29일 16:57, Lin Huang wrote:

base on dfi result, we do ddr frequency scaling, register
dmc driver to devfreq framework, and use simple-ondemand
policy.

Signed-off-by: Lin Huang <h...@rock-chips.com>
---
Changes in v4:
- use arm_smccc_smc() function talk to bl31
- delete rockchip_dmc.c file and config
- delete dmc_notify
- adjust probe order
   Changes in v3:
- operate dram setting through sip call
- imporve set rate flow

Changes in v2:
- None
   Changes in v1:
- move dfi controller to event
- fix set voltage sequence when set rate fail
- change Kconfig type from tristate to bool
- move unuse EXPORT_SYMBOL_GPL()

   drivers/devfreq/Kconfig   |   1 +
   drivers/devfreq/Makefile  |   1 +
   drivers/devfreq/rockchip/Kconfig  |   8 +
   drivers/devfreq/rockchip/Makefile |   1 +
   drivers/devfreq/rockchip/rk3399_dmc.c | 473 
++
   5 files changed, 484 insertions(+)
   create mode 100644 drivers/devfreq/rockchip/Kconfig
   create mode 100644 drivers/devfreq/rockchip/Makefile
   create mode 100644 drivers/devfreq/rockchip/rk3399_dmc.c


[snip]


+
+static int rk3399_dmcfreq_target(struct device *dev, unsigned long *freq,
+ u32 flags)
+{
+struct platform_device *pdev = container_of(dev, struct platform_device,
+dev);
+struct rk3399_dmcfreq *dmcfreq = platform_get_drvdata(pdev);

You can use the 'dev_get_drvdata()' to simplify it instead of 
'platform_get_drvdata()'.

 struct rk3399_dmcfreq *dmcfreq = dev_get_drvdata(dev);


+struct dev_pm_opp *opp;
+unsigned long old_clk_rate = dmcfreq->rate;
+unsigned long target_volt, target_rate;
+int err;
+
+rcu_read_lock();
+opp = devfreq_recommended_opp(dev, freq, flags);
+if (IS_ERR(opp)) {
+rcu_read_unlock();
+return PTR_ERR(opp);
+}
+
+target_rate = dev_pm_opp_get_freq(opp);
+target_volt = dev_pm_opp_get_voltage(opp);
+opp = devfreq_recommended_opp(dev, >rate, flags);
+if (IS_ERR(opp)) {
+rcu_read_unlock();
+return PTR_ERR(opp);
+}
+dmcfreq->volt = dev_pm_opp_get_voltage(opp);

If you add the 'curr_opp' variable to struct rk3399_dmcfreq,
you can remove the calling of devfreq_recommended_opp().
 dmcfreq->rate = dev_pm_opp_get_freq(dmcfreq->curr_opp);
 dmcfreq->volt = dev_pm_opp_get_freq(dmcfreq->curr_opp);

Because the current rate and voltage is already decided on previous polling 
cycle,
So we don't need to get the opp with devfreq_recommended_opp().

I prefer the way now use, since we get the dmcfreq->rate use clk_get_rate() 
after,
Base on that,  i do not care the set_rate success or fail. use curr_opp i need 
to
care about set_rate status, when fail, i must set some rate, when success i must
set other rate.

I think that it is not good to get the alrady decided opp
by devfreq_recommended_opp(). Usually, devfreq_recommended_opp() is used
to get the proper opp which get the close frequency (dmcfreq->rate).

Also, When finishing the rk3399_dmcfreq_target(), the rk3399_dmc.c
have to know the current opp or rate without any finding sequence.
The additional finding procedure is un-needed.


+rcu_read_unlock();
+
+if (dmcfreq->rate == target_rate)
+return 0;
+
+mutex_lock(>lock);
+
+/*
+ * if frequency scaling from low to high, adjust voltage first;
+ * if frequency scaling from high to low, adjuset frequency first;
+ */

s/adjuset/adjust

I recommend that you use a captital letter for first character and use the '.'
instead of ';'.


+if (old_clk_rate < target_rate) {
+err = regulator_set_voltage(dmcfreq->vdd_center, target_volt,
+target_volt);
+if (err) {
+dev_err(dev, "Unable to set vol %lu\n", target_volt);

To readability, you better to use the corrent word to pass the precise the log 
message.
- s/vol/voltage

And, this patch uses the 'Unable to' or 'Cannot' to show the error log.
I recommend that you use the consistent expression if there is not any specific 
reason.

 dev_err(dev, "Cannot set the voltage %lu uV\n", target_volt);


+goto out;
+}
+}
+dmcfreq->wait_dcf_flag = 1;
+err = clk_set_rate(dmcfreq->dmc_clk, target_rate);
+if (err) {
+dev_err(dev,
+"Una

Re: [PATCH v4 6/7] PM / devfreq: rockchip: add devfreq driver for rk3399 dmc

2016-08-03 Thread hl


Hi Chanwoo Choi,
On 2016年08月02日 12:21, Chanwoo Choi wrote:

Hi Lin,

On the next version, I'd like you to add the 'linux...@vger.kernel.org'
because devfreq is a subsystem of power management.

Sure, will do it next version.

On 2016년 08월 02일 10:03, hl wrote:

Hi Chanwoo Choi,

 Thanks for reviewing so carefully. And i have some question:

On 2016年08月01日 18:28, Chanwoo Choi wrote:

Hi Lin,

As I mentioned on patch5, you better to make the documentation as following:
- Documentation/devicetree/bindings/devfreq/rk3399_dmc.txt
And, I add the comments.


On 2016년 07월 29일 16:57, Lin Huang wrote:

base on dfi result, we do ddr frequency scaling, register
dmc driver to devfreq framework, and use simple-ondemand
policy.

Signed-off-by: Lin Huang 
---
Changes in v4:
- use arm_smccc_smc() function talk to bl31
- delete rockchip_dmc.c file and config
- delete dmc_notify
- adjust probe order
   Changes in v3:
- operate dram setting through sip call
- imporve set rate flow

Changes in v2:
- None
   Changes in v1:
- move dfi controller to event
- fix set voltage sequence when set rate fail
- change Kconfig type from tristate to bool
- move unuse EXPORT_SYMBOL_GPL()

   drivers/devfreq/Kconfig   |   1 +
   drivers/devfreq/Makefile  |   1 +
   drivers/devfreq/rockchip/Kconfig  |   8 +
   drivers/devfreq/rockchip/Makefile |   1 +
   drivers/devfreq/rockchip/rk3399_dmc.c | 473 
++
   5 files changed, 484 insertions(+)
   create mode 100644 drivers/devfreq/rockchip/Kconfig
   create mode 100644 drivers/devfreq/rockchip/Makefile
   create mode 100644 drivers/devfreq/rockchip/rk3399_dmc.c


[snip]


+
+static int rk3399_dmcfreq_target(struct device *dev, unsigned long *freq,
+ u32 flags)
+{
+struct platform_device *pdev = container_of(dev, struct platform_device,
+dev);
+struct rk3399_dmcfreq *dmcfreq = platform_get_drvdata(pdev);

You can use the 'dev_get_drvdata()' to simplify it instead of 
'platform_get_drvdata()'.

 struct rk3399_dmcfreq *dmcfreq = dev_get_drvdata(dev);


+struct dev_pm_opp *opp;
+unsigned long old_clk_rate = dmcfreq->rate;
+unsigned long target_volt, target_rate;
+int err;
+
+rcu_read_lock();
+opp = devfreq_recommended_opp(dev, freq, flags);
+if (IS_ERR(opp)) {
+rcu_read_unlock();
+return PTR_ERR(opp);
+}
+
+target_rate = dev_pm_opp_get_freq(opp);
+target_volt = dev_pm_opp_get_voltage(opp);
+opp = devfreq_recommended_opp(dev, >rate, flags);
+if (IS_ERR(opp)) {
+rcu_read_unlock();
+return PTR_ERR(opp);
+}
+dmcfreq->volt = dev_pm_opp_get_voltage(opp);

If you add the 'curr_opp' variable to struct rk3399_dmcfreq,
you can remove the calling of devfreq_recommended_opp().
 dmcfreq->rate = dev_pm_opp_get_freq(dmcfreq->curr_opp);
 dmcfreq->volt = dev_pm_opp_get_freq(dmcfreq->curr_opp);

Because the current rate and voltage is already decided on previous polling 
cycle,
So we don't need to get the opp with devfreq_recommended_opp().

I prefer the way now use, since we get the dmcfreq->rate use clk_get_rate() 
after,
Base on that,  i do not care the set_rate success or fail. use curr_opp i need 
to
care about set_rate status, when fail, i must set some rate, when success i must
set other rate.

I think that it is not good to get the alrady decided opp
by devfreq_recommended_opp(). Usually, devfreq_recommended_opp() is used
to get the proper opp which get the close frequency (dmcfreq->rate).

Also, When finishing the rk3399_dmcfreq_target(), the rk3399_dmc.c
have to know the current opp or rate without any finding sequence.
The additional finding procedure is un-needed.


+rcu_read_unlock();
+
+if (dmcfreq->rate == target_rate)
+return 0;
+
+mutex_lock(>lock);
+
+/*
+ * if frequency scaling from low to high, adjust voltage first;
+ * if frequency scaling from high to low, adjuset frequency first;
+ */

s/adjuset/adjust

I recommend that you use a captital letter for first character and use the '.'
instead of ';'.


+if (old_clk_rate < target_rate) {
+err = regulator_set_voltage(dmcfreq->vdd_center, target_volt,
+target_volt);
+if (err) {
+dev_err(dev, "Unable to set vol %lu\n", target_volt);

To readability, you better to use the corrent word to pass the precise the log 
message.
- s/vol/voltage

And, this patch uses the 'Unable to' or 'Cannot' to show the error log.
I recommend that you use the consistent expression if there is not any specific 
reason.

 dev_err(dev, "Cannot set the voltage %lu uV\n", target_volt);


+goto out;
+}
+}
+dmcfreq->wait_dcf_flag = 1;
+err = clk_set_rate(dmcfreq->dmc_clk, target_rate);
+if (err) {
+dev_err(dev,
+"Unable to set freq %lu. Curr

Re: [PATCH v4 6/7] PM / devfreq: rockchip: add devfreq driver for rk3399 dmc

2016-08-01 Thread hl

Hi Chanwoo Choi,

Thanks for reviewing so carefully. And i have some question:

On 2016年08月01日 18:28, Chanwoo Choi wrote:

Hi Lin,

As I mentioned on patch5, you better to make the documentation as following:
- Documentation/devicetree/bindings/devfreq/rk3399_dmc.txt
And, I add the comments.


On 2016년 07월 29일 16:57, Lin Huang wrote:

base on dfi result, we do ddr frequency scaling, register
dmc driver to devfreq framework, and use simple-ondemand
policy.

Signed-off-by: Lin Huang 
---
Changes in v4:
- use arm_smccc_smc() function talk to bl31
- delete rockchip_dmc.c file and config
- delete dmc_notify
- adjust probe order
  
Changes in v3:

- operate dram setting through sip call
- imporve set rate flow

Changes in v2:
- None
  
Changes in v1:

- move dfi controller to event
- fix set voltage sequence when set rate fail
- change Kconfig type from tristate to bool
- move unuse EXPORT_SYMBOL_GPL()

  drivers/devfreq/Kconfig   |   1 +
  drivers/devfreq/Makefile  |   1 +
  drivers/devfreq/rockchip/Kconfig  |   8 +
  drivers/devfreq/rockchip/Makefile |   1 +
  drivers/devfreq/rockchip/rk3399_dmc.c | 473 ++
  5 files changed, 484 insertions(+)
  create mode 100644 drivers/devfreq/rockchip/Kconfig
  create mode 100644 drivers/devfreq/rockchip/Makefile
  create mode 100644 drivers/devfreq/rockchip/rk3399_dmc.c

diff --git a/drivers/devfreq/Kconfig b/drivers/devfreq/Kconfig
index 64281bb..acb2a57 100644
--- a/drivers/devfreq/Kconfig
+++ b/drivers/devfreq/Kconfig
@@ -99,5 +99,6 @@ config ARM_TEGRA_DEVFREQ
   operating frequencies and voltages with OPP support.
  
  source "drivers/devfreq/event/Kconfig"

+source "drivers/devfreq/rockchip/Kconfig"

This patch include the only one patch. So, I think that
you don't need to create the 'rockchip' directory.

  
  endif # PM_DEVFREQ

diff --git a/drivers/devfreq/Makefile b/drivers/devfreq/Makefile
index 5134f9e..d844e23 100644
--- a/drivers/devfreq/Makefile
+++ b/drivers/devfreq/Makefile
@@ -9,6 +9,7 @@ obj-$(CONFIG_DEVFREQ_GOV_USERSPACE) += governor_userspace.o
  obj-$(CONFIG_ARM_EXYNOS4_BUS_DEVFREQ) += exynos/
  obj-$(CONFIG_ARM_EXYNOS5_BUS_DEVFREQ) += exynos/
  obj-$(CONFIG_ARM_TEGRA_DEVFREQ)   += tegra-devfreq.o
+obj-$(CONFIG_ARCH_ROCKCHIP)+= rockchip/

ditto.

  
  # DEVFREQ Event Drivers

  obj-$(CONFIG_PM_DEVFREQ_EVENT)+= event/
diff --git a/drivers/devfreq/rockchip/Kconfig b/drivers/devfreq/rockchip/Kconfig
new file mode 100644
index 000..d8f9e66
--- /dev/null
+++ b/drivers/devfreq/rockchip/Kconfig
@@ -0,0 +1,8 @@
+config ARM_RK3399_DMC_DEVFREQ
+   tristate "ARM RK3399 DMC DEVFREQ Driver"
+   select PM_OPP
+   select DEVFREQ_GOV_SIMPLE_ONDEMAND
+   help
+  This adds the DEVFREQ driver for the RK3399 dmc. It sets the 
frequency

If you add the full description for 'dmc' as following,
it is easy to understand the operation of this device driver.
- DMC (Dynamic Memory Controller)


+  for the memory controller and reads the usage counts from hardware.
+
diff --git a/drivers/devfreq/rockchip/Makefile 
b/drivers/devfreq/rockchip/Makefile
new file mode 100644
index 000..c62c105
--- /dev/null
+++ b/drivers/devfreq/rockchip/Makefile
@@ -0,0 +1 @@
+obj-$(CONFIG_ARM_RK3399_DMC_DEVFREQ)   += rk3399_dmc.o
diff --git a/drivers/devfreq/rockchip/rk3399_dmc.c 
b/drivers/devfreq/rockchip/rk3399_dmc.c
new file mode 100644
index 000..527aa11
--- /dev/null
+++ b/drivers/devfreq/rockchip/rk3399_dmc.c
@@ -0,0 +1,473 @@
+/*
+ * Copyright (c) 2016, Fuzhou Rockchip Electronics Co., Ltd

You miss the '.' at the end of the copylight.
When you use an abbreviation, you should add '.' for Ltd.
- s/Ltd/Ltd.



+ * Author: Lin Huang 
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ */
+
+#include 
+#include 
+#include 

You don't need to include the "completion.h".
Without "completion.h", the build is working.


+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 

You don't need to include the "syscore_ops.h".
Without "syscore_ops.h", the build is working.


+
+#include 
+
+struct dram_timing {
+   unsigned int ddr3_speed_bin;
+   unsigned int pd_idle;
+   unsigned int sr_idle;
+   unsigned int sr_mc_gate_idle;
+   unsigned int srpd_lite_idle;
+   unsigned int standby_idle;
+   unsigned int dram_dll_dis_freq;
+   unsigned int phy_dll_dis_freq;
+   unsigned int 

Re: [PATCH v4 6/7] PM / devfreq: rockchip: add devfreq driver for rk3399 dmc

2016-08-01 Thread hl

Hi Chanwoo Choi,

Thanks for reviewing so carefully. And i have some question:

On 2016年08月01日 18:28, Chanwoo Choi wrote:

Hi Lin,

As I mentioned on patch5, you better to make the documentation as following:
- Documentation/devicetree/bindings/devfreq/rk3399_dmc.txt
And, I add the comments.


On 2016년 07월 29일 16:57, Lin Huang wrote:

base on dfi result, we do ddr frequency scaling, register
dmc driver to devfreq framework, and use simple-ondemand
policy.

Signed-off-by: Lin Huang 
---
Changes in v4:
- use arm_smccc_smc() function talk to bl31
- delete rockchip_dmc.c file and config
- delete dmc_notify
- adjust probe order
  
Changes in v3:

- operate dram setting through sip call
- imporve set rate flow

Changes in v2:
- None
  
Changes in v1:

- move dfi controller to event
- fix set voltage sequence when set rate fail
- change Kconfig type from tristate to bool
- move unuse EXPORT_SYMBOL_GPL()

  drivers/devfreq/Kconfig   |   1 +
  drivers/devfreq/Makefile  |   1 +
  drivers/devfreq/rockchip/Kconfig  |   8 +
  drivers/devfreq/rockchip/Makefile |   1 +
  drivers/devfreq/rockchip/rk3399_dmc.c | 473 ++
  5 files changed, 484 insertions(+)
  create mode 100644 drivers/devfreq/rockchip/Kconfig
  create mode 100644 drivers/devfreq/rockchip/Makefile
  create mode 100644 drivers/devfreq/rockchip/rk3399_dmc.c

diff --git a/drivers/devfreq/Kconfig b/drivers/devfreq/Kconfig
index 64281bb..acb2a57 100644
--- a/drivers/devfreq/Kconfig
+++ b/drivers/devfreq/Kconfig
@@ -99,5 +99,6 @@ config ARM_TEGRA_DEVFREQ
   operating frequencies and voltages with OPP support.
  
  source "drivers/devfreq/event/Kconfig"

+source "drivers/devfreq/rockchip/Kconfig"

This patch include the only one patch. So, I think that
you don't need to create the 'rockchip' directory.

  
  endif # PM_DEVFREQ

diff --git a/drivers/devfreq/Makefile b/drivers/devfreq/Makefile
index 5134f9e..d844e23 100644
--- a/drivers/devfreq/Makefile
+++ b/drivers/devfreq/Makefile
@@ -9,6 +9,7 @@ obj-$(CONFIG_DEVFREQ_GOV_USERSPACE) += governor_userspace.o
  obj-$(CONFIG_ARM_EXYNOS4_BUS_DEVFREQ) += exynos/
  obj-$(CONFIG_ARM_EXYNOS5_BUS_DEVFREQ) += exynos/
  obj-$(CONFIG_ARM_TEGRA_DEVFREQ)   += tegra-devfreq.o
+obj-$(CONFIG_ARCH_ROCKCHIP)+= rockchip/

ditto.

  
  # DEVFREQ Event Drivers

  obj-$(CONFIG_PM_DEVFREQ_EVENT)+= event/
diff --git a/drivers/devfreq/rockchip/Kconfig b/drivers/devfreq/rockchip/Kconfig
new file mode 100644
index 000..d8f9e66
--- /dev/null
+++ b/drivers/devfreq/rockchip/Kconfig
@@ -0,0 +1,8 @@
+config ARM_RK3399_DMC_DEVFREQ
+   tristate "ARM RK3399 DMC DEVFREQ Driver"
+   select PM_OPP
+   select DEVFREQ_GOV_SIMPLE_ONDEMAND
+   help
+  This adds the DEVFREQ driver for the RK3399 dmc. It sets the 
frequency

If you add the full description for 'dmc' as following,
it is easy to understand the operation of this device driver.
- DMC (Dynamic Memory Controller)


+  for the memory controller and reads the usage counts from hardware.
+
diff --git a/drivers/devfreq/rockchip/Makefile 
b/drivers/devfreq/rockchip/Makefile
new file mode 100644
index 000..c62c105
--- /dev/null
+++ b/drivers/devfreq/rockchip/Makefile
@@ -0,0 +1 @@
+obj-$(CONFIG_ARM_RK3399_DMC_DEVFREQ)   += rk3399_dmc.o
diff --git a/drivers/devfreq/rockchip/rk3399_dmc.c 
b/drivers/devfreq/rockchip/rk3399_dmc.c
new file mode 100644
index 000..527aa11
--- /dev/null
+++ b/drivers/devfreq/rockchip/rk3399_dmc.c
@@ -0,0 +1,473 @@
+/*
+ * Copyright (c) 2016, Fuzhou Rockchip Electronics Co., Ltd

You miss the '.' at the end of the copylight.
When you use an abbreviation, you should add '.' for Ltd.
- s/Ltd/Ltd.



+ * Author: Lin Huang 
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ */
+
+#include 
+#include 
+#include 

You don't need to include the "completion.h".
Without "completion.h", the build is working.


+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 

You don't need to include the "syscore_ops.h".
Without "syscore_ops.h", the build is working.


+
+#include 
+
+struct dram_timing {
+   unsigned int ddr3_speed_bin;
+   unsigned int pd_idle;
+   unsigned int sr_idle;
+   unsigned int sr_mc_gate_idle;
+   unsigned int srpd_lite_idle;
+   unsigned int standby_idle;
+   unsigned int dram_dll_dis_freq;
+   unsigned int phy_dll_dis_freq;
+   unsigned int ddr3_odt_dis_freq;
+   unsigned int ddr3_drv;
+   

Re: [PATCH v4 5/7] PM / devfreq: event: support rockchip dfi controller

2016-08-01 Thread hl

Hi Chanwoo Choi,

On 2016年08月01日 16:08, Chanwoo Choi wrote:

Hi Lin,

I add the one minor comment for full name of 'DRI'.

On 2016년 08월 01일 16:41, Chanwoo Choi wrote:

Hi Lin,

Because you remove the 'RFC' prefix on patch title,
I think that you better to make the documentation as following:
- Documentation/devicetree/bindings/devfreq/event/rockchip-dfi.txt

Regards,
Chanwoo Choi

On 2016년 07월 29일 16:56, Lin Huang wrote:

on rk3399 platform, there is dfi conroller can monitor
ddr load, base on this result, we can do ddr freqency
scaling.

Signed-off-by: Lin Huang 
Acked-by: Chanwoo Choi 
---
Changes in v4:
- None

Changes in v3:
- None

Changes in v2:
- use clk_disable_unprepare and clk_enable_prepare
- remove clk_enable_prepare in probe
- remove rockchip_dfi_remove function

Changes in v1:
- None

  drivers/devfreq/event/Kconfig|   7 +
  drivers/devfreq/event/Makefile   |   1 +
  drivers/devfreq/event/rockchip-dfi.c | 253 +++
  3 files changed, 261 insertions(+)
  create mode 100644 drivers/devfreq/event/rockchip-dfi.c

diff --git a/drivers/devfreq/event/Kconfig b/drivers/devfreq/event/Kconfig
index a11720a..ff9279f 100644
--- a/drivers/devfreq/event/Kconfig
+++ b/drivers/devfreq/event/Kconfig
@@ -22,4 +22,11 @@ config DEVFREQ_EVENT_EXYNOS_PPMU
  (Platform Performance Monitoring Unit) counters to estimate the
  utilization of each module.
  
+config DEVFREQ_EVENT_ROCKCHIP_DFI

+   tristate "ROCKCHIP DFI DEVFREQ event Driver"
+   depends on ARCH_ROCKCHIP
+   help
+ This add the devfreq-event driver for Rockchip SoC. It provides DFI
+ (DDR Monitor Module) driver to count ddr load.

The DFI is "DDR Monitor Module" full name? I need the correct abbreviation
and full name.
We just call this module DFI in datasheet, and this module function is 
ddr monitor module,
yes, it is do not fit the full name, but i think it is better follow the 
datasheet name.



+
  endif # PM_DEVFREQ_EVENT
diff --git a/drivers/devfreq/event/Makefile b/drivers/devfreq/event/Makefile
index be146ea..e3f88fc 100644
--- a/drivers/devfreq/event/Makefile
+++ b/drivers/devfreq/event/Makefile
@@ -1,2 +1,3 @@
  # Exynos DEVFREQ Event Drivers
  obj-$(CONFIG_DEVFREQ_EVENT_EXYNOS_PPMU) += exynos-ppmu.o
+obj-$(CONFIG_DEVFREQ_EVENT_ROCKCHIP_DFI) += rockchip-dfi.o
diff --git a/drivers/devfreq/event/rockchip-dfi.c 
b/drivers/devfreq/event/rockchip-dfi.c
new file mode 100644
index 000..96a0307
--- /dev/null
+++ b/drivers/devfreq/event/rockchip-dfi.c
@@ -0,0 +1,253 @@
+/*
+ * Copyright (c) 2016, Fuzhou Rockchip Electronics Co., Ltd
+ * Author: Lin Huang 
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#define RK3399_DMC_NUM_CH  2
+
+/* DDRMON_CTRL */
+#define DDRMON_CTRL0x04
+#define CLR_DDRMON_CTRL(0x1f << 0)
+#define LPDDR4_EN  (0x10001 << 4)
+#define HARDWARE_EN(0x10001 << 3)
+#define LPDDR3_EN  (0x10001 << 2)
+#define SOFTWARE_EN(0x10001 << 1)
+#define TIME_CNT_EN(0x10001 << 0)
+
+#define DDRMON_CH0_COUNT_NUM   0x28
+#define DDRMON_CH0_DFI_ACCESS_NUM  0x2c
+#define DDRMON_CH1_COUNT_NUM   0x3c
+#define DDRMON_CH1_DFI_ACCESS_NUM  0x40
+
+/* pmu grf */
+#define PMUGRF_OS_REG2 0x308
+#define DDRTYPE_SHIFT  13
+#define DDRTYPE_MASK   7
+
+enum {
+   DDR3 = 3,
+   LPDDR3 = 6,
+   LPDDR4 = 7,
+   UNUSED = 0xFF
+};
+
+struct dmc_usage {
+   u32 access;
+   u32 total;
+};
+
+struct rockchip_dfi {
+   struct devfreq_event_dev *edev;
+   struct devfreq_event_desc *desc;
+   struct dmc_usage ch_usage[RK3399_DMC_NUM_CH];
+   struct device *dev;
+   void __iomem *regs;
+   struct regmap *regmap_pmu;
+   struct clk *clk;
+};
+
+static void rockchip_dfi_start_hardware_counter(struct devfreq_event_dev *edev)
+{
+   struct rockchip_dfi *info = devfreq_event_get_drvdata(edev);
+   void __iomem *dfi_regs = info->regs;
+   u32 val;
+   u32 ddr_type;
+
+   /* get ddr type */
+   regmap_read(info->regmap_pmu, PMUGRF_OS_REG2, );
+   ddr_type = (val >> DDRTYPE_SHIFT) & DDRTYPE_MASK;
+
+   /* clear DDRMON_CTRL setting */
+   writel_relaxed(CLR_DDRMON_CTRL, dfi_regs + DDRMON_CTRL);
+
+   /* set ddr type to dfi */
+   if (ddr_type == LPDDR3)
+   writel_relaxed(LPDDR3_EN, dfi_regs + DDRMON_CTRL);
+ 

Re: [PATCH v4 5/7] PM / devfreq: event: support rockchip dfi controller

2016-08-01 Thread hl

Hi Chanwoo Choi,

On 2016年08月01日 16:08, Chanwoo Choi wrote:

Hi Lin,

I add the one minor comment for full name of 'DRI'.

On 2016년 08월 01일 16:41, Chanwoo Choi wrote:

Hi Lin,

Because you remove the 'RFC' prefix on patch title,
I think that you better to make the documentation as following:
- Documentation/devicetree/bindings/devfreq/event/rockchip-dfi.txt

Regards,
Chanwoo Choi

On 2016년 07월 29일 16:56, Lin Huang wrote:

on rk3399 platform, there is dfi conroller can monitor
ddr load, base on this result, we can do ddr freqency
scaling.

Signed-off-by: Lin Huang 
Acked-by: Chanwoo Choi 
---
Changes in v4:
- None

Changes in v3:
- None

Changes in v2:
- use clk_disable_unprepare and clk_enable_prepare
- remove clk_enable_prepare in probe
- remove rockchip_dfi_remove function

Changes in v1:
- None

  drivers/devfreq/event/Kconfig|   7 +
  drivers/devfreq/event/Makefile   |   1 +
  drivers/devfreq/event/rockchip-dfi.c | 253 +++
  3 files changed, 261 insertions(+)
  create mode 100644 drivers/devfreq/event/rockchip-dfi.c

diff --git a/drivers/devfreq/event/Kconfig b/drivers/devfreq/event/Kconfig
index a11720a..ff9279f 100644
--- a/drivers/devfreq/event/Kconfig
+++ b/drivers/devfreq/event/Kconfig
@@ -22,4 +22,11 @@ config DEVFREQ_EVENT_EXYNOS_PPMU
  (Platform Performance Monitoring Unit) counters to estimate the
  utilization of each module.
  
+config DEVFREQ_EVENT_ROCKCHIP_DFI

+   tristate "ROCKCHIP DFI DEVFREQ event Driver"
+   depends on ARCH_ROCKCHIP
+   help
+ This add the devfreq-event driver for Rockchip SoC. It provides DFI
+ (DDR Monitor Module) driver to count ddr load.

The DFI is "DDR Monitor Module" full name? I need the correct abbreviation
and full name.
We just call this module DFI in datasheet, and this module function is 
ddr monitor module,
yes, it is do not fit the full name, but i think it is better follow the 
datasheet name.



+
  endif # PM_DEVFREQ_EVENT
diff --git a/drivers/devfreq/event/Makefile b/drivers/devfreq/event/Makefile
index be146ea..e3f88fc 100644
--- a/drivers/devfreq/event/Makefile
+++ b/drivers/devfreq/event/Makefile
@@ -1,2 +1,3 @@
  # Exynos DEVFREQ Event Drivers
  obj-$(CONFIG_DEVFREQ_EVENT_EXYNOS_PPMU) += exynos-ppmu.o
+obj-$(CONFIG_DEVFREQ_EVENT_ROCKCHIP_DFI) += rockchip-dfi.o
diff --git a/drivers/devfreq/event/rockchip-dfi.c 
b/drivers/devfreq/event/rockchip-dfi.c
new file mode 100644
index 000..96a0307
--- /dev/null
+++ b/drivers/devfreq/event/rockchip-dfi.c
@@ -0,0 +1,253 @@
+/*
+ * Copyright (c) 2016, Fuzhou Rockchip Electronics Co., Ltd
+ * Author: Lin Huang 
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#define RK3399_DMC_NUM_CH  2
+
+/* DDRMON_CTRL */
+#define DDRMON_CTRL0x04
+#define CLR_DDRMON_CTRL(0x1f << 0)
+#define LPDDR4_EN  (0x10001 << 4)
+#define HARDWARE_EN(0x10001 << 3)
+#define LPDDR3_EN  (0x10001 << 2)
+#define SOFTWARE_EN(0x10001 << 1)
+#define TIME_CNT_EN(0x10001 << 0)
+
+#define DDRMON_CH0_COUNT_NUM   0x28
+#define DDRMON_CH0_DFI_ACCESS_NUM  0x2c
+#define DDRMON_CH1_COUNT_NUM   0x3c
+#define DDRMON_CH1_DFI_ACCESS_NUM  0x40
+
+/* pmu grf */
+#define PMUGRF_OS_REG2 0x308
+#define DDRTYPE_SHIFT  13
+#define DDRTYPE_MASK   7
+
+enum {
+   DDR3 = 3,
+   LPDDR3 = 6,
+   LPDDR4 = 7,
+   UNUSED = 0xFF
+};
+
+struct dmc_usage {
+   u32 access;
+   u32 total;
+};
+
+struct rockchip_dfi {
+   struct devfreq_event_dev *edev;
+   struct devfreq_event_desc *desc;
+   struct dmc_usage ch_usage[RK3399_DMC_NUM_CH];
+   struct device *dev;
+   void __iomem *regs;
+   struct regmap *regmap_pmu;
+   struct clk *clk;
+};
+
+static void rockchip_dfi_start_hardware_counter(struct devfreq_event_dev *edev)
+{
+   struct rockchip_dfi *info = devfreq_event_get_drvdata(edev);
+   void __iomem *dfi_regs = info->regs;
+   u32 val;
+   u32 ddr_type;
+
+   /* get ddr type */
+   regmap_read(info->regmap_pmu, PMUGRF_OS_REG2, );
+   ddr_type = (val >> DDRTYPE_SHIFT) & DDRTYPE_MASK;
+
+   /* clear DDRMON_CTRL setting */
+   writel_relaxed(CLR_DDRMON_CTRL, dfi_regs + DDRMON_CTRL);
+
+   /* set ddr type to dfi */
+   if (ddr_type == LPDDR3)
+   writel_relaxed(LPDDR3_EN, dfi_regs + DDRMON_CTRL);
+   else if (ddr_type == LPDDR4)
+   

Re: [PATCH v4 0/7] rk3399 support ddr frequency scaling

2016-08-01 Thread hl

Hi Chanwoo Choi,

Ah, i am base on 
https://chromium.googlesource.com/chromiumos/third_party/kernel/v4.4,
and forget to rebase on 
https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git, i 
will fix it in next version.
I am sorry about that. And can you help to review the devfreq patch 
first, if something need to update,

i will do it together. Thanks.

On 2016年08月01日 15:39, Chanwoo Choi wrote:

Hi Lin,

On 2016년 07월 29일 16:56, Lin Huang wrote:

rk3399 platform have dfi controller can monitor ddr load,
and dcf controller to handle ddr register so we can get the
right ddr frequency and make ddr controller happy work(which
will implement in bl31). So we do ddr frequency scaling with
following flow:

 kernelbl31

monitor ddr load
|
|
get_target_rate
|
|   pass rate to bl31
clk_set_rate(ddr) ->run dcf flow
|   |
|   |
wait dcf interrupt<---trigger dcf interrupt
|
|
  return

Lin Huang (6):
   clk: rockchip: add new clock-type for the ddrclk
   clk: rockchip: rk3399: add SCLK_DDRCLK ID for ddrc
   clk: rockchip: rk3399: add ddrc clock support
   PM / devfreq: event: support rockchip dfi controller
   PM / devfreq: rockchip: add devfreq driver for rk3399 dmc
   drm/rockchip: Add dmc notifier in vop driver


Heiko Stübner (1):
   clk: rockchip: add clock flag parameter when register pll

Lin Huang (6):
   clk: rockchip: add new clock-type for the ddrclk
   clk: rockchip: rk3399: add SCLK_DDRCLK ID for ddrc
   clk: rockchip: rk3399: add ddrc clock support
   PM / devfreq: event: support rockchip dfi controller
   PM / devfreq: rockchip: add devfreq driver for rk3399 dmc
   drm/rockchip: Add dmc notifier in vop driver

The cover-letter includes the duplicate list of patches.

Also, I want to test the build test. but, When I apply these patches,
merge conflict happen. Could you give the information about base git repository?

Regards,
Chanwoo Choi



  drivers/clk/rockchip/Makefile   |   1 +
  drivers/clk/rockchip/clk-ddr.c  | 146 +
  drivers/clk/rockchip/clk-pll.c  |   4 +-
  drivers/clk/rockchip/clk-rk3399.c   |  19 ++
  drivers/clk/rockchip/clk.c  |  11 +-
  drivers/clk/rockchip/clk.h  |  29 +-
  drivers/devfreq/Kconfig |   1 +
  drivers/devfreq/Makefile|   1 +
  drivers/devfreq/event/Kconfig   |   7 +
  drivers/devfreq/event/Makefile  |   1 +
  drivers/devfreq/event/rockchip-dfi.c| 253 +++
  drivers/devfreq/rockchip/Kconfig|   8 +
  drivers/devfreq/rockchip/Makefile   |   1 +
  drivers/devfreq/rockchip/rk3399_dmc.c   | 473 
  drivers/gpu/drm/rockchip/rockchip_drm_vop.c | 124 +++-
  include/dt-bindings/clock/rk3399-cru.h  |   1 +
  include/soc/rockchip/rockchip_sip.h |  27 ++
  17 files changed, 1098 insertions(+), 9 deletions(-)
  create mode 100644 drivers/clk/rockchip/clk-ddr.c
  create mode 100644 drivers/devfreq/event/rockchip-dfi.c
  create mode 100644 drivers/devfreq/rockchip/Kconfig
  create mode 100644 drivers/devfreq/rockchip/Makefile
  create mode 100644 drivers/devfreq/rockchip/rk3399_dmc.c
  create mode 100644 include/soc/rockchip/rockchip_sip.h







--
Lin Huang




Re: [PATCH v4 0/7] rk3399 support ddr frequency scaling

2016-08-01 Thread hl

Hi Chanwoo Choi,

Ah, i am base on 
https://chromium.googlesource.com/chromiumos/third_party/kernel/v4.4,
and forget to rebase on 
https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git, i 
will fix it in next version.
I am sorry about that. And can you help to review the devfreq patch 
first, if something need to update,

i will do it together. Thanks.

On 2016年08月01日 15:39, Chanwoo Choi wrote:

Hi Lin,

On 2016년 07월 29일 16:56, Lin Huang wrote:

rk3399 platform have dfi controller can monitor ddr load,
and dcf controller to handle ddr register so we can get the
right ddr frequency and make ddr controller happy work(which
will implement in bl31). So we do ddr frequency scaling with
following flow:

 kernelbl31

monitor ddr load
|
|
get_target_rate
|
|   pass rate to bl31
clk_set_rate(ddr) ->run dcf flow
|   |
|   |
wait dcf interrupt<---trigger dcf interrupt
|
|
  return

Lin Huang (6):
   clk: rockchip: add new clock-type for the ddrclk
   clk: rockchip: rk3399: add SCLK_DDRCLK ID for ddrc
   clk: rockchip: rk3399: add ddrc clock support
   PM / devfreq: event: support rockchip dfi controller
   PM / devfreq: rockchip: add devfreq driver for rk3399 dmc
   drm/rockchip: Add dmc notifier in vop driver


Heiko Stübner (1):
   clk: rockchip: add clock flag parameter when register pll

Lin Huang (6):
   clk: rockchip: add new clock-type for the ddrclk
   clk: rockchip: rk3399: add SCLK_DDRCLK ID for ddrc
   clk: rockchip: rk3399: add ddrc clock support
   PM / devfreq: event: support rockchip dfi controller
   PM / devfreq: rockchip: add devfreq driver for rk3399 dmc
   drm/rockchip: Add dmc notifier in vop driver

The cover-letter includes the duplicate list of patches.

Also, I want to test the build test. but, When I apply these patches,
merge conflict happen. Could you give the information about base git repository?

Regards,
Chanwoo Choi



  drivers/clk/rockchip/Makefile   |   1 +
  drivers/clk/rockchip/clk-ddr.c  | 146 +
  drivers/clk/rockchip/clk-pll.c  |   4 +-
  drivers/clk/rockchip/clk-rk3399.c   |  19 ++
  drivers/clk/rockchip/clk.c  |  11 +-
  drivers/clk/rockchip/clk.h  |  29 +-
  drivers/devfreq/Kconfig |   1 +
  drivers/devfreq/Makefile|   1 +
  drivers/devfreq/event/Kconfig   |   7 +
  drivers/devfreq/event/Makefile  |   1 +
  drivers/devfreq/event/rockchip-dfi.c| 253 +++
  drivers/devfreq/rockchip/Kconfig|   8 +
  drivers/devfreq/rockchip/Makefile   |   1 +
  drivers/devfreq/rockchip/rk3399_dmc.c   | 473 
  drivers/gpu/drm/rockchip/rockchip_drm_vop.c | 124 +++-
  include/dt-bindings/clock/rk3399-cru.h  |   1 +
  include/soc/rockchip/rockchip_sip.h |  27 ++
  17 files changed, 1098 insertions(+), 9 deletions(-)
  create mode 100644 drivers/clk/rockchip/clk-ddr.c
  create mode 100644 drivers/devfreq/event/rockchip-dfi.c
  create mode 100644 drivers/devfreq/rockchip/Kconfig
  create mode 100644 drivers/devfreq/rockchip/Makefile
  create mode 100644 drivers/devfreq/rockchip/rk3399_dmc.c
  create mode 100644 include/soc/rockchip/rockchip_sip.h







--
Lin Huang




Re: [PATCH v3 6/7] PM / devfreq: rockchip: add devfreq driver for rk3399 dmc

2016-07-25 Thread hl

Hi Chanwoo Choi,

On 2016年07月25日 17:45, Chanwoo Choi wrote:

Hi Lin,

On 2016년 07월 25일 17:47, hl wrote:

Hi Chanwoo Choi,

On 2016年07月25日 14:01, Chanwoo Choi wrote:

Hi Lin,

I'm glad to support the for dmc ddr clock scaling with devfreq/devfreq-event.

But, I think that you have to use the standard interface.
As I already mentioned[1] on previous mail, devfreq fwk support
the standard DEVFREQ_TRANSITION_NOTIFIER notifier which has the two 
notifications.
- DEVFREQ_PRECHANGE
- DEVFREQ_POSTCHANGE
[1] https://patchwork.kernel.org/patch/9194305/

You can use the DEVFREQ_PRECHANGE instead of DMCFREQ_ADJUST
and use the DEVFREQ_POSTCHANGE instead of DMCFREQ_FINISH.

On 2016년 07월 22일 18:07, Lin Huang wrote:

base on dfi result, we do ddr frequency scaling, register
dmc driver to devfreq framework, and use simple-ondemand
policy.

Signed-off-by: Lin Huang <h...@rock-chips.com>
---
Changes in v3:
- operate dram setting through sip call
- imporve set rate flow

Changes in v2:
- None
   Changes in v1:
- move dfi controller to event
- fix set voltage sequence when set rate fail
- change Kconfig type from tristate to bool
- move unuse EXPORT_SYMBOL_GPL()

   drivers/devfreq/Kconfig |   1 +
   drivers/devfreq/Makefile|   1 +
   drivers/devfreq/rockchip/Kconfig|  15 +
   drivers/devfreq/rockchip/Makefile   |   2 +
   drivers/devfreq/rockchip/rk3399_dmc.c   | 482 

   drivers/devfreq/rockchip/rockchip_dmc.c | 143 ++
   include/soc/rockchip/rockchip_dmc.h |  45 +++
   7 files changed, 689 insertions(+)
   create mode 100644 drivers/devfreq/rockchip/Kconfig
   create mode 100644 drivers/devfreq/rockchip/Makefile
   create mode 100644 drivers/devfreq/rockchip/rk3399_dmc.c
   create mode 100644 drivers/devfreq/rockchip/rockchip_dmc.c
   create mode 100644 include/soc/rockchip/rockchip_dmc.h

diff --git a/drivers/devfreq/Kconfig b/drivers/devfreq/Kconfig
index a5be56e..cb67246 100644
--- a/drivers/devfreq/Kconfig
+++ b/drivers/devfreq/Kconfig
@@ -101,5 +101,6 @@ config ARM_TEGRA_DEVFREQ
operating frequencies and voltages with OPP support.
 source "drivers/devfreq/event/Kconfig"
+source "drivers/devfreq/rockchip/Kconfig"
 endif # PM_DEVFREQ
diff --git a/drivers/devfreq/Makefile b/drivers/devfreq/Makefile
index 09f11d9..48e2ae6 100644
--- a/drivers/devfreq/Makefile
+++ b/drivers/devfreq/Makefile
@@ -9,6 +9,7 @@ obj-$(CONFIG_DEVFREQ_GOV_PASSIVE)+= governor_passive.o
   # DEVFREQ Drivers
   obj-$(CONFIG_ARM_EXYNOS_BUS_DEVFREQ)+= exynos-bus.o
   obj-$(CONFIG_ARM_TEGRA_DEVFREQ)+= tegra-devfreq.o
+obj-$(CONFIG_ARCH_ROCKCHIP)+= rockchip/
 # DEVFREQ Event Drivers
   obj-$(CONFIG_PM_DEVFREQ_EVENT)+= event/
diff --git a/drivers/devfreq/rockchip/Kconfig b/drivers/devfreq/rockchip/Kconfig
new file mode 100644
index 000..7fb1cff
--- /dev/null
+++ b/drivers/devfreq/rockchip/Kconfig
@@ -0,0 +1,15 @@
+config ARM_ROCKCHIP_DMC_DEVFREQ
+bool "ARM ROCKCHIP DMC DEVFREQ Driver"
+depends on ARCH_ROCKCHIP
+help
+  This adds the DEVFREQ driver framework for the rockchip dmc.
+
+config ARM_RK3399_DMC_DEVFREQ
+bool "ARM RK3399 DMC DEVFREQ Driver"
+depends on ARM_ROCKCHIP_DMC_DEVFREQ
+select PM_OPP
+select DEVFREQ_GOV_SIMPLE_ONDEMAND
+help
+  This adds the DEVFREQ driver for the RK3399 dmc. It sets the 
frequency
+  for the memory controller and reads the usage counts from hardware.
+
diff --git a/drivers/devfreq/rockchip/Makefile 
b/drivers/devfreq/rockchip/Makefile
new file mode 100644
index 000..caca525
--- /dev/null
+++ b/drivers/devfreq/rockchip/Makefile
@@ -0,0 +1,2 @@
+obj-$(CONFIG_ARM_ROCKCHIP_DMC_DEVFREQ)+= rockchip_dmc.o
+obj-$(CONFIG_ARM_RK3399_DMC_DEVFREQ)+= rk3399_dmc.o
diff --git a/drivers/devfreq/rockchip/rk3399_dmc.c 
b/drivers/devfreq/rockchip/rk3399_dmc.c
new file mode 100644
index 000..f1d6120
--- /dev/null
+++ b/drivers/devfreq/rockchip/rk3399_dmc.c
@@ -0,0 +1,482 @@
+/*
+ * Copyright (c) 2016, Fuzhou Rockchip Electronics Co., Ltd
+ * Author: Lin Huang <h...@rock-chips.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include 
+#include "../../firmware/rockchip_sip.h"
+
+struct dram_timing {
+unsigned int ddr3_speed_bin;
+unsigned int pd_idle;
+unsigned int sr_idle;
+

Re: [PATCH v3 6/7] PM / devfreq: rockchip: add devfreq driver for rk3399 dmc

2016-07-25 Thread hl

Hi Chanwoo Choi,

On 2016年07月25日 17:45, Chanwoo Choi wrote:

Hi Lin,

On 2016년 07월 25일 17:47, hl wrote:

Hi Chanwoo Choi,

On 2016年07月25日 14:01, Chanwoo Choi wrote:

Hi Lin,

I'm glad to support the for dmc ddr clock scaling with devfreq/devfreq-event.

But, I think that you have to use the standard interface.
As I already mentioned[1] on previous mail, devfreq fwk support
the standard DEVFREQ_TRANSITION_NOTIFIER notifier which has the two 
notifications.
- DEVFREQ_PRECHANGE
- DEVFREQ_POSTCHANGE
[1] https://patchwork.kernel.org/patch/9194305/

You can use the DEVFREQ_PRECHANGE instead of DMCFREQ_ADJUST
and use the DEVFREQ_POSTCHANGE instead of DMCFREQ_FINISH.

On 2016년 07월 22일 18:07, Lin Huang wrote:

base on dfi result, we do ddr frequency scaling, register
dmc driver to devfreq framework, and use simple-ondemand
policy.

Signed-off-by: Lin Huang 
---
Changes in v3:
- operate dram setting through sip call
- imporve set rate flow

Changes in v2:
- None
   Changes in v1:
- move dfi controller to event
- fix set voltage sequence when set rate fail
- change Kconfig type from tristate to bool
- move unuse EXPORT_SYMBOL_GPL()

   drivers/devfreq/Kconfig |   1 +
   drivers/devfreq/Makefile|   1 +
   drivers/devfreq/rockchip/Kconfig|  15 +
   drivers/devfreq/rockchip/Makefile   |   2 +
   drivers/devfreq/rockchip/rk3399_dmc.c   | 482 

   drivers/devfreq/rockchip/rockchip_dmc.c | 143 ++
   include/soc/rockchip/rockchip_dmc.h |  45 +++
   7 files changed, 689 insertions(+)
   create mode 100644 drivers/devfreq/rockchip/Kconfig
   create mode 100644 drivers/devfreq/rockchip/Makefile
   create mode 100644 drivers/devfreq/rockchip/rk3399_dmc.c
   create mode 100644 drivers/devfreq/rockchip/rockchip_dmc.c
   create mode 100644 include/soc/rockchip/rockchip_dmc.h

diff --git a/drivers/devfreq/Kconfig b/drivers/devfreq/Kconfig
index a5be56e..cb67246 100644
--- a/drivers/devfreq/Kconfig
+++ b/drivers/devfreq/Kconfig
@@ -101,5 +101,6 @@ config ARM_TEGRA_DEVFREQ
operating frequencies and voltages with OPP support.
 source "drivers/devfreq/event/Kconfig"
+source "drivers/devfreq/rockchip/Kconfig"
 endif # PM_DEVFREQ
diff --git a/drivers/devfreq/Makefile b/drivers/devfreq/Makefile
index 09f11d9..48e2ae6 100644
--- a/drivers/devfreq/Makefile
+++ b/drivers/devfreq/Makefile
@@ -9,6 +9,7 @@ obj-$(CONFIG_DEVFREQ_GOV_PASSIVE)+= governor_passive.o
   # DEVFREQ Drivers
   obj-$(CONFIG_ARM_EXYNOS_BUS_DEVFREQ)+= exynos-bus.o
   obj-$(CONFIG_ARM_TEGRA_DEVFREQ)+= tegra-devfreq.o
+obj-$(CONFIG_ARCH_ROCKCHIP)+= rockchip/
 # DEVFREQ Event Drivers
   obj-$(CONFIG_PM_DEVFREQ_EVENT)+= event/
diff --git a/drivers/devfreq/rockchip/Kconfig b/drivers/devfreq/rockchip/Kconfig
new file mode 100644
index 000..7fb1cff
--- /dev/null
+++ b/drivers/devfreq/rockchip/Kconfig
@@ -0,0 +1,15 @@
+config ARM_ROCKCHIP_DMC_DEVFREQ
+bool "ARM ROCKCHIP DMC DEVFREQ Driver"
+depends on ARCH_ROCKCHIP
+help
+  This adds the DEVFREQ driver framework for the rockchip dmc.
+
+config ARM_RK3399_DMC_DEVFREQ
+bool "ARM RK3399 DMC DEVFREQ Driver"
+depends on ARM_ROCKCHIP_DMC_DEVFREQ
+select PM_OPP
+select DEVFREQ_GOV_SIMPLE_ONDEMAND
+help
+  This adds the DEVFREQ driver for the RK3399 dmc. It sets the 
frequency
+  for the memory controller and reads the usage counts from hardware.
+
diff --git a/drivers/devfreq/rockchip/Makefile 
b/drivers/devfreq/rockchip/Makefile
new file mode 100644
index 000..caca525
--- /dev/null
+++ b/drivers/devfreq/rockchip/Makefile
@@ -0,0 +1,2 @@
+obj-$(CONFIG_ARM_ROCKCHIP_DMC_DEVFREQ)+= rockchip_dmc.o
+obj-$(CONFIG_ARM_RK3399_DMC_DEVFREQ)+= rk3399_dmc.o
diff --git a/drivers/devfreq/rockchip/rk3399_dmc.c 
b/drivers/devfreq/rockchip/rk3399_dmc.c
new file mode 100644
index 000..f1d6120
--- /dev/null
+++ b/drivers/devfreq/rockchip/rk3399_dmc.c
@@ -0,0 +1,482 @@
+/*
+ * Copyright (c) 2016, Fuzhou Rockchip Electronics Co., Ltd
+ * Author: Lin Huang 
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include 
+#include "../../firmware/rockchip_sip.h"
+
+struct dram_timing {
+unsigned int ddr3_speed_bin;
+unsigned int pd_idle;
+unsigned int sr_idle;
+unsigned int sr_mc_gate_idle;
+unsigned int srpd_lite_idle;

Re: [PATCH v3 1/7] firmware: rockchip: sip: Add rockchip SIP runtime service

2016-07-25 Thread hl

Hi Sudeep Holla,

On 2016年07月26日 01:36, Sudeep Holla wrote:



On 22/07/16 21:50, Heiko Stübner wrote:

Hi again,

one bigger thing I noticed only now.

Am Freitag, 22. Juli 2016, 17:07:14 schrieben Sie:

diff --git a/drivers/firmware/rockchip_sip.c
b/drivers/firmware/rockchip_sip.c new file mode 100644
index 000..7756af9
--- /dev/null
+++ b/drivers/firmware/rockchip_sip.c
@@ -0,0 +1,64 @@
+/*
+ * This program is free software; you can redistribute it and/or 
modify

+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * Copyright (C) 2016 ARM Limited
+ */
+#include 
+#include 
+#include 
+#include 
+#include 
+#include "rockchip_sip.h"
+
+typedef unsigned long (psci_fn)(unsigned long, unsigned long,
+unsigned long, unsigned long);
+asmlinkage psci_fn __invoke_psci_fn_smc;
+
+#define CONFIG_DRAM_INIT0x00
+#define CONFIG_DRAM_SET_RATE0x01
+#define CONFIG_DRAM_ROUND_RATE0x02
+#define CONFIG_DRAM_SET_AT_SR0x03
+#define CONFIG_DRAM_GET_BW0x04
+#define CONFIG_DRAM_GET_RATE0x05
+#define CONFIG_DRAM_CLR_IRQ0x06
+#define CONFIG_DRAM_SET_PARAM   0x07
+
+uint64_t sip_smc_ddr_init(void)
+{
+return __invoke_psci_fn_smc(SIP_DDR_FREQ, 0,
+0, CONFIG_DRAM_INIT);


I don't think that is legal to use. For one this function itself is 
declared

static in the psci code - most likely for a specific reason.

And also if anything invoke_psci_fn would hold the correct pointer 
depending

on the calling method.

But as said above, accessing psci static stuff is most likely wrong. 
Maybe the

two psci people I've included can tell us how this is to be accessed.



Thanks Heiko for looping us in this thread.

The feature being added in this series is completely out of scope of
PSCI specification and hence PSCI can't be used. Firstly we need to
audit if these are need in Linux and why they can't be handled within
the existing PSCI APIs. But yes, this series is misuse of PSCI.

I also see to know that ARM Trusted Firmware community has not accepted
this PSCI approach, so this patches are useless without that.

If they are still needed they need to make use of SMC Calling Convention
(arm_smccc_smc). Either make these smc function identifiers standard on
their platforms and use them directly in the driver. If they tend to
change too much across their platforms, use the DT approach with
appropriate bindings.

Thanks for your suggestion, i will update the code in next version.

--
Lin Huang




Re: [PATCH v3 1/7] firmware: rockchip: sip: Add rockchip SIP runtime service

2016-07-25 Thread hl

Hi Sudeep Holla,

On 2016年07月26日 01:36, Sudeep Holla wrote:



On 22/07/16 21:50, Heiko Stübner wrote:

Hi again,

one bigger thing I noticed only now.

Am Freitag, 22. Juli 2016, 17:07:14 schrieben Sie:

diff --git a/drivers/firmware/rockchip_sip.c
b/drivers/firmware/rockchip_sip.c new file mode 100644
index 000..7756af9
--- /dev/null
+++ b/drivers/firmware/rockchip_sip.c
@@ -0,0 +1,64 @@
+/*
+ * This program is free software; you can redistribute it and/or 
modify

+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * Copyright (C) 2016 ARM Limited
+ */
+#include 
+#include 
+#include 
+#include 
+#include 
+#include "rockchip_sip.h"
+
+typedef unsigned long (psci_fn)(unsigned long, unsigned long,
+unsigned long, unsigned long);
+asmlinkage psci_fn __invoke_psci_fn_smc;
+
+#define CONFIG_DRAM_INIT0x00
+#define CONFIG_DRAM_SET_RATE0x01
+#define CONFIG_DRAM_ROUND_RATE0x02
+#define CONFIG_DRAM_SET_AT_SR0x03
+#define CONFIG_DRAM_GET_BW0x04
+#define CONFIG_DRAM_GET_RATE0x05
+#define CONFIG_DRAM_CLR_IRQ0x06
+#define CONFIG_DRAM_SET_PARAM   0x07
+
+uint64_t sip_smc_ddr_init(void)
+{
+return __invoke_psci_fn_smc(SIP_DDR_FREQ, 0,
+0, CONFIG_DRAM_INIT);


I don't think that is legal to use. For one this function itself is 
declared

static in the psci code - most likely for a specific reason.

And also if anything invoke_psci_fn would hold the correct pointer 
depending

on the calling method.

But as said above, accessing psci static stuff is most likely wrong. 
Maybe the

two psci people I've included can tell us how this is to be accessed.



Thanks Heiko for looping us in this thread.

The feature being added in this series is completely out of scope of
PSCI specification and hence PSCI can't be used. Firstly we need to
audit if these are need in Linux and why they can't be handled within
the existing PSCI APIs. But yes, this series is misuse of PSCI.

I also see to know that ARM Trusted Firmware community has not accepted
this PSCI approach, so this patches are useless without that.

If they are still needed they need to make use of SMC Calling Convention
(arm_smccc_smc). Either make these smc function identifiers standard on
their platforms and use them directly in the driver. If they tend to
change too much across their platforms, use the DT approach with
appropriate bindings.

Thanks for your suggestion, i will update the code in next version.

--
Lin Huang




Re: [PATCH v3 6/7] PM / devfreq: rockchip: add devfreq driver for rk3399 dmc

2016-07-25 Thread hl

Hi Chanwoo Choi,

On 2016年07月25日 14:01, Chanwoo Choi wrote:

Hi Lin,

I'm glad to support the for dmc ddr clock scaling with devfreq/devfreq-event.

But, I think that you have to use the standard interface.
As I already mentioned[1] on previous mail, devfreq fwk support
the standard DEVFREQ_TRANSITION_NOTIFIER notifier which has the two 
notifications.
- DEVFREQ_PRECHANGE
- DEVFREQ_POSTCHANGE
[1] https://patchwork.kernel.org/patch/9194305/

You can use the DEVFREQ_PRECHANGE instead of DMCFREQ_ADJUST
and use the DEVFREQ_POSTCHANGE instead of DMCFREQ_FINISH.

On 2016년 07월 22일 18:07, Lin Huang wrote:

base on dfi result, we do ddr frequency scaling, register
dmc driver to devfreq framework, and use simple-ondemand
policy.

Signed-off-by: Lin Huang 
---
Changes in v3:
- operate dram setting through sip call
- imporve set rate flow

Changes in v2:
- None
  
Changes in v1:

- move dfi controller to event
- fix set voltage sequence when set rate fail
- change Kconfig type from tristate to bool
- move unuse EXPORT_SYMBOL_GPL()

  drivers/devfreq/Kconfig |   1 +
  drivers/devfreq/Makefile|   1 +
  drivers/devfreq/rockchip/Kconfig|  15 +
  drivers/devfreq/rockchip/Makefile   |   2 +
  drivers/devfreq/rockchip/rk3399_dmc.c   | 482 
  drivers/devfreq/rockchip/rockchip_dmc.c | 143 ++
  include/soc/rockchip/rockchip_dmc.h |  45 +++
  7 files changed, 689 insertions(+)
  create mode 100644 drivers/devfreq/rockchip/Kconfig
  create mode 100644 drivers/devfreq/rockchip/Makefile
  create mode 100644 drivers/devfreq/rockchip/rk3399_dmc.c
  create mode 100644 drivers/devfreq/rockchip/rockchip_dmc.c
  create mode 100644 include/soc/rockchip/rockchip_dmc.h

diff --git a/drivers/devfreq/Kconfig b/drivers/devfreq/Kconfig
index a5be56e..cb67246 100644
--- a/drivers/devfreq/Kconfig
+++ b/drivers/devfreq/Kconfig
@@ -101,5 +101,6 @@ config ARM_TEGRA_DEVFREQ
   operating frequencies and voltages with OPP support.
  
  source "drivers/devfreq/event/Kconfig"

+source "drivers/devfreq/rockchip/Kconfig"
  
  endif # PM_DEVFREQ

diff --git a/drivers/devfreq/Makefile b/drivers/devfreq/Makefile
index 09f11d9..48e2ae6 100644
--- a/drivers/devfreq/Makefile
+++ b/drivers/devfreq/Makefile
@@ -9,6 +9,7 @@ obj-$(CONFIG_DEVFREQ_GOV_PASSIVE)   += governor_passive.o
  # DEVFREQ Drivers
  obj-$(CONFIG_ARM_EXYNOS_BUS_DEVFREQ)  += exynos-bus.o
  obj-$(CONFIG_ARM_TEGRA_DEVFREQ)   += tegra-devfreq.o
+obj-$(CONFIG_ARCH_ROCKCHIP)+= rockchip/
  
  # DEVFREQ Event Drivers

  obj-$(CONFIG_PM_DEVFREQ_EVENT)+= event/
diff --git a/drivers/devfreq/rockchip/Kconfig b/drivers/devfreq/rockchip/Kconfig
new file mode 100644
index 000..7fb1cff
--- /dev/null
+++ b/drivers/devfreq/rockchip/Kconfig
@@ -0,0 +1,15 @@
+config ARM_ROCKCHIP_DMC_DEVFREQ
+   bool "ARM ROCKCHIP DMC DEVFREQ Driver"
+   depends on ARCH_ROCKCHIP
+   help
+ This adds the DEVFREQ driver framework for the rockchip dmc.
+
+config ARM_RK3399_DMC_DEVFREQ
+   bool "ARM RK3399 DMC DEVFREQ Driver"
+   depends on ARM_ROCKCHIP_DMC_DEVFREQ
+   select PM_OPP
+   select DEVFREQ_GOV_SIMPLE_ONDEMAND
+   help
+  This adds the DEVFREQ driver for the RK3399 dmc. It sets the 
frequency
+  for the memory controller and reads the usage counts from hardware.
+
diff --git a/drivers/devfreq/rockchip/Makefile 
b/drivers/devfreq/rockchip/Makefile
new file mode 100644
index 000..caca525
--- /dev/null
+++ b/drivers/devfreq/rockchip/Makefile
@@ -0,0 +1,2 @@
+obj-$(CONFIG_ARM_ROCKCHIP_DMC_DEVFREQ) += rockchip_dmc.o
+obj-$(CONFIG_ARM_RK3399_DMC_DEVFREQ)   += rk3399_dmc.o
diff --git a/drivers/devfreq/rockchip/rk3399_dmc.c 
b/drivers/devfreq/rockchip/rk3399_dmc.c
new file mode 100644
index 000..f1d6120
--- /dev/null
+++ b/drivers/devfreq/rockchip/rk3399_dmc.c
@@ -0,0 +1,482 @@
+/*
+ * Copyright (c) 2016, Fuzhou Rockchip Electronics Co., Ltd
+ * Author: Lin Huang 
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include 
+#include "../../firmware/rockchip_sip.h"
+
+struct dram_timing {
+   unsigned int ddr3_speed_bin;
+   unsigned int pd_idle;
+   unsigned int sr_idle;
+   unsigned int sr_mc_gate_idle;
+   unsigned int srpd_lite_idle;
+   unsigned int standby_idle;
+   unsigned int 

Re: [PATCH v3 6/7] PM / devfreq: rockchip: add devfreq driver for rk3399 dmc

2016-07-25 Thread hl

Hi Chanwoo Choi,

On 2016年07月25日 14:01, Chanwoo Choi wrote:

Hi Lin,

I'm glad to support the for dmc ddr clock scaling with devfreq/devfreq-event.

But, I think that you have to use the standard interface.
As I already mentioned[1] on previous mail, devfreq fwk support
the standard DEVFREQ_TRANSITION_NOTIFIER notifier which has the two 
notifications.
- DEVFREQ_PRECHANGE
- DEVFREQ_POSTCHANGE
[1] https://patchwork.kernel.org/patch/9194305/

You can use the DEVFREQ_PRECHANGE instead of DMCFREQ_ADJUST
and use the DEVFREQ_POSTCHANGE instead of DMCFREQ_FINISH.

On 2016년 07월 22일 18:07, Lin Huang wrote:

base on dfi result, we do ddr frequency scaling, register
dmc driver to devfreq framework, and use simple-ondemand
policy.

Signed-off-by: Lin Huang 
---
Changes in v3:
- operate dram setting through sip call
- imporve set rate flow

Changes in v2:
- None
  
Changes in v1:

- move dfi controller to event
- fix set voltage sequence when set rate fail
- change Kconfig type from tristate to bool
- move unuse EXPORT_SYMBOL_GPL()

  drivers/devfreq/Kconfig |   1 +
  drivers/devfreq/Makefile|   1 +
  drivers/devfreq/rockchip/Kconfig|  15 +
  drivers/devfreq/rockchip/Makefile   |   2 +
  drivers/devfreq/rockchip/rk3399_dmc.c   | 482 
  drivers/devfreq/rockchip/rockchip_dmc.c | 143 ++
  include/soc/rockchip/rockchip_dmc.h |  45 +++
  7 files changed, 689 insertions(+)
  create mode 100644 drivers/devfreq/rockchip/Kconfig
  create mode 100644 drivers/devfreq/rockchip/Makefile
  create mode 100644 drivers/devfreq/rockchip/rk3399_dmc.c
  create mode 100644 drivers/devfreq/rockchip/rockchip_dmc.c
  create mode 100644 include/soc/rockchip/rockchip_dmc.h

diff --git a/drivers/devfreq/Kconfig b/drivers/devfreq/Kconfig
index a5be56e..cb67246 100644
--- a/drivers/devfreq/Kconfig
+++ b/drivers/devfreq/Kconfig
@@ -101,5 +101,6 @@ config ARM_TEGRA_DEVFREQ
   operating frequencies and voltages with OPP support.
  
  source "drivers/devfreq/event/Kconfig"

+source "drivers/devfreq/rockchip/Kconfig"
  
  endif # PM_DEVFREQ

diff --git a/drivers/devfreq/Makefile b/drivers/devfreq/Makefile
index 09f11d9..48e2ae6 100644
--- a/drivers/devfreq/Makefile
+++ b/drivers/devfreq/Makefile
@@ -9,6 +9,7 @@ obj-$(CONFIG_DEVFREQ_GOV_PASSIVE)   += governor_passive.o
  # DEVFREQ Drivers
  obj-$(CONFIG_ARM_EXYNOS_BUS_DEVFREQ)  += exynos-bus.o
  obj-$(CONFIG_ARM_TEGRA_DEVFREQ)   += tegra-devfreq.o
+obj-$(CONFIG_ARCH_ROCKCHIP)+= rockchip/
  
  # DEVFREQ Event Drivers

  obj-$(CONFIG_PM_DEVFREQ_EVENT)+= event/
diff --git a/drivers/devfreq/rockchip/Kconfig b/drivers/devfreq/rockchip/Kconfig
new file mode 100644
index 000..7fb1cff
--- /dev/null
+++ b/drivers/devfreq/rockchip/Kconfig
@@ -0,0 +1,15 @@
+config ARM_ROCKCHIP_DMC_DEVFREQ
+   bool "ARM ROCKCHIP DMC DEVFREQ Driver"
+   depends on ARCH_ROCKCHIP
+   help
+ This adds the DEVFREQ driver framework for the rockchip dmc.
+
+config ARM_RK3399_DMC_DEVFREQ
+   bool "ARM RK3399 DMC DEVFREQ Driver"
+   depends on ARM_ROCKCHIP_DMC_DEVFREQ
+   select PM_OPP
+   select DEVFREQ_GOV_SIMPLE_ONDEMAND
+   help
+  This adds the DEVFREQ driver for the RK3399 dmc. It sets the 
frequency
+  for the memory controller and reads the usage counts from hardware.
+
diff --git a/drivers/devfreq/rockchip/Makefile 
b/drivers/devfreq/rockchip/Makefile
new file mode 100644
index 000..caca525
--- /dev/null
+++ b/drivers/devfreq/rockchip/Makefile
@@ -0,0 +1,2 @@
+obj-$(CONFIG_ARM_ROCKCHIP_DMC_DEVFREQ) += rockchip_dmc.o
+obj-$(CONFIG_ARM_RK3399_DMC_DEVFREQ)   += rk3399_dmc.o
diff --git a/drivers/devfreq/rockchip/rk3399_dmc.c 
b/drivers/devfreq/rockchip/rk3399_dmc.c
new file mode 100644
index 000..f1d6120
--- /dev/null
+++ b/drivers/devfreq/rockchip/rk3399_dmc.c
@@ -0,0 +1,482 @@
+/*
+ * Copyright (c) 2016, Fuzhou Rockchip Electronics Co., Ltd
+ * Author: Lin Huang 
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include 
+#include "../../firmware/rockchip_sip.h"
+
+struct dram_timing {
+   unsigned int ddr3_speed_bin;
+   unsigned int pd_idle;
+   unsigned int sr_idle;
+   unsigned int sr_mc_gate_idle;
+   unsigned int srpd_lite_idle;
+   unsigned int standby_idle;
+   unsigned int dram_dll_dis_freq;
+   unsigned int 

Re: [PATCH v3 1/7] firmware: rockchip: sip: Add rockchip SIP runtime service

2016-07-24 Thread hl

Hi Heiko,

On 2016年07月23日 04:50, Heiko Stübner wrote:

Hi again,

one bigger thing I noticed only now.

Am Freitag, 22. Juli 2016, 17:07:14 schrieben Sie:

diff --git a/drivers/firmware/rockchip_sip.c
b/drivers/firmware/rockchip_sip.c new file mode 100644
index 000..7756af9
--- /dev/null
+++ b/drivers/firmware/rockchip_sip.c
@@ -0,0 +1,64 @@
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * Copyright (C) 2016 ARM Limited
+ */
+#include 
+#include 
+#include 
+#include 
+#include 
+#include "rockchip_sip.h"
+
+typedef unsigned long (psci_fn)(unsigned long, unsigned long,
+   unsigned long, unsigned long);
+asmlinkage psci_fn __invoke_psci_fn_smc;
+
+#define CONFIG_DRAM_INIT   0x00
+#define CONFIG_DRAM_SET_RATE   0x01
+#define CONFIG_DRAM_ROUND_RATE 0x02
+#define CONFIG_DRAM_SET_AT_SR  0x03
+#define CONFIG_DRAM_GET_BW 0x04
+#define CONFIG_DRAM_GET_RATE   0x05
+#define CONFIG_DRAM_CLR_IRQ0x06
+#define CONFIG_DRAM_SET_PARAM   0x07
+
+uint64_t sip_smc_ddr_init(void)
+{
+   return __invoke_psci_fn_smc(SIP_DDR_FREQ, 0,
+   0, CONFIG_DRAM_INIT);

I don't think that is legal to use. For one this function itself is declared
static in the psci code - most likely for a specific reason.

And also if anything invoke_psci_fn would hold the correct pointer depending
on the calling method.

But as said above, accessing psci static stuff is most likely wrong. Maybe the
two psci people I've included can tell us how this is to be accessed.


  Thanks Heiko. Hope Sudeep Holla and Lorenzo Pieralisi can give me advice.

Heiko


+}
+
+uint64_t sip_smc_set_ddr_param(uint64_t param)
+{
+   return __invoke_psci_fn_smc(SIP_DDR_FREQ, param,
+   0, CONFIG_DRAM_SET_PARAM);
+}
+
+uint64_t sip_smc_set_ddr_rate(uint64_t rate)
+{
+   return __invoke_psci_fn_smc(SIP_DDR_FREQ, rate, 0,
+   CONFIG_DRAM_SET_RATE);
+}
+
+uint64_t sip_smc_get_ddr_rate(void)
+{
+   return __invoke_psci_fn_smc(SIP_DDR_FREQ, 0, 0, CONFIG_DRAM_GET_RATE);
+}
+
+uint64_t sip_smc_clr_ddr_irq(void)
+{
+   return __invoke_psci_fn_smc(SIP_DDR_FREQ, 0, 0, CONFIG_DRAM_CLR_IRQ);
+}
+
+uint64_t sip_smc_get_call_count(void)
+{
+   return __invoke_psci_fn_smc(SIP_SVC_CALL_COUNT, 0, 0, 0);
+}


___
Linux-rockchip mailing list
linux-rockc...@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-rockchip





--
Lin Huang




Re: [PATCH v3 1/7] firmware: rockchip: sip: Add rockchip SIP runtime service

2016-07-24 Thread hl

Hi Heiko,

On 2016年07月23日 04:50, Heiko Stübner wrote:

Hi again,

one bigger thing I noticed only now.

Am Freitag, 22. Juli 2016, 17:07:14 schrieben Sie:

diff --git a/drivers/firmware/rockchip_sip.c
b/drivers/firmware/rockchip_sip.c new file mode 100644
index 000..7756af9
--- /dev/null
+++ b/drivers/firmware/rockchip_sip.c
@@ -0,0 +1,64 @@
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * Copyright (C) 2016 ARM Limited
+ */
+#include 
+#include 
+#include 
+#include 
+#include 
+#include "rockchip_sip.h"
+
+typedef unsigned long (psci_fn)(unsigned long, unsigned long,
+   unsigned long, unsigned long);
+asmlinkage psci_fn __invoke_psci_fn_smc;
+
+#define CONFIG_DRAM_INIT   0x00
+#define CONFIG_DRAM_SET_RATE   0x01
+#define CONFIG_DRAM_ROUND_RATE 0x02
+#define CONFIG_DRAM_SET_AT_SR  0x03
+#define CONFIG_DRAM_GET_BW 0x04
+#define CONFIG_DRAM_GET_RATE   0x05
+#define CONFIG_DRAM_CLR_IRQ0x06
+#define CONFIG_DRAM_SET_PARAM   0x07
+
+uint64_t sip_smc_ddr_init(void)
+{
+   return __invoke_psci_fn_smc(SIP_DDR_FREQ, 0,
+   0, CONFIG_DRAM_INIT);

I don't think that is legal to use. For one this function itself is declared
static in the psci code - most likely for a specific reason.

And also if anything invoke_psci_fn would hold the correct pointer depending
on the calling method.

But as said above, accessing psci static stuff is most likely wrong. Maybe the
two psci people I've included can tell us how this is to be accessed.


  Thanks Heiko. Hope Sudeep Holla and Lorenzo Pieralisi can give me advice.

Heiko


+}
+
+uint64_t sip_smc_set_ddr_param(uint64_t param)
+{
+   return __invoke_psci_fn_smc(SIP_DDR_FREQ, param,
+   0, CONFIG_DRAM_SET_PARAM);
+}
+
+uint64_t sip_smc_set_ddr_rate(uint64_t rate)
+{
+   return __invoke_psci_fn_smc(SIP_DDR_FREQ, rate, 0,
+   CONFIG_DRAM_SET_RATE);
+}
+
+uint64_t sip_smc_get_ddr_rate(void)
+{
+   return __invoke_psci_fn_smc(SIP_DDR_FREQ, 0, 0, CONFIG_DRAM_GET_RATE);
+}
+
+uint64_t sip_smc_clr_ddr_irq(void)
+{
+   return __invoke_psci_fn_smc(SIP_DDR_FREQ, 0, 0, CONFIG_DRAM_CLR_IRQ);
+}
+
+uint64_t sip_smc_get_call_count(void)
+{
+   return __invoke_psci_fn_smc(SIP_SVC_CALL_COUNT, 0, 0, 0);
+}


___
Linux-rockchip mailing list
linux-rockc...@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-rockchip





--
Lin Huang




Re: [PATCH v3 6/7] PM / devfreq: rockchip: add devfreq driver for rk3399 dmc

2016-07-24 Thread hl

Hi Paul,

On 2016年07月23日 04:24, Paul Gortmaker wrote:

On Fri, Jul 22, 2016 at 5:07 AM, Lin Huang  wrote:

base on dfi result, we do ddr frequency scaling, register
dmc driver to devfreq framework, and use simple-ondemand
policy.

Signed-off-by: Lin Huang 
---
Changes in v3:
- operate dram setting through sip call
- imporve set rate flow

Changes in v2:
- None

Changes in v1:
- move dfi controller to event
- fix set voltage sequence when set rate fail
- change Kconfig type from tristate to bool
- move unuse EXPORT_SYMBOL_GPL()

  drivers/devfreq/Kconfig |   1 +
  drivers/devfreq/Makefile|   1 +
  drivers/devfreq/rockchip/Kconfig|  15 +
  drivers/devfreq/rockchip/Makefile   |   2 +
  drivers/devfreq/rockchip/rk3399_dmc.c   | 482 
  drivers/devfreq/rockchip/rockchip_dmc.c | 143 ++
  include/soc/rockchip/rockchip_dmc.h |  45 +++
  7 files changed, 689 insertions(+)
  create mode 100644 drivers/devfreq/rockchip/Kconfig
  create mode 100644 drivers/devfreq/rockchip/Makefile
  create mode 100644 drivers/devfreq/rockchip/rk3399_dmc.c
  create mode 100644 drivers/devfreq/rockchip/rockchip_dmc.c
  create mode 100644 include/soc/rockchip/rockchip_dmc.h

diff --git a/drivers/devfreq/Kconfig b/drivers/devfreq/Kconfig
index a5be56e..cb67246 100644
--- a/drivers/devfreq/Kconfig
+++ b/drivers/devfreq/Kconfig
@@ -101,5 +101,6 @@ config ARM_TEGRA_DEVFREQ
   operating frequencies and voltages with OPP support.

  source "drivers/devfreq/event/Kconfig"
+source "drivers/devfreq/rockchip/Kconfig"

  endif # PM_DEVFREQ
diff --git a/drivers/devfreq/Makefile b/drivers/devfreq/Makefile
index 09f11d9..48e2ae6 100644
--- a/drivers/devfreq/Makefile
+++ b/drivers/devfreq/Makefile
@@ -9,6 +9,7 @@ obj-$(CONFIG_DEVFREQ_GOV_PASSIVE)   += governor_passive.o
  # DEVFREQ Drivers
  obj-$(CONFIG_ARM_EXYNOS_BUS_DEVFREQ)   += exynos-bus.o
  obj-$(CONFIG_ARM_TEGRA_DEVFREQ)+= tegra-devfreq.o
+obj-$(CONFIG_ARCH_ROCKCHIP)+= rockchip/

  # DEVFREQ Event Drivers
  obj-$(CONFIG_PM_DEVFREQ_EVENT) += event/
diff --git a/drivers/devfreq/rockchip/Kconfig b/drivers/devfreq/rockchip/Kconfig
new file mode 100644
index 000..7fb1cff
--- /dev/null
+++ b/drivers/devfreq/rockchip/Kconfig
@@ -0,0 +1,15 @@
+config ARM_ROCKCHIP_DMC_DEVFREQ
+   bool "ARM ROCKCHIP DMC DEVFREQ Driver"
+   depends on ARCH_ROCKCHIP
+   help
+ This adds the DEVFREQ driver framework for the rockchip dmc.
+
+config ARM_RK3399_DMC_DEVFREQ
+   bool "ARM RK3399 DMC DEVFREQ Driver"

Since you are using bool Kconfigs for your driver, please do not use
module.h or MODULE_ tags in your driver, and use the builtin
register function.

Alternatively if there really is  a use case for it to be a modular driver
then use a tristate Kconfig.

Thanks for pointing it, will fix it next version.

THanks,
Paul.
--


+   depends on ARM_ROCKCHIP_DMC_DEVFREQ
+   select PM_OPP
+   select DEVFREQ_GOV_SIMPLE_ONDEMAND
+   help
+  This adds the DEVFREQ driver for the RK3399 dmc. It sets the 
frequency
+  for the memory controller and reads the usage counts from hardware.
+

___
Linux-rockchip mailing list
linux-rockc...@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-rockchip





--
Lin Huang




Re: [PATCH v3 6/7] PM / devfreq: rockchip: add devfreq driver for rk3399 dmc

2016-07-24 Thread hl

Hi Paul,

On 2016年07月23日 04:24, Paul Gortmaker wrote:

On Fri, Jul 22, 2016 at 5:07 AM, Lin Huang  wrote:

base on dfi result, we do ddr frequency scaling, register
dmc driver to devfreq framework, and use simple-ondemand
policy.

Signed-off-by: Lin Huang 
---
Changes in v3:
- operate dram setting through sip call
- imporve set rate flow

Changes in v2:
- None

Changes in v1:
- move dfi controller to event
- fix set voltage sequence when set rate fail
- change Kconfig type from tristate to bool
- move unuse EXPORT_SYMBOL_GPL()

  drivers/devfreq/Kconfig |   1 +
  drivers/devfreq/Makefile|   1 +
  drivers/devfreq/rockchip/Kconfig|  15 +
  drivers/devfreq/rockchip/Makefile   |   2 +
  drivers/devfreq/rockchip/rk3399_dmc.c   | 482 
  drivers/devfreq/rockchip/rockchip_dmc.c | 143 ++
  include/soc/rockchip/rockchip_dmc.h |  45 +++
  7 files changed, 689 insertions(+)
  create mode 100644 drivers/devfreq/rockchip/Kconfig
  create mode 100644 drivers/devfreq/rockchip/Makefile
  create mode 100644 drivers/devfreq/rockchip/rk3399_dmc.c
  create mode 100644 drivers/devfreq/rockchip/rockchip_dmc.c
  create mode 100644 include/soc/rockchip/rockchip_dmc.h

diff --git a/drivers/devfreq/Kconfig b/drivers/devfreq/Kconfig
index a5be56e..cb67246 100644
--- a/drivers/devfreq/Kconfig
+++ b/drivers/devfreq/Kconfig
@@ -101,5 +101,6 @@ config ARM_TEGRA_DEVFREQ
   operating frequencies and voltages with OPP support.

  source "drivers/devfreq/event/Kconfig"
+source "drivers/devfreq/rockchip/Kconfig"

  endif # PM_DEVFREQ
diff --git a/drivers/devfreq/Makefile b/drivers/devfreq/Makefile
index 09f11d9..48e2ae6 100644
--- a/drivers/devfreq/Makefile
+++ b/drivers/devfreq/Makefile
@@ -9,6 +9,7 @@ obj-$(CONFIG_DEVFREQ_GOV_PASSIVE)   += governor_passive.o
  # DEVFREQ Drivers
  obj-$(CONFIG_ARM_EXYNOS_BUS_DEVFREQ)   += exynos-bus.o
  obj-$(CONFIG_ARM_TEGRA_DEVFREQ)+= tegra-devfreq.o
+obj-$(CONFIG_ARCH_ROCKCHIP)+= rockchip/

  # DEVFREQ Event Drivers
  obj-$(CONFIG_PM_DEVFREQ_EVENT) += event/
diff --git a/drivers/devfreq/rockchip/Kconfig b/drivers/devfreq/rockchip/Kconfig
new file mode 100644
index 000..7fb1cff
--- /dev/null
+++ b/drivers/devfreq/rockchip/Kconfig
@@ -0,0 +1,15 @@
+config ARM_ROCKCHIP_DMC_DEVFREQ
+   bool "ARM ROCKCHIP DMC DEVFREQ Driver"
+   depends on ARCH_ROCKCHIP
+   help
+ This adds the DEVFREQ driver framework for the rockchip dmc.
+
+config ARM_RK3399_DMC_DEVFREQ
+   bool "ARM RK3399 DMC DEVFREQ Driver"

Since you are using bool Kconfigs for your driver, please do not use
module.h or MODULE_ tags in your driver, and use the builtin
register function.

Alternatively if there really is  a use case for it to be a modular driver
then use a tristate Kconfig.

Thanks for pointing it, will fix it next version.

THanks,
Paul.
--


+   depends on ARM_ROCKCHIP_DMC_DEVFREQ
+   select PM_OPP
+   select DEVFREQ_GOV_SIMPLE_ONDEMAND
+   help
+  This adds the DEVFREQ driver for the RK3399 dmc. It sets the 
frequency
+  for the memory controller and reads the usage counts from hardware.
+

___
Linux-rockchip mailing list
linux-rockc...@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-rockchip





--
Lin Huang




Re: [RFC PATCH v1 4/6] PM / devfreq: event: support rockchip dfi controller

2016-06-06 Thread hl

Hi Thierry,

On 2016年06月04日 00:54, Thierry Reding wrote:

On Fri, Jun 03, 2016 at 05:55:17PM +0800, Lin Huang wrote:
[...]

+   ret = clk_prepare_enable(data->clk);
+   if (ret) {
+   dev_err(>dev, "failed to enable clk: %d\n", ret);
+   clk_disable_unprepare(data->clk);
+   return ret;
+   }

This is going to give you a large WARN. clk_prepare_enable() already
leaves the clock in a proper state when it fails (i.e. it calls
clk_unprepare() if the clk_enable() part failed), so calling
clk_disable_unprepare() upon failure is going to unbalance the
reference counts.

Thanks for reminding, i will fix it next version.


Thierry


--
Lin Huang




Re: [RFC PATCH v1 4/6] PM / devfreq: event: support rockchip dfi controller

2016-06-06 Thread hl

Hi Thierry,

On 2016年06月04日 00:54, Thierry Reding wrote:

On Fri, Jun 03, 2016 at 05:55:17PM +0800, Lin Huang wrote:
[...]

+   ret = clk_prepare_enable(data->clk);
+   if (ret) {
+   dev_err(>dev, "failed to enable clk: %d\n", ret);
+   clk_disable_unprepare(data->clk);
+   return ret;
+   }

This is going to give you a large WARN. clk_prepare_enable() already
leaves the clock in a proper state when it fails (i.e. it calls
clk_unprepare() if the clk_enable() part failed), so calling
clk_disable_unprepare() upon failure is going to unbalance the
reference counts.

Thanks for reminding, i will fix it next version.


Thierry


--
Lin Huang




Re: [RFC PATCH v1 4/6] PM / devfreq: event: support rockchip dfi controller

2016-06-05 Thread hl



On 2016年06月03日 18:26, Chanwoo Choi wrote:

Hi Lin,

I add the some comment on below. If you modify it,
You can add my acked-by tag. Looks good to me.

Thanks for you reviewing, i will update the code folloiwing your comment.

Acked-by: Chanwoo Choi 

Also, I'd like you to add me to mail thread
on next version because I'm supporter of devfreq-event.
I am sorry for missing you mail in before patch:-[ , will add you to 
mail thread next vesion.

On 2016년 06월 03일 18:55, Lin Huang wrote:

on rk3399 platform, there is dfi conroller can monitor
ddr load, base on this result, we can do ddr freqency
scaling.

Signed-off-by: Lin Huang 
---
Changes in v1:
- NOne

  drivers/devfreq/event/Kconfig|   7 +
  drivers/devfreq/event/Makefile   |   1 +
  drivers/devfreq/event/rockchip-dfi.c | 265 +++
  3 files changed, 273 insertions(+)
  create mode 100644 drivers/devfreq/event/rockchip-dfi.c

diff --git a/drivers/devfreq/event/Kconfig b/drivers/devfreq/event/Kconfig
index 1e8b4f4..6ebdc13 100644
--- a/drivers/devfreq/event/Kconfig
+++ b/drivers/devfreq/event/Kconfig
@@ -30,4 +30,11 @@ config DEVFREQ_EVENT_EXYNOS_PPMU
  (Platform Performance Monitoring Unit) counters to estimate the
  utilization of each module.
  
+config DEVFREQ_EVENT_ROCKCHIP_DFI

+   bool "ROCKCHIP DFI DEVFREQ event Driver"
+   depends on ARCH_ROCKCHIP
+   help
+ This add the devfreq-event driver for Rockchip SoC. It provides DFI

You better to full name of 'DFI' abbreviation as following:
- DFI (Dxxx Fxxx Ixxx)


+ driver to count ddr load.
+
  endif # PM_DEVFREQ_EVENT
diff --git a/drivers/devfreq/event/Makefile b/drivers/devfreq/event/Makefile
index 3d6afd3..dda7090 100644
--- a/drivers/devfreq/event/Makefile
+++ b/drivers/devfreq/event/Makefile
@@ -2,3 +2,4 @@
  
  obj-$(CONFIG_DEVFREQ_EVENT_EXYNOS_NOCP) += exynos-nocp.o

  obj-$(CONFIG_DEVFREQ_EVENT_EXYNOS_PPMU) += exynos-ppmu.o
+obj-$(CONFIG_DEVFREQ_EVENT_ROCKCHIP_DFI) += rockchip-dfi.o
diff --git a/drivers/devfreq/event/rockchip-dfi.c 
b/drivers/devfreq/event/rockchip-dfi.c
new file mode 100644
index 000..e3b020f9
--- /dev/null
+++ b/drivers/devfreq/event/rockchip-dfi.c
@@ -0,0 +1,265 @@
+/*
+ * Copyright (c) 2016, Fuzhou Rockchip Electronics Co., Ltd
+ * Author: Lin Huang 
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#define RK3399_DMC_NUM_CH  2
+
+/* DDRMON_CTRL */
+#define DDRMON_CTRL0x04
+#define CLR_DDRMON_CTRL(0x1f << 0)
+#define LPDDR4_EN  (0x10001 << 4)
+#define HARDWARE_EN(0x10001 << 3)
+#define LPDDR3_EN  (0x10001 << 2)
+#define SOFTWARE_EN(0x10001 << 1)
+#define TIME_CNT_EN(0x10001 << 0)
+
+#define DDRMON_CH0_COUNT_NUM   0x28
+#define DDRMON_CH0_DFI_ACCESS_NUM  0x2c
+#define DDRMON_CH1_COUNT_NUM   0x3c
+#define DDRMON_CH1_DFI_ACCESS_NUM  0x40
+
+/* pmu grf */
+#define PMUGRF_OS_REG2 0x308
+#define DDRTYPE_SHIFT  13
+#define DDRTYPE_MASK   7
+
+enum {
+   DDR3 = 3,
+   LPDDR3 = 6,
+   LPDDR4 = 7,
+   UNUSED = 0xFF
+};
+
+struct dmc_usage {
+   u32 access;
+   u32 total;
+};
+
+struct rockchip_dfi {
+   struct devfreq_event_dev *edev;
+   struct devfreq_event_desc *desc;
+   struct dmc_usage ch_usage[RK3399_DMC_NUM_CH];
+   struct device *dev;
+   void __iomem *regs;
+   struct regmap *regmap_pmu;
+   struct clk *clk;
+};
+
+static void rockchip_dfi_start_hardware_counter(struct devfreq_event_dev *edev)
+{
+   struct rockchip_dfi *info = devfreq_event_get_drvdata(edev);
+   void __iomem *dfi_regs = info->regs;
+   u32 val;
+   u32 ddr_type;
+
+   /* get ddr type */
+   regmap_read(info->regmap_pmu, PMUGRF_OS_REG2, );
+   ddr_type = (val >> DDRTYPE_SHIFT) & DDRTYPE_MASK;
+
+   /* clear DDRMON_CTRL setting */
+   writel_relaxed(CLR_DDRMON_CTRL, dfi_regs + DDRMON_CTRL);
+
+   /* set ddr type to dfi */
+   if (ddr_type == LPDDR3)
+   writel_relaxed(LPDDR3_EN, dfi_regs + DDRMON_CTRL);
+   else if (ddr_type == LPDDR4)
+   writel_relaxed(LPDDR4_EN, dfi_regs + DDRMON_CTRL);
+
+   /* enable count, use software mode */
+   writel_relaxed(SOFTWARE_EN, dfi_regs + DDRMON_CTRL);
+}
+
+static void rockchip_dfi_stop_hardware_counter(struct devfreq_event_dev *edev)
+{
+   struct rockchip_dfi 

Re: [RFC PATCH v1 4/6] PM / devfreq: event: support rockchip dfi controller

2016-06-05 Thread hl



On 2016年06月03日 18:26, Chanwoo Choi wrote:

Hi Lin,

I add the some comment on below. If you modify it,
You can add my acked-by tag. Looks good to me.

Thanks for you reviewing, i will update the code folloiwing your comment.

Acked-by: Chanwoo Choi 

Also, I'd like you to add me to mail thread
on next version because I'm supporter of devfreq-event.
I am sorry for missing you mail in before patch:-[ , will add you to 
mail thread next vesion.

On 2016년 06월 03일 18:55, Lin Huang wrote:

on rk3399 platform, there is dfi conroller can monitor
ddr load, base on this result, we can do ddr freqency
scaling.

Signed-off-by: Lin Huang 
---
Changes in v1:
- NOne

  drivers/devfreq/event/Kconfig|   7 +
  drivers/devfreq/event/Makefile   |   1 +
  drivers/devfreq/event/rockchip-dfi.c | 265 +++
  3 files changed, 273 insertions(+)
  create mode 100644 drivers/devfreq/event/rockchip-dfi.c

diff --git a/drivers/devfreq/event/Kconfig b/drivers/devfreq/event/Kconfig
index 1e8b4f4..6ebdc13 100644
--- a/drivers/devfreq/event/Kconfig
+++ b/drivers/devfreq/event/Kconfig
@@ -30,4 +30,11 @@ config DEVFREQ_EVENT_EXYNOS_PPMU
  (Platform Performance Monitoring Unit) counters to estimate the
  utilization of each module.
  
+config DEVFREQ_EVENT_ROCKCHIP_DFI

+   bool "ROCKCHIP DFI DEVFREQ event Driver"
+   depends on ARCH_ROCKCHIP
+   help
+ This add the devfreq-event driver for Rockchip SoC. It provides DFI

You better to full name of 'DFI' abbreviation as following:
- DFI (Dxxx Fxxx Ixxx)


+ driver to count ddr load.
+
  endif # PM_DEVFREQ_EVENT
diff --git a/drivers/devfreq/event/Makefile b/drivers/devfreq/event/Makefile
index 3d6afd3..dda7090 100644
--- a/drivers/devfreq/event/Makefile
+++ b/drivers/devfreq/event/Makefile
@@ -2,3 +2,4 @@
  
  obj-$(CONFIG_DEVFREQ_EVENT_EXYNOS_NOCP) += exynos-nocp.o

  obj-$(CONFIG_DEVFREQ_EVENT_EXYNOS_PPMU) += exynos-ppmu.o
+obj-$(CONFIG_DEVFREQ_EVENT_ROCKCHIP_DFI) += rockchip-dfi.o
diff --git a/drivers/devfreq/event/rockchip-dfi.c 
b/drivers/devfreq/event/rockchip-dfi.c
new file mode 100644
index 000..e3b020f9
--- /dev/null
+++ b/drivers/devfreq/event/rockchip-dfi.c
@@ -0,0 +1,265 @@
+/*
+ * Copyright (c) 2016, Fuzhou Rockchip Electronics Co., Ltd
+ * Author: Lin Huang 
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#define RK3399_DMC_NUM_CH  2
+
+/* DDRMON_CTRL */
+#define DDRMON_CTRL0x04
+#define CLR_DDRMON_CTRL(0x1f << 0)
+#define LPDDR4_EN  (0x10001 << 4)
+#define HARDWARE_EN(0x10001 << 3)
+#define LPDDR3_EN  (0x10001 << 2)
+#define SOFTWARE_EN(0x10001 << 1)
+#define TIME_CNT_EN(0x10001 << 0)
+
+#define DDRMON_CH0_COUNT_NUM   0x28
+#define DDRMON_CH0_DFI_ACCESS_NUM  0x2c
+#define DDRMON_CH1_COUNT_NUM   0x3c
+#define DDRMON_CH1_DFI_ACCESS_NUM  0x40
+
+/* pmu grf */
+#define PMUGRF_OS_REG2 0x308
+#define DDRTYPE_SHIFT  13
+#define DDRTYPE_MASK   7
+
+enum {
+   DDR3 = 3,
+   LPDDR3 = 6,
+   LPDDR4 = 7,
+   UNUSED = 0xFF
+};
+
+struct dmc_usage {
+   u32 access;
+   u32 total;
+};
+
+struct rockchip_dfi {
+   struct devfreq_event_dev *edev;
+   struct devfreq_event_desc *desc;
+   struct dmc_usage ch_usage[RK3399_DMC_NUM_CH];
+   struct device *dev;
+   void __iomem *regs;
+   struct regmap *regmap_pmu;
+   struct clk *clk;
+};
+
+static void rockchip_dfi_start_hardware_counter(struct devfreq_event_dev *edev)
+{
+   struct rockchip_dfi *info = devfreq_event_get_drvdata(edev);
+   void __iomem *dfi_regs = info->regs;
+   u32 val;
+   u32 ddr_type;
+
+   /* get ddr type */
+   regmap_read(info->regmap_pmu, PMUGRF_OS_REG2, );
+   ddr_type = (val >> DDRTYPE_SHIFT) & DDRTYPE_MASK;
+
+   /* clear DDRMON_CTRL setting */
+   writel_relaxed(CLR_DDRMON_CTRL, dfi_regs + DDRMON_CTRL);
+
+   /* set ddr type to dfi */
+   if (ddr_type == LPDDR3)
+   writel_relaxed(LPDDR3_EN, dfi_regs + DDRMON_CTRL);
+   else if (ddr_type == LPDDR4)
+   writel_relaxed(LPDDR4_EN, dfi_regs + DDRMON_CTRL);
+
+   /* enable count, use software mode */
+   writel_relaxed(SOFTWARE_EN, dfi_regs + DDRMON_CTRL);
+}
+
+static void rockchip_dfi_stop_hardware_counter(struct devfreq_event_dev *edev)
+{
+   struct rockchip_dfi *info = devfreq_event_get_drvdata(edev);
+   void __iomem 

Re: [RFC PATCH v1 1/6] rockchip: rockchip: add new clock-type for the ddrclk

2016-06-05 Thread hl

Hi Heiko,

On 2016年06月03日 20:51, Heiko Stübner wrote:

Am Freitag, 3. Juni 2016, 17:55:14 schrieb Lin Huang:

On new rockchip platform(rk3399 etc), there have dcf controller to
do ddr frequency scaling, and this controller will implement in
arm-trust-firmware. We add a special clock-type to handle that.

Signed-off-by: Lin Huang 
---
Changes in v1:
- None

  drivers/clk/rockchip/Makefile  |   1 +
  drivers/clk/rockchip/clk-ddr.c | 147
+ drivers/clk/rockchip/clk.c |
  9 +++
  drivers/clk/rockchip/clk.h |  27 
  4 files changed, 184 insertions(+)
  create mode 100644 drivers/clk/rockchip/clk-ddr.c

diff --git a/drivers/clk/rockchip/Makefile b/drivers/clk/rockchip/Makefile
index f47a2fa..b5f2c8e 100644
--- a/drivers/clk/rockchip/Makefile
+++ b/drivers/clk/rockchip/Makefile
@@ -8,6 +8,7 @@ obj-y   += clk-pll.o
  obj-y += clk-cpu.o
  obj-y += clk-inverter.o
  obj-y += clk-mmc-phase.o
+obj-y  += clk-ddr.o
  obj-$(CONFIG_RESET_CONTROLLER)+= softrst.o

  obj-y += clk-rk3036.o
diff --git a/drivers/clk/rockchip/clk-ddr.c b/drivers/clk/rockchip/clk-ddr.c
new file mode 100644
index 000..5b6630d
--- /dev/null
+++ b/drivers/clk/rockchip/clk-ddr.c
@@ -0,0 +1,147 @@
+/*
+ * Copyright (c) 2016 Rockchip Electronics Co. Ltd.
+ * Author: Lin Huang 
+ *
+ * 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.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include "clk.h"
+
+struct rockchip_ddrclk {
+   struct clk_hw   hw;
+   void __iomem*reg_base;
+   int mux_offset;
+   int mux_shift;
+   int mux_width;
+   int mux_flag;
+   int div_shift;
+   int div_width;
+   int div_flag;
+   spinlock_t  *lock;
+};
+
+#define to_rockchip_ddrclk_hw(hw) container_of(hw, struct rockchip_ddrclk,
hw)
+#define val_mask(width)((1 << (width)) - 1)

maybe use GENMASK?

Oh, yes, we can use it. Will fix next version.



+
+static int rockchip_ddrclk_set_rate(struct clk_hw *hw, unsigned long drate,
+   unsigned long prate)
+{
+   struct rockchip_ddrclk *ddrclk = to_rockchip_ddrclk_hw(hw);
+   unsigned long flags;
+
+   spin_lock_irqsave(ddrclk->lock, flags);
+
+   /* TODO: set ddr rate in bl31 */

I expect this interface to be in existence and merged into the main ATF first.

Right now the whole clock-type does nothing more than a simple COMPOSITE with
added CLK_DIVIDER_READ_ONLY | CLK_MUX_READ_ONLY.

Also Mike is propably still working in the so called coordinated rate change
for clocks needing special handling on rate changes, which might provide a
second approach to this.
You mean there is a patch set can handle it now? Can you tell me 
the ID,

I want to check it.


So please, first of all get the ATF-interface merged and meanwhile if you need
to read the clock-rate, just use a regular composite, with the read-only flags.

My colleague are wroking on ATF code now, I agree with you, We can 
not merge
this patch set before ATF-interface merged. And we do not need to 
add a new code
if we only want to read ddr clock rate(we can get the ddr rate to 
read dpll), so i prefer
to keep this function for now, and do review first, once the ATF 
code ready, we can merge

soon(i hope :-P ) .

+   spin_unlock_irqrestore(ddrclk->lock, flags);
+
+   return 0;
+}
+
+static unsigned long
+rockchip_ddrclk_recalc_rate(struct clk_hw *hw,
+   unsigned long parent_rate)
+{
+   struct rockchip_ddrclk *ddrclk = to_rockchip_ddrclk_hw(hw);
+   int val;
+
+   val = clk_readl(ddrclk->reg_base +
+   ddrclk->mux_offset) >> ddrclk->div_shift;
+   val &= val_mask(ddrclk->div_width);
+
+   return DIV_ROUND_UP_ULL((u64)parent_rate, val + 1);

return divider_recalc_rate(...)

got it , thank you.



Heiko





--
Lin Huang




Re: [RFC PATCH v1 1/6] rockchip: rockchip: add new clock-type for the ddrclk

2016-06-05 Thread hl

Hi Heiko,

On 2016年06月03日 20:51, Heiko Stübner wrote:

Am Freitag, 3. Juni 2016, 17:55:14 schrieb Lin Huang:

On new rockchip platform(rk3399 etc), there have dcf controller to
do ddr frequency scaling, and this controller will implement in
arm-trust-firmware. We add a special clock-type to handle that.

Signed-off-by: Lin Huang 
---
Changes in v1:
- None

  drivers/clk/rockchip/Makefile  |   1 +
  drivers/clk/rockchip/clk-ddr.c | 147
+ drivers/clk/rockchip/clk.c |
  9 +++
  drivers/clk/rockchip/clk.h |  27 
  4 files changed, 184 insertions(+)
  create mode 100644 drivers/clk/rockchip/clk-ddr.c

diff --git a/drivers/clk/rockchip/Makefile b/drivers/clk/rockchip/Makefile
index f47a2fa..b5f2c8e 100644
--- a/drivers/clk/rockchip/Makefile
+++ b/drivers/clk/rockchip/Makefile
@@ -8,6 +8,7 @@ obj-y   += clk-pll.o
  obj-y += clk-cpu.o
  obj-y += clk-inverter.o
  obj-y += clk-mmc-phase.o
+obj-y  += clk-ddr.o
  obj-$(CONFIG_RESET_CONTROLLER)+= softrst.o

  obj-y += clk-rk3036.o
diff --git a/drivers/clk/rockchip/clk-ddr.c b/drivers/clk/rockchip/clk-ddr.c
new file mode 100644
index 000..5b6630d
--- /dev/null
+++ b/drivers/clk/rockchip/clk-ddr.c
@@ -0,0 +1,147 @@
+/*
+ * Copyright (c) 2016 Rockchip Electronics Co. Ltd.
+ * Author: Lin Huang 
+ *
+ * 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.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include "clk.h"
+
+struct rockchip_ddrclk {
+   struct clk_hw   hw;
+   void __iomem*reg_base;
+   int mux_offset;
+   int mux_shift;
+   int mux_width;
+   int mux_flag;
+   int div_shift;
+   int div_width;
+   int div_flag;
+   spinlock_t  *lock;
+};
+
+#define to_rockchip_ddrclk_hw(hw) container_of(hw, struct rockchip_ddrclk,
hw)
+#define val_mask(width)((1 << (width)) - 1)

maybe use GENMASK?

Oh, yes, we can use it. Will fix next version.



+
+static int rockchip_ddrclk_set_rate(struct clk_hw *hw, unsigned long drate,
+   unsigned long prate)
+{
+   struct rockchip_ddrclk *ddrclk = to_rockchip_ddrclk_hw(hw);
+   unsigned long flags;
+
+   spin_lock_irqsave(ddrclk->lock, flags);
+
+   /* TODO: set ddr rate in bl31 */

I expect this interface to be in existence and merged into the main ATF first.

Right now the whole clock-type does nothing more than a simple COMPOSITE with
added CLK_DIVIDER_READ_ONLY | CLK_MUX_READ_ONLY.

Also Mike is propably still working in the so called coordinated rate change
for clocks needing special handling on rate changes, which might provide a
second approach to this.
You mean there is a patch set can handle it now? Can you tell me 
the ID,

I want to check it.


So please, first of all get the ATF-interface merged and meanwhile if you need
to read the clock-rate, just use a regular composite, with the read-only flags.

My colleague are wroking on ATF code now, I agree with you, We can 
not merge
this patch set before ATF-interface merged. And we do not need to 
add a new code
if we only want to read ddr clock rate(we can get the ddr rate to 
read dpll), so i prefer
to keep this function for now, and do review first, once the ATF 
code ready, we can merge

soon(i hope :-P ) .

+   spin_unlock_irqrestore(ddrclk->lock, flags);
+
+   return 0;
+}
+
+static unsigned long
+rockchip_ddrclk_recalc_rate(struct clk_hw *hw,
+   unsigned long parent_rate)
+{
+   struct rockchip_ddrclk *ddrclk = to_rockchip_ddrclk_hw(hw);
+   int val;
+
+   val = clk_readl(ddrclk->reg_base +
+   ddrclk->mux_offset) >> ddrclk->div_shift;
+   val &= val_mask(ddrclk->div_width);
+
+   return DIV_ROUND_UP_ULL((u64)parent_rate, val + 1);

return divider_recalc_rate(...)

got it , thank you.



Heiko





--
Lin Huang




Re: [RFC PATCH v1 3/6] clk: rockchip: rk3399: add ddrc clock support

2016-06-05 Thread hl

Hi Heiko,

On 2016年06月03日 20:56, Heiko Stübner wrote:

Am Freitag, 3. Juni 2016, 17:55:16 schrieb Lin Huang:

add ddrc clock setting, so we can do ddr frequency
scaling on rk3399 platform in future.

Signed-off-by: Lin Huang 
---
Changes in v1:
- remove ddrc source CLK_IGNORE_UNUSED flag, Suggestion by Doug
- move clk_ddrc and clk_ddrc_dpll_src to critical, Suggestion by Doug

  drivers/clk/rockchip/clk-rk3399.c | 20 
  1 file changed, 20 insertions(+)

diff --git a/drivers/clk/rockchip/clk-rk3399.c
b/drivers/clk/rockchip/clk-rk3399.c index f1d8e44..29afb88 100644
--- a/drivers/clk/rockchip/clk-rk3399.c
+++ b/drivers/clk/rockchip/clk-rk3399.c

[...]


@@ -1377,6 +1381,18 @@ static struct rockchip_clk_branch
rk3399_clk_branches[] __initdata = { COMPOSITE_NOMUX(0, "clk_test",
"clk_test_pre", CLK_IGNORE_UNUSED, RK3368_CLKSEL_CON(58), 0, 5, DFLAGS,
RK3368_CLKGATE_CON(13), 11, GFLAGS),
+
+   /* ddrc */
+   GATE(0, "clk_ddrc_lpll_src", "lpll", 0, RK3399_CLKGATE_CON(3),
+0, GFLAGS),
+   GATE(0, "clk_ddrc_bpll_src", "bpll", 0, RK3399_CLKGATE_CON(3),
+1, GFLAGS),
+   GATE(0, "clk_ddrc_dpll_src", "dpll", 0, RK3399_CLKGATE_CON(3),
+2, GFLAGS),
+   GATE(0, "clk_ddrc_gpll_src", "gpll", 0, RK3399_CLKGATE_CON(3),
+3, GFLAGS),
+   COMPOSITE_DDRC(SCLK_DDRCLK, "clk_ddrc", mux_ddrclk_p, 0,
+  RK3399_CLKSEL_CON(6), 4, 2, MFLAGS, 0, 3, DFLAGS),
  };

as said in the other patch, just make this a regular COMPOSITE_NOGATE with
CLK_DIVIDER_READ_ONLY | CLK_MUX_READ_ONLY until that interface to the ATF
exists and is approved.

That way you can still read back the clock rate without anything changing the
clock-rate, but we don't need to add duplicate code for it.



  static struct rockchip_clk_branch rk3399_clk_pmu_branches[] __initdata = {
@@ -1487,6 +1503,10 @@ static const char *const rk3399_cru_critical_clocks[]
__initconst = { "gpll_hclk_perilp1_src",
"gpll_aclk_perilp0_src",
"gpll_aclk_perihp_src",
+
+   /* ddrc */
+   "clk_ddrc_dpll_src",

Why does your clk_ddrc_dpll_src need a separate critical entry. Any code
changing the clk_ddrc parent should make sure the new parent is enabled. (The
clock-framework of course does this already).

Okay, thank you.



+   "clk_ddrc",
  };

  static const char *const rk3399_pmucru_critical_clocks[] __initconst = {


Heiko






--
Lin Huang




Re: [RFC PATCH v1 3/6] clk: rockchip: rk3399: add ddrc clock support

2016-06-05 Thread hl

Hi Heiko,

On 2016年06月03日 20:56, Heiko Stübner wrote:

Am Freitag, 3. Juni 2016, 17:55:16 schrieb Lin Huang:

add ddrc clock setting, so we can do ddr frequency
scaling on rk3399 platform in future.

Signed-off-by: Lin Huang 
---
Changes in v1:
- remove ddrc source CLK_IGNORE_UNUSED flag, Suggestion by Doug
- move clk_ddrc and clk_ddrc_dpll_src to critical, Suggestion by Doug

  drivers/clk/rockchip/clk-rk3399.c | 20 
  1 file changed, 20 insertions(+)

diff --git a/drivers/clk/rockchip/clk-rk3399.c
b/drivers/clk/rockchip/clk-rk3399.c index f1d8e44..29afb88 100644
--- a/drivers/clk/rockchip/clk-rk3399.c
+++ b/drivers/clk/rockchip/clk-rk3399.c

[...]


@@ -1377,6 +1381,18 @@ static struct rockchip_clk_branch
rk3399_clk_branches[] __initdata = { COMPOSITE_NOMUX(0, "clk_test",
"clk_test_pre", CLK_IGNORE_UNUSED, RK3368_CLKSEL_CON(58), 0, 5, DFLAGS,
RK3368_CLKGATE_CON(13), 11, GFLAGS),
+
+   /* ddrc */
+   GATE(0, "clk_ddrc_lpll_src", "lpll", 0, RK3399_CLKGATE_CON(3),
+0, GFLAGS),
+   GATE(0, "clk_ddrc_bpll_src", "bpll", 0, RK3399_CLKGATE_CON(3),
+1, GFLAGS),
+   GATE(0, "clk_ddrc_dpll_src", "dpll", 0, RK3399_CLKGATE_CON(3),
+2, GFLAGS),
+   GATE(0, "clk_ddrc_gpll_src", "gpll", 0, RK3399_CLKGATE_CON(3),
+3, GFLAGS),
+   COMPOSITE_DDRC(SCLK_DDRCLK, "clk_ddrc", mux_ddrclk_p, 0,
+  RK3399_CLKSEL_CON(6), 4, 2, MFLAGS, 0, 3, DFLAGS),
  };

as said in the other patch, just make this a regular COMPOSITE_NOGATE with
CLK_DIVIDER_READ_ONLY | CLK_MUX_READ_ONLY until that interface to the ATF
exists and is approved.

That way you can still read back the clock rate without anything changing the
clock-rate, but we don't need to add duplicate code for it.



  static struct rockchip_clk_branch rk3399_clk_pmu_branches[] __initdata = {
@@ -1487,6 +1503,10 @@ static const char *const rk3399_cru_critical_clocks[]
__initconst = { "gpll_hclk_perilp1_src",
"gpll_aclk_perilp0_src",
"gpll_aclk_perihp_src",
+
+   /* ddrc */
+   "clk_ddrc_dpll_src",

Why does your clk_ddrc_dpll_src need a separate critical entry. Any code
changing the clk_ddrc parent should make sure the new parent is enabled. (The
clock-framework of course does this already).

Okay, thank you.



+   "clk_ddrc",
  };

  static const char *const rk3399_pmucru_critical_clocks[] __initconst = {


Heiko






--
Lin Huang




Re: [RFC PATCH v1 1/6] rockchip: rockchip: add new clock-type for the ddrclk

2016-06-05 Thread hl

Hi Heiko,

On 2016年06月03日 20:51, Heiko Stübner wrote:

Am Freitag, 3. Juni 2016, 17:55:14 schrieb Lin Huang:

On new rockchip platform(rk3399 etc), there have dcf controller to
do ddr frequency scaling, and this controller will implement in
arm-trust-firmware. We add a special clock-type to handle that.

Signed-off-by: Lin Huang 
---
Changes in v1:
- None

  drivers/clk/rockchip/Makefile  |   1 +
  drivers/clk/rockchip/clk-ddr.c | 147
+ drivers/clk/rockchip/clk.c |
  9 +++
  drivers/clk/rockchip/clk.h |  27 
  4 files changed, 184 insertions(+)
  create mode 100644 drivers/clk/rockchip/clk-ddr.c

diff --git a/drivers/clk/rockchip/Makefile b/drivers/clk/rockchip/Makefile
index f47a2fa..b5f2c8e 100644
--- a/drivers/clk/rockchip/Makefile
+++ b/drivers/clk/rockchip/Makefile
@@ -8,6 +8,7 @@ obj-y   += clk-pll.o
  obj-y += clk-cpu.o
  obj-y += clk-inverter.o
  obj-y += clk-mmc-phase.o
+obj-y  += clk-ddr.o
  obj-$(CONFIG_RESET_CONTROLLER)+= softrst.o

  obj-y += clk-rk3036.o
diff --git a/drivers/clk/rockchip/clk-ddr.c b/drivers/clk/rockchip/clk-ddr.c
new file mode 100644
index 000..5b6630d
--- /dev/null
+++ b/drivers/clk/rockchip/clk-ddr.c
@@ -0,0 +1,147 @@
+/*
+ * Copyright (c) 2016 Rockchip Electronics Co. Ltd.
+ * Author: Lin Huang 
+ *
+ * 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.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include "clk.h"
+
+struct rockchip_ddrclk {
+   struct clk_hw   hw;
+   void __iomem*reg_base;
+   int mux_offset;
+   int mux_shift;
+   int mux_width;
+   int mux_flag;
+   int div_shift;
+   int div_width;
+   int div_flag;
+   spinlock_t  *lock;
+};
+
+#define to_rockchip_ddrclk_hw(hw) container_of(hw, struct rockchip_ddrclk,
hw)
+#define val_mask(width)((1 << (width)) - 1)

maybe use GENMASK?

Oh, yes, we can use it. Will fix next version.



+
+static int rockchip_ddrclk_set_rate(struct clk_hw *hw, unsigned long drate,
+   unsigned long prate)
+{
+   struct rockchip_ddrclk *ddrclk = to_rockchip_ddrclk_hw(hw);
+   unsigned long flags;
+
+   spin_lock_irqsave(ddrclk->lock, flags);
+
+   /* TODO: set ddr rate in bl31 */

I expect this interface to be in existence and merged into the main ATF first.

Right now the whole clock-type does nothing more than a simple COMPOSITE with
added CLK_DIVIDER_READ_ONLY | CLK_MUX_READ_ONLY.

Also Mike is propably still working in the so called coordinated rate change
for clocks needing special handling on rate changes, which might provide a
second approach to this.
You mean there is a patch set can handle it now? Can you tell me 
the ID,

I want to check it.


So please, first of all get the ATF-interface merged and meanwhile if you need
to read the clock-rate, just use a regular composite, with the read-only flags.

My colleague are wroking on ATF code now, I agree with you, We can 
not merge
this patch set before ATF-interface merged. And we do not need to 
add a new code
if we only want to read ddr clock rate(we can get the ddr rate to 
read dpll), so i prefer
to keep this function for now, and do review first, once the ATF 
code ready, we can merge

soon it(i hope :-P ) .

+   spin_unlock_irqrestore(ddrclk->lock, flags);
+
+   return 0;
+}
+
+static unsigned long
+rockchip_ddrclk_recalc_rate(struct clk_hw *hw,
+   unsigned long parent_rate)
+{
+   struct rockchip_ddrclk *ddrclk = to_rockchip_ddrclk_hw(hw);
+   int val;
+
+   val = clk_readl(ddrclk->reg_base +
+   ddrclk->mux_offset) >> ddrclk->div_shift;
+   val &= val_mask(ddrclk->div_width);
+
+   return DIV_ROUND_UP_ULL((u64)parent_rate, val + 1);

return divider_recalc_rate(...)

got it , thank you.



Heiko





--
Lin Huang




Re: [RFC PATCH v1 1/6] rockchip: rockchip: add new clock-type for the ddrclk

2016-06-05 Thread hl

Hi Heiko,

On 2016年06月03日 20:51, Heiko Stübner wrote:

Am Freitag, 3. Juni 2016, 17:55:14 schrieb Lin Huang:

On new rockchip platform(rk3399 etc), there have dcf controller to
do ddr frequency scaling, and this controller will implement in
arm-trust-firmware. We add a special clock-type to handle that.

Signed-off-by: Lin Huang 
---
Changes in v1:
- None

  drivers/clk/rockchip/Makefile  |   1 +
  drivers/clk/rockchip/clk-ddr.c | 147
+ drivers/clk/rockchip/clk.c |
  9 +++
  drivers/clk/rockchip/clk.h |  27 
  4 files changed, 184 insertions(+)
  create mode 100644 drivers/clk/rockchip/clk-ddr.c

diff --git a/drivers/clk/rockchip/Makefile b/drivers/clk/rockchip/Makefile
index f47a2fa..b5f2c8e 100644
--- a/drivers/clk/rockchip/Makefile
+++ b/drivers/clk/rockchip/Makefile
@@ -8,6 +8,7 @@ obj-y   += clk-pll.o
  obj-y += clk-cpu.o
  obj-y += clk-inverter.o
  obj-y += clk-mmc-phase.o
+obj-y  += clk-ddr.o
  obj-$(CONFIG_RESET_CONTROLLER)+= softrst.o

  obj-y += clk-rk3036.o
diff --git a/drivers/clk/rockchip/clk-ddr.c b/drivers/clk/rockchip/clk-ddr.c
new file mode 100644
index 000..5b6630d
--- /dev/null
+++ b/drivers/clk/rockchip/clk-ddr.c
@@ -0,0 +1,147 @@
+/*
+ * Copyright (c) 2016 Rockchip Electronics Co. Ltd.
+ * Author: Lin Huang 
+ *
+ * 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.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include "clk.h"
+
+struct rockchip_ddrclk {
+   struct clk_hw   hw;
+   void __iomem*reg_base;
+   int mux_offset;
+   int mux_shift;
+   int mux_width;
+   int mux_flag;
+   int div_shift;
+   int div_width;
+   int div_flag;
+   spinlock_t  *lock;
+};
+
+#define to_rockchip_ddrclk_hw(hw) container_of(hw, struct rockchip_ddrclk,
hw)
+#define val_mask(width)((1 << (width)) - 1)

maybe use GENMASK?

Oh, yes, we can use it. Will fix next version.



+
+static int rockchip_ddrclk_set_rate(struct clk_hw *hw, unsigned long drate,
+   unsigned long prate)
+{
+   struct rockchip_ddrclk *ddrclk = to_rockchip_ddrclk_hw(hw);
+   unsigned long flags;
+
+   spin_lock_irqsave(ddrclk->lock, flags);
+
+   /* TODO: set ddr rate in bl31 */

I expect this interface to be in existence and merged into the main ATF first.

Right now the whole clock-type does nothing more than a simple COMPOSITE with
added CLK_DIVIDER_READ_ONLY | CLK_MUX_READ_ONLY.

Also Mike is propably still working in the so called coordinated rate change
for clocks needing special handling on rate changes, which might provide a
second approach to this.
You mean there is a patch set can handle it now? Can you tell me 
the ID,

I want to check it.


So please, first of all get the ATF-interface merged and meanwhile if you need
to read the clock-rate, just use a regular composite, with the read-only flags.

My colleague are wroking on ATF code now, I agree with you, We can 
not merge
this patch set before ATF-interface merged. And we do not need to 
add a new code
if we only want to read ddr clock rate(we can get the ddr rate to 
read dpll), so i prefer
to keep this function for now, and do review first, once the ATF 
code ready, we can merge

soon it(i hope :-P ) .

+   spin_unlock_irqrestore(ddrclk->lock, flags);
+
+   return 0;
+}
+
+static unsigned long
+rockchip_ddrclk_recalc_rate(struct clk_hw *hw,
+   unsigned long parent_rate)
+{
+   struct rockchip_ddrclk *ddrclk = to_rockchip_ddrclk_hw(hw);
+   int val;
+
+   val = clk_readl(ddrclk->reg_base +
+   ddrclk->mux_offset) >> ddrclk->div_shift;
+   val &= val_mask(ddrclk->div_width);
+
+   return DIV_ROUND_UP_ULL((u64)parent_rate, val + 1);

return divider_recalc_rate(...)

got it , thank you.



Heiko





--
Lin Huang




Re: [RFC PATCH v1 1/6] rockchip: rockchip: add new clock-type for the ddrclk

2016-06-05 Thread hl

Hi Shawn,

On 2016年06月03日 20:29, Shawn Lin wrote:

Hi Lin,

It looks good with only a few minor comments.

On 2016/6/3 17:55, Lin Huang wrote:

On new rockchip platform(rk3399 etc), there have dcf controller to
do ddr frequency scaling, and this controller will implement in
arm-trust-firmware. We add a special clock-type to handle that.

Signed-off-by: Lin Huang 
---
Changes in v1:
- None

 drivers/clk/rockchip/Makefile  |   1 +
 drivers/clk/rockchip/clk-ddr.c | 147 
+

 drivers/clk/rockchip/clk.c |   9 +++
 drivers/clk/rockchip/clk.h |  27 
 4 files changed, 184 insertions(+)
 create mode 100644 drivers/clk/rockchip/clk-ddr.c

diff --git a/drivers/clk/rockchip/Makefile 
b/drivers/clk/rockchip/Makefile

index f47a2fa..b5f2c8e 100644
--- a/drivers/clk/rockchip/Makefile
+++ b/drivers/clk/rockchip/Makefile
@@ -8,6 +8,7 @@ obj-y+= clk-pll.o
 obj-y+= clk-cpu.o
 obj-y+= clk-inverter.o
 obj-y+= clk-mmc-phase.o
+obj-y+= clk-ddr.o
 obj-$(CONFIG_RESET_CONTROLLER)+= softrst.o

 obj-y+= clk-rk3036.o
diff --git a/drivers/clk/rockchip/clk-ddr.c 
b/drivers/clk/rockchip/clk-ddr.c

new file mode 100644
index 000..5b6630d
--- /dev/null
+++ b/drivers/clk/rockchip/clk-ddr.c
@@ -0,0 +1,147 @@
+/*
+ * Copyright (c) 2016 Rockchip Electronics Co. Ltd.
+ * Author: Lin Huang 
+ *
+ * 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.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include "clk.h"
+


alphabetical order would be better.

Okay, will fix next version, thank you.



+struct rockchip_ddrclk {
+struct clk_hwhw;
+void __iomem*reg_base;
+intmux_offset;
+intmux_shift;
+intmux_width;
+intmux_flag;
+intdiv_shift;
+intdiv_width;
+intdiv_flag;
+spinlock_t*lock;
+};
+
+#define to_rockchip_ddrclk_hw(hw) container_of(hw, struct 
rockchip_ddrclk, hw)

+#define val_mask(width)((1 << (width)) - 1)
+
+static int rockchip_ddrclk_set_rate(struct clk_hw *hw, unsigned long 
drate,

+unsigned long prate)
+{
+struct rockchip_ddrclk *ddrclk = to_rockchip_ddrclk_hw(hw);
+unsigned long flags;
+
+spin_lock_irqsave(ddrclk->lock, flags);
+
+/* TODO: set ddr rate in bl31 */
+
+spin_unlock_irqrestore(ddrclk->lock, flags);
+


What do you wanna protect here?

I am not sure for now, when i finish this function,
if there nothing need protect i will remove it. Thank you.



+return 0;
+}
+
+static unsigned long
+rockchip_ddrclk_recalc_rate(struct clk_hw *hw,
+unsigned long parent_rate)
+{
+struct rockchip_ddrclk *ddrclk = to_rockchip_ddrclk_hw(hw);
+int val;
+
+val = clk_readl(ddrclk->reg_base +
+ddrclk->mux_offset) >> ddrclk->div_shift;
+val &= val_mask(ddrclk->div_width);
+
+return DIV_ROUND_UP_ULL((u64)parent_rate, val + 1);
+}
+
+static long clk_ddrclk_round_rate(struct clk_hw *hw, unsigned long 
rate,

+  unsigned long *prate)
+{
+return rate;
+}
+
+static u8 rockchip_ddrclk_get_parent(struct clk_hw *hw)
+{
+struct rockchip_ddrclk *ddrclk = to_rockchip_ddrclk_hw(hw);
+int num_parents = clk_hw_get_num_parents(hw);
+u32 val;
+
+val = clk_readl(ddrclk->reg_base +
+ddrclk->mux_offset) >> ddrclk->mux_shift;
+val &= val_mask(ddrclk->mux_width);
+
+if (val >= num_parents)
+return -EINVAL;
+
+return val;
+}
+
+static const struct clk_ops rockchip_ddrclk_ops = {
+.recalc_rate = rockchip_ddrclk_recalc_rate,
+.set_rate = rockchip_ddrclk_set_rate,
+.round_rate = clk_ddrclk_round_rate,
+.get_parent = rockchip_ddrclk_get_parent,
+};
+
+struct clk *rockchip_clk_register_ddrclk(const char *name, int flags,
+ const char *const *parent_names,
+ u8 num_parents, int mux_offset,
+ int mux_shift, int mux_width,
+ int mux_flag, int div_shift,
+ int div_width, int div_flag,
+ void __iomem *reg_base,
+ spinlock_t *lock)
+{
+struct rockchip_ddrclk *ddrclk;
+struct clk_init_data init;
+struct clk *clk;
+int ret;
+
+ddrclk = kzalloc(sizeof(*ddrclk), GFP_KERNEL);
+if (!ddrclk)
+return ERR_PTR(-ENOMEM);
+
+init.name = name;
+init.parent_names = parent_names;
+init.num_parents = num_parents;
+init.ops = 

Re: [RFC PATCH v1 1/6] rockchip: rockchip: add new clock-type for the ddrclk

2016-06-05 Thread hl

Hi Shawn,

On 2016年06月03日 20:29, Shawn Lin wrote:

Hi Lin,

It looks good with only a few minor comments.

On 2016/6/3 17:55, Lin Huang wrote:

On new rockchip platform(rk3399 etc), there have dcf controller to
do ddr frequency scaling, and this controller will implement in
arm-trust-firmware. We add a special clock-type to handle that.

Signed-off-by: Lin Huang 
---
Changes in v1:
- None

 drivers/clk/rockchip/Makefile  |   1 +
 drivers/clk/rockchip/clk-ddr.c | 147 
+

 drivers/clk/rockchip/clk.c |   9 +++
 drivers/clk/rockchip/clk.h |  27 
 4 files changed, 184 insertions(+)
 create mode 100644 drivers/clk/rockchip/clk-ddr.c

diff --git a/drivers/clk/rockchip/Makefile 
b/drivers/clk/rockchip/Makefile

index f47a2fa..b5f2c8e 100644
--- a/drivers/clk/rockchip/Makefile
+++ b/drivers/clk/rockchip/Makefile
@@ -8,6 +8,7 @@ obj-y+= clk-pll.o
 obj-y+= clk-cpu.o
 obj-y+= clk-inverter.o
 obj-y+= clk-mmc-phase.o
+obj-y+= clk-ddr.o
 obj-$(CONFIG_RESET_CONTROLLER)+= softrst.o

 obj-y+= clk-rk3036.o
diff --git a/drivers/clk/rockchip/clk-ddr.c 
b/drivers/clk/rockchip/clk-ddr.c

new file mode 100644
index 000..5b6630d
--- /dev/null
+++ b/drivers/clk/rockchip/clk-ddr.c
@@ -0,0 +1,147 @@
+/*
+ * Copyright (c) 2016 Rockchip Electronics Co. Ltd.
+ * Author: Lin Huang 
+ *
+ * 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.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include "clk.h"
+


alphabetical order would be better.

Okay, will fix next version, thank you.



+struct rockchip_ddrclk {
+struct clk_hwhw;
+void __iomem*reg_base;
+intmux_offset;
+intmux_shift;
+intmux_width;
+intmux_flag;
+intdiv_shift;
+intdiv_width;
+intdiv_flag;
+spinlock_t*lock;
+};
+
+#define to_rockchip_ddrclk_hw(hw) container_of(hw, struct 
rockchip_ddrclk, hw)

+#define val_mask(width)((1 << (width)) - 1)
+
+static int rockchip_ddrclk_set_rate(struct clk_hw *hw, unsigned long 
drate,

+unsigned long prate)
+{
+struct rockchip_ddrclk *ddrclk = to_rockchip_ddrclk_hw(hw);
+unsigned long flags;
+
+spin_lock_irqsave(ddrclk->lock, flags);
+
+/* TODO: set ddr rate in bl31 */
+
+spin_unlock_irqrestore(ddrclk->lock, flags);
+


What do you wanna protect here?

I am not sure for now, when i finish this function,
if there nothing need protect i will remove it. Thank you.



+return 0;
+}
+
+static unsigned long
+rockchip_ddrclk_recalc_rate(struct clk_hw *hw,
+unsigned long parent_rate)
+{
+struct rockchip_ddrclk *ddrclk = to_rockchip_ddrclk_hw(hw);
+int val;
+
+val = clk_readl(ddrclk->reg_base +
+ddrclk->mux_offset) >> ddrclk->div_shift;
+val &= val_mask(ddrclk->div_width);
+
+return DIV_ROUND_UP_ULL((u64)parent_rate, val + 1);
+}
+
+static long clk_ddrclk_round_rate(struct clk_hw *hw, unsigned long 
rate,

+  unsigned long *prate)
+{
+return rate;
+}
+
+static u8 rockchip_ddrclk_get_parent(struct clk_hw *hw)
+{
+struct rockchip_ddrclk *ddrclk = to_rockchip_ddrclk_hw(hw);
+int num_parents = clk_hw_get_num_parents(hw);
+u32 val;
+
+val = clk_readl(ddrclk->reg_base +
+ddrclk->mux_offset) >> ddrclk->mux_shift;
+val &= val_mask(ddrclk->mux_width);
+
+if (val >= num_parents)
+return -EINVAL;
+
+return val;
+}
+
+static const struct clk_ops rockchip_ddrclk_ops = {
+.recalc_rate = rockchip_ddrclk_recalc_rate,
+.set_rate = rockchip_ddrclk_set_rate,
+.round_rate = clk_ddrclk_round_rate,
+.get_parent = rockchip_ddrclk_get_parent,
+};
+
+struct clk *rockchip_clk_register_ddrclk(const char *name, int flags,
+ const char *const *parent_names,
+ u8 num_parents, int mux_offset,
+ int mux_shift, int mux_width,
+ int mux_flag, int div_shift,
+ int div_width, int div_flag,
+ void __iomem *reg_base,
+ spinlock_t *lock)
+{
+struct rockchip_ddrclk *ddrclk;
+struct clk_init_data init;
+struct clk *clk;
+int ret;
+
+ddrclk = kzalloc(sizeof(*ddrclk), GFP_KERNEL);
+if (!ddrclk)
+return ERR_PTR(-ENOMEM);
+
+init.name = name;
+init.parent_names = parent_names;
+init.num_parents = num_parents;
+init.ops = _ddrclk_ops;
+
+init.flags = flags;
+

Re: [RFC PATCH 3/4] PM / devfreq: rockchip: add devfreq driver for rk3399 dmc

2016-06-01 Thread hl

Hi Chanwoo Choi,

I just check the devfreq-event framework code, it is good,
i will do more dig to see whether it can fit for rk3399 dmc, thank you.

On 2016年06月01日 19:47, Chanwoo Choi wrote:

Hi Lin,

This patch include the two features as following:
- Monitor the ddr load
- Control the ddr's clock with ondemand governor based on load

The "Monitor the ddr load" has the specific the address in SoC.
Namely, it is separate the module.
So, I implemented the devfreq-event framework[1] which was merged.

It is right method to separate two feature from your device driver.
You can refer to patch[2][3]. The patch[2] show how to implement the
"monitor the ddr load"
by using Devfreq-Event framework and the patch[3] include the method
how to implement the rk3399 dmc driver.

[1] Devfreq-Event framework
- 
https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/commit/?id=f262f28c147051e7aa6daaf4fb5996833ffadff4

[2] Exynos Noc probe driver by using Devfreq-Event framework
- 
https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/commit/?id=0179a913875a8b39eaf5b848c876439a3a4650af

[3] Exynos Busfreq driver using the devfreq-evnet framework to get the
monitored data
- 
https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/commit/?id=0722249ac1f3dcc3af9e9d7ed89792a68f00

If you have more information and help, please let me know. I'll help you.

Thanks,
Chanwoo Choi

On Wed, Jun 1, 2016 at 6:35 PM, Lin Huang  wrote:

there is dfi controller on rk3399 platform, it can monitor
ddr load, register this controller to devfreq framework, and
default to use simple_ondeamnd policy, and do ddr frequency
scaling base on this result.

Signed-off-by: Lin Huang 
---
  drivers/devfreq/Kconfig |   2 +-
  drivers/devfreq/Makefile|   1 +
  drivers/devfreq/rockchip/Kconfig|  14 +
  drivers/devfreq/rockchip/Makefile   |   2 +
  drivers/devfreq/rockchip/rk3399_dmc.c   | 438 
  drivers/devfreq/rockchip/rockchip_dmc.c | 132 ++
  include/soc/rockchip/rockchip_dmc.h |  44 
  7 files changed, 632 insertions(+), 1 deletion(-)
  create mode 100644 drivers/devfreq/rockchip/Kconfig
  create mode 100644 drivers/devfreq/rockchip/Makefile
  create mode 100644 drivers/devfreq/rockchip/rk3399_dmc.c
  create mode 100644 drivers/devfreq/rockchip/rockchip_dmc.c
  create mode 100644 include/soc/rockchip/rockchip_dmc.h

diff --git a/drivers/devfreq/Kconfig b/drivers/devfreq/Kconfig
index 78dac0e..a883744 100644
--- a/drivers/devfreq/Kconfig
+++ b/drivers/devfreq/Kconfig
@@ -101,5 +101,5 @@ config ARM_TEGRA_DEVFREQ
   operating frequencies and voltages with OPP support.

  source "drivers/devfreq/event/Kconfig"
-
+source "drivers/devfreq/rockchip/Kconfig"
  endif # PM_DEVFREQ
diff --git a/drivers/devfreq/Makefile b/drivers/devfreq/Makefile
index 09f11d9..48e2ae6 100644
--- a/drivers/devfreq/Makefile
+++ b/drivers/devfreq/Makefile
@@ -9,6 +9,7 @@ obj-$(CONFIG_DEVFREQ_GOV_PASSIVE)   += governor_passive.o
  # DEVFREQ Drivers
  obj-$(CONFIG_ARM_EXYNOS_BUS_DEVFREQ)   += exynos-bus.o
  obj-$(CONFIG_ARM_TEGRA_DEVFREQ)+= tegra-devfreq.o
+obj-$(CONFIG_ARCH_ROCKCHIP)+= rockchip/

  # DEVFREQ Event Drivers
  obj-$(CONFIG_PM_DEVFREQ_EVENT) += event/
diff --git a/drivers/devfreq/rockchip/Kconfig b/drivers/devfreq/rockchip/Kconfig
new file mode 100644
index 000..617b5fe
--- /dev/null
+++ b/drivers/devfreq/rockchip/Kconfig
@@ -0,0 +1,14 @@
+config ARM_ROCKCHIP_DMC_DEVFREQ
+   tristate "ARM ROCKCHIP DMC DEVFREQ Driver"
+   depends on ARCH_ROCKCHIP
+   help
+ This adds the DEVFREQ driver framework for the rockchip dmc.
+
+config ARM_RK3399_DMC_DEVFREQ
+   tristate "ARM RK3399 DMC DEVFREQ Driver"
+   depends on ARM_ROCKCHIP_DMC_DEVFREQ
+   select PM_OPP
+   select DEVFREQ_GOV_SIMPLE_ONDEMAND
+   help
+ This adds the DEVFREQ driver for the RK3399 dmc. It sets the frequency
+ for the memory controller and reads the usage counts from hardware.
diff --git a/drivers/devfreq/rockchip/Makefile 
b/drivers/devfreq/rockchip/Makefile
new file mode 100644
index 000..caca525
--- /dev/null
+++ b/drivers/devfreq/rockchip/Makefile
@@ -0,0 +1,2 @@
+obj-$(CONFIG_ARM_ROCKCHIP_DMC_DEVFREQ) += rockchip_dmc.o
+obj-$(CONFIG_ARM_RK3399_DMC_DEVFREQ)   += rk3399_dmc.o
diff --git a/drivers/devfreq/rockchip/rk3399_dmc.c 
b/drivers/devfreq/rockchip/rk3399_dmc.c
new file mode 100644
index 000..4907d38
--- /dev/null
+++ b/drivers/devfreq/rockchip/rk3399_dmc.c
@@ -0,0 +1,438 @@
+/*
+ * Copyright (c) 2016, Fuzhou Rockchip Electronics Co., Ltd
+ * Author: Lin Huang 
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed 

Re: [RFC PATCH 3/4] PM / devfreq: rockchip: add devfreq driver for rk3399 dmc

2016-06-01 Thread hl

Hi Chanwoo Choi,

I just check the devfreq-event framework code, it is good,
i will do more dig to see whether it can fit for rk3399 dmc, thank you.

On 2016年06月01日 19:47, Chanwoo Choi wrote:

Hi Lin,

This patch include the two features as following:
- Monitor the ddr load
- Control the ddr's clock with ondemand governor based on load

The "Monitor the ddr load" has the specific the address in SoC.
Namely, it is separate the module.
So, I implemented the devfreq-event framework[1] which was merged.

It is right method to separate two feature from your device driver.
You can refer to patch[2][3]. The patch[2] show how to implement the
"monitor the ddr load"
by using Devfreq-Event framework and the patch[3] include the method
how to implement the rk3399 dmc driver.

[1] Devfreq-Event framework
- 
https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/commit/?id=f262f28c147051e7aa6daaf4fb5996833ffadff4

[2] Exynos Noc probe driver by using Devfreq-Event framework
- 
https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/commit/?id=0179a913875a8b39eaf5b848c876439a3a4650af

[3] Exynos Busfreq driver using the devfreq-evnet framework to get the
monitored data
- 
https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/commit/?id=0722249ac1f3dcc3af9e9d7ed89792a68f00

If you have more information and help, please let me know. I'll help you.

Thanks,
Chanwoo Choi

On Wed, Jun 1, 2016 at 6:35 PM, Lin Huang  wrote:

there is dfi controller on rk3399 platform, it can monitor
ddr load, register this controller to devfreq framework, and
default to use simple_ondeamnd policy, and do ddr frequency
scaling base on this result.

Signed-off-by: Lin Huang 
---
  drivers/devfreq/Kconfig |   2 +-
  drivers/devfreq/Makefile|   1 +
  drivers/devfreq/rockchip/Kconfig|  14 +
  drivers/devfreq/rockchip/Makefile   |   2 +
  drivers/devfreq/rockchip/rk3399_dmc.c   | 438 
  drivers/devfreq/rockchip/rockchip_dmc.c | 132 ++
  include/soc/rockchip/rockchip_dmc.h |  44 
  7 files changed, 632 insertions(+), 1 deletion(-)
  create mode 100644 drivers/devfreq/rockchip/Kconfig
  create mode 100644 drivers/devfreq/rockchip/Makefile
  create mode 100644 drivers/devfreq/rockchip/rk3399_dmc.c
  create mode 100644 drivers/devfreq/rockchip/rockchip_dmc.c
  create mode 100644 include/soc/rockchip/rockchip_dmc.h

diff --git a/drivers/devfreq/Kconfig b/drivers/devfreq/Kconfig
index 78dac0e..a883744 100644
--- a/drivers/devfreq/Kconfig
+++ b/drivers/devfreq/Kconfig
@@ -101,5 +101,5 @@ config ARM_TEGRA_DEVFREQ
   operating frequencies and voltages with OPP support.

  source "drivers/devfreq/event/Kconfig"
-
+source "drivers/devfreq/rockchip/Kconfig"
  endif # PM_DEVFREQ
diff --git a/drivers/devfreq/Makefile b/drivers/devfreq/Makefile
index 09f11d9..48e2ae6 100644
--- a/drivers/devfreq/Makefile
+++ b/drivers/devfreq/Makefile
@@ -9,6 +9,7 @@ obj-$(CONFIG_DEVFREQ_GOV_PASSIVE)   += governor_passive.o
  # DEVFREQ Drivers
  obj-$(CONFIG_ARM_EXYNOS_BUS_DEVFREQ)   += exynos-bus.o
  obj-$(CONFIG_ARM_TEGRA_DEVFREQ)+= tegra-devfreq.o
+obj-$(CONFIG_ARCH_ROCKCHIP)+= rockchip/

  # DEVFREQ Event Drivers
  obj-$(CONFIG_PM_DEVFREQ_EVENT) += event/
diff --git a/drivers/devfreq/rockchip/Kconfig b/drivers/devfreq/rockchip/Kconfig
new file mode 100644
index 000..617b5fe
--- /dev/null
+++ b/drivers/devfreq/rockchip/Kconfig
@@ -0,0 +1,14 @@
+config ARM_ROCKCHIP_DMC_DEVFREQ
+   tristate "ARM ROCKCHIP DMC DEVFREQ Driver"
+   depends on ARCH_ROCKCHIP
+   help
+ This adds the DEVFREQ driver framework for the rockchip dmc.
+
+config ARM_RK3399_DMC_DEVFREQ
+   tristate "ARM RK3399 DMC DEVFREQ Driver"
+   depends on ARM_ROCKCHIP_DMC_DEVFREQ
+   select PM_OPP
+   select DEVFREQ_GOV_SIMPLE_ONDEMAND
+   help
+ This adds the DEVFREQ driver for the RK3399 dmc. It sets the frequency
+ for the memory controller and reads the usage counts from hardware.
diff --git a/drivers/devfreq/rockchip/Makefile 
b/drivers/devfreq/rockchip/Makefile
new file mode 100644
index 000..caca525
--- /dev/null
+++ b/drivers/devfreq/rockchip/Makefile
@@ -0,0 +1,2 @@
+obj-$(CONFIG_ARM_ROCKCHIP_DMC_DEVFREQ) += rockchip_dmc.o
+obj-$(CONFIG_ARM_RK3399_DMC_DEVFREQ)   += rk3399_dmc.o
diff --git a/drivers/devfreq/rockchip/rk3399_dmc.c 
b/drivers/devfreq/rockchip/rk3399_dmc.c
new file mode 100644
index 000..4907d38
--- /dev/null
+++ b/drivers/devfreq/rockchip/rk3399_dmc.c
@@ -0,0 +1,438 @@
+/*
+ * Copyright (c) 2016, Fuzhou Rockchip Electronics Co., Ltd
+ * Author: Lin Huang 
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; 

Re: [RFC PATCH 3/4] PM / devfreq: rockchip: add devfreq driver for rk3399 dmc

2016-06-01 Thread hl

Hi Myungloo Ham,


On 2016年06月01日 18:47, MyungJoo Ham wrote:

On Wed, Jun 1, 2016 at 6:35 PM, Lin Huang  wrote:

there is dfi controller on rk3399 platform, it can monitor
ddr load, register this controller to devfreq framework, and
default to use simple_ondeamnd policy, and do ddr frequency
scaling base on this result.

Signed-off-by: Lin Huang 
---
  drivers/devfreq/Kconfig |   2 +-
  drivers/devfreq/Makefile|   1 +
  drivers/devfreq/rockchip/Kconfig|  14 +
  drivers/devfreq/rockchip/Makefile   |   2 +
  drivers/devfreq/rockchip/rk3399_dmc.c   | 438 
  drivers/devfreq/rockchip/rockchip_dmc.c | 132 ++
  include/soc/rockchip/rockchip_dmc.h |  44 
  7 files changed, 632 insertions(+), 1 deletion(-)
  create mode 100644 drivers/devfreq/rockchip/Kconfig
  create mode 100644 drivers/devfreq/rockchip/Makefile
  create mode 100644 drivers/devfreq/rockchip/rk3399_dmc.c
  create mode 100644 drivers/devfreq/rockchip/rockchip_dmc.c
  create mode 100644 include/soc/rockchip/rockchip_dmc.h

+
+   /* check the rate we get whether correct */
+   dmcfreq->rate = clk_get_rate(dmcfreq->dmc_clk);
+   if (dmcfreq->rate != target_rate) {
+   dev_err(dev, "get wrong ddr frequency, Request freq %lu,\
+   Current freq %lu\n", target_rate, dmcfreq->rate);
+   regulator_set_voltage(dmcfreq->vdd_center, dmcfreq->volt,
+ dmcfreq->volt);

Why do you need to check this and
more importantly, why do you assume that dmvfreq->volt
will be safe in this case? (what if the new dmcfreq->rate is
larger than the old dmcfreq->rate after clk_get_rate?)
Note that you didn't update dmcfreq->volt after clk_get_rate()
Now we will set the ddr clock rate in bl31 use dcf controller(as i 
show in the patch cover letter),
 and there only two result we can get, set clock rate fail(ddr 
clock still in old rate) or set clock rate
sucessful(use the new ddr rate), if the set rate fail, we should 
keep the voltage old value. Ah, you

remind me, i should check clock rate before:
if (old_clk_rate > target_rate)
otherwise there have chance set high rate fail and use low voltage.

And about the dmcfreq->volt, i will update this value when into the 
function, throuth


opp = devfreq_recommended_opp(dev, >rate, flags);
if (IS_ERR(opp)) {
rcu_read_unlock();
return PTR_ERR(opp);
}
dmcfreq->volt = dev_pm_opp_get_voltage(opp);



+EXPORT_SYMBOL_GPL(dmc_event);
+EXPORT_SYMBOL_GPL(rockchip_dmc_enabled);
+EXPORT_SYMBOL_GPL(rockchip_dmc_enable);
+EXPORT_SYMBOL_GPL(rockchip_dmc_disable);
+EXPORT_SYMBOL_GPL(dmc_register_notifier);
+EXPORT_SYMBOL_GPL(dmc_unregister_notifier);
+EXPORT_SYMBOL_GPL(rockchip_dmc_get);
+EXPORT_SYMBOL_GPL(rockchip_dmc_put);

Do you really need to export all these device driver specific
functions? Looks like a design flaw here.

there is some situation we need to disable ddr frequency 
scaling(connect two panel etc)
on rk3399 platform, and it should be also needed on other rockchip 
platform, so i move these

funticon as separate file.


Cheers,
MyungJoo




--
Lin Huang




Re: [RFC PATCH 3/4] PM / devfreq: rockchip: add devfreq driver for rk3399 dmc

2016-06-01 Thread hl

Hi Myungloo Ham,


On 2016年06月01日 18:47, MyungJoo Ham wrote:

On Wed, Jun 1, 2016 at 6:35 PM, Lin Huang  wrote:

there is dfi controller on rk3399 platform, it can monitor
ddr load, register this controller to devfreq framework, and
default to use simple_ondeamnd policy, and do ddr frequency
scaling base on this result.

Signed-off-by: Lin Huang 
---
  drivers/devfreq/Kconfig |   2 +-
  drivers/devfreq/Makefile|   1 +
  drivers/devfreq/rockchip/Kconfig|  14 +
  drivers/devfreq/rockchip/Makefile   |   2 +
  drivers/devfreq/rockchip/rk3399_dmc.c   | 438 
  drivers/devfreq/rockchip/rockchip_dmc.c | 132 ++
  include/soc/rockchip/rockchip_dmc.h |  44 
  7 files changed, 632 insertions(+), 1 deletion(-)
  create mode 100644 drivers/devfreq/rockchip/Kconfig
  create mode 100644 drivers/devfreq/rockchip/Makefile
  create mode 100644 drivers/devfreq/rockchip/rk3399_dmc.c
  create mode 100644 drivers/devfreq/rockchip/rockchip_dmc.c
  create mode 100644 include/soc/rockchip/rockchip_dmc.h

+
+   /* check the rate we get whether correct */
+   dmcfreq->rate = clk_get_rate(dmcfreq->dmc_clk);
+   if (dmcfreq->rate != target_rate) {
+   dev_err(dev, "get wrong ddr frequency, Request freq %lu,\
+   Current freq %lu\n", target_rate, dmcfreq->rate);
+   regulator_set_voltage(dmcfreq->vdd_center, dmcfreq->volt,
+ dmcfreq->volt);

Why do you need to check this and
more importantly, why do you assume that dmvfreq->volt
will be safe in this case? (what if the new dmcfreq->rate is
larger than the old dmcfreq->rate after clk_get_rate?)
Note that you didn't update dmcfreq->volt after clk_get_rate()
Now we will set the ddr clock rate in bl31 use dcf controller(as i 
show in the patch cover letter),
 and there only two result we can get, set clock rate fail(ddr 
clock still in old rate) or set clock rate
sucessful(use the new ddr rate), if the set rate fail, we should 
keep the voltage old value. Ah, you

remind me, i should check clock rate before:
if (old_clk_rate > target_rate)
otherwise there have chance set high rate fail and use low voltage.

And about the dmcfreq->volt, i will update this value when into the 
function, throuth


opp = devfreq_recommended_opp(dev, >rate, flags);
if (IS_ERR(opp)) {
rcu_read_unlock();
return PTR_ERR(opp);
}
dmcfreq->volt = dev_pm_opp_get_voltage(opp);



+EXPORT_SYMBOL_GPL(dmc_event);
+EXPORT_SYMBOL_GPL(rockchip_dmc_enabled);
+EXPORT_SYMBOL_GPL(rockchip_dmc_enable);
+EXPORT_SYMBOL_GPL(rockchip_dmc_disable);
+EXPORT_SYMBOL_GPL(dmc_register_notifier);
+EXPORT_SYMBOL_GPL(dmc_unregister_notifier);
+EXPORT_SYMBOL_GPL(rockchip_dmc_get);
+EXPORT_SYMBOL_GPL(rockchip_dmc_put);

Do you really need to export all these device driver specific
functions? Looks like a design flaw here.

there is some situation we need to disable ddr frequency 
scaling(connect two panel etc)
on rk3399 platform, and it should be also needed on other rockchip 
platform, so i move these

funticon as separate file.


Cheers,
MyungJoo




--
Lin Huang




Re: [RFC PATCH 2/4] clk: rockchip: rk3399: add ddrc clock support

2016-06-01 Thread hl

Hi Doug,

On 2016年06月01日 23:46, Heiko Stübner wrote:

Am Mittwoch, 1. Juni 2016, 08:24:48 schrieb Doug Anderson:

Lin Huang,

On Wed, Jun 1, 2016 at 2:35 AM, Lin Huang  wrote:

add ddrc clock setting, so we can do ddr frequency
scaling on rk3399 platform in future.

Signed-off-by: Lin Huang 
---

  drivers/clk/rockchip/clk-rk3399.c  | 16 
  include/dt-bindings/clock/rk3399-cru.h |  1 +
  2 files changed, 17 insertions(+)

diff --git a/drivers/clk/rockchip/clk-rk3399.c
b/drivers/clk/rockchip/clk-rk3399.c index f1d8e44..749ea59 100644
--- a/drivers/clk/rockchip/clk-rk3399.c
+++ b/drivers/clk/rockchip/clk-rk3399.c
@@ -118,6 +118,10 @@ PNAME(mux_armclkb_p)   =
{ "clk_core_b_lpll_src",>
 "clk_core_b_bpll_src",
 "clk_core_b_dpll_src",
 "clk_core_b_gpll_src"
 };

+PNAME(mux_ddrclk_p)= { "clk_ddrc_lpll_src",
+   "clk_ddrc_bpll_src",
+   "clk_ddrc_dpll_src",
+   "clk_ddrc_gpll_src" };

  PNAME(mux_aclk_cci_p)  = { "cpll_aclk_cci_src",
  
 "gpll_aclk_cci_src",

 "npll_aclk_cci_src",

@@ -1377,6 +1381,18 @@ static struct rockchip_clk_branch
rk3399_clk_branches[] __initdata = {>
 COMPOSITE_NOMUX(0, "clk_test", "clk_test_pre", CLK_IGNORE_UNUSED,
 
 RK3368_CLKSEL_CON(58), 0, 5, DFLAGS,

 RK3368_CLKGATE_CON(13), 11, GFLAGS),

+
+   /* ddrc */
+   GATE(0, "clk_ddrc_lpll_src", "lpll", CLK_IGNORE_UNUSED,
+RK3399_CLKGATE_CON(3), 0, GFLAGS),
+   GATE(0, "clk_ddrc_bpll_src", "bpll", CLK_IGNORE_UNUSED,
+RK3399_CLKGATE_CON(3), 1, GFLAGS),
+   GATE(0, "clk_ddrc_dpll_src", "dpll", CLK_IGNORE_UNUSED,
+RK3399_CLKGATE_CON(3), 2, GFLAGS),
+   GATE(0, "clk_ddrc_gpll_src", "gpll", CLK_IGNORE_UNUSED,
+RK3399_CLKGATE_CON(3), 3, GFLAGS),
+   COMPOSITE_DDRC(SCLK_DDRCLK, "clk_ddrc", mux_ddrclk_p,
CLK_IGNORE_UNUSED, +  RK3399_CLKSEL_CON(6), 4, 2,
MFLAGS, 0, 3, DFLAGS),

It seems slightly unfortunate that we need CLK_IGNORE_UNUSED on these.
Only one of these will ever be used at once and it would be awfully
nice if the others could get gated, right?

...presumably this is needed because we might not have an actual
driver for DDR Freq and we definitely want to make sure that clk_ddrc
is enabled in that case.  I guess what we really want is something
like CLK_ENABLE_HAND_OFF eventually, but until then I think you might
get slightly better behavior by getting rid of all of these
CLK_IGNORE_UNUSED and setting "clk_ddrc" as a critical clock, either
using the table in this file or the new flag.

My current feeling is that staying with the homegrown solution for critical
clocks might be preferable until the clk-handoff mechanism lands as well, as
our critical clocks fall into both categories and I'd like to not touch
everything twice.

The clock above should be controlled by the dcf, so falls into the handoff
category (critical until a driver picks up the clock).

Also mixing both new and old approach might get confusing.

But I'm definitly open to counter-arguments :-)

I will remove CLK_IGNORE_UNUSED flag  and set
"clk_ddrc"  as critical clock in next version. Besides, i think we 
should also
set "clk_ddrc_dpll_src" as critical clock, since we always use dpll 
as ddr clock source,

and it should always on.



  };
  
  static struct rockchip_clk_branch rk3399_clk_pmu_branches[] __initdata =

  {

diff --git a/include/dt-bindings/clock/rk3399-cru.h
b/include/dt-bindings/clock/rk3399-cru.h index 50a44cf..8a0f0442 100644
--- a/include/dt-bindings/clock/rk3399-cru.h
+++ b/include/dt-bindings/clock/rk3399-cru.h
@@ -131,6 +131,7 @@

  #define SCLK_DPHY_RX0_CFG  165
  #define SCLK_RMII_SRC  166
  #define SCLK_PCIEPHY_REF100M   167

+#define SCLK_DDRCLK168

Almost certainly you'll want to create a separate patch for the
dt-bindings change since it will need to land in a different tree so
it can be pulled into both Heiko's clock topic branch and dts64 topic
branch.

correct.

will fix next version, thanks.


___
Linux-rockchip mailing list
linux-rockc...@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-rockchip





--
Lin Huang




Re: [RFC PATCH 2/4] clk: rockchip: rk3399: add ddrc clock support

2016-06-01 Thread hl

Hi Doug,

On 2016年06月01日 23:46, Heiko Stübner wrote:

Am Mittwoch, 1. Juni 2016, 08:24:48 schrieb Doug Anderson:

Lin Huang,

On Wed, Jun 1, 2016 at 2:35 AM, Lin Huang  wrote:

add ddrc clock setting, so we can do ddr frequency
scaling on rk3399 platform in future.

Signed-off-by: Lin Huang 
---

  drivers/clk/rockchip/clk-rk3399.c  | 16 
  include/dt-bindings/clock/rk3399-cru.h |  1 +
  2 files changed, 17 insertions(+)

diff --git a/drivers/clk/rockchip/clk-rk3399.c
b/drivers/clk/rockchip/clk-rk3399.c index f1d8e44..749ea59 100644
--- a/drivers/clk/rockchip/clk-rk3399.c
+++ b/drivers/clk/rockchip/clk-rk3399.c
@@ -118,6 +118,10 @@ PNAME(mux_armclkb_p)   =
{ "clk_core_b_lpll_src",>
 "clk_core_b_bpll_src",
 "clk_core_b_dpll_src",
 "clk_core_b_gpll_src"
 };

+PNAME(mux_ddrclk_p)= { "clk_ddrc_lpll_src",
+   "clk_ddrc_bpll_src",
+   "clk_ddrc_dpll_src",
+   "clk_ddrc_gpll_src" };

  PNAME(mux_aclk_cci_p)  = { "cpll_aclk_cci_src",
  
 "gpll_aclk_cci_src",

 "npll_aclk_cci_src",

@@ -1377,6 +1381,18 @@ static struct rockchip_clk_branch
rk3399_clk_branches[] __initdata = {>
 COMPOSITE_NOMUX(0, "clk_test", "clk_test_pre", CLK_IGNORE_UNUSED,
 
 RK3368_CLKSEL_CON(58), 0, 5, DFLAGS,

 RK3368_CLKGATE_CON(13), 11, GFLAGS),

+
+   /* ddrc */
+   GATE(0, "clk_ddrc_lpll_src", "lpll", CLK_IGNORE_UNUSED,
+RK3399_CLKGATE_CON(3), 0, GFLAGS),
+   GATE(0, "clk_ddrc_bpll_src", "bpll", CLK_IGNORE_UNUSED,
+RK3399_CLKGATE_CON(3), 1, GFLAGS),
+   GATE(0, "clk_ddrc_dpll_src", "dpll", CLK_IGNORE_UNUSED,
+RK3399_CLKGATE_CON(3), 2, GFLAGS),
+   GATE(0, "clk_ddrc_gpll_src", "gpll", CLK_IGNORE_UNUSED,
+RK3399_CLKGATE_CON(3), 3, GFLAGS),
+   COMPOSITE_DDRC(SCLK_DDRCLK, "clk_ddrc", mux_ddrclk_p,
CLK_IGNORE_UNUSED, +  RK3399_CLKSEL_CON(6), 4, 2,
MFLAGS, 0, 3, DFLAGS),

It seems slightly unfortunate that we need CLK_IGNORE_UNUSED on these.
Only one of these will ever be used at once and it would be awfully
nice if the others could get gated, right?

...presumably this is needed because we might not have an actual
driver for DDR Freq and we definitely want to make sure that clk_ddrc
is enabled in that case.  I guess what we really want is something
like CLK_ENABLE_HAND_OFF eventually, but until then I think you might
get slightly better behavior by getting rid of all of these
CLK_IGNORE_UNUSED and setting "clk_ddrc" as a critical clock, either
using the table in this file or the new flag.

My current feeling is that staying with the homegrown solution for critical
clocks might be preferable until the clk-handoff mechanism lands as well, as
our critical clocks fall into both categories and I'd like to not touch
everything twice.

The clock above should be controlled by the dcf, so falls into the handoff
category (critical until a driver picks up the clock).

Also mixing both new and old approach might get confusing.

But I'm definitly open to counter-arguments :-)

I will remove CLK_IGNORE_UNUSED flag  and set
"clk_ddrc"  as critical clock in next version. Besides, i think we 
should also
set "clk_ddrc_dpll_src" as critical clock, since we always use dpll 
as ddr clock source,

and it should always on.



  };
  
  static struct rockchip_clk_branch rk3399_clk_pmu_branches[] __initdata =

  {

diff --git a/include/dt-bindings/clock/rk3399-cru.h
b/include/dt-bindings/clock/rk3399-cru.h index 50a44cf..8a0f0442 100644
--- a/include/dt-bindings/clock/rk3399-cru.h
+++ b/include/dt-bindings/clock/rk3399-cru.h
@@ -131,6 +131,7 @@

  #define SCLK_DPHY_RX0_CFG  165
  #define SCLK_RMII_SRC  166
  #define SCLK_PCIEPHY_REF100M   167

+#define SCLK_DDRCLK168

Almost certainly you'll want to create a separate patch for the
dt-bindings change since it will need to land in a different tree so
it can be pulled into both Heiko's clock topic branch and dts64 topic
branch.

correct.

will fix next version, thanks.


___
Linux-rockchip mailing list
linux-rockc...@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-rockchip





--
Lin Huang




Re: [PATCH 1/2] clk: rockchip: dmc: support rk3399 dmc clock driver

2015-11-23 Thread hl

Hi MyungJoo,

On 23/11/15 16:09, MyungJoo Ham wrote:

+static unsigned long rk3399_dmcclk_recalc_rate(struct clk_hw *hw,
+  unsigned long parent_rate)
+{
+   struct rk3399_dmcclk *dmc = to_rk3399_dmcclk();
+   u32 val;
+
+   /*
+* Get parent rate since it changed in this clks set_rate op. The parent
+* rate passed into this function is cached before set_rate is called in
+* the common clk code, so we have to get it here.
+*/
+   parent_rate = clk_get_rate(clk_get_parent(hw->clk));
+
+   val = readl(dmc->cru + CRU_CLKSEL6_CON);
+   val = (val >> CLK_DDRC_DIV_CON_SHIFT) & CLK_DDRC_DIV_CON_MASK;
+
+   return parent_rate / (val + 1);
+}
+
+/*
+ * TODO: set ddr frequcney in dcf which run in ATF
+ */
+static int rk3399_dmcclk_set_rate(struct clk_hw *hw, unsigned long rate,
+ unsigned long parent_rate)
+{
+   return 0;
+}

Is it correct that you didn't fill this up because your
Trustzone driver (SMC) is not ready yet?

Yep, the SMC is not ready yet.


Then, why don't you fill that function assuming that TrustZone is not activated
and add SMC call functions with if or #if after its TrustZone driver is ready?

Or does your SoC mandate the usage ot TrustZone, restricting the usage
of CRU_CLKSEL6_CON write? (I don't see why SoC vendors will do this..)


I'll be ready to merge the RK3399 devfreq driver if you
fill this up (assuming that TZ is not enabled) or
add TZ driver and SMC calls.
Thank you for your reply,  it is good idea use if or #if to 
distinguish the TrustZone whether ready,
i will handle it in next version. I may follow Heiko advice to do 
some modify in dmc clock and rk3399 devfreq driver,

I will upload new version when it's ready.


Cheers,
MyungJoo
ps. according to rk339_dmcclk_recalc_rate(), filling rk339_dmcclk_set_rate
assuming that TZ is not enabled seems trivial.


--
Lin Huang


--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH 1/2] clk: rockchip: dmc: support rk3399 dmc clock driver

2015-11-23 Thread hl

Hi Heiko,

On 22/11/15 02:30, Heiko Stuebner wrote:

Hi Lin,

Am Freitag, 20. November 2015, 09:37:15 schrieb hl:

On 20/11/15 05:47, Heiko Stuebner wrote:

Hi Lin,

Am Donnerstag, 19. November 2015, 18:21:10 schrieb Lin Huang:

support rk3399 dmc clock driver. Note, ddr set rate function will
use dcf controller which run in ATF, it need to fishish it when rk3399
arm trust firmware ready.

this unfinalized state is slightly unfortunate and I think this code will
need to wait until CRU and DDRC specs are available.

Because this is clearly part of the CRU (labeled CRU_CLKSEL6_CON etc)
so shouldn't be a separate driver at all and also what your driver currently
only does can still simply be described in the regular scheme as part of
a full clock driver like

PNAME(mux_ddrc_p) = { "pll_dpll", "pll_gpll", "pll_alpll", "pll_abpll" };
COMPOSITE_NOGATE(0, "ddrc", mux_ddrc_p, 0,
RK3399_CLKSEL_CON(6), 4, 2, MFLAGS, 0, 
3,
DFLAGS | CLK_DIVIDER_POWER_OF_TWO),

So the code needs to actually demonstrate why a separate clock type is
really necessary.

I do understand that we will probably need a special way to talk to this
dcf controller but seeing how this interaction will work is really a
prequisite to finding a correct solution.

  if we can use common clock driver, i can put the dfi controller as
a  independent driver
  into devfreq,  this is the best way. But how do we separate the ddr
clk_set_rate() ,
  so we can manipulate dcf controller(actually, we use SMC handle dcf
controller in arm trust firmware ),
  i check clock driver code, it seem there is not way to do that for now.

the core problem I have right now is, that I don't understand how the
interaction with the dfi controller works at all :-) .

One thing that might work, is that your dfi-driver takes the ddrc-clock
from the clock controller and then registers a clock notifier to get
notified before and after the clock-rate changes. But that depends as
stated above on how the dfi-controller needs to be handled.

For example the current armclk-handling uses a clock notifier around the
actual rate change ... so you could use that as inspiration.
Thank you for your inspiration. I think i can handle ddrc clk like 
the armclk.
About the dfi, it will monitor ddr utilization, according this 
result to do
ddr frequency scaling. I think i can implement a dfi drvier, and 
register it to devfreq,
then call the dmc_set_rate fucntion in the dfi drvier, meanwhile i 
will implement a ddrc clk driver
like the armclk, implement set rate funciton, and call the 
dcf(implement in ATF) in this function.



Heiko






--
Lin Huang


--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH 1/2] clk: rockchip: dmc: support rk3399 dmc clock driver

2015-11-23 Thread hl

Hi Heiko,

On 22/11/15 02:30, Heiko Stuebner wrote:

Hi Lin,

Am Freitag, 20. November 2015, 09:37:15 schrieb hl:

On 20/11/15 05:47, Heiko Stuebner wrote:

Hi Lin,

Am Donnerstag, 19. November 2015, 18:21:10 schrieb Lin Huang:

support rk3399 dmc clock driver. Note, ddr set rate function will
use dcf controller which run in ATF, it need to fishish it when rk3399
arm trust firmware ready.

this unfinalized state is slightly unfortunate and I think this code will
need to wait until CRU and DDRC specs are available.

Because this is clearly part of the CRU (labeled CRU_CLKSEL6_CON etc)
so shouldn't be a separate driver at all and also what your driver currently
only does can still simply be described in the regular scheme as part of
a full clock driver like

PNAME(mux_ddrc_p) = { "pll_dpll", "pll_gpll", "pll_alpll", "pll_abpll" };
COMPOSITE_NOGATE(0, "ddrc", mux_ddrc_p, 0,
RK3399_CLKSEL_CON(6), 4, 2, MFLAGS, 0, 
3,
DFLAGS | CLK_DIVIDER_POWER_OF_TWO),

So the code needs to actually demonstrate why a separate clock type is
really necessary.

I do understand that we will probably need a special way to talk to this
dcf controller but seeing how this interaction will work is really a
prequisite to finding a correct solution.

  if we can use common clock driver, i can put the dfi controller as
a  independent driver
  into devfreq,  this is the best way. But how do we separate the ddr
clk_set_rate() ,
  so we can manipulate dcf controller(actually, we use SMC handle dcf
controller in arm trust firmware ),
  i check clock driver code, it seem there is not way to do that for now.

the core problem I have right now is, that I don't understand how the
interaction with the dfi controller works at all :-) .

One thing that might work, is that your dfi-driver takes the ddrc-clock
from the clock controller and then registers a clock notifier to get
notified before and after the clock-rate changes. But that depends as
stated above on how the dfi-controller needs to be handled.

For example the current armclk-handling uses a clock notifier around the
actual rate change ... so you could use that as inspiration.
Thank you for your inspiration. I think i can handle ddrc clk like 
the armclk.
About the dfi, it will monitor ddr utilization, according this 
result to do
ddr frequency scaling. I think i can implement a dfi drvier, and 
register it to devfreq,
then call the dmc_set_rate fucntion in the dfi drvier, meanwhile i 
will implement a ddrc clk driver
like the armclk, implement set rate funciton, and call the 
dcf(implement in ATF) in this function.



Heiko






--
Lin Huang


--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH 1/2] clk: rockchip: dmc: support rk3399 dmc clock driver

2015-11-23 Thread hl

Hi MyungJoo,

On 23/11/15 16:09, MyungJoo Ham wrote:

+static unsigned long rk3399_dmcclk_recalc_rate(struct clk_hw *hw,
+  unsigned long parent_rate)
+{
+   struct rk3399_dmcclk *dmc = to_rk3399_dmcclk();
+   u32 val;
+
+   /*
+* Get parent rate since it changed in this clks set_rate op. The parent
+* rate passed into this function is cached before set_rate is called in
+* the common clk code, so we have to get it here.
+*/
+   parent_rate = clk_get_rate(clk_get_parent(hw->clk));
+
+   val = readl(dmc->cru + CRU_CLKSEL6_CON);
+   val = (val >> CLK_DDRC_DIV_CON_SHIFT) & CLK_DDRC_DIV_CON_MASK;
+
+   return parent_rate / (val + 1);
+}
+
+/*
+ * TODO: set ddr frequcney in dcf which run in ATF
+ */
+static int rk3399_dmcclk_set_rate(struct clk_hw *hw, unsigned long rate,
+ unsigned long parent_rate)
+{
+   return 0;
+}

Is it correct that you didn't fill this up because your
Trustzone driver (SMC) is not ready yet?

Yep, the SMC is not ready yet.


Then, why don't you fill that function assuming that TrustZone is not activated
and add SMC call functions with if or #if after its TrustZone driver is ready?

Or does your SoC mandate the usage ot TrustZone, restricting the usage
of CRU_CLKSEL6_CON write? (I don't see why SoC vendors will do this..)


I'll be ready to merge the RK3399 devfreq driver if you
fill this up (assuming that TZ is not enabled) or
add TZ driver and SMC calls.
Thank you for your reply,  it is good idea use if or #if to 
distinguish the TrustZone whether ready,
i will handle it in next version. I may follow Heiko advice to do 
some modify in dmc clock and rk3399 devfreq driver,

I will upload new version when it's ready.


Cheers,
MyungJoo
ps. according to rk339_dmcclk_recalc_rate(), filling rk339_dmcclk_set_rate
assuming that TZ is not enabled seems trivial.


--
Lin Huang


--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH 1/2] clk: rockchip: dmc: support rk3399 dmc clock driver

2015-11-19 Thread hl

Hi Heiko,

On 20/11/15 05:47, Heiko Stuebner wrote:

Hi Lin,

Am Donnerstag, 19. November 2015, 18:21:10 schrieb Lin Huang:

support rk3399 dmc clock driver. Note, ddr set rate function will
use dcf controller which run in ATF, it need to fishish it when rk3399
arm trust firmware ready.

this unfinalized state is slightly unfortunate and I think this code will
need to wait until CRU and DDRC specs are available.

Because this is clearly part of the CRU (labeled CRU_CLKSEL6_CON etc)
so shouldn't be a separate driver at all and also what your driver currently
only does can still simply be described in the regular scheme as part of
a full clock driver like

PNAME(mux_ddrc_p) = { "pll_dpll", "pll_gpll", "pll_alpll", "pll_abpll" };
COMPOSITE_NOGATE(0, "ddrc", mux_ddrc_p, 0,
RK3399_CLKSEL_CON(6), 4, 2, MFLAGS, 0, 
3,
DFLAGS | CLK_DIVIDER_POWER_OF_TWO),

So the code needs to actually demonstrate why a separate clock type is
really necessary.

I do understand that we will probably need a special way to talk to this
dcf controller but seeing how this interaction will work is really a
prequisite to finding a correct solution.
if we can use common clock driver, i can put the dfi controller as 
a  independent driver
into devfreq,  this is the best way. But how do we separate the ddr 
clk_set_rate() ,
so we can manipulate dcf controller(actually, we use SMC handle dcf 
controller in arm trust firmware ),

i check clock driver code, it seem there is not way to do that for now.


Heiko


---
  drivers/clk/rockchip/Makefile |   1 +
  drivers/clk/rockchip/clk-rk3399-dmc.c | 196 ++
  include/soc/rockchip/rk3399-dmc-clk.h |  36 +++
  3 files changed, 233 insertions(+)
  create mode 100644 drivers/clk/rockchip/clk-rk3399-dmc.c
  create mode 100644 include/soc/rockchip/rk3399-dmc-clk.h

diff --git a/drivers/clk/rockchip/Makefile b/drivers/clk/rockchip/Makefile
index b27edd6..98bd955 100644
--- a/drivers/clk/rockchip/Makefile
+++ b/drivers/clk/rockchip/Makefile
@@ -13,3 +13,4 @@ obj-$(CONFIG_RESET_CONTROLLER)+= softrst.o
  obj-y += clk-rk3188.o
  obj-y += clk-rk3288.o
  obj-y += clk-rk3368.o
+obj-y  += clk-rk3399-dmc.o
diff --git a/drivers/clk/rockchip/clk-rk3399-dmc.c 
b/drivers/clk/rockchip/clk-rk3399-dmc.c
new file mode 100644
index 000..03cc044
--- /dev/null
+++ b/drivers/clk/rockchip/clk-rk3399-dmc.c
@@ -0,0 +1,196 @@
+/*
+ * Copyright (c) 2014, Fuzhou Rockchip Electronics Co., Ltd
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#define to_rk3399_dmcclk(obj)  container_of(obj, struct rk3399_dmcclk, hw)
+
+/* CRU_CLKSEL6_CON*/
+#define CRU_CLKSEL6_CON0x118
+#define CLK_DDRC_PLL_SEL_SHIFT 0x4
+#define CLK_DDRC_PLL_SEL_MASK  0x3
+#define CLK_DDRC_DIV_CON_SHIFT 0
+#define CLK_DDRC_DIV_CON_MASK  0x07
+
+static unsigned long rk3399_dmcclk_recalc_rate(struct clk_hw *hw,
+  unsigned long parent_rate)
+{
+   struct rk3399_dmcclk *dmc = to_rk3399_dmcclk();
+   u32 val;
+
+   /*
+* Get parent rate since it changed in this clks set_rate op. The parent
+* rate passed into this function is cached before set_rate is called in
+* the common clk code, so we have to get it here.
+*/
+   parent_rate = clk_get_rate(clk_get_parent(hw->clk));
+
+   val = readl(dmc->cru + CRU_CLKSEL6_CON);
+   val = (val >> CLK_DDRC_DIV_CON_SHIFT) & CLK_DDRC_DIV_CON_MASK;
+
+   return parent_rate / (val + 1);
+}
+
+/*
+ * TODO: set ddr frequcney in dcf which run in ATF
+ */
+static int rk3399_dmcclk_set_rate(struct clk_hw *hw, unsigned long rate,
+ unsigned long parent_rate)
+{
+   return 0;
+}
+
+static u8 rk3399_dmcclk_get_parent(struct clk_hw *hw)
+{
+   struct rk3399_dmcclk *dmc = to_rk3399_dmcclk();
+   u32 val;
+
+   val = readl(dmc->cru + CRU_CLKSEL6_CON);
+
+   return (val >> CLK_DDRC_PLL_SEL_SHIFT) &
+   CLK_DDRC_PLL_SEL_MASK;
+}
+
+static const struct clk_ops rk3399_dmcclk_ops = {
+   .recalc_rate = rk3399_dmcclk_recalc_rate,
+   .set_rate = rk3399_dmcclk_set_rate,
+   .get_parent = rk3399_dmcclk_get_parent,
+};
+
+static const char *parent_clk_names[] = {
+   "pll_dpll",
+   "pll_gpll",
+   "pll_alpll",
+   "pll_abpll",
+};
+
+static int 

Re: [PATCH 1/2] clk: rockchip: dmc: support rk3399 dmc clock driver

2015-11-19 Thread hl

Hi Heiko,

On 20/11/15 05:47, Heiko Stuebner wrote:

Hi Lin,

Am Donnerstag, 19. November 2015, 18:21:10 schrieb Lin Huang:

support rk3399 dmc clock driver. Note, ddr set rate function will
use dcf controller which run in ATF, it need to fishish it when rk3399
arm trust firmware ready.

this unfinalized state is slightly unfortunate and I think this code will
need to wait until CRU and DDRC specs are available.

Because this is clearly part of the CRU (labeled CRU_CLKSEL6_CON etc)
so shouldn't be a separate driver at all and also what your driver currently
only does can still simply be described in the regular scheme as part of
a full clock driver like

PNAME(mux_ddrc_p) = { "pll_dpll", "pll_gpll", "pll_alpll", "pll_abpll" };
COMPOSITE_NOGATE(0, "ddrc", mux_ddrc_p, 0,
RK3399_CLKSEL_CON(6), 4, 2, MFLAGS, 0, 
3,
DFLAGS | CLK_DIVIDER_POWER_OF_TWO),

So the code needs to actually demonstrate why a separate clock type is
really necessary.

I do understand that we will probably need a special way to talk to this
dcf controller but seeing how this interaction will work is really a
prequisite to finding a correct solution.
if we can use common clock driver, i can put the dfi controller as 
a  independent driver
into devfreq,  this is the best way. But how do we separate the ddr 
clk_set_rate() ,
so we can manipulate dcf controller(actually, we use SMC handle dcf 
controller in arm trust firmware ),

i check clock driver code, it seem there is not way to do that for now.


Heiko


---
  drivers/clk/rockchip/Makefile |   1 +
  drivers/clk/rockchip/clk-rk3399-dmc.c | 196 ++
  include/soc/rockchip/rk3399-dmc-clk.h |  36 +++
  3 files changed, 233 insertions(+)
  create mode 100644 drivers/clk/rockchip/clk-rk3399-dmc.c
  create mode 100644 include/soc/rockchip/rk3399-dmc-clk.h

diff --git a/drivers/clk/rockchip/Makefile b/drivers/clk/rockchip/Makefile
index b27edd6..98bd955 100644
--- a/drivers/clk/rockchip/Makefile
+++ b/drivers/clk/rockchip/Makefile
@@ -13,3 +13,4 @@ obj-$(CONFIG_RESET_CONTROLLER)+= softrst.o
  obj-y += clk-rk3188.o
  obj-y += clk-rk3288.o
  obj-y += clk-rk3368.o
+obj-y  += clk-rk3399-dmc.o
diff --git a/drivers/clk/rockchip/clk-rk3399-dmc.c 
b/drivers/clk/rockchip/clk-rk3399-dmc.c
new file mode 100644
index 000..03cc044
--- /dev/null
+++ b/drivers/clk/rockchip/clk-rk3399-dmc.c
@@ -0,0 +1,196 @@
+/*
+ * Copyright (c) 2014, Fuzhou Rockchip Electronics Co., Ltd
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#define to_rk3399_dmcclk(obj)  container_of(obj, struct rk3399_dmcclk, hw)
+
+/* CRU_CLKSEL6_CON*/
+#define CRU_CLKSEL6_CON0x118
+#define CLK_DDRC_PLL_SEL_SHIFT 0x4
+#define CLK_DDRC_PLL_SEL_MASK  0x3
+#define CLK_DDRC_DIV_CON_SHIFT 0
+#define CLK_DDRC_DIV_CON_MASK  0x07
+
+static unsigned long rk3399_dmcclk_recalc_rate(struct clk_hw *hw,
+  unsigned long parent_rate)
+{
+   struct rk3399_dmcclk *dmc = to_rk3399_dmcclk();
+   u32 val;
+
+   /*
+* Get parent rate since it changed in this clks set_rate op. The parent
+* rate passed into this function is cached before set_rate is called in
+* the common clk code, so we have to get it here.
+*/
+   parent_rate = clk_get_rate(clk_get_parent(hw->clk));
+
+   val = readl(dmc->cru + CRU_CLKSEL6_CON);
+   val = (val >> CLK_DDRC_DIV_CON_SHIFT) & CLK_DDRC_DIV_CON_MASK;
+
+   return parent_rate / (val + 1);
+}
+
+/*
+ * TODO: set ddr frequcney in dcf which run in ATF
+ */
+static int rk3399_dmcclk_set_rate(struct clk_hw *hw, unsigned long rate,
+ unsigned long parent_rate)
+{
+   return 0;
+}
+
+static u8 rk3399_dmcclk_get_parent(struct clk_hw *hw)
+{
+   struct rk3399_dmcclk *dmc = to_rk3399_dmcclk();
+   u32 val;
+
+   val = readl(dmc->cru + CRU_CLKSEL6_CON);
+
+   return (val >> CLK_DDRC_PLL_SEL_SHIFT) &
+   CLK_DDRC_PLL_SEL_MASK;
+}
+
+static const struct clk_ops rk3399_dmcclk_ops = {
+   .recalc_rate = rk3399_dmcclk_recalc_rate,
+   .set_rate = rk3399_dmcclk_set_rate,
+   .get_parent = rk3399_dmcclk_get_parent,
+};
+
+static const char *parent_clk_names[] = {
+   "pll_dpll",
+   "pll_gpll",
+   "pll_alpll",
+   "pll_abpll",
+};
+
+static int 

  1   2   >