[PATCH 2/3] drm/exynos: dp: Remove support for unused dptx-phy

2014-09-15 Thread Vivek Gautam
Now that we have moved to generic phy based bindings,
we don't need to have any code related to older dptx-phy.
Nobody is using this dptx-phy anymore, so removing the
same.

Signed-off-by: Vivek Gautam 
Cc: Jingoo Han 
---
 drivers/gpu/drm/exynos/exynos_dp_core.c |   58 +++
 drivers/gpu/drm/exynos/exynos_dp_core.h |2 --
 2 files changed, 13 insertions(+), 47 deletions(-)

diff --git a/drivers/gpu/drm/exynos/exynos_dp_core.c 
b/drivers/gpu/drm/exynos/exynos_dp_core.c
index 4f3c7eb..5ffc1b2 100644
--- a/drivers/gpu/drm/exynos/exynos_dp_core.c
+++ b/drivers/gpu/drm/exynos/exynos_dp_core.c
@@ -1050,28 +1050,14 @@ static int exynos_dp_create_connector(struct 
exynos_drm_display *display,

 static void exynos_dp_phy_init(struct exynos_dp_device *dp)
 {
-   if (dp->phy) {
+   if (dp->phy)
phy_power_on(dp->phy);
-   } else if (dp->phy_addr) {
-   u32 reg;
-
-   reg = __raw_readl(dp->phy_addr);
-   reg |= dp->enable_mask;
-   __raw_writel(reg, dp->phy_addr);
-   }
 }

 static void exynos_dp_phy_exit(struct exynos_dp_device *dp)
 {
-   if (dp->phy) {
+   if (dp->phy)
phy_power_off(dp->phy);
-   } else if (dp->phy_addr) {
-   u32 reg;
-
-   reg = __raw_readl(dp->phy_addr);
-   reg &= ~(dp->enable_mask);
-   __raw_writel(reg, dp->phy_addr);
-   }
 }

 static void exynos_dp_poweron(struct exynos_drm_display *display)
@@ -1210,39 +1196,21 @@ static struct video_info 
*exynos_dp_dt_parse_pdata(struct device *dev)

 static int exynos_dp_dt_parse_phydata(struct exynos_dp_device *dp)
 {
-   struct device_node *dp_phy_node = of_node_get(dp->dev->of_node);
-   u32 phy_base;
int ret = 0;

-   dp_phy_node = of_find_node_by_name(dp_phy_node, "dptx-phy");
-   if (!dp_phy_node) {
-   dp->phy = devm_phy_get(dp->dev, "dp");
-   return PTR_ERR_OR_ZERO(dp->phy);
-   }
-
-   if (of_property_read_u32(dp_phy_node, "reg", _base)) {
-   dev_err(dp->dev, "failed to get reg for dptx-phy\n");
-   ret = -EINVAL;
-   goto err;
-   }
-
-   if (of_property_read_u32(dp_phy_node, "samsung,enable-mask",
-   >enable_mask)) {
-   dev_err(dp->dev, "failed to get enable-mask for dptx-phy\n");
-   ret = -EINVAL;
-   goto err;
-   }
-
-   dp->phy_addr = ioremap(phy_base, SZ_4);
-   if (!dp->phy_addr) {
-   dev_err(dp->dev, "failed to ioremap dp-phy\n");
-   ret = -ENOMEM;
-   goto err;
+   dp->phy = devm_phy_get(dp->dev, "dp");
+   if (IS_ERR(dp->phy)) {
+   ret = PTR_ERR(dp->phy);
+   if (ret == -ENOSYS || ret == -ENODEV) {
+   dp->phy = NULL;
+   } else if (ret == -EPROBE_DEFER) {
+   return ret;
+   } else {
+   dev_err(dp->dev, "no DP phy configured\n");
+   return ret;
+   }
}

-err:
-   of_node_put(dp_phy_node);
-
return ret;
 }

diff --git a/drivers/gpu/drm/exynos/exynos_dp_core.h 
b/drivers/gpu/drm/exynos/exynos_dp_core.h
index a1aee69..6426201 100644
--- a/drivers/gpu/drm/exynos/exynos_dp_core.h
+++ b/drivers/gpu/drm/exynos/exynos_dp_core.h
@@ -153,8 +153,6 @@ struct exynos_dp_device {
struct clk  *clock;
unsigned intirq;
void __iomem*reg_base;
-   void __iomem*phy_addr;
-   unsigned intenable_mask;

struct video_info   *video_info;
struct link_train   link_train;
-- 
1.7.10.4



[PATCH 0/3] drm-exynos-dp/phy-exynos-dp: Refactor to use pmu-system-controller and dp driver cleanup

2014-09-15 Thread Vivek Gautam
These patches are based on 'for-next' branch of kgene's linux-samsung tree.

Refactoring the exynos-dp-video phy to use pmu-system-controller handle
and access the register using mfd-syscon and regmap.
Simultaneously, removing the support for older dptx-phy, since it's obsolete
now and noone uses it.

Vivek Gautam (3):
  phy: exynos-dp-video: Use syscon support to control pmu register
  drm/exynos: dp: Remove support for unused dptx-phy
  arm: dts: Exynos5: Use pmu_system_controller phandle for dp phy

 .../devicetree/bindings/phy/samsung-phy.txt|7 +-
 arch/arm/boot/dts/exynos5250.dtsi  |2 +-
 arch/arm/boot/dts/exynos5420.dtsi  |4 +-
 drivers/gpu/drm/exynos/exynos_dp_core.c|   58 ---
 drivers/gpu/drm/exynos/exynos_dp_core.h|2 -
 drivers/phy/phy-exynos-dp-video.c  |   76 ++--
 6 files changed, 75 insertions(+), 74 deletions(-)

-- 
1.7.10.4



[PATCH 3/3] arm: dts: Exynos5: Use pmu_system_controller phandle for dp phy

2014-09-15 Thread Vivek Gautam
DP PHY now require pmu-system-controller to handle PMU register
to control PHY's power isolation. Adding the same to dp-phy
node.

Signed-off-by: Vivek Gautam 
Cc: Jingoo Han 
---
 arch/arm/boot/dts/exynos5250.dtsi |2 +-
 arch/arm/boot/dts/exynos5420.dtsi |4 ++--
 2 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/arch/arm/boot/dts/exynos5250.dtsi 
b/arch/arm/boot/dts/exynos5250.dtsi
index f21b9aa..9b85a2b 100644
--- a/arch/arm/boot/dts/exynos5250.dtsi
+++ b/arch/arm/boot/dts/exynos5250.dtsi
@@ -732,7 +732,7 @@

dp_phy: video-phy at 10040720 {
compatible = "samsung,exynos5250-dp-video-phy";
-   reg = <0x10040720 4>;
+   samsung,pmu-syscon = <_system_controller>;
#phy-cells = <0>;
};

diff --git a/arch/arm/boot/dts/exynos5420.dtsi 
b/arch/arm/boot/dts/exynos5420.dtsi
index bfe056d..a677812 100644
--- a/arch/arm/boot/dts/exynos5420.dtsi
+++ b/arch/arm/boot/dts/exynos5420.dtsi
@@ -503,8 +503,8 @@
};

dp_phy: video-phy at 10040728 {
-   compatible = "samsung,exynos5250-dp-video-phy";
-   reg = <0x10040728 4>;
+   compatible = "samsung,exynos5420-dp-video-phy";
+   samsung,pmu-syscon = <_system_controller>;
#phy-cells = <0>;
};

-- 
1.7.10.4



[PATCH v2 1/3] phy: exynos-dp-video: Use syscon support to control pmu register

2014-09-16 Thread Vivek Gautam
Currently the DP_PHY_ENABLE register is mapped in the driver,
and accessed to control power to the PHY.
With mfd-syscon and regmap interface available at our disposal,
it's wise to use that instead of using a 'reg' property for the
controller and allocating a memory resource for that.

To facilitate this, we have added another compatible string
for Exynso5420 SoC to acquire driver data which contains
different DP-PHY-CONTROL register offset.

Signed-off-by: Vivek Gautam 
Cc: Jingoo Han 
Cc: Kishon Vijay Abraham I 
---

Changes since v1:
 - state->regs should have been "struct regmap *" instead of
   "void __iomem *". So corrected the same.

 .../devicetree/bindings/phy/samsung-phy.txt|7 +-
 drivers/phy/phy-exynos-dp-video.c  |   78 ++--
 2 files changed, 60 insertions(+), 25 deletions(-)

diff --git a/Documentation/devicetree/bindings/phy/samsung-phy.txt 
b/Documentation/devicetree/bindings/phy/samsung-phy.txt
index 7a6feea..15e0f2c 100644
--- a/Documentation/devicetree/bindings/phy/samsung-phy.txt
+++ b/Documentation/devicetree/bindings/phy/samsung-phy.txt
@@ -17,8 +17,11 @@ Samsung EXYNOS SoC series Display Port PHY
 -

 Required properties:
-- compatible : should be "samsung,exynos5250-dp-video-phy";
-- reg : offset and length of the Display Port PHY register set;
+- compatible : should be one of the following supported values:
+- "samsung,exynos5250-dp-video-phy"
+- "samsung,exynos5420-dp-video-phy"
+- samsung,pmu-syscon: phandle for PMU system controller interface, used to
+ control pmu registers for power isolation.
 - #phy-cells : from the generic PHY bindings, must be 0;

 Samsung S5P/EXYNOS SoC series USB PHY
diff --git a/drivers/phy/phy-exynos-dp-video.c 
b/drivers/phy/phy-exynos-dp-video.c
index 8b3026e..881ddb5 100644
--- a/drivers/phy/phy-exynos-dp-video.c
+++ b/drivers/phy/phy-exynos-dp-video.c
@@ -13,44 +13,58 @@
 #include 
 #include 
 #include 
+#include 
+#include 
 #include 
 #include 
 #include 
 #include 
+#include 

 /* DPTX_PHY_CONTROL register */
 #define EXYNOS_DPTX_PHY_ENABLE (1 << 0)

+struct exynos_dp_video_phy_drvdata {
+   u32 phy_ctrl_offset;
+};
+
 struct exynos_dp_video_phy {
-   void __iomem *regs;
+   struct regmap *regs;
+   const struct exynos_dp_video_phy_drvdata *drvdata;
 };

-static int __set_phy_state(struct exynos_dp_video_phy *state, unsigned int on)
+static void exynos_dp_video_phy_pwr_isol(struct exynos_dp_video_phy *state,
+   unsigned int on)
 {
-   u32 reg;
+   unsigned int val;

-   reg = readl(state->regs);
-   if (on)
-   reg |= EXYNOS_DPTX_PHY_ENABLE;
-   else
-   reg &= ~EXYNOS_DPTX_PHY_ENABLE;
-   writel(reg, state->regs);
+   if (IS_ERR(state->regs))
+   return;

-   return 0;
+   val = on ? 0 : EXYNOS_DPTX_PHY_ENABLE;
+
+   regmap_update_bits(state->regs, state->drvdata->phy_ctrl_offset,
+  EXYNOS_DPTX_PHY_ENABLE, val);
 }

 static int exynos_dp_video_phy_power_on(struct phy *phy)
 {
struct exynos_dp_video_phy *state = phy_get_drvdata(phy);

-   return __set_phy_state(state, 1);
+   /* Disable power isolation on DP-PHY */
+   exynos_dp_video_phy_pwr_isol(state, 0);
+
+   return 0;
 }

 static int exynos_dp_video_phy_power_off(struct phy *phy)
 {
struct exynos_dp_video_phy *state = phy_get_drvdata(phy);

-   return __set_phy_state(state, 0);
+   /* Enable power isolation on DP-PHY */
+   exynos_dp_video_phy_pwr_isol(state, 1);
+
+   return 0;
 }

 static struct phy_ops exynos_dp_video_phy_ops = {
@@ -59,11 +73,31 @@ static struct phy_ops exynos_dp_video_phy_ops = {
.owner  = THIS_MODULE,
 };

+static const struct exynos_dp_video_phy_drvdata exynos5250_dp_video_phy = {
+   .phy_ctrl_offset= EXYNOS5_DPTX_PHY_CONTROL,
+};
+
+static const struct exynos_dp_video_phy_drvdata exynos5420_dp_video_phy = {
+   .phy_ctrl_offset= EXYNOS5420_DPTX_PHY_CONTROL,
+};
+
+static const struct of_device_id exynos_dp_video_phy_of_match[] = {
+   {
+   .compatible = "samsung,exynos5250-dp-video-phy",
+   .data = _dp_video_phy,
+   }, {
+   .compatible = "samsung,exynos5420-dp-video-phy",
+   .data = _dp_video_phy,
+   },
+   { },
+};
+MODULE_DEVICE_TABLE(of, exynos_dp_video_phy_of_match);
+
 static int exynos_dp_video_phy_probe(struct platform_device *pdev)
 {
struct exynos_dp_video_phy *state;
struct device *dev = >dev;
-   struct resource *res;
+   const struct of_device_id *match;
struct phy_provider *phy_provider;
struct phy *phy;

@@ -71,11 +105,15 @@ static int exynos_dp_video_p

[PATCH 1/3] phy: exynos-dp-video: Use syscon support to control pmu register

2014-09-15 Thread Vivek Gautam
Currently the DP_PHY_ENABLE register is mapped in the driver,
and accessed to control power to the PHY.
With mfd-syscon and regmap interface available at our disposal,
it's wise to use that instead of using a 'reg' property for the
controller and allocating a memory resource for that.

To facilitate this, we have added another compatible string
for Exynso5420 SoC to acquire driver data which contains
different DP-PHY-CONTROL register offset.

Signed-off-by: Vivek Gautam 
Cc: Jingoo Han 
Cc: Kishon Vijay Abraham I 
---
 .../devicetree/bindings/phy/samsung-phy.txt|7 +-
 drivers/phy/phy-exynos-dp-video.c  |   76 ++--
 2 files changed, 59 insertions(+), 24 deletions(-)

diff --git a/Documentation/devicetree/bindings/phy/samsung-phy.txt 
b/Documentation/devicetree/bindings/phy/samsung-phy.txt
index 7a6feea..15e0f2c 100644
--- a/Documentation/devicetree/bindings/phy/samsung-phy.txt
+++ b/Documentation/devicetree/bindings/phy/samsung-phy.txt
@@ -17,8 +17,11 @@ Samsung EXYNOS SoC series Display Port PHY
 -

 Required properties:
-- compatible : should be "samsung,exynos5250-dp-video-phy";
-- reg : offset and length of the Display Port PHY register set;
+- compatible : should be one of the following supported values:
+- "samsung,exynos5250-dp-video-phy"
+- "samsung,exynos5420-dp-video-phy"
+- samsung,pmu-syscon: phandle for PMU system controller interface, used to
+ control pmu registers for power isolation.
 - #phy-cells : from the generic PHY bindings, must be 0;

 Samsung S5P/EXYNOS SoC series USB PHY
diff --git a/drivers/phy/phy-exynos-dp-video.c 
b/drivers/phy/phy-exynos-dp-video.c
index 8b3026e..f093719 100644
--- a/drivers/phy/phy-exynos-dp-video.c
+++ b/drivers/phy/phy-exynos-dp-video.c
@@ -13,44 +13,58 @@
 #include 
 #include 
 #include 
+#include 
+#include 
 #include 
 #include 
 #include 
 #include 
+#include 

 /* DPTX_PHY_CONTROL register */
 #define EXYNOS_DPTX_PHY_ENABLE (1 << 0)

+struct exynos_dp_video_phy_drvdata {
+   u32 phy_ctrl_offset;
+};
+
 struct exynos_dp_video_phy {
void __iomem *regs;
+   const struct exynos_dp_video_phy_drvdata *drvdata;
 };

-static int __set_phy_state(struct exynos_dp_video_phy *state, unsigned int on)
+static void exynos_dp_video_phy_pwr_isol(struct exynos_dp_video_phy *state,
+   unsigned int on)
 {
-   u32 reg;
+   unsigned int val;

-   reg = readl(state->regs);
-   if (on)
-   reg |= EXYNOS_DPTX_PHY_ENABLE;
-   else
-   reg &= ~EXYNOS_DPTX_PHY_ENABLE;
-   writel(reg, state->regs);
+   if (IS_ERR(state->regs))
+   return;

-   return 0;
+   val = on ? 0 : EXYNOS_DPTX_PHY_ENABLE;
+
+   regmap_update_bits(state->regs, state->drvdata->phy_ctrl_offset,
+  EXYNOS_DPTX_PHY_ENABLE, val);
 }

 static int exynos_dp_video_phy_power_on(struct phy *phy)
 {
struct exynos_dp_video_phy *state = phy_get_drvdata(phy);

-   return __set_phy_state(state, 1);
+   /* Disable power isolation on DP-PHY */
+   exynos_dp_video_phy_pwr_isol(state, 0);
+
+   return 0;
 }

 static int exynos_dp_video_phy_power_off(struct phy *phy)
 {
struct exynos_dp_video_phy *state = phy_get_drvdata(phy);

-   return __set_phy_state(state, 0);
+   /* Enable power isolation on DP-PHY */
+   exynos_dp_video_phy_pwr_isol(state, 1);
+
+   return 0;
 }

 static struct phy_ops exynos_dp_video_phy_ops = {
@@ -59,11 +73,31 @@ static struct phy_ops exynos_dp_video_phy_ops = {
.owner  = THIS_MODULE,
 };

+static const struct exynos_dp_video_phy_drvdata exynos5250_dp_video_phy = {
+   .phy_ctrl_offset= EXYNOS5_DPTX_PHY_CONTROL,
+};
+
+static const struct exynos_dp_video_phy_drvdata exynos5420_dp_video_phy = {
+   .phy_ctrl_offset= EXYNOS5420_DPTX_PHY_CONTROL,
+};
+
+static const struct of_device_id exynos_dp_video_phy_of_match[] = {
+   {
+   .compatible = "samsung,exynos5250-dp-video-phy",
+   .data = _dp_video_phy,
+   }, {
+   .compatible = "samsung,exynos5420-dp-video-phy",
+   .data = _dp_video_phy,
+   },
+   { },
+};
+MODULE_DEVICE_TABLE(of, exynos_dp_video_phy_of_match);
+
 static int exynos_dp_video_phy_probe(struct platform_device *pdev)
 {
struct exynos_dp_video_phy *state;
struct device *dev = >dev;
-   struct resource *res;
+   const struct of_device_id *match;
struct phy_provider *phy_provider;
struct phy *phy;

@@ -71,11 +105,15 @@ static int exynos_dp_video_phy_probe(struct 
platform_device *pdev)
if (!state)
return -ENOMEM;

-   res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-
-   state->re

[PATCH v3 1/3] phy: exynos-dp-video: Use syscon support to control pmu register

2014-09-16 Thread Vivek Gautam
Currently the DP_PHY_ENABLE register is mapped in the driver,
and accessed to control power to the PHY.
With mfd-syscon and regmap interface available at our disposal,
it's wise to use that instead of using a 'reg' property for the
controller and allocating a memory resource for that.

To facilitate this, we have added another compatible string
for Exynso5420 SoC to acquire driver data which contains
different DP-PHY-CONTROL register offset.

Signed-off-by: Vivek Gautam 
Cc: Jingoo Han 
Cc: Kishon Vijay Abraham I 
---

Changes since v2:
 - Using 'EXYNOS5_PHY_ENABLE' macro instead of 'EXYNOS_DPTX_PHY_ENABLE'
   since that's available with us in "linux/mfd/syscon/exynos5-pmu.h" file.

Changes since v1:
 - state->regs should have been "struct regmap *" instead of
   "void __iomem *". So corrected the same.

 .../devicetree/bindings/phy/samsung-phy.txt|7 +-
 drivers/phy/phy-exynos-dp-video.c  |   79 +---
 2 files changed, 59 insertions(+), 27 deletions(-)

diff --git a/Documentation/devicetree/bindings/phy/samsung-phy.txt 
b/Documentation/devicetree/bindings/phy/samsung-phy.txt
index 7a6feea..15e0f2c 100644
--- a/Documentation/devicetree/bindings/phy/samsung-phy.txt
+++ b/Documentation/devicetree/bindings/phy/samsung-phy.txt
@@ -17,8 +17,11 @@ Samsung EXYNOS SoC series Display Port PHY
 -

 Required properties:
-- compatible : should be "samsung,exynos5250-dp-video-phy";
-- reg : offset and length of the Display Port PHY register set;
+- compatible : should be one of the following supported values:
+- "samsung,exynos5250-dp-video-phy"
+- "samsung,exynos5420-dp-video-phy"
+- samsung,pmu-syscon: phandle for PMU system controller interface, used to
+ control pmu registers for power isolation.
 - #phy-cells : from the generic PHY bindings, must be 0;

 Samsung S5P/EXYNOS SoC series USB PHY
diff --git a/drivers/phy/phy-exynos-dp-video.c 
b/drivers/phy/phy-exynos-dp-video.c
index 8b3026e..53f44a0 100644
--- a/drivers/phy/phy-exynos-dp-video.c
+++ b/drivers/phy/phy-exynos-dp-video.c
@@ -13,44 +13,55 @@
 #include 
 #include 
 #include 
+#include 
+#include 
 #include 
 #include 
 #include 
 #include 
+#include 

-/* DPTX_PHY_CONTROL register */
-#define EXYNOS_DPTX_PHY_ENABLE (1 << 0)
+struct exynos_dp_video_phy_drvdata {
+   u32 phy_ctrl_offset;
+};

 struct exynos_dp_video_phy {
-   void __iomem *regs;
+   struct regmap *regs;
+   const struct exynos_dp_video_phy_drvdata *drvdata;
 };

-static int __set_phy_state(struct exynos_dp_video_phy *state, unsigned int on)
+static void exynos_dp_video_phy_pwr_isol(struct exynos_dp_video_phy *state,
+   unsigned int on)
 {
-   u32 reg;
+   unsigned int val;
+
+   if (IS_ERR(state->regs))
+   return;

-   reg = readl(state->regs);
-   if (on)
-   reg |= EXYNOS_DPTX_PHY_ENABLE;
-   else
-   reg &= ~EXYNOS_DPTX_PHY_ENABLE;
-   writel(reg, state->regs);
+   val = on ? 0 : EXYNOS5_PHY_ENABLE;

-   return 0;
+   regmap_update_bits(state->regs, state->drvdata->phy_ctrl_offset,
+  EXYNOS5_PHY_ENABLE, val);
 }

 static int exynos_dp_video_phy_power_on(struct phy *phy)
 {
struct exynos_dp_video_phy *state = phy_get_drvdata(phy);

-   return __set_phy_state(state, 1);
+   /* Disable power isolation on DP-PHY */
+   exynos_dp_video_phy_pwr_isol(state, 0);
+
+   return 0;
 }

 static int exynos_dp_video_phy_power_off(struct phy *phy)
 {
struct exynos_dp_video_phy *state = phy_get_drvdata(phy);

-   return __set_phy_state(state, 0);
+   /* Enable power isolation on DP-PHY */
+   exynos_dp_video_phy_pwr_isol(state, 1);
+
+   return 0;
 }

 static struct phy_ops exynos_dp_video_phy_ops = {
@@ -59,11 +70,31 @@ static struct phy_ops exynos_dp_video_phy_ops = {
.owner  = THIS_MODULE,
 };

+static const struct exynos_dp_video_phy_drvdata exynos5250_dp_video_phy = {
+   .phy_ctrl_offset= EXYNOS5_DPTX_PHY_CONTROL,
+};
+
+static const struct exynos_dp_video_phy_drvdata exynos5420_dp_video_phy = {
+   .phy_ctrl_offset= EXYNOS5420_DPTX_PHY_CONTROL,
+};
+
+static const struct of_device_id exynos_dp_video_phy_of_match[] = {
+   {
+   .compatible = "samsung,exynos5250-dp-video-phy",
+   .data = _dp_video_phy,
+   }, {
+   .compatible = "samsung,exynos5420-dp-video-phy",
+   .data = _dp_video_phy,
+   },
+   { },
+};
+MODULE_DEVICE_TABLE(of, exynos_dp_video_phy_of_match);
+
 static int exynos_dp_video_phy_probe(struct platform_device *pdev)
 {
struct exynos_dp_video_phy *state;
struct device *dev = >dev;
-   struct resource 

[PATCH v3 1/3] phy: exynos-dp-video: Use syscon support to control pmu register

2014-09-18 Thread Vivek Gautam
Hi Kishon,


On Wed, Sep 17, 2014 at 10:24 PM, Kishon Vijay Abraham I  
wrote:
>
>
> On Tuesday 16 September 2014 10:32 AM, Vivek Gautam wrote:
>> Currently the DP_PHY_ENABLE register is mapped in the driver,
>> and accessed to control power to the PHY.
>> With mfd-syscon and regmap interface available at our disposal,
>> it's wise to use that instead of using a 'reg' property for the
>> controller and allocating a memory resource for that.
>>
>> To facilitate this, we have added another compatible string
>> for Exynso5420 SoC to acquire driver data which contains
>> different DP-PHY-CONTROL register offset.
>>
>> Signed-off-by: Vivek Gautam 
>> Cc: Jingoo Han 
>> Cc: Kishon Vijay Abraham I 
>
> Taking this in linux-phy tree. If someone has already taken this patch, please
> let me know.

Thanks for taking this. But just one check, i think i need to separate
out the Documentation
to a separate patch even before this driver patch. Isn't it ?

>
> Thanks
> Kishon
>
>> ---
>>
>> Changes since v2:
>>  - Using 'EXYNOS5_PHY_ENABLE' macro instead of 'EXYNOS_DPTX_PHY_ENABLE'
>>since that's available with us in "linux/mfd/syscon/exynos5-pmu.h" file.
>>
>> Changes since v1:
>>  - state->regs should have been "struct regmap *" instead of
>>"void __iomem *". So corrected the same.
>>
>>  .../devicetree/bindings/phy/samsung-phy.txt|7 +-
>>  drivers/phy/phy-exynos-dp-video.c  |   79 
>> +---
>>  2 files changed, 59 insertions(+), 27 deletions(-)
>>
>> diff --git a/Documentation/devicetree/bindings/phy/samsung-phy.txt 
>> b/Documentation/devicetree/bindings/phy/samsung-phy.txt
>> index 7a6feea..15e0f2c 100644
>> --- a/Documentation/devicetree/bindings/phy/samsung-phy.txt
>> +++ b/Documentation/devicetree/bindings/phy/samsung-phy.txt
>> @@ -17,8 +17,11 @@ Samsung EXYNOS SoC series Display Port PHY
>>  -
>>
>>  Required properties:
>> -- compatible : should be "samsung,exynos5250-dp-video-phy";
>> -- reg : offset and length of the Display Port PHY register set;
>> +- compatible : should be one of the following supported values:
>> +  - "samsung,exynos5250-dp-video-phy"
>> +  - "samsung,exynos5420-dp-video-phy"
>> +- samsung,pmu-syscon: phandle for PMU system controller interface, used to
>> +   control pmu registers for power isolation.
>>  - #phy-cells : from the generic PHY bindings, must be 0;
>>
>>  Samsung S5P/EXYNOS SoC series USB PHY
>> diff --git a/drivers/phy/phy-exynos-dp-video.c 
>> b/drivers/phy/phy-exynos-dp-video.c
>> index 8b3026e..53f44a0 100644
>> --- a/drivers/phy/phy-exynos-dp-video.c
>> +++ b/drivers/phy/phy-exynos-dp-video.c
>> @@ -13,44 +13,55 @@
>>  #include 
>>  #include 
>>  #include 
>> +#include 
>> +#include 
>>  #include 
>>  #include 
>>  #include 
>>  #include 
>> +#include 
>>
>> -/* DPTX_PHY_CONTROL register */
>> -#define EXYNOS_DPTX_PHY_ENABLE   (1 << 0)
>> +struct exynos_dp_video_phy_drvdata {
>> + u32 phy_ctrl_offset;
>> +};
>>
>>  struct exynos_dp_video_phy {
>> - void __iomem *regs;
>> + struct regmap *regs;
>> + const struct exynos_dp_video_phy_drvdata *drvdata;
>>  };
>>
>> -static int __set_phy_state(struct exynos_dp_video_phy *state, unsigned int 
>> on)
>> +static void exynos_dp_video_phy_pwr_isol(struct exynos_dp_video_phy *state,
>> + unsigned int on)
>>  {
>> - u32 reg;
>> + unsigned int val;
>> +
>> + if (IS_ERR(state->regs))
>> + return;
>>
>> - reg = readl(state->regs);
>> - if (on)
>> - reg |= EXYNOS_DPTX_PHY_ENABLE;
>> - else
>> - reg &= ~EXYNOS_DPTX_PHY_ENABLE;
>> - writel(reg, state->regs);
>> + val = on ? 0 : EXYNOS5_PHY_ENABLE;
>>
>> - return 0;
>> + regmap_update_bits(state->regs, state->drvdata->phy_ctrl_offset,
>> +EXYNOS5_PHY_ENABLE, val);
>>  }
>>
>>  static int exynos_dp_video_phy_power_on(struct phy *phy)
>>  {
>>   struct exynos_dp_video_phy *state = phy_get_drvdata(phy);
>>
>> - return __set_phy_state(state, 1);
>> + /* Disable power isolation on DP-PHY */
>> + exynos_dp_video_phy_pwr_is

[PATCH v3 03/15] ARM: dts: sysreg: add exynos5 compatible to DT bindings

2014-06-04 Thread Vivek Gautam
Hi,


On Mon, Jun 2, 2014 at 10:52 AM, YoungJun Cho  wrote:
> This patch adds relevant to exynos5 compatible for exynos5 SoCs.

This change is not required. Please check the latest 'for-next' branch
of linux-samsung tree.
Recently a patch "dfbbdbf ARM: dts: Add sysreg sytem controller node
to exynos5250 and exynos5420"
has already updated this binding information.

>
> Signed-off-by: YoungJun Cho 
> Acked-by: Inki Dae 
> Acked-by: Kyungmin Park 
> ---
>  .../devicetree/bindings/arm/samsung/sysreg.txt |1 +
>  1 file changed, 1 insertion(+)
>
> diff --git a/Documentation/devicetree/bindings/arm/samsung/sysreg.txt 
> b/Documentation/devicetree/bindings/arm/samsung/sysreg.txt
> index 0ab3251..fd71581 100644
> --- a/Documentation/devicetree/bindings/arm/samsung/sysreg.txt
> +++ b/Documentation/devicetree/bindings/arm/samsung/sysreg.txt
> @@ -3,6 +3,7 @@ SAMSUNG S5P/Exynos SoC series System Registers (SYSREG)
>  Properties:
>   - compatible : should contain "samsung,-sysreg", "syscon";
> For Exynos4 SoC series it should be "samsung,exynos4-sysreg", "syscon";
> +   For Exynos5 SoC series it should be "samsung,exynos5-sysreg", "syscon";
>   - reg : offset and length of the register set.
>
>  Example:
> --
> 1.7.9.5
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-samsung-soc" 
> in
> the body of a message to majordomo at vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html



-- 
Best Regards
Vivek Gautam
Samsung R Institute, Bangalore
India


[PATCH v3 13/15] ARM: dts: exynos5: add system register support

2014-06-04 Thread Vivek Gautam
On Mon, Jun 2, 2014 at 10:52 AM, YoungJun Cho  wrote:
> This patch adds sysreg device node, and sysreg property
> to fimd device node which is required to use I80 interface.

Same here. The system register nodes have been added to exynos5250 and
exynos5420 by the patch:
dfbbdbf ARM: dts: Add sysreg sytem controller node to exynos5250 and exynos5420

May be, you may want to move those two nodes to this common file (exynos5.dtsi).

>
> Signed-off-by: YoungJun Cho 
> Acked-by: Inki Dae 
> Acked-by: Kyungmin Park 
> ---
>  arch/arm/boot/dts/exynos5.dtsi |6 ++
>  1 file changed, 6 insertions(+)
>
> diff --git a/arch/arm/boot/dts/exynos5.dtsi b/arch/arm/boot/dts/exynos5.dtsi
> index 79d0608..95ee496 100644
> --- a/arch/arm/boot/dts/exynos5.dtsi
> +++ b/arch/arm/boot/dts/exynos5.dtsi
> @@ -81,12 +81,18 @@
> status = "disabled";
> };
>
> +   sys_reg: syscon at 1005 {
> +   compatible = "samsung,exynos5-sysreg", "syscon";
> +   reg = <0x1005 0x500>;
> +   };
> +
> fimd at 1440 {
> compatible = "samsung,exynos5250-fimd";
> interrupt-parent = <>;
> reg = <0x1440 0x4>;
> interrupt-names = "fifo", "vsync", "lcd_sys";
> interrupts = <18 4>, <18 5>, <18 6>;
> +   samsung,sysreg = <_reg>;
> status = "disabled";
> };
>
> --
> 1.7.9.5
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-samsung-soc" 
> in
> the body of a message to majordomo at vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html



-- 
Best Regards
Vivek Gautam
Samsung R Institute, Bangalore
India


[PATCH v3 13/15] ARM: dts: exynos5: add system register support

2014-06-05 Thread Vivek Gautam
Hi YoungJun,


On Thu, Jun 5, 2014 at 8:22 AM, YoungJun Cho  wrote:
> Hi Vivek,
>
>
> On 06/04/2014 08:50 PM, Vivek Gautam wrote:
>>
>> On Mon, Jun 2, 2014 at 10:52 AM, YoungJun Cho 
>> wrote:
>>>
>>> This patch adds sysreg device node, and sysreg property
>>> to fimd device node which is required to use I80 interface.
>>
>>
>> Same here. The system register nodes have been added to exynos5250 and
>> exynos5420 by the patch:
>> dfbbdbf ARM: dts: Add sysreg sytem controller node to exynos5250 and
>> exynos5420
>>
>> May be, you may want to move those two nodes to this common file
>> (exynos5.dtsi).
>>
>
> Thank you for reporting.
> I didn't check linux-samsung-soc.
>
> The exynos5410, 5420 and 5422 use system register with base address
> 0x1005.
> But exynos5260 and 5430 are different.
> And I can't check exynos5250.

Exynos5250 too starts with same register base address as Exynos5420,
but as you say Exynos5430 and Exynos5260 starts with different base address
then it make sense to keep them separate in their dtsi. (I couldn't
check Exynos5430)

>
> So with this condition, it is reasonable to remove these sysreg relevant
> patches.

Sure.

[snip]


-- 
Best Regards
Vivek Gautam
Samsung R Institute, Bangalore
India


[PATCH v2 1/2] drm/exynos: dp: Remove support for unused dptx-phy

2014-11-12 Thread Vivek Gautam
On Wed, Nov 12, 2014 at 9:38 AM, Jingoo Han  wrote:
> On Thursday, October 30, 2014 10:24 PM, Vivek Gautam wrote:
>>
>> Now that we have moved to generic phy based bindings,
>> we don't need to have any code related to older dptx-phy.
>> Nobody is using this dptx-phy anymore, so removing the
>> same.
>
> Right, older dptx-phy was replaced long time ago.
> However, it was not removed for DT compatibility.
> I think that now these old DT properties can be removed.
>
> I added some comments below.

Thanks Jingoo for reviewing.

>
>>
>> Signed-off-by: Vivek Gautam 
>> Cc: Inki Dae 
>> Cc: Jingoo Han 
>> ---
>>
>> Changes from V1:
>>  - Reworked error handling in exynos_dp_dt_parse_phydata() as commented
>>by Inki.
>>
>>  drivers/gpu/drm/exynos/exynos_dp_core.c |   67 
>> ---
>>  drivers/gpu/drm/exynos/exynos_dp_core.h |2 -
>>  2 files changed, 17 insertions(+), 52 deletions(-)
>>
>> diff --git a/drivers/gpu/drm/exynos/exynos_dp_core.c 
>> b/drivers/gpu/drm/exynos/exynos_dp_core.c
>> index cd50ece..206163b 100644
>> --- a/drivers/gpu/drm/exynos/exynos_dp_core.c
>> +++ b/drivers/gpu/drm/exynos/exynos_dp_core.c
>> @@ -1052,28 +1052,14 @@ static int exynos_dp_create_connector(struct 
>> exynos_drm_display *display,
>>
>>  static void exynos_dp_phy_init(struct exynos_dp_device *dp)
>>  {
>> - if (dp->phy) {
>> + if (dp->phy)
>>   phy_power_on(dp->phy);
>> - } else if (dp->phy_addr) {
>> - u32 reg;
>> -
>> - reg = __raw_readl(dp->phy_addr);
>> - reg |= dp->enable_mask;
>> - __raw_writel(reg, dp->phy_addr);
>> - }
>>  }
>>
>>  static void exynos_dp_phy_exit(struct exynos_dp_device *dp)
>>  {
>> - if (dp->phy) {
>> + if (dp->phy)
>>   phy_power_off(dp->phy);
>> - } else if (dp->phy_addr) {
>> - u32 reg;
>> -
>> - reg = __raw_readl(dp->phy_addr);
>> - reg &= ~(dp->enable_mask);
>> - __raw_writel(reg, dp->phy_addr);
>> - }
>>  }
>>
>>  static void exynos_dp_poweron(struct exynos_drm_display *display)
>> @@ -1212,40 +1198,13 @@ static struct video_info 
>> *exynos_dp_dt_parse_pdata(struct device *dev)
>>
>>  static int exynos_dp_dt_parse_phydata(struct exynos_dp_device *dp)
>>  {
>> - struct device_node *dp_phy_node = of_node_get(dp->dev->of_node);
>> - u32 phy_base;
>> - int ret = 0;
>> -
>> - dp_phy_node = of_find_node_by_name(dp_phy_node, "dptx-phy");
>> - if (!dp_phy_node) {
>> - dp->phy = devm_phy_get(dp->dev, "dp");
>> - return PTR_ERR_OR_ZERO(dp->phy);
>> - }
>> -
>> - if (of_property_read_u32(dp_phy_node, "reg", _base)) {
>> - dev_err(dp->dev, "failed to get reg for dptx-phy\n");
>> - ret = -EINVAL;
>> - goto err;
>> - }
>> -
>> - if (of_property_read_u32(dp_phy_node, "samsung,enable-mask",
>> - >enable_mask)) {
>> - dev_err(dp->dev, "failed to get enable-mask for dptx-phy\n");
>> - ret = -EINVAL;
>> - goto err;
>> - }
>> -
>> - dp->phy_addr = ioremap(phy_base, SZ_4);
>> - if (!dp->phy_addr) {
>> - dev_err(dp->dev, "failed to ioremap dp-phy\n");
>> - ret = -ENOMEM;
>> - goto err;
>> + dp->phy = devm_phy_get(dp->dev, "dp");
>> + if (IS_ERR(dp->phy)) {
>> + dev_err(dp->dev, "no DP phy configured\n");
>> + return PTR_ERR(dp->phy);
>>   }
>>
>> -err:
>> - of_node_put(dp_phy_node);
>> -
>> - return ret;
>> + return 0;
>>  }
>>
>>  static int exynos_dp_dt_parse_panel(struct exynos_dp_device *dp)
>> @@ -1278,8 +1237,16 @@ static int exynos_dp_bind(struct device *dev, struct 
>> device *master, void *data)
>>   return PTR_ERR(dp->video_info);
>>
>>   ret = exynos_dp_dt_parse_phydata(dp);
>
> In your patch, exynos_dp_dt_parse_phydata() calls only devm_phy_get().
> Then, how about calling devm_phy_get() directly and removing
> exynos_dp_dt_parse_phydata()? It looks simpler.

Right, makes sense. Will send quic

[PATCH v3 RESEND 1/2] drm/exynos: dp: Remove support for unused dptx-phy

2014-11-12 Thread Vivek Gautam
Now that we have moved to generic phy based bindings,
we don't need to have any code related to older dptx-phy.
Nobody is using this dptx-phy anymore, so removing the
same.

Signed-off-by: Vivek Gautam 
Acked-by: Jingoo Han 
Cc: Inki Dae 
---

Problem with my mail client caused change in author's mail id.
So resending it with authorship under my Samsung id.

 drivers/gpu/drm/exynos/exynos_dp_core.c |   74 +++
 drivers/gpu/drm/exynos/exynos_dp_core.h |2 -
 2 files changed, 17 insertions(+), 59 deletions(-)

diff --git a/drivers/gpu/drm/exynos/exynos_dp_core.c 
b/drivers/gpu/drm/exynos/exynos_dp_core.c
index cd50ece..dbe9add 100644
--- a/drivers/gpu/drm/exynos/exynos_dp_core.c
+++ b/drivers/gpu/drm/exynos/exynos_dp_core.c
@@ -1052,28 +1052,14 @@ static int exynos_dp_create_connector(struct 
exynos_drm_display *display,

 static void exynos_dp_phy_init(struct exynos_dp_device *dp)
 {
-   if (dp->phy) {
+   if (dp->phy)
phy_power_on(dp->phy);
-   } else if (dp->phy_addr) {
-   u32 reg;
-
-   reg = __raw_readl(dp->phy_addr);
-   reg |= dp->enable_mask;
-   __raw_writel(reg, dp->phy_addr);
-   }
 }

 static void exynos_dp_phy_exit(struct exynos_dp_device *dp)
 {
-   if (dp->phy) {
+   if (dp->phy)
phy_power_off(dp->phy);
-   } else if (dp->phy_addr) {
-   u32 reg;
-
-   reg = __raw_readl(dp->phy_addr);
-   reg &= ~(dp->enable_mask);
-   __raw_writel(reg, dp->phy_addr);
-   }
 }

 static void exynos_dp_poweron(struct exynos_drm_display *display)
@@ -1210,44 +1196,6 @@ static struct video_info 
*exynos_dp_dt_parse_pdata(struct device *dev)
return dp_video_config;
 }

-static int exynos_dp_dt_parse_phydata(struct exynos_dp_device *dp)
-{
-   struct device_node *dp_phy_node = of_node_get(dp->dev->of_node);
-   u32 phy_base;
-   int ret = 0;
-
-   dp_phy_node = of_find_node_by_name(dp_phy_node, "dptx-phy");
-   if (!dp_phy_node) {
-   dp->phy = devm_phy_get(dp->dev, "dp");
-   return PTR_ERR_OR_ZERO(dp->phy);
-   }
-
-   if (of_property_read_u32(dp_phy_node, "reg", _base)) {
-   dev_err(dp->dev, "failed to get reg for dptx-phy\n");
-   ret = -EINVAL;
-   goto err;
-   }
-
-   if (of_property_read_u32(dp_phy_node, "samsung,enable-mask",
-   >enable_mask)) {
-   dev_err(dp->dev, "failed to get enable-mask for dptx-phy\n");
-   ret = -EINVAL;
-   goto err;
-   }
-
-   dp->phy_addr = ioremap(phy_base, SZ_4);
-   if (!dp->phy_addr) {
-   dev_err(dp->dev, "failed to ioremap dp-phy\n");
-   ret = -ENOMEM;
-   goto err;
-   }
-
-err:
-   of_node_put(dp_phy_node);
-
-   return ret;
-}
-
 static int exynos_dp_dt_parse_panel(struct exynos_dp_device *dp)
 {
int ret;
@@ -1277,9 +1225,21 @@ static int exynos_dp_bind(struct device *dev, struct 
device *master, void *data)
if (IS_ERR(dp->video_info))
return PTR_ERR(dp->video_info);

-   ret = exynos_dp_dt_parse_phydata(dp);
-   if (ret)
-   return ret;
+   dp->phy = devm_phy_get(dp->dev, "dp");
+   if (IS_ERR(dp->phy)) {
+   dev_err(dp->dev, "no DP phy configured\n");
+   ret = PTR_ERR(dp->phy);
+   if (ret) {
+   /*
+* phy itself is not enabled, so we can move forward
+* assigning NULL to phy pointer.
+*/
+   if (ret == -ENOSYS || ret == -ENODEV)
+   dp->phy = NULL;
+   else
+   return ret;
+   }
+   }

if (!dp->panel) {
ret = exynos_dp_dt_parse_panel(dp);
diff --git a/drivers/gpu/drm/exynos/exynos_dp_core.h 
b/drivers/gpu/drm/exynos/exynos_dp_core.h
index a1aee69..6426201 100644
--- a/drivers/gpu/drm/exynos/exynos_dp_core.h
+++ b/drivers/gpu/drm/exynos/exynos_dp_core.h
@@ -153,8 +153,6 @@ struct exynos_dp_device {
struct clk  *clock;
unsigned intirq;
void __iomem*reg_base;
-   void __iomem*phy_addr;
-   unsigned intenable_mask;

struct video_info   *video_info;
struct link_train   link_train;
-- 
1.7.9.5



[PATCH v2 2/2] arm: dts: Exynos5: Use pmu_system_controller phandle for dp phy

2014-11-19 Thread Vivek Gautam
Hi Javier,


On Wed, Nov 19, 2014 at 5:06 PM, Javier Martinez Canillas
 wrote:
> [adding Kukjin to cc list]
>
> Hello Vivek,
>
> On Wed, Nov 12, 2014 at 5:21 AM, Jingoo Han  wrote:
>> On Thursday, October 30, 2014 10:24 PM, Vivek Gautam wrote:
>>>
>>> DP PHY now require pmu-system-controller to handle PMU register
>>> to control PHY's power isolation. Adding the same to dp-phy
>>> node.
>>>
>>> Signed-off-by: Vivek Gautam 
>>> Cc: Jingoo Han 
>>
>> Reviewed-by: Jingoo Han 
>>
>
> Tested-by: Javier Martinez Canillas 

Thanks for testing.

>
> Kukjin,

Sorry for not adding Kukjin to the list and thereby for the delay
about this patch.

>
> This patch is -rc material and is needed to have display working in
> 3.18 again since commit a5ec598 ("phy: exynos-dp-video: Use syscon
> support to control pmu register") landed in 3.18 and broke the Exynos
> Display Port PHY:
>
> exynos-dp-video-phy 10040728.video-phy: Failed to lookup PMU regmap

Yes, we should pick this up and merge it since the driver patch is merged now.



-- 
Best Regards
Vivek Gautam
Samsung R Institute, Bangalore
India


[RFC PATCH 1/1] drm/exynos: Move platform drivers registration to module init

2014-11-20 Thread Vivek Gautam
Hi Javier, Kevin,



On Wed, Nov 19, 2014 at 10:22 PM, Javier Martinez Canillas
 wrote:
> [adding Paolo and Vivek as cc]
>
> Hello,
>
> On 11/18/2014 07:41 PM, Kevin Hilman wrote:
>>
>> It fixes the DRM deadlock, issue for me on exynos5800-peach-pi, but then
>> it proceeds to panic in the workqueue code called by the asoc max98090
>> codec[1].
>>
>> If I then disable CONFIG_SND_SOC_SNOW, I can get it to boot to a shell,
>> but I still don't have display output.
>>
>
> Paolo Pisati pointed out in another thread that he needed the patch
> "[PATCH v2 2/2] arm: dts: Exynos5: Use pmu_system_controller phandle for dp 
> phy"
> is also needed to get display working for exynos on linux-next.
>
> I've pinged Kukjin to apply this as a -rc fix since is needed after
> a5ec598 ("phy: exynos-dp-video: Use syscon support to control pmu register")
> landed in 3.18 which broke the Exynos Display Port PHY:
>
> exynos-dp-video-phy 10040728.video-phy: Failed to lookup PMU regmap
>
> I've an Exynos5800 Peach Pi now so I wanted to test display on it. Just 
> $subject
> and [0] should be enough to have display working on Peach Pi with linux-next 
> but
> it fails to me with:
>
> exynos-mipi-video-phy 10040714.video-phy: can't request region for resource 
> [mem 0x10040714-0x1004071f]
>
> The same issue was reported by Paolo a couple of days ago [1].
>
> Vivek,
>
> Any idea what could cause this regression on linux-next? As reported by Paolo 
> this
> works well for me in 3.18-rc5.

I tested linux-next on Exynos5800 peach-pi board with linux-next and and the two
patches $Subject and [0].

Below is my git hash:
4d9e6ee drm/exynos: Move platform drivers registration to module init
4545ed4 POSTED: arm: dts: Exynos5: Use pmu_system_controller phandle for dp phy
36391a5 Add linux-next specific files for 20141119
9b1ced1 Merge branch 'akpm/master'
282497e mm: add strictlimit knob

With this display works for me.
Without $Subject patch i get lookup in drm.

Javier can you tell me your git hash. Was it on yesterday's linux-next ?

>
> Best regards,
> Javier
>
> [0]: https://lkml.org/lkml/2014/10/30/394
> [1]: http://www.spinics.net/lists/linux-samsung-soc/msg39032.html
> --
> To unsubscribe from this list: send the line "unsubscribe linux-samsung-soc" 
> in
> the body of a message to majordomo at vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html



-- 
Best Regards
Vivek Gautam
Samsung R Institute, Bangalore
India


[RFC PATCH 1/1] drm/exynos: Move platform drivers registration to module init

2014-11-20 Thread Vivek Gautam
Hi,


On Thu, Nov 20, 2014 at 12:36 PM, Vivek Gautam
 wrote:
> Hi Javier, Kevin,
>
>
>
> On Wed, Nov 19, 2014 at 10:22 PM, Javier Martinez Canillas
>  wrote:
>> [adding Paolo and Vivek as cc]
>>
>> Hello,
>>
>> On 11/18/2014 07:41 PM, Kevin Hilman wrote:
>>>
>>> It fixes the DRM deadlock, issue for me on exynos5800-peach-pi, but then
>>> it proceeds to panic in the workqueue code called by the asoc max98090
>>> codec[1].
>>>
>>> If I then disable CONFIG_SND_SOC_SNOW, I can get it to boot to a shell,
>>> but I still don't have display output.
>>>
>>
>> Paolo Pisati pointed out in another thread that he needed the patch
>> "[PATCH v2 2/2] arm: dts: Exynos5: Use pmu_system_controller phandle for dp 
>> phy"
>> is also needed to get display working for exynos on linux-next.
>>
>> I've pinged Kukjin to apply this as a -rc fix since is needed after
>> a5ec598 ("phy: exynos-dp-video: Use syscon support to control pmu register")
>> landed in 3.18 which broke the Exynos Display Port PHY:
>>
>> exynos-dp-video-phy 10040728.video-phy: Failed to lookup PMU regmap
>>
>> I've an Exynos5800 Peach Pi now so I wanted to test display on it. Just 
>> $subject
>> and [0] should be enough to have display working on Peach Pi with linux-next 
>> but
>> it fails to me with:
>>
>> exynos-mipi-video-phy 10040714.video-phy: can't request region for resource 
>> [mem 0x10040714-0x1004071f]
>>
>> The same issue was reported by Paolo a couple of days ago [1].
>>
>> Vivek,
>>
>> Any idea what could cause this regression on linux-next? As reported by 
>> Paolo this
>> works well for me in 3.18-rc5.
>
> I tested linux-next on Exynos5800 peach-pi board with linux-next and and the 
> two
> patches $Subject and [0].
>
> Below is my git hash:
> 4d9e6ee drm/exynos: Move platform drivers registration to module init
> 4545ed4 POSTED: arm: dts: Exynos5: Use pmu_system_controller phandle for dp 
> phy
> 36391a5 Add linux-next specific files for 20141119
> 9b1ced1 Merge branch 'akpm/master'
> 282497e mm: add strictlimit knob

used exynos_defconfig

>
> With this display works for me.
> Without $Subject patch i get lookup in drm.
>
> Javier can you tell me your git hash. Was it on yesterday's linux-next ?

With 3.18-rc5 i could see display on Exynos5800 peach-pi with
following git hash:

b6dca11 drm/exynos: dp: Remove support for unused dptx-phy
7cc5c2d ARM: exynos_defconfig: Enable options for display panel support
d0aca5e arm: dts: Exynos5: Use pmu_system_controller phandle for dp phy
fc14f9c Linux 3.18-rc5
e35c5a2 Merge tag 'armsoc-for-rc5' of
git://git.kernel.org/pub/scm/linux/kernel/git/arm/arm-soc

I don't need this drm lockup patch with 3.18-rc5 (with exynos_defconfig).

I am checking further with linux-samsung, coz i could see weird
behavior as mentioned
in [1] with linux-samsun/for-next merged with above git hash.

>> [0]: https://lkml.org/lkml/2014/10/30/394
>> [1]: http://www.spinics.net/lists/linux-samsung-soc/msg39032.html




-- 
Best Regards
Vivek Gautam
Samsung R Institute, Bangalore
India


[RFC PATCH 1/1] drm/exynos: Move platform drivers registration to module init

2014-11-20 Thread Vivek Gautam
Hi Javier,


On Thu, Nov 20, 2014 at 2:15 PM, Javier Martinez Canillas
 wrote:
> Hello Vivek,
>
> On 11/20/2014 08:51 AM, Vivek Gautam wrote:
>>>
>>> I tested linux-next on Exynos5800 peach-pi board with linux-next and and 
>>> the two
>>> patches $Subject and [0].
>>>
>>> Below is my git hash:
>>> 4d9e6ee drm/exynos: Move platform drivers registration to module init
>>> 4545ed4 POSTED: arm: dts: Exynos5: Use pmu_system_controller phandle for dp 
>>> phy
>>> 36391a5 Add linux-next specific files for 20141119
>>> 9b1ced1 Merge branch 'akpm/master'
>>> 282497e mm: add strictlimit knob
>>
>> used exynos_defconfig
>>
>
> Same here.
>
>>>
>>> With this display works for me.
>>> Without $Subject patch i get lookup in drm.
>>>
>
> I tested with today linux-next (next-20141120) and display is indeed
> working for me. So it seems that whatever caused the error in the
> phy-exynos-mipi-video driver reported by Paolo, got fixed recently.
>
> My working git hash is:
>
> 65a8d01 arm: dts: Exynos5: Use pmu_system_controller phandle for dp phy
> a9b43cb drm/exynos: Move platform drivers registration to module init
> 5b83d7a Add linux-next specific files for 20141120
> 1172916 mm: add strictlimit knob
>
> I did have to disable CONFIG_SND_SOC_SNOW though, otherwise the kernel
> did not boot due the issue reported previously by Kevin.
>
>>> Javier can you tell me your git hash. Was it on yesterday's linux-next ?
>>
>
> In fact, my branch where I could reproduce the phy-exynos-mipi-video issue
> was not based on yesterday's next but next-20141117. The git hash is:
>
> 9fb5d7c arm: dts: Exynos5: Use pmu_system_controller phandle for dp phy
> f740096 drm/exynos: Move platform drivers registration to module init
> efefb5c Add linux-next specific files for 20141117
> 8c944d7 mm: add strictlimit knob
>
>> With 3.18-rc5 i could see display on Exynos5800 peach-pi with
>> following git hash:
>>
>> b6dca11 drm/exynos: dp: Remove support for unused dptx-phy
>> 7cc5c2d ARM: exynos_defconfig: Enable options for display panel support
>> d0aca5e arm: dts: Exynos5: Use pmu_system_controller phandle for dp phy
>> fc14f9c Linux 3.18-rc5
>> e35c5a2 Merge tag 'armsoc-for-rc5' of
>> git://git.kernel.org/pub/scm/linux/kernel/git/arm/arm-soc
>>
>> I don't need this drm lockup patch with 3.18-rc5 (with exynos_defconfig).
>>
>
> Yes, that works because the commit that caused the Exynos DRM lockup was:
>
> 43c0767 ("of/platform: Move platform devices under /sys/devices/platform")
>
> which landed in next-20141105.
>
> Reverting 43c0767 and only applying [0] should have the same effect.
>
>> I am checking further with linux-samsung, coz i could see weird
>> behavior as mentioned
>> in [1] with linux-samsun/for-next merged with above git hash.
>>
>
> Great, it should be good to know what caused:

On linux-samsung tree the only patch that's missing apart from dptx-phy patches
is the syscon patch from Pankaj Dubey:
b784b98 mfd: syscon: Decouple syscon interface from platform devices

So with below git hash, linux-samsung/for-next display works fine along with
other devices that request PMU system controller :

7bd219e drm/exynos: dp: Remove support for unused dptx-phy
e8f21fd arm: dts: Exynos5: Use pmu_system_controller phandle for dp phy
7099bde Revert "Revert "ARM: exynos_defconfig: Enable options for
display panel support""
713a994 mfd: syscon: Decouple syscon interface from platform devices
7552917 Revert "ARM: exynos_defconfig: Enable options for display
panel support" /* This is Kukjin's for-next today */
ff0391a Merge branch 'v3.19-samsung-defconfig' into for-next
26c6283 Merge branch 'v3.18-samsung-fixes' into for-next
cf864fd Merge branch 'v3.18-samsung-defconfig' into for-next
98b6380 ARM: exynos_defconfig: Enable max77802 rtc and clock drivers
839275c ARM: exynos_defconfig: Use 16 minors per MMC block device
0526f27 ARM: dts: Explicitly set dr_mode on exynos5250-snow
fc14f9c Linux 3.18-rc5


>
> exynos-mipi-video-phy 10040714.video-phy: can't request region for resource 
> [mem 0x10040714-0x1004071f]

The only reason i see this fails is since PMU is now requesting the
entire memory
region with base 0x1004. We should convert the mipi-phy pmu
register handling
too through syscon.

>
> even when I could not reproduce it anymore with today's linux-next.
>
>>>> [0]: https://lkml.org/lkml/2014/10/30/394
>>>> [1]: http://www.spinics.net/lists/linux-samsung-soc/msg39032.html



-- 
Best Regards
Vivek Gautam
Samsung R Institute, Bangalore
India


[PATCH V2 RESEND] arm: dts: Exynos5: Use pmu_system_controller phandle for dp phy

2014-11-24 Thread Vivek Gautam
DP PHY now require pmu-system-controller to handle PMU register
to control PHY's power isolation. Adding the same to dp-phy
node.

Signed-off-by: Vivek Gautam 
Reviewed-by: Jingoo Han 
Tested-by: Javier Martinez Canillas 
Cc: Kukjin Kim 
---
 arch/arm/boot/dts/exynos5250.dtsi |2 +-
 arch/arm/boot/dts/exynos5420.dtsi |4 ++--
 2 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/arch/arm/boot/dts/exynos5250.dtsi 
b/arch/arm/boot/dts/exynos5250.dtsi
index 0a588b4..bebd099 100644
--- a/arch/arm/boot/dts/exynos5250.dtsi
+++ b/arch/arm/boot/dts/exynos5250.dtsi
@@ -732,7 +732,7 @@

dp_phy: video-phy at 10040720 {
compatible = "samsung,exynos5250-dp-video-phy";
-   reg = <0x10040720 4>;
+   samsung,pmu-syscon = <_system_controller>;
#phy-cells = <0>;
};

diff --git a/arch/arm/boot/dts/exynos5420.dtsi 
b/arch/arm/boot/dts/exynos5420.dtsi
index 8617a03..1353a09 100644
--- a/arch/arm/boot/dts/exynos5420.dtsi
+++ b/arch/arm/boot/dts/exynos5420.dtsi
@@ -503,8 +503,8 @@
};

dp_phy: video-phy at 10040728 {
-   compatible = "samsung,exynos5250-dp-video-phy";
-   reg = <0x10040728 4>;
+   compatible = "samsung,exynos5420-dp-video-phy";
+   samsung,pmu-syscon = <_system_controller>;
#phy-cells = <0>;
};

-- 
1.7.10.4



[PATCH v2 2/2] arm: dts: Exynos5: Use pmu_system_controller phandle for dp phy

2014-11-24 Thread Vivek Gautam
On Sun, Nov 23, 2014 at 12:26 AM, Javier Martinez Canillas
 wrote:
> Hello Vivek
>
> On Wed, Nov 19, 2014 at 1:03 PM, Vivek Gautam  
> wrote:
>>>
>>> Tested-by: Javier Martinez Canillas 
>>
>> Thanks for testing.
>>
>
> You are welcome
>
>>>
>>> Kukjin,
>>
>> Sorry for not adding Kukjin to the list and thereby for the delay
>> about this patch.
>>
>
> No worries but I'm not sure if Kukjin is aware of this patch. I see he
> has been applying other patches but didn't pick $subject.
Right,

>
> Maybe you can resend it to Kukjin just to be sure he will have it in
> his mailbox?

Posted a RESEND version of this patch. Thanks again for noticing.



-- 
Best Regards
Vivek Gautam
Samsung R Institute, Bangalore
India


[PATCH V2 RESEND] arm: dts: Exynos5: Use pmu_system_controller phandle for dp phy

2014-11-24 Thread Vivek Gautam
Hi,


On Mon, Nov 24, 2014 at 4:02 PM, Thierry Reding
 wrote:
> On Mon, Nov 24, 2014 at 11:11:23AM +0530, Vivek Gautam wrote:
>> DP PHY now require pmu-system-controller to handle PMU register
>> to control PHY's power isolation. Adding the same to dp-phy
>> node.
>>
>> Signed-off-by: Vivek Gautam 
>> Reviewed-by: Jingoo Han 
>> Tested-by: Javier Martinez Canillas 
>> Cc: Kukjin Kim 
>> ---
>>  arch/arm/boot/dts/exynos5250.dtsi |2 +-
>>  arch/arm/boot/dts/exynos5420.dtsi |4 ++--
>>  2 files changed, 3 insertions(+), 3 deletions(-)
>>
>> diff --git a/arch/arm/boot/dts/exynos5250.dtsi 
>> b/arch/arm/boot/dts/exynos5250.dtsi
>> index 0a588b4..bebd099 100644
>> --- a/arch/arm/boot/dts/exynos5250.dtsi
>> +++ b/arch/arm/boot/dts/exynos5250.dtsi
>> @@ -732,7 +732,7 @@
>>
>>   dp_phy: video-phy at 10040720 {
>>   compatible = "samsung,exynos5250-dp-video-phy";
>> - reg = <0x10040720 4>;
>> + samsung,pmu-syscon = <_system_controller>;
>>   #phy-cells = <0>;
>>   };
>>
>> diff --git a/arch/arm/boot/dts/exynos5420.dtsi 
>> b/arch/arm/boot/dts/exynos5420.dtsi
>> index 8617a03..1353a09 100644
>> --- a/arch/arm/boot/dts/exynos5420.dtsi
>> +++ b/arch/arm/boot/dts/exynos5420.dtsi
>> @@ -503,8 +503,8 @@
>>   };
>>
>>   dp_phy: video-phy at 10040728 {
>> - compatible = "samsung,exynos5250-dp-video-phy";
>> - reg = <0x10040728 4>;
>> + compatible = "samsung,exynos5420-dp-video-phy";
>> + samsung,pmu-syscon = <_system_controller>;
>>   #phy-cells = <0>;
>>   };
>>
>
> It seems like these nodes have been in the Linux tree since 3.12 and
> 3.17, respectively and these changes break backwards-compatibility. Has
> anyone thought about the possible consequences?

Sorry for my ignorance, but i have a doubt.
If the bindings and device node both are being changed in the same kernel
version (as fixes),
so that the stable will have both; then the only scenerio of backward
compatibility comes when kernel is upgraded but not dtbs.
Does such upgradation makes sense for distros ?

>
> Although, looking more closely it seems like this isn't the first time
> that backwards-compatibility was broken in these files, so perhaps
> nobody cares...
>
> Thierry



-- 
Best Regards
Vivek Gautam
Samsung R Institute, Bangalore
India


[RFC PATCH 1/1] drm/exynos: Move platform drivers registration to module init

2014-11-24 Thread Vivek Gautam
Hi Javier,


On Mon, Nov 24, 2014 at 3:35 PM, Javier Martinez Canillas
 wrote:
> Hello Ajay,
>
> On 11/21/2014 09:57 PM, Javier Martinez Canillas wrote:
>> On 11/21/2014 06:32 PM, Ajay kumar wrote:
>>> Hi,
>>>
>>> I have rebased my bridge series on top of linux-next.
>>>
>>> This is my git log:
>>> 4b38a6f Revert "Revert "ARM: exynos_defconfig: Enable options for
>>> display panel support""
>>> 6fb39a7 ARM: dts: peach-pit: represent the connection between bridge
>>> and panel using videoport and endpoints
>>> aee649c ARM: dts: snow: represent the connection between bridge and
>>> panel using videoport and endpoints
>>> 5b76d8d drm/bridge: Add i2c based driver for ps8622/ps8625 bridge
>>> 581257f Documentation: bridge: Add documentation for ps8622 DT properties
>>> 178e8b9 Documentation: devicetree: Add vendor prefix for parade
>>> 0ceea75 Documentation: drm: bridge: move to video/bridge
>>> f143e2e drm/bridge: ptn3460: use gpiod interface
>>> 2d5cb9d drm/bridge: ptn3460: probe connector at the end of bridge attach
>>> 32ac563 drm/bridge: ptn3460: support drm_panel
>>> 91c6c30 drm/exynos: dp: support drm_bridge
>>> 7eea7eb drm/bridge: ptn3460: Convert to i2c driver model
>>> 602f343 drm/bridge: make bridge registration independent of drm flow
>>> 14c7143 drm/bridge: do not pass drm_bridge_funcs to drm_bridge_init
>>> 2c01ac4 drm/bridge: ptn3460: Few trivial cleanups
>>> 7415f6c arm: dts: Exynos5: Use pmu_system_controller phandle for dp phy
>>> 28655d1 drm/exynos: Move platform drivers registration to module init
>>> ed6778a Add linux-next specific files for 20141121
>>>
>>> I have attached the rebased patches as well.
>>> I tested it on snow, peach_pit and peach_pi without *clk_ignore_unused*.
>>> Display is totally fine with exynos_defconfig (booting is fine even
>>> with CONFIG_SND_SOC_SNOW=y)
>>>
>>
>> Thanks for forward porting your patches to linux-next. Unfortunately I
>> won't have time to test them until Monday but I wonder why you didn't
>> have the boot issues that we have with next-20141121.
>>
>
> I tested your ToT patches on top of next-20141121, this is my git log:
>
> 93fe3d7 Revert "Revert "ARM: exynos_defconfig: Enable options for display 
> panel support""
> 552f74e ARM: dts: peach-pit: represent the connection between bridge and 
> panel using videoport and endpoints
> dbbc293 ARM: dts: snow: represent the connection between bridge and panel 
> using videoport and endpoints
> d8687f8 drm/bridge: Add i2c based driver for ps8622/ps8625 bridge
> f29a649 Documentation: bridge: Add documentation for ps8622 DT properties
> 6ade887 Documentation: devicetree: Add vendor prefix for parade
> d81c42d Documentation: drm: bridge: move to video/bridge
> 50b9828 drm/bridge: ptn3460: use gpiod interface
> 1274c56 drm/bridge: ptn3460: probe connector at the end of bridge attach
> f3cf063 drm/bridge: ptn3460: support drm_panel
> cab682b drm/exynos: dp: support drm_bridge
> 6e78916 drm/bridge: ptn3460: Convert to i2c driver model
> 93f4b5f drm/bridge: make bridge registration independent of drm flow
> 81a038f drm/bridge: do not pass drm_bridge_funcs to drm_bridge_init
> eb6996e drm/bridge: ptn3460: Few trivial cleanups
> c41fa5d arm: dts: Exynos5: Use pmu_system_controller phandle for dp phy
> 51b2c75 drm/exynos: Move platform drivers registration to module init
> ed6778a Add linux-next specific files for 20141121
>
>> I found that the commit ae43b32 ("ARM: 8202/1: dmaengine: pl330: Add
>> runtime Power Management support v12") had to be reverted in order to
>> boot linux-next.
>>
>
> Display works but I needed to revert the mentioned commit, otherwise
> the boot hangs as reported before. I'm using exynos_defconfig and this
> kernel command line:
>
> console=ttySAC3,115200N8 debug earlyprintk root=/dev/mmcblk1p2 rootwait rw

My git log --oneline gives following git hash
vivek at vivek-linuxpc:~/MAINLINE_KERNEL/linux-next$ git log --oneline

9af3770 arm: dts: Exynos5: Use pmu_system_controller phandle for dp phy
1558298 drm/exynos: Move platform drivers registration to module init
4df404f Revert "Revert "ARM: exynos_defconfig: Enable options for
display panel support""
ed6778a Add linux-next specific files for 20141121
eb052c1 Merge branch 'akpm/master'
9c46812 mm: add strictlimit knob

Also attached my config (which is just made out of exynos_defconfig) :
config_next20141124

The boot arguments used are:
[0.00] Kernel command line: root=/dev/mmcblk1p1 rootwait ro
console=ttySAC3,115

[PATCH V2 RESEND] arm: dts: Exynos5: Use pmu_system_controller phandle for dp phy

2014-11-24 Thread Vivek Gautam
On Mon, Nov 24, 2014 at 4:26 PM, Thierry Reding
 wrote:
> On Mon, Nov 24, 2014 at 04:17:18PM +0530, Vivek Gautam wrote:
>> Hi,
>>
>>
>> On Mon, Nov 24, 2014 at 4:02 PM, Thierry Reding
>>  wrote:
>> > On Mon, Nov 24, 2014 at 11:11:23AM +0530, Vivek Gautam wrote:
>> >> DP PHY now require pmu-system-controller to handle PMU register
>> >> to control PHY's power isolation. Adding the same to dp-phy
>> >> node.
>> >>
>> >> Signed-off-by: Vivek Gautam 
>> >> Reviewed-by: Jingoo Han 
>> >> Tested-by: Javier Martinez Canillas 
>> >> Cc: Kukjin Kim 
>> >> ---
>> >>  arch/arm/boot/dts/exynos5250.dtsi |2 +-
>> >>  arch/arm/boot/dts/exynos5420.dtsi |4 ++--
>> >>  2 files changed, 3 insertions(+), 3 deletions(-)
>> >>
>> >> diff --git a/arch/arm/boot/dts/exynos5250.dtsi 
>> >> b/arch/arm/boot/dts/exynos5250.dtsi
>> >> index 0a588b4..bebd099 100644
>> >> --- a/arch/arm/boot/dts/exynos5250.dtsi
>> >> +++ b/arch/arm/boot/dts/exynos5250.dtsi
>> >> @@ -732,7 +732,7 @@
>> >>
>> >>   dp_phy: video-phy at 10040720 {
>> >>   compatible = "samsung,exynos5250-dp-video-phy";
>> >> - reg = <0x10040720 4>;
>> >> + samsung,pmu-syscon = <_system_controller>;
>> >>   #phy-cells = <0>;
>> >>   };
>> >>
>> >> diff --git a/arch/arm/boot/dts/exynos5420.dtsi 
>> >> b/arch/arm/boot/dts/exynos5420.dtsi
>> >> index 8617a03..1353a09 100644
>> >> --- a/arch/arm/boot/dts/exynos5420.dtsi
>> >> +++ b/arch/arm/boot/dts/exynos5420.dtsi
>> >> @@ -503,8 +503,8 @@
>> >>   };
>> >>
>> >>   dp_phy: video-phy at 10040728 {
>> >> - compatible = "samsung,exynos5250-dp-video-phy";
>> >> - reg = <0x10040728 4>;
>> >> + compatible = "samsung,exynos5420-dp-video-phy";
>> >> + samsung,pmu-syscon = <_system_controller>;
>> >>   #phy-cells = <0>;
>> >>   };
>> >>
>> >
>> > It seems like these nodes have been in the Linux tree since 3.12 and
>> > 3.17, respectively and these changes break backwards-compatibility. Has
>> > anyone thought about the possible consequences?
>>
>> Sorry for my ignorance, but i have a doubt.
>> If the bindings and device node both are being changed in the same kernel
>> version (as fixes),
>> so that the stable will have both; then the only scenerio of backward
>> compatibility comes when kernel is upgraded but not dtbs.
>
> Correct.
>
>> Does such upgradation makes sense for distros ?
>
> Yes. Back at the time a decision was made that device trees need to be
> stable ABI because eventually they'd be shipped with the device rather
> than the distribution. As such it may not at all be possible to update
> them (they could be in some sort of ROM).
>
> For that reason new kernels need to keep working with old DTBs unless an
> argument can be made that would justify breaking things. I don't think I
> have ever seen anyone win such an argument.
> One of the rare exceptions
> that I know of is if you can prove that a given hardware block has never
> been used in an upstream kernel, then changing the DTB in backwards-
> incompatible ways would be okay because you wouldn't be breaking things
> for existing users.

I am pretty sure about the Chrome devices (which have not been
upgraded to any kernel after
3.8).
Probably Javier may have better knowledge.

Javier, is there any other device using upstream kernel post 3.12 (any
arndale octa based) ?




-- 
Best Regards
Vivek Gautam
Samsung R Institute, Bangalore
India


[PATCH 2/3] drm/exynos: dp: Remove support for unused dptx-phy

2014-10-08 Thread Vivek Gautam
Hi,


On Mon, Sep 15, 2014 at 6:43 PM, Vivek Gautam  
wrote:
> Now that we have moved to generic phy based bindings,
> we don't need to have any code related to older dptx-phy.
> Nobody is using this dptx-phy anymore, so removing the
> same.
>
> Signed-off-by: Vivek Gautam 
> Cc: Jingoo Han 
> ---

Is someone taking care of this patch ? We already have got the corresponsding
dp-phy patch merged, so we should also get this patch in.

>  drivers/gpu/drm/exynos/exynos_dp_core.c |   58 
> +++
>  drivers/gpu/drm/exynos/exynos_dp_core.h |2 --
>  2 files changed, 13 insertions(+), 47 deletions(-)
>
> diff --git a/drivers/gpu/drm/exynos/exynos_dp_core.c 
> b/drivers/gpu/drm/exynos/exynos_dp_core.c
> index 4f3c7eb..5ffc1b2 100644
> --- a/drivers/gpu/drm/exynos/exynos_dp_core.c
> +++ b/drivers/gpu/drm/exynos/exynos_dp_core.c
> @@ -1050,28 +1050,14 @@ static int exynos_dp_create_connector(struct 
> exynos_drm_display *display,
>
>  static void exynos_dp_phy_init(struct exynos_dp_device *dp)
>  {
> -   if (dp->phy) {
> +   if (dp->phy)
> phy_power_on(dp->phy);
> -   } else if (dp->phy_addr) {
> -   u32 reg;
> -
> -   reg = __raw_readl(dp->phy_addr);
> -   reg |= dp->enable_mask;
> -   __raw_writel(reg, dp->phy_addr);
> -   }
>  }
>
>  static void exynos_dp_phy_exit(struct exynos_dp_device *dp)
>  {
> -   if (dp->phy) {
> +   if (dp->phy)
> phy_power_off(dp->phy);
> -   } else if (dp->phy_addr) {
> -   u32 reg;
> -
> -   reg = __raw_readl(dp->phy_addr);
> -   reg &= ~(dp->enable_mask);
> -   __raw_writel(reg, dp->phy_addr);
> -   }
>  }
>
>  static void exynos_dp_poweron(struct exynos_drm_display *display)
> @@ -1210,39 +1196,21 @@ static struct video_info 
> *exynos_dp_dt_parse_pdata(struct device *dev)
>
>  static int exynos_dp_dt_parse_phydata(struct exynos_dp_device *dp)
>  {
> -   struct device_node *dp_phy_node = of_node_get(dp->dev->of_node);
> -   u32 phy_base;
> int ret = 0;
>
> -   dp_phy_node = of_find_node_by_name(dp_phy_node, "dptx-phy");
> -   if (!dp_phy_node) {
> -   dp->phy = devm_phy_get(dp->dev, "dp");
> -   return PTR_ERR_OR_ZERO(dp->phy);
> -   }
> -
> -   if (of_property_read_u32(dp_phy_node, "reg", _base)) {
> -   dev_err(dp->dev, "failed to get reg for dptx-phy\n");
> -   ret = -EINVAL;
> -   goto err;
> -   }
> -
> -   if (of_property_read_u32(dp_phy_node, "samsung,enable-mask",
> -   >enable_mask)) {
> -   dev_err(dp->dev, "failed to get enable-mask for dptx-phy\n");
> -   ret = -EINVAL;
> -   goto err;
> -   }
> -
> -   dp->phy_addr = ioremap(phy_base, SZ_4);
> -   if (!dp->phy_addr) {
> -   dev_err(dp->dev, "failed to ioremap dp-phy\n");
> -   ret = -ENOMEM;
> -   goto err;
> +   dp->phy = devm_phy_get(dp->dev, "dp");
> +   if (IS_ERR(dp->phy)) {
> +   ret = PTR_ERR(dp->phy);
> +   if (ret == -ENOSYS || ret == -ENODEV) {
> +   dp->phy = NULL;
> +   } else if (ret == -EPROBE_DEFER) {
> +   return ret;
> +   } else {
> +   dev_err(dp->dev, "no DP phy configured\n");
> +   return ret;
> +   }
> }
>
> -err:
> -   of_node_put(dp_phy_node);
> -
> return ret;
>  }
>
> diff --git a/drivers/gpu/drm/exynos/exynos_dp_core.h 
> b/drivers/gpu/drm/exynos/exynos_dp_core.h
> index a1aee69..6426201 100644
> --- a/drivers/gpu/drm/exynos/exynos_dp_core.h
> +++ b/drivers/gpu/drm/exynos/exynos_dp_core.h
> @@ -153,8 +153,6 @@ struct exynos_dp_device {
> struct clk  *clock;
> unsigned intirq;
> void __iomem*reg_base;
> -   void __iomem*phy_addr;
> -   unsigned intenable_mask;
>
> struct video_info   *video_info;
> struct link_train   link_train;
> --
> 1.7.10.4
>



-- 
Best Regards
Vivek Gautam
Samsung R Institute, Bangalore
India


[PATCH 3/3] arm: dts: Exynos5: Use pmu_system_controller phandle for dp phy

2014-10-08 Thread Vivek Gautam
Hi,

CC'ing Kukjin,
my bad, missed him while sending the patch. :-(

On Mon, Sep 15, 2014 at 6:43 PM, Vivek Gautam  
wrote:
> DP PHY now require pmu-system-controller to handle PMU register
> to control PHY's power isolation. Adding the same to dp-phy
> node.
>
> Signed-off-by: Vivek Gautam 
> Cc: Jingoo Han 
> ---

Is someone taking care of this patch ? We already have got the corresponsding
dp-phy patch merged, so we should also get this patch in.

>  arch/arm/boot/dts/exynos5250.dtsi |2 +-
>  arch/arm/boot/dts/exynos5420.dtsi |4 ++--
>  2 files changed, 3 insertions(+), 3 deletions(-)
>
> diff --git a/arch/arm/boot/dts/exynos5250.dtsi 
> b/arch/arm/boot/dts/exynos5250.dtsi
> index f21b9aa..9b85a2b 100644
> --- a/arch/arm/boot/dts/exynos5250.dtsi
> +++ b/arch/arm/boot/dts/exynos5250.dtsi
> @@ -732,7 +732,7 @@
>
> dp_phy: video-phy at 10040720 {
> compatible = "samsung,exynos5250-dp-video-phy";
> -   reg = <0x10040720 4>;
> +   samsung,pmu-syscon = <_system_controller>;
> #phy-cells = <0>;
> };
>
> diff --git a/arch/arm/boot/dts/exynos5420.dtsi 
> b/arch/arm/boot/dts/exynos5420.dtsi
> index bfe056d..a677812 100644
> --- a/arch/arm/boot/dts/exynos5420.dtsi
> +++ b/arch/arm/boot/dts/exynos5420.dtsi
> @@ -503,8 +503,8 @@
> };
>
> dp_phy: video-phy at 10040728 {
> -   compatible = "samsung,exynos5250-dp-video-phy";
> -   reg = <0x10040728 4>;
> +   compatible = "samsung,exynos5420-dp-video-phy";
> +   samsung,pmu-syscon = <_system_controller>;
> #phy-cells = <0>;
> };
>
> --
> 1.7.10.4
>



-- 
Best Regards
Vivek Gautam
Samsung R Institute, Bangalore
India


[PATCH 2/3] drm/exynos: dp: Remove support for unused dptx-phy

2014-10-08 Thread Vivek Gautam
Hi,


CC'ing Kukjin,
my bad, missed him while sending the patch. :-(

On Wed, Oct 8, 2014 at 8:27 AM, Vivek Gautam  
wrote:
> Hi,
>
>
> On Mon, Sep 15, 2014 at 6:43 PM, Vivek Gautam  
> wrote:
>> Now that we have moved to generic phy based bindings,
>> we don't need to have any code related to older dptx-phy.
>> Nobody is using this dptx-phy anymore, so removing the
>> same.
>>
>> Signed-off-by: Vivek Gautam 
>> Cc: Jingoo Han 
>> ---
>
> Is someone taking care of this patch ? We already have got the corresponsding
> dp-phy patch merged, so we should also get this patch in.
>
>>  drivers/gpu/drm/exynos/exynos_dp_core.c |   58 
>> +++
>>  drivers/gpu/drm/exynos/exynos_dp_core.h |2 --
>>  2 files changed, 13 insertions(+), 47 deletions(-)
>>
>> diff --git a/drivers/gpu/drm/exynos/exynos_dp_core.c 
>> b/drivers/gpu/drm/exynos/exynos_dp_core.c
>> index 4f3c7eb..5ffc1b2 100644
>> --- a/drivers/gpu/drm/exynos/exynos_dp_core.c
>> +++ b/drivers/gpu/drm/exynos/exynos_dp_core.c
>> @@ -1050,28 +1050,14 @@ static int exynos_dp_create_connector(struct 
>> exynos_drm_display *display,
>>
>>  static void exynos_dp_phy_init(struct exynos_dp_device *dp)
>>  {
>> -   if (dp->phy) {
>> +   if (dp->phy)
>> phy_power_on(dp->phy);
>> -   } else if (dp->phy_addr) {
>> -   u32 reg;
>> -
>> -   reg = __raw_readl(dp->phy_addr);
>> -   reg |= dp->enable_mask;
>> -   __raw_writel(reg, dp->phy_addr);
>> -   }
>>  }
>>
>>  static void exynos_dp_phy_exit(struct exynos_dp_device *dp)
>>  {
>> -   if (dp->phy) {
>> +   if (dp->phy)
>> phy_power_off(dp->phy);
>> -   } else if (dp->phy_addr) {
>> -   u32 reg;
>> -
>> -   reg = __raw_readl(dp->phy_addr);
>> -   reg &= ~(dp->enable_mask);
>> -   __raw_writel(reg, dp->phy_addr);
>> -   }
>>  }
>>
>>  static void exynos_dp_poweron(struct exynos_drm_display *display)
>> @@ -1210,39 +1196,21 @@ static struct video_info 
>> *exynos_dp_dt_parse_pdata(struct device *dev)
>>
>>  static int exynos_dp_dt_parse_phydata(struct exynos_dp_device *dp)
>>  {
>> -   struct device_node *dp_phy_node = of_node_get(dp->dev->of_node);
>> -   u32 phy_base;
>> int ret = 0;
>>
>> -   dp_phy_node = of_find_node_by_name(dp_phy_node, "dptx-phy");
>> -   if (!dp_phy_node) {
>> -   dp->phy = devm_phy_get(dp->dev, "dp");
>> -   return PTR_ERR_OR_ZERO(dp->phy);
>> -   }
>> -
>> -   if (of_property_read_u32(dp_phy_node, "reg", _base)) {
>> -   dev_err(dp->dev, "failed to get reg for dptx-phy\n");
>> -   ret = -EINVAL;
>> -   goto err;
>> -   }
>> -
>> -   if (of_property_read_u32(dp_phy_node, "samsung,enable-mask",
>> -   >enable_mask)) {
>> -   dev_err(dp->dev, "failed to get enable-mask for dptx-phy\n");
>> -   ret = -EINVAL;
>> -   goto err;
>> -   }
>> -
>> -   dp->phy_addr = ioremap(phy_base, SZ_4);
>> -   if (!dp->phy_addr) {
>> -   dev_err(dp->dev, "failed to ioremap dp-phy\n");
>> -   ret = -ENOMEM;
>> -   goto err;
>> +   dp->phy = devm_phy_get(dp->dev, "dp");
>> +   if (IS_ERR(dp->phy)) {
>> +   ret = PTR_ERR(dp->phy);
>> +   if (ret == -ENOSYS || ret == -ENODEV) {
>> +   dp->phy = NULL;
>> +   } else if (ret == -EPROBE_DEFER) {
>> +   return ret;
>> +   } else {
>> +   dev_err(dp->dev, "no DP phy configured\n");
>> +   return ret;
>> +   }
>> }
>>
>> -err:
>> -   of_node_put(dp_phy_node);
>> -
>> return ret;
>>  }
>>
>> diff --git a/drivers/gpu/drm/exynos/exynos_dp_core.h 
>> b/drivers/gpu/drm/exynos/exynos_dp_core.h
>> index a1aee69..6426201 100644
>> --- a/drivers/gpu/drm/exynos/exynos_dp_core.h
>> +++ b/drivers/gpu/drm/exynos/exynos_dp_core.h
>> @@ -153,8 +153,6 @@ struct exynos_dp_device {
>> struct clk  *clock;
>> unsigned intirq;
>> void __iomem*reg_base;
>> -   void __iomem*phy_addr;
>> -   unsigned intenable_mask;
>>
>> struct video_info   *video_info;
>> struct link_train   link_train;
>> --
>> 1.7.10.4
>>
>
>
>
> --
> Best Regards
> Vivek Gautam
> Samsung R Institute, Bangalore
> India



-- 
Best Regards
Vivek Gautam
Samsung R Institute, Bangalore
India


[PATCH 0/3] drm-exynos-dp/phy-exynos-dp: Refactor to use pmu-system-controller and dp driver cleanup

2014-10-09 Thread Vivek Gautam
Ajay,


On Thu, Oct 9, 2014 at 3:48 PM, Ajay kumar  wrote:
> Hi,
>
> On Mon, Sep 15, 2014 at 6:43 PM, Vivek Gautam  
> wrote:
>> These patches are based on 'for-next' branch of kgene's linux-samsung tree.
>>
>> Refactoring the exynos-dp-video phy to use pmu-system-controller handle
>> and access the register using mfd-syscon and regmap.
>> Simultaneously, removing the support for older dptx-phy, since it's obsolete
>> now and noone uses it.
>>
>> Vivek Gautam (3):
>>   phy: exynos-dp-video: Use syscon support to control pmu register
>>   drm/exynos: dp: Remove support for unused dptx-phy
>>   arm: dts: Exynos5: Use pmu_system_controller phandle for dp phy
>>
>>  .../devicetree/bindings/phy/samsung-phy.txt|7 +-
>>  arch/arm/boot/dts/exynos5250.dtsi  |2 +-
>>  arch/arm/boot/dts/exynos5420.dtsi  |4 +-
>>  drivers/gpu/drm/exynos/exynos_dp_core.c|   58 ---
>>  drivers/gpu/drm/exynos/exynos_dp_core.h|2 -
>>  drivers/phy/phy-exynos-dp-video.c  |   76 
>> ++--
>>  6 files changed, 75 insertions(+), 74 deletions(-)
>>
>> --
>> 1.7.10.4
>>
>> --
>> To unsubscribe from this list: send the line "unsubscribe linux-samsung-soc" 
>> in
>> the body of a message to majordomo at vger.kernel.org
>> More majordomo info at  http://vger.kernel.org/majordomo-info.html
>
> I have tested this patchset on exynos5800-peach-pi, and I can see DP
> display with the above patches.

we expect "Tested-by", if you have tested please give the same.


-- 
Best Regards
Vivek Gautam
Samsung R Institute, Bangalore
India


[PATCH 2/3] drm/exynos: dp: Remove support for unused dptx-phy

2014-10-30 Thread Vivek Gautam
Hi Inki,


On Thu, Oct 30, 2014 at 5:50 PM, Inki Dae  wrote:
>
> Sorry for late. I missed this patch a little bit for long time.

Thanks for reviewing.

>
>
> On 2014년 09월 15일 22:13, Vivek Gautam wrote:
>> Now that we have moved to generic phy based bindings,
>> we don't need to have any code related to older dptx-phy.
>> Nobody is using this dptx-phy anymore, so removing the
>> same.
>>
>> Signed-off-by: Vivek Gautam 
>> Cc: Jingoo Han 
>> ---
>>  drivers/gpu/drm/exynos/exynos_dp_core.c |   58 
>> +++
>>  drivers/gpu/drm/exynos/exynos_dp_core.h |2 --
>>  2 files changed, 13 insertions(+), 47 deletions(-)
>>
>> diff --git a/drivers/gpu/drm/exynos/exynos_dp_core.c 
>> b/drivers/gpu/drm/exynos/exynos_dp_core.c
>> index 4f3c7eb..5ffc1b2 100644
>> --- a/drivers/gpu/drm/exynos/exynos_dp_core.c
>> +++ b/drivers/gpu/drm/exynos/exynos_dp_core.c
>> @@ -1050,28 +1050,14 @@ static int exynos_dp_create_connector(struct 
>> exynos_drm_display *display,
>>
>>  static void exynos_dp_phy_init(struct exynos_dp_device *dp)
>>  {
>> - if (dp->phy) {
>> + if (dp->phy)
>>   phy_power_on(dp->phy);
>> - } else if (dp->phy_addr) {
>> - u32 reg;
>> -
>> - reg = __raw_readl(dp->phy_addr);
>> - reg |= dp->enable_mask;
>> - __raw_writel(reg, dp->phy_addr);
>> - }
>>  }
>>
>>  static void exynos_dp_phy_exit(struct exynos_dp_device *dp)
>>  {
>> - if (dp->phy) {
>> + if (dp->phy)
>>   phy_power_off(dp->phy);
>> - } else if (dp->phy_addr) {
>> - u32 reg;
>> -
>> - reg = __raw_readl(dp->phy_addr);
>> - reg &= ~(dp->enable_mask);
>> - __raw_writel(reg, dp->phy_addr);
>> - }
>>  }
>>
>>  static void exynos_dp_poweron(struct exynos_drm_display *display)
>> @@ -1210,39 +1196,21 @@ static struct video_info 
>> *exynos_dp_dt_parse_pdata(struct device *dev)
>>
>>  static int exynos_dp_dt_parse_phydata(struct exynos_dp_device *dp)
>>  {
>> - struct device_node *dp_phy_node = of_node_get(dp->dev->of_node);
>> - u32 phy_base;
>>   int ret = 0;
>>
>> - dp_phy_node = of_find_node_by_name(dp_phy_node, "dptx-phy");
>> - if (!dp_phy_node) {
>> - dp->phy = devm_phy_get(dp->dev, "dp");
>> - return PTR_ERR_OR_ZERO(dp->phy);
>> - }
>> -
>> - if (of_property_read_u32(dp_phy_node, "reg", _base)) {
>> - dev_err(dp->dev, "failed to get reg for dptx-phy\n");
>> - ret = -EINVAL;
>> - goto err;
>> - }
>> -
>> - if (of_property_read_u32(dp_phy_node, "samsung,enable-mask",
>> - >enable_mask)) {
>> - dev_err(dp->dev, "failed to get enable-mask for dptx-phy\n");
>> - ret = -EINVAL;
>> - goto err;
>> - }
>> -
>> - dp->phy_addr = ioremap(phy_base, SZ_4);
>> - if (!dp->phy_addr) {
>> - dev_err(dp->dev, "failed to ioremap dp-phy\n");
>> - ret = -ENOMEM;
>> - goto err;
>> + dp->phy = devm_phy_get(dp->dev, "dp");
>> + if (IS_ERR(dp->phy)) {
>> + ret = PTR_ERR(dp->phy);
>> + if (ret == -ENOSYS || ret == -ENODEV) {
>> +     dp->phy = NULL;
>> + } else if (ret == -EPROBE_DEFER) {
>> + return ret;
>> + } else {
>
> WARNING: else is not generally useful after a break or return
> #146: FILE: drivers/gpu/drm/exynos/exynos_dp_core.c:1208:
> +   return ret;
> +   } else {
>
> How about just returning ret like below?
> if (IS_ERR(dp->phy)) {
> dev_err(dp->dev, "no DP phy configured\n");
> return PTR_ERR(ret);
> }
>
> And then you can handle the error at probe function properly.

Right, point taken. Will post the reworked patch.

[snip]

-- 
Best Regards
Vivek Gautam
Samsung R Institute, Bangalore
India


[PATCH v2 1/2] drm/exynos: dp: Remove support for unused dptx-phy

2014-10-30 Thread Vivek Gautam
Now that we have moved to generic phy based bindings,
we don't need to have any code related to older dptx-phy.
Nobody is using this dptx-phy anymore, so removing the
same.

Signed-off-by: Vivek Gautam 
Cc: Inki Dae 
Cc: Jingoo Han 
---

Changes from V1:
 - Reworked error handling in exynos_dp_dt_parse_phydata() as commented
   by Inki.

 drivers/gpu/drm/exynos/exynos_dp_core.c |   67 ---
 drivers/gpu/drm/exynos/exynos_dp_core.h |2 -
 2 files changed, 17 insertions(+), 52 deletions(-)

diff --git a/drivers/gpu/drm/exynos/exynos_dp_core.c 
b/drivers/gpu/drm/exynos/exynos_dp_core.c
index cd50ece..206163b 100644
--- a/drivers/gpu/drm/exynos/exynos_dp_core.c
+++ b/drivers/gpu/drm/exynos/exynos_dp_core.c
@@ -1052,28 +1052,14 @@ static int exynos_dp_create_connector(struct 
exynos_drm_display *display,

 static void exynos_dp_phy_init(struct exynos_dp_device *dp)
 {
-   if (dp->phy) {
+   if (dp->phy)
phy_power_on(dp->phy);
-   } else if (dp->phy_addr) {
-   u32 reg;
-
-   reg = __raw_readl(dp->phy_addr);
-   reg |= dp->enable_mask;
-   __raw_writel(reg, dp->phy_addr);
-   }
 }

 static void exynos_dp_phy_exit(struct exynos_dp_device *dp)
 {
-   if (dp->phy) {
+   if (dp->phy)
phy_power_off(dp->phy);
-   } else if (dp->phy_addr) {
-   u32 reg;
-
-   reg = __raw_readl(dp->phy_addr);
-   reg &= ~(dp->enable_mask);
-   __raw_writel(reg, dp->phy_addr);
-   }
 }

 static void exynos_dp_poweron(struct exynos_drm_display *display)
@@ -1212,40 +1198,13 @@ static struct video_info 
*exynos_dp_dt_parse_pdata(struct device *dev)

 static int exynos_dp_dt_parse_phydata(struct exynos_dp_device *dp)
 {
-   struct device_node *dp_phy_node = of_node_get(dp->dev->of_node);
-   u32 phy_base;
-   int ret = 0;
-
-   dp_phy_node = of_find_node_by_name(dp_phy_node, "dptx-phy");
-   if (!dp_phy_node) {
-   dp->phy = devm_phy_get(dp->dev, "dp");
-   return PTR_ERR_OR_ZERO(dp->phy);
-   }
-
-   if (of_property_read_u32(dp_phy_node, "reg", _base)) {
-   dev_err(dp->dev, "failed to get reg for dptx-phy\n");
-   ret = -EINVAL;
-   goto err;
-   }
-
-   if (of_property_read_u32(dp_phy_node, "samsung,enable-mask",
-   >enable_mask)) {
-   dev_err(dp->dev, "failed to get enable-mask for dptx-phy\n");
-   ret = -EINVAL;
-   goto err;
-   }
-
-   dp->phy_addr = ioremap(phy_base, SZ_4);
-   if (!dp->phy_addr) {
-   dev_err(dp->dev, "failed to ioremap dp-phy\n");
-   ret = -ENOMEM;
-   goto err;
+   dp->phy = devm_phy_get(dp->dev, "dp");
+   if (IS_ERR(dp->phy)) {
+   dev_err(dp->dev, "no DP phy configured\n");
+   return PTR_ERR(dp->phy);
}

-err:
-   of_node_put(dp_phy_node);
-
-   return ret;
+   return 0;
 }

 static int exynos_dp_dt_parse_panel(struct exynos_dp_device *dp)
@@ -1278,8 +1237,16 @@ static int exynos_dp_bind(struct device *dev, struct 
device *master, void *data)
return PTR_ERR(dp->video_info);

ret = exynos_dp_dt_parse_phydata(dp);
-   if (ret)
-   return ret;
+   if (ret) {
+   /*
+* phy itself is not enabled, so we can move forward
+* assigning NULL to phy pointer.
+*/
+   if (ret == -ENOSYS || ret == -ENODEV)
+   dp->phy = NULL;
+   else
+   return ret;
+   }

if (!dp->panel) {
ret = exynos_dp_dt_parse_panel(dp);
diff --git a/drivers/gpu/drm/exynos/exynos_dp_core.h 
b/drivers/gpu/drm/exynos/exynos_dp_core.h
index a1aee69..6426201 100644
--- a/drivers/gpu/drm/exynos/exynos_dp_core.h
+++ b/drivers/gpu/drm/exynos/exynos_dp_core.h
@@ -153,8 +153,6 @@ struct exynos_dp_device {
struct clk  *clock;
unsigned intirq;
void __iomem*reg_base;
-   void __iomem*phy_addr;
-   unsigned intenable_mask;

struct video_info   *video_info;
struct link_train   link_train;
-- 
1.7.10.4



[PATCH v2 2/2] arm: dts: Exynos5: Use pmu_system_controller phandle for dp phy

2014-10-30 Thread Vivek Gautam
DP PHY now require pmu-system-controller to handle PMU register
to control PHY's power isolation. Adding the same to dp-phy
node.

Signed-off-by: Vivek Gautam 
Cc: Jingoo Han 
---

Changes from V1:
 - none.

 arch/arm/boot/dts/exynos5250.dtsi |2 +-
 arch/arm/boot/dts/exynos5420.dtsi |4 ++--
 2 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/arch/arm/boot/dts/exynos5250.dtsi 
b/arch/arm/boot/dts/exynos5250.dtsi
index 012b021..69f5eb0 100644
--- a/arch/arm/boot/dts/exynos5250.dtsi
+++ b/arch/arm/boot/dts/exynos5250.dtsi
@@ -732,7 +732,7 @@

dp_phy: video-phy at 10040720 {
compatible = "samsung,exynos5250-dp-video-phy";
-   reg = <0x10040720 4>;
+   samsung,pmu-syscon = <_system_controller>;
#phy-cells = <0>;
};

diff --git a/arch/arm/boot/dts/exynos5420.dtsi 
b/arch/arm/boot/dts/exynos5420.dtsi
index 8617a03..1353a09 100644
--- a/arch/arm/boot/dts/exynos5420.dtsi
+++ b/arch/arm/boot/dts/exynos5420.dtsi
@@ -503,8 +503,8 @@
};

dp_phy: video-phy at 10040728 {
-   compatible = "samsung,exynos5250-dp-video-phy";
-   reg = <0x10040728 4>;
+   compatible = "samsung,exynos5420-dp-video-phy";
+   samsung,pmu-syscon = <_system_controller>;
#phy-cells = <0>;
};

-- 
1.7.10.4



Re: [PATCH 1/5] drm/msm: Remove pm_runtime operations from msm_iommu

2018-06-15 Thread Vivek Gautam
Hi Jordan,

On Mon, Jun 11, 2018 at 11:56 PM, Jordan Crouse  wrote:
> Now that the IOMMU is the master of it's own power we don't need to bring
> up the GPU to do IOMMU operations. This is good because bringing up a6xx
> requires the GMU so calling pm_runtime_get_sync() too early in the process
> gets us into some nasty circular dependency situations.

Thanks for the patch.
While you are removing these calls, we should add pm_runtime calls
to qcom_iommu_map(). That should make qcom_iommu too master of
its power control.
Then we should be good to go with this patch.

>
> Signed-off-by: Jordan Crouse 
> ---
>  drivers/gpu/drm/msm/msm_iommu.c | 8 
>  1 file changed, 8 deletions(-)
>
> diff --git a/drivers/gpu/drm/msm/msm_iommu.c b/drivers/gpu/drm/msm/msm_iommu.c
> index b23d33622f37..ccd93ac6a4d8 100644
> --- a/drivers/gpu/drm/msm/msm_iommu.c
> +++ b/drivers/gpu/drm/msm/msm_iommu.c
> @@ -40,9 +40,7 @@ static int msm_iommu_attach(struct msm_mmu *mmu, const char 
> * const *names,
> struct msm_iommu *iommu = to_msm_iommu(mmu);
> int ret;
>
> -   pm_runtime_get_sync(mmu->dev);
> ret = iommu_attach_device(iommu->domain, mmu->dev);
> -   pm_runtime_put_sync(mmu->dev);

may be just do the following here.
   return iommu_attach_device(iommu->domain, mmu->dev);

Rest looks good. So after the change.
Reviewed-by: Vivek Gautam 

Best regards
Vivek

>
> return ret;
>  }
> @@ -52,9 +50,7 @@ static void msm_iommu_detach(struct msm_mmu *mmu, const 
> char * const *names,
>  {
> struct msm_iommu *iommu = to_msm_iommu(mmu);
>
> -   pm_runtime_get_sync(mmu->dev);
> iommu_detach_device(iommu->domain, mmu->dev);
> -   pm_runtime_put_sync(mmu->dev);
>  }
>
>  static int msm_iommu_map(struct msm_mmu *mmu, uint64_t iova,
> @@ -63,9 +59,7 @@ static int msm_iommu_map(struct msm_mmu *mmu, uint64_t iova,
> struct msm_iommu *iommu = to_msm_iommu(mmu);
> size_t ret;
>
> -// pm_runtime_get_sync(mmu->dev);
> ret = iommu_map_sg(iommu->domain, iova, sgt->sgl, sgt->nents, prot);
> -// pm_runtime_put_sync(mmu->dev);
> WARN_ON(ret < 0);
>
> return (ret == len) ? 0 : -EINVAL;
> @@ -76,9 +70,7 @@ static int msm_iommu_unmap(struct msm_mmu *mmu, uint64_t 
> iova,
>  {
> struct msm_iommu *iommu = to_msm_iommu(mmu);
>
> -   pm_runtime_get_sync(mmu->dev);
> iommu_unmap(iommu->domain, iova, len);
> -   pm_runtime_put_sync(mmu->dev);
>
> return 0;
>  }
> --
> 2.17.1
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-arm-msm" in
> the body of a message to majord...@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html



-- 
QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member
of Code Aurora Forum, hosted by The Linux Foundation
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


Re: [PATCH 1/5] drm/msm: Remove pm_runtime operations from msm_iommu

2018-06-27 Thread Vivek Gautam
On Wed, Jun 20, 2018 at 4:00 AM, Jordan Crouse  wrote:
> Now that the IOMMU is the master of it's own power we don't need to bring
> up the GPU to do IOMMU operations. This is good because bringing up a6xx
> requires the GMU so calling pm_runtime_get_sync() too early in the process
> gets us into some nasty circular dependency situations.
>
> Signed-off-by: Jordan Crouse 
> ---
>  drivers/gpu/drm/msm/msm_iommu.c | 13 +
>  1 file changed, 1 insertion(+), 12 deletions(-)
>
> diff --git a/drivers/gpu/drm/msm/msm_iommu.c b/drivers/gpu/drm/msm/msm_iommu.c
> index b23d33622f37..e80c79b3bb5c 100644
> --- a/drivers/gpu/drm/msm/msm_iommu.c
> +++ b/drivers/gpu/drm/msm/msm_iommu.c
> @@ -38,13 +38,8 @@ static int msm_iommu_attach(struct msm_mmu *mmu, const 
> char * const *names,
> int cnt)
>  {
> struct msm_iommu *iommu = to_msm_iommu(mmu);
> -   int ret;
>
> -   pm_runtime_get_sync(mmu->dev);
> -   ret = iommu_attach_device(iommu->domain, mmu->dev);
> -   pm_runtime_put_sync(mmu->dev);
> -
> -   return ret;
> +   return iommu_attach_device(iommu->domain, mmu->dev);
>  }
>
>  static void msm_iommu_detach(struct msm_mmu *mmu, const char * const *names,
> @@ -52,9 +47,7 @@ static void msm_iommu_detach(struct msm_mmu *mmu, const 
> char * const *names,
>  {
> struct msm_iommu *iommu = to_msm_iommu(mmu);
>
> -   pm_runtime_get_sync(mmu->dev);
> iommu_detach_device(iommu->domain, mmu->dev);
> -   pm_runtime_put_sync(mmu->dev);
>  }
>
>  static int msm_iommu_map(struct msm_mmu *mmu, uint64_t iova,
> @@ -63,9 +56,7 @@ static int msm_iommu_map(struct msm_mmu *mmu, uint64_t iova,
> struct msm_iommu *iommu = to_msm_iommu(mmu);
> size_t ret;
>
> -// pm_runtime_get_sync(mmu->dev);
> ret = iommu_map_sg(iommu->domain, iova, sgt->sgl, sgt->nents, prot);
> -// pm_runtime_put_sync(mmu->dev);
> WARN_ON(ret < 0);
>
> return (ret == len) ? 0 : -EINVAL;
> @@ -76,9 +67,7 @@ static int msm_iommu_unmap(struct msm_mmu *mmu, uint64_t 
> iova,
>  {
> struct msm_iommu *iommu = to_msm_iommu(mmu);
>
> -   pm_runtime_get_sync(mmu->dev);
> iommu_unmap(iommu->domain, iova, len);
> -   pm_runtime_put_sync(mmu->dev);
>
> return 0;
>  }

Looks good to me.
Reviewed-by: Vivek Gautam 

Best regards
Vivek

> --
> 2.17.1
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-arm-msm" in
> the body of a message to majord...@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html



-- 
QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member
of Code Aurora Forum, hosted by The Linux Foundation
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH v6 4/6] iommu/arm-smmu: Add the device_link between masters and smmu

2018-01-19 Thread Vivek Gautam
From: Sricharan R 

Finally add the device link between the master device and
smmu, so that the smmu gets runtime enabled/disabled only when the
master needs it. This is done from add_device callback which gets
called once when the master is added to the smmu.

Signed-off-by: Sricharan R 
---
 drivers/iommu/arm-smmu.c | 11 +++
 1 file changed, 11 insertions(+)

diff --git a/drivers/iommu/arm-smmu.c b/drivers/iommu/arm-smmu.c
index 95478bfb182c..33bbcfedb896 100644
--- a/drivers/iommu/arm-smmu.c
+++ b/drivers/iommu/arm-smmu.c
@@ -1367,6 +1367,7 @@ static int arm_smmu_add_device(struct device *dev)
struct arm_smmu_device *smmu;
struct arm_smmu_master_cfg *cfg;
struct iommu_fwspec *fwspec = dev->iommu_fwspec;
+   struct device_link *link;
int i, ret;
 
if (using_legacy_binding) {
@@ -1428,6 +1429,16 @@ static int arm_smmu_add_device(struct device *dev)
 
pm_runtime_put_sync(smmu->dev);
 
+   /*
+* Establish the link between smmu and master, so that the
+* smmu gets runtime enabled/disabled as per the master's
+* needs.
+*/
+   link = device_link_add(dev, smmu->dev, DL_FLAG_PM_RUNTIME);
+   if (!link)
+   dev_warn(smmu->dev, "Unable to create device link between %s 
and %s\n",
+dev_name(smmu->dev), dev_name(dev));
+
return 0;
 
 out_cfg_free:
-- 
QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member
of Code Aurora Forum, hosted by The Linux Foundation

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


[PATCH v6 0/6] iommu/arm-smmu: Add runtime pm/sleep support

2018-01-19 Thread Vivek Gautam
This series provides the support for turning on the arm-smmu's
clocks/power domains using runtime pm. This is done using the
recently introduced device links patches, which lets the smmu's
runtime to follow the master's runtime pm, so the smmu remains
powered only when the masters use it.

It also adds support for Qcom's arm-smmu-v2 variant that
has different clocks and power requirements.

Took some reference from the exynos runtime patches [1].

After much discussion [3] over the use of pm_runtime_get/put() in
.unmap op path for the arm-smmu, and after disussing over more than
a couple of approaches to address this, we are putting forward the
changes *without* using pm_runtime APIs in 'unmap'. Rather, letting
the client device take the control of powering on/off the connected
iommu through pm_runtime_get(put)_suppliers() APIs for the scnerios
when the iommu power can't be directly controlled by clients through
device links.
Rafael has agreed to export the suppliers APIs [4].

Hi Robin, Will,
please consider reviewing this series.

[V6]
   * Added Ack given by Rafael to first patch in the series.
   * Addressed Rob Herring's comment for adding soc specific compatible
 string as well besides 'qcom,smmu-v2'.

[V5]
   * Dropped runtime pm calls from "arm_smmu_unmap" op as discussed over
 the list [3] for the last patch series.
   * Added a patch to export pm_runtime_get/put_suppliers() APIs to the
 series as agreed with Rafael [4].
   * Added the related patch for msm drm iommu layer to use
 pm_runtime_get/put_suppliers() APIs in msm_mmu_funcs.
   * Dropped arm-mmu500 clock patch since that would break existing
 platforms.
   * Changed compatible 'qcom,msm8996-smmu-v2' to 'qcom,smmu-v2' to reflect
 the IP version rather than the platform on which it is used.
 The same IP is used across multiple platforms including msm8996,
 and sdm845 etc.
   * Using clock bulk APIs to handle the clocks available to the IP as
 suggested by Stephen Boyd.
   * The first patch in v4 version of the patch-series:
 ("iommu/arm-smmu: Fix the error path in arm_smmu_add_device") has
 already made it to mainline.

[V4]
   * Reworked the clock handling part. We now take clock names as data
 in the driver for supported compatible versions, and loop over them
 to get, enable, and disable the clocks.
   * Using qcom,msm8996 based compatibles for bindings instead of a generic
 qcom compatible.
   * Refactor MMU500 patch to just add the necessary clock names data and
 corresponding bindings.
   * Added the pm_runtime_get/put() calls in .unmap iommu op (fix added by
 Stanimir on top of previous patch version.
   * Added a patch to fix error path in arm_smmu_add_device()
   * Removed patch 3/5 of V3 patch series that added qcom,smmu-v2 bindings.

[V3]
   * Reworked the patches to keep the clocks init/enabling function
 separately for each compatible.

   * Added clocks bindings for MMU40x/500.

   * Added a new compatible for qcom,smmu-v2 implementation and
 the clock bindings for the same.

   * Rebased on top of 4.11-rc1

[V2]
   * Split the patches little differently.

   * Addressed comments.

   * Removed the patch #4 [2] from previous post
 for arm-smmu context save restore. Planning to
 post this separately after reworking/addressing Robin's
 feedback.

   * Reversed the sequence to disable clocks than enabling.
 This was required for those cases where the
 clocks are populated in a dependent order from DT.

[1] https://lkml.org/lkml/2016/10/20/70
[2] https://patchwork.kernel.org/patch/9389717/
[3] https://patchwork.kernel.org/patch/9827825/
[4] https://patchwork.kernel.org/patch/10102445/

Sricharan R (3):
  iommu/arm-smmu: Add pm_runtime/sleep ops
  iommu/arm-smmu: Invoke pm_runtime during probe, add/remove device
  iommu/arm-smmu: Add the device_link between masters and smmu

Vivek Gautam (3):
  base: power: runtime: Export pm_runtime_get/put_suppliers
  iommu/arm-smmu: Add support for qcom,smmu-v2 variant
  drm/msm: iommu: Replace runtime calls with runtime suppliers

 .../devicetree/bindings/iommu/arm,smmu.txt |  43 +++
 drivers/base/power/runtime.c   |   2 +
 drivers/gpu/drm/msm/msm_iommu.c|  16 +--
 drivers/iommu/arm-smmu.c   | 124 -
 4 files changed, 171 insertions(+), 14 deletions(-)

-- 
QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member
of Code Aurora Forum, hosted by The Linux Foundation

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


[PATCH v6 3/6] iommu/arm-smmu: Invoke pm_runtime during probe, add/remove device

2018-01-19 Thread Vivek Gautam
From: Sricharan R <sricha...@codeaurora.org>

The smmu device probe/remove and add/remove master device callbacks
gets called when the smmu is not linked to its master, that is without
the context of the master device. So calling runtime apis in those places
separately.

Signed-off-by: Sricharan R <sricha...@codeaurora.org>
[vivek: Cleanup pm runtime calls]
Signed-off-by: Vivek Gautam <vivek.gau...@codeaurora.org>
---
 drivers/iommu/arm-smmu.c | 45 +
 1 file changed, 41 insertions(+), 4 deletions(-)

diff --git a/drivers/iommu/arm-smmu.c b/drivers/iommu/arm-smmu.c
index 21acffe91a1c..95478bfb182c 100644
--- a/drivers/iommu/arm-smmu.c
+++ b/drivers/iommu/arm-smmu.c
@@ -914,11 +914,15 @@ static void arm_smmu_destroy_domain_context(struct 
iommu_domain *domain)
struct arm_smmu_domain *smmu_domain = to_smmu_domain(domain);
struct arm_smmu_device *smmu = smmu_domain->smmu;
struct arm_smmu_cfg *cfg = _domain->cfg;
-   int irq;
+   int ret, irq;
 
if (!smmu || domain->type == IOMMU_DOMAIN_IDENTITY)
return;
 
+   ret = pm_runtime_get_sync(smmu->dev);
+   if (ret)
+   return;
+
/*
 * Disable the context bank and free the page tables before freeing
 * it.
@@ -933,6 +937,8 @@ static void arm_smmu_destroy_domain_context(struct 
iommu_domain *domain)
 
free_io_pgtable_ops(smmu_domain->pgtbl_ops);
__arm_smmu_free_bitmap(smmu->context_map, cfg->cbndx);
+
+   pm_runtime_put_sync(smmu->dev);
 }
 
 static struct iommu_domain *arm_smmu_domain_alloc(unsigned type)
@@ -1408,12 +1414,20 @@ static int arm_smmu_add_device(struct device *dev)
while (i--)
cfg->smendx[i] = INVALID_SMENDX;
 
-   ret = arm_smmu_master_alloc_smes(dev);
+   ret = pm_runtime_get_sync(smmu->dev);
if (ret)
goto out_cfg_free;
 
+   ret = arm_smmu_master_alloc_smes(dev);
+   if (ret) {
+   pm_runtime_put_sync(smmu->dev);
+   goto out_cfg_free;
+   }
+
iommu_device_link(>iommu, dev);
 
+   pm_runtime_put_sync(smmu->dev);
+
return 0;
 
 out_cfg_free:
@@ -1428,7 +1442,7 @@ static void arm_smmu_remove_device(struct device *dev)
struct iommu_fwspec *fwspec = dev->iommu_fwspec;
struct arm_smmu_master_cfg *cfg;
struct arm_smmu_device *smmu;
-
+   int ret;
 
if (!fwspec || fwspec->ops != _smmu_ops)
return;
@@ -1436,8 +1450,21 @@ static void arm_smmu_remove_device(struct device *dev)
cfg  = fwspec->iommu_priv;
smmu = cfg->smmu;
 
+   /*
+* The device link between the master device and
+* smmu is already purged at this point.
+* So enable the power to smmu explicitly.
+*/
+
+   ret = pm_runtime_get_sync(smmu->dev);
+   if (ret)
+   return;
+
iommu_device_unlink(>iommu, dev);
arm_smmu_master_free_smes(fwspec);
+
+   pm_runtime_put_sync(smmu->dev);
+
iommu_group_remove_device(dev);
kfree(fwspec->iommu_priv);
iommu_fwspec_free(dev);
@@ -2130,6 +2157,14 @@ static int arm_smmu_device_probe(struct platform_device 
*pdev)
if (err)
return err;
 
+   platform_set_drvdata(pdev, smmu);
+
+   pm_runtime_enable(dev);
+
+   err = pm_runtime_get_sync(dev);
+   if (err)
+   return err;
+
err = arm_smmu_device_cfg_probe(smmu);
if (err)
return err;
@@ -2171,9 +2206,9 @@ static int arm_smmu_device_probe(struct platform_device 
*pdev)
return err;
}
 
-   platform_set_drvdata(pdev, smmu);
arm_smmu_device_reset(smmu);
arm_smmu_test_smr_masks(smmu);
+   pm_runtime_put_sync(dev);
 
/*
 * For ACPI and generic DT bindings, an SMMU will be probed before
@@ -2212,6 +2247,8 @@ static int arm_smmu_device_remove(struct platform_device 
*pdev)
 
/* Turn the thing off */
writel(sCR0_CLIENTPD, ARM_SMMU_GR0_NS(smmu) + ARM_SMMU_GR0_sCR0);
+   pm_runtime_force_suspend(smmu->dev);
+
return 0;
 }
 
-- 
QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member
of Code Aurora Forum, hosted by The Linux Foundation

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


[PATCH v6 5/6] iommu/arm-smmu: Add support for qcom,smmu-v2 variant

2018-01-19 Thread Vivek Gautam
qcom,smmu-v2 is an arm,smmu-v2 implementation with specific
clock and power requirements. This smmu core is used with
multiple masters on msm8996, viz. mdss, video, etc.
Add bindings for the same.

Signed-off-by: Vivek Gautam <vivek.gau...@codeaurora.org>
---
 .../devicetree/bindings/iommu/arm,smmu.txt | 43 ++
 drivers/iommu/arm-smmu.c   | 13 +++
 2 files changed, 56 insertions(+)

diff --git a/Documentation/devicetree/bindings/iommu/arm,smmu.txt 
b/Documentation/devicetree/bindings/iommu/arm,smmu.txt
index 8a6ffce12af5..169222ae2706 100644
--- a/Documentation/devicetree/bindings/iommu/arm,smmu.txt
+++ b/Documentation/devicetree/bindings/iommu/arm,smmu.txt
@@ -17,10 +17,19 @@ conditions.
 "arm,mmu-401"
 "arm,mmu-500"
 "cavium,smmu-v2"
+"qcom,-smmu-v2", "qcom,smmu-v2"
 
   depending on the particular implementation and/or the
   version of the architecture implemented.
 
+  A number of Qcom SoCs use qcom,smmu-v2 version of the IP.
+  "qcom,-smmu-v2" represents a soc specific compatible
+  string that should be present along with the "qcom,smmu-v2"
+  to facilitate SoC specific clocks/power connections and to
+  address specific bug fixes.
+  An example string would be -
+  "qcom,msm8996-smmu-v2", "qcom,smmu-v2".
+
 - reg   : Base address and size of the SMMU.
 
 - #global-interrupts : The number of global interrupts exposed by the
@@ -71,6 +80,23 @@ conditions.
   or using stream matching with #iommu-cells = <2>, and
   may be ignored if present in such cases.
 
+- clock-names:Should be "bus", and "iface" for "qcom,smmu-v2"
+  implementation.
+
+  "bus" clock for "qcom,smmu-v2" is required for downstream
+  bus access and for the smmu ptw.
+
+  "iface" clock is required to access smmu's registers through
+  the TCU's programming interface.
+
+- clocks: Phandles for respective clocks described by clock-names.
+
+- power-domains:  Phandles to SMMU's power domain specifier. This is
+  required even if SMMU belongs to the master's power
+  domain, as the SMMU will have to be enabled and
+  accessed before master gets enabled and linked to its
+  SMMU.
+
 ** Deprecated properties:
 
 - mmu-masters (deprecated in favour of the generic "iommus" binding) :
@@ -137,3 +163,20 @@ conditions.
 iommu-map = <0  0 0x400>;
 ...
 };
+
+   /* Qcom's arm,smmu-v2 implementation */
+   smmu4: iommu {
+   compatible = "qcom,msm8996-smmu-v2", "qcom,smmu-v2";
+   reg = <0xd0 0x1>;
+
+   #global-interrupts = <1>;
+   interrupts = ,
+,
+;
+   #iommu-cells = <1>;
+   power-domains = < MDSS_GDSC>;
+
+   clocks = < SMMU_MDP_AXI_CLK>,
+< SMMU_MDP_AHB_CLK>;
+   clock-names = "bus", "iface";
+   };
diff --git a/drivers/iommu/arm-smmu.c b/drivers/iommu/arm-smmu.c
index 33bbcfedb896..2ade214c41bc 100644
--- a/drivers/iommu/arm-smmu.c
+++ b/drivers/iommu/arm-smmu.c
@@ -119,6 +119,7 @@ enum arm_smmu_implementation {
GENERIC_SMMU,
ARM_MMU500,
CAVIUM_SMMUV2,
+   QCOM_SMMUV2,
 };
 
 struct arm_smmu_s2cr {
@@ -1971,6 +1972,17 @@ struct arm_smmu_match_data {
 ARM_SMMU_MATCH_DATA(arm_mmu500, ARM_SMMU_V2, ARM_MMU500);
 ARM_SMMU_MATCH_DATA(cavium_smmuv2, ARM_SMMU_V2, CAVIUM_SMMUV2);
 
+static const char * const qcom_smmuv2_clks[] = {
+   "bus", "iface",
+};
+
+static const struct arm_smmu_match_data qcom_smmuv2 = {
+   .version = ARM_SMMU_V2,
+   .model = QCOM_SMMUV2,
+   .clks = qcom_smmuv2_clks,
+   .num_clks = ARRAY_SIZE(qcom_smmuv2_clks),
+};
+
 static const struct of_device_id arm_smmu_of_match[] = {
{ .compatible = "arm,smmu-v1", .data = _generic_v1 },
{ .compatible = "arm,smmu-v2", .data = _generic_v2 },
@@ -1978,6 +1990,7 @@ struct arm_smmu_match_data {
{ .compatible = "arm,mmu-401", .data = _mmu401 },
{ .compatible = "arm,mmu-500", .data = _mmu500 },
{ .compatible = "cavium,smmu-v2", .data = _smmuv2 },
+   { .compatible = "qcom,smmu-v2", .data = _smmuv2 },
{ },
 };
 MODULE_DEVICE_TABLE(of, arm_smmu_of_match);
-- 
QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member
of Code Aurora Forum, hosted by The Linux Foundation

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


[PATCH v6 6/6] drm/msm: iommu: Replace runtime calls with runtime suppliers

2018-01-19 Thread Vivek Gautam
While handling the concerned iommu, there should not be a
need to power control the drm devices from iommu interface.
If these drm devices need to be powered around this time,
the respective drivers should take care of this.

Replace the pm_runtime_get/put_sync() with
pm_runtime_get/put_suppliers() calls, to power-up
the connected iommu through the device link interface.
In case the device link is not setup these get/put_suppliers()
calls will be a no-op, and the iommu driver should take care of
powering on its devices accordingly.

Signed-off-by: Vivek Gautam <vivek.gau...@codeaurora.org>
---
 drivers/gpu/drm/msm/msm_iommu.c | 16 
 1 file changed, 8 insertions(+), 8 deletions(-)

diff --git a/drivers/gpu/drm/msm/msm_iommu.c b/drivers/gpu/drm/msm/msm_iommu.c
index b23d33622f37..1ab629bbee69 100644
--- a/drivers/gpu/drm/msm/msm_iommu.c
+++ b/drivers/gpu/drm/msm/msm_iommu.c
@@ -40,9 +40,9 @@ static int msm_iommu_attach(struct msm_mmu *mmu, const char * 
const *names,
struct msm_iommu *iommu = to_msm_iommu(mmu);
int ret;
 
-   pm_runtime_get_sync(mmu->dev);
+   pm_runtime_get_suppliers(mmu->dev);
ret = iommu_attach_device(iommu->domain, mmu->dev);
-   pm_runtime_put_sync(mmu->dev);
+   pm_runtime_put_suppliers(mmu->dev);
 
return ret;
 }
@@ -52,9 +52,9 @@ static void msm_iommu_detach(struct msm_mmu *mmu, const char 
* const *names,
 {
struct msm_iommu *iommu = to_msm_iommu(mmu);
 
-   pm_runtime_get_sync(mmu->dev);
+   pm_runtime_get_suppliers(mmu->dev);
iommu_detach_device(iommu->domain, mmu->dev);
-   pm_runtime_put_sync(mmu->dev);
+   pm_runtime_put_suppliers(mmu->dev);
 }
 
 static int msm_iommu_map(struct msm_mmu *mmu, uint64_t iova,
@@ -63,9 +63,9 @@ static int msm_iommu_map(struct msm_mmu *mmu, uint64_t iova,
struct msm_iommu *iommu = to_msm_iommu(mmu);
size_t ret;
 
-// pm_runtime_get_sync(mmu->dev);
+   pm_runtime_get_suppliers(mmu->dev);
ret = iommu_map_sg(iommu->domain, iova, sgt->sgl, sgt->nents, prot);
-// pm_runtime_put_sync(mmu->dev);
+   pm_runtime_put_suppliers(mmu->dev);
WARN_ON(ret < 0);
 
return (ret == len) ? 0 : -EINVAL;
@@ -76,9 +76,9 @@ static int msm_iommu_unmap(struct msm_mmu *mmu, uint64_t iova,
 {
struct msm_iommu *iommu = to_msm_iommu(mmu);
 
-   pm_runtime_get_sync(mmu->dev);
+   pm_runtime_get_suppliers(mmu->dev);
iommu_unmap(iommu->domain, iova, len);
-   pm_runtime_put_sync(mmu->dev);
+   pm_runtime_put_suppliers(mmu->dev);
 
return 0;
 }
-- 
QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member
of Code Aurora Forum, hosted by The Linux Foundation

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


[PATCH v6 1/6] base: power: runtime: Export pm_runtime_get/put_suppliers

2018-01-19 Thread Vivek Gautam
The device link allows the pm framework to tie the supplier and
consumer. So, whenever the consumer is powered-on the supplier
is powered-on first.

There are however cases in which the consumer wants to power-on
the supplier, but not itself.
E.g., A Graphics or multimedia driver wants to power-on the SMMU
to unmap a buffer and finish the TLB operations without powering
on itself. Some of these unmap requests are coming from the
user space when the controller itself is not powered-up, and it
can be huge penalty in terms of power and latency to power-up
the graphics/mm controllers.
There can be an argument that the supplier should handle this case
on its own and there should not be a need for the consumer to
power-on the supplier. But as discussed on the thread [1] about
ARM-SMMU runtime pm, we don't want to introduce runtime pm calls
in atomic path in arm_smmu_unmap.

[1] https://patchwork.kernel.org/patch/9827825/

Signed-off-by: Vivek Gautam <vivek.gau...@codeaurora.org>
Acked-by: Rafael J. Wysocki <rafael.j.wyso...@intel.com>
---
 drivers/base/power/runtime.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/base/power/runtime.c b/drivers/base/power/runtime.c
index 6e89b51ea3d9..06a2a88fe866 100644
--- a/drivers/base/power/runtime.c
+++ b/drivers/base/power/runtime.c
@@ -1579,6 +1579,7 @@ void pm_runtime_get_suppliers(struct device *dev)
 
device_links_read_unlock(idx);
 }
+EXPORT_SYMBOL_GPL(pm_runtime_get_suppliers);
 
 /**
  * pm_runtime_put_suppliers - Drop references to supplier devices.
@@ -1597,6 +1598,7 @@ void pm_runtime_put_suppliers(struct device *dev)
 
device_links_read_unlock(idx);
 }
+EXPORT_SYMBOL_GPL(pm_runtime_put_suppliers);
 
 void pm_runtime_new_link(struct device *dev)
 {
-- 
QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member
of Code Aurora Forum, hosted by The Linux Foundation

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


[PATCH v6 2/6] iommu/arm-smmu: Add pm_runtime/sleep ops

2018-01-19 Thread Vivek Gautam
From: Sricharan R <sricha...@codeaurora.org>

The smmu needs to be functional only when the respective
master's using it are active. The device_link feature
helps to track such functional dependencies, so that the
iommu gets powered when the master device enables itself
using pm_runtime. So by adapting the smmu driver for
runtime pm, above said dependency can be addressed.

This patch adds the pm runtime/sleep callbacks to the
driver and also the functions to parse the smmu clocks
from DT and enable them in resume/suspend.

Signed-off-by: Sricharan R <sricha...@codeaurora.org>
Signed-off-by: Archit Taneja <arch...@codeaurora.org>
[vivek: Clock rework to request bulk of clocks]
Signed-off-by: Vivek Gautam <vivek.gau...@codeaurora.org>
---
 drivers/iommu/arm-smmu.c | 55 ++--
 1 file changed, 53 insertions(+), 2 deletions(-)

diff --git a/drivers/iommu/arm-smmu.c b/drivers/iommu/arm-smmu.c
index 78d4c6b8f1ba..21acffe91a1c 100644
--- a/drivers/iommu/arm-smmu.c
+++ b/drivers/iommu/arm-smmu.c
@@ -48,6 +48,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 
@@ -205,6 +206,9 @@ struct arm_smmu_device {
u32 num_global_irqs;
u32 num_context_irqs;
unsigned int*irqs;
+   struct clk_bulk_data*clocks;
+   int num_clks;
+   const char * const  *clk_names;
 
u32 cavium_id_base; /* Specific to Cavium */
 
@@ -1685,6 +1689,25 @@ static int arm_smmu_id_size_to_bits(int size)
}
 }
 
+static int arm_smmu_init_clocks(struct arm_smmu_device *smmu)
+{
+   int i;
+   int num = smmu->num_clks;
+
+   if (num < 1)
+   return 0;
+
+   smmu->clocks = devm_kcalloc(smmu->dev, num,
+   sizeof(*smmu->clocks), GFP_KERNEL);
+   if (!smmu->clocks)
+   return -ENOMEM;
+
+   for (i = 0; i < num; i++)
+   smmu->clocks[i].id = smmu->clk_names[i];
+
+   return devm_clk_bulk_get(smmu->dev, num, smmu->clocks);
+}
+
 static int arm_smmu_device_cfg_probe(struct arm_smmu_device *smmu)
 {
unsigned long size;
@@ -1897,10 +1920,12 @@ static int arm_smmu_device_cfg_probe(struct 
arm_smmu_device *smmu)
 struct arm_smmu_match_data {
enum arm_smmu_arch_version version;
enum arm_smmu_implementation model;
+   const char * const *clks;
+   int num_clks;
 };
 
 #define ARM_SMMU_MATCH_DATA(name, ver, imp)\
-static struct arm_smmu_match_data name = { .version = ver, .model = imp }
+static const struct arm_smmu_match_data name = { .version = ver, .model = imp }
 
 ARM_SMMU_MATCH_DATA(smmu_generic_v1, ARM_SMMU_V1, GENERIC_SMMU);
 ARM_SMMU_MATCH_DATA(smmu_generic_v2, ARM_SMMU_V2, GENERIC_SMMU);
@@ -2001,6 +2026,8 @@ static int arm_smmu_device_dt_probe(struct 
platform_device *pdev,
data = of_device_get_match_data(dev);
smmu->version = data->version;
smmu->model = data->model;
+   smmu->clk_names = data->clks;
+   smmu->num_clks = data->num_clks;
 
parse_driver_options(smmu);
 
@@ -2099,6 +2126,10 @@ static int arm_smmu_device_probe(struct platform_device 
*pdev)
smmu->irqs[i] = irq;
}
 
+   err = arm_smmu_init_clocks(smmu);
+   if (err)
+   return err;
+
err = arm_smmu_device_cfg_probe(smmu);
if (err)
return err;
@@ -2197,7 +2228,27 @@ static int __maybe_unused arm_smmu_pm_resume(struct 
device *dev)
return 0;
 }
 
-static SIMPLE_DEV_PM_OPS(arm_smmu_pm_ops, NULL, arm_smmu_pm_resume);
+static int __maybe_unused arm_smmu_runtime_resume(struct device *dev)
+{
+   struct arm_smmu_device *smmu = dev_get_drvdata(dev);
+
+   return clk_bulk_prepare_enable(smmu->num_clks, smmu->clocks);
+}
+
+static int __maybe_unused arm_smmu_runtime_suspend(struct device *dev)
+{
+   struct arm_smmu_device *smmu = dev_get_drvdata(dev);
+
+   clk_bulk_disable_unprepare(smmu->num_clks, smmu->clocks);
+
+   return 0;
+}
+
+static const struct dev_pm_ops arm_smmu_pm_ops = {
+   SET_SYSTEM_SLEEP_PM_OPS(NULL, arm_smmu_pm_resume)
+   SET_RUNTIME_PM_OPS(arm_smmu_runtime_suspend,
+  arm_smmu_runtime_resume, NULL)
+};
 
 static struct platform_driver arm_smmu_driver = {
.driver = {
-- 
QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member
of Code Aurora Forum, hosted by The Linux Foundation

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


[PATCH v5 4/6] iommu/arm-smmu: Add the device_link between masters and smmu

2018-01-10 Thread Vivek Gautam
From: Sricharan R 

Finally add the device link between the master device and
smmu, so that the smmu gets runtime enabled/disabled only when the
master needs it. This is done from add_device callback which gets
called once when the master is added to the smmu.

Signed-off-by: Sricharan R 
---
 drivers/iommu/arm-smmu.c | 11 +++
 1 file changed, 11 insertions(+)

diff --git a/drivers/iommu/arm-smmu.c b/drivers/iommu/arm-smmu.c
index 95478bfb182c..33bbcfedb896 100644
--- a/drivers/iommu/arm-smmu.c
+++ b/drivers/iommu/arm-smmu.c
@@ -1367,6 +1367,7 @@ static int arm_smmu_add_device(struct device *dev)
struct arm_smmu_device *smmu;
struct arm_smmu_master_cfg *cfg;
struct iommu_fwspec *fwspec = dev->iommu_fwspec;
+   struct device_link *link;
int i, ret;
 
if (using_legacy_binding) {
@@ -1428,6 +1429,16 @@ static int arm_smmu_add_device(struct device *dev)
 
pm_runtime_put_sync(smmu->dev);
 
+   /*
+* Establish the link between smmu and master, so that the
+* smmu gets runtime enabled/disabled as per the master's
+* needs.
+*/
+   link = device_link_add(dev, smmu->dev, DL_FLAG_PM_RUNTIME);
+   if (!link)
+   dev_warn(smmu->dev, "Unable to create device link between %s 
and %s\n",
+dev_name(smmu->dev), dev_name(dev));
+
return 0;
 
 out_cfg_free:
-- 
QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member
of Code Aurora Forum, hosted by The Linux Foundation

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


[PATCH v5 5/6] iommu/arm-smmu: Add support for qcom,smmu-v2 variant

2018-01-10 Thread Vivek Gautam
qcom,smmu-v2 is an arm,smmu-v2 implementation with specific
clock and power requirements. This smmu core is used with
multiple masters on msm8996, viz. mdss, video, etc.
Add bindings for the same.

Signed-off-by: Vivek Gautam <vivek.gau...@codeaurora.org>
---

 * Major change in this patch -
   Changed compatible string from 'qcom,msm8996-smmu-v2' to
   'qcom,smmu-v2' to reflect the IP version rather than the
   platform on which it is used.
   The same IP is used across multiple platforms including msm8996,
   and sdm845 etc.

 .../devicetree/bindings/iommu/arm,smmu.txt | 35 ++
 drivers/iommu/arm-smmu.c   | 13 
 2 files changed, 48 insertions(+)

diff --git a/Documentation/devicetree/bindings/iommu/arm,smmu.txt 
b/Documentation/devicetree/bindings/iommu/arm,smmu.txt
index 8a6ffce12af5..e4951288c87c 100644
--- a/Documentation/devicetree/bindings/iommu/arm,smmu.txt
+++ b/Documentation/devicetree/bindings/iommu/arm,smmu.txt
@@ -17,6 +17,7 @@ conditions.
 "arm,mmu-401"
 "arm,mmu-500"
 "cavium,smmu-v2"
+"qcom,smmu-v2"
 
   depending on the particular implementation and/or the
   version of the architecture implemented.
@@ -71,6 +72,23 @@ conditions.
   or using stream matching with #iommu-cells = <2>, and
   may be ignored if present in such cases.
 
+- clock-names:Should be "bus", and "iface" for "qcom,smmu-v2"
+  implementation.
+
+  "bus" clock for "qcom,smmu-v2" is required for downstream
+  bus access and for the smmu ptw.
+
+  "iface" clock is required to access smmu's registers through
+  the TCU's programming interface.
+
+- clocks: Phandles for respective clocks described by clock-names.
+
+- power-domains:  Phandles to SMMU's power domain specifier. This is
+  required even if SMMU belongs to the master's power
+  domain, as the SMMU will have to be enabled and
+  accessed before master gets enabled and linked to its
+  SMMU.
+
 ** Deprecated properties:
 
 - mmu-masters (deprecated in favour of the generic "iommus" binding) :
@@ -137,3 +155,20 @@ conditions.
 iommu-map = <0  0 0x400>;
 ...
 };
+
+   /* Qcom's arm,smmu-v2 implementation */
+   smmu4: iommu {
+   compatible = "qcom,smmu-v2";
+   reg = <0xd0 0x1>;
+
+   #global-interrupts = <1>;
+   interrupts = ,
+,
+;
+   #iommu-cells = <1>;
+   power-domains = < MDSS_GDSC>;
+
+   clocks = < SMMU_MDP_AXI_CLK>,
+< SMMU_MDP_AHB_CLK>;
+   clock-names = "bus", "iface";
+   };
diff --git a/drivers/iommu/arm-smmu.c b/drivers/iommu/arm-smmu.c
index 33bbcfedb896..2ade214c41bc 100644
--- a/drivers/iommu/arm-smmu.c
+++ b/drivers/iommu/arm-smmu.c
@@ -119,6 +119,7 @@ enum arm_smmu_implementation {
GENERIC_SMMU,
ARM_MMU500,
CAVIUM_SMMUV2,
+   QCOM_SMMUV2,
 };
 
 struct arm_smmu_s2cr {
@@ -1971,6 +1972,17 @@ struct arm_smmu_match_data {
 ARM_SMMU_MATCH_DATA(arm_mmu500, ARM_SMMU_V2, ARM_MMU500);
 ARM_SMMU_MATCH_DATA(cavium_smmuv2, ARM_SMMU_V2, CAVIUM_SMMUV2);
 
+static const char * const qcom_smmuv2_clks[] = {
+   "bus", "iface",
+};
+
+static const struct arm_smmu_match_data qcom_smmuv2 = {
+   .version = ARM_SMMU_V2,
+   .model = QCOM_SMMUV2,
+   .clks = qcom_smmuv2_clks,
+   .num_clks = ARRAY_SIZE(qcom_smmuv2_clks),
+};
+
 static const struct of_device_id arm_smmu_of_match[] = {
{ .compatible = "arm,smmu-v1", .data = _generic_v1 },
{ .compatible = "arm,smmu-v2", .data = _generic_v2 },
@@ -1978,6 +1990,7 @@ struct arm_smmu_match_data {
{ .compatible = "arm,mmu-401", .data = _mmu401 },
{ .compatible = "arm,mmu-500", .data = _mmu500 },
{ .compatible = "cavium,smmu-v2", .data = _smmuv2 },
+   { .compatible = "qcom,smmu-v2", .data = _smmuv2 },
{ },
 };
 MODULE_DEVICE_TABLE(of, arm_smmu_of_match);
-- 
QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member
of Code Aurora Forum, hosted by The Linux Foundation

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


[PATCH v5 0/6] iommu/arm-smmu: Add runtime pm/sleep support

2018-01-10 Thread Vivek Gautam
This series provides the support for turning on the arm-smmu's
clocks/power domains using runtime pm. This is done using the
recently introduced device links patches, which lets the smmu's
runtime to follow the master's runtime pm, so the smmu remains
powered only when the masters use it.

It also adds support for Qcom's arm-smmu-v2 variant that
has different clocks and power requirements.

Took some reference from the exynos runtime patches [2].

Previous version of the patchset [1].

After much discussion [4] over the use of pm_runtime_get/put() in
.unmap op path for the arm-smmu, and after disussing over more than
a couple of approaches to address this, we are putting forward the
changes *without* using pm_runtime APIs in 'unmap'. Rather, letting
the client device take the control of powering on/off the connected
iommu through pm_runtime_get(put)_suppliers() APIs for the scnerios
when the iommu power can't be directly controlled by clients through
device links.
Rafael has agreed to export the suppliers APIs [5].

[V5]
   * Dropped runtime pm calls from "arm_smmu_unmap" op as discussed over
 the list [4] for the last patch series.
   * Added a patch to export pm_runtime_get/put_suppliers() APIs to the
 series as agreed with Rafael [5].
   * Added the related patch for msm drm iommu layer to use
 pm_runtime_get/put_suppliers() APIs in msm_mmu_funcs.
   * Dropped arm-mmu500 clock patch since that would break existing
 platforms.
   * Changed compatible 'qcom,msm8996-smmu-v2' to 'qcom,smmu-v2' to reflect
 the IP version rather than the platform on which it is used.
 The same IP is used across multiple platforms including msm8996,
 and sdm845 etc.
   * Using clock bulk APIs to handle the clocks available to the IP as
 suggested by Stephen Boyd.
   * The first patch in v4 version of the patch-series:
 ("iommu/arm-smmu: Fix the error path in arm_smmu_add_device") has
 already made it to mainline.

[V4]
   * Reworked the clock handling part. We now take clock names as data
 in the driver for supported compatible versions, and loop over them
 to get, enable, and disable the clocks.
   * Using qcom,msm8996 based compatibles for bindings instead of a generic
 qcom compatible.
   * Refactor MMU500 patch to just add the necessary clock names data and
 corresponding bindings.
   * Added the pm_runtime_get/put() calls in .unmap iommu op (fix added by
 Stanimir on top of previous patch version.
   * Added a patch to fix error path in arm_smmu_add_device()
   * Removed patch 3/5 of V3 patch series that added qcom,smmu-v2 bindings.

[V3]
   * Reworked the patches to keep the clocks init/enabling function
 separately for each compatible.

   * Added clocks bindings for MMU40x/500.

   * Added a new compatible for qcom,smmu-v2 implementation and
 the clock bindings for the same.

   * Rebased on top of 4.11-rc1

[V2]
   * Split the patches little differently.

   * Addressed comments.

   * Removed the patch #4 [3] from previous post
 for arm-smmu context save restore. Planning to
 post this separately after reworking/addressing Robin's
 feedback.

   * Reversed the sequence to disable clocks than enabling.
 This was required for those cases where the
 clocks are populated in a dependent order from DT.

[1] https://www.spinics.net/lists/arm-kernel/msg567488.html
[2] https://lkml.org/lkml/2016/10/20/70
[3] https://patchwork.kernel.org/patch/9389717/
[4] https://patchwork.kernel.org/patch/9827825/
[5] https://patchwork.kernel.org/patch/10102445/

Sricharan R (3):
  iommu/arm-smmu: Add pm_runtime/sleep ops
  iommu/arm-smmu: Invoke pm_runtime during probe, add/remove device
  iommu/arm-smmu: Add the device_link between masters and smmu

Vivek Gautam (3):
  base: power: runtime: Export pm_runtime_get/put_suppliers
  iommu/arm-smmu: Add support for qcom,smmu-v2 variant
  drm/msm: iommu: Replace runtime calls with runtime suppliers

 .../devicetree/bindings/iommu/arm,smmu.txt |  35 ++
 drivers/base/power/runtime.c   |   2 +
 drivers/gpu/drm/msm/msm_iommu.c|  16 +--
 drivers/iommu/arm-smmu.c   | 124 -
 4 files changed, 163 insertions(+), 14 deletions(-)

-- 
QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member
of Code Aurora Forum, hosted by The Linux Foundation

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


[PATCH v5 1/6] base: power: runtime: Export pm_runtime_get/put_suppliers

2018-01-10 Thread Vivek Gautam
The device link allows the pm framework to tie the supplier and
consumer. So, whenever the consumer is powered-on the supplier
is powered-on first.

There are however cases in which the consumer wants to power-on
the supplier, but not itself.
E.g., A Graphics or multimedia driver wants to power-on the SMMU
to unmap a buffer and finish the TLB operations without powering
on itself. Some of these unmap requests are coming from the
user space when the controller itself is not powered-up, and it
can be huge penalty in terms of power and latency to power-up
the graphics/mm controllers.
There can be an argument that the supplier should handle this case
on its own and there should not be a need for the consumer to
power-on the supplier. But as discussed on the thread [1] about
ARM-SMMU runtime pm, we don't want to introduce runtime pm calls
in atomic path in arm_smmu_unmap.

[1] https://patchwork.kernel.org/patch/9827825/

Signed-off-by: Vivek Gautam <vivek.gau...@codeaurora.org>
---

 * This is v2 of the patch [1]. Adding it to this patch series.
   [1] https://patchwork.kernel.org/patch/10102447/

 drivers/base/power/runtime.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/base/power/runtime.c b/drivers/base/power/runtime.c
index 6e89b51ea3d9..06a2a88fe866 100644
--- a/drivers/base/power/runtime.c
+++ b/drivers/base/power/runtime.c
@@ -1579,6 +1579,7 @@ void pm_runtime_get_suppliers(struct device *dev)
 
device_links_read_unlock(idx);
 }
+EXPORT_SYMBOL_GPL(pm_runtime_get_suppliers);
 
 /**
  * pm_runtime_put_suppliers - Drop references to supplier devices.
@@ -1597,6 +1598,7 @@ void pm_runtime_put_suppliers(struct device *dev)
 
device_links_read_unlock(idx);
 }
+EXPORT_SYMBOL_GPL(pm_runtime_put_suppliers);
 
 void pm_runtime_new_link(struct device *dev)
 {
-- 
QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member
of Code Aurora Forum, hosted by The Linux Foundation

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


[PATCH v5 3/6] iommu/arm-smmu: Invoke pm_runtime during probe, add/remove device

2018-01-10 Thread Vivek Gautam
From: Sricharan R <sricha...@codeaurora.org>

The smmu device probe/remove and add/remove master device callbacks
gets called when the smmu is not linked to its master, that is without
the context of the master device. So calling runtime apis in those places
separately.

Signed-off-by: Sricharan R <sricha...@codeaurora.org>
[vivek: Cleanup pm runtime calls]
Signed-off-by: Vivek Gautam <vivek.gau...@codeaurora.org>
---
 drivers/iommu/arm-smmu.c | 45 +
 1 file changed, 41 insertions(+), 4 deletions(-)

diff --git a/drivers/iommu/arm-smmu.c b/drivers/iommu/arm-smmu.c
index 21acffe91a1c..95478bfb182c 100644
--- a/drivers/iommu/arm-smmu.c
+++ b/drivers/iommu/arm-smmu.c
@@ -914,11 +914,15 @@ static void arm_smmu_destroy_domain_context(struct 
iommu_domain *domain)
struct arm_smmu_domain *smmu_domain = to_smmu_domain(domain);
struct arm_smmu_device *smmu = smmu_domain->smmu;
struct arm_smmu_cfg *cfg = _domain->cfg;
-   int irq;
+   int ret, irq;
 
if (!smmu || domain->type == IOMMU_DOMAIN_IDENTITY)
return;
 
+   ret = pm_runtime_get_sync(smmu->dev);
+   if (ret)
+   return;
+
/*
 * Disable the context bank and free the page tables before freeing
 * it.
@@ -933,6 +937,8 @@ static void arm_smmu_destroy_domain_context(struct 
iommu_domain *domain)
 
free_io_pgtable_ops(smmu_domain->pgtbl_ops);
__arm_smmu_free_bitmap(smmu->context_map, cfg->cbndx);
+
+   pm_runtime_put_sync(smmu->dev);
 }
 
 static struct iommu_domain *arm_smmu_domain_alloc(unsigned type)
@@ -1408,12 +1414,20 @@ static int arm_smmu_add_device(struct device *dev)
while (i--)
cfg->smendx[i] = INVALID_SMENDX;
 
-   ret = arm_smmu_master_alloc_smes(dev);
+   ret = pm_runtime_get_sync(smmu->dev);
if (ret)
goto out_cfg_free;
 
+   ret = arm_smmu_master_alloc_smes(dev);
+   if (ret) {
+   pm_runtime_put_sync(smmu->dev);
+   goto out_cfg_free;
+   }
+
iommu_device_link(>iommu, dev);
 
+   pm_runtime_put_sync(smmu->dev);
+
return 0;
 
 out_cfg_free:
@@ -1428,7 +1442,7 @@ static void arm_smmu_remove_device(struct device *dev)
struct iommu_fwspec *fwspec = dev->iommu_fwspec;
struct arm_smmu_master_cfg *cfg;
struct arm_smmu_device *smmu;
-
+   int ret;
 
if (!fwspec || fwspec->ops != _smmu_ops)
return;
@@ -1436,8 +1450,21 @@ static void arm_smmu_remove_device(struct device *dev)
cfg  = fwspec->iommu_priv;
smmu = cfg->smmu;
 
+   /*
+* The device link between the master device and
+* smmu is already purged at this point.
+* So enable the power to smmu explicitly.
+*/
+
+   ret = pm_runtime_get_sync(smmu->dev);
+   if (ret)
+   return;
+
iommu_device_unlink(>iommu, dev);
arm_smmu_master_free_smes(fwspec);
+
+   pm_runtime_put_sync(smmu->dev);
+
iommu_group_remove_device(dev);
kfree(fwspec->iommu_priv);
iommu_fwspec_free(dev);
@@ -2130,6 +2157,14 @@ static int arm_smmu_device_probe(struct platform_device 
*pdev)
if (err)
return err;
 
+   platform_set_drvdata(pdev, smmu);
+
+   pm_runtime_enable(dev);
+
+   err = pm_runtime_get_sync(dev);
+   if (err)
+   return err;
+
err = arm_smmu_device_cfg_probe(smmu);
if (err)
return err;
@@ -2171,9 +2206,9 @@ static int arm_smmu_device_probe(struct platform_device 
*pdev)
return err;
}
 
-   platform_set_drvdata(pdev, smmu);
arm_smmu_device_reset(smmu);
arm_smmu_test_smr_masks(smmu);
+   pm_runtime_put_sync(dev);
 
/*
 * For ACPI and generic DT bindings, an SMMU will be probed before
@@ -2212,6 +2247,8 @@ static int arm_smmu_device_remove(struct platform_device 
*pdev)
 
/* Turn the thing off */
writel(sCR0_CLIENTPD, ARM_SMMU_GR0_NS(smmu) + ARM_SMMU_GR0_sCR0);
+   pm_runtime_force_suspend(smmu->dev);
+
return 0;
 }
 
-- 
QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member
of Code Aurora Forum, hosted by The Linux Foundation

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


[PATCH v5 6/6] drm/msm: iommu: Replace runtime calls with runtime suppliers

2018-01-10 Thread Vivek Gautam
While handling the concerned iommu, there should not be a
need to power control the drm devices from iommu interface.
If these drm devices need to be powered around this time,
the respective drivers should take care of this.

Replace the pm_runtime_get/put_sync() with
pm_runtime_get/put_suppliers() calls, to power-up
the connected iommu through the device link interface.
In case the device link is not setup these get/put_suppliers()
calls will be a no-op, and the iommu driver should take care of
powering on its devices accordingly.

Signed-off-by: Vivek Gautam <vivek.gau...@codeaurora.org>
---

 * New patch added in this series for client side change for using
   pm_runtime_get_suppliers() and pm_runtime_put_suppliers().

 drivers/gpu/drm/msm/msm_iommu.c | 16 
 1 file changed, 8 insertions(+), 8 deletions(-)

diff --git a/drivers/gpu/drm/msm/msm_iommu.c b/drivers/gpu/drm/msm/msm_iommu.c
index b23d33622f37..1ab629bbee69 100644
--- a/drivers/gpu/drm/msm/msm_iommu.c
+++ b/drivers/gpu/drm/msm/msm_iommu.c
@@ -40,9 +40,9 @@ static int msm_iommu_attach(struct msm_mmu *mmu, const char * 
const *names,
struct msm_iommu *iommu = to_msm_iommu(mmu);
int ret;
 
-   pm_runtime_get_sync(mmu->dev);
+   pm_runtime_get_suppliers(mmu->dev);
ret = iommu_attach_device(iommu->domain, mmu->dev);
-   pm_runtime_put_sync(mmu->dev);
+   pm_runtime_put_suppliers(mmu->dev);
 
return ret;
 }
@@ -52,9 +52,9 @@ static void msm_iommu_detach(struct msm_mmu *mmu, const char 
* const *names,
 {
struct msm_iommu *iommu = to_msm_iommu(mmu);
 
-   pm_runtime_get_sync(mmu->dev);
+   pm_runtime_get_suppliers(mmu->dev);
iommu_detach_device(iommu->domain, mmu->dev);
-   pm_runtime_put_sync(mmu->dev);
+   pm_runtime_put_suppliers(mmu->dev);
 }
 
 static int msm_iommu_map(struct msm_mmu *mmu, uint64_t iova,
@@ -63,9 +63,9 @@ static int msm_iommu_map(struct msm_mmu *mmu, uint64_t iova,
struct msm_iommu *iommu = to_msm_iommu(mmu);
size_t ret;
 
-// pm_runtime_get_sync(mmu->dev);
+   pm_runtime_get_suppliers(mmu->dev);
ret = iommu_map_sg(iommu->domain, iova, sgt->sgl, sgt->nents, prot);
-// pm_runtime_put_sync(mmu->dev);
+   pm_runtime_put_suppliers(mmu->dev);
WARN_ON(ret < 0);
 
return (ret == len) ? 0 : -EINVAL;
@@ -76,9 +76,9 @@ static int msm_iommu_unmap(struct msm_mmu *mmu, uint64_t iova,
 {
struct msm_iommu *iommu = to_msm_iommu(mmu);
 
-   pm_runtime_get_sync(mmu->dev);
+   pm_runtime_get_suppliers(mmu->dev);
iommu_unmap(iommu->domain, iova, len);
-   pm_runtime_put_sync(mmu->dev);
+   pm_runtime_put_suppliers(mmu->dev);
 
return 0;
 }
-- 
QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member
of Code Aurora Forum, hosted by The Linux Foundation

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


[PATCH v5 2/6] iommu/arm-smmu: Add pm_runtime/sleep ops

2018-01-10 Thread Vivek Gautam
From: Sricharan R <sricha...@codeaurora.org>

The smmu needs to be functional only when the respective
master's using it are active. The device_link feature
helps to track such functional dependencies, so that the
iommu gets powered when the master device enables itself
using pm_runtime. So by adapting the smmu driver for
runtime pm, above said dependency can be addressed.

This patch adds the pm runtime/sleep callbacks to the
driver and also the functions to parse the smmu clocks
from DT and enable them in resume/suspend.

Signed-off-by: Sricharan R <sricha...@codeaurora.org>
Signed-off-by: Archit Taneja <arch...@codeaurora.org>
[vivek: Clock rework to request bulk of clocks]
Signed-off-by: Vivek Gautam <vivek.gau...@codeaurora.org>
---
 drivers/iommu/arm-smmu.c | 55 ++--
 1 file changed, 53 insertions(+), 2 deletions(-)

diff --git a/drivers/iommu/arm-smmu.c b/drivers/iommu/arm-smmu.c
index 78d4c6b8f1ba..21acffe91a1c 100644
--- a/drivers/iommu/arm-smmu.c
+++ b/drivers/iommu/arm-smmu.c
@@ -48,6 +48,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 
@@ -205,6 +206,9 @@ struct arm_smmu_device {
u32 num_global_irqs;
u32 num_context_irqs;
unsigned int*irqs;
+   struct clk_bulk_data*clocks;
+   int num_clks;
+   const char * const  *clk_names;
 
u32 cavium_id_base; /* Specific to Cavium */
 
@@ -1685,6 +1689,25 @@ static int arm_smmu_id_size_to_bits(int size)
}
 }
 
+static int arm_smmu_init_clocks(struct arm_smmu_device *smmu)
+{
+   int i;
+   int num = smmu->num_clks;
+
+   if (num < 1)
+   return 0;
+
+   smmu->clocks = devm_kcalloc(smmu->dev, num,
+   sizeof(*smmu->clocks), GFP_KERNEL);
+   if (!smmu->clocks)
+   return -ENOMEM;
+
+   for (i = 0; i < num; i++)
+   smmu->clocks[i].id = smmu->clk_names[i];
+
+   return devm_clk_bulk_get(smmu->dev, num, smmu->clocks);
+}
+
 static int arm_smmu_device_cfg_probe(struct arm_smmu_device *smmu)
 {
unsigned long size;
@@ -1897,10 +1920,12 @@ static int arm_smmu_device_cfg_probe(struct 
arm_smmu_device *smmu)
 struct arm_smmu_match_data {
enum arm_smmu_arch_version version;
enum arm_smmu_implementation model;
+   const char * const *clks;
+   int num_clks;
 };
 
 #define ARM_SMMU_MATCH_DATA(name, ver, imp)\
-static struct arm_smmu_match_data name = { .version = ver, .model = imp }
+static const struct arm_smmu_match_data name = { .version = ver, .model = imp }
 
 ARM_SMMU_MATCH_DATA(smmu_generic_v1, ARM_SMMU_V1, GENERIC_SMMU);
 ARM_SMMU_MATCH_DATA(smmu_generic_v2, ARM_SMMU_V2, GENERIC_SMMU);
@@ -2001,6 +2026,8 @@ static int arm_smmu_device_dt_probe(struct 
platform_device *pdev,
data = of_device_get_match_data(dev);
smmu->version = data->version;
smmu->model = data->model;
+   smmu->clk_names = data->clks;
+   smmu->num_clks = data->num_clks;
 
parse_driver_options(smmu);
 
@@ -2099,6 +2126,10 @@ static int arm_smmu_device_probe(struct platform_device 
*pdev)
smmu->irqs[i] = irq;
}
 
+   err = arm_smmu_init_clocks(smmu);
+   if (err)
+   return err;
+
err = arm_smmu_device_cfg_probe(smmu);
if (err)
return err;
@@ -2197,7 +2228,27 @@ static int __maybe_unused arm_smmu_pm_resume(struct 
device *dev)
return 0;
 }
 
-static SIMPLE_DEV_PM_OPS(arm_smmu_pm_ops, NULL, arm_smmu_pm_resume);
+static int __maybe_unused arm_smmu_runtime_resume(struct device *dev)
+{
+   struct arm_smmu_device *smmu = dev_get_drvdata(dev);
+
+   return clk_bulk_prepare_enable(smmu->num_clks, smmu->clocks);
+}
+
+static int __maybe_unused arm_smmu_runtime_suspend(struct device *dev)
+{
+   struct arm_smmu_device *smmu = dev_get_drvdata(dev);
+
+   clk_bulk_disable_unprepare(smmu->num_clks, smmu->clocks);
+
+   return 0;
+}
+
+static const struct dev_pm_ops arm_smmu_pm_ops = {
+   SET_SYSTEM_SLEEP_PM_OPS(NULL, arm_smmu_pm_resume)
+   SET_RUNTIME_PM_OPS(arm_smmu_runtime_suspend,
+  arm_smmu_runtime_resume, NULL)
+};
 
 static struct platform_driver arm_smmu_driver = {
.driver = {
-- 
QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member
of Code Aurora Forum, hosted by The Linux Foundation

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


Re: [PATCH v5 0/6] iommu/arm-smmu: Add runtime pm/sleep support

2018-01-10 Thread Vivek Gautam



On 01/09/2018 04:53 PM, Rafael J. Wysocki wrote:

On Tuesday, January 9, 2018 11:01:43 AM CET Vivek Gautam wrote:

This series provides the support for turning on the arm-smmu's
clocks/power domains using runtime pm. This is done using the
recently introduced device links patches, which lets the smmu's
runtime to follow the master's runtime pm, so the smmu remains
powered only when the masters use it.

It also adds support for Qcom's arm-smmu-v2 variant that
has different clocks and power requirements.

Took some reference from the exynos runtime patches [2].

Previous version of the patchset [1].

After much discussion [4] over the use of pm_runtime_get/put() in
.unmap op path for the arm-smmu, and after disussing over more than
a couple of approaches to address this, we are putting forward the
changes *without* using pm_runtime APIs in 'unmap'. Rather, letting
the client device take the control of powering on/off the connected
iommu through pm_runtime_get(put)_suppliers() APIs for the scnerios
when the iommu power can't be directly controlled by clients through
device links.
Rafael has agreed to export the suppliers APIs [5].

[V5]
* Dropped runtime pm calls from "arm_smmu_unmap" op as discussed over
  the list [4] for the last patch series.
* Added a patch to export pm_runtime_get/put_suppliers() APIs to the
  series as agreed with Rafael [5].
* Added the related patch for msm drm iommu layer to use
  pm_runtime_get/put_suppliers() APIs in msm_mmu_funcs.
* Dropped arm-mmu500 clock patch since that would break existing
  platforms.
* Changed compatible 'qcom,msm8996-smmu-v2' to 'qcom,smmu-v2' to reflect
  the IP version rather than the platform on which it is used.
  The same IP is used across multiple platforms including msm8996,
  and sdm845 etc.
* Using clock bulk APIs to handle the clocks available to the IP as
  suggested by Stephen Boyd.
* The first patch in v4 version of the patch-series:
  ("iommu/arm-smmu: Fix the error path in arm_smmu_add_device") has
  already made it to mainline.

[V4]
* Reworked the clock handling part. We now take clock names as data
  in the driver for supported compatible versions, and loop over them
  to get, enable, and disable the clocks.
* Using qcom,msm8996 based compatibles for bindings instead of a generic
  qcom compatible.
* Refactor MMU500 patch to just add the necessary clock names data and
  corresponding bindings.
* Added the pm_runtime_get/put() calls in .unmap iommu op (fix added by
  Stanimir on top of previous patch version.
* Added a patch to fix error path in arm_smmu_add_device()
* Removed patch 3/5 of V3 patch series that added qcom,smmu-v2 bindings.

[V3]
* Reworked the patches to keep the clocks init/enabling function
  separately for each compatible.

* Added clocks bindings for MMU40x/500.

* Added a new compatible for qcom,smmu-v2 implementation and
  the clock bindings for the same.

* Rebased on top of 4.11-rc1

[V2]
* Split the patches little differently.

* Addressed comments.

* Removed the patch #4 [3] from previous post
  for arm-smmu context save restore. Planning to
  post this separately after reworking/addressing Robin's
  feedback.

* Reversed the sequence to disable clocks than enabling.
  This was required for those cases where the
  clocks are populated in a dependent order from DT.

[1] https://www.spinics.net/lists/arm-kernel/msg567488.html
[2] https://lkml.org/lkml/2016/10/20/70
[3] https://patchwork.kernel.org/patch/9389717/
[4] https://patchwork.kernel.org/patch/9827825/
[5] https://patchwork.kernel.org/patch/10102445/

Sricharan R (3):
   iommu/arm-smmu: Add pm_runtime/sleep ops
   iommu/arm-smmu: Invoke pm_runtime during probe, add/remove device
   iommu/arm-smmu: Add the device_link between masters and smmu

Vivek Gautam (3):
   base: power: runtime: Export pm_runtime_get/put_suppliers
   iommu/arm-smmu: Add support for qcom,smmu-v2 variant
   drm/msm: iommu: Replace runtime calls with runtime suppliers

  .../devicetree/bindings/iommu/arm,smmu.txt |  35 ++
  drivers/base/power/runtime.c   |   2 +
  drivers/gpu/drm/msm/msm_iommu.c|  16 +--
  drivers/iommu/arm-smmu.c   | 124 -
  4 files changed, 163 insertions(+), 14 deletions(-)

I need some time to review the series.


Sure, thanks Rafael.

regards
Vivek



Thanks,
Rafael

--
To unsubscribe from this list: send the line "unsubscribe linux-arm-msm" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


--
The Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
a Linux Foundation Collaborative Project

___
dri-devel mailing list
dri-dev

Re: [PATCH v5 1/6] base: power: runtime: Export pm_runtime_get/put_suppliers

2018-01-12 Thread Vivek Gautam



On 01/12/2018 04:23 AM, Rafael J. Wysocki wrote:

On Tue, Jan 9, 2018 at 11:01 AM, Vivek Gautam
<vivek.gau...@codeaurora.org> wrote:

The device link allows the pm framework to tie the supplier and
consumer. So, whenever the consumer is powered-on the supplier
is powered-on first.

There are however cases in which the consumer wants to power-on
the supplier, but not itself.
E.g., A Graphics or multimedia driver wants to power-on the SMMU
to unmap a buffer and finish the TLB operations without powering
on itself. Some of these unmap requests are coming from the
user space when the controller itself is not powered-up, and it
can be huge penalty in terms of power and latency to power-up
the graphics/mm controllers.
There can be an argument that the supplier should handle this case
on its own and there should not be a need for the consumer to
power-on the supplier. But as discussed on the thread [1] about
ARM-SMMU runtime pm, we don't want to introduce runtime pm calls
in atomic path in arm_smmu_unmap.

[1] https://patchwork.kernel.org/patch/9827825/

Signed-off-by: Vivek Gautam <vivek.gau...@codeaurora.org>

Acked-by: Rafael J. Wysocki <rafael.j.wyso...@intel.com>

Please feel free to route this along with the rest of the series.


Thanks Rafael.

regards
Vivek



Thanks!


---

  * This is v2 of the patch [1]. Adding it to this patch series.
[1] https://patchwork.kernel.org/patch/10102447/

  drivers/base/power/runtime.c | 2 ++
  1 file changed, 2 insertions(+)

diff --git a/drivers/base/power/runtime.c b/drivers/base/power/runtime.c
index 6e89b51ea3d9..06a2a88fe866 100644
--- a/drivers/base/power/runtime.c
+++ b/drivers/base/power/runtime.c
@@ -1579,6 +1579,7 @@ void pm_runtime_get_suppliers(struct device *dev)

 device_links_read_unlock(idx);
  }
+EXPORT_SYMBOL_GPL(pm_runtime_get_suppliers);

  /**
   * pm_runtime_put_suppliers - Drop references to supplier devices.
@@ -1597,6 +1598,7 @@ void pm_runtime_put_suppliers(struct device *dev)

 device_links_read_unlock(idx);
  }
+EXPORT_SYMBOL_GPL(pm_runtime_put_suppliers);

  void pm_runtime_new_link(struct device *dev)
  {
--
QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member
of Code Aurora Forum, hosted by The Linux Foundation


--
To unsubscribe from this list: send the line "unsubscribe linux-arm-msm" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


--
The Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
a Linux Foundation Collaborative Project

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


Re: [PATCH v5 5/6] iommu/arm-smmu: Add support for qcom,smmu-v2 variant

2018-01-12 Thread Vivek Gautam

Hi Rob,


On 01/12/2018 03:53 AM, Rob Herring wrote:

On Tue, Jan 09, 2018 at 03:31:48PM +0530, Vivek Gautam wrote:

qcom,smmu-v2 is an arm,smmu-v2 implementation with specific
clock and power requirements. This smmu core is used with
multiple masters on msm8996, viz. mdss, video, etc.
Add bindings for the same.

Signed-off-by: Vivek Gautam <vivek.gau...@codeaurora.org>
---

  * Major change in this patch -
Changed compatible string from 'qcom,msm8996-smmu-v2' to
'qcom,smmu-v2' to reflect the IP version rather than the
platform on which it is used.

The bugs and how things are connected are all the same? I'd suggest you
keep both strings.


Sure,
compatible = "qcom,msm8996-smmu-v2", "qcom,smmu-v2";




The same IP is used across multiple platforms including msm8996,
and sdm845 etc.

But for only 2 or so platforms a fallback is not really worth it. You'll
probably be on SMMUv3 before too long...

Right. There's msm8998 as well, but as you said keeping both strings
will make more sense.
Thanks.

Best regards
Vivek

[snip]

--
The Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
a Linux Foundation Collaborative Project

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


Re: [PATCH v6 3/6] iommu/arm-smmu: Invoke pm_runtime during probe, add/remove device

2018-02-01 Thread Vivek Gautam



On 2/1/2018 5:03 PM, Sricharan R wrote:

Hi Robin,

On 1/31/2018 6:36 PM, Robin Murphy wrote:

On 19/01/18 11:43, Vivek Gautam wrote:

From: Sricharan R <sricha...@codeaurora.org>

The smmu device probe/remove and add/remove master device callbacks
gets called when the smmu is not linked to its master, that is without
the context of the master device. So calling runtime apis in those places
separately.

Signed-off-by: Sricharan R <sricha...@codeaurora.org>
[vivek: Cleanup pm runtime calls]
Signed-off-by: Vivek Gautam <vivek.gau...@codeaurora.org>
---
   drivers/iommu/arm-smmu.c | 45 +
   1 file changed, 41 insertions(+), 4 deletions(-)

diff --git a/drivers/iommu/arm-smmu.c b/drivers/iommu/arm-smmu.c
index 21acffe91a1c..95478bfb182c 100644
--- a/drivers/iommu/arm-smmu.c
+++ b/drivers/iommu/arm-smmu.c
@@ -914,11 +914,15 @@ static void arm_smmu_destroy_domain_context(struct 
iommu_domain *domain)
   struct arm_smmu_domain *smmu_domain = to_smmu_domain(domain);
   struct arm_smmu_device *smmu = smmu_domain->smmu;
   struct arm_smmu_cfg *cfg = _domain->cfg;
-    int irq;
+    int ret, irq;
     if (!smmu || domain->type == IOMMU_DOMAIN_IDENTITY)
   return;
   +    ret = pm_runtime_get_sync(smmu->dev);
+    if (ret)
+    return;
+
   /*
    * Disable the context bank and free the page tables before freeing
    * it.
@@ -933,6 +937,8 @@ static void arm_smmu_destroy_domain_context(struct 
iommu_domain *domain)
     free_io_pgtable_ops(smmu_domain->pgtbl_ops);
   __arm_smmu_free_bitmap(smmu->context_map, cfg->cbndx);
+
+    pm_runtime_put_sync(smmu->dev);
   }
     static struct iommu_domain *arm_smmu_domain_alloc(unsigned type)
@@ -1408,12 +1414,20 @@ static int arm_smmu_add_device(struct device *dev)
   while (i--)
   cfg->smendx[i] = INVALID_SMENDX;
   -    ret = arm_smmu_master_alloc_smes(dev);
+    ret = pm_runtime_get_sync(smmu->dev);
   if (ret)
   goto out_cfg_free;
   +    ret = arm_smmu_master_alloc_smes(dev);
+    if (ret) {
+    pm_runtime_put_sync(smmu->dev);
+    goto out_cfg_free;

Please keep to the existing pattern and put this on the cleanup path with a new 
label, rather than inline.

  ok.


+    }
+
   iommu_device_link(>iommu, dev);
   +    pm_runtime_put_sync(smmu->dev);
+
   return 0;
     out_cfg_free:
@@ -1428,7 +1442,7 @@ static void arm_smmu_remove_device(struct device *dev)
   struct iommu_fwspec *fwspec = dev->iommu_fwspec;
   struct arm_smmu_master_cfg *cfg;
   struct arm_smmu_device *smmu;
-
+    int ret;
     if (!fwspec || fwspec->ops != _smmu_ops)
   return;
@@ -1436,8 +1450,21 @@ static void arm_smmu_remove_device(struct device *dev)
   cfg  = fwspec->iommu_priv;
   smmu = cfg->smmu;
   +    /*
+ * The device link between the master device and
+ * smmu is already purged at this point.
+ * So enable the power to smmu explicitly.
+ */

I don't understand this comment, especially since we don't even introduce 
device links until the following patch... :/


  This is because the core device_del callback, does a device_links_purge for 
that device,
  before calling the remove_device notifier. As a result, have to explicitly 
turn on the
  power to iommu. Probably the comment should be removed, rest of the places we 
don't
  explain why we are turning on explicitly.


Yes, will remove the comment here.




+
+    ret = pm_runtime_get_sync(smmu->dev);
+    if (ret)
+    return;
+
   iommu_device_unlink(>iommu, dev);
   arm_smmu_master_free_smes(fwspec);
+
+    pm_runtime_put_sync(smmu->dev);
+
   iommu_group_remove_device(dev);
   kfree(fwspec->iommu_priv);
   iommu_fwspec_free(dev);
@@ -2130,6 +2157,14 @@ static int arm_smmu_device_probe(struct platform_device 
*pdev)
   if (err)
   return err;
   +    platform_set_drvdata(pdev, smmu);
+
+    pm_runtime_enable(dev);
+
+    err = pm_runtime_get_sync(dev);
+    if (err)
+    return err;
+
   err = arm_smmu_device_cfg_probe(smmu);
   if (err)
   return err;
@@ -2171,9 +2206,9 @@ static int arm_smmu_device_probe(struct platform_device 
*pdev)
   return err;
   }
   -    platform_set_drvdata(pdev, smmu);
   arm_smmu_device_reset(smmu);
   arm_smmu_test_smr_masks(smmu);
+    pm_runtime_put_sync(dev);
     /*
    * For ACPI and generic DT bindings, an SMMU will be probed before
@@ -2212,6 +2247,8 @@ static int arm_smmu_device_remove(struct platform_device 
*pdev)
     /* Turn the thing off */
   writel(sCR0_CLIENTPD, ARM_SMMU_GR0_NS(smmu) + ARM_SMMU_GR0_sCR0);
+    pm_runtime_force_suspend(smmu->dev);

Why do we need this? I guess it might be a Qualcomm-ism as I don't see anyone 
else calling it from .remove other than a couple of other qcom_* drivers. Given 
that we only get here during 

Re: [PATCH v6 4/6] iommu/arm-smmu: Add the device_link between masters and smmu

2018-02-01 Thread Vivek Gautam

Hi,


On 1/31/2018 6:39 PM, Robin Murphy wrote:

On 19/01/18 11:43, Vivek Gautam wrote:

From: Sricharan R <sricha...@codeaurora.org>

Finally add the device link between the master device and
smmu, so that the smmu gets runtime enabled/disabled only when the
master needs it. This is done from add_device callback which gets
called once when the master is added to the smmu.


Don't we need to balance this with a device_link_del() in 
.remove_device (like exynos-iommu does)?


Right. Will add device_link_del() call. Thanks for pointing out.

regards
Vivek



Robin.


Signed-off-by: Sricharan R <sricha...@codeaurora.org>
---
  drivers/iommu/arm-smmu.c | 11 +++
  1 file changed, 11 insertions(+)

diff --git a/drivers/iommu/arm-smmu.c b/drivers/iommu/arm-smmu.c
index 95478bfb182c..33bbcfedb896 100644
--- a/drivers/iommu/arm-smmu.c
+++ b/drivers/iommu/arm-smmu.c
@@ -1367,6 +1367,7 @@ static int arm_smmu_add_device(struct device *dev)
  struct arm_smmu_device *smmu;
  struct arm_smmu_master_cfg *cfg;
  struct iommu_fwspec *fwspec = dev->iommu_fwspec;
+    struct device_link *link;
  int i, ret;
    if (using_legacy_binding) {
@@ -1428,6 +1429,16 @@ static int arm_smmu_add_device(struct device 
*dev)

    pm_runtime_put_sync(smmu->dev);
  +    /*
+ * Establish the link between smmu and master, so that the
+ * smmu gets runtime enabled/disabled as per the master's
+ * needs.
+ */
+    link = device_link_add(dev, smmu->dev, DL_FLAG_PM_RUNTIME);
+    if (!link)
+    dev_warn(smmu->dev, "Unable to create device link between %s 
and %s\n",

+ dev_name(smmu->dev), dev_name(dev));
+
  return 0;
    out_cfg_free:



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


Re: [PATCH v6 2/6] iommu/arm-smmu: Add pm_runtime/sleep ops

2018-01-31 Thread Vivek Gautam



On 1/31/2018 5:53 PM, Robin Murphy wrote:

On 19/01/18 11:43, Vivek Gautam wrote:

From: Sricharan R <sricha...@codeaurora.org>

The smmu needs to be functional only when the respective
master's using it are active. The device_link feature
helps to track such functional dependencies, so that the
iommu gets powered when the master device enables itself
using pm_runtime. So by adapting the smmu driver for
runtime pm, above said dependency can be addressed.

This patch adds the pm runtime/sleep callbacks to the
driver and also the functions to parse the smmu clocks
from DT and enable them in resume/suspend.

Signed-off-by: Sricharan R <sricha...@codeaurora.org>
Signed-off-by: Archit Taneja <arch...@codeaurora.org>
[vivek: Clock rework to request bulk of clocks]
Signed-off-by: Vivek Gautam <vivek.gau...@codeaurora.org>
---
  drivers/iommu/arm-smmu.c | 55 
++--

  1 file changed, 53 insertions(+), 2 deletions(-)

diff --git a/drivers/iommu/arm-smmu.c b/drivers/iommu/arm-smmu.c
index 78d4c6b8f1ba..21acffe91a1c 100644
--- a/drivers/iommu/arm-smmu.c
+++ b/drivers/iommu/arm-smmu.c
@@ -48,6 +48,7 @@
  #include 
  #include 
  #include 
+#include 
  #include 
  #include 
  @@ -205,6 +206,9 @@ struct arm_smmu_device {
  u32    num_global_irqs;
  u32    num_context_irqs;
  unsigned int    *irqs;
+    struct clk_bulk_data    *clocks;
+    int    num_clks;
+    const char * const    *clk_names;


This seems unnecessary, as we use it a grand total of of once, during 
initialisation when we have the source data directly to hand. Just 
pass data->clks into arm_smmu_init_clks() as an additional argument.


Sure, will do that.


Otherwise, I think this looks reasonable; it's about as unobtrusive as 
it's going to get.


Thanks for reviewing.

regards
Vivek



Robin.


  u32    cavium_id_base; /* Specific to Cavium */
  @@ -1685,6 +1689,25 @@ static int arm_smmu_id_size_to_bits(int size)
  }
  }
  +static int arm_smmu_init_clocks(struct arm_smmu_device *smmu)
+{
+    int i;
+    int num = smmu->num_clks;
+
+    if (num < 1)
+    return 0;
+
+    smmu->clocks = devm_kcalloc(smmu->dev, num,
+    sizeof(*smmu->clocks), GFP_KERNEL);
+    if (!smmu->clocks)
+    return -ENOMEM;
+
+    for (i = 0; i < num; i++)
+    smmu->clocks[i].id = smmu->clk_names[i];
+
+    return devm_clk_bulk_get(smmu->dev, num, smmu->clocks);
+}
+
  static int arm_smmu_device_cfg_probe(struct arm_smmu_device *smmu)
  {
  unsigned long size;
@@ -1897,10 +1920,12 @@ static int arm_smmu_device_cfg_probe(struct 
arm_smmu_device *smmu)

  struct arm_smmu_match_data {
  enum arm_smmu_arch_version version;
  enum arm_smmu_implementation model;
+    const char * const *clks;
+    int num_clks;
  };
    #define ARM_SMMU_MATCH_DATA(name, ver, imp)    \
-static struct arm_smmu_match_data name = { .version = ver, .model = 
imp }
+static const struct arm_smmu_match_data name = { .version = ver, 
.model = imp }

    ARM_SMMU_MATCH_DATA(smmu_generic_v1, ARM_SMMU_V1, GENERIC_SMMU);
  ARM_SMMU_MATCH_DATA(smmu_generic_v2, ARM_SMMU_V2, GENERIC_SMMU);
@@ -2001,6 +2026,8 @@ static int arm_smmu_device_dt_probe(struct 
platform_device *pdev,

  data = of_device_get_match_data(dev);
  smmu->version = data->version;
  smmu->model = data->model;
+    smmu->clk_names = data->clks;
+    smmu->num_clks = data->num_clks;
    parse_driver_options(smmu);
  @@ -2099,6 +2126,10 @@ static int arm_smmu_device_probe(struct 
platform_device *pdev)

  smmu->irqs[i] = irq;
  }
  +    err = arm_smmu_init_clocks(smmu);
+    if (err)
+    return err;
+
  err = arm_smmu_device_cfg_probe(smmu);
  if (err)
  return err;
@@ -2197,7 +2228,27 @@ static int __maybe_unused 
arm_smmu_pm_resume(struct device *dev)

  return 0;
  }
  -static SIMPLE_DEV_PM_OPS(arm_smmu_pm_ops, NULL, arm_smmu_pm_resume);
+static int __maybe_unused arm_smmu_runtime_resume(struct device *dev)
+{
+    struct arm_smmu_device *smmu = dev_get_drvdata(dev);
+
+    return clk_bulk_prepare_enable(smmu->num_clks, smmu->clocks);
+}
+
+static int __maybe_unused arm_smmu_runtime_suspend(struct device *dev)
+{
+    struct arm_smmu_device *smmu = dev_get_drvdata(dev);
+
+    clk_bulk_disable_unprepare(smmu->num_clks, smmu->clocks);
+
+    return 0;
+}
+
+static const struct dev_pm_ops arm_smmu_pm_ops = {
+    SET_SYSTEM_SLEEP_PM_OPS(NULL, arm_smmu_pm_resume)
+    SET_RUNTIME_PM_OPS(arm_smmu_runtime_suspend,
+   arm_smmu_runtime_resume, NULL)
+};
    static struct platform_driver arm_smmu_driver = {
  .driver    = {



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


Re: [PATCH v6 5/6] iommu/arm-smmu: Add support for qcom,smmu-v2 variant

2018-01-31 Thread Vivek Gautam



On 1/30/2018 1:12 AM, Rob Herring wrote:

On Fri, Jan 19, 2018 at 05:13:42PM +0530, Vivek Gautam wrote:

qcom,smmu-v2 is an arm,smmu-v2 implementation with specific
clock and power requirements. This smmu core is used with
multiple masters on msm8996, viz. mdss, video, etc.
Add bindings for the same.

Signed-off-by: Vivek Gautam <vivek.gau...@codeaurora.org>
---
  .../devicetree/bindings/iommu/arm,smmu.txt | 43 ++
  drivers/iommu/arm-smmu.c   | 13 +++
  2 files changed, 56 insertions(+)

Reviewed-by: Rob Herring <r...@kernel.org>


Thanks Rob.


--
To unsubscribe from this list: send the line "unsubscribe linux-arm-msm" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


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


[PATCH v7 3/6] iommu/arm-smmu: Invoke pm_runtime during probe, add/remove device

2018-02-08 Thread Vivek Gautam
From: Sricharan R <sricha...@codeaurora.org>

The smmu device probe/remove and add/remove master device callbacks
gets called when the smmu is not linked to its master, that is without
the context of the master device. So calling runtime apis in those places
separately.

Signed-off-by: Sricharan R <sricha...@codeaurora.org>
[vivek: Cleanup pm runtime calls]
Signed-off-by: Vivek Gautam <vivek.gau...@codeaurora.org>
---
 drivers/iommu/arm-smmu.c | 42 ++
 1 file changed, 38 insertions(+), 4 deletions(-)

diff --git a/drivers/iommu/arm-smmu.c b/drivers/iommu/arm-smmu.c
index 9e2f917e16c2..c024f69c1682 100644
--- a/drivers/iommu/arm-smmu.c
+++ b/drivers/iommu/arm-smmu.c
@@ -913,11 +913,15 @@ static void arm_smmu_destroy_domain_context(struct 
iommu_domain *domain)
struct arm_smmu_domain *smmu_domain = to_smmu_domain(domain);
struct arm_smmu_device *smmu = smmu_domain->smmu;
struct arm_smmu_cfg *cfg = _domain->cfg;
-   int irq;
+   int ret, irq;
 
if (!smmu || domain->type == IOMMU_DOMAIN_IDENTITY)
return;
 
+   ret = pm_runtime_get_sync(smmu->dev);
+   if (ret)
+   return;
+
/*
 * Disable the context bank and free the page tables before freeing
 * it.
@@ -932,6 +936,8 @@ static void arm_smmu_destroy_domain_context(struct 
iommu_domain *domain)
 
free_io_pgtable_ops(smmu_domain->pgtbl_ops);
__arm_smmu_free_bitmap(smmu->context_map, cfg->cbndx);
+
+   pm_runtime_put_sync(smmu->dev);
 }
 
 static struct iommu_domain *arm_smmu_domain_alloc(unsigned type)
@@ -1407,14 +1413,22 @@ static int arm_smmu_add_device(struct device *dev)
while (i--)
cfg->smendx[i] = INVALID_SMENDX;
 
-   ret = arm_smmu_master_alloc_smes(dev);
+   ret = pm_runtime_get_sync(smmu->dev);
if (ret)
goto out_cfg_free;
 
+   ret = arm_smmu_master_alloc_smes(dev);
+   if (ret)
+   goto out_rpm_put;
+
iommu_device_link(>iommu, dev);
 
+   pm_runtime_put_sync(smmu->dev);
+
return 0;
 
+out_rpm_put:
+   pm_runtime_put_sync(smmu->dev);
 out_cfg_free:
kfree(cfg);
 out_free:
@@ -1427,7 +1441,7 @@ static void arm_smmu_remove_device(struct device *dev)
struct iommu_fwspec *fwspec = dev->iommu_fwspec;
struct arm_smmu_master_cfg *cfg;
struct arm_smmu_device *smmu;
-
+   int ret;
 
if (!fwspec || fwspec->ops != _smmu_ops)
return;
@@ -1435,8 +1449,15 @@ static void arm_smmu_remove_device(struct device *dev)
cfg  = fwspec->iommu_priv;
smmu = cfg->smmu;
 
+   ret = pm_runtime_get_sync(smmu->dev);
+   if (ret)
+   return;
+
iommu_device_unlink(>iommu, dev);
arm_smmu_master_free_smes(fwspec);
+
+   pm_runtime_put_sync(smmu->dev);
+
iommu_group_remove_device(dev);
kfree(fwspec->iommu_priv);
iommu_fwspec_free(dev);
@@ -2131,6 +2152,14 @@ static int arm_smmu_device_probe(struct platform_device 
*pdev)
if (err)
return err;
 
+   platform_set_drvdata(pdev, smmu);
+
+   pm_runtime_enable(dev);
+
+   err = pm_runtime_get_sync(dev);
+   if (err)
+   return err;
+
err = arm_smmu_device_cfg_probe(smmu);
if (err)
return err;
@@ -2172,9 +2201,9 @@ static int arm_smmu_device_probe(struct platform_device 
*pdev)
return err;
}
 
-   platform_set_drvdata(pdev, smmu);
arm_smmu_device_reset(smmu);
arm_smmu_test_smr_masks(smmu);
+   pm_runtime_put_sync(dev);
 
/*
 * For ACPI and generic DT bindings, an SMMU will be probed before
@@ -2211,8 +2240,13 @@ static int arm_smmu_device_remove(struct platform_device 
*pdev)
if (!bitmap_empty(smmu->context_map, ARM_SMMU_MAX_CBS))
dev_err(>dev, "removing device with active domains!\n");
 
+   pm_runtime_get_sync(smmu->dev);
/* Turn the thing off */
writel(sCR0_CLIENTPD, ARM_SMMU_GR0_NS(smmu) + ARM_SMMU_GR0_sCR0);
+   pm_runtime_put_sync(smmu->dev);
+
+   pm_runtime_disable(smmu->dev);
+
return 0;
 }
 
-- 
QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member
of Code Aurora Forum, hosted by The Linux Foundation

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


[PATCH v7 0/6] iommu/arm-smmu: Add runtime pm/sleep support

2018-02-08 Thread Vivek Gautam
This series provides the support for turning on the arm-smmu's
clocks/power domains using runtime pm. This is done using the
recently introduced device links patches, which lets the smmu's
runtime to follow the master's runtime pm, so the smmu remains
powered only when the masters use it.

It also adds support for Qcom's arm-smmu-v2 variant that
has different clocks and power requirements.

Took some reference from the exynos runtime patches [1].

After much discussion [3] over the use of pm_runtime_get/put() in
.unmap op path for the arm-smmu, and after disussing over more than
a couple of approaches to address this, we are putting forward the
changes *without* using pm_runtime APIs in 'unmap'. Rather, letting
the client device take the control of powering on/off the connected
iommu through pm_runtime_get(put)_suppliers() APIs for the scnerios
when the iommu power can't be directly controlled by clients through
device links.
Rafael acked the change to export the suppliers APIs.

Previous version of this patch series is @ [5].

[v7]
   * Addressed review comments given by Robin Murphy -
 -- Added device_link_del() in .remove_device path.
 -- Error path cleanup in arm_smmu_add_device().
 -- Added pm_runtime_get/put_sync() in .remove path, and replaced
pm_runtime_force_suspend() with pm_runtime_disable().
 -- clk_names cleanup in arm_smmu_init_clks()
   * Added 'Reviewed-by' given by Rob H.

[V6]
   * Added Ack given by Rafael to first patch in the series.
   * Addressed Rob Herring's comment for adding soc specific compatible
 string as well besides 'qcom,smmu-v2'.

[V5]
   * Dropped runtime pm calls from "arm_smmu_unmap" op as discussed over
 the list [3] for the last patch series.
   * Added a patch to export pm_runtime_get/put_suppliers() APIs to the
 series as agreed with Rafael [4].
   * Added the related patch for msm drm iommu layer to use
 pm_runtime_get/put_suppliers() APIs in msm_mmu_funcs.
   * Dropped arm-mmu500 clock patch since that would break existing
 platforms.
   * Changed compatible 'qcom,msm8996-smmu-v2' to 'qcom,smmu-v2' to reflect
 the IP version rather than the platform on which it is used.
 The same IP is used across multiple platforms including msm8996,
 and sdm845 etc.
   * Using clock bulk APIs to handle the clocks available to the IP as
 suggested by Stephen Boyd.
   * The first patch in v4 version of the patch-series:
 ("iommu/arm-smmu: Fix the error path in arm_smmu_add_device") has
 already made it to mainline.

[V4]
   * Reworked the clock handling part. We now take clock names as data
 in the driver for supported compatible versions, and loop over them
 to get, enable, and disable the clocks.
   * Using qcom,msm8996 based compatibles for bindings instead of a generic
 qcom compatible.
   * Refactor MMU500 patch to just add the necessary clock names data and
 corresponding bindings.
   * Added the pm_runtime_get/put() calls in .unmap iommu op (fix added by
 Stanimir on top of previous patch version.
   * Added a patch to fix error path in arm_smmu_add_device()
   * Removed patch 3/5 of V3 patch series that added qcom,smmu-v2 bindings.

[V3]
   * Reworked the patches to keep the clocks init/enabling function
 separately for each compatible.

   * Added clocks bindings for MMU40x/500.

   * Added a new compatible for qcom,smmu-v2 implementation and
 the clock bindings for the same.

   * Rebased on top of 4.11-rc1

[V2]
   * Split the patches little differently.

   * Addressed comments.

   * Removed the patch #4 [2] from previous post
 for arm-smmu context save restore. Planning to
 post this separately after reworking/addressing Robin's
 feedback.

   * Reversed the sequence to disable clocks than enabling.
 This was required for those cases where the
 clocks are populated in a dependent order from DT.

[1] https://lkml.org/lkml/2016/10/20/70
[2] https://patchwork.kernel.org/patch/9389717/
[3] https://patchwork.kernel.org/patch/9827825/
[4] https://patchwork.kernel.org/patch/10102445/
[5] https://lkml.org/lkml/2018/1/19/217

Sricharan R (3):
  iommu/arm-smmu: Add pm_runtime/sleep ops
  iommu/arm-smmu: Invoke pm_runtime during probe, add/remove device
  iommu/arm-smmu: Add the device_link between masters and smmu

Vivek Gautam (3):
  base: power: runtime: Export pm_runtime_get/put_suppliers
  iommu/arm-smmu: Add support for qcom,smmu-v2 variant
  drm/msm: iommu: Replace runtime calls with runtime suppliers

 .../devicetree/bindings/iommu/arm,smmu.txt |  43 +++
 drivers/base/power/runtime.c   |   2 +
 drivers/gpu/drm/msm/msm_iommu.c|  16 +--
 drivers/iommu/arm-smmu.c   | 127 -
 4 files changed, 174 insertions(+), 14 deletions(-)

-- 
QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member
of Code Aurora Forum, hosted by 

[PATCH v7 2/6] iommu/arm-smmu: Add pm_runtime/sleep ops

2018-02-08 Thread Vivek Gautam
From: Sricharan R <sricha...@codeaurora.org>

The smmu needs to be functional only when the respective
master's using it are active. The device_link feature
helps to track such functional dependencies, so that the
iommu gets powered when the master device enables itself
using pm_runtime. So by adapting the smmu driver for
runtime pm, above said dependency can be addressed.

This patch adds the pm runtime/sleep callbacks to the
driver and also the functions to parse the smmu clocks
from DT and enable them in resume/suspend.

Signed-off-by: Sricharan R <sricha...@codeaurora.org>
Signed-off-by: Archit Taneja <arch...@codeaurora.org>
[vivek: Clock rework to request bulk of clocks]
Signed-off-by: Vivek Gautam <vivek.gau...@codeaurora.org>
---
 drivers/iommu/arm-smmu.c | 56 ++--
 1 file changed, 54 insertions(+), 2 deletions(-)

diff --git a/drivers/iommu/arm-smmu.c b/drivers/iommu/arm-smmu.c
index 69e7c60792a8..9e2f917e16c2 100644
--- a/drivers/iommu/arm-smmu.c
+++ b/drivers/iommu/arm-smmu.c
@@ -48,6 +48,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 
@@ -205,6 +206,8 @@ struct arm_smmu_device {
u32 num_global_irqs;
u32 num_context_irqs;
unsigned int*irqs;
+   struct clk_bulk_data*clocks;
+   int num_clks;
 
u32 cavium_id_base; /* Specific to Cavium */
 
@@ -1897,10 +1900,12 @@ static int arm_smmu_device_cfg_probe(struct 
arm_smmu_device *smmu)
 struct arm_smmu_match_data {
enum arm_smmu_arch_version version;
enum arm_smmu_implementation model;
+   const char * const *clks;
+   int num_clks;
 };
 
 #define ARM_SMMU_MATCH_DATA(name, ver, imp)\
-static struct arm_smmu_match_data name = { .version = ver, .model = imp }
+static const struct arm_smmu_match_data name = { .version = ver, .model = imp }
 
 ARM_SMMU_MATCH_DATA(smmu_generic_v1, ARM_SMMU_V1, GENERIC_SMMU);
 ARM_SMMU_MATCH_DATA(smmu_generic_v2, ARM_SMMU_V2, GENERIC_SMMU);
@@ -2001,6 +2006,7 @@ static int arm_smmu_device_dt_probe(struct 
platform_device *pdev,
data = of_device_get_match_data(dev);
smmu->version = data->version;
smmu->model = data->model;
+   smmu->num_clks = data->num_clks;
 
parse_driver_options(smmu);
 
@@ -2039,6 +2045,28 @@ static void arm_smmu_bus_init(void)
 #endif
 }
 
+static int arm_smmu_init_clks(struct arm_smmu_device *smmu)
+{
+   int i;
+   int num = smmu->num_clks;
+   const struct arm_smmu_match_data *data;
+
+   if (num < 1)
+   return 0;
+
+   smmu->clocks = devm_kcalloc(smmu->dev, num,
+   sizeof(*smmu->clocks), GFP_KERNEL);
+   if (!smmu->clocks)
+   return -ENOMEM;
+
+   data = of_device_get_match_data(smmu->dev);
+
+   for (i = 0; i < num; i++)
+   smmu->clocks[i].id = data->clks[i];
+
+   return devm_clk_bulk_get(smmu->dev, num, smmu->clocks);
+}
+
 static int arm_smmu_device_probe(struct platform_device *pdev)
 {
struct resource *res;
@@ -2099,6 +2127,10 @@ static int arm_smmu_device_probe(struct platform_device 
*pdev)
smmu->irqs[i] = irq;
}
 
+   err = arm_smmu_init_clks(smmu);
+   if (err)
+   return err;
+
err = arm_smmu_device_cfg_probe(smmu);
if (err)
return err;
@@ -2197,7 +2229,27 @@ static int __maybe_unused arm_smmu_pm_resume(struct 
device *dev)
return 0;
 }
 
-static SIMPLE_DEV_PM_OPS(arm_smmu_pm_ops, NULL, arm_smmu_pm_resume);
+static int __maybe_unused arm_smmu_runtime_resume(struct device *dev)
+{
+   struct arm_smmu_device *smmu = dev_get_drvdata(dev);
+
+   return clk_bulk_prepare_enable(smmu->num_clks, smmu->clocks);
+}
+
+static int __maybe_unused arm_smmu_runtime_suspend(struct device *dev)
+{
+   struct arm_smmu_device *smmu = dev_get_drvdata(dev);
+
+   clk_bulk_disable_unprepare(smmu->num_clks, smmu->clocks);
+
+   return 0;
+}
+
+static const struct dev_pm_ops arm_smmu_pm_ops = {
+   SET_SYSTEM_SLEEP_PM_OPS(NULL, arm_smmu_pm_resume)
+   SET_RUNTIME_PM_OPS(arm_smmu_runtime_suspend,
+  arm_smmu_runtime_resume, NULL)
+};
 
 static struct platform_driver arm_smmu_driver = {
.driver = {
-- 
QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member
of Code Aurora Forum, hosted by The Linux Foundation

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


[PATCH v7 1/6] base: power: runtime: Export pm_runtime_get/put_suppliers

2018-02-08 Thread Vivek Gautam
The device link allows the pm framework to tie the supplier and
consumer. So, whenever the consumer is powered-on the supplier
is powered-on first.

There are however cases in which the consumer wants to power-on
the supplier, but not itself.
E.g., A Graphics or multimedia driver wants to power-on the SMMU
to unmap a buffer and finish the TLB operations without powering
on itself. Some of these unmap requests are coming from the
user space when the controller itself is not powered-up, and it
can be huge penalty in terms of power and latency to power-up
the graphics/mm controllers.
There can be an argument that the supplier should handle this case
on its own and there should not be a need for the consumer to
power-on the supplier. But as discussed on the thread [1] about
ARM-SMMU runtime pm, we don't want to introduce runtime pm calls
in atomic path in arm_smmu_unmap.

[1] https://patchwork.kernel.org/patch/9827825/

Signed-off-by: Vivek Gautam <vivek.gau...@codeaurora.org>
Acked-by: Rafael J. Wysocki <rafael.j.wyso...@intel.com>
---
 drivers/base/power/runtime.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/base/power/runtime.c b/drivers/base/power/runtime.c
index 8bef3cb2424d..5b8226c8af19 100644
--- a/drivers/base/power/runtime.c
+++ b/drivers/base/power/runtime.c
@@ -1579,6 +1579,7 @@ void pm_runtime_get_suppliers(struct device *dev)
 
device_links_read_unlock(idx);
 }
+EXPORT_SYMBOL_GPL(pm_runtime_get_suppliers);
 
 /**
  * pm_runtime_put_suppliers - Drop references to supplier devices.
@@ -1597,6 +1598,7 @@ void pm_runtime_put_suppliers(struct device *dev)
 
device_links_read_unlock(idx);
 }
+EXPORT_SYMBOL_GPL(pm_runtime_put_suppliers);
 
 void pm_runtime_new_link(struct device *dev)
 {
-- 
QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member
of Code Aurora Forum, hosted by The Linux Foundation

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


[PATCH v7 4/6] iommu/arm-smmu: Add the device_link between masters and smmu

2018-02-08 Thread Vivek Gautam
From: Sricharan R <sricha...@codeaurora.org>

Finally add the device link between the master device and
smmu, so that the smmu gets runtime enabled/disabled only when the
master needs it. This is done from add_device callback which gets
called once when the master is added to the smmu.

Signed-off-by: Sricharan R <sricha...@codeaurora.org>
Signed-off-by: Vivek Gautam <vivek.gau...@codeaurora.org>
---
 drivers/iommu/arm-smmu.c | 16 
 1 file changed, 16 insertions(+)

diff --git a/drivers/iommu/arm-smmu.c b/drivers/iommu/arm-smmu.c
index c024f69c1682..c7e924d553bd 100644
--- a/drivers/iommu/arm-smmu.c
+++ b/drivers/iommu/arm-smmu.c
@@ -215,6 +215,9 @@ struct arm_smmu_device {
 
/* IOMMU core code handle */
struct iommu_device iommu;
+
+   /* runtime PM link to master */
+   struct device_link *link;
 };
 
 enum arm_smmu_context_fmt {
@@ -1425,6 +1428,17 @@ static int arm_smmu_add_device(struct device *dev)
 
pm_runtime_put_sync(smmu->dev);
 
+   /*
+* Establish the link between smmu and master, so that the
+* smmu gets runtime enabled/disabled as per the master's
+* needs.
+*/
+   smmu->link = device_link_add(dev, smmu->dev, DL_FLAG_PM_RUNTIME);
+   if (!smmu->link)
+   dev_warn(smmu->dev,
+"Unable to create device link between %s and %s\n",
+dev_name(smmu->dev), dev_name(dev));
+
return 0;
 
 out_rpm_put:
@@ -1449,6 +1463,8 @@ static void arm_smmu_remove_device(struct device *dev)
cfg  = fwspec->iommu_priv;
smmu = cfg->smmu;
 
+   device_link_del(smmu->link);
+
ret = pm_runtime_get_sync(smmu->dev);
if (ret)
return;
-- 
QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member
of Code Aurora Forum, hosted by The Linux Foundation

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


[PATCH v7 6/6] drm/msm: iommu: Replace runtime calls with runtime suppliers

2018-02-08 Thread Vivek Gautam
While handling the concerned iommu, there should not be a
need to power control the drm devices from iommu interface.
If these drm devices need to be powered around this time,
the respective drivers should take care of this.

Replace the pm_runtime_get/put_sync() with
pm_runtime_get/put_suppliers() calls, to power-up
the connected iommu through the device link interface.
In case the device link is not setup these get/put_suppliers()
calls will be a no-op, and the iommu driver should take care of
powering on its devices accordingly.

Signed-off-by: Vivek Gautam <vivek.gau...@codeaurora.org>
---
 drivers/gpu/drm/msm/msm_iommu.c | 16 
 1 file changed, 8 insertions(+), 8 deletions(-)

diff --git a/drivers/gpu/drm/msm/msm_iommu.c b/drivers/gpu/drm/msm/msm_iommu.c
index b23d33622f37..1ab629bbee69 100644
--- a/drivers/gpu/drm/msm/msm_iommu.c
+++ b/drivers/gpu/drm/msm/msm_iommu.c
@@ -40,9 +40,9 @@ static int msm_iommu_attach(struct msm_mmu *mmu, const char * 
const *names,
struct msm_iommu *iommu = to_msm_iommu(mmu);
int ret;
 
-   pm_runtime_get_sync(mmu->dev);
+   pm_runtime_get_suppliers(mmu->dev);
ret = iommu_attach_device(iommu->domain, mmu->dev);
-   pm_runtime_put_sync(mmu->dev);
+   pm_runtime_put_suppliers(mmu->dev);
 
return ret;
 }
@@ -52,9 +52,9 @@ static void msm_iommu_detach(struct msm_mmu *mmu, const char 
* const *names,
 {
struct msm_iommu *iommu = to_msm_iommu(mmu);
 
-   pm_runtime_get_sync(mmu->dev);
+   pm_runtime_get_suppliers(mmu->dev);
iommu_detach_device(iommu->domain, mmu->dev);
-   pm_runtime_put_sync(mmu->dev);
+   pm_runtime_put_suppliers(mmu->dev);
 }
 
 static int msm_iommu_map(struct msm_mmu *mmu, uint64_t iova,
@@ -63,9 +63,9 @@ static int msm_iommu_map(struct msm_mmu *mmu, uint64_t iova,
struct msm_iommu *iommu = to_msm_iommu(mmu);
size_t ret;
 
-// pm_runtime_get_sync(mmu->dev);
+   pm_runtime_get_suppliers(mmu->dev);
ret = iommu_map_sg(iommu->domain, iova, sgt->sgl, sgt->nents, prot);
-// pm_runtime_put_sync(mmu->dev);
+   pm_runtime_put_suppliers(mmu->dev);
WARN_ON(ret < 0);
 
return (ret == len) ? 0 : -EINVAL;
@@ -76,9 +76,9 @@ static int msm_iommu_unmap(struct msm_mmu *mmu, uint64_t iova,
 {
struct msm_iommu *iommu = to_msm_iommu(mmu);
 
-   pm_runtime_get_sync(mmu->dev);
+   pm_runtime_get_suppliers(mmu->dev);
iommu_unmap(iommu->domain, iova, len);
-   pm_runtime_put_sync(mmu->dev);
+   pm_runtime_put_suppliers(mmu->dev);
 
return 0;
 }
-- 
QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member
of Code Aurora Forum, hosted by The Linux Foundation

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


[PATCH v7 5/6] iommu/arm-smmu: Add support for qcom,smmu-v2 variant

2018-02-08 Thread Vivek Gautam
qcom,smmu-v2 is an arm,smmu-v2 implementation with specific
clock and power requirements. This smmu core is used with
multiple masters on msm8996, viz. mdss, video, etc.
Add bindings for the same.

Signed-off-by: Vivek Gautam <vivek.gau...@codeaurora.org>
Reviewed-by: Rob Herring <r...@kernel.org>
---
 .../devicetree/bindings/iommu/arm,smmu.txt | 43 ++
 drivers/iommu/arm-smmu.c   | 13 +++
 2 files changed, 56 insertions(+)

diff --git a/Documentation/devicetree/bindings/iommu/arm,smmu.txt 
b/Documentation/devicetree/bindings/iommu/arm,smmu.txt
index 8a6ffce12af5..169222ae2706 100644
--- a/Documentation/devicetree/bindings/iommu/arm,smmu.txt
+++ b/Documentation/devicetree/bindings/iommu/arm,smmu.txt
@@ -17,10 +17,19 @@ conditions.
 "arm,mmu-401"
 "arm,mmu-500"
 "cavium,smmu-v2"
+"qcom,-smmu-v2", "qcom,smmu-v2"
 
   depending on the particular implementation and/or the
   version of the architecture implemented.
 
+  A number of Qcom SoCs use qcom,smmu-v2 version of the IP.
+  "qcom,-smmu-v2" represents a soc specific compatible
+  string that should be present along with the "qcom,smmu-v2"
+  to facilitate SoC specific clocks/power connections and to
+  address specific bug fixes.
+  An example string would be -
+  "qcom,msm8996-smmu-v2", "qcom,smmu-v2".
+
 - reg   : Base address and size of the SMMU.
 
 - #global-interrupts : The number of global interrupts exposed by the
@@ -71,6 +80,23 @@ conditions.
   or using stream matching with #iommu-cells = <2>, and
   may be ignored if present in such cases.
 
+- clock-names:Should be "bus", and "iface" for "qcom,smmu-v2"
+  implementation.
+
+  "bus" clock for "qcom,smmu-v2" is required for downstream
+  bus access and for the smmu ptw.
+
+  "iface" clock is required to access smmu's registers through
+  the TCU's programming interface.
+
+- clocks: Phandles for respective clocks described by clock-names.
+
+- power-domains:  Phandles to SMMU's power domain specifier. This is
+  required even if SMMU belongs to the master's power
+  domain, as the SMMU will have to be enabled and
+  accessed before master gets enabled and linked to its
+  SMMU.
+
 ** Deprecated properties:
 
 - mmu-masters (deprecated in favour of the generic "iommus" binding) :
@@ -137,3 +163,20 @@ conditions.
 iommu-map = <0  0 0x400>;
 ...
 };
+
+   /* Qcom's arm,smmu-v2 implementation */
+   smmu4: iommu {
+   compatible = "qcom,msm8996-smmu-v2", "qcom,smmu-v2";
+   reg = <0xd0 0x1>;
+
+   #global-interrupts = <1>;
+   interrupts = ,
+,
+;
+   #iommu-cells = <1>;
+   power-domains = < MDSS_GDSC>;
+
+   clocks = < SMMU_MDP_AXI_CLK>,
+< SMMU_MDP_AHB_CLK>;
+   clock-names = "bus", "iface";
+   };
diff --git a/drivers/iommu/arm-smmu.c b/drivers/iommu/arm-smmu.c
index c7e924d553bd..721cf1291f85 100644
--- a/drivers/iommu/arm-smmu.c
+++ b/drivers/iommu/arm-smmu.c
@@ -119,6 +119,7 @@ enum arm_smmu_implementation {
GENERIC_SMMU,
ARM_MMU500,
CAVIUM_SMMUV2,
+   QCOM_SMMUV2,
 };
 
 struct arm_smmu_s2cr {
@@ -1950,6 +1951,17 @@ struct arm_smmu_match_data {
 ARM_SMMU_MATCH_DATA(arm_mmu500, ARM_SMMU_V2, ARM_MMU500);
 ARM_SMMU_MATCH_DATA(cavium_smmuv2, ARM_SMMU_V2, CAVIUM_SMMUV2);
 
+static const char * const qcom_smmuv2_clks[] = {
+   "bus", "iface",
+};
+
+static const struct arm_smmu_match_data qcom_smmuv2 = {
+   .version = ARM_SMMU_V2,
+   .model = QCOM_SMMUV2,
+   .clks = qcom_smmuv2_clks,
+   .num_clks = ARRAY_SIZE(qcom_smmuv2_clks),
+};
+
 static const struct of_device_id arm_smmu_of_match[] = {
{ .compatible = "arm,smmu-v1", .data = _generic_v1 },
{ .compatible = "arm,smmu-v2", .data = _generic_v2 },
@@ -1957,6 +1969,7 @@ struct arm_smmu_match_data {
{ .compatible = "arm,mmu-401", .data = _mmu401 },
{ .compatible = "arm,mmu-500", .data = _mmu500 },
{ .compatible = "cavium,smmu-v2", .data = _smmuv2 },
+   { .compatible = "qcom,smmu-v2", .data = _smmuv2 },
   

[PATCH v8 5/6] iommu/arm-smmu: Add support for qcom,smmu-v2 variant

2018-02-09 Thread Vivek Gautam
qcom,smmu-v2 is an arm,smmu-v2 implementation with specific
clock and power requirements. This smmu core is used with
multiple masters on msm8996, viz. mdss, video, etc.
Add bindings for the same.

Signed-off-by: Vivek Gautam <vivek.gau...@codeaurora.org>
Reviewed-by: Rob Herring <r...@kernel.org>
---

Changes in v8:
 - Added the missing IOMMU_OF_DECLARE declaration for "qcom,smmu-v2"

 .../devicetree/bindings/iommu/arm,smmu.txt | 43 ++
 drivers/iommu/arm-smmu.c   | 14 +++
 2 files changed, 57 insertions(+)

diff --git a/Documentation/devicetree/bindings/iommu/arm,smmu.txt 
b/Documentation/devicetree/bindings/iommu/arm,smmu.txt
index 8a6ffce12af5..169222ae2706 100644
--- a/Documentation/devicetree/bindings/iommu/arm,smmu.txt
+++ b/Documentation/devicetree/bindings/iommu/arm,smmu.txt
@@ -17,10 +17,19 @@ conditions.
 "arm,mmu-401"
 "arm,mmu-500"
 "cavium,smmu-v2"
+"qcom,-smmu-v2", "qcom,smmu-v2"
 
   depending on the particular implementation and/or the
   version of the architecture implemented.
 
+  A number of Qcom SoCs use qcom,smmu-v2 version of the IP.
+  "qcom,-smmu-v2" represents a soc specific compatible
+  string that should be present along with the "qcom,smmu-v2"
+  to facilitate SoC specific clocks/power connections and to
+  address specific bug fixes.
+  An example string would be -
+  "qcom,msm8996-smmu-v2", "qcom,smmu-v2".
+
 - reg   : Base address and size of the SMMU.
 
 - #global-interrupts : The number of global interrupts exposed by the
@@ -71,6 +80,23 @@ conditions.
   or using stream matching with #iommu-cells = <2>, and
   may be ignored if present in such cases.
 
+- clock-names:Should be "bus", and "iface" for "qcom,smmu-v2"
+  implementation.
+
+  "bus" clock for "qcom,smmu-v2" is required for downstream
+  bus access and for the smmu ptw.
+
+  "iface" clock is required to access smmu's registers through
+  the TCU's programming interface.
+
+- clocks: Phandles for respective clocks described by clock-names.
+
+- power-domains:  Phandles to SMMU's power domain specifier. This is
+  required even if SMMU belongs to the master's power
+  domain, as the SMMU will have to be enabled and
+  accessed before master gets enabled and linked to its
+  SMMU.
+
 ** Deprecated properties:
 
 - mmu-masters (deprecated in favour of the generic "iommus" binding) :
@@ -137,3 +163,20 @@ conditions.
 iommu-map = <0  0 0x400>;
 ...
 };
+
+   /* Qcom's arm,smmu-v2 implementation */
+   smmu4: iommu {
+   compatible = "qcom,msm8996-smmu-v2", "qcom,smmu-v2";
+   reg = <0xd0 0x1>;
+
+   #global-interrupts = <1>;
+   interrupts = ,
+,
+;
+   #iommu-cells = <1>;
+   power-domains = < MDSS_GDSC>;
+
+   clocks = < SMMU_MDP_AXI_CLK>,
+< SMMU_MDP_AHB_CLK>;
+   clock-names = "bus", "iface";
+   };
diff --git a/drivers/iommu/arm-smmu.c b/drivers/iommu/arm-smmu.c
index c7e924d553bd..40da3f251acf 100644
--- a/drivers/iommu/arm-smmu.c
+++ b/drivers/iommu/arm-smmu.c
@@ -119,6 +119,7 @@ enum arm_smmu_implementation {
GENERIC_SMMU,
ARM_MMU500,
CAVIUM_SMMUV2,
+   QCOM_SMMUV2,
 };
 
 struct arm_smmu_s2cr {
@@ -1950,6 +1951,17 @@ struct arm_smmu_match_data {
 ARM_SMMU_MATCH_DATA(arm_mmu500, ARM_SMMU_V2, ARM_MMU500);
 ARM_SMMU_MATCH_DATA(cavium_smmuv2, ARM_SMMU_V2, CAVIUM_SMMUV2);
 
+static const char * const qcom_smmuv2_clks[] = {
+   "bus", "iface",
+};
+
+static const struct arm_smmu_match_data qcom_smmuv2 = {
+   .version = ARM_SMMU_V2,
+   .model = QCOM_SMMUV2,
+   .clks = qcom_smmuv2_clks,
+   .num_clks = ARRAY_SIZE(qcom_smmuv2_clks),
+};
+
 static const struct of_device_id arm_smmu_of_match[] = {
{ .compatible = "arm,smmu-v1", .data = _generic_v1 },
{ .compatible = "arm,smmu-v2", .data = _generic_v2 },
@@ -1957,6 +1969,7 @@ struct arm_smmu_match_data {
{ .compatible = "arm,mmu-401", .data = _mmu401 },
{ .compatible = "arm,mmu-500", .data = _mmu500 },
{ .compatible = "cavi

Re: [PATCH v7 3/6] iommu/arm-smmu: Invoke pm_runtime during probe, add/remove device

2018-02-14 Thread Vivek Gautam
On Tue, Feb 13, 2018 at 7:22 PM, Tomasz Figa <tf...@chromium.org> wrote:
> On Tue, Feb 13, 2018 at 9:57 PM, Robin Murphy <robin.mur...@arm.com> wrote:
>> On 13/02/18 08:24, Tomasz Figa wrote:
>>>
>>> Hi Vivek,
>>>
>>> Thanks for the patch. Please see my comments inline.
>>>
>>> On Wed, Feb 7, 2018 at 7:31 PM, Vivek Gautam
>>> <vivek.gau...@codeaurora.org> wrote:
>>>>
>>>> From: Sricharan R <sricha...@codeaurora.org>
>>>>
>>>> The smmu device probe/remove and add/remove master device callbacks
>>>> gets called when the smmu is not linked to its master, that is without
>>>> the context of the master device. So calling runtime apis in those places
>>>> separately.
>>>>
>>>> Signed-off-by: Sricharan R <sricha...@codeaurora.org>
>>>> [vivek: Cleanup pm runtime calls]
>>>> Signed-off-by: Vivek Gautam <vivek.gau...@codeaurora.org>
>>>> ---
>>>>   drivers/iommu/arm-smmu.c | 42
>>>> ++
>>>>   1 file changed, 38 insertions(+), 4 deletions(-)
>>>>
>>>> diff --git a/drivers/iommu/arm-smmu.c b/drivers/iommu/arm-smmu.c
>>>> index 9e2f917e16c2..c024f69c1682 100644
>>>> --- a/drivers/iommu/arm-smmu.c
>>>> +++ b/drivers/iommu/arm-smmu.c
>>>> @@ -913,11 +913,15 @@ static void arm_smmu_destroy_domain_context(struct
>>>> iommu_domain *domain)
>>>>  struct arm_smmu_domain *smmu_domain = to_smmu_domain(domain);
>>>>  struct arm_smmu_device *smmu = smmu_domain->smmu;
>>>>  struct arm_smmu_cfg *cfg = _domain->cfg;
>>>> -   int irq;
>>>> +   int ret, irq;
>>>>
>>>>  if (!smmu || domain->type == IOMMU_DOMAIN_IDENTITY)
>>>>  return;
>>>>
>>>> +   ret = pm_runtime_get_sync(smmu->dev);
>>>> +   if (ret)
>>>> +   return;
>>>
>>>
>>> pm_runtime_get_sync() will return 0 if the device was powered off, 1
>>> if it was already/still powered on or runtime PM is not compiled in,
>>> or a negative value on error, so shouldn't the test be (ret < 0)?
>>>
>>> Moreover, I'm actually wondering if it makes any sense to power up the
>>> hardware just to program it and power it down again. In a system where
>>> the IOMMU is located within a power domain, it would cause the IOMMU
>>> block to lose its state anyway.
>>
>>
>> This is generally for the case where the SMMU internal state remains active,
>> but the programming interface needs to be powered up in order to access it.
>
> That's true for Qualcomm SMMU, but I think that would be different for
> existing users of the driver?
>
>>
>>> Actually, reflecting back on "[PATCH v7 2/6] iommu/arm-smmu: Add
>>> pm_runtime/sleep ops", perhaps it would make more sense to just
>>> control the clocks independently of runtime PM? Then, runtime PM could
>>> be used for real power management, e.g. really powering the block up
>>> and down, for further power saving.
>>
>>
>> Unfortunately that ends up pretty much unmanageable, because there are
>> numerous different SMMU microarchitectures with fundamentally different
>> clock/power domain schemes (multiplied by individual SoC integration
>> possibilities). Since this is fundamentally a generic architectural driver,
>> adding explicit clock support would probably make the whole thing about 50%
>> clock code, with complicated decision trees around every hardware access
>> calculating which clocks are necessary for a given operation on a given
>> system. That maintainability aspect is why we've already nacked such a
>> fine-grained approach in the past.
>
> Hmm, I think we are talking about different things here. My suggestion
> would not add much more code to the driver than this patch does, calls
> to arm_smmu_enable_clocks() instead of pm_runtime_get_sync() and
> arm_smmu_disable_clocks() instead of pm_runtime_put(). The
> implementation of both functions would be a simple call to clk_bulk_
> API (possibly even no need to put this into functions, just call
> directly).

Well, things are not so straight on msm. The IP clocks on msm are usually
powered by (or i should rather say, controlled by) the same power domain
that provides the VDD supply to iommu block. This is the behavior on msm8996
atleast that we are testing on right now.
On later SoCs too things

Re: [PATCH v7 2/6] iommu/arm-smmu: Add pm_runtime/sleep ops

2018-02-14 Thread Vivek Gautam
Hi Tomasz,


Please find my response inline below.

On Tue, Feb 13, 2018 at 1:33 PM, Tomasz Figa <tf...@chromium.org> wrote:
> Hi Vivek,
>
> Thanks for the patch. Please see some comments inline.
>
> On Wed, Feb 7, 2018 at 7:31 PM, Vivek Gautam
> <vivek.gau...@codeaurora.org> wrote:
>> From: Sricharan R <sricha...@codeaurora.org>
>>
>> The smmu needs to be functional only when the respective
>> master's using it are active. The device_link feature
>> helps to track such functional dependencies, so that the
>> iommu gets powered when the master device enables itself
>> using pm_runtime. So by adapting the smmu driver for
>> runtime pm, above said dependency can be addressed.
>>
>> This patch adds the pm runtime/sleep callbacks to the
>> driver and also the functions to parse the smmu clocks
>> from DT and enable them in resume/suspend.
>>
>> Signed-off-by: Sricharan R <sricha...@codeaurora.org>
>> Signed-off-by: Archit Taneja <arch...@codeaurora.org>
>> [vivek: Clock rework to request bulk of clocks]
>> Signed-off-by: Vivek Gautam <vivek.gau...@codeaurora.org>
>> ---
>>  drivers/iommu/arm-smmu.c | 56 
>> ++--
>>  1 file changed, 54 insertions(+), 2 deletions(-)
>>
>> diff --git a/drivers/iommu/arm-smmu.c b/drivers/iommu/arm-smmu.c
>> index 69e7c60792a8..9e2f917e16c2 100644
>> --- a/drivers/iommu/arm-smmu.c
>> +++ b/drivers/iommu/arm-smmu.c
>> @@ -48,6 +48,7 @@
>>  #include 
>>  #include 
>>  #include 
>> +#include 
>>  #include 
>>  #include 
>>
>> @@ -205,6 +206,8 @@ struct arm_smmu_device {
>> u32 num_global_irqs;
>> u32 num_context_irqs;
>> unsigned int*irqs;
>> +   struct clk_bulk_data*clocks;
>> +   int num_clks;
>
> nit: Perhaps "num_clocks" to be consistent with "clocks"?
>
>>
>> u32 cavium_id_base; /* Specific to 
>> Cavium */
>>
>> @@ -1897,10 +1900,12 @@ static int arm_smmu_device_cfg_probe(struct 
>> arm_smmu_device *smmu)
>>  struct arm_smmu_match_data {
>> enum arm_smmu_arch_version version;
>> enum arm_smmu_implementation model;
>> +   const char * const *clks;
>> +   int num_clks;
>
> nit: Perhaps s/clks/clocks/ here or s/clocks/clks/ in struct arm_smmu_device?

Sure. Will change to s/clocks/clks/ in struct arm_smmu_device.

>
>>  };
>>
>>  #define ARM_SMMU_MATCH_DATA(name, ver, imp)\
>> -static struct arm_smmu_match_data name = { .version = ver, .model = imp }
>> +static const struct arm_smmu_match_data name = { .version = ver, .model = 
>> imp }
>>
>>  ARM_SMMU_MATCH_DATA(smmu_generic_v1, ARM_SMMU_V1, GENERIC_SMMU);
>>  ARM_SMMU_MATCH_DATA(smmu_generic_v2, ARM_SMMU_V2, GENERIC_SMMU);
>> @@ -2001,6 +2006,7 @@ static int arm_smmu_device_dt_probe(struct 
>> platform_device *pdev,
>> data = of_device_get_match_data(dev);
>> smmu->version = data->version;
>> smmu->model = data->model;
>> +   smmu->num_clks = data->num_clks;
>>
>> parse_driver_options(smmu);
>>
>> @@ -2039,6 +2045,28 @@ static void arm_smmu_bus_init(void)
>>  #endif
>>  }
>>
>> +static int arm_smmu_init_clks(struct arm_smmu_device *smmu)
>> +{
>> +   int i;
>> +   int num = smmu->num_clks;
>> +   const struct arm_smmu_match_data *data;
>> +
>> +   if (num < 1)
>> +   return 0;
>> +
>> +   smmu->clocks = devm_kcalloc(smmu->dev, num,
>> +   sizeof(*smmu->clocks), GFP_KERNEL);
>> +   if (!smmu->clocks)
>> +   return -ENOMEM;
>> +
>> +   data = of_device_get_match_data(smmu->dev);
>> +
>> +   for (i = 0; i < num; i++)
>> +   smmu->clocks[i].id = data->clks[i];
>
> I'd argue that arm_smmu_device_dt_probe() is a better place for all
> the code above, since this function is called regardless of whether
> the device is probed from DT or not. Going further,
> arm_smmu_device_acpi_probe() could fill smmu->num_clks and ->clocks
> using ACPI-like way (as opposed to OF match data) if necessary.

Right, it's valid to fill the data in arm_smmu_device_dt_probe().
Perhaps we can just keep the devm_clk_bulk_get() in arm_smmu_device_probe()
at the point where we are currently doing arm_smmu_init_clks().

Thanks & regards
Vivek

>
> Best regards,
> Tomasz
> --
> To unsubscribe from this list: send the line "unsubscribe linux-arm-msm" in
> the body of a message to majord...@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html



-- 
QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member
of Code Aurora Forum, hosted by The Linux Foundation
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


Re: [PATCH v7 3/6] iommu/arm-smmu: Invoke pm_runtime during probe, add/remove device

2018-02-14 Thread Vivek Gautam
Hi Tomasz,


On Tue, Feb 13, 2018 at 1:54 PM, Tomasz Figa <tf...@chromium.org> wrote:
> Hi Vivek,
>
> Thanks for the patch. Please see my comments inline.
>
> On Wed, Feb 7, 2018 at 7:31 PM, Vivek Gautam
> <vivek.gau...@codeaurora.org> wrote:
>> From: Sricharan R <sricha...@codeaurora.org>
>>
>> The smmu device probe/remove and add/remove master device callbacks
>> gets called when the smmu is not linked to its master, that is without
>> the context of the master device. So calling runtime apis in those places
>> separately.
>>
>> Signed-off-by: Sricharan R <sricha...@codeaurora.org>
>> [vivek: Cleanup pm runtime calls]
>> Signed-off-by: Vivek Gautam <vivek.gau...@codeaurora.org>
>> ---
>>  drivers/iommu/arm-smmu.c | 42 ++
>>  1 file changed, 38 insertions(+), 4 deletions(-)
>>
>> diff --git a/drivers/iommu/arm-smmu.c b/drivers/iommu/arm-smmu.c
>> index 9e2f917e16c2..c024f69c1682 100644
>> --- a/drivers/iommu/arm-smmu.c
>> +++ b/drivers/iommu/arm-smmu.c
>> @@ -913,11 +913,15 @@ static void arm_smmu_destroy_domain_context(struct 
>> iommu_domain *domain)
>> struct arm_smmu_domain *smmu_domain = to_smmu_domain(domain);
>> struct arm_smmu_device *smmu = smmu_domain->smmu;
>> struct arm_smmu_cfg *cfg = _domain->cfg;
>> -   int irq;
>> +   int ret, irq;
>>
>> if (!smmu || domain->type == IOMMU_DOMAIN_IDENTITY)
>> return;
>>
>> +   ret = pm_runtime_get_sync(smmu->dev);
>> +   if (ret)
>> +   return;
>
> pm_runtime_get_sync() will return 0 if the device was powered off, 1
> if it was already/still powered on or runtime PM is not compiled in,
> or a negative value on error, so shouldn't the test be (ret < 0)?

Yes, I too noticed it while i was testing on a different platform, and
was hitting
a failure case. Will update at all places.

>
> Moreover, I'm actually wondering if it makes any sense to power up the
> hardware just to program it and power it down again. In a system where
> the IOMMU is located within a power domain, it would cause the IOMMU
> block to lose its state anyway.
>
> Actually, reflecting back on "[PATCH v7 2/6] iommu/arm-smmu: Add
> pm_runtime/sleep ops", perhaps it would make more sense to just
> control the clocks independently of runtime PM? Then, runtime PM could
> be used for real power management, e.g. really powering the block up
> and down, for further power saving.
>
> +Generally similar comments for other places in this patch.
>
>> +
>> /*
>>  * Disable the context bank and free the page tables before freeing
>>  * it.
>> @@ -932,6 +936,8 @@ static void arm_smmu_destroy_domain_context(struct 
>> iommu_domain *domain)
>>
>> free_io_pgtable_ops(smmu_domain->pgtbl_ops);
>> __arm_smmu_free_bitmap(smmu->context_map, cfg->cbndx);
>> +
>> +   pm_runtime_put_sync(smmu->dev);
>
> Is there any point in the put being sync here?

No, I don't think. Can manage with just a 'put' here. Will modify.

best regards
Vivek

>
> [snip]
>
>> @@ -2131,6 +2152,14 @@ static int arm_smmu_device_probe(struct 
>> platform_device *pdev)
>> if (err)
>> return err;
>>
>> +   platform_set_drvdata(pdev, smmu);
>> +
>> +   pm_runtime_enable(dev);
>
> I suspect this may be a disaster for systems where IOMMUs are located
> inside power domains, because the driver doesn't take care of the
> IOMMU block losing its state on physical power down, as I mentioned in
> my comments above.
>
> Best regards,
> Tomasz



-- 
QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member
of Code Aurora Forum, hosted by The Linux Foundation
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


Re: [PATCH v7 4/6] iommu/arm-smmu: Add the device_link between masters and smmu

2018-02-14 Thread Vivek Gautam
Hi Tomasz,


On Tue, Feb 13, 2018 at 2:01 PM, Tomasz Figa <tf...@chromium.org> wrote:
> Hi Vivek,
>
> Thanks for the patch. Please see my comments inline.

Thanks for reviewing the patch series.

>
> On Wed, Feb 7, 2018 at 7:31 PM, Vivek Gautam
> <vivek.gau...@codeaurora.org> wrote:
>> From: Sricharan R <sricha...@codeaurora.org>
>>
>> Finally add the device link between the master device and
>> smmu, so that the smmu gets runtime enabled/disabled only when the
>> master needs it. This is done from add_device callback which gets
>> called once when the master is added to the smmu.
>>
>> Signed-off-by: Sricharan R <sricha...@codeaurora.org>
>> Signed-off-by: Vivek Gautam <vivek.gau...@codeaurora.org>
>> ---
>>  drivers/iommu/arm-smmu.c | 16 
>>  1 file changed, 16 insertions(+)
>>
>> diff --git a/drivers/iommu/arm-smmu.c b/drivers/iommu/arm-smmu.c
>> index c024f69c1682..c7e924d553bd 100644
>> --- a/drivers/iommu/arm-smmu.c
>> +++ b/drivers/iommu/arm-smmu.c
>> @@ -215,6 +215,9 @@ struct arm_smmu_device {
>>
>> /* IOMMU core code handle */
>> struct iommu_device iommu;
>> +
>> +   /* runtime PM link to master */
>> +   struct device_link *link;
>>  };
>>
>>  enum arm_smmu_context_fmt {
>> @@ -1425,6 +1428,17 @@ static int arm_smmu_add_device(struct device *dev)
>>
>> pm_runtime_put_sync(smmu->dev);
>>
>> +   /*
>> +* Establish the link between smmu and master, so that the
>> +* smmu gets runtime enabled/disabled as per the master's
>> +* needs.
>> +*/
>> +   smmu->link = device_link_add(dev, smmu->dev, DL_FLAG_PM_RUNTIME);
>> +   if (!smmu->link)
>> +   dev_warn(smmu->dev,
>> +"Unable to create device link between %s and %s\n",
>> +dev_name(smmu->dev), dev_name(dev));
>
> How likely it is that the master can work normally even if the link
> add fails? Perhaps we should just return an error here?

Right. We are assuming that the power is handled for most of the
smmu operations, after we add the master with smmu, based on the fact
that the device link is successful.
We should return error code here. Will make the necessary change.

>
>> +
>> return 0;
>>
>>  out_rpm_put:
>> @@ -1449,6 +1463,8 @@ static void arm_smmu_remove_device(struct device *dev)
>> cfg  = fwspec->iommu_priv;
>> smmu = cfg->smmu;
>>
>> +   device_link_del(smmu->link);
>
> We allowed smmu->link in arm_smmu_add_device(), but here we don't
> check it. Looking at the code, device_link_del() doesn't seem to check
> either.
>
> Note that this problem would go away if we fail add_device on
> device_link_add() failure, as I suggested above, so no change would be
> necessary.

Sure. After making the above change, this should also be handled.

Best regards
Vivek

>
> Best regards,
> Tomasz



-- 
QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member
of Code Aurora Forum, hosted by The Linux Foundation
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


Re: [PATCH v7 6/6] drm/msm: iommu: Replace runtime calls with runtime suppliers

2018-02-14 Thread Vivek Gautam
Hi Tomasz,

On Wed, Feb 14, 2018 at 8:31 AM, Tomasz Figa <tf...@chromium.org> wrote:
> On Wed, Feb 14, 2018 at 11:13 AM, Rob Clark <robdcl...@gmail.com> wrote:
>> On Tue, Feb 13, 2018 at 8:59 PM, Tomasz Figa <tf...@chromium.org> wrote:
>>> On Wed, Feb 14, 2018 at 3:03 AM, Rob Clark <robdcl...@gmail.com> wrote:
>>>> On Tue, Feb 13, 2018 at 4:10 AM, Tomasz Figa <tf...@chromium.org> wrote:
>>>>> Hi Vivek,
>>>>>
>>>>> Thanks for the patch. Please see my comments inline.
>>>>>
>>>>> On Wed, Feb 7, 2018 at 7:31 PM, Vivek Gautam
>>>>> <vivek.gau...@codeaurora.org> wrote:
>>>>>> While handling the concerned iommu, there should not be a
>>>>>> need to power control the drm devices from iommu interface.
>>>>>> If these drm devices need to be powered around this time,
>>>>>> the respective drivers should take care of this.
>>>>>>
>>>>>> Replace the pm_runtime_get/put_sync() with
>>>>>> pm_runtime_get/put_suppliers() calls, to power-up
>>>>>> the connected iommu through the device link interface.
>>>>>> In case the device link is not setup these get/put_suppliers()
>>>>>> calls will be a no-op, and the iommu driver should take care of
>>>>>> powering on its devices accordingly.
>>>>>>
>>>>>> Signed-off-by: Vivek Gautam <vivek.gau...@codeaurora.org>
>>>>>> ---
>>>>>>  drivers/gpu/drm/msm/msm_iommu.c | 16 
>>>>>>  1 file changed, 8 insertions(+), 8 deletions(-)
>>>>>>
>>>>>> diff --git a/drivers/gpu/drm/msm/msm_iommu.c 
>>>>>> b/drivers/gpu/drm/msm/msm_iommu.c
>>>>>> index b23d33622f37..1ab629bbee69 100644
>>>>>> --- a/drivers/gpu/drm/msm/msm_iommu.c
>>>>>> +++ b/drivers/gpu/drm/msm/msm_iommu.c
>>>>>> @@ -40,9 +40,9 @@ static int msm_iommu_attach(struct msm_mmu *mmu, const 
>>>>>> char * const *names,
>>>>>> struct msm_iommu *iommu = to_msm_iommu(mmu);
>>>>>> int ret;
>>>>>>
>>>>>> -   pm_runtime_get_sync(mmu->dev);
>>>>>> +   pm_runtime_get_suppliers(mmu->dev);
>>>>>> ret = iommu_attach_device(iommu->domain, mmu->dev);
>>>>>> -   pm_runtime_put_sync(mmu->dev);
>>>>>> +   pm_runtime_put_suppliers(mmu->dev);
>>>>>
>>>>> For me, it looks like a wrong place to handle runtime PM of IOMMU
>>>>> here. iommu_attach_device() calls into IOMMU driver's attach_device()
>>>>> callback and that's where necessary runtime PM gets should happen, if
>>>>> any. In other words, driver A (MSM DRM driver) shouldn't be dealing
>>>>> with power state of device controlled by driver B (ARM SMMU).
>>>>
>>>> Note that we end up having to do the same, because of iommu_unmap()
>>>> while DRM driver is powered off..  it might be cleaner if it was all
>>>> self contained in the iommu driver, but that would make it so other
>>>> drivers couldn't call iommu_unmap() from an irq handler, which is
>>>> apparently something that some of them want to do..
>>>
>>> I'd assume that runtime PM status is already guaranteed to be active
>>> when the IRQ handler is running, by some other means (e.g.
>>> pm_runtime_get_sync() called earlier, when queuing some work to the
>>> hardware). Otherwise, I'm not sure how a powered down device could
>>> trigger an IRQ.
>>>
>>> So, if the master device power is already on, suppliers should be
>>> powered on as well, thanks to device links.
>>>
>>
>> umm, that is kindof the inverse of the problem..  the problem is
>> things like gpu driver (and v4l2 drivers that import dma-buf's,
>> afaict).. they will potentially call iommu->unmap() when device is not
>> active (due to userspace or things beyond the control of the driver)..
>> so *they* would want iommu to do pm get/put calls.
>
> Which is fine and which is actually already done by one of the patches
> in this series, not for map/unmap, but probe, add_device,
> remove_device. Having parts of the API doing it inside the callback
> and other parts outside sounds at least inconsistent.
>
>> But other drivers
>> trying to unmap from irq ctx would not.  Which is t

Re: [PATCH v7 6/6] drm/msm: iommu: Replace runtime calls with runtime suppliers

2018-02-14 Thread Vivek Gautam
Hi Tomasz,

On Wed, Feb 14, 2018 at 11:08 AM, Tomasz Figa <tf...@chromium.org> wrote:
> On Wed, Feb 14, 2018 at 1:17 PM, Vivek Gautam
> <vivek.gau...@codeaurora.org> wrote:
>> Hi Tomasz,
>>
>> On Wed, Feb 14, 2018 at 8:31 AM, Tomasz Figa <tf...@chromium.org> wrote:
>>> On Wed, Feb 14, 2018 at 11:13 AM, Rob Clark <robdcl...@gmail.com> wrote:
>>>> On Tue, Feb 13, 2018 at 8:59 PM, Tomasz Figa <tf...@chromium.org> wrote:
>>>>> On Wed, Feb 14, 2018 at 3:03 AM, Rob Clark <robdcl...@gmail.com> wrote:
>>>>>> On Tue, Feb 13, 2018 at 4:10 AM, Tomasz Figa <tf...@chromium.org> wrote:
>>>>>>> Hi Vivek,
>>>>>>>
>>>>>>> Thanks for the patch. Please see my comments inline.
>>>>>>>
>>>>>>> On Wed, Feb 7, 2018 at 7:31 PM, Vivek Gautam
>>>>>>> <vivek.gau...@codeaurora.org> wrote:
>>>>>>>> While handling the concerned iommu, there should not be a
>>>>>>>> need to power control the drm devices from iommu interface.
>>>>>>>> If these drm devices need to be powered around this time,
>>>>>>>> the respective drivers should take care of this.
>>>>>>>>
>>>>>>>> Replace the pm_runtime_get/put_sync() with
>>>>>>>> pm_runtime_get/put_suppliers() calls, to power-up
>>>>>>>> the connected iommu through the device link interface.
>>>>>>>> In case the device link is not setup these get/put_suppliers()
>>>>>>>> calls will be a no-op, and the iommu driver should take care of
>>>>>>>> powering on its devices accordingly.
>>>>>>>>
>>>>>>>> Signed-off-by: Vivek Gautam <vivek.gau...@codeaurora.org>
>>>>>>>> ---
>>>>>>>>  drivers/gpu/drm/msm/msm_iommu.c | 16 
>>>>>>>>  1 file changed, 8 insertions(+), 8 deletions(-)
>>>>>>>>
>>>>>>>> diff --git a/drivers/gpu/drm/msm/msm_iommu.c 
>>>>>>>> b/drivers/gpu/drm/msm/msm_iommu.c
>>>>>>>> index b23d33622f37..1ab629bbee69 100644
>>>>>>>> --- a/drivers/gpu/drm/msm/msm_iommu.c
>>>>>>>> +++ b/drivers/gpu/drm/msm/msm_iommu.c
>>>>>>>> @@ -40,9 +40,9 @@ static int msm_iommu_attach(struct msm_mmu *mmu, 
>>>>>>>> const char * const *names,
>>>>>>>> struct msm_iommu *iommu = to_msm_iommu(mmu);
>>>>>>>> int ret;
>>>>>>>>
>>>>>>>> -   pm_runtime_get_sync(mmu->dev);
>>>>>>>> +   pm_runtime_get_suppliers(mmu->dev);
>>>>>>>> ret = iommu_attach_device(iommu->domain, mmu->dev);
>>>>>>>> -   pm_runtime_put_sync(mmu->dev);
>>>>>>>> +   pm_runtime_put_suppliers(mmu->dev);
>>>>>>>
>>>>>>> For me, it looks like a wrong place to handle runtime PM of IOMMU
>>>>>>> here. iommu_attach_device() calls into IOMMU driver's attach_device()
>>>>>>> callback and that's where necessary runtime PM gets should happen, if
>>>>>>> any. In other words, driver A (MSM DRM driver) shouldn't be dealing
>>>>>>> with power state of device controlled by driver B (ARM SMMU).
>>>>>>
>>>>>> Note that we end up having to do the same, because of iommu_unmap()
>>>>>> while DRM driver is powered off..  it might be cleaner if it was all
>>>>>> self contained in the iommu driver, but that would make it so other
>>>>>> drivers couldn't call iommu_unmap() from an irq handler, which is
>>>>>> apparently something that some of them want to do..
>>>>>
>>>>> I'd assume that runtime PM status is already guaranteed to be active
>>>>> when the IRQ handler is running, by some other means (e.g.
>>>>> pm_runtime_get_sync() called earlier, when queuing some work to the
>>>>> hardware). Otherwise, I'm not sure how a powered down device could
>>>>> trigger an IRQ.
>>>>>
>>>>> So, if the master device power is already on, suppliers should be
>>>>> powered on as well, thanks to device links.
>>>>>
>>>>

Re: [PATCH v7 6/6] drm/msm: iommu: Replace runtime calls with runtime suppliers

2018-02-14 Thread Vivek Gautam
On Wed, Feb 14, 2018 at 2:46 PM, Tomasz Figa <tf...@chromium.org> wrote:

Adding Jordan to this thread as well.

> On Wed, Feb 14, 2018 at 6:13 PM, Vivek Gautam
> <vivek.gau...@codeaurora.org> wrote:
>> Hi Tomasz,
>>
>> On Wed, Feb 14, 2018 at 11:08 AM, Tomasz Figa <tf...@chromium.org> wrote:
>>> On Wed, Feb 14, 2018 at 1:17 PM, Vivek Gautam
>>> <vivek.gau...@codeaurora.org> wrote:
>>>> Hi Tomasz,
>>>>
>>>> On Wed, Feb 14, 2018 at 8:31 AM, Tomasz Figa <tf...@chromium.org> wrote:
>>>>> On Wed, Feb 14, 2018 at 11:13 AM, Rob Clark <robdcl...@gmail.com> wrote:
>>>>>> On Tue, Feb 13, 2018 at 8:59 PM, Tomasz Figa <tf...@chromium.org> wrote:
>>>>>>> On Wed, Feb 14, 2018 at 3:03 AM, Rob Clark <robdcl...@gmail.com> wrote:
>>>>>>>> On Tue, Feb 13, 2018 at 4:10 AM, Tomasz Figa <tf...@chromium.org> 
>>>>>>>> wrote:
>>>>>>>>> Hi Vivek,
>>>>>>>>>
>>>>>>>>> Thanks for the patch. Please see my comments inline.
>>>>>>>>>
>>>>>>>>> On Wed, Feb 7, 2018 at 7:31 PM, Vivek Gautam
>>>>>>>>> <vivek.gau...@codeaurora.org> wrote:
>>>>>>>>>> While handling the concerned iommu, there should not be a
>>>>>>>>>> need to power control the drm devices from iommu interface.
>>>>>>>>>> If these drm devices need to be powered around this time,
>>>>>>>>>> the respective drivers should take care of this.
>>>>>>>>>>
>>>>>>>>>> Replace the pm_runtime_get/put_sync() with
>>>>>>>>>> pm_runtime_get/put_suppliers() calls, to power-up
>>>>>>>>>> the connected iommu through the device link interface.
>>>>>>>>>> In case the device link is not setup these get/put_suppliers()
>>>>>>>>>> calls will be a no-op, and the iommu driver should take care of
>>>>>>>>>> powering on its devices accordingly.
>>>>>>>>>>
>>>>>>>>>> Signed-off-by: Vivek Gautam <vivek.gau...@codeaurora.org>
>>>>>>>>>> ---
>>>>>>>>>>  drivers/gpu/drm/msm/msm_iommu.c | 16 
>>>>>>>>>>  1 file changed, 8 insertions(+), 8 deletions(-)
>>>>>>>>>>
>>>>>>>>>> diff --git a/drivers/gpu/drm/msm/msm_iommu.c 
>>>>>>>>>> b/drivers/gpu/drm/msm/msm_iommu.c
>>>>>>>>>> index b23d33622f37..1ab629bbee69 100644
>>>>>>>>>> --- a/drivers/gpu/drm/msm/msm_iommu.c
>>>>>>>>>> +++ b/drivers/gpu/drm/msm/msm_iommu.c
>>>>>>>>>> @@ -40,9 +40,9 @@ static int msm_iommu_attach(struct msm_mmu *mmu, 
>>>>>>>>>> const char * const *names,
>>>>>>>>>> struct msm_iommu *iommu = to_msm_iommu(mmu);
>>>>>>>>>> int ret;
>>>>>>>>>>
>>>>>>>>>> -   pm_runtime_get_sync(mmu->dev);
>>>>>>>>>> +   pm_runtime_get_suppliers(mmu->dev);
>>>>>>>>>> ret = iommu_attach_device(iommu->domain, mmu->dev);
>>>>>>>>>> -   pm_runtime_put_sync(mmu->dev);
>>>>>>>>>> +   pm_runtime_put_suppliers(mmu->dev);
>>>>>>>>>
>>>>>>>>> For me, it looks like a wrong place to handle runtime PM of IOMMU
>>>>>>>>> here. iommu_attach_device() calls into IOMMU driver's attach_device()
>>>>>>>>> callback and that's where necessary runtime PM gets should happen, if
>>>>>>>>> any. In other words, driver A (MSM DRM driver) shouldn't be dealing
>>>>>>>>> with power state of device controlled by driver B (ARM SMMU).
>>>>>>>>
>>>>>>>> Note that we end up having to do the same, because of iommu_unmap()
>>>>>>>> while DRM driver is powered off..  it might be cleaner if it was all
>>>>>>>> self contained in the iommu driver, but that would make it so other
>>>>>>>> drivers couldn't call 

Re: [PATCH v7 6/6] drm/msm: iommu: Replace runtime calls with runtime suppliers

2018-02-23 Thread Vivek Gautam
Hi,

On Thu, Feb 22, 2018 at 7:42 PM, Tomasz Figa  wrote:
> On Thu, Feb 22, 2018 at 10:45 PM, Robin Murphy  wrote:
>> [sorry, I had intended to reply sooner but clearly forgot]
>>
>>
>> On 16/02/18 00:13, Tomasz Figa wrote:
>>>
>>> On Fri, Feb 16, 2018 at 2:14 AM, Robin Murphy 
>>> wrote:

 On 15/02/18 04:17, Tomasz Figa wrote:
 [...]
>>
>>
>> Could you elaborate on what kind of locking you are concerned about?
>> As I explained before, the normally happening fast path would lock
>> dev->power_lock only for the brief moment of incrementing the runtime
>> PM usage counter.
>
>
>
> My bad, that's not even it.
>
> The atomic usage counter is incremented beforehands, without any
> locking [1] and the spinlock is acquired only for the sake of
> validating that device's runtime PM state remained valid indeed [2],
> which would be the case in the fast path of the same driver doing two
> mappings in parallel, with the master powered on (and so the SMMU,
> through device links; if master was not powered on already, powering
> on the SMMU is unavoidable anyway and it would add much more latency
> than the spinlock itself).



 We now have no locking at all in the map path, and only a per-domain lock
 around TLB sync in unmap which is unfortunately necessary for
 correctness;
 the latter isn't too terrible, since in "serious" hardware it should only
 be
 serialising a few cpus serving the same device against each other (e.g.
 for
 multiple queues on a single NIC).

 Putting in a global lock which serialises *all* concurrent map and unmap
 calls for *all* unrelated devices makes things worse. Period. Even if the
 lock itself were held for the minimum possible time, i.e. trivially
 "spin_lock(); spin_unlock()", the cost of repeatedly bouncing
 that
 one cache line around between 96 CPUs across two sockets is not
 negligible.
>>>
>>>
>>> Fair enough. Note that we're in a quite interesting situation now:
>>>   a) We need to have runtime PM enabled on Qualcomm SoC to have power
>>> properly managed,
>>>   b) We need to have lock-free map/unmap on such distributed systems,
>>>   c) If runtime PM is enabled, we need to call into runtime PM from any
>>> code that does hardware accesses, otherwise the IOMMU API (and so DMA
>>> API and then any V4L2 driver) becomes unusable.
>>>
>>> I can see one more way that could potentially let us have all the
>>> three. How about enabling runtime PM only on selected implementations
>>> (e.g. qcom,smmu) and then having all the runtime PM calls surrounded
>>> with if (pm_runtime_enabled()), which is lockless?
>>
>>
>> Yes, that's the kind of thing I was gravitating towards - my vague thought
>> was adding some flag to the smmu_domain, but pm_runtime_enabled() does look
>> conceptually a lot cleaner.
>
> Great, thanks. Looks like we're in agreement now. \o/
>
> Vivek, does this sound reasonable to you?

Yea, sound good to me. I will respin the patches.

Thanks & Regards
Vivek

>
> Best regards,
> Tomasz



-- 
QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member
of Code Aurora Forum, hosted by The Linux Foundation
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


Re: [PATCH v7 3/6] iommu/arm-smmu: Invoke pm_runtime during probe, add/remove device

2018-02-25 Thread Vivek Gautam
On Fri, Feb 23, 2018 at 5:22 AM, Jordan Crouse <jcro...@codeaurora.org> wrote:
> On Wed, Feb 07, 2018 at 04:01:19PM +0530, Vivek Gautam wrote:
>> From: Sricharan R <sricha...@codeaurora.org>
>>
>> The smmu device probe/remove and add/remove master device callbacks
>> gets called when the smmu is not linked to its master, that is without
>> the context of the master device. So calling runtime apis in those places
>> separately.
>>
>> Signed-off-by: Sricharan R <sricha...@codeaurora.org>
>> [vivek: Cleanup pm runtime calls]
>> Signed-off-by: Vivek Gautam <vivek.gau...@codeaurora.org>
>> ---
>>  drivers/iommu/arm-smmu.c | 42 ++
>>  1 file changed, 38 insertions(+), 4 deletions(-)
>>
>> diff --git a/drivers/iommu/arm-smmu.c b/drivers/iommu/arm-smmu.c
>> index 9e2f917e16c2..c024f69c1682 100644
>> --- a/drivers/iommu/arm-smmu.c
>> +++ b/drivers/iommu/arm-smmu.c
>> @@ -913,11 +913,15 @@ static void arm_smmu_destroy_domain_context(struct 
>> iommu_domain *domain)
>>   struct arm_smmu_domain *smmu_domain = to_smmu_domain(domain);
>>   struct arm_smmu_device *smmu = smmu_domain->smmu;
>>   struct arm_smmu_cfg *cfg = _domain->cfg;
>> - int irq;
>> + int ret, irq;
>>
>>   if (!smmu || domain->type == IOMMU_DOMAIN_IDENTITY)
>>   return;
>>
>> + ret = pm_runtime_get_sync(smmu->dev);
>> + if (ret)
>> + return;
>> +
>>   /*
>>* Disable the context bank and free the page tables before freeing
>>* it.
>> @@ -932,6 +936,8 @@ static void arm_smmu_destroy_domain_context(struct 
>> iommu_domain *domain)
>>
>>   free_io_pgtable_ops(smmu_domain->pgtbl_ops);
>>   __arm_smmu_free_bitmap(smmu->context_map, cfg->cbndx);
>> +
>> + pm_runtime_put_sync(smmu->dev);
>>  }
>>
>>  static struct iommu_domain *arm_smmu_domain_alloc(unsigned type)
>> @@ -1407,14 +1413,22 @@ static int arm_smmu_add_device(struct device *dev)
>>   while (i--)
>>   cfg->smendx[i] = INVALID_SMENDX;
>>
>> - ret = arm_smmu_master_alloc_smes(dev);
>> + ret = pm_runtime_get_sync(smmu->dev);
>>   if (ret)
>>   goto out_cfg_free;
>
> Hey Vivek, I just hit a problem with this on sdm845. It turns out that
> pm_runtime_get_sync() returns a positive 1 if the device is already active.
>
> I hit this in the GPU code. The a6xx has two platform devices that each use a
> different sid on the iommu. The GPU is probed normally from a platform driver
> and it in turn initializes the GMU device by way of a phandle.
>
> Because the GMU isn't probed with a platform driver we need to call
> of_dma_configure() on the device to set up the IOMMU for the device which ends
> up calling through this path and we discover that the smmu->dev is already
> powered (pm_runtime_get_sync returns 1).
>
> I'm not immediately sure if this is a bug on sdm845 or not because a cursory
> inspection says that the SMMU device shouldn't be powered at this time but 
> there
> might be a connection that I'm not seeing. Obviously if the SMMU was left
> powered thats a bad thing. But putting that aside it is obvious that this
> code should be accommodating of the possibility that the device is already
> powered, and so this should be
>
> if (ret < 0)
> goto out_cfg_free;

Right, as Tomasz also pointed, we should surely check the negative value of
pm_runtime_get_sync().

From your description, it may be that the GPU has turned on the smmu, and
then once if goes and probes the GMU, the GMU device also wants to turn-on
the same smmu device. But that's already active. So pm_runtime_get_sync()
returns 1.
Am i making sense?

regards
Vivek

>
> With that the GPU/GMU successfully comes up on Sean Paul's display testing
> branch.
>
> Jordan
>
> --
> The Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
> a Linux Foundation Collaborative Project
> --
> To unsubscribe from this list: send the line "unsubscribe linux-arm-msm" in
> the body of a message to majord...@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html



-- 
QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member
of Code Aurora Forum, hosted by The Linux Foundation
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


Re: [Freedreno] [PATCH v7 3/6] iommu/arm-smmu: Invoke pm_runtime during probe, add/remove device

2018-02-25 Thread Vivek Gautam
On Fri, Feb 23, 2018 at 9:10 PM, Jordan Crouse <jcro...@codeaurora.org> wrote:
> On Fri, Feb 23, 2018 at 04:06:39PM +0530, Vivek Gautam wrote:
>> On Fri, Feb 23, 2018 at 5:22 AM, Jordan Crouse <jcro...@codeaurora.org> 
>> wrote:
>> > On Wed, Feb 07, 2018 at 04:01:19PM +0530, Vivek Gautam wrote:
>> >> From: Sricharan R <sricha...@codeaurora.org>
>> >>
>> >> The smmu device probe/remove and add/remove master device callbacks
>> >> gets called when the smmu is not linked to its master, that is without
>> >> the context of the master device. So calling runtime apis in those places
>> >> separately.
>> >>
>> >> Signed-off-by: Sricharan R <sricha...@codeaurora.org>
>> >> [vivek: Cleanup pm runtime calls]
>> >> Signed-off-by: Vivek Gautam <vivek.gau...@codeaurora.org>
>> >> ---
>> >>  drivers/iommu/arm-smmu.c | 42 ++
>> >>  1 file changed, 38 insertions(+), 4 deletions(-)
>> >>
>> >> diff --git a/drivers/iommu/arm-smmu.c b/drivers/iommu/arm-smmu.c
>> >> index 9e2f917e16c2..c024f69c1682 100644
>> >> --- a/drivers/iommu/arm-smmu.c
>> >> +++ b/drivers/iommu/arm-smmu.c
>> >> @@ -913,11 +913,15 @@ static void arm_smmu_destroy_domain_context(struct 
>> >> iommu_domain *domain)
>> >>   struct arm_smmu_domain *smmu_domain = to_smmu_domain(domain);
>> >>   struct arm_smmu_device *smmu = smmu_domain->smmu;
>> >>   struct arm_smmu_cfg *cfg = _domain->cfg;
>> >> - int irq;
>> >> + int ret, irq;
>> >>
>> >>   if (!smmu || domain->type == IOMMU_DOMAIN_IDENTITY)
>> >>   return;
>> >>
>> >> + ret = pm_runtime_get_sync(smmu->dev);
>> >> + if (ret)
>> >> + return;
>> >> +
>> >>   /*
>> >>* Disable the context bank and free the page tables before freeing
>> >>* it.
>> >> @@ -932,6 +936,8 @@ static void arm_smmu_destroy_domain_context(struct 
>> >> iommu_domain *domain)
>> >>
>> >>   free_io_pgtable_ops(smmu_domain->pgtbl_ops);
>> >>   __arm_smmu_free_bitmap(smmu->context_map, cfg->cbndx);
>> >> +
>> >> + pm_runtime_put_sync(smmu->dev);
>> >>  }
>> >>
>> >>  static struct iommu_domain *arm_smmu_domain_alloc(unsigned type)
>> >> @@ -1407,14 +1413,22 @@ static int arm_smmu_add_device(struct device *dev)
>> >>   while (i--)
>> >>   cfg->smendx[i] = INVALID_SMENDX;
>> >>
>> >> - ret = arm_smmu_master_alloc_smes(dev);
>> >> + ret = pm_runtime_get_sync(smmu->dev);
>> >>   if (ret)
>> >>   goto out_cfg_free;
>> >
>> > Hey Vivek, I just hit a problem with this on sdm845. It turns out that
>> > pm_runtime_get_sync() returns a positive 1 if the device is already active.
>> >
>> > I hit this in the GPU code. The a6xx has two platform devices that each 
>> > use a
>> > different sid on the iommu. The GPU is probed normally from a platform 
>> > driver
>> > and it in turn initializes the GMU device by way of a phandle.
>> >
>> > Because the GMU isn't probed with a platform driver we need to call
>> > of_dma_configure() on the device to set up the IOMMU for the device which 
>> > ends
>> > up calling through this path and we discover that the smmu->dev is already
>> > powered (pm_runtime_get_sync returns 1).
>> >
>> > I'm not immediately sure if this is a bug on sdm845 or not because a 
>> > cursory
>> > inspection says that the SMMU device shouldn't be powered at this time but 
>> > there
>> > might be a connection that I'm not seeing. Obviously if the SMMU was left
>> > powered thats a bad thing. But putting that aside it is obvious that this
>> > code should be accommodating of the possibility that the device is already
>> > powered, and so this should be
>> >
>> > if (ret < 0)
>> > goto out_cfg_free;
>>
>> Right, as Tomasz also pointed, we should surely check the negative value of
>> pm_runtime_get_sync().
>
> Sorry, I didn't notice that Tomasz had pointed it out as well. I wanted to
> quickly get it on the mailing list so you could catch it in your time zone.
>
>> From

Re: [PATCH 5/9] arm64: dts: sdm845: Add gpu and gmu device nodes

2018-08-29 Thread Vivek Gautam
Hi Jordan,

On Mon, Aug 27, 2018 at 8:42 PM Jordan Crouse  wrote:
>
> Add the nodes to describe the Adreno GPU and GMU devices.
>
> Signed-off-by: Jordan Crouse 
> ---
>  arch/arm64/boot/dts/qcom/sdm845.dtsi | 121 +++
>  1 file changed, 121 insertions(+)
>
> diff --git a/arch/arm64/boot/dts/qcom/sdm845.dtsi 
> b/arch/arm64/boot/dts/qcom/sdm845.dtsi
> index cdaabeb3c995..10db0ceb3699 100644
> --- a/arch/arm64/boot/dts/qcom/sdm845.dtsi
> +++ b/arch/arm64/boot/dts/qcom/sdm845.dtsi
> @@ -192,6 +192,59 @@
> method = "smc";
> };
>
> +gpu_opp_table: adreno-opp-table {
> +   compatible = "operating-points-v2-qcom-level";
> +
> +   opp-71000 {
> +   opp-hz = /bits/ 64 <71000>;
> +   qcom,level = <416>;
> +   };
> +
> +   opp-67500 {
> +   opp-hz = /bits/ 64 <67500>;
> +   qcom,level = <384>;
> +   };
> +
> +   opp-59600 {
> +   opp-hz = /bits/ 64 <59600>;
> +   qcom,level = <320>;
> +   };
> +
> +   opp-52000 {
> +   opp-hz = /bits/ 64 <52000>;
> +   qcom,level = <256>;
> +   };
> +
> +   opp-41400 {
> +   opp-hz = /bits/ 64 <41400>;
> +   qcom,level = <192>;
> +   };
> +
> +   opp-34200 {
> +   opp-hz = /bits/ 64 <34200>;
> +   qcom,level = <128>;
> +   };
> +
> +   opp-25700 {
> +   opp-hz = /bits/ 64 <25700>;
> +   qcom,level = <64>;
> +   };
> +   };
> +
> +   gmu_opp_table: adreno-gmu-opp-table {
> +   compatible = "operating-points-v2-qcom-level";
> +
> +   opp-4 {
> +   opp-hz = /bits/ 64 <4>;
> +   qcom,level = <128>;
> +   };
> +
> +   opp-2 {
> +   opp-hz = /bits/ 64 <2>;
> +   qcom,level = <48>;
> +   };
> +   };
> +
> soc: soc {
> #address-cells = <1>;
> #size-cells = <1>;
> @@ -323,5 +376,73 @@
> status = "disabled";
> };
> };
> +
> +   adreno_smmu: adreno-smmu@504 {

iommu@504 as pointed out by Rob in [1]

> +   compatible = "qcom,sdm845-smmu-v2", "qcom,smmu-v2";
> +   reg = <0x504 0x1>;
> +   #iommu-cells = <1>;
> +   #global-interrupts = <2>;
> +   interrupts = ,
> +   ,
> +   ,
> +   ,
> +   ,
> +   ,
> +   ,
> +   ,
> +   ,
> +   ;
> +   clocks = < GCC_GPU_MEMNOC_GFX_CLK>,
> +   < GCC_GPU_CFG_AHB_CLK>;
> +   clock-names = "bus", "iface";
> +
> +   power-domains = < GPU_CX_GDSC>;

and for this you need to include the gpucc dt-bindings header which is coming
from Amit's gpucc driver patch.

[1] https://patchwork.kernel.org/patch/10534999/

Best regards
Vivek

[snip]

-- 
QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member
of Code Aurora Forum, hosted by The Linux Foundation
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


Re: [PATCH 1/2] device core: Rename flag AUTOREMOVE to AUTOREMOVE_CONSUMER

2018-07-05 Thread Vivek Gautam
On Wed, Jul 4, 2018 at 6:25 PM, Ulf Hansson  wrote:
> On 27 June 2018 at 14:50, Vivek Gautam  wrote:
>> Now that we want to add another flag to autoremove the device link
>> on supplier unbind, it's fair to rename the existing flag from
>> DL_FLAG_AUTOREMOVE to DL_FLAG_AUTOREMOVE_CONSUMER so that we can
>> add similar flag for supplier later.
>> And, while we are touching device.h, fix a doc build warning.
>>
>> Signed-off-by: Vivek Gautam 
>> Cc: Lukas Wunner 
>> Cc: Jonathan Corbet 
>> Cc: Greg Kroah-Hartman 
>> Cc: Thierry Reding 
>> Cc: David Airlie 
>> Cc: Jonathan Hunter 
>> Cc: Philipp Zabel 
>> Cc: Shawn Guo 
>> Cc: Sascha Hauer 
>> Cc: Robin Murphy 
>> Cc: linux-...@vger.kernel.org
>> Cc: dri-devel@lists.freedesktop.org
>> Cc: linux-te...@vger.kernel.org
>> Cc: linux-arm-ker...@lists.infradead.org
>> Cc: linux...@vger.kernel.org
>> Cc: linux-arm-...@vger.kernel.org
>
> Reviewed-by: Ulf Hansson 

Thank you Ulf for reviewing the series.

Best regards
Vivek

>
> Kind regards
> Uffe
>
>> ---
>>  Documentation/driver-api/device_link.rst |  8 
>>  drivers/base/core.c  | 15 ---
>>  drivers/gpu/drm/tegra/dc.c   |  2 +-
>>  drivers/gpu/ipu-v3/ipu-pre.c |  3 ++-
>>  drivers/gpu/ipu-v3/ipu-prg.c |  3 ++-
>>  drivers/soc/imx/gpc.c|  2 +-
>>  include/linux/device.h   | 12 ++--
>>  7 files changed, 24 insertions(+), 21 deletions(-)
>>
>> diff --git a/Documentation/driver-api/device_link.rst 
>> b/Documentation/driver-api/device_link.rst
>> index 70e328e16aad..a005b904a264 100644
>> --- a/Documentation/driver-api/device_link.rst
>> +++ b/Documentation/driver-api/device_link.rst
>> @@ -81,10 +81,10 @@ integration is desired.
>>  Two other flags are specifically targeted at use cases where the device
>>  link is added from the consumer's ``->probe`` callback:  
>> ``DL_FLAG_RPM_ACTIVE``
>>  can be specified to runtime resume the supplier upon addition of the
>> -device link.  ``DL_FLAG_AUTOREMOVE`` causes the device link to be 
>> automatically
>> -purged when the consumer fails to probe or later unbinds.  This obviates
>> -the need to explicitly delete the link in the ``->remove`` callback or in
>> -the error path of the ``->probe`` callback.
>> +device link.  ``DL_FLAG_AUTOREMOVE_CONSUMER`` causes the device link to be
>> +automatically purged when the consumer fails to probe or later unbinds.
>> +This obviates the need to explicitly delete the link in the ``->remove``
>> +callback or in the error path of the ``->probe`` callback.
>>
>>  Limitations
>>  ===
>> diff --git a/drivers/base/core.c b/drivers/base/core.c
>> index df3e1a44707a..14c1e3151e08 100644
>> --- a/drivers/base/core.c
>> +++ b/drivers/base/core.c
>> @@ -178,10 +178,10 @@ void device_pm_move_to_tail(struct device *dev)
>>   * of the link.  If DL_FLAG_PM_RUNTIME is not set, DL_FLAG_RPM_ACTIVE will 
>> be
>>   * ignored.
>>   *
>> - * If the DL_FLAG_AUTOREMOVE is set, the link will be removed automatically
>> - * when the consumer device driver unbinds from it.  The combination of both
>> - * DL_FLAG_AUTOREMOVE and DL_FLAG_STATELESS set is invalid and will cause 
>> NULL
>> - * to be returned.
>> + * If the DL_FLAG_AUTOREMOVE_CONSUMER is set, the link will be removed
>> + * automatically when the consumer device driver unbinds from it.
>> + * The combination of both DL_FLAG_AUTOREMOVE_CONSUMER and DL_FLAG_STATELESS
>> + * set is invalid and will cause NULL to be returned.
>>   *
>>   * A side effect of the link creation is re-ordering of dpm_list and the
>>   * devices_kset list by moving the consumer device and all devices depending
>> @@ -198,7 +198,8 @@ struct device_link *device_link_add(struct device 
>> *consumer,
>> struct device_link *link;
>>
>> if (!consumer || !supplier ||
>> -   ((flags & DL_FLAG_STATELESS) && (flags & DL_FLAG_AUTOREMOVE)))
>> +   ((flags & DL_FLAG_STATELESS) &&
>> +(flags & DL_FLAG_AUTOREMOVE_CONSUMER)))
>> return NULL;
>>
>> device_links_write_lock();
>> @@ -479,7 +480,7 @@ static void __device_links_no_driver(struct device *dev)
>> if (link->flags & DL_FLAG_STATELESS)
>> continue;
>>
>> -   if (link->flags & DL_FLAG_AUTOREMOVE)
>> +

Re: [PATCH 4/5] drm/msm: Pass mmu features to generic layers

2018-04-05 Thread Vivek Gautam

Hi Sharat,


On 3/23/2018 12:49 PM, Sharat Masetty wrote:

Allow different Adreno targets the ability to pass
specific mmu features to the generic layers. This will
help conditionally configure certain iommu features for
certain Adreno targets.

Also Add a few simple support functions to support a bitmask of
features that a specific MMU implementation supports.

Signed-off-by: Sharat Masetty 


Just a nit; please see my comment below.


---
  drivers/gpu/drm/msm/adreno/a3xx_gpu.c   |  2 +-
  drivers/gpu/drm/msm/adreno/a4xx_gpu.c   |  2 +-
  drivers/gpu/drm/msm/adreno/a5xx_gpu.c   |  2 +-
  drivers/gpu/drm/msm/adreno/a6xx_gpu.c   |  2 +-
  drivers/gpu/drm/msm/adreno/adreno_gpu.c |  4 +++-
  drivers/gpu/drm/msm/adreno/adreno_gpu.h |  2 +-
  drivers/gpu/drm/msm/msm_gpu.c   |  6 --
  drivers/gpu/drm/msm/msm_gpu.h   |  1 +
  drivers/gpu/drm/msm/msm_mmu.h   | 13 +
  9 files changed, 26 insertions(+), 8 deletions(-)

diff --git a/drivers/gpu/drm/msm/adreno/a3xx_gpu.c 
b/drivers/gpu/drm/msm/adreno/a3xx_gpu.c
index 1dd84d3..a7a8573 100644
--- a/drivers/gpu/drm/msm/adreno/a3xx_gpu.c
+++ b/drivers/gpu/drm/msm/adreno/a3xx_gpu.c
@@ -492,7 +492,7 @@ struct msm_gpu *a3xx_gpu_init(struct drm_device *dev)
adreno_gpu->registers = a3xx_registers;
adreno_gpu->reg_offsets = a3xx_register_offsets;
  
-	ret = adreno_gpu_init(dev, pdev, adreno_gpu, , 1);

+   ret = adreno_gpu_init(dev, pdev, adreno_gpu, , 1, 0);
if (ret)
goto fail;
  
diff --git a/drivers/gpu/drm/msm/adreno/a4xx_gpu.c b/drivers/gpu/drm/msm/adreno/a4xx_gpu.c

index 2884b1b..5e7e15d6 100644
--- a/drivers/gpu/drm/msm/adreno/a4xx_gpu.c
+++ b/drivers/gpu/drm/msm/adreno/a4xx_gpu.c
@@ -574,7 +574,7 @@ struct msm_gpu *a4xx_gpu_init(struct drm_device *dev)
adreno_gpu->registers = a4xx_registers;
adreno_gpu->reg_offsets = a4xx_register_offsets;
  
-	ret = adreno_gpu_init(dev, pdev, adreno_gpu, , 1);

+   ret = adreno_gpu_init(dev, pdev, adreno_gpu, , 1, 0);
if (ret)
goto fail;
  
diff --git a/drivers/gpu/drm/msm/adreno/a5xx_gpu.c b/drivers/gpu/drm/msm/adreno/a5xx_gpu.c

index a4f68af..c9e06ff 100644
--- a/drivers/gpu/drm/msm/adreno/a5xx_gpu.c
+++ b/drivers/gpu/drm/msm/adreno/a5xx_gpu.c
@@ -1295,7 +1295,7 @@ struct msm_gpu *a5xx_gpu_init(struct drm_device *dev)
  
  	check_speed_bin(>dev);
  
-	ret = adreno_gpu_init(dev, pdev, adreno_gpu, , 4);

+   ret = adreno_gpu_init(dev, pdev, adreno_gpu, , 4, 0);
if (ret) {
a5xx_destroy(&(a5xx_gpu->base.base));
return ERR_PTR(ret);
diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c 
b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c
index e83b066..bd50674 100644
--- a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c
+++ b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c
@@ -1040,7 +1040,7 @@ struct msm_gpu *a6xx_gpu_init(struct drm_device *dev)
adreno_gpu->registers = a6xx_registers;
adreno_gpu->reg_offsets = a6xx_register_offsets;
  
-	ret = adreno_gpu_init(dev, pdev, adreno_gpu, , 4);

+   ret = adreno_gpu_init(dev, pdev, adreno_gpu, , 4, 0);
if (ret) {
a6xx_destroy(&(a6xx_gpu->base.base));
return ERR_PTR(ret);
diff --git a/drivers/gpu/drm/msm/adreno/adreno_gpu.c 
b/drivers/gpu/drm/msm/adreno/adreno_gpu.c
index 6657461..a87ec6b 100644
--- a/drivers/gpu/drm/msm/adreno/adreno_gpu.c
+++ b/drivers/gpu/drm/msm/adreno/adreno_gpu.c
@@ -557,7 +557,8 @@ static int adreno_get_pwrlevels(struct device *dev,
  
  int adreno_gpu_init(struct drm_device *drm, struct platform_device *pdev,

struct adreno_gpu *adreno_gpu,
-   const struct adreno_gpu_funcs *funcs, int nr_rings)
+   const struct adreno_gpu_funcs *funcs, int nr_rings,
+   unsigned long mmu_features)
  {
struct adreno_platform_config *config = pdev->dev.platform_data;
struct msm_gpu_config adreno_gpu_config  = { 0 };
@@ -576,6 +577,7 @@ int adreno_gpu_init(struct drm_device *drm, struct 
platform_device *pdev,
adreno_gpu_config.va_end = 0x;
  
  	adreno_gpu_config.nr_rings = nr_rings;

+   adreno_gpu_config.mmu_features = mmu_features;
  
  	adreno_get_pwrlevels(>dev, gpu);
  
diff --git a/drivers/gpu/drm/msm/adreno/adreno_gpu.h b/drivers/gpu/drm/msm/adreno/adreno_gpu.h

index bb9affd..19eda65 100644
--- a/drivers/gpu/drm/msm/adreno/adreno_gpu.h
+++ b/drivers/gpu/drm/msm/adreno/adreno_gpu.h
@@ -225,7 +225,7 @@ void adreno_submit(struct msm_gpu *gpu, struct 
msm_gem_submit *submit,
  
  int adreno_gpu_init(struct drm_device *drm, struct platform_device *pdev,

struct adreno_gpu *gpu, const struct adreno_gpu_funcs *funcs,
-   int nr_rings);
+   int nr_rings, unsigned long mmu_features);
  void adreno_gpu_cleanup(struct adreno_gpu *gpu);
  int adreno_load_fw(struct adreno_gpu *adreno_gpu);
  
diff --git a/drivers/gpu/drm/msm/msm_gpu.c 

Re: [PATCH 2/5] arm64:dts:sdm845: Add support for GPU LLCC

2018-04-05 Thread Vivek Gautam

Hi Sharat,


On 3/23/2018 12:49 PM, Sharat Masetty wrote:

Add client side bindings required for the GPU to use the last level
system cache. Also add a register range in the GPU CX domain.

Signed-off-by: Sharat Masetty 
---
  arch/arm64/boot/dts/qcom/sdm845.dtsi | 8 ++--
  1 file changed, 6 insertions(+), 2 deletions(-)

diff --git a/arch/arm64/boot/dts/qcom/sdm845.dtsi 
b/arch/arm64/boot/dts/qcom/sdm845.dtsi
index eb0a1b2..7e2d938 100644
--- a/arch/arm64/boot/dts/qcom/sdm845.dtsi
+++ b/arch/arm64/boot/dts/qcom/sdm845.dtsi
@@ -887,8 +887,8 @@
compatible = "qcom,adreno-630.2", "qcom,adreno";
#stream-id-cells = <16>;
  
-		reg = <0x500 0x4>;

-   reg-names = "kgsl_3d0_reg_memory";
+   reg = <0x500 0x4>, <0x509e000 0x10>;
+   reg-names = "kgsl_3d0_reg_memory", "cx_mem";
  
  		/*

 * Look ma, no clocks! The GPU clocks and power are controlled
@@ -898,6 +898,10 @@
interrupts = <0 300 0>;
interrupt-names = "kgsl_3d0_irq";
  
+		/* GPU related llc slices */

+   cache-slice-names = "gpu", "gpuhtw";
+   cache-slices = < 12>, < 11>;


Please add corresponding binding doc changes.

Best regards
Vivek


+
iommus = <_smmu 0>;
  
  		operating-points-v2 = <_opp_table>;


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


Re: [PATCH 5/5] drm/msm/A6xx: Add support for using system cache(llc)

2018-04-05 Thread Vivek Gautam

Hi Sharat,


On 3/23/2018 12:49 PM, Sharat Masetty wrote:

The last level system cache can be partitioned to 32
different slices of which GPU has two slices preallocated.
The "gpu" slice is used for caching GPU buffers and
the "gpuhtw" slice is used for caching the GPU SMMU
pagetables.  This patch talks to the core system cache
driver to acquire the slice handles, configure the SCID's
to those slices and activates and deactivates the slices
upon GPU power collapse and restore.

Some support from the IOMMU driver is also needed to
make use of the system cache. IOMMU_UPSTREAM_HINT is
a buffer protection flag which enables caching GPU data
buffers in the system cache with memory attributes such
as outer cacheable, read-allocate, write-allocate for buffers.
The GPU then has the ability to override a few cacheability
parameters which it does to override write-allocate to
write-no-allocate as the GPU hardware does not benefit much
from it.
Similarly DOMAIN_ATTR_USE_UPSTREAM_HINT is another domain level
attribute used by the IOMMU driver to set the right attributes
to cache the hardware pagetables into the system cache.

Signed-off-by: Sharat Masetty 
---


Couple of minor nits. Please see comments inline below.


  drivers/gpu/drm/msm/adreno/a6xx_gpu.c | 162 +-
  drivers/gpu/drm/msm/adreno/a6xx_gpu.h |   9 ++
  drivers/gpu/drm/msm/msm_iommu.c   |  13 +++
  drivers/gpu/drm/msm/msm_mmu.h |   3 +
  4 files changed, 186 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c 
b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c
index bd50674..e4554eb 100644
--- a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c
+++ b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c
@@ -13,6 +13,7 @@
  
  #include 

  #include 
+#include 
  
  #include "msm_gem.h"

  #include "msm_mmu.h"
@@ -913,6 +914,154 @@ static irqreturn_t a6xx_irq(struct msm_gpu *gpu)
~0
  };
  
+#define A6XX_LLC_NUM_GPU_SCIDS		5

+#define A6XX_GPU_LLC_SCID_NUM_BITS 5
+
+#define A6XX_GPU_LLC_SCID_MASK \
+   ((1 << (A6XX_LLC_NUM_GPU_SCIDS * A6XX_GPU_LLC_SCID_NUM_BITS)) - 1)
+
+#define A6XX_GPUHTW_LLC_SCID_SHIFT 25
+#define A6XX_GPUHTW_LLC_SCID_MASK \
+   (((1 << A6XX_GPU_LLC_SCID_NUM_BITS) - 1) << A6XX_GPUHTW_LLC_SCID_SHIFT)
+
+static inline void a6xx_gpu_cx_rmw(struct a6xx_llc *llc,
+   u32 reg, u32 mask, u32 or)
+{
+   msm_rmw(llc->mmio + (reg << 2), mask, or);
+}
+
+static void a6xx_llc_deactivate(struct msm_gpu *gpu)
+{
+   struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu);
+   struct a6xx_gpu *a6xx_gpu = to_a6xx_gpu(adreno_gpu);
+   struct a6xx_llc *llc = _gpu->llc;
+
+   llcc_slice_deactivate(llc->gpu_llc_slice);
+   llcc_slice_deactivate(llc->gpuhtw_llc_slice);
+}
+
+static void a6xx_llc_activate(struct msm_gpu *gpu)
+{
+   struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu);
+   struct a6xx_gpu *a6xx_gpu = to_a6xx_gpu(adreno_gpu);
+   struct a6xx_llc *llc = _gpu->llc;
+
+   if (!llc->mmio)
+   return;
+
+   if (llc->gpu_llc_slice)
+   if (!llcc_slice_activate(llc->gpu_llc_slice))
+   /* Program the sub-cache ID for all GPU blocks */
+   a6xx_gpu_cx_rmw(llc,
+   REG_A6XX_GPU_CX_MISC_SYSTEM_CACHE_CNTL_1,
+   A6XX_GPU_LLC_SCID_MASK,
+   (llc->cntl1_regval &
+   A6XX_GPU_LLC_SCID_MASK));
+
+   if (llc->gpuhtw_llc_slice)
+   if (!llcc_slice_activate(llc->gpuhtw_llc_slice))
+   /* Program the sub-cache ID for GPU pagetables */
+   a6xx_gpu_cx_rmw(llc,
+   REG_A6XX_GPU_CX_MISC_SYSTEM_CACHE_CNTL_1,
+   A6XX_GPUHTW_LLC_SCID_MASK,
+   (llc->cntl1_regval &
+   A6XX_GPUHTW_LLC_SCID_MASK));
+
+   /* Program cacheability overrides */
+   a6xx_gpu_cx_rmw(llc, REG_A6XX_GPU_CX_MISC_SYSTEM_CACHE_CNTL_0, 0xF,
+   llc->cntl0_regval);
+}
+
+void a6xx_llc_slices_destroy(struct a6xx_llc *llc)


static?


+{
+   if (llc->mmio) {
+   iounmap(llc->mmio);
+   llc->mmio = NULL;
+   }
+
+   llcc_slice_putd(llc->gpu_llc_slice);
+   llc->gpu_llc_slice = NULL;
+
+   llcc_slice_putd(llc->gpuhtw_llc_slice);
+   llc->gpuhtw_llc_slice = NULL;
+}
+
+static int a6xx_llc_slices_init(struct platform_device *pdev,
+   struct a6xx_llc *llc)
+{
+   int i;
+
+   /* Get the system cache slice descriptor for GPU and GPUHTWs */
+   llc->gpu_llc_slice = llcc_slice_getd(>dev, "gpu");
+   if (IS_ERR(llc->gpu_llc_slice))
+   llc->gpu_llc_slice = NULL;
+
+   llc->gpuhtw_llc_slice = llcc_slice_getd(>dev, "gpuhtw");
+   if (IS_ERR(llc->gpuhtw_llc_slice))
+   llc->gpuhtw_llc_slice = NULL;
+
+   

[PATCH 1/2] device core: Rename flag AUTOREMOVE to AUTOREMOVE_CONSUMER

2018-06-28 Thread Vivek Gautam
Now that we want to add another flag to autoremove the device link
on supplier unbind, it's fair to rename the existing flag from
DL_FLAG_AUTOREMOVE to DL_FLAG_AUTOREMOVE_CONSUMER so that we can
add similar flag for supplier later.
And, while we are touching device.h, fix a doc build warning.

Signed-off-by: Vivek Gautam 
Cc: Lukas Wunner 
Cc: Jonathan Corbet 
Cc: Greg Kroah-Hartman 
Cc: Thierry Reding 
Cc: David Airlie 
Cc: Jonathan Hunter 
Cc: Philipp Zabel 
Cc: Shawn Guo 
Cc: Sascha Hauer 
Cc: Robin Murphy 
Cc: linux-...@vger.kernel.org
Cc: dri-devel@lists.freedesktop.org
Cc: linux-te...@vger.kernel.org
Cc: linux-arm-ker...@lists.infradead.org
Cc: linux...@vger.kernel.org
Cc: linux-arm-...@vger.kernel.org
---
 Documentation/driver-api/device_link.rst |  8 
 drivers/base/core.c  | 15 ---
 drivers/gpu/drm/tegra/dc.c   |  2 +-
 drivers/gpu/ipu-v3/ipu-pre.c |  3 ++-
 drivers/gpu/ipu-v3/ipu-prg.c |  3 ++-
 drivers/soc/imx/gpc.c|  2 +-
 include/linux/device.h   | 12 ++--
 7 files changed, 24 insertions(+), 21 deletions(-)

diff --git a/Documentation/driver-api/device_link.rst 
b/Documentation/driver-api/device_link.rst
index 70e328e16aad..a005b904a264 100644
--- a/Documentation/driver-api/device_link.rst
+++ b/Documentation/driver-api/device_link.rst
@@ -81,10 +81,10 @@ integration is desired.
 Two other flags are specifically targeted at use cases where the device
 link is added from the consumer's ``->probe`` callback:  ``DL_FLAG_RPM_ACTIVE``
 can be specified to runtime resume the supplier upon addition of the
-device link.  ``DL_FLAG_AUTOREMOVE`` causes the device link to be automatically
-purged when the consumer fails to probe or later unbinds.  This obviates
-the need to explicitly delete the link in the ``->remove`` callback or in
-the error path of the ``->probe`` callback.
+device link.  ``DL_FLAG_AUTOREMOVE_CONSUMER`` causes the device link to be
+automatically purged when the consumer fails to probe or later unbinds.
+This obviates the need to explicitly delete the link in the ``->remove``
+callback or in the error path of the ``->probe`` callback.
 
 Limitations
 ===
diff --git a/drivers/base/core.c b/drivers/base/core.c
index df3e1a44707a..14c1e3151e08 100644
--- a/drivers/base/core.c
+++ b/drivers/base/core.c
@@ -178,10 +178,10 @@ void device_pm_move_to_tail(struct device *dev)
  * of the link.  If DL_FLAG_PM_RUNTIME is not set, DL_FLAG_RPM_ACTIVE will be
  * ignored.
  *
- * If the DL_FLAG_AUTOREMOVE is set, the link will be removed automatically
- * when the consumer device driver unbinds from it.  The combination of both
- * DL_FLAG_AUTOREMOVE and DL_FLAG_STATELESS set is invalid and will cause NULL
- * to be returned.
+ * If the DL_FLAG_AUTOREMOVE_CONSUMER is set, the link will be removed
+ * automatically when the consumer device driver unbinds from it.
+ * The combination of both DL_FLAG_AUTOREMOVE_CONSUMER and DL_FLAG_STATELESS
+ * set is invalid and will cause NULL to be returned.
  *
  * A side effect of the link creation is re-ordering of dpm_list and the
  * devices_kset list by moving the consumer device and all devices depending
@@ -198,7 +198,8 @@ struct device_link *device_link_add(struct device *consumer,
struct device_link *link;
 
if (!consumer || !supplier ||
-   ((flags & DL_FLAG_STATELESS) && (flags & DL_FLAG_AUTOREMOVE)))
+   ((flags & DL_FLAG_STATELESS) &&
+(flags & DL_FLAG_AUTOREMOVE_CONSUMER)))
return NULL;
 
device_links_write_lock();
@@ -479,7 +480,7 @@ static void __device_links_no_driver(struct device *dev)
if (link->flags & DL_FLAG_STATELESS)
continue;
 
-   if (link->flags & DL_FLAG_AUTOREMOVE)
+   if (link->flags & DL_FLAG_AUTOREMOVE_CONSUMER)
kref_put(>kref, __device_link_del);
else if (link->status != DL_STATE_SUPPLIER_UNBIND)
WRITE_ONCE(link->status, DL_STATE_AVAILABLE);
@@ -515,7 +516,7 @@ void device_links_driver_cleanup(struct device *dev)
if (link->flags & DL_FLAG_STATELESS)
continue;
 
-   WARN_ON(link->flags & DL_FLAG_AUTOREMOVE);
+   WARN_ON(link->flags & DL_FLAG_AUTOREMOVE_CONSUMER);
WARN_ON(link->status != DL_STATE_SUPPLIER_UNBIND);
WRITE_ONCE(link->status, DL_STATE_DORMANT);
}
diff --git a/drivers/gpu/drm/tegra/dc.c b/drivers/gpu/drm/tegra/dc.c
index c3afe7b2237e..965088afcfad 100644
--- a/drivers/gpu/drm/tegra/dc.c
+++ b/drivers/gpu/drm/tegra/dc.c
@@ -2312,7 +2312,7 @@ static int tegra_dc_couple(struct tegra_dc *dc)
 * POWER_CONTROL registers during CRTC enabling.
 */
if (dc->soc->coupled_pm &

Re: [PATCH v2 1/1] drm: msm: Replace dma_map_sg with dma_sync_sg*

2018-11-29 Thread Vivek Gautam
Hi Christoph ,

On Wed, Nov 28, 2018 at 1:10 PM Christoph Hellwig  wrote:
>
> > + /*
> > +  * dma_sync_sg_*() flush the physical pages, so point
> > +  * sg->dma_address to the physical ones for the right 
> > behavior.
> > +  */
> > + for_each_sg(msm_obj->sgt->sgl, s, msm_obj->sgt->nents, i)
> > + sg_dma_address(s) = sg_phys(s);
> > +
>
> I'm sorry, but this is completely bogus and not acceptable.
>
> The only place that is allowed to initialize sg_dma_address is
> dma_map_sg.  If the default dma ops don't work for your setup we have
> major a problem and need to fix the dma api / iommu integration instead
> of hacking around it.

Thanks for reviewing this change.
From what I understand the things in drm, we don't use the default
iommu-dma domain
for drm devices. Rather we allocate a new iommu domain, and therefore we can't
use the default dma ops. Hence we need separate dma_sync_sg*() to
flush/invalidate
the cache. For this we need to initialize the sg's addresses.

Please correct me if my understanding is incomplete.

Best regards
Vivek



--
QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member
of Code Aurora Forum, hosted by The Linux Foundation
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


Re: [PATCH] of/device: add blacklist for iommu dma_ops

2018-12-04 Thread Vivek Gautam
On Mon, Dec 3, 2018 at 7:56 PM Rob Clark  wrote:
>
> On Mon, Dec 3, 2018 at 7:45 AM Robin Murphy  wrote:
> >
> > Hi Rob,
> >
> > On 01/12/2018 16:53, Rob Clark wrote:
> > > This solves a problem we see with drm/msm, caused by getting
> > > iommu_dma_ops while we attach our own domain and manage it directly at
> > > the iommu API level:
> > >
> > >[0038] user address but active_mm is swapper
> > >Internal error: Oops: 9605 [#1] PREEMPT SMP
> > >Modules linked in:
> > >CPU: 7 PID: 70 Comm: kworker/7:1 Tainted: GW 4.19.3 #90
> > >Hardware name: xxx (DT)
> > >Workqueue: events deferred_probe_work_func
> > >pstate: 80c9 (Nzcv daif +PAN +UAO)
> > >pc : iommu_dma_map_sg+0x7c/0x2c8
> > >lr : iommu_dma_map_sg+0x40/0x2c8
> > >sp : ff80095eb4f0
> > >x29: ff80095eb4f0 x28: 
> > >x27: ffc0f9431578 x26: 
> > >x25:  x24: 0003
> > >x23: 0001 x22: ffc0fa9ac010
> > >x21:  x20: ffc0fab40980
> > >x19: ffc0fab40980 x18: 0003
> > >x17: 01c4 x16: 0007
> > >x15: 000e x14: 
> > >x13:  x12: 0028
> > >x11: 0101010101010101 x10: 7f7f7f7f7f7f7f7f
> > >x9 :  x8 : ffc0fab409a0
> > >x7 :  x6 : 0002
> > >x5 : 0001 x4 : 
> > >x3 : 0001 x2 : 0002
> > >x1 : ffc0f9431578 x0 : 
> > >Process kworker/7:1 (pid: 70, stack limit = 0x17d08ffb)
> > >Call trace:
> > > iommu_dma_map_sg+0x7c/0x2c8
> > > __iommu_map_sg_attrs+0x70/0x84
> > > get_pages+0x170/0x1e8
> > > msm_gem_get_iova+0x8c/0x128
> > > _msm_gem_kernel_new+0x6c/0xc8
> > > msm_gem_kernel_new+0x4c/0x58
> > > dsi_tx_buf_alloc_6g+0x4c/0x8c
> > > msm_dsi_host_modeset_init+0xc8/0x108
> > > msm_dsi_modeset_init+0x54/0x18c
> > > _dpu_kms_drm_obj_init+0x430/0x474
> > > dpu_kms_hw_init+0x5f8/0x6b4
> > > msm_drm_bind+0x360/0x6c8
> > > try_to_bring_up_master.part.7+0x28/0x70
> > > component_master_add_with_match+0xe8/0x124
> > > msm_pdev_probe+0x294/0x2b4
> > > platform_drv_probe+0x58/0xa4
> > > really_probe+0x150/0x294
> > > driver_probe_device+0xac/0xe8
> > > __device_attach_driver+0xa4/0xb4
> > > bus_for_each_drv+0x98/0xc8
> > > __device_attach+0xac/0x12c
> > > device_initial_probe+0x24/0x30
> > > bus_probe_device+0x38/0x98
> > > deferred_probe_work_func+0x78/0xa4
> > > process_one_work+0x24c/0x3dc
> > > worker_thread+0x280/0x360
> > > kthread+0x134/0x13c
> > > ret_from_fork+0x10/0x18
> > >Code: d284 91000725 6b17039f 5400048a (f9401f40)
> > >---[ end trace f22dda57f3648e2c ]---
> > >Kernel panic - not syncing: Fatal exception
> > >SMP: stopping secondary CPUs
> > >Kernel Offset: disabled
> > >CPU features: 0x0,22802a18
> > >Memory Limit: none
> > >
> > > The problem is that when drm/msm does it's own iommu_attach_device(),
> > > now the domain returned by iommu_get_domain_for_dev() is drm/msm's
> > > domain, and it doesn't have domain->iova_cookie.
> >
> > Does this crash still happen with 4.20-rc? Because as of 6af588fed391 it
> > really shouldn't.
> >
> > > We kind of avoided this problem prior to sdm845/dpu because the iommu
> > > was attached to the mdp node in dt, which is a child of the toplevel
> > > mdss node (which corresponds to the dev passed in dma_map_sg()).  But
> > > with sdm845, now the iommu is attached at the mdss level so we hit the
> > > iommu_dma_ops in dma_map_sg().
> > >
> > > But auto allocating/attaching a domain before the driver is probed was
> > > already a blocking problem for enabling per-context pagetables for the
> > > GPU.  This problem is also now solved with this patch.
> >
> > s/solved/worked around/
> >
> > If you want a guarantee of actually getting a specific hardware context
> > allocated for a given domain, there needs to be code in the IOMMU driver
> > to understand and honour that. Implicitly depending on whatever happens
> > to fall out of current driver behaviour on current systems is not a real
> > solution.
> >
> > > Fixes: 97890ba9289c dma-mapping: detect and configure IOMMU in 
> > > of_dma_configure
> >
> > That's rather misleading, since the crash described above depends on at
> > least two other major changes which came long after that commit.
> >
> > It's not that I don't understand exactly what you want here - just that
> > this commit message isn't a coherent justification for that ;)
> >
> > > Tested-by: Douglas Anderson 
> > > Signed-off-by: Rob Clark 
> > > ---
> > > This is an alternative/replacement for [1].  What it lacks in elegance
> > > it makes up for in practicality ;-)
> > >
> > > [1] 

[PATCH v3 1/1] drm: msm: Replace dma_map_sg with dma_sync_sg*

2018-11-30 Thread Vivek Gautam
dma_map_sg() expects a DMA domain. However, the drm devices
have been traditionally using unmanaged iommu domain which
is non-dma type. Using dma mapping APIs with that domain is bad.

Replace dma_map_sg() calls with dma_sync_sg_for_device{|cpu}()
to do the cache maintenance.

Signed-off-by: Vivek Gautam 
Suggested-by: Tomasz Figa 
Cc: Rob Clark 
Cc: Christoph Hellwig 
Cc: Robin Murphy 
Cc: Jordan Crouse 
Cc: Sean Paul 
---

Changes since v2:
 - Addressed Tomasz's comment to keep DMA_BIDIRECTIONAL dma direction
   flag intact.
 - Updated comment for sg's dma-address assignment as per Tomasz'
   suggestion.

 drivers/gpu/drm/msm/msm_gem.c | 33 -
 1 file changed, 24 insertions(+), 9 deletions(-)

diff --git a/drivers/gpu/drm/msm/msm_gem.c b/drivers/gpu/drm/msm/msm_gem.c
index 00c795ced02c..7048e9fe00c6 100644
--- a/drivers/gpu/drm/msm/msm_gem.c
+++ b/drivers/gpu/drm/msm/msm_gem.c
@@ -81,6 +81,8 @@ static struct page **get_pages(struct drm_gem_object *obj)
struct drm_device *dev = obj->dev;
struct page **p;
int npages = obj->size >> PAGE_SHIFT;
+   struct scatterlist *s;
+   int i;
 
if (use_pages(obj))
p = drm_gem_get_pages(obj);
@@ -104,12 +106,23 @@ static struct page **get_pages(struct drm_gem_object *obj)
return ptr;
}
 
-   /* For non-cached buffers, ensure the new pages are clean
+   /*
+* Some implementations of the DMA mapping ops expect
+* physical addresses of the pages to be stored as DMA
+* addresses of the sglist entries. To work around it,
+* set them here explicitly.
+*/
+   for_each_sg(msm_obj->sgt->sgl, s, msm_obj->sgt->nents, i)
+   sg_dma_address(s) = sg_phys(s);
+
+   /*
+* For non-cached buffers, ensure the new pages are clean
 * because display controller, GPU, etc. are not coherent:
 */
-   if (msm_obj->flags & (MSM_BO_WC|MSM_BO_UNCACHED))
-   dma_map_sg(dev->dev, msm_obj->sgt->sgl,
-   msm_obj->sgt->nents, DMA_BIDIRECTIONAL);
+   if (msm_obj->flags & (MSM_BO_WC | MSM_BO_UNCACHED))
+   dma_sync_sg_for_device(dev->dev, msm_obj->sgt->sgl,
+  msm_obj->sgt->nents,
+  DMA_BIDIRECTIONAL);
}
 
return msm_obj->pages;
@@ -133,14 +146,16 @@ static void put_pages(struct drm_gem_object *obj)
 
if (msm_obj->pages) {
if (msm_obj->sgt) {
-   /* For non-cached buffers, ensure the new
+   /*
+* For non-cached buffers, ensure the new
 * pages are clean because display controller,
 * GPU, etc. are not coherent:
 */
-   if (msm_obj->flags & (MSM_BO_WC|MSM_BO_UNCACHED))
-   dma_unmap_sg(obj->dev->dev, msm_obj->sgt->sgl,
-msm_obj->sgt->nents,
-DMA_BIDIRECTIONAL);
+   if (msm_obj->flags & (MSM_BO_WC | MSM_BO_UNCACHED))
+   dma_sync_sg_for_cpu(obj->dev->dev,
+   msm_obj->sgt->sgl,
+   msm_obj->sgt->nents,
+   DMA_BIDIRECTIONAL);
 
sg_free_table(msm_obj->sgt);
kfree(msm_obj->sgt);
-- 
QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member
of Code Aurora Forum, hosted by The Linux Foundation

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


Re: [PATCH v2 1/1] drm: msm: Replace dma_map_sg with dma_sync_sg*

2018-11-30 Thread Vivek Gautam
Hi Tomasz,

On Wed, Nov 28, 2018 at 8:39 AM Tomasz Figa  wrote:
>
> Hi Vivek,
>
> On Tue, Nov 27, 2018 at 6:37 AM Vivek Gautam
>  wrote:
> >
> > dma_map_sg() expects a DMA domain. However, the drm devices
> > have been traditionally using unmanaged iommu domain which
> > is non-dma type. Using dma mapping APIs with that domain is bad.
> >
> > Replace dma_map_sg() calls with dma_sync_sg_for_device{|cpu}()
> > to do the cache maintenance.
> >
> > Signed-off-by: Vivek Gautam 
> > Suggested-by: Tomasz Figa 
> > Cc: Rob Clark 
> > Cc: Jordan Crouse 
> > Cc: Sean Paul 
> > ---
> >
> > Changes since v1:
> >  - Addressed Jordan's and Tomasz's comments for
> >- moving sg dma addresses preparation out of the coditional
> >  check to the main path so we do it irrespective of whether
> >  the buffer is cached or uncached.
> >- Enhance the comment to explain this dma addresses prepartion.
> >
>
> Thanks for the patch. Some comments inline.
>
> >  drivers/gpu/drm/msm/msm_gem.c | 31 ++-
> >  1 file changed, 22 insertions(+), 9 deletions(-)
> >
> > diff --git a/drivers/gpu/drm/msm/msm_gem.c b/drivers/gpu/drm/msm/msm_gem.c
> > index 00c795ced02c..1811ac23a31c 100644
> > --- a/drivers/gpu/drm/msm/msm_gem.c
> > +++ b/drivers/gpu/drm/msm/msm_gem.c
> > @@ -81,6 +81,8 @@ static struct page **get_pages(struct drm_gem_object *obj)
> > struct drm_device *dev = obj->dev;
> > struct page **p;
> > int npages = obj->size >> PAGE_SHIFT;
> > +   struct scatterlist *s;
> > +   int i;
> >
> > if (use_pages(obj))
> > p = drm_gem_get_pages(obj);
> > @@ -104,12 +106,21 @@ static struct page **get_pages(struct drm_gem_object 
> > *obj)
> > return ptr;
> > }
> >
> > -   /* For non-cached buffers, ensure the new pages are clean
> > +   /*
> > +* dma_sync_sg_*() flush the physical pages, so point
> > +* sg->dma_address to the physical ones for the right 
> > behavior.
>
> The two halves of the sequence don't really relate to each other. An
> sglist has the `page` field for the purpose of pointing to physical
> pages. The `dma_address` field is for DMA addresses, which are not
> equivalent to physical addresses. I'd rewrite it like this;

I guess I was lenient in using the physical pages and dma address words.

>
> /*
>  * Some implementations of the DMA mapping ops expect
>  * physical addresses of the pages to be stored as DMA
>  * addresses of the sglist entries. To work around it,
>  * set them here explicitly.
>  */

Will update as suggested.

> > +*/
> > +   for_each_sg(msm_obj->sgt->sgl, s, msm_obj->sgt->nents, i)
> > +   sg_dma_address(s) = sg_phys(s);
> > +
> > +   /*
> > +* For non-cached buffers, ensure the new pages are clean
> >  * because display controller, GPU, etc. are not coherent:
> >  */
> > -   if (msm_obj->flags & (MSM_BO_WC|MSM_BO_UNCACHED))
> > -   dma_map_sg(dev->dev, msm_obj->sgt->sgl,
> > -   msm_obj->sgt->nents, 
> > DMA_BIDIRECTIONAL);
> > +   if (msm_obj->flags & (MSM_BO_WC | MSM_BO_UNCACHED))
> > +   dma_sync_sg_for_device(dev->dev, msm_obj->sgt->sgl,
> > +  msm_obj->sgt->nents,
> > +  DMA_TO_DEVICE);
>
> Why changing from DMA_BIDIRECTIONAL?

Yea, I went back and checked that we wanted to do this for both.
Will keep DMA_BIDIRECTIONAL intact.

>
> > }
> >
> > return msm_obj->pages;
> > @@ -133,14 +144,16 @@ static void put_pages(struct drm_gem_object *obj)
> >
> > if (msm_obj->pages) {
> > if (msm_obj->sgt) {
> > -   /* For non-cached buffers, ensure the new
> > +   /*
> > +* For non-cached buffers, ensure the new
> >  * pages are clean because display controller,
> >  * GPU, etc. are not coherent:
> >  */
> > -   if (msm_obj->flags & (MSM_BO_WC|MSM_BO_UNCACHED))
> >

Re: [PATCH v2 1/1] drm: msm: Replace dma_map_sg with dma_sync_sg*

2018-11-30 Thread Vivek Gautam
On Wed, Nov 28, 2018 at 6:09 PM Rob Clark  wrote:
>
> On Wed, Nov 28, 2018 at 2:39 AM Christoph Hellwig  wrote:
> >
> > > + /*
> > > +  * dma_sync_sg_*() flush the physical pages, so point
> > > +  * sg->dma_address to the physical ones for the right 
> > > behavior.
> > > +  */
> > > + for_each_sg(msm_obj->sgt->sgl, s, msm_obj->sgt->nents, i)
> > > + sg_dma_address(s) = sg_phys(s);
> > > +
> >
> > I'm sorry, but this is completely bogus and not acceptable.
> >
> > The only place that is allowed to initialize sg_dma_address is
> > dma_map_sg.  If the default dma ops don't work for your setup we have
> > major a problem and need to fix the dma api / iommu integration instead
> > of hacking around it.
>
> I agree that the dma/iommu integration is very problematic for drm (in
> particular, gpu drivers that use the iommu as an gpu mmu)..  Really we
> need a way that a driver can opt-out of this, and access the cpu cache
> APIs directly, skipping the dma API entirely.  But as it is, we've had
> to hack around the dma API.  I'm not really sure this hack is any
> worse than abusing dma_(un)map_sg() for doing cache operations.
>
> I probably should have paid more attention and nak'd the dma/iommu
> integration before it landed.  But given that now we are stuck in this
> situation, while I'm certainly interested if anyone has some ideas
> about how to let drivers opt out of the dma/iommu integration and
> bypass the dma API layer, I'm ok with replacing a hack with a less-bad
> hack.

May I take it as a positive nod to respin the next version?

Regards
Vivek

>
> BR,
> -R



-- 
QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member
of Code Aurora Forum, hosted by The Linux Foundation
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


Re: [PATCH 1/1] drm: msm: Replace dma_map_sg with dma_sync_sg*

2018-11-22 Thread Vivek Gautam

Hi Tomasz, Jordan,


On 11/21/2018 9:18 AM, Tomasz Figa wrote:

Hi Jordan, Vivek,

On Wed, Nov 21, 2018 at 12:41 AM Jordan Crouse  wrote:

On Tue, Nov 20, 2018 at 03:24:37PM +0530, Vivek Gautam wrote:

dma_map_sg() expects a DMA domain. However, the drm devices
have been traditionally using unmanaged iommu domain which
is non-dma type. Using dma mapping APIs with that domain is bad.

Replace dma_map_sg() calls with dma_sync_sg_for_device{|cpu}()
to do the cache maintenance.

Signed-off-by: Vivek Gautam 
Suggested-by: Tomasz Figa 
---

Tested on an MTP sdm845:
https://github.com/vivekgautam1/linux/tree/v4.19/sdm845-mtp-display-working

  drivers/gpu/drm/msm/msm_gem.c | 27 ---
  1 file changed, 20 insertions(+), 7 deletions(-)

diff --git a/drivers/gpu/drm/msm/msm_gem.c b/drivers/gpu/drm/msm/msm_gem.c
index 00c795ced02c..d7a7af610803 100644
--- a/drivers/gpu/drm/msm/msm_gem.c
+++ b/drivers/gpu/drm/msm/msm_gem.c
@@ -81,6 +81,8 @@ static struct page **get_pages(struct drm_gem_object *obj)
   struct drm_device *dev = obj->dev;
   struct page **p;
   int npages = obj->size >> PAGE_SHIFT;
+ struct scatterlist *s;
+ int i;

   if (use_pages(obj))
   p = drm_gem_get_pages(obj);
@@ -107,9 +109,19 @@ static struct page **get_pages(struct drm_gem_object *obj)
   /* For non-cached buffers, ensure the new pages are clean
* because display controller, GPU, etc. are not coherent:
*/
- if (msm_obj->flags & (MSM_BO_WC|MSM_BO_UNCACHED))
- dma_map_sg(dev->dev, msm_obj->sgt->sgl,
- msm_obj->sgt->nents, DMA_BIDIRECTIONAL);
+ if (msm_obj->flags & (MSM_BO_WC | MSM_BO_UNCACHED)) {
+ /*
+  * Fake up the SG table so that dma_sync_sg_*()
+  * can be used to flush the pages associated with it.
+  */

We aren't really faking.  The table is real, we are just slightly abusing the
sg_dma_address() which makes this comment a bit misleading. Instead I would
probably say something like:

/* dma_sync_sg_* flushes pages using sg_dma_address() so point it at the
  * physical page for the right behavior */

Or something like that.


It's actually quite complicated, but I agree that the comment isn't
very precise. The cases are as follows:
- arm64 iommu_dma_ops use sg_phys()
https://elixir.bootlin.com/linux/v4.20-rc3/source/arch/arm64/mm/dma-mapping.c#L599
- swiotlb_dma_ops used on arm64 if no IOMMU is available use
sg->dma_address directly:
https://elixir.bootlin.com/linux/v4.20-rc3/source/kernel/dma/swiotlb.c#L832
- arm_dma_ops use sg_dma_address():
https://elixir.bootlin.com/linux/v4.20-rc3/source/arch/arm/mm/dma-mapping.c#L1130
- arm iommu_ops use sg_page():
https://elixir.bootlin.com/linux/v4.20-rc3/source/arch/arm/mm/dma-mapping.c#L1869

Sounds like a mess...

Thanks for the review.

Technically with the below assignment we address all of the above. How 
about an even

simpler version of the suggested comment:

/* dma_sync_sg_* flushes physical pages, so point sg->dma_address to
 * the physical one for the right behavior.
 */





+ for_each_sg(msm_obj->sgt->sgl, s,
+ msm_obj->sgt->nents, i)
+ sg_dma_address(s) = sg_phys(s);
+

I'm wondering - wouldn't we want to do this association for cached buffers to so
we could sync them correctly in cpu_prep and cpu_fini?  Maybe it wouldn't hurt
to put this association in the main path (obviously the sync should stay inside
the conditional for uncached buffers).



Sure, I will move this out of the conditional check.


I guess it wouldn't hurt indeed. Note that cpu_prep/fini seem to be
missing the sync call currently.


I can't say I understand the usage of cpu_prep and cpu_fini(). But I can add
the necessary support if you can point me in the right direction.
Thanks

Best regards
Vivek


P.S. Jordan, not sure if it's my Gmail or your email client, but your
message had all the recipients in a Reply-to header, except you, so
pressing Reply to all in my case led to a message that didn't have you
in recipients anymore...

Best regards,
Tomasz


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


[PATCH 1/1] drm: msm: Replace dma_map_sg with dma_sync_sg*

2018-11-21 Thread Vivek Gautam
dma_map_sg() expects a DMA domain. However, the drm devices
have been traditionally using unmanaged iommu domain which
is non-dma type. Using dma mapping APIs with that domain is bad.

Replace dma_map_sg() calls with dma_sync_sg_for_device{|cpu}()
to do the cache maintenance.

Signed-off-by: Vivek Gautam 
Suggested-by: Tomasz Figa 
---

Tested on an MTP sdm845:
https://github.com/vivekgautam1/linux/tree/v4.19/sdm845-mtp-display-working

 drivers/gpu/drm/msm/msm_gem.c | 27 ---
 1 file changed, 20 insertions(+), 7 deletions(-)

diff --git a/drivers/gpu/drm/msm/msm_gem.c b/drivers/gpu/drm/msm/msm_gem.c
index 00c795ced02c..d7a7af610803 100644
--- a/drivers/gpu/drm/msm/msm_gem.c
+++ b/drivers/gpu/drm/msm/msm_gem.c
@@ -81,6 +81,8 @@ static struct page **get_pages(struct drm_gem_object *obj)
struct drm_device *dev = obj->dev;
struct page **p;
int npages = obj->size >> PAGE_SHIFT;
+   struct scatterlist *s;
+   int i;
 
if (use_pages(obj))
p = drm_gem_get_pages(obj);
@@ -107,9 +109,19 @@ static struct page **get_pages(struct drm_gem_object *obj)
/* For non-cached buffers, ensure the new pages are clean
 * because display controller, GPU, etc. are not coherent:
 */
-   if (msm_obj->flags & (MSM_BO_WC|MSM_BO_UNCACHED))
-   dma_map_sg(dev->dev, msm_obj->sgt->sgl,
-   msm_obj->sgt->nents, DMA_BIDIRECTIONAL);
+   if (msm_obj->flags & (MSM_BO_WC | MSM_BO_UNCACHED)) {
+   /*
+* Fake up the SG table so that dma_sync_sg_*()
+* can be used to flush the pages associated with it.
+*/
+   for_each_sg(msm_obj->sgt->sgl, s,
+   msm_obj->sgt->nents, i)
+   sg_dma_address(s) = sg_phys(s);
+
+   dma_sync_sg_for_device(dev->dev, msm_obj->sgt->sgl,
+  msm_obj->sgt->nents,
+  DMA_TO_DEVICE);
+   }
}
 
return msm_obj->pages;
@@ -137,10 +149,11 @@ static void put_pages(struct drm_gem_object *obj)
 * pages are clean because display controller,
 * GPU, etc. are not coherent:
 */
-   if (msm_obj->flags & (MSM_BO_WC|MSM_BO_UNCACHED))
-   dma_unmap_sg(obj->dev->dev, msm_obj->sgt->sgl,
-msm_obj->sgt->nents,
-DMA_BIDIRECTIONAL);
+   if (msm_obj->flags & (MSM_BO_WC | MSM_BO_UNCACHED))
+   dma_sync_sg_for_cpu(obj->dev->dev,
+   msm_obj->sgt->sgl,
+   msm_obj->sgt->nents,
+   DMA_FROM_DEVICE);
 
sg_free_table(msm_obj->sgt);
kfree(msm_obj->sgt);
-- 
QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member
of Code Aurora Forum, hosted by The Linux Foundation

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


[PATCH v2 1/1] drm: msm: Replace dma_map_sg with dma_sync_sg*

2018-11-27 Thread Vivek Gautam
dma_map_sg() expects a DMA domain. However, the drm devices
have been traditionally using unmanaged iommu domain which
is non-dma type. Using dma mapping APIs with that domain is bad.

Replace dma_map_sg() calls with dma_sync_sg_for_device{|cpu}()
to do the cache maintenance.

Signed-off-by: Vivek Gautam 
Suggested-by: Tomasz Figa 
Cc: Rob Clark 
Cc: Jordan Crouse  
Cc: Sean Paul 
---

Changes since v1:
 - Addressed Jordan's and Tomasz's comments for
   - moving sg dma addresses preparation out of the coditional
 check to the main path so we do it irrespective of whether
 the buffer is cached or uncached.
   - Enhance the comment to explain this dma addresses prepartion.

 drivers/gpu/drm/msm/msm_gem.c | 31 ++-
 1 file changed, 22 insertions(+), 9 deletions(-)

diff --git a/drivers/gpu/drm/msm/msm_gem.c b/drivers/gpu/drm/msm/msm_gem.c
index 00c795ced02c..1811ac23a31c 100644
--- a/drivers/gpu/drm/msm/msm_gem.c
+++ b/drivers/gpu/drm/msm/msm_gem.c
@@ -81,6 +81,8 @@ static struct page **get_pages(struct drm_gem_object *obj)
struct drm_device *dev = obj->dev;
struct page **p;
int npages = obj->size >> PAGE_SHIFT;
+   struct scatterlist *s;
+   int i;
 
if (use_pages(obj))
p = drm_gem_get_pages(obj);
@@ -104,12 +106,21 @@ static struct page **get_pages(struct drm_gem_object *obj)
return ptr;
}
 
-   /* For non-cached buffers, ensure the new pages are clean
+   /*
+* dma_sync_sg_*() flush the physical pages, so point
+* sg->dma_address to the physical ones for the right behavior.
+*/
+   for_each_sg(msm_obj->sgt->sgl, s, msm_obj->sgt->nents, i)
+   sg_dma_address(s) = sg_phys(s);
+
+   /*
+* For non-cached buffers, ensure the new pages are clean
 * because display controller, GPU, etc. are not coherent:
 */
-   if (msm_obj->flags & (MSM_BO_WC|MSM_BO_UNCACHED))
-   dma_map_sg(dev->dev, msm_obj->sgt->sgl,
-   msm_obj->sgt->nents, DMA_BIDIRECTIONAL);
+   if (msm_obj->flags & (MSM_BO_WC | MSM_BO_UNCACHED))
+   dma_sync_sg_for_device(dev->dev, msm_obj->sgt->sgl,
+  msm_obj->sgt->nents,
+  DMA_TO_DEVICE);
}
 
return msm_obj->pages;
@@ -133,14 +144,16 @@ static void put_pages(struct drm_gem_object *obj)
 
if (msm_obj->pages) {
if (msm_obj->sgt) {
-   /* For non-cached buffers, ensure the new
+   /*
+* For non-cached buffers, ensure the new
 * pages are clean because display controller,
 * GPU, etc. are not coherent:
 */
-   if (msm_obj->flags & (MSM_BO_WC|MSM_BO_UNCACHED))
-   dma_unmap_sg(obj->dev->dev, msm_obj->sgt->sgl,
-msm_obj->sgt->nents,
-DMA_BIDIRECTIONAL);
+   if (msm_obj->flags & (MSM_BO_WC | MSM_BO_UNCACHED))
+   dma_sync_sg_for_cpu(obj->dev->dev,
+   msm_obj->sgt->sgl,
+   msm_obj->sgt->nents,
+   DMA_FROM_DEVICE);
 
sg_free_table(msm_obj->sgt);
kfree(msm_obj->sgt);
-- 
QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member
of Code Aurora Forum, hosted by The Linux Foundation

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


[PATCH 1/1] drm/prime: Use sg_dma_len() macro to get sg's length

2019-01-08 Thread Vivek Gautam
After mapping a sg list we should use sg_dma_address(), and
sg_dma_len() macros to access sg->address and sg->length. Fix
the same for sg->length in drm_prime_sg_to_page_addr_arrays().

Signed-off-by: Vivek Gautam 
---

This came while debugging one dmabuf import issue that we are seeing
on sdm845 target.
The dmabuf which is prepared by video (venus in this case), is imported
by drm device.
The import call flow looks like follows:

drm_gem_prime_import()
 - drm_gem_prime_import_dev()
   - dma_buf_attach() & dma_buf_map_attachment()
 - From dma_buf_map_attachment()
   - vb2_dma_sg_dmabuf_ops_map()
 - dma_map_sg(): this updates the sg->nents.

From debugging, the sg table mapping results in sg's 'nents' to be less that
the original nents. Now drm device prepares the page information based on
this sg table, and messes up with the mappings, and we start seeing random
crashes as below from drm's memory space.

Although this change isn't helping to fix the issue currently, but
this fix seems the right thing to do.

One thing to notice is that, if we restore the sg->nents to
sg->orig_nents in vb2_dma_sg_dmabuf_ops_map(), we don't see the below
corruptions.

Any pointers on this will be highly appreciated.
Thanks.

--
[  338.070558] Unable to handle kernel paging request at virtual address 
4038
[  338.078751] Mem abort info:
[  338.081671]   ESR = 0x9604
[  338.084860]   Exception class = DABT (current EL), IL = 32 bits
[  338.090972]   SET = 0, FnV = 0
[  338.094139]   EA = 0, S1PTW = 0
[  338.097393] Data abort info:
[  338.100375]   ISV = 0, ISS = 0x0004
[  338.104362]   CM = 0, WnR = 0
[  338.107446] [4038] address between user and kernel address ranges
[  338.114801] Internal error: Oops: 9604 [#1] PREEMPT SMP
[  338.120527] Modules linked in: rfcomm uinput cdc_ether venus_dec venus_enc 
usbnet videobuf2_dma_sg videobuf2_memops hci_uart btqca bluetooth r8152 mii 
ath10k_snoc venus_core ath10k_core v4l2_mem2mem videobuf2_v4l2 videobuf2_common 
ath mac80211 ecdh_generic qcom_q6v5_mss lzo lzo_compress qcom_q6v5_adsp 
qcom_common qcom_q6v5 zram bridge stp llc ipt_MASQUERADE fuse snd_seq_dummy 
snd_seq snd_seq_device cfg80211 joydev
[  338.158192] CPU: 4 PID: 3235 Comm: chrome Tainted: GW 4.19.0 
#2
[  338.165700] Hardware name: Google Cheza (rev1) (DT)
[  338.170720] pstate: 8049 (Nzcv daif +PAN -UAO)
[  338.175660] pc : drm_mm_insert_node_in_range+0xfc/0x348
[  338.181035] lr : drm_mm_insert_node_in_range+0x24/0x348
[  338.186407] sp : ff8013033b30
[  338.189816] x29: ff8013033bd0 x28: ff8008591894
[  338.195275] x27: 0010 x26: 
[  338.200734] x25:  x24: 
[  338.206194] x23:  x22: ffc0f48b7e08
[  338.211656] x21:  x20: 005d
[  338.217118] x19:  x18: 
[  338.222581] x17:  x16: 
[  338.228046] x15:  x14: 
[  338.233511] x13: 0001 x12: ffc0b1da7200
[  338.238978] x11: 0010 x10: 0010
[  338.244437] x9 : 0008 x8 : 4000
[  338.249898] x7 :  x6 : 
[  338.255361] x5 :  x4 : 
[  338.260823] x3 :  x2 : 005d
[  338.266285] x1 : ffc0b1da7100 x0 : ffc0b0215800
[  338.271748] Process chrome (pid: 3235, stack limit = 0x0900f416)
[  338.278628] Call trace:
[  338.281151]  drm_mm_insert_node_in_range+0xfc/0x348
[  338.286168]  msm_gem_map_vma+0x60/0xdc
[  338.290022]  msm_gem_get_iova+0xb4/0xf4
[  338.293967]  msm_ioctl_gem_info+0x90/0xdc
[  338.298089]  drm_ioctl_kernel+0xa8/0xe8
[  338.302043]  drm_ioctl+0x218/0x384
[  338.305547]  drm_compat_ioctl+0xd8/0xe8
[  338.309503]  __arm64_compat_sys_ioctl+0x134/0x20c
[  338.314339]  el0_svc_common+0xa0/0xf0
[  338.318108]  el0_svc_compat_handler+0x2c/0x38
[  338.322588]  el0_svc_compat+0x8/0x18
[  338.326274] Code: f94066c8 aa1f03e0 321d03e9 321c03ea (f9401d0b)
[  338.332538] ---[ end trace 5c09e60869887d87 ]---
[  338.354633] Kernel panic - not syncing: Fatal exception
[  338.360018] SMP: stopping secondary CPUs
[  338.364179] Kernel Offset: disabled
[  338.367779] CPU features: 0x0,22802a18
[  338.371643] Memory Limit: none
--

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

diff --git a/drivers/gpu/drm/drm_prime.c b/drivers/gpu/drm/drm_prime.c
index 231e3f6d5f41..0d9b1c43523a 100644
--- a/drivers/gpu/drm/drm_prime.c
+++ b/drivers/gpu/drm/drm_prime.c
@@ -945,7 +945,7 @@ int drm_prime_sg_to_page_addr_arrays(struct sg_table *sgt, 
struct page **pages,
 
index = 0;
for_each_sg(sgt->sgl, sg, sgt->nents, count) {
-   len = sg->length;
+   len = sg_dma_length(sg);
page = sg_page(sg);
 

Re: [PATCH 1/1] drm/prime: Use sg_dma_len() macro to get sg's length

2019-01-08 Thread Vivek Gautam
On Mon, Jan 7, 2019 at 4:14 PM kbuild test robot  wrote:
>
> Hi Vivek,
>
> Thank you for the patch! Yet something to improve:
>
> [auto build test ERROR on linus/master]
> [also build test ERROR on v5.0-rc1 next-20190107]
> [if your patch is applied to the wrong git tree, please drop us a note to 
> help improve the system]
>
> url:
> https://github.com/0day-ci/linux/commits/Vivek-Gautam/drm-prime-Use-sg_dma_len-macro-to-get-sg-s-length/20190107-181350
> config: x86_64-randconfig-x013-201901 (attached as .config)
> compiler: gcc-7 (Debian 7.3.0-1) 7.3.0
> reproduce:
> # save the attached .config to linux build tree
> make ARCH=x86_64
>
> All errors (new ones prefixed by >>):
>
>drivers/gpu/drm/drm_prime.c: In function 
> 'drm_prime_sg_to_page_addr_arrays':
> >> drivers/gpu/drm/drm_prime.c:948:9: error: implicit declaration of function 
> >> 'sg_dma_length'; did you mean 'sg_dma_len'? 
> >> [-Werror=implicit-function-declaration]
>   len = sg_dma_length(sg);
> ^
> sg_dma_len

Sorry, my fat finger :(
This should be as suggested - sg_dma_len().

Thanks
Vivek

>cc1: some warnings being treated as errors
>
> vim +948 drivers/gpu/drm/drm_prime.c
>
>926
>927  /**
>928   * drm_prime_sg_to_page_addr_arrays - convert an sg table into a page 
> array
>929   * @sgt: scatter-gather table to convert
>930   * @pages: optional array of page pointers to store the page array in
>931   * @addrs: optional array to store the dma bus address of each page
>932   * @max_entries: size of both the passed-in arrays
>933   *
>934   * Exports an sg table into an array of pages and addresses. This is 
> currently
>935   * required by the TTM driver in order to do correct fault handling.
>936   */
>937  int drm_prime_sg_to_page_addr_arrays(struct sg_table *sgt, struct 
> page **pages,
>938   dma_addr_t *addrs, int 
> max_entries)
>939  {
>940  unsigned count;
>941  struct scatterlist *sg;
>942  struct page *page;
>943  u32 len, index;
>944  dma_addr_t addr;
>945
>946  index = 0;
>947  for_each_sg(sgt->sgl, sg, sgt->nents, count) {
>  > 948  len = sg_dma_length(sg);
>949  page = sg_page(sg);
>950  addr = sg_dma_address(sg);
>951
>952  while (len > 0) {
>953  if (WARN_ON(index >= max_entries))
>954  return -1;
>955  if (pages)
>956  pages[index] = page;
>957  if (addrs)
>958  addrs[index] = addr;
>959
>960  page++;
>961  addr += PAGE_SIZE;
>962  len -= PAGE_SIZE;
>963  index++;
>964  }
>965  }
>966  return 0;
>967  }
>968  EXPORT_SYMBOL(drm_prime_sg_to_page_addr_arrays);
>969
>
> ---
> 0-DAY kernel test infrastructureOpen Source Technology Center
> https://lists.01.org/pipermail/kbuild-all   Intel Corporation



-- 
QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member
of Code Aurora Forum, hosted by The Linux Foundation
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH v2 1/1] drm/prime: Use sg_dma_len() macro to get sg's length

2019-01-08 Thread Vivek Gautam
After mapping a sg list the we should use sg_dma_address() and
sg_dma_len() macros to access sg->address and sg->length. Fix
the same for sg->length in drm_prime_sg_to_page_addr_arrays().

Signed-off-by: Vivek Gautam 
---

Changes since v1:
 - Fixed compilation error: replaced sg_dma_length() with sg_dma_len().

This came while debugging one dmabuf import issue that we are seeing
on sdm845 target.
The dmabuf which is prepared by video (venus in this case), is imported
by drm device.
The import call flow looks like follows:

drm_gem_prime_import()
 - drm_gem_prime_import_dev()
   - dma_buf_attach() & dma_buf_map_attachment()
 - From dma_buf_map_attachment()
   - vb2_dma_sg_dmabuf_ops_map()
 - dma_map_sg(): this updates the sg->nents.

From debugging, the sg table mapping results in sg's 'nents' to be less that
the original nents. Now drm device prepares the page information based on
this sg table, and messes up with the mappings, and we start seeing random
crashes as below from drm's memory space.

Although this change isn't helping to fix the issue currently, but
this fix seems the right thing to do.

One thing to notice is that, if we restore the sg->nents to
sg->orig_nents in vb2_dma_sg_dmabuf_ops_map(), we don't see the below
corruptions.

Any pointers on this will be highly appreciated.
Thanks.

--
[  338.070558] Unable to handle kernel paging request at virtual address 
4038
[  338.078751] Mem abort info:
[  338.081671]   ESR = 0x9604
[  338.084860]   Exception class = DABT (current EL), IL = 32 bits
[  338.090972]   SET = 0, FnV = 0
[  338.094139]   EA = 0, S1PTW = 0
[  338.097393] Data abort info:
[  338.100375]   ISV = 0, ISS = 0x0004
[  338.104362]   CM = 0, WnR = 0
[  338.107446] [4038] address between user and kernel address ranges
[  338.114801] Internal error: Oops: 9604 [#1] PREEMPT SMP
[  338.120527] Modules linked in: rfcomm uinput cdc_ether venus_dec venus_enc 
usbnet videobuf2_dma_sg videobuf2_memops hci_uart btqca bluetooth r8152 mii 
ath10k_snoc venus_core ath10k_core v4l2_mem2mem videobuf2_v4l2 videobuf2_common 
ath mac80211 ecdh_generic qcom_q6v5_mss lzo lzo_compress qcom_q6v5_adsp 
qcom_common qcom_q6v5 zram bridge stp llc ipt_MASQUERADE fuse snd_seq_dummy 
snd_seq snd_seq_device cfg80211 joydev
[  338.158192] CPU: 4 PID: 3235 Comm: chrome Tainted: GW 4.19.0 
#2
[  338.165700] Hardware name: Google Cheza (rev1) (DT)
[  338.170720] pstate: 8049 (Nzcv daif +PAN -UAO)
[  338.175660] pc : drm_mm_insert_node_in_range+0xfc/0x348
[  338.181035] lr : drm_mm_insert_node_in_range+0x24/0x348
[  338.186407] sp : ff8013033b30
[  338.189816] x29: ff8013033bd0 x28: ff8008591894
[  338.195275] x27: 0010 x26: 
[  338.200734] x25:  x24: 
[  338.206194] x23:  x22: ffc0f48b7e08
[  338.211656] x21:  x20: 005d
[  338.217118] x19:  x18: 
[  338.222581] x17:  x16: 
[  338.228046] x15:  x14: 
[  338.233511] x13: 0001 x12: ffc0b1da7200
[  338.238978] x11: 0010 x10: 0010
[  338.244437] x9 : 0008 x8 : 4000
[  338.249898] x7 :  x6 : 
[  338.255361] x5 :  x4 : 
[  338.260823] x3 :  x2 : 005d
[  338.266285] x1 : ffc0b1da7100 x0 : ffc0b0215800
[  338.271748] Process chrome (pid: 3235, stack limit = 0x0900f416)
[  338.278628] Call trace:
[  338.281151]  drm_mm_insert_node_in_range+0xfc/0x348
[  338.286168]  msm_gem_map_vma+0x60/0xdc
[  338.290022]  msm_gem_get_iova+0xb4/0xf4
[  338.293967]  msm_ioctl_gem_info+0x90/0xdc
[  338.298089]  drm_ioctl_kernel+0xa8/0xe8
[  338.302043]  drm_ioctl+0x218/0x384
[  338.305547]  drm_compat_ioctl+0xd8/0xe8
[  338.309503]  __arm64_compat_sys_ioctl+0x134/0x20c
[  338.314339]  el0_svc_common+0xa0/0xf0
[  338.318108]  el0_svc_compat_handler+0x2c/0x38
[  338.322588]  el0_svc_compat+0x8/0x18
[  338.326274] Code: f94066c8 aa1f03e0 321d03e9 321c03ea (f9401d0b)
[  338.332538] ---[ end trace 5c09e60869887d87 ]---
[  338.354633] Kernel panic - not syncing: Fatal exception
[  338.360018] SMP: stopping secondary CPUs
[  338.364179] Kernel Offset: disabled
[  338.367779] CPU features: 0x0,22802a18
[  338.371643] Memory Limit: none
--

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

diff --git a/drivers/gpu/drm/drm_prime.c b/drivers/gpu/drm/drm_prime.c
index 231e3f6d5f41..aa87ba9c0d7b 100644
--- a/drivers/gpu/drm/drm_prime.c
+++ b/drivers/gpu/drm/drm_prime.c
@@ -945,7 +945,7 @@ int drm_prime_sg_to_page_addr_arrays(struct sg_table *sgt, 
struct page **pages,
 
index = 0;
for_each_sg(sgt->sgl, sg, sgt->nents, count) {
-   len = sg->length;
+   

Re: [PATCH] of/device: add blacklist for iommu dma_ops

2019-06-03 Thread Vivek Gautam
On Mon, Jun 3, 2019 at 4:47 PM Christoph Hellwig  wrote:
>
> If you (and a few others actors in the thread) want people to actually
> read what you wrote please follow proper mailing list ettiquette.  I've
> given up on reading all the recent mails after scrolling through two
> pages of full quotes.

Apologies for not cutting down the quoted text. I will be more careful
next time onwards.

Regards
Vivek

-- 
QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member
of Code Aurora Forum, hosted by The Linux Foundation


Re: [PATCH] of/device: add blacklist for iommu dma_ops

2019-06-03 Thread Vivek Gautam




On 6/3/2019 11:50 AM, Tomasz Figa wrote:

On Mon, Jun 3, 2019 at 4:40 AM Rob Clark  wrote:

On Fri, May 10, 2019 at 7:35 AM Rob Clark  wrote:

On Tue, Dec 4, 2018 at 2:29 PM Rob Herring  wrote:

On Sat, Dec 1, 2018 at 10:54 AM Rob Clark  wrote:

This solves a problem we see with drm/msm, caused by getting
iommu_dma_ops while we attach our own domain and manage it directly at
the iommu API level:

   [0038] user address but active_mm is swapper
   Internal error: Oops: 9605 [#1] PREEMPT SMP
   Modules linked in:
   CPU: 7 PID: 70 Comm: kworker/7:1 Tainted: GW 4.19.3 #90
   Hardware name: xxx (DT)
   Workqueue: events deferred_probe_work_func
   pstate: 80c9 (Nzcv daif +PAN +UAO)
   pc : iommu_dma_map_sg+0x7c/0x2c8
   lr : iommu_dma_map_sg+0x40/0x2c8
   sp : ff80095eb4f0
   x29: ff80095eb4f0 x28: 
   x27: ffc0f9431578 x26: 
   x25:  x24: 0003
   x23: 0001 x22: ffc0fa9ac010
   x21:  x20: ffc0fab40980
   x19: ffc0fab40980 x18: 0003
   x17: 01c4 x16: 0007
   x15: 000e x14: 
   x13:  x12: 0028
   x11: 0101010101010101 x10: 7f7f7f7f7f7f7f7f
   x9 :  x8 : ffc0fab409a0
   x7 :  x6 : 0002
   x5 : 0001 x4 : 
   x3 : 0001 x2 : 0002
   x1 : ffc0f9431578 x0 : 
   Process kworker/7:1 (pid: 70, stack limit = 0x17d08ffb)
   Call trace:
iommu_dma_map_sg+0x7c/0x2c8
__iommu_map_sg_attrs+0x70/0x84
get_pages+0x170/0x1e8
msm_gem_get_iova+0x8c/0x128
_msm_gem_kernel_new+0x6c/0xc8
msm_gem_kernel_new+0x4c/0x58
dsi_tx_buf_alloc_6g+0x4c/0x8c
msm_dsi_host_modeset_init+0xc8/0x108
msm_dsi_modeset_init+0x54/0x18c
_dpu_kms_drm_obj_init+0x430/0x474
dpu_kms_hw_init+0x5f8/0x6b4
msm_drm_bind+0x360/0x6c8
try_to_bring_up_master.part.7+0x28/0x70
component_master_add_with_match+0xe8/0x124
msm_pdev_probe+0x294/0x2b4
platform_drv_probe+0x58/0xa4
really_probe+0x150/0x294
driver_probe_device+0xac/0xe8
__device_attach_driver+0xa4/0xb4
bus_for_each_drv+0x98/0xc8
__device_attach+0xac/0x12c
device_initial_probe+0x24/0x30
bus_probe_device+0x38/0x98
deferred_probe_work_func+0x78/0xa4
process_one_work+0x24c/0x3dc
worker_thread+0x280/0x360
kthread+0x134/0x13c
ret_from_fork+0x10/0x18
   Code: d284 91000725 6b17039f 5400048a (f9401f40)
   ---[ end trace f22dda57f3648e2c ]---
   Kernel panic - not syncing: Fatal exception
   SMP: stopping secondary CPUs
   Kernel Offset: disabled
   CPU features: 0x0,22802a18
   Memory Limit: none

The problem is that when drm/msm does it's own iommu_attach_device(),
now the domain returned by iommu_get_domain_for_dev() is drm/msm's
domain, and it doesn't have domain->iova_cookie.

We kind of avoided this problem prior to sdm845/dpu because the iommu
was attached to the mdp node in dt, which is a child of the toplevel
mdss node (which corresponds to the dev passed in dma_map_sg()).  But
with sdm845, now the iommu is attached at the mdss level so we hit the
iommu_dma_ops in dma_map_sg().

But auto allocating/attaching a domain before the driver is probed was
already a blocking problem for enabling per-context pagetables for the
GPU.  This problem is also now solved with this patch.

Fixes: 97890ba9289c dma-mapping: detect and configure IOMMU in of_dma_configure
Tested-by: Douglas Anderson 
Signed-off-by: Rob Clark 
---
This is an alternative/replacement for [1].  What it lacks in elegance
it makes up for in practicality ;-)

[1] https://patchwork.freedesktop.org/patch/264930/

  drivers/of/device.c | 22 ++
  1 file changed, 22 insertions(+)

diff --git a/drivers/of/device.c b/drivers/of/device.c
index 5957cd4fa262..15ffee00fb22 100644
--- a/drivers/of/device.c
+++ b/drivers/of/device.c
@@ -72,6 +72,14 @@ int of_device_add(struct platform_device *ofdev)
 return device_add(>dev);
  }

+static const struct of_device_id iommu_blacklist[] = {
+   { .compatible = "qcom,mdp4" },
+   { .compatible = "qcom,mdss" },
+   { .compatible = "qcom,sdm845-mdss" },
+   { .compatible = "qcom,adreno" },
+   {}
+};

Not completely clear to whether this is still needed or not, but this
really won't scale. Why can't the driver for these devices override
whatever has been setup by default?


fwiw, at the moment it is not needed, but it will become needed again
to implement per-context pagetables (although I suppose for this we
only need to blacklist qcom,adreno and not also the display nodes).

So, another case I've come across, on the display side.. I'm working
on handling the case where bootloader enables display (and takes iommu
out of reset).. as soon as DMA domain gets attached we get iommu
faults, because bootloader has 

Re: [PATCH] of/device: add blacklist for iommu dma_ops

2019-06-03 Thread Vivek Gautam
On Mon, Jun 3, 2019 at 4:14 PM Rob Clark  wrote:
>
> On Mon, Jun 3, 2019 at 12:57 AM Vivek Gautam
>  wrote:
> >
> >
> >
> > On 6/3/2019 11:50 AM, Tomasz Figa wrote:
> > > On Mon, Jun 3, 2019 at 4:40 AM Rob Clark  wrote:
> > >> On Fri, May 10, 2019 at 7:35 AM Rob Clark  wrote:
> > >>> On Tue, Dec 4, 2018 at 2:29 PM Rob Herring  wrote:
> > >>>> On Sat, Dec 1, 2018 at 10:54 AM Rob Clark  wrote:
> > >>>>> This solves a problem we see with drm/msm, caused by getting
> > >>>>> iommu_dma_ops while we attach our own domain and manage it directly at
> > >>>>> the iommu API level:
> > >>>>>
> > >>>>>[0038] user address but active_mm is swapper
> > >>>>>Internal error: Oops: 9605 [#1] PREEMPT SMP
> > >>>>>Modules linked in:
> > >>>>>CPU: 7 PID: 70 Comm: kworker/7:1 Tainted: GW 
> > >>>>> 4.19.3 #90
> > >>>>>Hardware name: xxx (DT)
> > >>>>>Workqueue: events deferred_probe_work_func
> > >>>>>pstate: 80c9 (Nzcv daif +PAN +UAO)
> > >>>>>pc : iommu_dma_map_sg+0x7c/0x2c8
> > >>>>>lr : iommu_dma_map_sg+0x40/0x2c8
> > >>>>>sp : ff80095eb4f0
> > >>>>>x29: ff80095eb4f0 x28: 
> > >>>>>x27: ffc0f9431578 x26: 
> > >>>>>x25:  x24: 0003
> > >>>>>x23: 0001 x22: ffc0fa9ac010
> > >>>>>x21:  x20: ffc0fab40980
> > >>>>>x19: ffc0fab40980 x18: 0003
> > >>>>>x17: 01c4 x16: 0007
> > >>>>>x15: 000e x14: 
> > >>>>>x13:  x12: 0028
> > >>>>>x11: 0101010101010101 x10: 7f7f7f7f7f7f7f7f
> > >>>>>x9 :  x8 : ffc0fab409a0
> > >>>>>x7 :  x6 : 0002
> > >>>>>x5 : 0001 x4 : 
> > >>>>>x3 : 0001 x2 : 0002
> > >>>>>x1 : ffc0f9431578 x0 : 
> > >>>>>Process kworker/7:1 (pid: 70, stack limit = 0x17d08ffb)
> > >>>>>Call trace:
> > >>>>> iommu_dma_map_sg+0x7c/0x2c8
> > >>>>> __iommu_map_sg_attrs+0x70/0x84
> > >>>>> get_pages+0x170/0x1e8
> > >>>>> msm_gem_get_iova+0x8c/0x128
> > >>>>> _msm_gem_kernel_new+0x6c/0xc8
> > >>>>> msm_gem_kernel_new+0x4c/0x58
> > >>>>> dsi_tx_buf_alloc_6g+0x4c/0x8c
> > >>>>> msm_dsi_host_modeset_init+0xc8/0x108
> > >>>>> msm_dsi_modeset_init+0x54/0x18c
> > >>>>> _dpu_kms_drm_obj_init+0x430/0x474
> > >>>>> dpu_kms_hw_init+0x5f8/0x6b4
> > >>>>> msm_drm_bind+0x360/0x6c8
> > >>>>> try_to_bring_up_master.part.7+0x28/0x70
> > >>>>> component_master_add_with_match+0xe8/0x124
> > >>>>> msm_pdev_probe+0x294/0x2b4
> > >>>>> platform_drv_probe+0x58/0xa4
> > >>>>> really_probe+0x150/0x294
> > >>>>> driver_probe_device+0xac/0xe8
> > >>>>> __device_attach_driver+0xa4/0xb4
> > >>>>> bus_for_each_drv+0x98/0xc8
> > >>>>> __device_attach+0xac/0x12c
> > >>>>> device_initial_probe+0x24/0x30
> > >>>>> bus_probe_device+0x38/0x98
> > >>>>> deferred_probe_work_func+0x78/0xa4
> > >>>>> process_one_work+0x24c/0x3dc
> > >>>>> worker_thread+0x280/0x360
> > >>>>> kthread+0x134/0x13c
> > >>>>> ret_from_fork+0x10/0x18
> > >>>>>Code: d284 91000725 6b17039f 5400048a (f9401f40)
> > >>>>>---[ end trace f22dda57f3648e2c ]---
> > >>>>>Kernel panic - not syncing: Fatal exception
> > >>>>>SMP: stopping secondary CPUs
> > >>>>>Kernel Offset: disable

Re: [PATCH 1/1] drm/panel: truly: Add additional delay after pulling down reset gpio

2019-06-06 Thread Vivek Gautam
On Wed, Jun 5, 2019 at 1:54 PM Sam Ravnborg  wrote:
>
> Hi Vivek,
>
> On Mon, May 27, 2019 at 03:56:16PM +0530, Vivek Gautam wrote:
> > MTP SDM845 panel seems to need additional delay to bring panel
> > to a workable state. Running modetest without this change displays
> > blurry artifacts.
> >
> > Signed-off-by: Vivek Gautam 
>
> added to drm-misc-next

Thanks a lot.

Best regards
Vivek

>
> Sam
>
> > ---
> >  drivers/gpu/drm/panel/panel-truly-nt35597.c | 1 +
> >  1 file changed, 1 insertion(+)
> >
> > diff --git a/drivers/gpu/drm/panel/panel-truly-nt35597.c 
> > b/drivers/gpu/drm/panel/panel-truly-nt35597.c
> > index fc2a66c53db4..aa7153fd3be4 100644
> > --- a/drivers/gpu/drm/panel/panel-truly-nt35597.c
> > +++ b/drivers/gpu/drm/panel/panel-truly-nt35597.c
> > @@ -280,6 +280,7 @@ static int truly_35597_power_on(struct truly_nt35597 
> > *ctx)
> >   gpiod_set_value(ctx->reset_gpio, 1);
> >   usleep_range(1, 2);
> >   gpiod_set_value(ctx->reset_gpio, 0);
> > + usleep_range(1, 2);
> >
> >   return 0;
> >  }
> > --
> > QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member
> > of Code Aurora Forum, hosted by The Linux Foundation
> >
> > ___
> > dri-devel mailing list
> > dri-devel@lists.freedesktop.org
> > https://lists.freedesktop.org/mailman/listinfo/dri-devel



-- 
QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member
of Code Aurora Forum, hosted by The Linux Foundation


[PATCH 1/1] drm/panel: truly: Add additional delay after pulling down reset gpio

2019-05-27 Thread Vivek Gautam
MTP SDM845 panel seems to need additional delay to bring panel
to a workable state. Running modetest without this change displays
blurry artifacts.

Signed-off-by: Vivek Gautam 
---
 drivers/gpu/drm/panel/panel-truly-nt35597.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/gpu/drm/panel/panel-truly-nt35597.c 
b/drivers/gpu/drm/panel/panel-truly-nt35597.c
index fc2a66c53db4..aa7153fd3be4 100644
--- a/drivers/gpu/drm/panel/panel-truly-nt35597.c
+++ b/drivers/gpu/drm/panel/panel-truly-nt35597.c
@@ -280,6 +280,7 @@ static int truly_35597_power_on(struct truly_nt35597 *ctx)
gpiod_set_value(ctx->reset_gpio, 1);
usleep_range(1, 2);
gpiod_set_value(ctx->reset_gpio, 0);
+   usleep_range(1, 2);
 
return 0;
 }
-- 
QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member
of Code Aurora Forum, hosted by The Linux Foundation