[9610] drivers: soc: cal-if: Apply CAL_IF for SHUB
authorByoung Kim <eric.by.kim@samsung.com>
Fri, 20 Apr 2018 13:42:44 +0000 (22:42 +0900)
committerTaekki Kim <taekki.kim@samsung.com>
Tue, 26 Jun 2018 03:51:23 +0000 (12:51 +0900)
Change-Id: I58b627cb61aaf9832031e2d0b9e35a267c74cc75
Signed-off-by: Byoung Kim <eric.by.kim@samsung.com>
Signed-off-by: Sukwon Ryoo <sw.ryoo@samsung.com>
drivers/soc/samsung/Kconfig
drivers/soc/samsung/cal-if/Makefile
drivers/soc/samsung/cal-if/cal-if.c
drivers/soc/samsung/cal-if/exynos8895/pmucal_p2vmap_exynos8895.h
drivers/soc/samsung/cal-if/exynos9610/cal_data.c
drivers/soc/samsung/cal-if/exynos9610/pmucal_shub_exynos9610.h [new file with mode: 0644]
drivers/soc/samsung/cal-if/pmucal_rae.c
drivers/soc/samsung/cal-if/pmucal_rae.h
drivers/soc/samsung/cal-if/pmucal_shub.c [new file with mode: 0644]
drivers/soc/samsung/cal-if/pmucal_shub.h [new file with mode: 0644]

index a0e504d13e0160c2a6e7dff4bc8e265c0dd82c70..836c2b85b941961a64d69a49abefc05533007498 100644 (file)
@@ -77,6 +77,12 @@ config EXYNOS_MODE_CHANGER
                Enable EXYNOS MODE CHANGER for Exynos SoC.
                This module controls number of online cpu.
 
+config SHUB_PMUCAL
+       bool "Exynos PMU(for SHUB) Chip Abstraction Layer"
+       depends on CAL_IF
+       help
+         Support SHUB_PMUCAL for Exynos SoC.
+
 config EXYNOS_PMU
        bool "Exynos Power Management Unit Driver Support"
        depends on ARCH_EXYNOS
index b7e9cf86a42024267f34689b517ccd7de10cf006..00944ace1b772acd0193edf80792dd7b884e4c0a 100644 (file)
@@ -9,6 +9,7 @@ obj-$(CONFIG_PMUCAL)                    += pmucal_system.o pmucal_local.o pmucal_cpu.o pmucal_rae
 obj-$(CONFIG_FLEXPMU)                  += pmucal_powermode.o
 obj-$(CONFIG_CP_PMUCAL)                += pmucal_cp.o
 obj-$(CONFIG_GNSS_PMUCAL)              += pmucal_gnss.o
+obj-$(CONFIG_SHUB_PMUCAL)              += pmucal_shub.o
 obj-$(CONFIG_CMUCAL)                   += cmucal.o ra.o vclk.o pll_spec.o
 obj-$(CONFIG_CMUCAL_DEBUG)             += cmucal-debug.o
 obj-$(CONFIG_ACPM_DVFS)                        += acpm_dvfs.o fvmap.o
index 8560a1889f6f7623425143231eb2cb92d1b40bbb..1ed72a00842e44ab75bb1ac380d5de026b4d7b8e 100644 (file)
@@ -16,6 +16,7 @@
 #include "pmucal_cpu.h"
 #include "pmucal_cp.h"
 #include "pmucal_gnss.h"
+#include "pmucal_shub.h"
 #include "pmucal_rae.h"
 #ifdef CONFIG_FLEXPMU
 #include "pmucal_powermode.h"
@@ -478,6 +479,13 @@ int __init cal_if_init(void *dev)
        ret = pmucal_gnss_initialize();
        if (ret < 0)
                return ret;
+#endif
+
+#ifdef CONFIG_SHUB_PMUCAL
+       ret = pmucal_shub_initialize();
+       if (ret < 0)
+               return ret;
+
 #endif
        exynos_acpm_set_device(dev);
 
index 252413bc76c6471ab27666ab493092e471bca559..4c7b70544c75d0f634356f78cd47c89f096fa28d 100644 (file)
@@ -48,6 +48,7 @@ struct p2v_map pmucal_p2v_list[] = {
        DEFINE_PHY(0x13420000),
        DEFINE_PHY(0x11020000),
        DEFINE_PHY(0x11420000),
+       DEFINE_PHY(0x11860000),
        DEFINE_PHY(0x13A20000),
        DEFINE_PHY(0x13820000),
        DEFINE_PHY(0x15E20000),
index 591f6245c287ed64f9fbfafea14485ebdccd9344..4583115e088d6dd12ab2a6e712b5a985afc3d420 100644 (file)
@@ -6,6 +6,7 @@
 #include "../pmucal_powermode.h"
 #include "../pmucal_cp.h"
 #include "../pmucal_gnss.h"
+#include "../pmucal_shub.h"
 
 #include "pmucal_cpu_exynos9610.h"
 #include "pmucal_local_exynos9610.h"
@@ -13,6 +14,7 @@
 #include "pmucal_system_exynos9610.h"
 #include "pmucal_cp_exynos9610.h"
 #include "pmucal_gnss_exynos9610.h"
+#include "pmucal_shub_exynos9610.h"
 
 #include "cmucal-node.c"
 #include "cmucal-qch.c"
diff --git a/drivers/soc/samsung/cal-if/exynos9610/pmucal_shub_exynos9610.h b/drivers/soc/samsung/cal-if/exynos9610/pmucal_shub_exynos9610.h
new file mode 100644 (file)
index 0000000..86d7964
--- /dev/null
@@ -0,0 +1,110 @@
+/* individual sequence descriptor for SHUB control - init, reset, release */
+struct pmucal_seq shub_init[] = {
+       PMUCAL_SEQ_DESC(PMUCAL_WRITE, "QCH_CON_CM4_SHUB_QCH", 0x11000000,
+                       0x3018, (0x7 << 0), (0x4 << 0), 0, 0, 0xffffffff, 0),
+       PMUCAL_SEQ_DESC(PMUCAL_WRITE, "RESET_SUBCPU_SHUB_OPTION", 0x11860000,
+                       0x3D28, (0x1 << 15), (0x1 << 15), 0, 0, 0xffffffff, 0),
+       PMUCAL_SEQ_DESC(PMUCAL_WAIT, "RESET_SU:BCPU_SHUB_STATUS", 0x11860000,
+                       0x3D24, (0x1 << 0), (0x0 << 0), 0x11860000, 0x3D24,
+                       (0x1 << 0), (0x0 << 0)),
+       PMUCAL_SEQ_DESC(PMUCAL_WRITE, "QCH_CON_CM4_SHUB_QCH", 0x11000000,
+                       0x3018, (0x7 << 0), (0x6 << 0), 0, 0, 0xffffffff, 0),
+       PMUCAL_SEQ_DESC(PMUCAL_WRITE, "QCH_CON_CM4_SHUB_QCH", 0x11000000,
+                       0x3018, (0x7 << 0), (0x2 << 0), 0, 0, 0xffffffff, 0),
+};
+
+struct pmucal_seq shub_standbywfi_status[] = {
+       PMUCAL_SEQ_DESC(PMUCAL_READ, "RESET_SUBCPU_SHUB_STATUS", 0x11860000,
+                       0x3D24, (0x1 << 28), 0, 0, 0, 0xffffffff, 0),
+};
+
+struct pmucal_seq shub_reset_assert[] = {
+       PMUCAL_SEQ_DESC(PMUCAL_WRITE, "RESET_SUBCPU_SHUB_CONFIGURATION",
+                       0x11860000, 0x3D20, (0x1 << 0), (0x0 << 0), 0, 0,
+                       0xffffffff, 0),
+       PMUCAL_SEQ_DESC(PMUCAL_WAIT, "RESET_SUBCPU_SHUB_STATUS", 0x11860000,
+                       0x3D24, (0x1 << 0), (0x0 << 0), 0x11860000, 0x3D24,
+                       (0x1 << 0), (0x0 << 0)),
+       PMUCAL_SEQ_DESC(PMUCAL_WRITE, "TOP_BUS_SHUB_OPTION", 0x11860000, 0x2C68,
+                       (0x3 << 0), (0x3 << 0), 0, 0, 0xffffffff, 0),
+       PMUCAL_SEQ_DESC(PMUCAL_WRITE, "TOP_BUS_SHUB_CONFIGURATION", 0x11860000,
+                       0x2C60, (0x7 << 0), (0x6 << 0), 0, 0, 0xffffffff, 0),
+       PMUCAL_SEQ_DESC(PMUCAL_WAIT, "TOP_BUS_SHUB_STATUS", 0x11860000, 0x2C64,
+                       (0x7 << 0), (0x6 << 0), 0x11860000, 0x2C64, (0x7 << 0),
+                       (0x6 << 0)),
+
+       PMUCAL_SEQ_DESC(PMUCAL_WRITE, "TOP_PWR_SHUB_CONFIGURATION", 0x11860000,
+                       0x2CE0, (0x3 << 0), (0x0 << 0), 0, 0, 0xffffffff, 0),
+       PMUCAL_SEQ_DESC(PMUCAL_WAIT, "TOP_PWR_SHUB_STATUS", 0x11860000, 0x2CE4,
+                       (0x3 << 0), (0x0 << 0), 0x11860000, 0x2CE4, (0x3 << 0),
+                       (0x0 << 0)),
+       PMUCAL_SEQ_DESC(PMUCAL_WRITE, "LOGIC_RESET_SHUB_CONFIGURATION",
+                       0x11860000, 0x2D80, (0x3 << 0), (0x0 << 0), 0, 0,
+                       0xffffffff, 0),
+       PMUCAL_SEQ_DESC(PMUCAL_WAIT, "LOGIC_RESET_SHUB_STATUS", 0x11860000,
+                       0x2D84, (0x3 << 0), (0x0 << 0), 0x11860000, 0x2D64,
+                       (0x3 << 0), (0x0 << 0)),
+
+       PMUCAL_SEQ_DESC(PMUCAL_WRITE, "RESET_CMU_SHUB_CONFIGURATION",
+                       0x11860000, 0x2A60, (0x3 << 0), (0x0 << 0), 0, 0,
+                       0xffffffff, 0),
+       PMUCAL_SEQ_DESC(PMUCAL_WAIT, "RESET_CMU_SHUB_STATUS", 0x11860000,
+                       0x2A64, (0x3 << 0), (0x0 << 0), 0x11860000, 0x2A64,
+                       (0x3 << 0), (0x0 << 0)),
+       PMUCAL_SEQ_DESC(PMUCAL_WRITE, "TOP_BUS_SHUB_CONFIGURATION", 0x11860000,
+                       0x2C60, (0x7 << 0), (0x0 << 0), 0, 0, 0xffffffff, 0),
+       PMUCAL_SEQ_DESC(PMUCAL_WAIT, "TOP_BUS_SHUB_STATUS", 0x11860000, 0x2C64,
+                       (0x7 << 0), (0x0 << 0), 0x11860000, 0x2C64, (0x7 << 0),
+                       (0x0 << 0)),
+       PMUCAL_SEQ_DESC(PMUCAL_WRITE, "TOP_BUS_SHUB_OPTION", 0x11860000, 0x2C68,
+                       (0x3 << 0), (0x0 << 0), 0, 0, 0xffffffff, 0),
+};
+
+struct pmucal_seq shub_reset_release_config[] = {
+       PMUCAL_SEQ_DESC(PMUCAL_WRITE, "RESET_CMU_SHUB_CONFIGURATION",
+                       0x11860000, 0x2A60, (0x3 << 0), (0x3 << 0), 0, 0,
+                       0xffffffff, 0),
+       PMUCAL_SEQ_DESC(PMUCAL_WAIT, "RESET_CMU_SHUB_STATUS", 0x11860000,
+                       0x2A64, (0x3 << 0), (0x3 << 0), 0x11860000, 0x2A64,
+                       (0x3 << 0), (0x3 << 0)),
+       PMUCAL_SEQ_DESC(PMUCAL_WRITE, "LOGIC_RESET_SHUB_CONFIGURATION",
+                       0x11860000, 0x2D80, (0x3 << 0), (0x3 << 0), 0, 0,
+                       0xffffffff, 0),
+       PMUCAL_SEQ_DESC(PMUCAL_WAIT, "LOGIC_RESET_SHUB_STATUS", 0x11860000,
+                       0x2D84, (0x3 << 0), (0x3 << 0), 0x11860000, 0x2D84,
+                       (0x3 << 0), (0x3 << 0)),
+
+       PMUCAL_SEQ_DESC(PMUCAL_WRITE, "TOP_PWR_SHUB_CONFIGURATION", 0x11860000,
+                       0x2CE0, (0x3 << 0), (0x3 << 0), 0, 0, 0xffffffff, 0),
+       PMUCAL_SEQ_DESC(PMUCAL_WAIT, "TOP_PWR_SHUB_STATUS", 0x11860000, 0x2CE4,
+                       (0x3 << 0), (0x3 << 0), 0x11860000, 0x2CE4, (0x3 << 0),
+                       (0x3 << 0)),
+       PMUCAL_SEQ_DESC(PMUCAL_WRITE, "TOP_BUS_SHUB_CONFIGURATION", 0x11860000,
+                       0x2C60, (0x7 << 0), (0x7 << 0), 0, 0, 0xffffffff, 0),
+       PMUCAL_SEQ_DESC(PMUCAL_WAIT, "TOP_BUS_SHUB_STATUS", 0x11860000, 0x2C64,
+                       (0x7 << 0), (0x7 << 0), 0x11860000, 0x2C64, (0x7 << 0),
+                       (0x7 << 0)),
+};
+
+struct pmucal_seq shub_reset_release[] = {
+       PMUCAL_SEQ_DESC(PMUCAL_WRITE, "RESET_SUBCPU_SHUB_CONFIGURATION",
+                       0x11860000, 0x3D20, (0x1 << 0), (0x1 << 0), 0, 0,
+                       0xffffffff, 0),
+       PMUCAL_SEQ_DESC(PMUCAL_READ, "RESET_SUBCPU_SHUB_STATUS", 0x11860000,
+                       0x3D24, (0xF << 0), (0xF << 0), 0, 0, 0xffffffff, 0)
+};
+
+struct pmucal_shub pmucal_shub_list = {
+       .init = shub_init,
+       .status = shub_standbywfi_status,
+       .reset_assert = shub_reset_assert,
+       .reset_release_config = shub_reset_release_config,
+       .reset_release = shub_reset_release,
+       .num_init = ARRAY_SIZE(shub_init),
+       .num_status = ARRAY_SIZE(shub_standbywfi_status),
+       .num_reset_assert = ARRAY_SIZE(shub_reset_assert),
+       .num_reset_release_config = ARRAY_SIZE(shub_reset_release_config),
+       .num_reset_release = ARRAY_SIZE(shub_reset_release),
+};
+
+unsigned int pmucal_shub_list_size = 1;
index 51f757c0c108098e4e7fa8def587c9019c7692e3..9156e05796be6686fe1886e54d41ce3dde0a2899 100644 (file)
@@ -82,6 +82,7 @@ static inline bool pmucal_rae_check_value(struct pmucal_seq *seq)
        reg = __raw_readl(seq->base_va + seq->offset);
 #endif
        reg &= seq->mask;
+
        if (reg == seq->value)
                return true;
        else
@@ -100,12 +101,11 @@ static int pmucal_rae_wait(struct pmucal_seq *seq)
                if (timeout > 1000) {
                        u32 reg;
                        reg = __raw_readl(seq->base_va + seq->offset);
-                       pr_err("%s %s:timed out during wait. (value:0x%x, seq_idx = %d)\n",
-                                               PMUCAL_PREFIX, __func__, reg, pmucal_rae_seq_idx);
+                       pr_err("%s %s:timed out during wait. (value:0x%x,intended: 0x%x, seq_idx = %d)\n",
+                                               PMUCAL_PREFIX, __func__, reg, seq->value, pmucal_rae_seq_idx);
                        return -ETIMEDOUT;
                }
        }
-
        return 0;
 }
 
@@ -405,6 +405,74 @@ int pmucal_rae_handle_gnss_seq(struct pmucal_seq *seq, unsigned int seq_size)
 }
 #endif
 
+/**
+ *  pmucal_rae_handle_shub_seq - handles a sequence array based on each element's access_type.
+ *                         exposed to PMUCAL common logics.
+ *
+ *  @seq: Sequence array to be handled.
+ *  @seq_size: Array size of seq.
+ *
+ *  Returns 0 on success. Otherwise, negative error code.
+ */
+
+#ifdef CONFIG_SHUB_PMUCAL
+static unsigned int pmucal_rae_shub_seq_idx;
+
+int pmucal_rae_handle_shub_seq(struct pmucal_seq *seq, unsigned int seq_size)
+{
+       int ret, i;
+       u32 reg;
+
+       for (i = 0; i < seq_size; i++) {
+               pmucal_rae_shub_seq_idx = i;
+               pr_info("%s: shub reset sequence %d pa: 0x%llx / va: 0x%llx\n",
+                       __func__, i,
+                       (unsigned long long int)seq[i].base_pa + seq[i].offset,
+                       (unsigned long long int)seq[i].base_va + seq[i].offset);
+               switch (seq[i].access_type) {
+               case PMUCAL_READ:
+                       pmucal_rae_read(&seq[i]);
+                       pr_info("%s%s  %s = 0x%08x\n", PMUCAL_PREFIX, "raw_read", seq[i].sfr_name,
+                                       __raw_readl(seq[i].base_va + seq[i].offset));
+                       break;
+               case PMUCAL_WRITE:
+                       reg = __raw_readl(seq[i].base_va + seq[i].offset);
+                       reg = (reg & ~seq[i].mask) | seq[i].value;
+                       pr_info("%s%s  %s = 0x%08x\n", PMUCAL_PREFIX,
+                               "raw_write      ", seq[i].sfr_name, reg);
+                       pmucal_rae_write(&seq[i]);
+                       pr_info("%s%s  %s = 0x%08x\n", PMUCAL_PREFIX, "raw_read(check)",
+                               seq[i].sfr_name, __raw_readl(seq[i].base_va + seq[i].offset));
+                       break;
+               case PMUCAL_COND_READ:
+                       if (pmucal_rae_check_condition(&seq[i]))
+                               pmucal_rae_read(&seq[i]);
+                       break;
+               case PMUCAL_COND_WRITE:
+                       if (pmucal_rae_check_condition(&seq[i]))
+                               pmucal_rae_write(&seq[i]);
+                       break;
+               case PMUCAL_WAIT:
+                       ret = pmucal_rae_wait(&seq[i]);
+                       if (ret)
+                               return ret;
+                       pr_info("%s%s\t%s = 0x%08x\n", PMUCAL_PREFIX, "raw_read(wait)",
+                               seq[i].sfr_name,
+                               __raw_readl(seq[i].base_va + seq[i].offset) & seq[i].mask);
+                       break;
+               case PMUCAL_DELAY:
+                       udelay(seq[i].value);
+                       break;
+               default:
+                       pr_err("%s %s:invalid PMUCAL access type\n", PMUCAL_PREFIX, __func__);
+                       return -EINVAL;
+               }
+       }
+
+       return 0;
+}
+#endif
+
 /**
  *  pmucal_rae_init - Init function of PMUCAL Register Access Engine.
  *                   exposed to PWRCAL interface.
index a5fa7a221664d9c4be428d98b7c3ffa6657faaf8..9f6dc75f618a1a88b667184c96265426744d8909 100644 (file)
@@ -18,6 +18,7 @@ extern int pmucal_rae_init(void);
 extern int pmucal_rae_handle_seq(struct pmucal_seq *seq, unsigned int seq_size);
 extern int pmucal_rae_handle_cp_seq(struct pmucal_seq *seq, unsigned int seq_size);
 extern int pmucal_rae_handle_gnss_seq(struct pmucal_seq *seq, unsigned int seq_size);
+extern int pmucal_rae_handle_shub_seq(struct pmucal_seq *seq, unsigned int seq_size);
 extern void pmucal_rae_save_seq(struct pmucal_seq *seq, unsigned int seq_size);
 extern int pmucal_rae_restore_seq(struct pmucal_seq *seq, unsigned int seq_size);
 extern int pmucal_rae_phy2virt(struct pmucal_seq *seq, unsigned int seq_size);
diff --git a/drivers/soc/samsung/cal-if/pmucal_shub.c b/drivers/soc/samsung/cal-if/pmucal_shub.c
new file mode 100644 (file)
index 0000000..88a9ef4
--- /dev/null
@@ -0,0 +1,213 @@
+#include "pmucal_shub.h"
+#include "pmucal_rae.h"
+
+/**
+ *  pmucal_shub_init - init shub.
+ *                     exposed to PWRCAL interface.
+
+ *  Returns 0 on success. Otherwise, negative error code.
+ */
+int pmucal_shub_init(void)
+{
+       pr_info("%s%s()\n", PMUCAL_PREFIX, __func__);
+
+       return 0;
+}
+
+/**
+ *  pmucal_shub_standbywfi_status - get shub standbywfi status.
+ *                     exposed to PWRCAL interface.
+
+ *  Returns 1 when the shub is in wfi, 0 when not.
+ *  Otherwise, negative error code.
+ */
+int pmucal_shub_standbywfi_status(void)
+{
+       pr_info("%s%s()\n", PMUCAL_PREFIX, __func__);
+
+       if (!pmucal_shub_list.status) {
+               pr_err("%s there is no sequence element for shub-status.\n",
+                               PMUCAL_PREFIX);
+               return -ENOENT;
+       }
+
+       pmucal_rae_handle_shub_seq(pmucal_shub_list.status,
+                               pmucal_shub_list.num_status);
+
+       pr_err("shub_status: 0x%X\n", pmucal_shub_list.status->value);
+
+       if (pmucal_shub_list.status->value == 0x1)
+               return 1;
+       else
+               return 0;
+}
+
+/**
+ *  pmucal_shub_reset_assert - reset assert shub.
+ *                     exposed to PWRCAL interface.
+ *
+ *  Returns 0 on success. Otherwise, negative error code.
+ */
+int pmucal_shub_reset_assert(void)
+{
+       int ret;
+
+       if (!pmucal_shub_list.reset_assert) {
+               pr_err("%s there is no sequence element for shub-reset_assert.\n",
+                               PMUCAL_PREFIX);
+               return -ENOENT;
+       }
+
+       ret = pmucal_rae_handle_shub_seq(pmucal_shub_list.reset_assert,
+                               pmucal_shub_list.num_reset_assert);
+       if (ret) {
+               pr_err("%s %s: error on handling shub-reset_assert sequence.\n",
+                               PMUCAL_PREFIX, __func__);
+               return ret;
+       }
+
+       return 0;
+}
+
+/**
+ *  pmucal_shub_reset_release_config - reset_release_config shub except SHUB CPU reset
+ *                     exposed to PWRCAL interface.
+ *
+ *  Returns 0 on success. Otherwise, negative error code.
+ */
+int pmucal_shub_reset_release_config(void)
+{
+       int ret;
+
+       if (!pmucal_shub_list.reset_release_config) {
+               pr_err("%s there is no sequence element for shub-reset_release_config.\n",
+                               PMUCAL_PREFIX);
+               return -ENOENT;
+       }
+
+       ret = pmucal_rae_handle_shub_seq(pmucal_shub_list.reset_release_config,
+                               pmucal_shub_list.num_reset_release_config);
+       if (ret) {
+               pr_err("%s %s: error on handling shub-reset_release_config sequence.\n",
+                               PMUCAL_PREFIX, __func__);
+               return ret;
+       }
+       return 0;
+}
+int pmucal_shub_reset_release(void)
+{
+       int ret;
+
+       if (!pmucal_shub_list.reset_release) {
+               pr_err("%s there is no sequence element for shub-reset_release.\n",
+                               PMUCAL_PREFIX);
+               return -ENOENT;
+       }
+
+       ret = pmucal_rae_handle_shub_seq(pmucal_shub_list.reset_release,
+                               pmucal_shub_list.num_reset_release);
+       if (ret) {
+               pr_err("%s %s: error on handling shub-reset_release sequence.\n",
+                               PMUCAL_PREFIX, __func__);
+               return ret;
+       }
+
+       return 0;
+
+}
+int pmucal_is_shub_regs(int reg)
+{
+       int i;
+       int is_shub_regs = 0;
+
+       for (i = 0; i < pmucal_shub_list.num_init; i++) {
+               if (reg == pmucal_shub_list.init[i].base_pa + pmucal_shub_list.init[i].offset) {
+                       is_shub_regs = 1;
+                       goto out;
+               }
+       }
+
+       for (i = 0; i < pmucal_shub_list.num_reset_assert; i++) {
+               if (reg == pmucal_shub_list.reset_assert[i].base_pa + pmucal_shub_list.reset_assert[i].offset) {
+                       is_shub_regs = 1;
+                       goto out;
+               }
+       }
+
+       for (i = 0; i < pmucal_shub_list.num_reset_release; i++) {
+               if (reg == pmucal_shub_list.reset_release[i].base_pa + pmucal_shub_list.reset_release[i].offset) {
+                       is_shub_regs = 1;
+                       goto out;
+               }
+       }
+
+out:
+       return is_shub_regs;
+}
+
+/**
+ *  pmucal_cp_initialize - Initialize function of PMUCAL SHUB common logic.
+ *                         exposed to PWRCAL interface.
+ *
+ *  Returns 0 on success. Otherwise, negative error code.
+ */
+int __init pmucal_shub_initialize(void)
+{
+       int ret = 0;
+
+       pr_info("%s%s()\n", PMUCAL_PREFIX, __func__);
+
+       if (!pmucal_shub_list_size) {
+               pr_err("%s %s: there is no shub list. aborting init...\n",
+                               PMUCAL_PREFIX, __func__);
+               return -ENOENT;
+       }
+
+       /* convert physical base address to virtual addr */
+       ret = pmucal_rae_phy2virt(pmucal_shub_list.init,
+                               pmucal_shub_list.num_init);
+       if (ret) {
+               pr_err("%s %s: error on PA2VA conversion. aborting init...\n",
+                               PMUCAL_PREFIX, __func__);
+               goto out;
+       }
+
+       ret = pmucal_rae_phy2virt(pmucal_shub_list.status,
+                               pmucal_shub_list.num_status);
+       if (ret) {
+               pr_err("%s %s: error on PA2VA conversion. aborting status...\n",
+                               PMUCAL_PREFIX, __func__);
+               goto out;
+       }
+
+       ret = pmucal_rae_phy2virt(pmucal_shub_list.reset_assert,
+                               pmucal_shub_list.num_reset_assert);
+
+//investigating virtual address of assrtion
+
+       pr_info("%s %p\n", PMUCAL_PREFIX, pmucal_shub_list.reset_assert[0].base_va);
+
+       if (ret) {
+               pr_err("%s %s: error on PA2VA conversion. aborting reset_assert...\n",
+                               PMUCAL_PREFIX, __func__);
+               goto out;
+       }
+
+       ret = pmucal_rae_phy2virt(pmucal_shub_list.reset_release_config,
+                               pmucal_shub_list.num_reset_release_config);
+       if (ret) {
+               pr_err("%s %s: error on PA2VA conversion. aborting reset_release_config...\n",
+                               PMUCAL_PREFIX, __func__);
+               goto out;
+       }
+
+       ret = pmucal_rae_phy2virt(pmucal_shub_list.reset_release,
+                               pmucal_shub_list.num_reset_release);
+       if (ret) {
+               pr_err("%s %s: error on PA2VA conversion. aborting reset_release...\n",
+                               PMUCAL_PREFIX, __func__);
+               goto out;
+       }
+out:
+       return ret;
+}
diff --git a/drivers/soc/samsung/cal-if/pmucal_shub.h b/drivers/soc/samsung/cal-if/pmucal_shub.h
new file mode 100644 (file)
index 0000000..ec3e277
--- /dev/null
@@ -0,0 +1,27 @@
+#ifndef __PMUCAL_SHUB_H__
+#define __PMUCAL_SHUB_H__
+#include "pmucal_common.h"
+
+struct pmucal_shub {
+       struct pmucal_seq *init;
+       struct pmucal_seq *status;
+       struct pmucal_seq *reset_assert;
+       struct pmucal_seq *reset_release_config;
+       struct pmucal_seq *reset_release;
+       u32 num_init;
+       u32 num_status;
+       u32 num_reset_assert;
+       u32 num_reset_release_config;
+       u32 num_reset_release;
+};
+
+/* APIs to be supported to PWRCAL interface */
+extern int pmucal_shub_initialize(void);
+extern int pmucal_shub_init(void);
+extern int pmucal_shub_status(void);
+extern int pmucal_shub_reset_assert(void);
+extern int pmucal_shub_reset_release_config(void);
+extern int pmucal_shub_reset_release(void);
+extern struct pmucal_shub pmucal_shub_list;
+extern unsigned int pmucal_shub_list_size;
+#endif