Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 3c7f4fe8 authored by Michael Turquette's avatar Michael Turquette
Browse files

Merge branch 'for-v3.19/exynos-clk' of git://linuxtv.org/snawrocki/samsung into clk-next-exynos

parents 29a77b8a 932e9822
Loading
Loading
Loading
Loading
+38 −0
Original line number Diff line number Diff line
* Samsung Exynos4415 Clock Controller

The Exynos4415 clock controller generates and supplies clock to various
consumer devices within the Exynos4415 SoC.

Required properties:

- compatible: should be one of the following:
  - "samsung,exynos4415-cmu" - for the main system clocks controller
    (CMU_LEFTBUS, CMU_RIGHTBUS, CMU_TOP, CMU_CPU clock domains).
  - "samsung,exynos4415-cmu-dmc" - for the Exynos4415 SoC DRAM Memory
    Controller (DMC) domain clock controller.

- reg: physical base address of the controller and length of memory mapped
  region.

- #clock-cells: should be 1.

Each clock is assigned an identifier and client nodes can use this identifier
to specify the clock which they consume.

All available clocks are defined as preprocessor macros in
dt-bindings/clock/exynos4415.h header and can be used in device
tree sources.

Example 1: An example of a clock controller node is listed below.

	cmu: clock-controller@10030000 {
		compatible = "samsung,exynos4415-cmu";
		reg = <0x10030000 0x18000>;
		#clock-cells = <1>;
	};

	cmu-dmc: clock-controller@105C0000 {
		compatible = "samsung,exynos4415-cmu-dmc";
		reg = <0x105C0000 0x3000>;
		#clock-cells = <1>;
	};
+93 −0
Original line number Diff line number Diff line
* Samsung Exynos7 Clock Controller

Exynos7 clock controller has various blocks which are instantiated
independently from the device-tree. These clock controllers
generate and supply clocks to various hardware blocks within
the SoC.

Each clock is assigned an identifier and client nodes can use
this identifier to specify the clock which they consume. All
available clocks are defined as preprocessor macros in
dt-bindings/clock/exynos7-clk.h header and can be used in
device tree sources.

External clocks:

There are several clocks that are generated outside the SoC. It
is expected that they are defined using standard clock bindings
with following clock-output-names:

 - "fin_pll" - PLL input clock from XXTI

Required Properties for Clock Controller:

 - compatible: clock controllers will use one of the following
	compatible strings to indicate the clock controller
	functionality.

	- "samsung,exynos7-clock-topc"
	- "samsung,exynos7-clock-top0"
	- "samsung,exynos7-clock-top1"
	- "samsung,exynos7-clock-ccore"
	- "samsung,exynos7-clock-peric0"
	- "samsung,exynos7-clock-peric1"
	- "samsung,exynos7-clock-peris"
	- "samsung,exynos7-clock-fsys0"
	- "samsung,exynos7-clock-fsys1"

 - reg: physical base address of the controller and the length of
	memory mapped region.

 - #clock-cells: should be 1.

 - clocks: list of clock identifiers which are fed as the input to
	the given clock controller. Please refer the next section to
	find the input clocks for a given controller.

- clock-names: list of names of clocks which are fed as the input
	to the given clock controller.

Input clocks for top0 clock controller:
	- fin_pll
	- dout_sclk_bus0_pll
	- dout_sclk_bus1_pll
	- dout_sclk_cc_pll
	- dout_sclk_mfc_pll

Input clocks for top1 clock controller:
	- fin_pll
	- dout_sclk_bus0_pll
	- dout_sclk_bus1_pll
	- dout_sclk_cc_pll
	- dout_sclk_mfc_pll

Input clocks for ccore clock controller:
	- fin_pll
	- dout_aclk_ccore_133

Input clocks for peric0 clock controller:
	- fin_pll
	- dout_aclk_peric0_66
	- sclk_uart0

Input clocks for peric1 clock controller:
	- fin_pll
	- dout_aclk_peric1_66
	- sclk_uart1
	- sclk_uart2
	- sclk_uart3

Input clocks for peris clock controller:
	- fin_pll
	- dout_aclk_peris_66

Input clocks for fsys0 clock controller:
	- fin_pll
	- dout_aclk_fsys0_200
	- dout_sclk_mmc2

Input clocks for fsys1 clock controller:
	- fin_pll
	- dout_aclk_fsys1_200
	- dout_sclk_mmc0
	- dout_sclk_mmc1
+2 −0
Original line number Diff line number Diff line
@@ -5,6 +5,7 @@
obj-$(CONFIG_COMMON_CLK)	+= clk.o clk-pll.o
obj-$(CONFIG_SOC_EXYNOS3250)	+= clk-exynos3250.o
obj-$(CONFIG_ARCH_EXYNOS4)	+= clk-exynos4.o
obj-$(CONFIG_SOC_EXYNOS4415)	+= clk-exynos4415.o
obj-$(CONFIG_SOC_EXYNOS5250)	+= clk-exynos5250.o
obj-$(CONFIG_SOC_EXYNOS5260)	+= clk-exynos5260.o
obj-$(CONFIG_SOC_EXYNOS5410)	+= clk-exynos5410.o
@@ -12,6 +13,7 @@ obj-$(CONFIG_SOC_EXYNOS5420) += clk-exynos5420.o
obj-$(CONFIG_SOC_EXYNOS5440)	+= clk-exynos5440.o
obj-$(CONFIG_ARCH_EXYNOS)	+= clk-exynos-audss.o
obj-$(CONFIG_ARCH_EXYNOS)	+= clk-exynos-clkout.o
obj-$(CONFIG_ARCH_EXYNOS7)	+= clk-exynos7.o
obj-$(CONFIG_S3C2410_COMMON_CLK)+= clk-s3c2410.o
obj-$(CONFIG_S3C2410_COMMON_DCLK)+= clk-s3c2410-dclk.o
obj-$(CONFIG_S3C2412_COMMON_CLK)+= clk-s3c2412.o
+1142 −0

File added.

Preview size limit exceeded, changes collapsed.

+26 −159
Original line number Diff line number Diff line
@@ -11,10 +11,8 @@

#include <linux/clk.h>
#include <linux/clkdev.h>
#include <linux/clk-provider.h>
#include <linux/of.h>
#include <linux/of_address.h>
#include <linux/syscore_ops.h>

#include "clk-exynos5260.h"
#include "clk.h"
@@ -22,39 +20,6 @@

#include <dt-bindings/clock/exynos5260-clk.h>

static LIST_HEAD(clock_reg_cache_list);

struct exynos5260_clock_reg_cache {
	struct list_head node;
	void __iomem *reg_base;
	struct samsung_clk_reg_dump *rdump;
	unsigned int rd_num;
};

struct exynos5260_cmu_info {
	/* list of pll clocks and respective count */
	struct samsung_pll_clock *pll_clks;
	unsigned int nr_pll_clks;
	/* list of mux clocks and respective count */
	struct samsung_mux_clock *mux_clks;
	unsigned int nr_mux_clks;
	/* list of div clocks and respective count */
	struct samsung_div_clock *div_clks;
	unsigned int nr_div_clks;
	/* list of gate clocks and respective count */
	struct samsung_gate_clock *gate_clks;
	unsigned int nr_gate_clks;
	/* list of fixed clocks and respective count */
	struct samsung_fixed_rate_clock *fixed_clks;
	unsigned int nr_fixed_clks;
	/* total number of clocks with IDs assigned*/
	unsigned int nr_clk_ids;

	/* list and number of clocks registers */
	unsigned long *clk_regs;
	unsigned int nr_clk_regs;
};

/*
 * Applicable for all 2550 Type PLLS for Exynos5260, listed below
 * DISP_PLL, EGL_PLL, KFC_PLL, MEM_PLL, BUS_PLL, MEDIA_PLL, G3D_PLL.
@@ -113,104 +78,6 @@ static struct samsung_pll_rate_table pll2650_24mhz_tbl[] __initdata = {
	PLL_36XX_RATE(66000000, 176, 2, 5, 0),
};

#ifdef CONFIG_PM_SLEEP

static int exynos5260_clk_suspend(void)
{
	struct exynos5260_clock_reg_cache *cache;

	list_for_each_entry(cache, &clock_reg_cache_list, node)
		samsung_clk_save(cache->reg_base, cache->rdump,
				cache->rd_num);

	return 0;
}

static void exynos5260_clk_resume(void)
{
	struct exynos5260_clock_reg_cache *cache;

	list_for_each_entry(cache, &clock_reg_cache_list, node)
		samsung_clk_restore(cache->reg_base, cache->rdump,
				cache->rd_num);
}

static struct syscore_ops exynos5260_clk_syscore_ops = {
	.suspend = exynos5260_clk_suspend,
	.resume = exynos5260_clk_resume,
};

static void exynos5260_clk_sleep_init(void __iomem *reg_base,
			unsigned long *rdump,
			unsigned long nr_rdump)
{
	struct exynos5260_clock_reg_cache *reg_cache;

	reg_cache = kzalloc(sizeof(struct exynos5260_clock_reg_cache),
			GFP_KERNEL);
	if (!reg_cache)
		panic("could not allocate register cache.\n");

	reg_cache->rdump = samsung_clk_alloc_reg_dump(rdump, nr_rdump);

	if (!reg_cache->rdump)
		panic("could not allocate register dump storage.\n");

	if (list_empty(&clock_reg_cache_list))
		register_syscore_ops(&exynos5260_clk_syscore_ops);

	reg_cache->rd_num = nr_rdump;
	reg_cache->reg_base = reg_base;
	list_add_tail(&reg_cache->node, &clock_reg_cache_list);
}

#else
static void exynos5260_clk_sleep_init(void __iomem *reg_base,
			unsigned long *rdump,
			unsigned long nr_rdump){}
#endif

/*
 * Common function which registers plls, muxes, dividers and gates
 * for each CMU. It also add CMU register list to register cache.
 */

void __init exynos5260_cmu_register_one(struct device_node *np,
			struct exynos5260_cmu_info *cmu)
{
	void __iomem *reg_base;
	struct samsung_clk_provider *ctx;

	reg_base = of_iomap(np, 0);
	if (!reg_base)
		panic("%s: failed to map registers\n", __func__);

	ctx = samsung_clk_init(np, reg_base, cmu->nr_clk_ids);
	if (!ctx)
		panic("%s: unable to alllocate ctx\n", __func__);

	if (cmu->pll_clks)
		samsung_clk_register_pll(ctx, cmu->pll_clks, cmu->nr_pll_clks,
			reg_base);
	if (cmu->mux_clks)
		samsung_clk_register_mux(ctx,  cmu->mux_clks,
			cmu->nr_mux_clks);
	if (cmu->div_clks)
		samsung_clk_register_div(ctx, cmu->div_clks, cmu->nr_div_clks);
	if (cmu->gate_clks)
		samsung_clk_register_gate(ctx, cmu->gate_clks,
			cmu->nr_gate_clks);
	if (cmu->fixed_clks)
		samsung_clk_register_fixed_rate(ctx, cmu->fixed_clks,
			cmu->nr_fixed_clks);
	if (cmu->clk_regs)
		exynos5260_clk_sleep_init(reg_base, cmu->clk_regs,
			cmu->nr_clk_regs);

	samsung_clk_of_add_provider(np, ctx);
}


/* CMU_AUD */

static unsigned long aud_clk_regs[] __initdata = {
@@ -268,7 +135,7 @@ struct samsung_gate_clock aud_gate_clks[] __initdata = {

static void __init exynos5260_clk_aud_init(struct device_node *np)
{
	struct exynos5260_cmu_info cmu = {0};
	struct samsung_cmu_info cmu = {0};

	cmu.mux_clks = aud_mux_clks;
	cmu.nr_mux_clks = ARRAY_SIZE(aud_mux_clks);
@@ -280,7 +147,7 @@ static void __init exynos5260_clk_aud_init(struct device_node *np)
	cmu.clk_regs = aud_clk_regs;
	cmu.nr_clk_regs = ARRAY_SIZE(aud_clk_regs);

	exynos5260_cmu_register_one(np, &cmu);
	samsung_cmu_register_one(np, &cmu);
}

CLK_OF_DECLARE(exynos5260_clk_aud, "samsung,exynos5260-clock-aud",
@@ -458,7 +325,7 @@ struct samsung_gate_clock disp_gate_clks[] __initdata = {

static void __init exynos5260_clk_disp_init(struct device_node *np)
{
	struct exynos5260_cmu_info cmu = {0};
	struct samsung_cmu_info cmu = {0};

	cmu.mux_clks = disp_mux_clks;
	cmu.nr_mux_clks = ARRAY_SIZE(disp_mux_clks);
@@ -470,7 +337,7 @@ static void __init exynos5260_clk_disp_init(struct device_node *np)
	cmu.clk_regs = disp_clk_regs;
	cmu.nr_clk_regs = ARRAY_SIZE(disp_clk_regs);

	exynos5260_cmu_register_one(np, &cmu);
	samsung_cmu_register_one(np, &cmu);
}

CLK_OF_DECLARE(exynos5260_clk_disp, "samsung,exynos5260-clock-disp",
@@ -522,7 +389,7 @@ static struct samsung_pll_clock egl_pll_clks[] __initdata = {

static void __init exynos5260_clk_egl_init(struct device_node *np)
{
	struct exynos5260_cmu_info cmu = {0};
	struct samsung_cmu_info cmu = {0};

	cmu.pll_clks = egl_pll_clks;
	cmu.nr_pll_clks =  ARRAY_SIZE(egl_pll_clks);
@@ -534,7 +401,7 @@ static void __init exynos5260_clk_egl_init(struct device_node *np)
	cmu.clk_regs = egl_clk_regs;
	cmu.nr_clk_regs = ARRAY_SIZE(egl_clk_regs);

	exynos5260_cmu_register_one(np, &cmu);
	samsung_cmu_register_one(np, &cmu);
}

CLK_OF_DECLARE(exynos5260_clk_egl, "samsung,exynos5260-clock-egl",
@@ -624,7 +491,7 @@ struct samsung_gate_clock fsys_gate_clks[] __initdata = {

static void __init exynos5260_clk_fsys_init(struct device_node *np)
{
	struct exynos5260_cmu_info cmu = {0};
	struct samsung_cmu_info cmu = {0};

	cmu.mux_clks = fsys_mux_clks;
	cmu.nr_mux_clks = ARRAY_SIZE(fsys_mux_clks);
@@ -634,7 +501,7 @@ static void __init exynos5260_clk_fsys_init(struct device_node *np)
	cmu.clk_regs = fsys_clk_regs;
	cmu.nr_clk_regs = ARRAY_SIZE(fsys_clk_regs);

	exynos5260_cmu_register_one(np, &cmu);
	samsung_cmu_register_one(np, &cmu);
}

CLK_OF_DECLARE(exynos5260_clk_fsys, "samsung,exynos5260-clock-fsys",
@@ -713,7 +580,7 @@ struct samsung_gate_clock g2d_gate_clks[] __initdata = {

static void __init exynos5260_clk_g2d_init(struct device_node *np)
{
	struct exynos5260_cmu_info cmu = {0};
	struct samsung_cmu_info cmu = {0};

	cmu.mux_clks = g2d_mux_clks;
	cmu.nr_mux_clks = ARRAY_SIZE(g2d_mux_clks);
@@ -725,7 +592,7 @@ static void __init exynos5260_clk_g2d_init(struct device_node *np)
	cmu.clk_regs = g2d_clk_regs;
	cmu.nr_clk_regs = ARRAY_SIZE(g2d_clk_regs);

	exynos5260_cmu_register_one(np, &cmu);
	samsung_cmu_register_one(np, &cmu);
}

CLK_OF_DECLARE(exynos5260_clk_g2d, "samsung,exynos5260-clock-g2d",
@@ -774,7 +641,7 @@ static struct samsung_pll_clock g3d_pll_clks[] __initdata = {

static void __init exynos5260_clk_g3d_init(struct device_node *np)
{
	struct exynos5260_cmu_info cmu = {0};
	struct samsung_cmu_info cmu = {0};

	cmu.pll_clks = g3d_pll_clks;
	cmu.nr_pll_clks =  ARRAY_SIZE(g3d_pll_clks);
@@ -788,7 +655,7 @@ static void __init exynos5260_clk_g3d_init(struct device_node *np)
	cmu.clk_regs = g3d_clk_regs;
	cmu.nr_clk_regs = ARRAY_SIZE(g3d_clk_regs);

	exynos5260_cmu_register_one(np, &cmu);
	samsung_cmu_register_one(np, &cmu);
}

CLK_OF_DECLARE(exynos5260_clk_g3d, "samsung,exynos5260-clock-g3d",
@@ -909,7 +776,7 @@ struct samsung_gate_clock gscl_gate_clks[] __initdata = {

static void __init exynos5260_clk_gscl_init(struct device_node *np)
{
	struct exynos5260_cmu_info cmu = {0};
	struct samsung_cmu_info cmu = {0};

	cmu.mux_clks = gscl_mux_clks;
	cmu.nr_mux_clks = ARRAY_SIZE(gscl_mux_clks);
@@ -921,7 +788,7 @@ static void __init exynos5260_clk_gscl_init(struct device_node *np)
	cmu.clk_regs = gscl_clk_regs;
	cmu.nr_clk_regs = ARRAY_SIZE(gscl_clk_regs);

	exynos5260_cmu_register_one(np, &cmu);
	samsung_cmu_register_one(np, &cmu);
}

CLK_OF_DECLARE(exynos5260_clk_gscl, "samsung,exynos5260-clock-gscl",
@@ -1028,7 +895,7 @@ struct samsung_gate_clock isp_gate_clks[] __initdata = {

static void __init exynos5260_clk_isp_init(struct device_node *np)
{
	struct exynos5260_cmu_info cmu = {0};
	struct samsung_cmu_info cmu = {0};

	cmu.mux_clks = isp_mux_clks;
	cmu.nr_mux_clks = ARRAY_SIZE(isp_mux_clks);
@@ -1040,7 +907,7 @@ static void __init exynos5260_clk_isp_init(struct device_node *np)
	cmu.clk_regs = isp_clk_regs;
	cmu.nr_clk_regs = ARRAY_SIZE(isp_clk_regs);

	exynos5260_cmu_register_one(np, &cmu);
	samsung_cmu_register_one(np, &cmu);
}

CLK_OF_DECLARE(exynos5260_clk_isp, "samsung,exynos5260-clock-isp",
@@ -1092,7 +959,7 @@ static struct samsung_pll_clock kfc_pll_clks[] __initdata = {

static void __init exynos5260_clk_kfc_init(struct device_node *np)
{
	struct exynos5260_cmu_info cmu = {0};
	struct samsung_cmu_info cmu = {0};

	cmu.pll_clks = kfc_pll_clks;
	cmu.nr_pll_clks =  ARRAY_SIZE(kfc_pll_clks);
@@ -1104,7 +971,7 @@ static void __init exynos5260_clk_kfc_init(struct device_node *np)
	cmu.clk_regs = kfc_clk_regs;
	cmu.nr_clk_regs = ARRAY_SIZE(kfc_clk_regs);

	exynos5260_cmu_register_one(np, &cmu);
	samsung_cmu_register_one(np, &cmu);
}

CLK_OF_DECLARE(exynos5260_clk_kfc, "samsung,exynos5260-clock-kfc",
@@ -1148,7 +1015,7 @@ struct samsung_gate_clock mfc_gate_clks[] __initdata = {

static void __init exynos5260_clk_mfc_init(struct device_node *np)
{
	struct exynos5260_cmu_info cmu = {0};
	struct samsung_cmu_info cmu = {0};

	cmu.mux_clks = mfc_mux_clks;
	cmu.nr_mux_clks = ARRAY_SIZE(mfc_mux_clks);
@@ -1160,7 +1027,7 @@ static void __init exynos5260_clk_mfc_init(struct device_node *np)
	cmu.clk_regs = mfc_clk_regs;
	cmu.nr_clk_regs = ARRAY_SIZE(mfc_clk_regs);

	exynos5260_cmu_register_one(np, &cmu);
	samsung_cmu_register_one(np, &cmu);
}

CLK_OF_DECLARE(exynos5260_clk_mfc, "samsung,exynos5260-clock-mfc",
@@ -1295,7 +1162,7 @@ static struct samsung_pll_clock mif_pll_clks[] __initdata = {

static void __init exynos5260_clk_mif_init(struct device_node *np)
{
	struct exynos5260_cmu_info cmu = {0};
	struct samsung_cmu_info cmu = {0};

	cmu.pll_clks = mif_pll_clks;
	cmu.nr_pll_clks =  ARRAY_SIZE(mif_pll_clks);
@@ -1309,7 +1176,7 @@ static void __init exynos5260_clk_mif_init(struct device_node *np)
	cmu.clk_regs = mif_clk_regs;
	cmu.nr_clk_regs = ARRAY_SIZE(mif_clk_regs);

	exynos5260_cmu_register_one(np, &cmu);
	samsung_cmu_register_one(np, &cmu);
}

CLK_OF_DECLARE(exynos5260_clk_mif, "samsung,exynos5260-clock-mif",
@@ -1503,7 +1370,7 @@ struct samsung_gate_clock peri_gate_clks[] __initdata = {

static void __init exynos5260_clk_peri_init(struct device_node *np)
{
	struct exynos5260_cmu_info cmu = {0};
	struct samsung_cmu_info cmu = {0};

	cmu.mux_clks = peri_mux_clks;
	cmu.nr_mux_clks = ARRAY_SIZE(peri_mux_clks);
@@ -1515,7 +1382,7 @@ static void __init exynos5260_clk_peri_init(struct device_node *np)
	cmu.clk_regs = peri_clk_regs;
	cmu.nr_clk_regs = ARRAY_SIZE(peri_clk_regs);

	exynos5260_cmu_register_one(np, &cmu);
	samsung_cmu_register_one(np, &cmu);
}

CLK_OF_DECLARE(exynos5260_clk_peri, "samsung,exynos5260-clock-peri",
@@ -1959,7 +1826,7 @@ static struct samsung_pll_clock top_pll_clks[] __initdata = {

static void __init exynos5260_clk_top_init(struct device_node *np)
{
	struct exynos5260_cmu_info cmu = {0};
	struct samsung_cmu_info cmu = {0};

	cmu.pll_clks = top_pll_clks;
	cmu.nr_pll_clks =  ARRAY_SIZE(top_pll_clks);
@@ -1975,7 +1842,7 @@ static void __init exynos5260_clk_top_init(struct device_node *np)
	cmu.clk_regs = top_clk_regs;
	cmu.nr_clk_regs = ARRAY_SIZE(top_clk_regs);

	exynos5260_cmu_register_one(np, &cmu);
	samsung_cmu_register_one(np, &cmu);
}

CLK_OF_DECLARE(exynos5260_clk_top, "samsung,exynos5260-clock-top",
Loading