Re: [PATCH v1 2/3] drivers: meson: introduce secure power controller driver

2023-05-30 Thread Neil Armstrong

On 22/05/2023 14:09, Alexey Romanov via groups.io wrote:

This patch adds Power controller driver support for Amlogic
A1 family using secure monitor calls. The power domains register
only can access in secure world.

Signed-off-by: Alexey Romanov 
---
  drivers/power/domain/Kconfig   |   7 +
  drivers/power/domain/Makefile  |   1 +
  drivers/power/domain/meson-secure-pwrc.c   | 160 +
  include/dt-bindings/power/meson-a1-power.h |  32 +
  4 files changed, 200 insertions(+)
  create mode 100644 drivers/power/domain/meson-secure-pwrc.c
  create mode 100644 include/dt-bindings/power/meson-a1-power.h

diff --git a/drivers/power/domain/Kconfig b/drivers/power/domain/Kconfig
index 7e1b8c072fa..411c210756a 100644
--- a/drivers/power/domain/Kconfig
+++ b/drivers/power/domain/Kconfig
@@ -68,6 +68,13 @@ config MESON_EE_POWER_DOMAIN
  Enable support for manipulating Amlogic Meson Everything-Else power
  domains.
  
+config MESON_SECURE_POWER_DOMAIN

+   bool "Enable Amlogic Secure power domain driver"
+   depends on POWER_DOMAIN && ARCH_MESON && MESON_A1
+   help
+ Enable support for manipulating Amlogic Meson Secure power domains.
+ Support for Amlogic A1 series.
+
  config SANDBOX_POWER_DOMAIN
bool "Enable the sandbox power domain test driver"
depends on POWER_DOMAIN && SANDBOX
diff --git a/drivers/power/domain/Makefile b/drivers/power/domain/Makefile
index e6244776216..aa5a4ba57cd 100644
--- a/drivers/power/domain/Makefile
+++ b/drivers/power/domain/Makefile
@@ -12,6 +12,7 @@ obj-$(CONFIG_IMX8MP_HSIOMIX_BLKCTRL) += imx8mp-hsiomix.o
  obj-$(CONFIG_MTK_POWER_DOMAIN) += mtk-power-domain.o
  obj-$(CONFIG_MESON_GX_VPU_POWER_DOMAIN) += meson-gx-pwrc-vpu.o
  obj-$(CONFIG_MESON_EE_POWER_DOMAIN) += meson-ee-pwrc.o
+obj-$(CONFIG_MESON_SECURE_POWER_DOMAIN) += meson-secure-pwrc.o
  obj-$(CONFIG_SANDBOX_POWER_DOMAIN) += sandbox-power-domain.o
  obj-$(CONFIG_SANDBOX_POWER_DOMAIN) += sandbox-power-domain-test.o
  obj-$(CONFIG_TEGRA186_POWER_DOMAIN) += tegra186-power-domain.o
diff --git a/drivers/power/domain/meson-secure-pwrc.c 
b/drivers/power/domain/meson-secure-pwrc.c
new file mode 100644
index 000..f70f8e02423
--- /dev/null
+++ b/drivers/power/domain/meson-secure-pwrc.c
@@ -0,0 +1,160 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (c) 2023 SberDevices, Inc.
+ * Author: Alexey Romanov 
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+
+struct meson_secure_pwrc_domain_desc {
+   char *name;
+   size_t index;
+};
+
+struct meson_secure_pwrc_domain_data {
+   unsigned int count;
+   struct meson_secure_pwrc_domain_desc *domains;
+};
+
+struct meson_secure_pwrc_priv {
+   const struct meson_secure_pwrc_domain_data *data;
+};
+
+static int meson_secure_pwrc_on(struct power_domain *power_domain)
+{
+   struct meson_secure_pwrc_priv *priv = dev_get_priv(power_domain->dev);
+   struct meson_secure_pwrc_domain_desc *pwrc_domain;
+   int err;
+
+   pwrc_domain = &priv->data->domains[power_domain->id];
+
+   err = meson_sm_pwrdm_on(pwrc_domain->index);
+   if (err) {
+   pr_err("meson_sm_pwrdm_on() failed (%d)\n", err);
+   return err;
+   }
+
+   pr_debug("enable %s power domain\n", pwrc_domain->name);
+
+   return 0;
+}
+
+static int meson_secure_pwrc_off(struct power_domain *power_domain)
+{
+   struct meson_secure_pwrc_priv *priv = dev_get_priv(power_domain->dev);
+   struct meson_secure_pwrc_domain_desc *pwrc_domain;
+   int err;
+
+   pwrc_domain = &priv->data->domains[power_domain->id];
+
+   err = meson_sm_pwrdm_off(pwrc_domain->index);
+   if (err) {
+   pr_err("meson_sm_pwrdm_off() failed (%d)\n", err);
+   return err;
+   }
+
+   pr_debug("disable %s power domain\n", pwrc_domain->name);
+
+   return 0;
+}
+
+static int meson_secure_pwrc_of_xlate(struct power_domain *power_domain,
+ struct ofnode_phandle_args *args)
+{
+   struct meson_secure_pwrc_priv *priv = dev_get_priv(power_domain->dev);
+   struct meson_secure_pwrc_domain_desc *pwrc_domain;
+
+   if (args->args_count < 1) {
+   pr_err("invalid args count: %d\n", args->args_count);
+   return -EINVAL;
+   }
+
+   power_domain->id = args->args[0];
+
+   if (power_domain->id >= priv->data->count) {
+   pr_err("domain with ID=%lu is invalid\n", power_domain->id);
+   return -EINVAL;
+   }
+
+   pwrc_domain = &priv->data->domains[power_domain->id];
+
+   if (!pwrc_domain->name) {
+   pr_err("domain with ID=%lu is invalid\n", power_domain->id);
+   return -EINVAL;
+   }
+
+   return 0;
+}
+
+#define SEC_PD(__name) \
+[PWRC_##__name##_ID] = \
+{  \
+   .name = #__name,\

[PATCH v1 2/3] drivers: meson: introduce secure power controller driver

2023-05-22 Thread Alexey Romanov
This patch adds Power controller driver support for Amlogic
A1 family using secure monitor calls. The power domains register
only can access in secure world.

Signed-off-by: Alexey Romanov 
---
 drivers/power/domain/Kconfig   |   7 +
 drivers/power/domain/Makefile  |   1 +
 drivers/power/domain/meson-secure-pwrc.c   | 160 +
 include/dt-bindings/power/meson-a1-power.h |  32 +
 4 files changed, 200 insertions(+)
 create mode 100644 drivers/power/domain/meson-secure-pwrc.c
 create mode 100644 include/dt-bindings/power/meson-a1-power.h

diff --git a/drivers/power/domain/Kconfig b/drivers/power/domain/Kconfig
index 7e1b8c072fa..411c210756a 100644
--- a/drivers/power/domain/Kconfig
+++ b/drivers/power/domain/Kconfig
@@ -68,6 +68,13 @@ config MESON_EE_POWER_DOMAIN
  Enable support for manipulating Amlogic Meson Everything-Else power
  domains.
 
+config MESON_SECURE_POWER_DOMAIN
+   bool "Enable Amlogic Secure power domain driver"
+   depends on POWER_DOMAIN && ARCH_MESON && MESON_A1
+   help
+ Enable support for manipulating Amlogic Meson Secure power domains.
+ Support for Amlogic A1 series.
+
 config SANDBOX_POWER_DOMAIN
bool "Enable the sandbox power domain test driver"
depends on POWER_DOMAIN && SANDBOX
diff --git a/drivers/power/domain/Makefile b/drivers/power/domain/Makefile
index e6244776216..aa5a4ba57cd 100644
--- a/drivers/power/domain/Makefile
+++ b/drivers/power/domain/Makefile
@@ -12,6 +12,7 @@ obj-$(CONFIG_IMX8MP_HSIOMIX_BLKCTRL) += imx8mp-hsiomix.o
 obj-$(CONFIG_MTK_POWER_DOMAIN) += mtk-power-domain.o
 obj-$(CONFIG_MESON_GX_VPU_POWER_DOMAIN) += meson-gx-pwrc-vpu.o
 obj-$(CONFIG_MESON_EE_POWER_DOMAIN) += meson-ee-pwrc.o
+obj-$(CONFIG_MESON_SECURE_POWER_DOMAIN) += meson-secure-pwrc.o
 obj-$(CONFIG_SANDBOX_POWER_DOMAIN) += sandbox-power-domain.o
 obj-$(CONFIG_SANDBOX_POWER_DOMAIN) += sandbox-power-domain-test.o
 obj-$(CONFIG_TEGRA186_POWER_DOMAIN) += tegra186-power-domain.o
diff --git a/drivers/power/domain/meson-secure-pwrc.c 
b/drivers/power/domain/meson-secure-pwrc.c
new file mode 100644
index 000..f70f8e02423
--- /dev/null
+++ b/drivers/power/domain/meson-secure-pwrc.c
@@ -0,0 +1,160 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (c) 2023 SberDevices, Inc.
+ * Author: Alexey Romanov 
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+
+struct meson_secure_pwrc_domain_desc {
+   char *name;
+   size_t index;
+};
+
+struct meson_secure_pwrc_domain_data {
+   unsigned int count;
+   struct meson_secure_pwrc_domain_desc *domains;
+};
+
+struct meson_secure_pwrc_priv {
+   const struct meson_secure_pwrc_domain_data *data;
+};
+
+static int meson_secure_pwrc_on(struct power_domain *power_domain)
+{
+   struct meson_secure_pwrc_priv *priv = dev_get_priv(power_domain->dev);
+   struct meson_secure_pwrc_domain_desc *pwrc_domain;
+   int err;
+
+   pwrc_domain = &priv->data->domains[power_domain->id];
+
+   err = meson_sm_pwrdm_on(pwrc_domain->index);
+   if (err) {
+   pr_err("meson_sm_pwrdm_on() failed (%d)\n", err);
+   return err;
+   }
+
+   pr_debug("enable %s power domain\n", pwrc_domain->name);
+
+   return 0;
+}
+
+static int meson_secure_pwrc_off(struct power_domain *power_domain)
+{
+   struct meson_secure_pwrc_priv *priv = dev_get_priv(power_domain->dev);
+   struct meson_secure_pwrc_domain_desc *pwrc_domain;
+   int err;
+
+   pwrc_domain = &priv->data->domains[power_domain->id];
+
+   err = meson_sm_pwrdm_off(pwrc_domain->index);
+   if (err) {
+   pr_err("meson_sm_pwrdm_off() failed (%d)\n", err);
+   return err;
+   }
+
+   pr_debug("disable %s power domain\n", pwrc_domain->name);
+
+   return 0;
+}
+
+static int meson_secure_pwrc_of_xlate(struct power_domain *power_domain,
+ struct ofnode_phandle_args *args)
+{
+   struct meson_secure_pwrc_priv *priv = dev_get_priv(power_domain->dev);
+   struct meson_secure_pwrc_domain_desc *pwrc_domain;
+
+   if (args->args_count < 1) {
+   pr_err("invalid args count: %d\n", args->args_count);
+   return -EINVAL;
+   }
+
+   power_domain->id = args->args[0];
+
+   if (power_domain->id >= priv->data->count) {
+   pr_err("domain with ID=%lu is invalid\n", power_domain->id);
+   return -EINVAL;
+   }
+
+   pwrc_domain = &priv->data->domains[power_domain->id];
+
+   if (!pwrc_domain->name) {
+   pr_err("domain with ID=%lu is invalid\n", power_domain->id);
+   return -EINVAL;
+   }
+
+   return 0;
+}
+
+#define SEC_PD(__name) \
+[PWRC_##__name##_ID] = \
+{  \
+   .name = #__name,\
+   .index = PWRC_##__name##_ID,\
+}
+
+static struct meson_secure