aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/soc
diff options
context:
space:
mode:
authorPankaj Dubey <pankaj.dubey@samsung.com>2015-12-17 22:32:16 -0500
committerKrzysztof Kozlowski <k.kozlowski@samsung.com>2016-02-24 20:18:07 -0500
commitbfce552d0b10e8fd79e703c67c084b4cf89ad68a (patch)
tree1918e8bcbbb0b960f985aca484e64f203c463796 /drivers/soc
parent92c4bf04735130023188995cb5dbc21fdedda88c (diff)
drivers: soc: Add support for Exynos PMU driver
This patch moves Exynos PMU driver implementation from "arm/mach-exynos" to "drivers/soc/samsung". This driver is mainly used for setting misc bits of register from PMU IP of Exynos SoC which will be required to configure before Suspend/Resume. Currently all these settings are done in "arch/arm/mach-exynos/pmu.c" but moving ahead for ARM64 based SoC support, there is a need of this PMU driver in driver/* folder. This driver uses existing DT binding information and there should be no functionality change in the supported platforms. Signed-off-by: Amit Daniel Kachhap <amitdanielk@gmail.com> [tested on Peach-Pi (Exynos5880)] Signed-off-by: Pankaj Dubey <pankaj.dubey@samsung.com> Reviewed-by: Krzysztof Kozlowski <k.kozlowski@samsung.com> [for testing on Trats2 (Exynos4412) and Odroid XU3 (Exynos5422)] Tested-by: Krzysztof Kozlowski <k.kozlowski@samsung.com> [k.kozlowski: Rebased, add necessary infrastructure for building and selecting drivers/soc because original patchset was on top of movement SROMc to drivers/soc] Signed-off-by: Krzysztof Kozlowski <k.kozlowski@samsung.com>
Diffstat (limited to 'drivers/soc')
-rw-r--r--drivers/soc/Kconfig1
-rw-r--r--drivers/soc/Makefile1
-rw-r--r--drivers/soc/samsung/Kconfig13
-rw-r--r--drivers/soc/samsung/Makefile2
-rw-r--r--drivers/soc/samsung/exynos-pmu.c141
-rw-r--r--drivers/soc/samsung/exynos-pmu.h44
-rw-r--r--drivers/soc/samsung/exynos3250-pmu.c175
-rw-r--r--drivers/soc/samsung/exynos4-pmu.c222
-rw-r--r--drivers/soc/samsung/exynos5250-pmu.c195
-rw-r--r--drivers/soc/samsung/exynos5420-pmu.c280
10 files changed, 1074 insertions, 0 deletions
diff --git a/drivers/soc/Kconfig b/drivers/soc/Kconfig
index 88260205a261..cb58ef0d9b2c 100644
--- a/drivers/soc/Kconfig
+++ b/drivers/soc/Kconfig
@@ -6,6 +6,7 @@ source "drivers/soc/fsl/qe/Kconfig"
6source "drivers/soc/mediatek/Kconfig" 6source "drivers/soc/mediatek/Kconfig"
7source "drivers/soc/qcom/Kconfig" 7source "drivers/soc/qcom/Kconfig"
8source "drivers/soc/rockchip/Kconfig" 8source "drivers/soc/rockchip/Kconfig"
9source "drivers/soc/samsung/Kconfig"
9source "drivers/soc/sunxi/Kconfig" 10source "drivers/soc/sunxi/Kconfig"
10source "drivers/soc/tegra/Kconfig" 11source "drivers/soc/tegra/Kconfig"
11source "drivers/soc/ti/Kconfig" 12source "drivers/soc/ti/Kconfig"
diff --git a/drivers/soc/Makefile b/drivers/soc/Makefile
index 2afdc74f7491..5ade71306ee1 100644
--- a/drivers/soc/Makefile
+++ b/drivers/soc/Makefile
@@ -10,6 +10,7 @@ obj-y += fsl/
10obj-$(CONFIG_ARCH_MEDIATEK) += mediatek/ 10obj-$(CONFIG_ARCH_MEDIATEK) += mediatek/
11obj-$(CONFIG_ARCH_QCOM) += qcom/ 11obj-$(CONFIG_ARCH_QCOM) += qcom/
12obj-$(CONFIG_ARCH_ROCKCHIP) += rockchip/ 12obj-$(CONFIG_ARCH_ROCKCHIP) += rockchip/
13obj-$(CONFIG_SOC_SAMSUNG) += samsung/
13obj-$(CONFIG_ARCH_SUNXI) += sunxi/ 14obj-$(CONFIG_ARCH_SUNXI) += sunxi/
14obj-$(CONFIG_ARCH_TEGRA) += tegra/ 15obj-$(CONFIG_ARCH_TEGRA) += tegra/
15obj-$(CONFIG_SOC_TI) += ti/ 16obj-$(CONFIG_SOC_TI) += ti/
diff --git a/drivers/soc/samsung/Kconfig b/drivers/soc/samsung/Kconfig
new file mode 100644
index 000000000000..2dff95dc697d
--- /dev/null
+++ b/drivers/soc/samsung/Kconfig
@@ -0,0 +1,13 @@
1#
2# SAMSUNG SoC drivers
3#
4menu "Samsung SOC driver support"
5
6config SOC_SAMSUNG
7 bool
8
9config EXYNOS_PMU
10 bool
11 depends on ARM && ARCH_EXYNOS
12
13endmenu
diff --git a/drivers/soc/samsung/Makefile b/drivers/soc/samsung/Makefile
new file mode 100644
index 000000000000..f64ac4d80564
--- /dev/null
+++ b/drivers/soc/samsung/Makefile
@@ -0,0 +1,2 @@
1obj-$(CONFIG_EXYNOS_PMU) += exynos-pmu.o exynos3250-pmu.o exynos4-pmu.o \
2 exynos5250-pmu.o exynos5420-pmu.o
diff --git a/drivers/soc/samsung/exynos-pmu.c b/drivers/soc/samsung/exynos-pmu.c
new file mode 100644
index 000000000000..0acdfd82e751
--- /dev/null
+++ b/drivers/soc/samsung/exynos-pmu.c
@@ -0,0 +1,141 @@
1/*
2 * Copyright (c) 2011-2014 Samsung Electronics Co., Ltd.
3 * http://www.samsung.com/
4 *
5 * EXYNOS - CPU PMU(Power Management Unit) support
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 */
11
12#include <linux/of.h>
13#include <linux/of_address.h>
14#include <linux/platform_device.h>
15#include <linux/delay.h>
16
17#include <linux/soc/samsung/exynos-regs-pmu.h>
18#include <linux/soc/samsung/exynos-pmu.h>
19
20#include "exynos-pmu.h"
21
22struct exynos_pmu_context {
23 struct device *dev;
24 const struct exynos_pmu_data *pmu_data;
25};
26
27void __iomem *pmu_base_addr;
28static struct exynos_pmu_context *pmu_context;
29
30void pmu_raw_writel(u32 val, u32 offset)
31{
32 writel_relaxed(val, pmu_base_addr + offset);
33}
34
35u32 pmu_raw_readl(u32 offset)
36{
37 return readl_relaxed(pmu_base_addr + offset);
38}
39
40void exynos_sys_powerdown_conf(enum sys_powerdown mode)
41{
42 unsigned int i;
43 const struct exynos_pmu_data *pmu_data;
44
45 if (!pmu_context)
46 return;
47
48 pmu_data = pmu_context->pmu_data;
49
50 if (pmu_data->powerdown_conf)
51 pmu_data->powerdown_conf(mode);
52
53 if (pmu_data->pmu_config) {
54 for (i = 0; (pmu_data->pmu_config[i].offset != PMU_TABLE_END); i++)
55 pmu_raw_writel(pmu_data->pmu_config[i].val[mode],
56 pmu_data->pmu_config[i].offset);
57 }
58
59 if (pmu_data->powerdown_conf_extra)
60 pmu_data->powerdown_conf_extra(mode);
61
62 if (pmu_data->pmu_config_extra) {
63 for (i = 0; pmu_data->pmu_config_extra[i].offset != PMU_TABLE_END; i++)
64 pmu_raw_writel(pmu_data->pmu_config_extra[i].val[mode],
65 pmu_data->pmu_config_extra[i].offset);
66 }
67}
68
69/*
70 * PMU platform driver and devicetree bindings.
71 */
72static const struct of_device_id exynos_pmu_of_device_ids[] = {
73 {
74 .compatible = "samsung,exynos3250-pmu",
75 .data = &exynos3250_pmu_data,
76 }, {
77 .compatible = "samsung,exynos4210-pmu",
78 .data = &exynos4210_pmu_data,
79 }, {
80 .compatible = "samsung,exynos4212-pmu",
81 .data = &exynos4212_pmu_data,
82 }, {
83 .compatible = "samsung,exynos4412-pmu",
84 .data = &exynos4412_pmu_data,
85 }, {
86 .compatible = "samsung,exynos5250-pmu",
87 .data = &exynos5250_pmu_data,
88 }, {
89 .compatible = "samsung,exynos5420-pmu",
90 .data = &exynos5420_pmu_data,
91 },
92 { /*sentinel*/ },
93};
94
95static int exynos_pmu_probe(struct platform_device *pdev)
96{
97 const struct of_device_id *match;
98 struct device *dev = &pdev->dev;
99 struct resource *res;
100
101 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
102 pmu_base_addr = devm_ioremap_resource(dev, res);
103 if (IS_ERR(pmu_base_addr))
104 return PTR_ERR(pmu_base_addr);
105
106 pmu_context = devm_kzalloc(&pdev->dev,
107 sizeof(struct exynos_pmu_context),
108 GFP_KERNEL);
109 if (!pmu_context) {
110 dev_err(dev, "Cannot allocate memory.\n");
111 return -ENOMEM;
112 }
113 pmu_context->dev = dev;
114
115 match = of_match_node(exynos_pmu_of_device_ids, dev->of_node);
116
117 pmu_context->pmu_data = match->data;
118
119 if (pmu_context->pmu_data->pmu_init)
120 pmu_context->pmu_data->pmu_init();
121
122 platform_set_drvdata(pdev, pmu_context);
123
124 dev_dbg(dev, "Exynos PMU Driver probe done\n");
125 return 0;
126}
127
128static struct platform_driver exynos_pmu_driver = {
129 .driver = {
130 .name = "exynos-pmu",
131 .of_match_table = exynos_pmu_of_device_ids,
132 },
133 .probe = exynos_pmu_probe,
134};
135
136static int __init exynos_pmu_init(void)
137{
138 return platform_driver_register(&exynos_pmu_driver);
139
140}
141postcore_initcall(exynos_pmu_init);
diff --git a/drivers/soc/samsung/exynos-pmu.h b/drivers/soc/samsung/exynos-pmu.h
new file mode 100644
index 000000000000..a469e366fead
--- /dev/null
+++ b/drivers/soc/samsung/exynos-pmu.h
@@ -0,0 +1,44 @@
1/*
2 * Copyright (c) 2015 Samsung Electronics Co., Ltd.
3 * http://www.samsung.com
4 *
5 * Header for EXYNOS PMU Driver support
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 */
11
12#ifndef __EXYNOS_PMU_H
13#define __EXYNOS_PMU_H
14
15#include <linux/io.h>
16
17#define PMU_TABLE_END (-1U)
18
19struct exynos_pmu_conf {
20 unsigned int offset;
21 u8 val[NUM_SYS_POWERDOWN];
22};
23
24struct exynos_pmu_data {
25 const struct exynos_pmu_conf *pmu_config;
26 const struct exynos_pmu_conf *pmu_config_extra;
27
28 void (*pmu_init)(void);
29 void (*powerdown_conf)(enum sys_powerdown);
30 void (*powerdown_conf_extra)(enum sys_powerdown);
31};
32
33extern void __iomem *pmu_base_addr;
34/* list of all exported SoC specific data */
35extern const struct exynos_pmu_data exynos3250_pmu_data;
36extern const struct exynos_pmu_data exynos4210_pmu_data;
37extern const struct exynos_pmu_data exynos4212_pmu_data;
38extern const struct exynos_pmu_data exynos4412_pmu_data;
39extern const struct exynos_pmu_data exynos5250_pmu_data;
40extern const struct exynos_pmu_data exynos5420_pmu_data;
41
42extern void pmu_raw_writel(u32 val, u32 offset);
43extern u32 pmu_raw_readl(u32 offset);
44#endif /* __EXYNOS_PMU_H */
diff --git a/drivers/soc/samsung/exynos3250-pmu.c b/drivers/soc/samsung/exynos3250-pmu.c
new file mode 100644
index 000000000000..20b3ab8aa790
--- /dev/null
+++ b/drivers/soc/samsung/exynos3250-pmu.c
@@ -0,0 +1,175 @@
1/*
2 * Copyright (c) 2011-2015 Samsung Electronics Co., Ltd.
3 * http://www.samsung.com/
4 *
5 * EXYNOS3250 - CPU PMU (Power Management Unit) support
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 */
11
12#include <linux/soc/samsung/exynos-regs-pmu.h>
13#include <linux/soc/samsung/exynos-pmu.h>
14
15#include "exynos-pmu.h"
16
17static struct exynos_pmu_conf exynos3250_pmu_config[] = {
18 /* { .offset = offset, .val = { AFTR, W-AFTR, SLEEP } */
19 { EXYNOS3_ARM_CORE0_SYS_PWR_REG, { 0x0, 0x0, 0x2} },
20 { EXYNOS3_DIS_IRQ_ARM_CORE0_LOCAL_SYS_PWR_REG, { 0x0, 0x0, 0x0} },
21 { EXYNOS3_DIS_IRQ_ARM_CORE0_CENTRAL_SYS_PWR_REG, { 0x0, 0x0, 0x0} },
22 { EXYNOS3_ARM_CORE1_SYS_PWR_REG, { 0x0, 0x0, 0x2} },
23 { EXYNOS3_DIS_IRQ_ARM_CORE1_LOCAL_SYS_PWR_REG, { 0x0, 0x0, 0x0} },
24 { EXYNOS3_DIS_IRQ_ARM_CORE1_CENTRAL_SYS_PWR_REG, { 0x0, 0x0, 0x0} },
25 { EXYNOS3_ISP_ARM_SYS_PWR_REG, { 0x1, 0x0, 0x0} },
26 { EXYNOS3_DIS_IRQ_ISP_ARM_LOCAL_SYS_PWR_REG, { 0x0, 0x0, 0x0} },
27 { EXYNOS3_DIS_IRQ_ISP_ARM_CENTRAL_SYS_PWR_REG, { 0x0, 0x0, 0x0} },
28 { EXYNOS3_ARM_COMMON_SYS_PWR_REG, { 0x0, 0x0, 0x2} },
29 { EXYNOS3_ARM_L2_SYS_PWR_REG, { 0x0, 0x0, 0x3} },
30 { EXYNOS3_CMU_ACLKSTOP_SYS_PWR_REG, { 0x1, 0x1, 0x0} },
31 { EXYNOS3_CMU_SCLKSTOP_SYS_PWR_REG, { 0x1, 0x1, 0x0} },
32 { EXYNOS3_CMU_RESET_SYS_PWR_REG, { 0x1, 0x1, 0x0} },
33 { EXYNOS3_DRAM_FREQ_DOWN_SYS_PWR_REG, { 0x1, 0x1, 0x1} },
34 { EXYNOS3_DDRPHY_DLLOFF_SYS_PWR_REG, { 0x1, 0x1, 0x1} },
35 { EXYNOS3_LPDDR_PHY_DLL_LOCK_SYS_PWR_REG, { 0x1, 0x1, 0x1} },
36 { EXYNOS3_CMU_ACLKSTOP_COREBLK_SYS_PWR_REG, { 0x1, 0x0, 0x0} },
37 { EXYNOS3_CMU_SCLKSTOP_COREBLK_SYS_PWR_REG, { 0x1, 0x0, 0x0} },
38 { EXYNOS3_CMU_RESET_COREBLK_SYS_PWR_REG, { 0x1, 0x1, 0x0} },
39 { EXYNOS3_APLL_SYSCLK_SYS_PWR_REG, { 0x1, 0x0, 0x0} },
40 { EXYNOS3_MPLL_SYSCLK_SYS_PWR_REG, { 0x1, 0x0, 0x0} },
41 { EXYNOS3_BPLL_SYSCLK_SYS_PWR_REG, { 0x1, 0x0, 0x0} },
42 { EXYNOS3_VPLL_SYSCLK_SYS_PWR_REG, { 0x1, 0x1, 0x0} },
43 { EXYNOS3_EPLL_SYSCLK_SYS_PWR_REG, { 0x1, 0x0, 0x0} },
44 { EXYNOS3_UPLL_SYSCLK_SYS_PWR_REG, { 0x1, 0x1, 0x1} },
45 { EXYNOS3_EPLLUSER_SYSCLK_SYS_PWR_REG, { 0x1, 0x0, 0x0} },
46 { EXYNOS3_MPLLUSER_SYSCLK_SYS_PWR_REG, { 0x1, 0x0, 0x0} },
47 { EXYNOS3_BPLLUSER_SYSCLK_SYS_PWR_REG, { 0x1, 0x0, 0x0} },
48 { EXYNOS3_CMU_CLKSTOP_CAM_SYS_PWR_REG, { 0x1, 0x0, 0x0} },
49 { EXYNOS3_CMU_CLKSTOP_MFC_SYS_PWR_REG, { 0x1, 0x0, 0x0} },
50 { EXYNOS3_CMU_CLKSTOP_G3D_SYS_PWR_REG, { 0x1, 0x0, 0x0} },
51 { EXYNOS3_CMU_CLKSTOP_LCD0_SYS_PWR_REG, { 0x1, 0x0, 0x0} },
52 { EXYNOS3_CMU_CLKSTOP_ISP_SYS_PWR_REG, { 0x1, 0x0, 0x0} },
53 { EXYNOS3_CMU_CLKSTOP_MAUDIO_SYS_PWR_REG, { 0x1, 0x0, 0x0} },
54 { EXYNOS3_CMU_RESET_CAM_SYS_PWR_REG, { 0x1, 0x0, 0x0} },
55 { EXYNOS3_CMU_RESET_MFC_SYS_PWR_REG, { 0x1, 0x0, 0x0} },
56 { EXYNOS3_CMU_RESET_G3D_SYS_PWR_REG, { 0x1, 0x0, 0x0} },
57 { EXYNOS3_CMU_RESET_LCD0_SYS_PWR_REG, { 0x1, 0x0, 0x0} },
58 { EXYNOS3_CMU_RESET_ISP_SYS_PWR_REG, { 0x1, 0x0, 0x0} },
59 { EXYNOS3_CMU_RESET_MAUDIO_SYS_PWR_REG, { 0x1, 0x0, 0x0} },
60 { EXYNOS3_TOP_BUS_SYS_PWR_REG, { 0x3, 0x0, 0x0} },
61 { EXYNOS3_TOP_RETENTION_SYS_PWR_REG, { 0x1, 0x1, 0x1} },
62 { EXYNOS3_TOP_PWR_SYS_PWR_REG, { 0x3, 0x3, 0x3} },
63 { EXYNOS3_TOP_BUS_COREBLK_SYS_PWR_REG, { 0x3, 0x0, 0x0} },
64 { EXYNOS3_TOP_RETENTION_COREBLK_SYS_PWR_REG, { 0x1, 0x1, 0x1} },
65 { EXYNOS3_TOP_PWR_COREBLK_SYS_PWR_REG, { 0x3, 0x3, 0x3} },
66 { EXYNOS3_LOGIC_RESET_SYS_PWR_REG, { 0x1, 0x1, 0x0} },
67 { EXYNOS3_OSCCLK_GATE_SYS_PWR_REG, { 0x1, 0x1, 0x1} },
68 { EXYNOS3_LOGIC_RESET_COREBLK_SYS_PWR_REG, { 0x1, 0x1, 0x0} },
69 { EXYNOS3_OSCCLK_GATE_COREBLK_SYS_PWR_REG, { 0x1, 0x0, 0x1} },
70 { EXYNOS3_PAD_RETENTION_DRAM_SYS_PWR_REG, { 0x1, 0x1, 0x0} },
71 { EXYNOS3_PAD_RETENTION_MAUDIO_SYS_PWR_REG, { 0x1, 0x1, 0x0} },
72 { EXYNOS3_PAD_RETENTION_GPIO_SYS_PWR_REG, { 0x1, 0x1, 0x0} },
73 { EXYNOS3_PAD_RETENTION_UART_SYS_PWR_REG, { 0x1, 0x1, 0x0} },
74 { EXYNOS3_PAD_RETENTION_MMC0_SYS_PWR_REG, { 0x1, 0x1, 0x0} },
75 { EXYNOS3_PAD_RETENTION_MMC1_SYS_PWR_REG, { 0x1, 0x1, 0x0} },
76 { EXYNOS3_PAD_RETENTION_MMC2_SYS_PWR_REG, { 0x1, 0x1, 0x0} },
77 { EXYNOS3_PAD_RETENTION_SPI_SYS_PWR_REG, { 0x1, 0x1, 0x0} },
78 { EXYNOS3_PAD_RETENTION_EBIA_SYS_PWR_REG, { 0x1, 0x1, 0x0} },
79 { EXYNOS3_PAD_RETENTION_EBIB_SYS_PWR_REG, { 0x1, 0x1, 0x0} },
80 { EXYNOS3_PAD_RETENTION_JTAG_SYS_PWR_REG, { 0x1, 0x1, 0x0} },
81 { EXYNOS3_PAD_ISOLATION_SYS_PWR_REG, { 0x1, 0x1, 0x0} },
82 { EXYNOS3_PAD_ALV_SEL_SYS_PWR_REG, { 0x1, 0x1, 0x0} },
83 { EXYNOS3_XUSBXTI_SYS_PWR_REG, { 0x1, 0x1, 0x0} },
84 { EXYNOS3_XXTI_SYS_PWR_REG, { 0x1, 0x1, 0x0} },
85 { EXYNOS3_EXT_REGULATOR_SYS_PWR_REG, { 0x1, 0x1, 0x0} },
86 { EXYNOS3_EXT_REGULATOR_COREBLK_SYS_PWR_REG, { 0x1, 0x1, 0x0} },
87 { EXYNOS3_GPIO_MODE_SYS_PWR_REG, { 0x1, 0x1, 0x0} },
88 { EXYNOS3_GPIO_MODE_MAUDIO_SYS_PWR_REG, { 0x1, 0x1, 0x0} },
89 { EXYNOS3_TOP_ASB_RESET_SYS_PWR_REG, { 0x1, 0x1, 0x0} },
90 { EXYNOS3_TOP_ASB_ISOLATION_SYS_PWR_REG, { 0x1, 0x1, 0x0} },
91 { EXYNOS3_TOP_ASB_RESET_COREBLK_SYS_PWR_REG, { 0x1, 0x1, 0x0} },
92 { EXYNOS3_TOP_ASB_ISOLATION_COREBLK_SYS_PWR_REG, { 0x1, 0x1, 0x0} },
93 { EXYNOS3_CAM_SYS_PWR_REG, { 0x7, 0x0, 0x0} },
94 { EXYNOS3_MFC_SYS_PWR_REG, { 0x7, 0x0, 0x0} },
95 { EXYNOS3_G3D_SYS_PWR_REG, { 0x7, 0x0, 0x0} },
96 { EXYNOS3_LCD0_SYS_PWR_REG, { 0x7, 0x0, 0x0} },
97 { EXYNOS3_ISP_SYS_PWR_REG, { 0x7, 0x0, 0x0} },
98 { EXYNOS3_MAUDIO_SYS_PWR_REG, { 0x7, 0x0, 0x0} },
99 { EXYNOS3_CMU_SYSCLK_ISP_SYS_PWR_REG, { 0x1, 0x0, 0x0} },
100 { PMU_TABLE_END,},
101};
102
103static unsigned int const exynos3250_list_feed[] = {
104 EXYNOS3_ARM_CORE_OPTION(0),
105 EXYNOS3_ARM_CORE_OPTION(1),
106 EXYNOS3_ARM_CORE_OPTION(2),
107 EXYNOS3_ARM_CORE_OPTION(3),
108 EXYNOS3_ARM_COMMON_OPTION,
109 EXYNOS3_TOP_PWR_OPTION,
110 EXYNOS3_CORE_TOP_PWR_OPTION,
111 S5P_CAM_OPTION,
112 S5P_MFC_OPTION,
113 S5P_G3D_OPTION,
114 S5P_LCD0_OPTION,
115 S5P_ISP_OPTION,
116};
117
118static void exynos3250_powerdown_conf_extra(enum sys_powerdown mode)
119{
120 unsigned int i;
121 unsigned int tmp;
122
123 /* Enable only SC_FEEDBACK */
124 for (i = 0; i < ARRAY_SIZE(exynos3250_list_feed); i++) {
125 tmp = pmu_raw_readl(exynos3250_list_feed[i]);
126 tmp &= ~(EXYNOS3_OPTION_USE_SC_COUNTER);
127 tmp |= EXYNOS3_OPTION_USE_SC_FEEDBACK;
128 pmu_raw_writel(tmp, exynos3250_list_feed[i]);
129 }
130
131 if (mode != SYS_SLEEP)
132 return;
133
134 pmu_raw_writel(XUSBXTI_DURATION, EXYNOS3_XUSBXTI_DURATION);
135 pmu_raw_writel(XXTI_DURATION, EXYNOS3_XXTI_DURATION);
136 pmu_raw_writel(EXT_REGULATOR_DURATION, EXYNOS3_EXT_REGULATOR_DURATION);
137 pmu_raw_writel(EXT_REGULATOR_COREBLK_DURATION,
138 EXYNOS3_EXT_REGULATOR_COREBLK_DURATION);
139}
140
141static void exynos3250_pmu_init(void)
142{
143 unsigned int value;
144
145 /*
146 * To prevent from issuing new bus request form L2 memory system
147 * If core status is power down, should be set '1' to L2 power down
148 */
149 value = pmu_raw_readl(EXYNOS3_ARM_COMMON_OPTION);
150 value |= EXYNOS3_OPTION_SKIP_DEACTIVATE_ACEACP_IN_PWDN;
151 pmu_raw_writel(value, EXYNOS3_ARM_COMMON_OPTION);
152
153 /* Enable USE_STANDBY_WFI for all CORE */
154 pmu_raw_writel(S5P_USE_STANDBY_WFI_ALL, S5P_CENTRAL_SEQ_OPTION);
155
156 /*
157 * Set PSHOLD port for output high
158 */
159 value = pmu_raw_readl(S5P_PS_HOLD_CONTROL);
160 value |= S5P_PS_HOLD_OUTPUT_HIGH;
161 pmu_raw_writel(value, S5P_PS_HOLD_CONTROL);
162
163 /*
164 * Enable signal for PSHOLD port
165 */
166 value = pmu_raw_readl(S5P_PS_HOLD_CONTROL);
167 value |= S5P_PS_HOLD_EN;
168 pmu_raw_writel(value, S5P_PS_HOLD_CONTROL);
169}
170
171const struct exynos_pmu_data exynos3250_pmu_data = {
172 .pmu_config = exynos3250_pmu_config,
173 .pmu_init = exynos3250_pmu_init,
174 .powerdown_conf_extra = exynos3250_powerdown_conf_extra,
175};
diff --git a/drivers/soc/samsung/exynos4-pmu.c b/drivers/soc/samsung/exynos4-pmu.c
new file mode 100644
index 000000000000..bc4fa73bed11
--- /dev/null
+++ b/drivers/soc/samsung/exynos4-pmu.c
@@ -0,0 +1,222 @@
1/*
2 * Copyright (c) 2011-2015 Samsung Electronics Co., Ltd.
3 * http://www.samsung.com/
4 *
5 * EXYNOS4 - CPU PMU(Power Management Unit) support
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 */
11
12#include <linux/soc/samsung/exynos-regs-pmu.h>
13#include <linux/soc/samsung/exynos-pmu.h>
14
15#include "exynos-pmu.h"
16
17static const struct exynos_pmu_conf exynos4210_pmu_config[] = {
18 /* { .offset = offset, .val = { AFTR, LPA, SLEEP } */
19 { S5P_ARM_CORE0_LOWPWR, { 0x0, 0x0, 0x2 } },
20 { S5P_DIS_IRQ_CORE0, { 0x0, 0x0, 0x0 } },
21 { S5P_DIS_IRQ_CENTRAL0, { 0x0, 0x0, 0x0 } },
22 { S5P_ARM_CORE1_LOWPWR, { 0x0, 0x0, 0x2 } },
23 { S5P_DIS_IRQ_CORE1, { 0x0, 0x0, 0x0 } },
24 { S5P_DIS_IRQ_CENTRAL1, { 0x0, 0x0, 0x0 } },
25 { S5P_ARM_COMMON_LOWPWR, { 0x0, 0x0, 0x2 } },
26 { S5P_L2_0_LOWPWR, { 0x2, 0x2, 0x3 } },
27 { S5P_L2_1_LOWPWR, { 0x2, 0x2, 0x3 } },
28 { S5P_CMU_ACLKSTOP_LOWPWR, { 0x1, 0x0, 0x0 } },
29 { S5P_CMU_SCLKSTOP_LOWPWR, { 0x1, 0x0, 0x0 } },
30 { S5P_CMU_RESET_LOWPWR, { 0x1, 0x1, 0x0 } },
31 { S5P_APLL_SYSCLK_LOWPWR, { 0x1, 0x0, 0x0 } },
32 { S5P_MPLL_SYSCLK_LOWPWR, { 0x1, 0x0, 0x0 } },
33 { S5P_VPLL_SYSCLK_LOWPWR, { 0x1, 0x0, 0x0 } },
34 { S5P_EPLL_SYSCLK_LOWPWR, { 0x1, 0x1, 0x0 } },
35 { S5P_CMU_CLKSTOP_GPS_ALIVE_LOWPWR, { 0x1, 0x1, 0x0 } },
36 { S5P_CMU_RESET_GPSALIVE_LOWPWR, { 0x1, 0x1, 0x0 } },
37 { S5P_CMU_CLKSTOP_CAM_LOWPWR, { 0x1, 0x1, 0x0 } },
38 { S5P_CMU_CLKSTOP_TV_LOWPWR, { 0x1, 0x1, 0x0 } },
39 { S5P_CMU_CLKSTOP_MFC_LOWPWR, { 0x1, 0x1, 0x0 } },
40 { S5P_CMU_CLKSTOP_G3D_LOWPWR, { 0x1, 0x1, 0x0 } },
41 { S5P_CMU_CLKSTOP_LCD0_LOWPWR, { 0x1, 0x1, 0x0 } },
42 { S5P_CMU_CLKSTOP_LCD1_LOWPWR, { 0x1, 0x1, 0x0 } },
43 { S5P_CMU_CLKSTOP_MAUDIO_LOWPWR, { 0x1, 0x1, 0x0 } },
44 { S5P_CMU_CLKSTOP_GPS_LOWPWR, { 0x1, 0x1, 0x0 } },
45 { S5P_CMU_RESET_CAM_LOWPWR, { 0x1, 0x1, 0x0 } },
46 { S5P_CMU_RESET_TV_LOWPWR, { 0x1, 0x1, 0x0 } },
47 { S5P_CMU_RESET_MFC_LOWPWR, { 0x1, 0x1, 0x0 } },
48 { S5P_CMU_RESET_G3D_LOWPWR, { 0x1, 0x1, 0x0 } },
49 { S5P_CMU_RESET_LCD0_LOWPWR, { 0x1, 0x1, 0x0 } },
50 { S5P_CMU_RESET_LCD1_LOWPWR, { 0x1, 0x1, 0x0 } },
51 { S5P_CMU_RESET_MAUDIO_LOWPWR, { 0x1, 0x1, 0x0 } },
52 { S5P_CMU_RESET_GPS_LOWPWR, { 0x1, 0x1, 0x0 } },
53 { S5P_TOP_BUS_LOWPWR, { 0x3, 0x0, 0x0 } },
54 { S5P_TOP_RETENTION_LOWPWR, { 0x1, 0x0, 0x1 } },
55 { S5P_TOP_PWR_LOWPWR, { 0x3, 0x0, 0x3 } },
56 { S5P_LOGIC_RESET_LOWPWR, { 0x1, 0x1, 0x0 } },
57 { S5P_ONENAND_MEM_LOWPWR, { 0x3, 0x0, 0x0 } },
58 { S5P_MODIMIF_MEM_LOWPWR, { 0x3, 0x0, 0x0 } },
59 { S5P_G2D_ACP_MEM_LOWPWR, { 0x3, 0x0, 0x0 } },
60 { S5P_USBOTG_MEM_LOWPWR, { 0x3, 0x0, 0x0 } },
61 { S5P_HSMMC_MEM_LOWPWR, { 0x3, 0x0, 0x0 } },
62 { S5P_CSSYS_MEM_LOWPWR, { 0x3, 0x0, 0x0 } },
63 { S5P_SECSS_MEM_LOWPWR, { 0x3, 0x0, 0x0 } },
64 { S5P_PCIE_MEM_LOWPWR, { 0x3, 0x0, 0x0 } },
65 { S5P_SATA_MEM_LOWPWR, { 0x3, 0x0, 0x0 } },
66 { S5P_PAD_RETENTION_DRAM_LOWPWR, { 0x1, 0x0, 0x0 } },
67 { S5P_PAD_RETENTION_MAUDIO_LOWPWR, { 0x1, 0x1, 0x0 } },
68 { S5P_PAD_RETENTION_GPIO_LOWPWR, { 0x1, 0x0, 0x0 } },
69 { S5P_PAD_RETENTION_UART_LOWPWR, { 0x1, 0x0, 0x0 } },
70 { S5P_PAD_RETENTION_MMCA_LOWPWR, { 0x1, 0x0, 0x0 } },
71 { S5P_PAD_RETENTION_MMCB_LOWPWR, { 0x1, 0x0, 0x0 } },
72 { S5P_PAD_RETENTION_EBIA_LOWPWR, { 0x1, 0x0, 0x0 } },
73 { S5P_PAD_RETENTION_EBIB_LOWPWR, { 0x1, 0x0, 0x0 } },
74 { S5P_PAD_RETENTION_ISOLATION_LOWPWR, { 0x1, 0x0, 0x0 } },
75 { S5P_PAD_RETENTION_ALV_SEL_LOWPWR, { 0x1, 0x0, 0x0 } },
76 { S5P_XUSBXTI_LOWPWR, { 0x1, 0x1, 0x0 } },
77 { S5P_XXTI_LOWPWR, { 0x1, 0x1, 0x0 } },
78 { S5P_EXT_REGULATOR_LOWPWR, { 0x1, 0x1, 0x0 } },
79 { S5P_GPIO_MODE_LOWPWR, { 0x1, 0x0, 0x0 } },
80 { S5P_GPIO_MODE_MAUDIO_LOWPWR, { 0x1, 0x1, 0x0 } },
81 { S5P_CAM_LOWPWR, { 0x7, 0x0, 0x0 } },
82 { S5P_TV_LOWPWR, { 0x7, 0x0, 0x0 } },
83 { S5P_MFC_LOWPWR, { 0x7, 0x0, 0x0 } },
84 { S5P_G3D_LOWPWR, { 0x7, 0x0, 0x0 } },
85 { S5P_LCD0_LOWPWR, { 0x7, 0x0, 0x0 } },
86 { S5P_LCD1_LOWPWR, { 0x7, 0x0, 0x0 } },
87 { S5P_MAUDIO_LOWPWR, { 0x7, 0x7, 0x0 } },
88 { S5P_GPS_LOWPWR, { 0x7, 0x0, 0x0 } },
89 { S5P_GPS_ALIVE_LOWPWR, { 0x7, 0x0, 0x0 } },
90 { PMU_TABLE_END,},
91};
92
93static const struct exynos_pmu_conf exynos4x12_pmu_config[] = {
94 { S5P_ARM_CORE0_LOWPWR, { 0x0, 0x0, 0x2 } },
95 { S5P_DIS_IRQ_CORE0, { 0x0, 0x0, 0x0 } },
96 { S5P_DIS_IRQ_CENTRAL0, { 0x0, 0x0, 0x0 } },
97 { S5P_ARM_CORE1_LOWPWR, { 0x0, 0x0, 0x2 } },
98 { S5P_DIS_IRQ_CORE1, { 0x0, 0x0, 0x0 } },
99 { S5P_DIS_IRQ_CENTRAL1, { 0x0, 0x0, 0x0 } },
100 { S5P_ISP_ARM_LOWPWR, { 0x1, 0x0, 0x0 } },
101 { S5P_DIS_IRQ_ISP_ARM_LOCAL_LOWPWR, { 0x0, 0x0, 0x0 } },
102 { S5P_DIS_IRQ_ISP_ARM_CENTRAL_LOWPWR, { 0x0, 0x0, 0x0 } },
103 { S5P_ARM_COMMON_LOWPWR, { 0x0, 0x0, 0x2 } },
104 { S5P_L2_0_LOWPWR, { 0x0, 0x0, 0x3 } },
105 /* XXX_OPTION register should be set other field */
106 { S5P_ARM_L2_0_OPTION, { 0x10, 0x10, 0x0 } },
107 { S5P_L2_1_LOWPWR, { 0x0, 0x0, 0x3 } },
108 { S5P_ARM_L2_1_OPTION, { 0x10, 0x10, 0x0 } },
109 { S5P_CMU_ACLKSTOP_LOWPWR, { 0x1, 0x0, 0x0 } },
110 { S5P_CMU_SCLKSTOP_LOWPWR, { 0x1, 0x0, 0x0 } },
111 { S5P_CMU_RESET_LOWPWR, { 0x1, 0x1, 0x0 } },
112 { S5P_DRAM_FREQ_DOWN_LOWPWR, { 0x1, 0x1, 0x1 } },
113 { S5P_DDRPHY_DLLOFF_LOWPWR, { 0x1, 0x1, 0x1 } },
114 { S5P_LPDDR_PHY_DLL_LOCK_LOWPWR, { 0x1, 0x1, 0x1 } },
115 { S5P_CMU_ACLKSTOP_COREBLK_LOWPWR, { 0x1, 0x0, 0x0 } },
116 { S5P_CMU_SCLKSTOP_COREBLK_LOWPWR, { 0x1, 0x0, 0x0 } },
117 { S5P_CMU_RESET_COREBLK_LOWPWR, { 0x1, 0x1, 0x0 } },
118 { S5P_APLL_SYSCLK_LOWPWR, { 0x1, 0x0, 0x0 } },
119 { S5P_MPLL_SYSCLK_LOWPWR, { 0x1, 0x0, 0x0 } },
120 { S5P_VPLL_SYSCLK_LOWPWR, { 0x1, 0x0, 0x0 } },
121 { S5P_EPLL_SYSCLK_LOWPWR, { 0x1, 0x1, 0x0 } },
122 { S5P_MPLLUSER_SYSCLK_LOWPWR, { 0x1, 0x0, 0x0 } },
123 { S5P_CMU_CLKSTOP_GPS_ALIVE_LOWPWR, { 0x1, 0x0, 0x0 } },
124 { S5P_CMU_RESET_GPSALIVE_LOWPWR, { 0x1, 0x0, 0x0 } },
125 { S5P_CMU_CLKSTOP_CAM_LOWPWR, { 0x1, 0x0, 0x0 } },
126 { S5P_CMU_CLKSTOP_TV_LOWPWR, { 0x1, 0x0, 0x0 } },
127 { S5P_CMU_CLKSTOP_MFC_LOWPWR, { 0x1, 0x0, 0x0 } },
128 { S5P_CMU_CLKSTOP_G3D_LOWPWR, { 0x1, 0x0, 0x0 } },
129 { S5P_CMU_CLKSTOP_LCD0_LOWPWR, { 0x1, 0x0, 0x0 } },
130 { S5P_CMU_CLKSTOP_ISP_LOWPWR, { 0x1, 0x0, 0x0 } },
131 { S5P_CMU_CLKSTOP_MAUDIO_LOWPWR, { 0x1, 0x0, 0x0 } },
132 { S5P_CMU_CLKSTOP_GPS_LOWPWR, { 0x1, 0x0, 0x0 } },
133 { S5P_CMU_RESET_CAM_LOWPWR, { 0x1, 0x0, 0x0 } },
134 { S5P_CMU_RESET_TV_LOWPWR, { 0x1, 0x0, 0x0 } },
135 { S5P_CMU_RESET_MFC_LOWPWR, { 0x1, 0x0, 0x0 } },
136 { S5P_CMU_RESET_G3D_LOWPWR, { 0x1, 0x0, 0x0 } },
137 { S5P_CMU_RESET_LCD0_LOWPWR, { 0x1, 0x0, 0x0 } },
138 { S5P_CMU_RESET_ISP_LOWPWR, { 0x1, 0x0, 0x0 } },
139 { S5P_CMU_RESET_MAUDIO_LOWPWR, { 0x1, 0x1, 0x0 } },
140 { S5P_CMU_RESET_GPS_LOWPWR, { 0x1, 0x0, 0x0 } },
141 { S5P_TOP_BUS_LOWPWR, { 0x3, 0x0, 0x0 } },
142 { S5P_TOP_RETENTION_LOWPWR, { 0x1, 0x0, 0x1 } },
143 { S5P_TOP_PWR_LOWPWR, { 0x3, 0x0, 0x3 } },
144 { S5P_TOP_BUS_COREBLK_LOWPWR, { 0x3, 0x0, 0x0 } },
145 { S5P_TOP_RETENTION_COREBLK_LOWPWR, { 0x1, 0x0, 0x1 } },
146 { S5P_TOP_PWR_COREBLK_LOWPWR, { 0x3, 0x0, 0x3 } },
147 { S5P_LOGIC_RESET_LOWPWR, { 0x1, 0x1, 0x0 } },
148 { S5P_OSCCLK_GATE_LOWPWR, { 0x1, 0x0, 0x1 } },
149 { S5P_LOGIC_RESET_COREBLK_LOWPWR, { 0x1, 0x1, 0x0 } },
150 { S5P_OSCCLK_GATE_COREBLK_LOWPWR, { 0x1, 0x0, 0x1 } },
151 { S5P_ONENAND_MEM_LOWPWR, { 0x3, 0x0, 0x0 } },
152 { S5P_ONENAND_MEM_OPTION, { 0x10, 0x10, 0x0 } },
153 { S5P_HSI_MEM_LOWPWR, { 0x3, 0x0, 0x0 } },
154 { S5P_HSI_MEM_OPTION, { 0x10, 0x10, 0x0 } },
155 { S5P_G2D_ACP_MEM_LOWPWR, { 0x3, 0x0, 0x0 } },
156 { S5P_G2D_ACP_MEM_OPTION, { 0x10, 0x10, 0x0 } },
157 { S5P_USBOTG_MEM_LOWPWR, { 0x3, 0x0, 0x0 } },
158 { S5P_USBOTG_MEM_OPTION, { 0x10, 0x10, 0x0 } },
159 { S5P_HSMMC_MEM_LOWPWR, { 0x3, 0x0, 0x0 } },
160 { S5P_HSMMC_MEM_OPTION, { 0x10, 0x10, 0x0 } },
161 { S5P_CSSYS_MEM_LOWPWR, { 0x3, 0x0, 0x0 } },
162 { S5P_CSSYS_MEM_OPTION, { 0x10, 0x10, 0x0 } },
163 { S5P_SECSS_MEM_LOWPWR, { 0x3, 0x0, 0x0 } },
164 { S5P_SECSS_MEM_OPTION, { 0x10, 0x10, 0x0 } },
165 { S5P_ROTATOR_MEM_LOWPWR, { 0x3, 0x0, 0x0 } },
166 { S5P_ROTATOR_MEM_OPTION, { 0x10, 0x10, 0x0 } },
167 { S5P_PAD_RETENTION_DRAM_LOWPWR, { 0x1, 0x0, 0x0 } },
168 { S5P_PAD_RETENTION_MAUDIO_LOWPWR, { 0x1, 0x1, 0x0 } },
169 { S5P_PAD_RETENTION_GPIO_LOWPWR, { 0x1, 0x0, 0x0 } },
170 { S5P_PAD_RETENTION_UART_LOWPWR, { 0x1, 0x0, 0x0 } },
171 { S5P_PAD_RETENTION_MMCA_LOWPWR, { 0x1, 0x0, 0x0 } },
172 { S5P_PAD_RETENTION_MMCB_LOWPWR, { 0x1, 0x0, 0x0 } },
173 { S5P_PAD_RETENTION_EBIA_LOWPWR, { 0x1, 0x0, 0x0 } },
174 { S5P_PAD_RETENTION_EBIB_LOWPWR, { 0x1, 0x0, 0x0 } },
175 { S5P_PAD_RETENTION_GPIO_COREBLK_LOWPWR, { 0x1, 0x0, 0x0 } },
176 { S5P_PAD_RETENTION_ISOLATION_LOWPWR, { 0x1, 0x0, 0x0 } },
177 { S5P_PAD_ISOLATION_COREBLK_LOWPWR, { 0x1, 0x0, 0x0 } },
178 { S5P_PAD_RETENTION_ALV_SEL_LOWPWR, { 0x1, 0x0, 0x0 } },
179 { S5P_XUSBXTI_LOWPWR, { 0x1, 0x1, 0x0 } },
180 { S5P_XXTI_LOWPWR, { 0x1, 0x1, 0x0 } },
181 { S5P_EXT_REGULATOR_LOWPWR, { 0x1, 0x1, 0x0 } },
182 { S5P_GPIO_MODE_LOWPWR, { 0x1, 0x0, 0x0 } },
183 { S5P_GPIO_MODE_COREBLK_LOWPWR, { 0x1, 0x0, 0x0 } },
184 { S5P_GPIO_MODE_MAUDIO_LOWPWR, { 0x1, 0x1, 0x0 } },
185 { S5P_TOP_ASB_RESET_LOWPWR, { 0x1, 0x1, 0x1 } },
186 { S5P_TOP_ASB_ISOLATION_LOWPWR, { 0x1, 0x0, 0x1 } },
187 { S5P_CAM_LOWPWR, { 0x7, 0x0, 0x0 } },
188 { S5P_TV_LOWPWR, { 0x7, 0x0, 0x0 } },
189 { S5P_MFC_LOWPWR, { 0x7, 0x0, 0x0 } },
190 { S5P_G3D_LOWPWR, { 0x7, 0x0, 0x0 } },
191 { S5P_LCD0_LOWPWR, { 0x7, 0x0, 0x0 } },
192 { S5P_ISP_LOWPWR, { 0x7, 0x0, 0x0 } },
193 { S5P_MAUDIO_LOWPWR, { 0x7, 0x7, 0x0 } },
194 { S5P_GPS_LOWPWR, { 0x7, 0x0, 0x0 } },
195 { S5P_GPS_ALIVE_LOWPWR, { 0x7, 0x0, 0x0 } },
196 { S5P_CMU_SYSCLK_ISP_LOWPWR, { 0x1, 0x0, 0x0 } },
197 { S5P_CMU_SYSCLK_GPS_LOWPWR, { 0x1, 0x0, 0x0 } },
198 { PMU_TABLE_END,},
199};
200
201static const struct exynos_pmu_conf exynos4412_pmu_config[] = {
202 { S5P_ARM_CORE2_LOWPWR, { 0x0, 0x0, 0x2 } },
203 { S5P_DIS_IRQ_CORE2, { 0x0, 0x0, 0x0 } },
204 { S5P_DIS_IRQ_CENTRAL2, { 0x0, 0x0, 0x0 } },
205 { S5P_ARM_CORE3_LOWPWR, { 0x0, 0x0, 0x2 } },
206 { S5P_DIS_IRQ_CORE3, { 0x0, 0x0, 0x0 } },
207 { S5P_DIS_IRQ_CENTRAL3, { 0x0, 0x0, 0x0 } },
208 { PMU_TABLE_END,},
209};
210
211const struct exynos_pmu_data exynos4210_pmu_data = {
212 .pmu_config = exynos4210_pmu_config,
213};
214
215const struct exynos_pmu_data exynos4212_pmu_data = {
216 .pmu_config = exynos4x12_pmu_config,
217};
218
219const struct exynos_pmu_data exynos4412_pmu_data = {
220 .pmu_config = exynos4x12_pmu_config,
221 .pmu_config_extra = exynos4412_pmu_config,
222};
diff --git a/drivers/soc/samsung/exynos5250-pmu.c b/drivers/soc/samsung/exynos5250-pmu.c
new file mode 100644
index 000000000000..3fac42561964
--- /dev/null
+++ b/drivers/soc/samsung/exynos5250-pmu.c
@@ -0,0 +1,195 @@
1/*
2 * Copyright (c) 2011-2015 Samsung Electronics Co., Ltd.
3 * http://www.samsung.com/
4 *
5 * EXYNOS5250 - CPU PMU (Power Management Unit) support
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 */
11
12#include <linux/soc/samsung/exynos-regs-pmu.h>
13#include <linux/soc/samsung/exynos-pmu.h>
14
15#include "exynos-pmu.h"
16
17static const struct exynos_pmu_conf exynos5250_pmu_config[] = {
18 /* { .offset = offset, .val = { AFTR, LPA, SLEEP } */
19 { EXYNOS5_ARM_CORE0_SYS_PWR_REG, { 0x0, 0x0, 0x2} },
20 { EXYNOS5_DIS_IRQ_ARM_CORE0_LOCAL_SYS_PWR_REG, { 0x0, 0x0, 0x0} },
21 { EXYNOS5_DIS_IRQ_ARM_CORE0_CENTRAL_SYS_PWR_REG, { 0x0, 0x0, 0x0} },
22 { EXYNOS5_ARM_CORE1_SYS_PWR_REG, { 0x0, 0x0, 0x2} },
23 { EXYNOS5_DIS_IRQ_ARM_CORE1_LOCAL_SYS_PWR_REG, { 0x0, 0x0, 0x0} },
24 { EXYNOS5_DIS_IRQ_ARM_CORE1_CENTRAL_SYS_PWR_REG, { 0x0, 0x0, 0x0} },
25 { EXYNOS5_FSYS_ARM_SYS_PWR_REG, { 0x1, 0x0, 0x0} },
26 { EXYNOS5_DIS_IRQ_FSYS_ARM_CENTRAL_SYS_PWR_REG, { 0x1, 0x1, 0x1} },
27 { EXYNOS5_ISP_ARM_SYS_PWR_REG, { 0x1, 0x0, 0x0} },
28 { EXYNOS5_DIS_IRQ_ISP_ARM_LOCAL_SYS_PWR_REG, { 0x0, 0x0, 0x0} },
29 { EXYNOS5_DIS_IRQ_ISP_ARM_CENTRAL_SYS_PWR_REG, { 0x0, 0x0, 0x0} },
30 { EXYNOS5_ARM_COMMON_SYS_PWR_REG, { 0x0, 0x0, 0x2} },
31 { EXYNOS5_ARM_L2_SYS_PWR_REG, { 0x3, 0x3, 0x3} },
32 { EXYNOS5_ARM_L2_OPTION, { 0x10, 0x10, 0x0 } },
33 { EXYNOS5_CMU_ACLKSTOP_SYS_PWR_REG, { 0x1, 0x0, 0x1} },
34 { EXYNOS5_CMU_SCLKSTOP_SYS_PWR_REG, { 0x1, 0x0, 0x1} },
35 { EXYNOS5_CMU_RESET_SYS_PWR_REG, { 0x1, 0x1, 0x0} },
36 { EXYNOS5_CMU_ACLKSTOP_SYSMEM_SYS_PWR_REG, { 0x1, 0x0, 0x1} },
37 { EXYNOS5_CMU_SCLKSTOP_SYSMEM_SYS_PWR_REG, { 0x1, 0x0, 0x1} },
38 { EXYNOS5_CMU_RESET_SYSMEM_SYS_PWR_REG, { 0x1, 0x1, 0x0} },
39 { EXYNOS5_DRAM_FREQ_DOWN_SYS_PWR_REG, { 0x1, 0x1, 0x1} },
40 { EXYNOS5_DDRPHY_DLLOFF_SYS_PWR_REG, { 0x1, 0x1, 0x1} },
41 { EXYNOS5_DDRPHY_DLLLOCK_SYS_PWR_REG, { 0x1, 0x1, 0x1} },
42 { EXYNOS5_APLL_SYSCLK_SYS_PWR_REG, { 0x1, 0x0, 0x0} },
43 { EXYNOS5_MPLL_SYSCLK_SYS_PWR_REG, { 0x1, 0x0, 0x0} },
44 { EXYNOS5_VPLL_SYSCLK_SYS_PWR_REG, { 0x1, 0x0, 0x0} },
45 { EXYNOS5_EPLL_SYSCLK_SYS_PWR_REG, { 0x1, 0x1, 0x0} },
46 { EXYNOS5_BPLL_SYSCLK_SYS_PWR_REG, { 0x1, 0x0, 0x0} },
47 { EXYNOS5_CPLL_SYSCLK_SYS_PWR_REG, { 0x1, 0x0, 0x0} },
48 { EXYNOS5_MPLLUSER_SYSCLK_SYS_PWR_REG, { 0x1, 0x0, 0x0} },
49 { EXYNOS5_BPLLUSER_SYSCLK_SYS_PWR_REG, { 0x1, 0x0, 0x0} },
50 { EXYNOS5_TOP_BUS_SYS_PWR_REG, { 0x3, 0x0, 0x0} },
51 { EXYNOS5_TOP_RETENTION_SYS_PWR_REG, { 0x1, 0x0, 0x1} },
52 { EXYNOS5_TOP_PWR_SYS_PWR_REG, { 0x3, 0x0, 0x3} },
53 { EXYNOS5_TOP_BUS_SYSMEM_SYS_PWR_REG, { 0x3, 0x0, 0x0} },
54 { EXYNOS5_TOP_RETENTION_SYSMEM_SYS_PWR_REG, { 0x1, 0x0, 0x1} },
55 { EXYNOS5_TOP_PWR_SYSMEM_SYS_PWR_REG, { 0x3, 0x0, 0x3} },
56 { EXYNOS5_LOGIC_RESET_SYS_PWR_REG, { 0x1, 0x1, 0x0} },
57 { EXYNOS5_OSCCLK_GATE_SYS_PWR_REG, { 0x1, 0x0, 0x1} },
58 { EXYNOS5_LOGIC_RESET_SYSMEM_SYS_PWR_REG, { 0x1, 0x1, 0x0} },
59 { EXYNOS5_OSCCLK_GATE_SYSMEM_SYS_PWR_REG, { 0x1, 0x0, 0x1} },
60 { EXYNOS5_USBOTG_MEM_SYS_PWR_REG, { 0x3, 0x0, 0x0} },
61 { EXYNOS5_G2D_MEM_SYS_PWR_REG, { 0x3, 0x0, 0x0} },
62 { EXYNOS5_USBDRD_MEM_SYS_PWR_REG, { 0x3, 0x0, 0x0} },
63 { EXYNOS5_SDMMC_MEM_SYS_PWR_REG, { 0x3, 0x0, 0x0} },
64 { EXYNOS5_CSSYS_MEM_SYS_PWR_REG, { 0x3, 0x0, 0x0} },
65 { EXYNOS5_SECSS_MEM_SYS_PWR_REG, { 0x3, 0x0, 0x0} },
66 { EXYNOS5_ROTATOR_MEM_SYS_PWR_REG, { 0x3, 0x0, 0x0} },
67 { EXYNOS5_INTRAM_MEM_SYS_PWR_REG, { 0x3, 0x0, 0x0} },
68 { EXYNOS5_INTROM_MEM_SYS_PWR_REG, { 0x3, 0x0, 0x0} },
69 { EXYNOS5_JPEG_MEM_SYS_PWR_REG, { 0x3, 0x0, 0x0} },
70 { EXYNOS5_JPEG_MEM_OPTION, { 0x10, 0x10, 0x0} },
71 { EXYNOS5_HSI_MEM_SYS_PWR_REG, { 0x3, 0x0, 0x0} },
72 { EXYNOS5_MCUIOP_MEM_SYS_PWR_REG, { 0x3, 0x0, 0x0} },
73 { EXYNOS5_SATA_MEM_SYS_PWR_REG, { 0x3, 0x0, 0x0} },
74 { EXYNOS5_PAD_RETENTION_DRAM_SYS_PWR_REG, { 0x1, 0x0, 0x0} },
75 { EXYNOS5_PAD_RETENTION_MAU_SYS_PWR_REG, { 0x1, 0x1, 0x0} },
76 { EXYNOS5_PAD_RETENTION_GPIO_SYS_PWR_REG, { 0x1, 0x0, 0x0} },
77 { EXYNOS5_PAD_RETENTION_UART_SYS_PWR_REG, { 0x1, 0x0, 0x0} },
78 { EXYNOS5_PAD_RETENTION_MMCA_SYS_PWR_REG, { 0x1, 0x0, 0x0} },
79 { EXYNOS5_PAD_RETENTION_MMCB_SYS_PWR_REG, { 0x1, 0x0, 0x0} },
80 { EXYNOS5_PAD_RETENTION_EBIA_SYS_PWR_REG, { 0x1, 0x0, 0x0} },
81 { EXYNOS5_PAD_RETENTION_EBIB_SYS_PWR_REG, { 0x1, 0x0, 0x0} },
82 { EXYNOS5_PAD_RETENTION_SPI_SYS_PWR_REG, { 0x1, 0x0, 0x0} },
83 { EXYNOS5_PAD_RETENTION_GPIO_SYSMEM_SYS_PWR_REG, { 0x1, 0x0, 0x0} },
84 { EXYNOS5_PAD_ISOLATION_SYS_PWR_REG, { 0x1, 0x0, 0x0} },
85 { EXYNOS5_PAD_ISOLATION_SYSMEM_SYS_PWR_REG, { 0x1, 0x0, 0x0} },
86 { EXYNOS5_PAD_ALV_SEL_SYS_PWR_REG, { 0x1, 0x0, 0x0} },
87 { EXYNOS5_XUSBXTI_SYS_PWR_REG, { 0x1, 0x1, 0x1} },
88 { EXYNOS5_XXTI_SYS_PWR_REG, { 0x1, 0x1, 0x0} },
89 { EXYNOS5_EXT_REGULATOR_SYS_PWR_REG, { 0x1, 0x1, 0x0} },
90 { EXYNOS5_GPIO_MODE_SYS_PWR_REG, { 0x1, 0x0, 0x0} },
91 { EXYNOS5_GPIO_MODE_SYSMEM_SYS_PWR_REG, { 0x1, 0x0, 0x0} },
92 { EXYNOS5_GPIO_MODE_MAU_SYS_PWR_REG, { 0x1, 0x1, 0x0} },
93 { EXYNOS5_TOP_ASB_RESET_SYS_PWR_REG, { 0x1, 0x1, 0x1} },
94 { EXYNOS5_TOP_ASB_ISOLATION_SYS_PWR_REG, { 0x1, 0x0, 0x1} },
95 { EXYNOS5_GSCL_SYS_PWR_REG, { 0x7, 0x0, 0x0} },
96 { EXYNOS5_ISP_SYS_PWR_REG, { 0x7, 0x0, 0x0} },
97 { EXYNOS5_MFC_SYS_PWR_REG, { 0x7, 0x0, 0x0} },
98 { EXYNOS5_G3D_SYS_PWR_REG, { 0x7, 0x0, 0x0} },
99 { EXYNOS5_DISP1_SYS_PWR_REG, { 0x7, 0x0, 0x0} },
100 { EXYNOS5_MAU_SYS_PWR_REG, { 0x7, 0x7, 0x0} },
101 { EXYNOS5_CMU_CLKSTOP_GSCL_SYS_PWR_REG, { 0x1, 0x0, 0x0} },
102 { EXYNOS5_CMU_CLKSTOP_ISP_SYS_PWR_REG, { 0x1, 0x0, 0x0} },
103 { EXYNOS5_CMU_CLKSTOP_MFC_SYS_PWR_REG, { 0x1, 0x0, 0x0} },
104 { EXYNOS5_CMU_CLKSTOP_G3D_SYS_PWR_REG, { 0x1, 0x0, 0x0} },
105 { EXYNOS5_CMU_CLKSTOP_DISP1_SYS_PWR_REG, { 0x1, 0x0, 0x0} },
106 { EXYNOS5_CMU_CLKSTOP_MAU_SYS_PWR_REG, { 0x1, 0x1, 0x0} },
107 { EXYNOS5_CMU_SYSCLK_GSCL_SYS_PWR_REG, { 0x1, 0x0, 0x0} },
108 { EXYNOS5_CMU_SYSCLK_ISP_SYS_PWR_REG, { 0x1, 0x0, 0x0} },
109 { EXYNOS5_CMU_SYSCLK_MFC_SYS_PWR_REG, { 0x1, 0x0, 0x0} },
110 { EXYNOS5_CMU_SYSCLK_G3D_SYS_PWR_REG, { 0x1, 0x0, 0x0} },
111 { EXYNOS5_CMU_SYSCLK_DISP1_SYS_PWR_REG, { 0x1, 0x0, 0x0} },
112 { EXYNOS5_CMU_SYSCLK_MAU_SYS_PWR_REG, { 0x1, 0x1, 0x0} },
113 { EXYNOS5_CMU_RESET_GSCL_SYS_PWR_REG, { 0x1, 0x0, 0x0} },
114 { EXYNOS5_CMU_RESET_ISP_SYS_PWR_REG, { 0x1, 0x0, 0x0} },
115 { EXYNOS5_CMU_RESET_MFC_SYS_PWR_REG, { 0x1, 0x0, 0x0} },
116 { EXYNOS5_CMU_RESET_G3D_SYS_PWR_REG, { 0x1, 0x0, 0x0} },
117 { EXYNOS5_CMU_RESET_DISP1_SYS_PWR_REG, { 0x1, 0x0, 0x0} },
118 { EXYNOS5_CMU_RESET_MAU_SYS_PWR_REG, { 0x1, 0x1, 0x0} },
119 { PMU_TABLE_END,},
120};
121
122static unsigned int const exynos5_list_both_cnt_feed[] = {
123 EXYNOS5_ARM_CORE0_OPTION,
124 EXYNOS5_ARM_CORE1_OPTION,
125 EXYNOS5_ARM_COMMON_OPTION,
126 EXYNOS5_GSCL_OPTION,
127 EXYNOS5_ISP_OPTION,
128 EXYNOS5_MFC_OPTION,
129 EXYNOS5_G3D_OPTION,
130 EXYNOS5_DISP1_OPTION,
131 EXYNOS5_MAU_OPTION,
132 EXYNOS5_TOP_PWR_OPTION,
133 EXYNOS5_TOP_PWR_SYSMEM_OPTION,
134};
135
136static unsigned int const exynos5_list_disable_wfi_wfe[] = {
137 EXYNOS5_ARM_CORE1_OPTION,
138 EXYNOS5_FSYS_ARM_OPTION,
139 EXYNOS5_ISP_ARM_OPTION,
140};
141
142static void exynos5250_pmu_init(void)
143{
144 unsigned int value;
145 /*
146 * When SYS_WDTRESET is set, watchdog timer reset request
147 * is ignored by power management unit.
148 */
149 value = pmu_raw_readl(EXYNOS5_AUTO_WDTRESET_DISABLE);
150 value &= ~EXYNOS5_SYS_WDTRESET;
151 pmu_raw_writel(value, EXYNOS5_AUTO_WDTRESET_DISABLE);
152
153 value = pmu_raw_readl(EXYNOS5_MASK_WDTRESET_REQUEST);
154 value &= ~EXYNOS5_SYS_WDTRESET;
155 pmu_raw_writel(value, EXYNOS5_MASK_WDTRESET_REQUEST);
156}
157
158static void exynos5_powerdown_conf(enum sys_powerdown mode)
159{
160 unsigned int i;
161 unsigned int tmp;
162
163 /*
164 * Enable both SC_FEEDBACK and SC_COUNTER
165 */
166 for (i = 0; i < ARRAY_SIZE(exynos5_list_both_cnt_feed); i++) {
167 tmp = pmu_raw_readl(exynos5_list_both_cnt_feed[i]);
168 tmp |= (EXYNOS5_USE_SC_FEEDBACK |
169 EXYNOS5_USE_SC_COUNTER);
170 pmu_raw_writel(tmp, exynos5_list_both_cnt_feed[i]);
171 }
172
173 /*
174 * SKIP_DEACTIVATE_ACEACP_IN_PWDN_BITFIELD Enable
175 */
176 tmp = pmu_raw_readl(EXYNOS5_ARM_COMMON_OPTION);
177 tmp |= EXYNOS5_SKIP_DEACTIVATE_ACEACP_IN_PWDN;
178 pmu_raw_writel(tmp, EXYNOS5_ARM_COMMON_OPTION);
179
180 /*
181 * Disable WFI/WFE on XXX_OPTION
182 */
183 for (i = 0; i < ARRAY_SIZE(exynos5_list_disable_wfi_wfe); i++) {
184 tmp = pmu_raw_readl(exynos5_list_disable_wfi_wfe[i]);
185 tmp &= ~(EXYNOS5_OPTION_USE_STANDBYWFE |
186 EXYNOS5_OPTION_USE_STANDBYWFI);
187 pmu_raw_writel(tmp, exynos5_list_disable_wfi_wfe[i]);
188 }
189}
190
191const struct exynos_pmu_data exynos5250_pmu_data = {
192 .pmu_config = exynos5250_pmu_config,
193 .pmu_init = exynos5250_pmu_init,
194 .powerdown_conf = exynos5_powerdown_conf,
195};
diff --git a/drivers/soc/samsung/exynos5420-pmu.c b/drivers/soc/samsung/exynos5420-pmu.c
new file mode 100644
index 000000000000..b962fb6a5d22
--- /dev/null
+++ b/drivers/soc/samsung/exynos5420-pmu.c
@@ -0,0 +1,280 @@
1/*
2 * Copyright (c) 2011-2015 Samsung Electronics Co., Ltd.
3 * http://www.samsung.com/
4 *
5 * EXYNOS5420 - CPU PMU (Power Management Unit) support
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 */
11
12#include <linux/pm.h>
13#include <linux/soc/samsung/exynos-regs-pmu.h>
14#include <linux/soc/samsung/exynos-pmu.h>
15
16#include <asm/cputype.h>
17
18#include "exynos-pmu.h"
19
20static struct exynos_pmu_conf exynos5420_pmu_config[] = {
21 /* { .offset = offset, .val = { AFTR, LPA, SLEEP } */
22 { EXYNOS5_ARM_CORE0_SYS_PWR_REG, { 0x0, 0x0, 0x0} },
23 { EXYNOS5_DIS_IRQ_ARM_CORE0_LOCAL_SYS_PWR_REG, { 0x0, 0x0, 0x0} },
24 { EXYNOS5_DIS_IRQ_ARM_CORE0_CENTRAL_SYS_PWR_REG, { 0x0, 0x0, 0x0} },
25 { EXYNOS5_ARM_CORE1_SYS_PWR_REG, { 0x0, 0x0, 0x0} },
26 { EXYNOS5_DIS_IRQ_ARM_CORE1_LOCAL_SYS_PWR_REG, { 0x0, 0x0, 0x0} },
27 { EXYNOS5_DIS_IRQ_ARM_CORE1_CENTRAL_SYS_PWR_REG, { 0x0, 0x0, 0x0} },
28 { EXYNOS5420_ARM_CORE2_SYS_PWR_REG, { 0x0, 0x0, 0x0} },
29 { EXYNOS5420_DIS_IRQ_ARM_CORE2_LOCAL_SYS_PWR_REG, { 0x0, 0x0, 0x0} },
30 { EXYNOS5420_DIS_IRQ_ARM_CORE2_CENTRAL_SYS_PWR_REG, { 0x0, 0x0, 0x0} },
31 { EXYNOS5420_ARM_CORE3_SYS_PWR_REG, { 0x0, 0x0, 0x0} },
32 { EXYNOS5420_DIS_IRQ_ARM_CORE3_LOCAL_SYS_PWR_REG, { 0x0, 0x0, 0x0} },
33 { EXYNOS5420_DIS_IRQ_ARM_CORE3_CENTRAL_SYS_PWR_REG, { 0x0, 0x0, 0x0} },
34 { EXYNOS5420_KFC_CORE0_SYS_PWR_REG, { 0x0, 0x0, 0x0} },
35 { EXYNOS5420_DIS_IRQ_KFC_CORE0_LOCAL_SYS_PWR_REG, { 0x0, 0x0, 0x0} },
36 { EXYNOS5420_DIS_IRQ_KFC_CORE0_CENTRAL_SYS_PWR_REG, { 0x0, 0x0, 0x0} },
37 { EXYNOS5420_KFC_CORE1_SYS_PWR_REG, { 0x0, 0x0, 0x0} },
38 { EXYNOS5420_DIS_IRQ_KFC_CORE1_LOCAL_SYS_PWR_REG, { 0x0, 0x0, 0x0} },
39 { EXYNOS5420_DIS_IRQ_KFC_CORE1_CENTRAL_SYS_PWR_REG, { 0x0, 0x0, 0x0} },
40 { EXYNOS5420_KFC_CORE2_SYS_PWR_REG, { 0x0, 0x0, 0x0} },
41 { EXYNOS5420_DIS_IRQ_KFC_CORE2_LOCAL_SYS_PWR_REG, { 0x0, 0x0, 0x0} },
42 { EXYNOS5420_DIS_IRQ_KFC_CORE2_CENTRAL_SYS_PWR_REG, { 0x0, 0x0, 0x0} },
43 { EXYNOS5420_KFC_CORE3_SYS_PWR_REG, { 0x0, 0x0, 0x0} },
44 { EXYNOS5420_DIS_IRQ_KFC_CORE3_LOCAL_SYS_PWR_REG, { 0x0, 0x0, 0x0} },
45 { EXYNOS5420_DIS_IRQ_KFC_CORE3_CENTRAL_SYS_PWR_REG, { 0x0, 0x0, 0x0} },
46 { EXYNOS5_ISP_ARM_SYS_PWR_REG, { 0x1, 0x0, 0x0} },
47 { EXYNOS5_DIS_IRQ_ISP_ARM_LOCAL_SYS_PWR_REG, { 0x1, 0x0, 0x0} },
48 { EXYNOS5_DIS_IRQ_ISP_ARM_CENTRAL_SYS_PWR_REG, { 0x1, 0x0, 0x0} },
49 { EXYNOS5420_ARM_COMMON_SYS_PWR_REG, { 0x0, 0x0, 0x0} },
50 { EXYNOS5420_KFC_COMMON_SYS_PWR_REG, { 0x0, 0x0, 0x0} },
51 { EXYNOS5_ARM_L2_SYS_PWR_REG, { 0x0, 0x0, 0x0} },
52 { EXYNOS5420_KFC_L2_SYS_PWR_REG, { 0x0, 0x0, 0x0} },
53 { EXYNOS5_CMU_ACLKSTOP_SYS_PWR_REG, { 0x1, 0x0, 0x0} },
54 { EXYNOS5_CMU_SCLKSTOP_SYS_PWR_REG, { 0x1, 0x0, 0x1} },
55 { EXYNOS5_CMU_RESET_SYS_PWR_REG, { 0x1, 0x1, 0x0} },
56 { EXYNOS5_CMU_ACLKSTOP_SYSMEM_SYS_PWR_REG, { 0x1, 0x0, 0x0} },
57 { EXYNOS5_CMU_SCLKSTOP_SYSMEM_SYS_PWR_REG, { 0x1, 0x0, 0x1} },
58 { EXYNOS5_CMU_RESET_SYSMEM_SYS_PWR_REG, { 0x1, 0x1, 0x0} },
59 { EXYNOS5_DRAM_FREQ_DOWN_SYS_PWR_REG, { 0x1, 0x0, 0x1} },
60 { EXYNOS5_DDRPHY_DLLOFF_SYS_PWR_REG, { 0x1, 0x1, 0x1} },
61 { EXYNOS5_DDRPHY_DLLLOCK_SYS_PWR_REG, { 0x1, 0x0, 0x1} },
62 { EXYNOS5_APLL_SYSCLK_SYS_PWR_REG, { 0x1, 0x0, 0x0} },
63 { EXYNOS5_MPLL_SYSCLK_SYS_PWR_REG, { 0x1, 0x0, 0x0} },
64 { EXYNOS5_VPLL_SYSCLK_SYS_PWR_REG, { 0x1, 0x0, 0x0} },
65 { EXYNOS5_EPLL_SYSCLK_SYS_PWR_REG, { 0x1, 0x1, 0x0} },
66 { EXYNOS5_BPLL_SYSCLK_SYS_PWR_REG, { 0x1, 0x0, 0x0} },
67 { EXYNOS5_CPLL_SYSCLK_SYS_PWR_REG, { 0x1, 0x0, 0x0} },
68 { EXYNOS5420_DPLL_SYSCLK_SYS_PWR_REG, { 0x1, 0x0, 0x0} },
69 { EXYNOS5420_IPLL_SYSCLK_SYS_PWR_REG, { 0x1, 0x0, 0x0} },
70 { EXYNOS5420_KPLL_SYSCLK_SYS_PWR_REG, { 0x1, 0x0, 0x0} },
71 { EXYNOS5_MPLLUSER_SYSCLK_SYS_PWR_REG, { 0x1, 0x0, 0x0} },
72 { EXYNOS5_BPLLUSER_SYSCLK_SYS_PWR_REG, { 0x1, 0x0, 0x0} },
73 { EXYNOS5420_RPLL_SYSCLK_SYS_PWR_REG, { 0x1, 0x0, 0x0} },
74 { EXYNOS5420_SPLL_SYSCLK_SYS_PWR_REG, { 0x1, 0x0, 0x0} },
75 { EXYNOS5_TOP_BUS_SYS_PWR_REG, { 0x3, 0x0, 0x0} },
76 { EXYNOS5_TOP_RETENTION_SYS_PWR_REG, { 0x1, 0x1, 0x1} },
77 { EXYNOS5_TOP_PWR_SYS_PWR_REG, { 0x3, 0x3, 0x0} },
78 { EXYNOS5_TOP_BUS_SYSMEM_SYS_PWR_REG, { 0x3, 0x0, 0x0} },
79 { EXYNOS5_TOP_RETENTION_SYSMEM_SYS_PWR_REG, { 0x1, 0x0, 0x1} },
80 { EXYNOS5_TOP_PWR_SYSMEM_SYS_PWR_REG, { 0x3, 0x0, 0x0} },
81 { EXYNOS5_LOGIC_RESET_SYS_PWR_REG, { 0x1, 0x1, 0x0} },
82 { EXYNOS5_OSCCLK_GATE_SYS_PWR_REG, { 0x1, 0x0, 0x1} },
83 { EXYNOS5_LOGIC_RESET_SYSMEM_SYS_PWR_REG, { 0x1, 0x0, 0x0} },
84 { EXYNOS5_OSCCLK_GATE_SYSMEM_SYS_PWR_REG, { 0x1, 0x0, 0x0} },
85 { EXYNOS5420_INTRAM_MEM_SYS_PWR_REG, { 0x3, 0x0, 0x3} },
86 { EXYNOS5420_INTROM_MEM_SYS_PWR_REG, { 0x3, 0x0, 0x3} },
87 { EXYNOS5_PAD_RETENTION_DRAM_SYS_PWR_REG, { 0x1, 0x0, 0x0} },
88 { EXYNOS5_PAD_RETENTION_MAU_SYS_PWR_REG, { 0x1, 0x1, 0x0} },
89 { EXYNOS5420_PAD_RETENTION_JTAG_SYS_PWR_REG, { 0x1, 0x1, 0x0} },
90 { EXYNOS5420_PAD_RETENTION_DRAM_SYS_PWR_REG, { 0x1, 0x0, 0x0} },
91 { EXYNOS5420_PAD_RETENTION_UART_SYS_PWR_REG, { 0x1, 0x0, 0x0} },
92 { EXYNOS5420_PAD_RETENTION_MMC0_SYS_PWR_REG, { 0x1, 0x0, 0x0} },
93 { EXYNOS5420_PAD_RETENTION_MMC1_SYS_PWR_REG, { 0x1, 0x0, 0x0} },
94 { EXYNOS5420_PAD_RETENTION_MMC2_SYS_PWR_REG, { 0x1, 0x0, 0x0} },
95 { EXYNOS5420_PAD_RETENTION_HSI_SYS_PWR_REG, { 0x1, 0x0, 0x0} },
96 { EXYNOS5420_PAD_RETENTION_EBIA_SYS_PWR_REG, { 0x1, 0x0, 0x0} },
97 { EXYNOS5420_PAD_RETENTION_EBIB_SYS_PWR_REG, { 0x1, 0x0, 0x0} },
98 { EXYNOS5420_PAD_RETENTION_SPI_SYS_PWR_REG, { 0x1, 0x0, 0x0} },
99 { EXYNOS5420_PAD_RETENTION_DRAM_COREBLK_SYS_PWR_REG, { 0x1, 0x0, 0x0} },
100 { EXYNOS5_PAD_ISOLATION_SYS_PWR_REG, { 0x1, 0x1, 0x0} },
101 { EXYNOS5_PAD_ISOLATION_SYSMEM_SYS_PWR_REG, { 0x1, 0x0, 0x0} },
102 { EXYNOS5_PAD_ALV_SEL_SYS_PWR_REG, { 0x1, 0x0, 0x0} },
103 { EXYNOS5_XUSBXTI_SYS_PWR_REG, { 0x1, 0x1, 0x0} },
104 { EXYNOS5_XXTI_SYS_PWR_REG, { 0x1, 0x1, 0x0} },
105 { EXYNOS5_EXT_REGULATOR_SYS_PWR_REG, { 0x1, 0x1, 0x0} },
106 { EXYNOS5_GPIO_MODE_SYS_PWR_REG, { 0x1, 0x0, 0x0} },
107 { EXYNOS5_GPIO_MODE_SYSMEM_SYS_PWR_REG, { 0x1, 0x1, 0x0} },
108 { EXYNOS5_GPIO_MODE_MAU_SYS_PWR_REG, { 0x1, 0x1, 0x0} },
109 { EXYNOS5_TOP_ASB_RESET_SYS_PWR_REG, { 0x1, 0x1, 0x0} },
110 { EXYNOS5_TOP_ASB_ISOLATION_SYS_PWR_REG, { 0x1, 0x0, 0x0} },
111 { EXYNOS5_GSCL_SYS_PWR_REG, { 0x7, 0x0, 0x0} },
112 { EXYNOS5_ISP_SYS_PWR_REG, { 0x7, 0x0, 0x0} },
113 { EXYNOS5_MFC_SYS_PWR_REG, { 0x7, 0x0, 0x0} },
114 { EXYNOS5_G3D_SYS_PWR_REG, { 0x7, 0x0, 0x0} },
115 { EXYNOS5420_DISP1_SYS_PWR_REG, { 0x7, 0x0, 0x0} },
116 { EXYNOS5420_MAU_SYS_PWR_REG, { 0x7, 0x7, 0x0} },
117 { EXYNOS5420_G2D_SYS_PWR_REG, { 0x7, 0x0, 0x0} },
118 { EXYNOS5420_MSC_SYS_PWR_REG, { 0x7, 0x0, 0x0} },
119 { EXYNOS5420_FSYS_SYS_PWR_REG, { 0x7, 0x0, 0x0} },
120 { EXYNOS5420_FSYS2_SYS_PWR_REG, { 0x7, 0x0, 0x0} },
121 { EXYNOS5420_PSGEN_SYS_PWR_REG, { 0x7, 0x0, 0x0} },
122 { EXYNOS5420_PERIC_SYS_PWR_REG, { 0x7, 0x0, 0x0} },
123 { EXYNOS5420_WCORE_SYS_PWR_REG, { 0x7, 0x0, 0x0} },
124 { EXYNOS5_CMU_CLKSTOP_GSCL_SYS_PWR_REG, { 0x0, 0x0, 0x0} },
125 { EXYNOS5_CMU_CLKSTOP_ISP_SYS_PWR_REG, { 0x0, 0x0, 0x0} },
126 { EXYNOS5_CMU_CLKSTOP_MFC_SYS_PWR_REG, { 0x0, 0x0, 0x0} },
127 { EXYNOS5_CMU_CLKSTOP_G3D_SYS_PWR_REG, { 0x0, 0x0, 0x0} },
128 { EXYNOS5420_CMU_CLKSTOP_DISP1_SYS_PWR_REG, { 0x0, 0x0, 0x0} },
129 { EXYNOS5420_CMU_CLKSTOP_MAU_SYS_PWR_REG, { 0x0, 0x0, 0x0} },
130 { EXYNOS5420_CMU_CLKSTOP_G2D_SYS_PWR_REG, { 0x0, 0x0, 0x0} },
131 { EXYNOS5420_CMU_CLKSTOP_MSC_SYS_PWR_REG, { 0x0, 0x0, 0x0} },
132 { EXYNOS5420_CMU_CLKSTOP_FSYS_SYS_PWR_REG, { 0x0, 0x0, 0x0} },
133 { EXYNOS5420_CMU_CLKSTOP_PSGEN_SYS_PWR_REG, { 0x0, 0x0, 0x0} },
134 { EXYNOS5420_CMU_CLKSTOP_PERIC_SYS_PWR_REG, { 0x0, 0x0, 0x0} },
135 { EXYNOS5420_CMU_CLKSTOP_WCORE_SYS_PWR_REG, { 0x0, 0x0, 0x0} },
136 { EXYNOS5_CMU_SYSCLK_GSCL_SYS_PWR_REG, { 0x0, 0x0, 0x0} },
137 { EXYNOS5_CMU_SYSCLK_ISP_SYS_PWR_REG, { 0x0, 0x0, 0x0} },
138 { EXYNOS5_CMU_SYSCLK_MFC_SYS_PWR_REG, { 0x0, 0x0, 0x0} },
139 { EXYNOS5_CMU_SYSCLK_G3D_SYS_PWR_REG, { 0x0, 0x0, 0x0} },
140 { EXYNOS5420_CMU_SYSCLK_DISP1_SYS_PWR_REG, { 0x0, 0x0, 0x0} },
141 { EXYNOS5420_CMU_SYSCLK_MAU_SYS_PWR_REG, { 0x0, 0x0, 0x0} },
142 { EXYNOS5420_CMU_SYSCLK_G2D_SYS_PWR_REG, { 0x0, 0x0, 0x0} },
143 { EXYNOS5420_CMU_SYSCLK_MSC_SYS_PWR_REG, { 0x0, 0x0, 0x0} },
144 { EXYNOS5420_CMU_SYSCLK_FSYS_SYS_PWR_REG, { 0x0, 0x0, 0x0} },
145 { EXYNOS5420_CMU_SYSCLK_FSYS2_SYS_PWR_REG, { 0x0, 0x0, 0x0} },
146 { EXYNOS5420_CMU_SYSCLK_PSGEN_SYS_PWR_REG, { 0x0, 0x0, 0x0} },
147 { EXYNOS5420_CMU_SYSCLK_PERIC_SYS_PWR_REG, { 0x0, 0x0, 0x0} },
148 { EXYNOS5420_CMU_SYSCLK_WCORE_SYS_PWR_REG, { 0x0, 0x0, 0x0} },
149 { EXYNOS5420_CMU_RESET_FSYS2_SYS_PWR_REG, { 0x0, 0x0, 0x0} },
150 { EXYNOS5420_CMU_RESET_PSGEN_SYS_PWR_REG, { 0x0, 0x0, 0x0} },
151 { EXYNOS5420_CMU_RESET_PERIC_SYS_PWR_REG, { 0x0, 0x0, 0x0} },
152 { EXYNOS5420_CMU_RESET_WCORE_SYS_PWR_REG, { 0x0, 0x0, 0x0} },
153 { EXYNOS5_CMU_RESET_GSCL_SYS_PWR_REG, { 0x0, 0x0, 0x0} },
154 { EXYNOS5_CMU_RESET_ISP_SYS_PWR_REG, { 0x0, 0x0, 0x0} },
155 { EXYNOS5_CMU_RESET_MFC_SYS_PWR_REG, { 0x0, 0x0, 0x0} },
156 { EXYNOS5_CMU_RESET_G3D_SYS_PWR_REG, { 0x0, 0x0, 0x0} },
157 { EXYNOS5420_CMU_RESET_DISP1_SYS_PWR_REG, { 0x0, 0x0, 0x0} },
158 { EXYNOS5420_CMU_RESET_MAU_SYS_PWR_REG, { 0x0, 0x0, 0x0} },
159 { EXYNOS5420_CMU_RESET_G2D_SYS_PWR_REG, { 0x0, 0x0, 0x0} },
160 { EXYNOS5420_CMU_RESET_MSC_SYS_PWR_REG, { 0x0, 0x0, 0x0} },
161 { EXYNOS5420_CMU_RESET_FSYS_SYS_PWR_REG, { 0x0, 0x0, 0x0} },
162 { PMU_TABLE_END,},
163};
164
165static unsigned int const exynos5420_list_disable_pmu_reg[] = {
166 EXYNOS5_CMU_CLKSTOP_GSCL_SYS_PWR_REG,
167 EXYNOS5_CMU_CLKSTOP_ISP_SYS_PWR_REG,
168 EXYNOS5_CMU_CLKSTOP_G3D_SYS_PWR_REG,
169 EXYNOS5420_CMU_CLKSTOP_DISP1_SYS_PWR_REG,
170 EXYNOS5420_CMU_CLKSTOP_MAU_SYS_PWR_REG,
171 EXYNOS5420_CMU_CLKSTOP_G2D_SYS_PWR_REG,
172 EXYNOS5420_CMU_CLKSTOP_MSC_SYS_PWR_REG,
173 EXYNOS5420_CMU_CLKSTOP_FSYS_SYS_PWR_REG,
174 EXYNOS5420_CMU_CLKSTOP_PSGEN_SYS_PWR_REG,
175 EXYNOS5420_CMU_CLKSTOP_PERIC_SYS_PWR_REG,
176 EXYNOS5420_CMU_CLKSTOP_WCORE_SYS_PWR_REG,
177 EXYNOS5_CMU_SYSCLK_GSCL_SYS_PWR_REG,
178 EXYNOS5_CMU_SYSCLK_ISP_SYS_PWR_REG,
179 EXYNOS5_CMU_SYSCLK_G3D_SYS_PWR_REG,
180 EXYNOS5420_CMU_SYSCLK_DISP1_SYS_PWR_REG,
181 EXYNOS5420_CMU_SYSCLK_MAU_SYS_PWR_REG,
182 EXYNOS5420_CMU_SYSCLK_G2D_SYS_PWR_REG,
183 EXYNOS5420_CMU_SYSCLK_MSC_SYS_PWR_REG,
184 EXYNOS5420_CMU_SYSCLK_FSYS_SYS_PWR_REG,
185 EXYNOS5420_CMU_SYSCLK_FSYS2_SYS_PWR_REG,
186 EXYNOS5420_CMU_SYSCLK_PSGEN_SYS_PWR_REG,
187 EXYNOS5420_CMU_SYSCLK_PERIC_SYS_PWR_REG,
188 EXYNOS5420_CMU_SYSCLK_WCORE_SYS_PWR_REG,
189 EXYNOS5420_CMU_RESET_FSYS2_SYS_PWR_REG,
190 EXYNOS5420_CMU_RESET_PSGEN_SYS_PWR_REG,
191 EXYNOS5420_CMU_RESET_PERIC_SYS_PWR_REG,
192 EXYNOS5420_CMU_RESET_WCORE_SYS_PWR_REG,
193 EXYNOS5_CMU_RESET_GSCL_SYS_PWR_REG,
194 EXYNOS5_CMU_RESET_ISP_SYS_PWR_REG,
195 EXYNOS5_CMU_RESET_G3D_SYS_PWR_REG,
196 EXYNOS5420_CMU_RESET_DISP1_SYS_PWR_REG,
197 EXYNOS5420_CMU_RESET_MAU_SYS_PWR_REG,
198 EXYNOS5420_CMU_RESET_G2D_SYS_PWR_REG,
199 EXYNOS5420_CMU_RESET_MSC_SYS_PWR_REG,
200 EXYNOS5420_CMU_RESET_FSYS_SYS_PWR_REG,
201};
202
203static void exynos5420_powerdown_conf(enum sys_powerdown mode)
204{
205 u32 this_cluster;
206
207 this_cluster = MPIDR_AFFINITY_LEVEL(read_cpuid_mpidr(), 1);
208
209 /*
210 * set the cluster id to IROM register to ensure that we wake
211 * up with the current cluster.
212 */
213 pmu_raw_writel(this_cluster, EXYNOS_IROM_DATA2);
214}
215
216static void exynos5420_pmu_init(void)
217{
218 unsigned int value;
219 int i;
220
221 /*
222 * Set the CMU_RESET, CMU_SYSCLK and CMU_CLKSTOP registers
223 * for local power blocks to Low initially as per Table 8-4:
224 * "System-Level Power-Down Configuration Registers".
225 */
226 for (i = 0; i < ARRAY_SIZE(exynos5420_list_disable_pmu_reg); i++)
227 pmu_raw_writel(0, exynos5420_list_disable_pmu_reg[i]);
228
229 /* Enable USE_STANDBY_WFI for all CORE */
230 pmu_raw_writel(EXYNOS5420_USE_STANDBY_WFI_ALL, S5P_CENTRAL_SEQ_OPTION);
231
232 value = pmu_raw_readl(EXYNOS_L2_OPTION(0));
233 value &= ~EXYNOS5_USE_RETENTION;
234 pmu_raw_writel(value, EXYNOS_L2_OPTION(0));
235
236 value = pmu_raw_readl(EXYNOS_L2_OPTION(1));
237 value &= ~EXYNOS5_USE_RETENTION;
238 pmu_raw_writel(value, EXYNOS_L2_OPTION(1));
239
240 /*
241 * If L2_COMMON is turned off, clocks related to ATB async
242 * bridge are gated. Thus, when ISP power is gated, LPI
243 * may get stuck.
244 */
245 value = pmu_raw_readl(EXYNOS5420_LPI_MASK);
246 value |= EXYNOS5420_ATB_ISP_ARM;
247 pmu_raw_writel(value, EXYNOS5420_LPI_MASK);
248
249 value = pmu_raw_readl(EXYNOS5420_LPI_MASK1);
250 value |= EXYNOS5420_ATB_KFC;
251 pmu_raw_writel(value, EXYNOS5420_LPI_MASK1);
252
253 /* Prevent issue of new bus request from L2 memory */
254 value = pmu_raw_readl(EXYNOS5420_ARM_COMMON_OPTION);
255 value |= EXYNOS5_SKIP_DEACTIVATE_ACEACP_IN_PWDN;
256 pmu_raw_writel(value, EXYNOS5420_ARM_COMMON_OPTION);
257
258 value = pmu_raw_readl(EXYNOS5420_KFC_COMMON_OPTION);
259 value |= EXYNOS5_SKIP_DEACTIVATE_ACEACP_IN_PWDN;
260 pmu_raw_writel(value, EXYNOS5420_KFC_COMMON_OPTION);
261
262 /* This setting is to reduce suspend/resume time */
263 pmu_raw_writel(DUR_WAIT_RESET, EXYNOS5420_LOGIC_RESET_DURATION3);
264
265 /* Serialized CPU wakeup of Eagle */
266 pmu_raw_writel(SPREAD_ENABLE, EXYNOS5420_ARM_INTR_SPREAD_ENABLE);
267
268 pmu_raw_writel(SPREAD_USE_STANDWFI,
269 EXYNOS5420_ARM_INTR_SPREAD_USE_STANDBYWFI);
270
271 pmu_raw_writel(0x1, EXYNOS5420_UP_SCHEDULER);
272
273 pr_info("EXYNOS5420 PMU initialized\n");
274}
275
276const struct exynos_pmu_data exynos5420_pmu_data = {
277 .pmu_config = exynos5420_pmu_config,
278 .pmu_init = exynos5420_pmu_init,
279 .powerdown_conf = exynos5420_powerdown_conf,
280};