Re: [PATCH RFC v2 06/12] driver: soc: exynos-pmu: Add exynos7 power domain on/off ops

2014-11-25 Thread amit daniel kachhap
On Tue, Nov 25, 2014 at 1:00 PM, Ulf Hansson ulf.hans...@linaro.org wrote:
 On 24 November 2014 at 14:04, Amit Daniel Kachhap
 amit.dan...@samsung.com wrote:
 This patch uses the restructuring done in PD handlers and adds PD
 on/off/status handlers for exynos7. In this SoC, some extra settings
 need to be done prior to turning on/off power domains. Some of those
 settings are also different from different power domains so is uses
 the power domain compatible name feature to distinguish between power
 domains.

 Signed-off-by: Amit Daniel Kachhap amit.dan...@samsung.com
 ---
  drivers/soc/samsung/exynos-pmu.c|  105 
 +++
  include/linux/soc/samsung/exynos-regs-pmu.h |   17 +
  2 files changed, 122 insertions(+)

 diff --git a/drivers/soc/samsung/exynos-pmu.c 
 b/drivers/soc/samsung/exynos-pmu.c
 index e690f65..b9631d5 100644
 --- a/drivers/soc/samsung/exynos-pmu.c
 +++ b/drivers/soc/samsung/exynos-pmu.c
 @@ -1202,6 +1202,104 @@ static void exynos7_pmu_init(void)
 }
  }

 +static int exynos7_pd_extraconf_base(const char *pd_name)
 +{
 +   if (!pd_name)
 +   return -EINVAL;
 +
 +   if (!strcmp(samsung,exynos7-pd-mfc, pd_name))
 +   return EXYNOS7_CLKRUN_CMU_MFC_SYS_PWR_REG;
 +   else if (!strcmp(samsung,exynos7-pd-hevc, pd_name))
 +   return EXYNOS7_CLKRUN_CMU_HEVC_SYS_PWR_REG;
 +   else if (!strcmp(samsung,exynos7-pd-mscl, pd_name))
 +   return EXYNOS7_CLKRUN_CMU_MSCL_SYS_PWR_REG;
 +   else if (!strcmp(samsung,exynos7-pd-g2d, pd_name))
 +   return EXYNOS7_CLKRUN_CMU_G2D_SYS_PWR_REG;
 +   else if (!strcmp(samsung,exynos7-pd-fsys0, pd_name))
 +   return EXYNOS7_CLKRUN_CMU_FSYS0_SYS_PWR_REG;
 +   else if (!strcmp(samsung,exynos7-pd-fsys1, pd_name))
 +   return EXYNOS7_CLKRUN_CMU_FSYS1_SYS_PWR_REG;
 +   else if (!strcmp(samsung,exynos7-pd-aud, pd_name))
 +   return EXYNOS7_CLKRUN_CMU_AUD_SYS_PWR_REG;
 +   else if (!strcmp(samsung,exynos7-pd-disp, pd_name))
 +   return EXYNOS7_CLKRUN_CMU_DISP_SYS_PWR_REG;
 +   else if (!strcmp(samsung,exynos7-pd-vpp, pd_name))
 +   return EXYNOS7_CLKRUN_CMU_VPP_SYS_PWR_REG;
 +   else if (!strcmp(samsung,exynos7-pd-vpp, pd_name))
 +   return EXYNOS7_CLKRUN_CMU_VPP_SYS_PWR_REG;
 +   else if (!strcmp(samsung,exynos7-pd-isp0, pd_name))
 +   return EXYNOS7_CLKRUN_CMU_ISP0_SYS_PWR_REG;
 +   else if (!strcmp(samsung,exynos7-pd-isp1, pd_name))
 +   return EXYNOS7_CLKRUN_CMU_ISP1_SYS_PWR_REG;
 +   else if (!strcmp(samsung,exynos7-pd-cam0, pd_name))
 +   return EXYNOS7_CLKRUN_CMU_CAM0_SYS_PWR_REG;
 +   else if (!strcmp(samsung,exynos7-pd-cam1, pd_name))
 +   return EXYNOS7_CLKRUN_CMU_CAM1_SYS_PWR_REG;
 +   else if (!strcmp(samsung,exynos7-pd-g3d, pd_name))
 +   return EXYNOS7_CLKRUN_CMU_CAM1_SYS_PWR_REG;

 I think we should move away from using strings to find a matching PM
 domain. Instead we should use a enum/define pointing to the PM domain
 in an array of PM domains, or similar.
Thanks for looking into the series.
Here pd names are compatible string from the pd DT nodes. I think
compatible names are
used in many places like searching for platform data in DT based probe etc.
yes enum can also be used to locate the PM domain. Will check.

 The UX500 SOC initial support for PM domains is queued for 3.19 and is
 currently available in linux-next. You may want to get some
 inspiration from that approach.
ok will check them.

 +
 +   pr_err(%s: Unsupported power domain\n, pd_name);
 +   return 0;
 +}
 +
 +static int exynos7_pd_powerdown(const char *pd_name, void __iomem *pd_addr)
 +{

 Considering the suggestion above and to move away from using strings
 like this; this function could take a pointer to the PM domain instead
 of a string and the __iomem, right!?
Actually in our case there are 2 files, pm-domain.c and exynos-pmu.c.
I thought of abstracting out generic PD related stuffs from
exynos-pmu.c file so this function
takes these type of arguments.

 +   int off_base = exynos7_pd_extraconf_base(pd_name);
 +
 +   if (!off_base)
 +   return -EINVAL;
 +
 +   /* Initialise the pd extraconf registers */
 +   pmu_raw_writel(0, off_base + EXYNOS7_CLKRUN_CMU_PD_SYS_PWR_REG);
 +   pmu_raw_writel(0, off_base + EXYNOS7_CLKSTOP_CMU_PD_SYS_PWR_REG);
 +   pmu_raw_writel(0, off_base + EXYNOS7_DISABLE_PLL_CMU_PD_SYS_PWR_REG);
 +   pmu_raw_writel(0, off_base + EXYNOS7_RESET_LOGIC_PD_SYS_PWR_REG);
 +   pmu_raw_writel(0, off_base + EXYNOS7_MEMORY_PD_SYS_PWR_REG);
 +   pmu_raw_writel(0, off_base + EXYNOS7_RESET_CMU_PD_SYS_PWR_REG);
 +
 +   if (!strcmp(samsung,exynos7-pd-fsys0, pd_name) ||
 +   !strcmp(samsung,exynos7-pd-fsys1, pd_name))
 +   pmu_raw_writel(1,
 +   off_base + 
 

[PATCH RFC v2 06/12] driver: soc: exynos-pmu: Add exynos7 power domain on/off ops

2014-11-24 Thread Amit Daniel Kachhap
This patch uses the restructuring done in PD handlers and adds PD
on/off/status handlers for exynos7. In this SoC, some extra settings
need to be done prior to turning on/off power domains. Some of those
settings are also different from different power domains so is uses
the power domain compatible name feature to distinguish between power
domains.

Signed-off-by: Amit Daniel Kachhap amit.dan...@samsung.com
---
 drivers/soc/samsung/exynos-pmu.c|  105 +++
 include/linux/soc/samsung/exynos-regs-pmu.h |   17 +
 2 files changed, 122 insertions(+)

diff --git a/drivers/soc/samsung/exynos-pmu.c b/drivers/soc/samsung/exynos-pmu.c
index e690f65..b9631d5 100644
--- a/drivers/soc/samsung/exynos-pmu.c
+++ b/drivers/soc/samsung/exynos-pmu.c
@@ -1202,6 +1202,104 @@ static void exynos7_pmu_init(void)
}
 }
 
+static int exynos7_pd_extraconf_base(const char *pd_name)
+{
+   if (!pd_name)
+   return -EINVAL;
+
+   if (!strcmp(samsung,exynos7-pd-mfc, pd_name))
+   return EXYNOS7_CLKRUN_CMU_MFC_SYS_PWR_REG;
+   else if (!strcmp(samsung,exynos7-pd-hevc, pd_name))
+   return EXYNOS7_CLKRUN_CMU_HEVC_SYS_PWR_REG;
+   else if (!strcmp(samsung,exynos7-pd-mscl, pd_name))
+   return EXYNOS7_CLKRUN_CMU_MSCL_SYS_PWR_REG;
+   else if (!strcmp(samsung,exynos7-pd-g2d, pd_name))
+   return EXYNOS7_CLKRUN_CMU_G2D_SYS_PWR_REG;
+   else if (!strcmp(samsung,exynos7-pd-fsys0, pd_name))
+   return EXYNOS7_CLKRUN_CMU_FSYS0_SYS_PWR_REG;
+   else if (!strcmp(samsung,exynos7-pd-fsys1, pd_name))
+   return EXYNOS7_CLKRUN_CMU_FSYS1_SYS_PWR_REG;
+   else if (!strcmp(samsung,exynos7-pd-aud, pd_name))
+   return EXYNOS7_CLKRUN_CMU_AUD_SYS_PWR_REG;
+   else if (!strcmp(samsung,exynos7-pd-disp, pd_name))
+   return EXYNOS7_CLKRUN_CMU_DISP_SYS_PWR_REG;
+   else if (!strcmp(samsung,exynos7-pd-vpp, pd_name))
+   return EXYNOS7_CLKRUN_CMU_VPP_SYS_PWR_REG;
+   else if (!strcmp(samsung,exynos7-pd-vpp, pd_name))
+   return EXYNOS7_CLKRUN_CMU_VPP_SYS_PWR_REG;
+   else if (!strcmp(samsung,exynos7-pd-isp0, pd_name))
+   return EXYNOS7_CLKRUN_CMU_ISP0_SYS_PWR_REG;
+   else if (!strcmp(samsung,exynos7-pd-isp1, pd_name))
+   return EXYNOS7_CLKRUN_CMU_ISP1_SYS_PWR_REG;
+   else if (!strcmp(samsung,exynos7-pd-cam0, pd_name))
+   return EXYNOS7_CLKRUN_CMU_CAM0_SYS_PWR_REG;
+   else if (!strcmp(samsung,exynos7-pd-cam1, pd_name))
+   return EXYNOS7_CLKRUN_CMU_CAM1_SYS_PWR_REG;
+   else if (!strcmp(samsung,exynos7-pd-g3d, pd_name))
+   return EXYNOS7_CLKRUN_CMU_CAM1_SYS_PWR_REG;
+
+   pr_err(%s: Unsupported power domain\n, pd_name);
+   return 0;
+}
+
+static int exynos7_pd_powerdown(const char *pd_name, void __iomem *pd_addr)
+{
+   int off_base = exynos7_pd_extraconf_base(pd_name);
+
+   if (!off_base)
+   return -EINVAL;
+
+   /* Initialise the pd extraconf registers */
+   pmu_raw_writel(0, off_base + EXYNOS7_CLKRUN_CMU_PD_SYS_PWR_REG);
+   pmu_raw_writel(0, off_base + EXYNOS7_CLKSTOP_CMU_PD_SYS_PWR_REG);
+   pmu_raw_writel(0, off_base + EXYNOS7_DISABLE_PLL_CMU_PD_SYS_PWR_REG);
+   pmu_raw_writel(0, off_base + EXYNOS7_RESET_LOGIC_PD_SYS_PWR_REG);
+   pmu_raw_writel(0, off_base + EXYNOS7_MEMORY_PD_SYS_PWR_REG);
+   pmu_raw_writel(0, off_base + EXYNOS7_RESET_CMU_PD_SYS_PWR_REG);
+
+   if (!strcmp(samsung,exynos7-pd-fsys0, pd_name) ||
+   !strcmp(samsung,exynos7-pd-fsys1, pd_name))
+   pmu_raw_writel(1,
+   off_base + EXYNOS7_RESET_SLEEP_PD_SYS_PWR_REG);
+
+   if (!strcmp(samsung,exynos7-pd-aud, pd_name)) {
+   pmu_raw_writel(0, EXYNOS7_PAD_RETENTION_AUD_SYS_PWR_REG);
+   pmu_raw_writel(0, EXYNOS7_GPIO_MODE_AUD_SYS_PWR_REG);
+   }
+
+   writel_relaxed((EXYNOS7_USE_PROLONGED_LOGIC_RESET |
+   EXYNOS7_USE_SC_FEEDBACK), pd_addr + EXYNOS_PD_OPTION);
+
+   return 0;
+}
+
+static int exynos7_pd_poweron(const char *pd_name, void __iomem *pd_addr)
+{
+   if (exynos7_pd_powerdown(pd_name, pd_addr))
+   return -EINVAL;
+
+   return __exynos_pd_poweron_off(true, pd_name, pd_addr,
+   EXYNOS7_INT_LOCAL_PWR_EN);
+}
+
+static int exynos7_pd_poweroff(const char *pd_name, void __iomem *pd_addr)
+{
+   if (exynos7_pd_powerdown(pd_name, pd_addr))
+   return -EINVAL;
+
+   return __exynos_pd_poweron_off(false, pd_name, pd_addr,
+   EXYNOS7_INT_LOCAL_PWR_EN);
+}
+
+static bool exynos7_pd_status(void __iomem *pd_addr)
+{
+   unsigned int val;
+
+   val = readl_relaxed(pd_addr + EXYNOS_PD_STATUS) 
+   EXYNOS7_INT_LOCAL_PWR_EN;
+   return  val ? true : false;
+}
+
 static struct exynos_pmu_pd_ops 

Re: [PATCH RFC v2 06/12] driver: soc: exynos-pmu: Add exynos7 power domain on/off ops

2014-11-24 Thread Ulf Hansson
On 24 November 2014 at 14:04, Amit Daniel Kachhap
amit.dan...@samsung.com wrote:
 This patch uses the restructuring done in PD handlers and adds PD
 on/off/status handlers for exynos7. In this SoC, some extra settings
 need to be done prior to turning on/off power domains. Some of those
 settings are also different from different power domains so is uses
 the power domain compatible name feature to distinguish between power
 domains.

 Signed-off-by: Amit Daniel Kachhap amit.dan...@samsung.com
 ---
  drivers/soc/samsung/exynos-pmu.c|  105 
 +++
  include/linux/soc/samsung/exynos-regs-pmu.h |   17 +
  2 files changed, 122 insertions(+)

 diff --git a/drivers/soc/samsung/exynos-pmu.c 
 b/drivers/soc/samsung/exynos-pmu.c
 index e690f65..b9631d5 100644
 --- a/drivers/soc/samsung/exynos-pmu.c
 +++ b/drivers/soc/samsung/exynos-pmu.c
 @@ -1202,6 +1202,104 @@ static void exynos7_pmu_init(void)
 }
  }

 +static int exynos7_pd_extraconf_base(const char *pd_name)
 +{
 +   if (!pd_name)
 +   return -EINVAL;
 +
 +   if (!strcmp(samsung,exynos7-pd-mfc, pd_name))
 +   return EXYNOS7_CLKRUN_CMU_MFC_SYS_PWR_REG;
 +   else if (!strcmp(samsung,exynos7-pd-hevc, pd_name))
 +   return EXYNOS7_CLKRUN_CMU_HEVC_SYS_PWR_REG;
 +   else if (!strcmp(samsung,exynos7-pd-mscl, pd_name))
 +   return EXYNOS7_CLKRUN_CMU_MSCL_SYS_PWR_REG;
 +   else if (!strcmp(samsung,exynos7-pd-g2d, pd_name))
 +   return EXYNOS7_CLKRUN_CMU_G2D_SYS_PWR_REG;
 +   else if (!strcmp(samsung,exynos7-pd-fsys0, pd_name))
 +   return EXYNOS7_CLKRUN_CMU_FSYS0_SYS_PWR_REG;
 +   else if (!strcmp(samsung,exynos7-pd-fsys1, pd_name))
 +   return EXYNOS7_CLKRUN_CMU_FSYS1_SYS_PWR_REG;
 +   else if (!strcmp(samsung,exynos7-pd-aud, pd_name))
 +   return EXYNOS7_CLKRUN_CMU_AUD_SYS_PWR_REG;
 +   else if (!strcmp(samsung,exynos7-pd-disp, pd_name))
 +   return EXYNOS7_CLKRUN_CMU_DISP_SYS_PWR_REG;
 +   else if (!strcmp(samsung,exynos7-pd-vpp, pd_name))
 +   return EXYNOS7_CLKRUN_CMU_VPP_SYS_PWR_REG;
 +   else if (!strcmp(samsung,exynos7-pd-vpp, pd_name))
 +   return EXYNOS7_CLKRUN_CMU_VPP_SYS_PWR_REG;
 +   else if (!strcmp(samsung,exynos7-pd-isp0, pd_name))
 +   return EXYNOS7_CLKRUN_CMU_ISP0_SYS_PWR_REG;
 +   else if (!strcmp(samsung,exynos7-pd-isp1, pd_name))
 +   return EXYNOS7_CLKRUN_CMU_ISP1_SYS_PWR_REG;
 +   else if (!strcmp(samsung,exynos7-pd-cam0, pd_name))
 +   return EXYNOS7_CLKRUN_CMU_CAM0_SYS_PWR_REG;
 +   else if (!strcmp(samsung,exynos7-pd-cam1, pd_name))
 +   return EXYNOS7_CLKRUN_CMU_CAM1_SYS_PWR_REG;
 +   else if (!strcmp(samsung,exynos7-pd-g3d, pd_name))
 +   return EXYNOS7_CLKRUN_CMU_CAM1_SYS_PWR_REG;

I think we should move away from using strings to find a matching PM
domain. Instead we should use a enum/define pointing to the PM domain
in an array of PM domains, or similar.

The UX500 SOC initial support for PM domains is queued for 3.19 and is
currently available in linux-next. You may want to get some
inspiration from that approach.

 +
 +   pr_err(%s: Unsupported power domain\n, pd_name);
 +   return 0;
 +}
 +
 +static int exynos7_pd_powerdown(const char *pd_name, void __iomem *pd_addr)
 +{

Considering the suggestion above and to move away from using strings
like this; this function could take a pointer to the PM domain instead
of a string and the __iomem, right!?

 +   int off_base = exynos7_pd_extraconf_base(pd_name);
 +
 +   if (!off_base)
 +   return -EINVAL;
 +
 +   /* Initialise the pd extraconf registers */
 +   pmu_raw_writel(0, off_base + EXYNOS7_CLKRUN_CMU_PD_SYS_PWR_REG);
 +   pmu_raw_writel(0, off_base + EXYNOS7_CLKSTOP_CMU_PD_SYS_PWR_REG);
 +   pmu_raw_writel(0, off_base + EXYNOS7_DISABLE_PLL_CMU_PD_SYS_PWR_REG);
 +   pmu_raw_writel(0, off_base + EXYNOS7_RESET_LOGIC_PD_SYS_PWR_REG);
 +   pmu_raw_writel(0, off_base + EXYNOS7_MEMORY_PD_SYS_PWR_REG);
 +   pmu_raw_writel(0, off_base + EXYNOS7_RESET_CMU_PD_SYS_PWR_REG);
 +
 +   if (!strcmp(samsung,exynos7-pd-fsys0, pd_name) ||
 +   !strcmp(samsung,exynos7-pd-fsys1, pd_name))
 +   pmu_raw_writel(1,
 +   off_base + 
 EXYNOS7_RESET_SLEEP_PD_SYS_PWR_REG);
 +
 +   if (!strcmp(samsung,exynos7-pd-aud, pd_name)) {
 +   pmu_raw_writel(0, EXYNOS7_PAD_RETENTION_AUD_SYS_PWR_REG);
 +   pmu_raw_writel(0, EXYNOS7_GPIO_MODE_AUD_SYS_PWR_REG);
 +   }
 +
 +   writel_relaxed((EXYNOS7_USE_PROLONGED_LOGIC_RESET |
 +   EXYNOS7_USE_SC_FEEDBACK), pd_addr + EXYNOS_PD_OPTION);
 +
 +   return 0;
 +}
 +
 +static int exynos7_pd_poweron(const char *pd_name, void __iomem *pd_addr)
 +{
 +   if (exynos7_pd_powerdown(pd_name, pd_addr))
 +