On Tue, 29 Jan 2019 at 00:08, Stuart Menefy <stuart.menefy@xxxxxxxxxxxxxxxx> wrote: > > Initial support for the PMU on the Exynos5260, largely derived from the > Samsung 3.4 kernel. > > Signed-off-by: Stuart Menefy <stuart.menefy@xxxxxxxxxxxxxxxx> > --- > drivers/soc/samsung/Makefile | 2 +- > drivers/soc/samsung/exynos-pmu.c | 3 + > drivers/soc/samsung/exynos-pmu.h | 1 + > drivers/soc/samsung/exynos5260-pmu.c | 178 ++++++++++++++++++++++++++++ > include/linux/soc/samsung/exynos-regs-pmu.h | 126 ++++++++++++++++++++ > 5 files changed, 309 insertions(+), 1 deletion(-) > create mode 100644 drivers/soc/samsung/exynos5260-pmu.c > > diff --git a/drivers/soc/samsung/Makefile b/drivers/soc/samsung/Makefile > index 29f294baac6e..5b6bf33e8b39 100644 > --- a/drivers/soc/samsung/Makefile > +++ b/drivers/soc/samsung/Makefile > @@ -2,5 +2,5 @@ > obj-$(CONFIG_EXYNOS_PMU) += exynos-pmu.o > > obj-$(CONFIG_EXYNOS_PMU_ARM_DRIVERS) += exynos3250-pmu.o exynos4-pmu.o \ > - exynos5250-pmu.o exynos5420-pmu.o > + exynos5250-pmu.o exynos5260-pmu.o exynos5420-pmu.o > obj-$(CONFIG_EXYNOS_PM_DOMAINS) += pm_domains.o > diff --git a/drivers/soc/samsung/exynos-pmu.c b/drivers/soc/samsung/exynos-pmu.c > index d34ca201b8b7..dafdc0d1288b 100644 > --- a/drivers/soc/samsung/exynos-pmu.c > +++ b/drivers/soc/samsung/exynos-pmu.c > @@ -85,6 +85,9 @@ static const struct of_device_id exynos_pmu_of_device_ids[] = { > .compatible = "samsung,exynos5250-pmu", > .data = exynos_pmu_data_arm_ptr(exynos5250_pmu_data), > }, { > + .compatible = "samsung,exynos5260-pmu", > + .data = exynos_pmu_data_arm_ptr(exynos5260_pmu_data), > + }, { > .compatible = "samsung,exynos5410-pmu", > }, { > .compatible = "samsung,exynos5420-pmu", > diff --git a/drivers/soc/samsung/exynos-pmu.h b/drivers/soc/samsung/exynos-pmu.h > index 977e4daf5a0f..bfd30b6f3093 100644 > --- a/drivers/soc/samsung/exynos-pmu.h > +++ b/drivers/soc/samsung/exynos-pmu.h > @@ -34,6 +34,7 @@ extern const struct exynos_pmu_data exynos3250_pmu_data; > extern const struct exynos_pmu_data exynos4210_pmu_data; > extern const struct exynos_pmu_data exynos4412_pmu_data; > extern const struct exynos_pmu_data exynos5250_pmu_data; > +extern const struct exynos_pmu_data exynos5260_pmu_data; > extern const struct exynos_pmu_data exynos5420_pmu_data; > #endif > > diff --git a/drivers/soc/samsung/exynos5260-pmu.c b/drivers/soc/samsung/exynos5260-pmu.c > new file mode 100644 > index 000000000000..c121e3288dea > --- /dev/null > +++ b/drivers/soc/samsung/exynos5260-pmu.c > @@ -0,0 +1,178 @@ > +// SPDX-License-Identifier: GPL-2.0 > +// > +// Copyright (c) 2018 Garrison Technology Limited > +// derived from exynos5250-pmu.c which was: > +// Copyright (c) 2011-2015 Samsung Electronics Co., Ltd. > +// > +// EXYNOS5260 - CPU PMU (Power Management Unit) support > + > +#include <linux/soc/samsung/exynos-regs-pmu.h> > +#include <linux/soc/samsung/exynos-pmu.h> > + > +#include "exynos-pmu.h" > + > +static const struct exynos_pmu_conf exynos5260_pmu_config[] = { > + /* { .offset = offset, .val = { AFTR, LPA, SLEEP } */ > + { EXYNOS5_ARM_CORE0_SYS_PWR_REG, { 0x0, 0x0, 0x8} }, > + { EXYNOS5_DIS_IRQ_ARM_CORE0_CENTRAL_SYS_PWR_REG, { 0x0, 0x0, 0x0} }, > + { EXYNOS5_ARM_CORE1_SYS_PWR_REG, { 0x0, 0x0, 0x8} }, > + { EXYNOS5_DIS_IRQ_ARM_CORE1_CENTRAL_SYS_PWR_REG, { 0x0, 0x0, 0x0} }, > + { EXYNOS5260_KFC_CORE0_SYS_PWR_REG, { 0x0, 0x0, 0x8} }, > + { EXYNOS5260_DIS_IRQ_KFC_CORE0_CENTRAL_SYS_PWR_REG, { 0x0, 0x0, 0x0} }, > + { EXYNOS5260_KFC_CORE1_SYS_PWR_REG, { 0x0, 0x0, 0x8} }, > + { EXYNOS5260_DIS_IRQ_KFC_CORE1_CENTRAL_SYS_PWR_REG, { 0x0, 0x0, 0x0} }, > + { EXYNOS5260_KFC_CORE2_SYS_PWR_REG, { 0x0, 0x0, 0x8} }, > + { EXYNOS5260_DIS_IRQ_KFC_CORE2_CENTRAL_SYS_PWR_REG, { 0x0, 0x0, 0x0} }, > + { EXYNOS5260_KFC_CORE3_SYS_PWR_REG, { 0x0, 0x0, 0x8} }, > + { EXYNOS5260_DIS_IRQ_KFC_CORE3_CENTRAL_SYS_PWR_REG, { 0x0, 0x0, 0x0} }, > + { EXYNOS5260_EAGLE_NONCPU_SYS_PWR_REG, { 0x0, 0x0, 0x8} }, > + { EXYNOS5260_KFC_NONCPU_SYS_PWR_REG, { 0x0, 0x0, 0x8} }, > + { EXYNOS5260_A5IS_SYS_PWR_REG, { 0x0, 0x0, 0x0} }, > + { EXYNOS5260_DIS_IRQ_A5IS_LOCAL_SYS_PWR_REG, { 0x0, 0x0, 0x0} }, > + { EXYNOS5260_DIS_IRQ_A5IS_CENTRAL_SYS_PWR_REG, { 0x0, 0x0, 0x0} }, > + { EXYNOS5_ARM_L2_SYS_PWR_REG, { 0x0, 0x0, 0x7} }, > + { EXYNOS5260_KFC_L2_SYS_PWR_REG, { 0x0, 0x0, 0x7} }, > + { EXYNOS5260_CLKSTOP_CMU_TOP_SYS_PWR_REG, { 0x1, 0x0, 0x1} }, > + { EXYNOS5260_CLKRUN_CMU_TOP_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, > + { EXYNOS5260_RESET_CMU_TOP_SYS_PWR_REG, { 0x1, 0x1, 0x0} }, > + { EXYNOS5260_RESET_CPUCLKSTOP_SYS_PWR_REG, { 0x1, 0x1, 0x0} }, > + { EXYNOS5260_CLKSTOP_CMU_MIF_SYS_PWR_REG, { 0x1, 0x0, 0x1} }, > + { EXYNOS5260_CLKRUN_CMU_MIF_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, > + { EXYNOS5260_RESET_CMU_MIF_SYS_PWR_REG, { 0x1, 0x1, 0x0} }, > + { EXYNOS5_DDRPHY_DLLLOCK_SYS_PWR_REG, { 0x1, 0x1, 0x0} }, > + { EXYNOS5260_DISABLE_PLL_CMU_TOP_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, > + { EXYNOS5260_DISABLE_PLL_AUD_PLL_SYS_PWR_REG, { 0x1, 0x1, 0x0} }, > + { EXYNOS5260_DISABLE_PLL_MIF_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, > + { EXYNOS5_TOP_BUS_SYS_PWR_REG, { 0x7, 0x0, 0x0} }, > + { EXYNOS5_TOP_RETENTION_SYS_PWR_REG, { 0x1, 0x0, 0x1} }, > + { EXYNOS5_TOP_PWR_SYS_PWR_REG, { 0x3, 0x0, 0x3} }, > + { EXYNOS5260_TOP_BUS_MIF_SYS_PWR_REG, { 0x7, 0x0, 0x0} }, > + { EXYNOS5260_TOP_RETENTION_MIF_SYS_PWR_REG, { 0x1, 0x0, 0x1} }, > + { EXYNOS5260_TOP_PWR_MIF_SYS_PWR_REG, { 0x3, 0x0, 0x3} }, > + { EXYNOS5_LOGIC_RESET_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, > + { EXYNOS5_OSCCLK_GATE_SYS_PWR_REG, { 0x1, 0x0, 0x1} }, > + { EXYNOS5260_SLEEP_RESET_SYS_PWR_REG, { 0x1, 0x1, 0x0} }, > + { EXYNOS5260_LOGIC_RESET_MIF_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, > + { EXYNOS5260_OSCCLK_GATE_MIF_SYS_PWR_REG, { 0x1, 0x0, 0x1} }, > + { EXYNOS5260_SLEEP_RESET_MIF_SYS_PWR_REG, { 0x1, 0x1, 0x0} }, > + { EXYNOS5260_MEMORY_TOP_SYS_PWR_REG, { 0x3, 0x0, 0x0} }, > + { EXYNOS5260_MEMORY_MIF_SYS_PWR_REG, { 0x3, 0x0, 0x0} }, > + { EXYNOS5_PAD_RETENTION_DRAM_SYS_PWR_REG, { 0x3, 0x0, 0x0} }, > + { EXYNOS5260_PAD_RETENTION_AUD_SYS_PWR_REG, { 0x0, 0x0, 0x0} }, > + { EXYNOS5260_PAD_RETENTION_JTAG_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, > + { EXYNOS5260_PAD_RETENTION_MMC2_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, > + { EXYNOS5260_PAD_RETENTION_TOP_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, > + { EXYNOS5260_PAD_RETENTION_UART_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, > + { EXYNOS5260_PAD_RETENTION_MMC0_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, > + { EXYNOS5260_PAD_RETENTION_MMC1_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, > + { EXYNOS5260_PAD_RETENTION_SPI_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, > + { EXYNOS5260_PAD_RETENTION_MIF_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, > + { EXYNOS5_PAD_ISOLATION_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, > + { EXYNOS5260_PAD_RETENTION_BOOTLDO_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, > + { EXYNOS5260_PAD_ISOLATION_MIF_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, > + { EXYNOS5_PAD_ALV_SEL_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, > + { EXYNOS5_XXTI_SYS_PWR_REG, { 0x1, 0x1, 0x0} }, > + { EXYNOS5_EXT_REGULATOR_SYS_PWR_REG, { 0x1, 0x1, 0x0} }, > + { EXYNOS5_GPIO_MODE_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, > + { EXYNOS5260_GPIO_MODE_MIF_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, > + { EXYNOS5260_GPIO_MODE_AUD_SYS_PWR_REG, { 0x0, 0x0, 0x0} }, > + { EXYNOS5260_GSCL_SYS_PWR_REG, { 0xF, 0x0, 0x0} }, > + { EXYNOS5260_G3D_SYS_PWR_REG, { 0xF, 0x0, 0x0} }, > + { EXYNOS5260_DISP_SYS_PWR_REG, { 0xF, 0x0, 0x0} }, > + { EXYNOS5260_AUD_SYS_PWR_REG, { 0xF, 0xF, 0x0} }, > + { EXYNOS5260_G2D_SYS_PWR_REG, { 0xF, 0x0, 0x0} }, > + { EXYNOS5260_ISP_SYS_PWR_REG, { 0xF, 0x0, 0x0} }, > + { EXYNOS5260_MFC_SYS_PWR_REG, { 0xF, 0x0, 0x0} }, > + { EXYNOS5260_MEMORY_G2D_SYS_PWR_REG, { 0x0, 0x0, 0xF} }, > + { PMU_TABLE_END,}, > +}; > + > +static unsigned int const exynos5260_list_feed[] = { > + EXYNOS5_ARM_CORE0_OPTION, > + EXYNOS5_ARM_CORE1_OPTION, > + EXYNOS5260_KFC_CORE0_OPTION, > + EXYNOS5260_KFC_CORE1_OPTION, > + EXYNOS5260_KFC_CORE2_OPTION, > + EXYNOS5260_KFC_CORE3_OPTION, > + EXYNOS5260_EAGLE_NONCPU_OPTION, > + EXYNOS5260_KFC_NONCPU_OPTION, > + EXYNOS5260_TOP_PWR_OPTION, > + EXYNOS5260_TOP_PWR_MIF_OPTION, > + EXYNOS5260_GSCL_OPTION, > + EXYNOS5260_G3D_OPTION, > + EXYNOS5260_DISP_OPTION, > + EXYNOS5260_AUD_OPTION, > + EXYNOS5260_G2D_OPTION, > + EXYNOS5260_ISP_OPTION, > + EXYNOS5260_MFC_OPTION, > +}; > + > +static void exynos5260_powerdown_conf_extra(enum sys_powerdown mode) > +{ > + if (!(pmu_raw_readl(EXYNOS5260_PMU_DEBUG) & 0x1)) > + pmu_raw_writel(1, EXYNOS5_XXTI_SYS_PWR_REG); This should not be needed. The reset value is 1. > +} > + > +static void exynos5260_pmu_init(void) > +{ > + unsigned int value; > + int i; > + > + /* Enable USE_STANDBY_WFI for all CORE */ > + pmu_raw_writel(EXYNOS5260_USE_STANDBY_WFI_ALL | > + EXYNOS5260_USE_PROLOGNED_LOGIC_RESET, > + S5P_CENTRAL_SEQ_OPTION); > + > + /* Set PSHOLD port for output high */ > + value = pmu_raw_readl(S5P_PS_HOLD_CONTROL); > + value |= EXYNOS5260_PS_HOLD_OUTPUT_HIGH; > + pmu_raw_writel(value, S5P_PS_HOLD_CONTROL); > + > + /* Enable signal for PSHOLD port */ > + value = pmu_raw_readl(S5P_PS_HOLD_CONTROL); > + value |= EXYNOS5260_PS_HOLD_EN; > + pmu_raw_writel(value, S5P_PS_HOLD_CONTROL); This could be squashed to one write using existing S5P_PS_HOLD_OUTPUT_HIGH which meaning is exactly like what you did here: 1. Set it to output (enable). 2. Set it to high. The existing 3250 code is wrong... because it touches 31 bit which is reserved. Anyone in Samsung willing to test it and fix Exynos3250? Best regards, Krzysztof > + > + /* Init core interface reg */ > + value = pmu_raw_readl(EXYNOS5260_EAGLE_NONCPU_OPTION); > + value &= ~(0xF << 16); > + pmu_raw_writel(value, EXYNOS5260_EAGLE_NONCPU_OPTION); > + value = pmu_raw_readl(EXYNOS5260_KFC_NONCPU_OPTION); > + value &= ~(0xF << 16); > + pmu_raw_writel(value, EXYNOS5260_KFC_NONCPU_OPTION); > + > + /* Init L2 option */ > + pmu_raw_writel(0, EXYNOS5260_EAGLE_L2_OPTION); > + pmu_raw_writel(0, EXYNOS5260_KFC_L2_OPTION); > + > + /* Procedure of central sequencer needs to be changed */ > + pmu_raw_writel((1<<31 | 0x3a<<16 | 0x3e), EXYNOS5260_SEQ_TRANSITION0); > + pmu_raw_writel((1<<31 | 0x3e<<16 | 0x3b), EXYNOS5260_SEQ_TRANSITION1); > + pmu_raw_writel((1<<31 | 0x3d<<16 | 0x3f), EXYNOS5260_SEQ_TRANSITION2); > + > + /* Reset assert ctrl */ > + for (i = 0; i < 2; i++) { > + value = pmu_raw_readl(EXYNOS_ARM_CORE_OPTION(i)); > + value |= S5P_USE_DELAYED_RESET_ASSERTION; > + pmu_raw_writel(value, EXYNOS_ARM_CORE_OPTION(i)); > + } > + > + /* > + * Set power on/off notification method > + * Enable only SC_FEEDBACK > + */ > + for (i = 0; i < ARRAY_SIZE(exynos5260_list_feed); i++) { > + value = pmu_raw_readl(exynos5260_list_feed[i]); > + value &= ~EXYNOS5_USE_SC_COUNTER; > + value |= EXYNOS5_USE_SC_FEEDBACK; > + pmu_raw_writel(value, exynos5260_list_feed[i]); > + } > + > + pmu_raw_writel(0x3, EXYNOS5260_UP_SCHEDULER); > +} > + > +const struct exynos_pmu_data exynos5260_pmu_data = { > + .pmu_config = exynos5260_pmu_config, > + .pmu_init = exynos5260_pmu_init, > + .powerdown_conf_extra = exynos5260_powerdown_conf_extra, > +}; > diff --git a/include/linux/soc/samsung/exynos-regs-pmu.h b/include/linux/soc/samsung/exynos-regs-pmu.h > index 5addaf5ccbce..e35861aa08bc 100644 > --- a/include/linux/soc/samsung/exynos-regs-pmu.h > +++ b/include/linux/soc/samsung/exynos-regs-pmu.h > @@ -138,6 +138,8 @@ > (EXYNOS_ARM_CORE_CONFIGURATION(_nr) + 0x4) > #define EXYNOS_ARM_CORE_OPTION(_nr) \ > (EXYNOS_ARM_CORE_CONFIGURATION(_nr) + 0x8) > +#define EXYNOS_ARM_CORE_RESET(_nr) \ > + (EXYNOS_ARM_CORE_CONFIGURATION(_nr) + 0xc) This define is not used (and valid only for some of SoCs) so please remove it. > > #define EXYNOS_ARM_COMMON_CONFIGURATION 0x2500 > #define EXYNOS_COMMON_CONFIGURATION(_nr) \ > @@ -170,6 +172,8 @@ > #define S5P_PS_HOLD_CONTROL 0x330C > #define S5P_PS_HOLD_EN (1 << 31) > #define S5P_PS_HOLD_OUTPUT_HIGH (3 << 8) > +#define EXYNOS5260_PS_HOLD_EN (1 << 9) > +#define EXYNOS5260_PS_HOLD_OUTPUT_HIGH (1 << 8) Both defines are not needed. Best regards, Krzysztof