Commit 6df9543d authored by Stephen Boyd's avatar Stephen Boyd
Browse files

Merge tag 'clk-v4.20-samsung' of...

Merge tag 'clk-v4.20-samsung' of git://git.kernel.org/pub/scm/linux/kernel/git/snawrocki/clk into clk-samsung

Pull Samsung clk driver updates from Sylwester Nawrocki:

 - consolidation of system suspend related code in Exynos, S5P, S3C SoC clk drivers,
 - fixes of system suspend support on Exynos542x (Odroid boards) and Exynos5433 SoC,
 - removal of obsoleted Exynos4212 ISP clock definitions,
 - correction of Exynos CPU clock implementation,
 - addition of SPDX license identifiers.

* tag 'clk-v4.20-samsung' of git://git.kernel.org/pub/scm/linux/kernel/git/snawrocki/clk:
  dt-bindings: clock: samsung: Add SPDX license identifiers
  clk: samsung: Use clk_hw API for calling clk framework from clk notifiers
  clk: samsung: exynos5420: Enable PERIS clocks for suspend
  clk: samsung: exynos5420: Define CLK_SECKEY gate clock only or Exynos5420
  clk: samsung: exynos5433: Keep sclk_uart clocks enabled in suspend
  clk: samsung: Remove obsolete code for Exynos4412 ISP clocks
  clk: samsung: exynos5433: Add suspend state for TOP, CPIF & PERIC CMUs
  clk: samsung: Use NOIRQ stage for Exynos5433 clocks suspend/resume
  clk: samsung: exynos5420: Use generic helper for handling suspend/resume
  clk: samsung: exynos4: Use generic helper for handling suspend/resume
  clk: samsung: Add support for setting registers state before suspend
  clk: samsung: exynos5250: Use generic helper for handling suspend/resume
  clk: samsung: s5pv210: Use generic helper for handling suspend/resume
  clk: samsung: s3c64xx: Use generic helper for handling suspend/resume
  clk: samsung: s3c2443: Use generic helper for handling suspend/resume
  clk: samsung: s3c2412: Use generic helper for handling suspend/resume
  clk: samsung: s3c2410: Use generic helper for handling suspend/resume
  clk: samsung: Remove excessive include
parents 5b394b2d 9dbcfe1a
Loading
Loading
Loading
Loading
+3 −3
Original line number Diff line number Diff line
@@ -152,7 +152,7 @@ static int exynos_cpuclk_pre_rate_change(struct clk_notifier_data *ndata,
			struct exynos_cpuclk *cpuclk, void __iomem *base)
{
	const struct exynos_cpuclk_cfg_data *cfg_data = cpuclk->cfg;
	unsigned long alt_prate = clk_get_rate(cpuclk->alt_parent);
	unsigned long alt_prate = clk_hw_get_rate(cpuclk->alt_parent);
	unsigned long alt_div = 0, alt_div_mask = DIV_MASK;
	unsigned long div0, div1 = 0, mux_reg;
	unsigned long flags;
@@ -280,7 +280,7 @@ static int exynos5433_cpuclk_pre_rate_change(struct clk_notifier_data *ndata,
			struct exynos_cpuclk *cpuclk, void __iomem *base)
{
	const struct exynos_cpuclk_cfg_data *cfg_data = cpuclk->cfg;
	unsigned long alt_prate = clk_get_rate(cpuclk->alt_parent);
	unsigned long alt_prate = clk_hw_get_rate(cpuclk->alt_parent);
	unsigned long alt_div = 0, alt_div_mask = DIV_MASK;
	unsigned long div0, div1 = 0, mux_reg;
	unsigned long flags;
@@ -432,7 +432,7 @@ int __init exynos_register_cpu_clock(struct samsung_clk_provider *ctx,
	else
		cpuclk->clk_nb.notifier_call = exynos_cpuclk_notifier_cb;

	cpuclk->alt_parent = __clk_lookup(alt_parent);
	cpuclk->alt_parent = __clk_get_hw(__clk_lookup(alt_parent));
	if (!cpuclk->alt_parent) {
		pr_err("%s: could not lookup alternate parent %s\n",
				__func__, alt_parent);
+1 −1
Original line number Diff line number Diff line
@@ -49,7 +49,7 @@ struct exynos_cpuclk_cfg_data {
 */
struct exynos_cpuclk {
	struct clk_hw				hw;
	struct clk				*alt_parent;
	struct clk_hw				*alt_parent;
	void __iomem				*ctrl_base;
	spinlock_t				*lock;
	const struct exynos_cpuclk_cfg_data	*cfg;
+0 −1
Original line number Diff line number Diff line
@@ -15,7 +15,6 @@
#include <linux/clk-provider.h>
#include <linux/of_address.h>
#include <linux/of_device.h>
#include <linux/syscore_ops.h>
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/pm_runtime.h>
+0 −1
Original line number Diff line number Diff line
@@ -12,7 +12,6 @@
#include <linux/of.h>
#include <linux/of_address.h>
#include <linux/platform_device.h>
#include <linux/syscore_ops.h>

#include <dt-bindings/clock/exynos3250.h>

+14 −212
Original line number Diff line number Diff line
@@ -16,7 +16,6 @@
#include <linux/clk-provider.h>
#include <linux/of.h>
#include <linux/of_address.h>
#include <linux/syscore_ops.h>

#include "clk.h"
#include "clk-cpu.h"
@@ -123,10 +122,6 @@
#define CLKOUT_CMU_CPU		0x14a00
#define PWR_CTRL1		0x15020
#define E4X12_PWR_CTRL2		0x15024
#define E4X12_DIV_ISP0		0x18300
#define E4X12_DIV_ISP1		0x18304
#define E4X12_GATE_ISP0		0x18800
#define E4X12_GATE_ISP1		0x18804

/* Below definitions are used for PWR_CTRL settings */
#define PWR_CTRL1_CORE2_DOWN_RATIO(x)		(((x) & 0x7) << 28)
@@ -157,14 +152,6 @@ enum exynos4_plls {
static void __iomem *reg_base;
static enum exynos4_soc exynos4_soc;

/*
 * Support for CMU save/restore across system suspends
 */
#ifdef CONFIG_PM_SLEEP
static struct samsung_clk_reg_dump *exynos4_save_common;
static struct samsung_clk_reg_dump *exynos4_save_soc;
static struct samsung_clk_reg_dump *exynos4_save_pll;

/*
 * list of controller registers to be saved and restored during a
 * suspend/resume cycle.
@@ -192,7 +179,7 @@ static const unsigned long exynos4x12_clk_save[] __initconst = {
	E4X12_PWR_CTRL2,
};

static const unsigned long exynos4_clk_pll_regs[] __initconst = {
static const unsigned long exynos4_clk_regs[] __initconst = {
	EPLL_LOCK,
	VPLL_LOCK,
	EPLL_CON0,
@@ -201,9 +188,6 @@ static const unsigned long exynos4_clk_pll_regs[] __initconst = {
	VPLL_CON0,
	VPLL_CON1,
	VPLL_CON2,
};

static const unsigned long exynos4_clk_regs[] __initconst = {
	SRC_LEFTBUS,
	DIV_LEFTBUS,
	GATE_IP_LEFTBUS,
@@ -276,6 +260,8 @@ static const unsigned long exynos4_clk_regs[] __initconst = {
};

static const struct samsung_clk_reg_dump src_mask_suspend[] = {
	{ .offset = VPLL_CON0,			.value = 0x80600302, },
	{ .offset = EPLL_CON0,			.value = 0x806F0302, },
	{ .offset = SRC_MASK_TOP,		.value = 0x00000001, },
	{ .offset = SRC_MASK_CAM,		.value = 0x11111111, },
	{ .offset = SRC_MASK_TV,		.value = 0x00000111, },
@@ -291,123 +277,6 @@ static const struct samsung_clk_reg_dump src_mask_suspend_e4210[] = {
	{ .offset = E4210_SRC_MASK_LCD1,	.value = 0x00001111, },
};

#define PLL_ENABLED	(1 << 31)
#define PLL_LOCKED	(1 << 29)

static void exynos4_clk_enable_pll(u32 reg)
{
	u32 pll_con = readl(reg_base + reg);
	pll_con |= PLL_ENABLED;
	writel(pll_con, reg_base + reg);

	while (!(pll_con & PLL_LOCKED)) {
		cpu_relax();
		pll_con = readl(reg_base + reg);
	}
}

static void exynos4_clk_wait_for_pll(u32 reg)
{
	u32 pll_con;

	pll_con = readl(reg_base + reg);
	if (!(pll_con & PLL_ENABLED))
		return;

	while (!(pll_con & PLL_LOCKED)) {
		cpu_relax();
		pll_con = readl(reg_base + reg);
	}
}

static int exynos4_clk_suspend(void)
{
	samsung_clk_save(reg_base, exynos4_save_common,
				ARRAY_SIZE(exynos4_clk_regs));
	samsung_clk_save(reg_base, exynos4_save_pll,
				ARRAY_SIZE(exynos4_clk_pll_regs));

	exynos4_clk_enable_pll(EPLL_CON0);
	exynos4_clk_enable_pll(VPLL_CON0);

	if (exynos4_soc == EXYNOS4210) {
		samsung_clk_save(reg_base, exynos4_save_soc,
					ARRAY_SIZE(exynos4210_clk_save));
		samsung_clk_restore(reg_base, src_mask_suspend_e4210,
					ARRAY_SIZE(src_mask_suspend_e4210));
	} else {
		samsung_clk_save(reg_base, exynos4_save_soc,
					ARRAY_SIZE(exynos4x12_clk_save));
	}

	samsung_clk_restore(reg_base, src_mask_suspend,
					ARRAY_SIZE(src_mask_suspend));

	return 0;
}

static void exynos4_clk_resume(void)
{
	samsung_clk_restore(reg_base, exynos4_save_pll,
				ARRAY_SIZE(exynos4_clk_pll_regs));

	exynos4_clk_wait_for_pll(EPLL_CON0);
	exynos4_clk_wait_for_pll(VPLL_CON0);

	samsung_clk_restore(reg_base, exynos4_save_common,
				ARRAY_SIZE(exynos4_clk_regs));

	if (exynos4_soc == EXYNOS4210)
		samsung_clk_restore(reg_base, exynos4_save_soc,
					ARRAY_SIZE(exynos4210_clk_save));
	else
		samsung_clk_restore(reg_base, exynos4_save_soc,
					ARRAY_SIZE(exynos4x12_clk_save));
}

static struct syscore_ops exynos4_clk_syscore_ops = {
	.suspend = exynos4_clk_suspend,
	.resume = exynos4_clk_resume,
};

static void __init exynos4_clk_sleep_init(void)
{
	exynos4_save_common = samsung_clk_alloc_reg_dump(exynos4_clk_regs,
					ARRAY_SIZE(exynos4_clk_regs));
	if (!exynos4_save_common)
		goto err_warn;

	if (exynos4_soc == EXYNOS4210)
		exynos4_save_soc = samsung_clk_alloc_reg_dump(
					exynos4210_clk_save,
					ARRAY_SIZE(exynos4210_clk_save));
	else
		exynos4_save_soc = samsung_clk_alloc_reg_dump(
					exynos4x12_clk_save,
					ARRAY_SIZE(exynos4x12_clk_save));
	if (!exynos4_save_soc)
		goto err_common;

	exynos4_save_pll = samsung_clk_alloc_reg_dump(exynos4_clk_pll_regs,
					ARRAY_SIZE(exynos4_clk_pll_regs));
	if (!exynos4_save_pll)
		goto err_soc;

	register_syscore_ops(&exynos4_clk_syscore_ops);
	return;

err_soc:
	kfree(exynos4_save_soc);
err_common:
	kfree(exynos4_save_common);
err_warn:
	pr_warn("%s: failed to allocate sleep save data, no sleep support!\n",
		__func__);
}
#else
static void __init exynos4_clk_sleep_init(void) {}
#endif

/* list of all parent clock list */
PNAME(mout_apll_p)	= { "fin_pll", "fout_apll", };
PNAME(mout_mpll_p)	= { "fin_pll", "fout_mpll", };
@@ -841,18 +710,6 @@ static const struct samsung_div_clock exynos4x12_div_clks[] __initconst = {
	DIV(0, "div_c2c_aclk", "div_c2c", DIV_DMC1, 12, 3),
};

static struct samsung_div_clock exynos4x12_isp_div_clks[] = {
	DIV_F(CLK_DIV_ISP0, "div_isp0", "aclk200", E4X12_DIV_ISP0, 0, 3,
						CLK_GET_RATE_NOCACHE, 0),
	DIV_F(CLK_DIV_ISP1, "div_isp1", "aclk200", E4X12_DIV_ISP0, 4, 3,
						CLK_GET_RATE_NOCACHE, 0),
	DIV(0, "div_mpwm", "div_isp1", E4X12_DIV_ISP1, 0, 3),
	DIV_F(CLK_DIV_MCUISP0, "div_mcuisp0", "aclk400_mcuisp", E4X12_DIV_ISP1,
						4, 3, CLK_GET_RATE_NOCACHE, 0),
	DIV_F(CLK_DIV_MCUISP1, "div_mcuisp1", "div_mcuisp0", E4X12_DIV_ISP1,
						8, 3, CLK_GET_RATE_NOCACHE, 0),
};

/* list of gate clocks supported in all exynos4 soc's */
static const struct samsung_gate_clock exynos4_gate_clks[] __initconst = {
	GATE(CLK_PPMULEFT, "ppmuleft", "aclk200", GATE_IP_LEFTBUS, 1, 0, 0),
@@ -1150,61 +1007,6 @@ static const struct samsung_gate_clock exynos4x12_gate_clks[] __initconst = {
		0),
};

static struct samsung_gate_clock exynos4x12_isp_gate_clks[] = {
	GATE(CLK_FIMC_ISP, "isp", "aclk200", E4X12_GATE_ISP0, 0,
			CLK_IGNORE_UNUSED | CLK_GET_RATE_NOCACHE, 0),
	GATE(CLK_FIMC_DRC, "drc", "aclk200", E4X12_GATE_ISP0, 1,
			CLK_IGNORE_UNUSED | CLK_GET_RATE_NOCACHE, 0),
	GATE(CLK_FIMC_FD, "fd", "aclk200", E4X12_GATE_ISP0, 2,
			CLK_IGNORE_UNUSED | CLK_GET_RATE_NOCACHE, 0),
	GATE(CLK_FIMC_LITE0, "lite0", "aclk200", E4X12_GATE_ISP0, 3,
			CLK_IGNORE_UNUSED | CLK_GET_RATE_NOCACHE, 0),
	GATE(CLK_FIMC_LITE1, "lite1", "aclk200", E4X12_GATE_ISP0, 4,
			CLK_IGNORE_UNUSED | CLK_GET_RATE_NOCACHE, 0),
	GATE(CLK_MCUISP, "mcuisp", "aclk200", E4X12_GATE_ISP0, 5,
			CLK_IGNORE_UNUSED | CLK_GET_RATE_NOCACHE, 0),
	GATE(CLK_GICISP, "gicisp", "aclk200", E4X12_GATE_ISP0, 7,
			CLK_IGNORE_UNUSED | CLK_GET_RATE_NOCACHE, 0),
	GATE(CLK_SMMU_ISP, "smmu_isp", "aclk200", E4X12_GATE_ISP0, 8,
			CLK_IGNORE_UNUSED | CLK_GET_RATE_NOCACHE, 0),
	GATE(CLK_SMMU_DRC, "smmu_drc", "aclk200", E4X12_GATE_ISP0, 9,
			CLK_IGNORE_UNUSED | CLK_GET_RATE_NOCACHE, 0),
	GATE(CLK_SMMU_FD, "smmu_fd", "aclk200", E4X12_GATE_ISP0, 10,
			CLK_IGNORE_UNUSED | CLK_GET_RATE_NOCACHE, 0),
	GATE(CLK_SMMU_LITE0, "smmu_lite0", "aclk200", E4X12_GATE_ISP0, 11,
			CLK_IGNORE_UNUSED | CLK_GET_RATE_NOCACHE, 0),
	GATE(CLK_SMMU_LITE1, "smmu_lite1", "aclk200", E4X12_GATE_ISP0, 12,
			CLK_IGNORE_UNUSED | CLK_GET_RATE_NOCACHE, 0),
	GATE(CLK_PPMUISPMX, "ppmuispmx", "aclk200", E4X12_GATE_ISP0, 20,
			CLK_IGNORE_UNUSED | CLK_GET_RATE_NOCACHE, 0),
	GATE(CLK_PPMUISPX, "ppmuispx", "aclk200", E4X12_GATE_ISP0, 21,
			CLK_IGNORE_UNUSED | CLK_GET_RATE_NOCACHE, 0),
	GATE(CLK_MCUCTL_ISP, "mcuctl_isp", "aclk200", E4X12_GATE_ISP0, 23,
			CLK_IGNORE_UNUSED | CLK_GET_RATE_NOCACHE, 0),
	GATE(CLK_MPWM_ISP, "mpwm_isp", "aclk200", E4X12_GATE_ISP0, 24,
			CLK_IGNORE_UNUSED | CLK_GET_RATE_NOCACHE, 0),
	GATE(CLK_I2C0_ISP, "i2c0_isp", "aclk200", E4X12_GATE_ISP0, 25,
			CLK_IGNORE_UNUSED | CLK_GET_RATE_NOCACHE, 0),
	GATE(CLK_I2C1_ISP, "i2c1_isp", "aclk200", E4X12_GATE_ISP0, 26,
			CLK_IGNORE_UNUSED | CLK_GET_RATE_NOCACHE, 0),
	GATE(CLK_MTCADC_ISP, "mtcadc_isp", "aclk200", E4X12_GATE_ISP0, 27,
			CLK_IGNORE_UNUSED | CLK_GET_RATE_NOCACHE, 0),
	GATE(CLK_PWM_ISP, "pwm_isp", "aclk200", E4X12_GATE_ISP0, 28,
			CLK_IGNORE_UNUSED | CLK_GET_RATE_NOCACHE, 0),
	GATE(CLK_WDT_ISP, "wdt_isp", "aclk200", E4X12_GATE_ISP0, 30,
			CLK_IGNORE_UNUSED | CLK_GET_RATE_NOCACHE, 0),
	GATE(CLK_UART_ISP, "uart_isp", "aclk200", E4X12_GATE_ISP0, 31,
			CLK_IGNORE_UNUSED | CLK_GET_RATE_NOCACHE, 0),
	GATE(CLK_ASYNCAXIM, "asyncaxim", "aclk200", E4X12_GATE_ISP1, 0,
			CLK_IGNORE_UNUSED | CLK_GET_RATE_NOCACHE, 0),
	GATE(CLK_SMMU_ISPCX, "smmu_ispcx", "aclk200", E4X12_GATE_ISP1, 4,
			CLK_IGNORE_UNUSED | CLK_GET_RATE_NOCACHE, 0),
	GATE(CLK_SPI0_ISP, "spi0_isp", "aclk200", E4X12_GATE_ISP1, 12,
			CLK_IGNORE_UNUSED | CLK_GET_RATE_NOCACHE, 0),
	GATE(CLK_SPI1_ISP, "spi1_isp", "aclk200", E4X12_GATE_ISP1, 13,
			CLK_IGNORE_UNUSED | CLK_GET_RATE_NOCACHE, 0),
};

/*
 * The parent of the fin_pll clock is selected by the XOM[0] bit. This bit
 * resides in chipid register space, outside of the clock controller memory
@@ -1504,8 +1306,6 @@ static void __init exynos4_clk_init(struct device_node *np,
			e4210_armclk_d, ARRAY_SIZE(e4210_armclk_d),
			CLK_CPU_NEEDS_DEBUG_ALT_DIV | CLK_CPU_HAS_DIV1);
	} else {
		struct resource res;

		samsung_clk_register_mux(ctx, exynos4x12_mux_clks,
			ARRAY_SIZE(exynos4x12_mux_clks));
		samsung_clk_register_div(ctx, exynos4x12_div_clks,
@@ -1516,14 +1316,6 @@ static void __init exynos4_clk_init(struct device_node *np,
			exynos4x12_fixed_factor_clks,
			ARRAY_SIZE(exynos4x12_fixed_factor_clks));

		of_address_to_resource(np, 0, &res);
		if (resource_size(&res) > 0x18000) {
			samsung_clk_register_div(ctx, exynos4x12_isp_div_clks,
				ARRAY_SIZE(exynos4x12_isp_div_clks));
			samsung_clk_register_gate(ctx, exynos4x12_isp_gate_clks,
				ARRAY_SIZE(exynos4x12_isp_gate_clks));
		}

		exynos_register_cpu_clock(ctx, CLK_ARM_CLK, "armclk",
			mout_core_p4x12[0], mout_core_p4x12[1], 0x14200,
			e4412_armclk_d, ARRAY_SIZE(e4412_armclk_d),
@@ -1532,7 +1324,17 @@ static void __init exynos4_clk_init(struct device_node *np,

	if (soc == EXYNOS4X12)
		exynos4x12_core_down_clock();
	exynos4_clk_sleep_init();

	samsung_clk_extended_sleep_init(reg_base,
			exynos4_clk_regs, ARRAY_SIZE(exynos4_clk_regs),
			src_mask_suspend, ARRAY_SIZE(src_mask_suspend));
	if (exynos4_soc == EXYNOS4210)
		samsung_clk_extended_sleep_init(reg_base,
		    exynos4210_clk_save, ARRAY_SIZE(exynos4210_clk_save),
		    src_mask_suspend_e4210, ARRAY_SIZE(src_mask_suspend_e4210));
	else
		samsung_clk_sleep_init(reg_base, exynos4x12_clk_save,
				       ARRAY_SIZE(exynos4x12_clk_save));

	samsung_clk_of_add_provider(np, ctx);

Loading