summaryrefslogtreecommitdiff
path: root/drivers/clk/samsung/clk-exynos5420.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/clk/samsung/clk-exynos5420.c')
-rw-r--r--drivers/clk/samsung/clk-exynos5420.c61
1 files changed, 60 insertions, 1 deletions
diff --git a/drivers/clk/samsung/clk-exynos5420.c b/drivers/clk/samsung/clk-exynos5420.c
index a4e6cc782e5c..848d602efc06 100644
--- a/drivers/clk/samsung/clk-exynos5420.c
+++ b/drivers/clk/samsung/clk-exynos5420.c
@@ -28,6 +28,7 @@
#define GATE_BUS_CPU 0x700
#define GATE_SCLK_CPU 0x800
#define CLKOUT_CMU_CPU 0xa00
+#define SRC_MASK_CPERI 0x4300
#define GATE_IP_G2D 0x8800
#define CPLL_LOCK 0x10020
#define DPLL_LOCK 0x10030
@@ -70,6 +71,8 @@
#define SRC_TOP11 0x10284
#define SRC_TOP12 0x10288
#define SRC_TOP13 0x1028c /* 5800 specific */
+#define SRC_MASK_TOP0 0x10300
+#define SRC_MASK_TOP1 0x10304
#define SRC_MASK_TOP2 0x10308
#define SRC_MASK_TOP7 0x1031c
#define SRC_MASK_DISP10 0x1032c
@@ -77,6 +80,7 @@
#define SRC_MASK_FSYS 0x10340
#define SRC_MASK_PERIC0 0x10350
#define SRC_MASK_PERIC1 0x10354
+#define SRC_MASK_ISP 0x10370
#define DIV_TOP0 0x10500
#define DIV_TOP1 0x10504
#define DIV_TOP2 0x10508
@@ -98,6 +102,7 @@
#define DIV2_RATIO0 0x10590
#define DIV4_RATIO 0x105a0
#define GATE_BUS_TOP 0x10700
+#define GATE_BUS_DISP1 0x10728
#define GATE_BUS_GEN 0x1073c
#define GATE_BUS_FSYS0 0x10740
#define GATE_BUS_FSYS2 0x10748
@@ -190,6 +195,10 @@ static unsigned long exynos5x_clk_regs[] __initdata = {
SRC_MASK_FSYS,
SRC_MASK_PERIC0,
SRC_MASK_PERIC1,
+ SRC_MASK_TOP0,
+ SRC_MASK_TOP1,
+ SRC_MASK_MAU,
+ SRC_MASK_ISP,
SRC_ISP,
DIV_TOP0,
DIV_TOP1,
@@ -208,6 +217,7 @@ static unsigned long exynos5x_clk_regs[] __initdata = {
SCLK_DIV_ISP1,
DIV2_RATIO0,
DIV4_RATIO,
+ GATE_BUS_DISP1,
GATE_BUS_TOP,
GATE_BUS_GEN,
GATE_BUS_FSYS0,
@@ -249,6 +259,22 @@ static unsigned long exynos5800_clk_regs[] __initdata = {
GATE_IP_CAM,
};
+static const struct samsung_clk_reg_dump exynos5420_set_clksrc[] = {
+ { .offset = SRC_MASK_CPERI, .value = 0xffffffff, },
+ { .offset = SRC_MASK_TOP0, .value = 0x11111111, },
+ { .offset = SRC_MASK_TOP1, .value = 0x11101111, },
+ { .offset = SRC_MASK_TOP2, .value = 0x11111110, },
+ { .offset = SRC_MASK_TOP7, .value = 0x00111100, },
+ { .offset = SRC_MASK_DISP10, .value = 0x11111110, },
+ { .offset = SRC_MASK_MAU, .value = 0x10000000, },
+ { .offset = SRC_MASK_FSYS, .value = 0x11111110, },
+ { .offset = SRC_MASK_PERIC0, .value = 0x11111110, },
+ { .offset = SRC_MASK_PERIC1, .value = 0x11111100, },
+ { .offset = SRC_MASK_ISP, .value = 0x11111000, },
+ { .offset = GATE_BUS_DISP1, .value = 0xffffffff, },
+ { .offset = GATE_IP_PERIC, .value = 0xffffffff, },
+};
+
static int exynos5420_clk_suspend(void)
{
samsung_clk_save(reg_base, exynos5x_save,
@@ -258,6 +284,9 @@ static int exynos5420_clk_suspend(void)
samsung_clk_save(reg_base, exynos5800_save,
ARRAY_SIZE(exynos5800_clk_regs));
+ samsung_clk_restore(reg_base, exynos5420_set_clksrc,
+ ARRAY_SIZE(exynos5420_set_clksrc));
+
return 0;
}
@@ -1169,6 +1198,28 @@ static struct samsung_gate_clock exynos5x_gate_clks[] __initdata = {
GATE(CLK_G3D, "g3d", "mout_user_aclk_g3d", GATE_IP_G3D, 9, 0, 0),
};
+static const struct samsung_pll_rate_table exynos5420_pll2550x_24mhz_tbl[] = {
+ PLL_35XX_RATE(2000000000, 250, 3, 0),
+ PLL_35XX_RATE(1900000000, 475, 6, 0),
+ PLL_35XX_RATE(1800000000, 225, 3, 0),
+ PLL_35XX_RATE(1700000000, 425, 6, 0),
+ PLL_35XX_RATE(1600000000, 200, 3, 0),
+ PLL_35XX_RATE(1500000000, 250, 4, 0),
+ PLL_35XX_RATE(1400000000, 175, 3, 0),
+ PLL_35XX_RATE(1300000000, 325, 6, 0),
+ PLL_35XX_RATE(1200000000, 200, 2, 1),
+ PLL_35XX_RATE(1100000000, 275, 3, 1),
+ PLL_35XX_RATE(1000000000, 250, 3, 1),
+ PLL_35XX_RATE(900000000, 150, 2, 1),
+ PLL_35XX_RATE(800000000, 200, 3, 1),
+ PLL_35XX_RATE(700000000, 175, 3, 1),
+ PLL_35XX_RATE(600000000, 200, 2, 2),
+ PLL_35XX_RATE(500000000, 250, 3, 2),
+ PLL_35XX_RATE(400000000, 200, 3, 2),
+ PLL_35XX_RATE(300000000, 200, 2, 3),
+ PLL_35XX_RATE(200000000, 200, 3, 3),
+};
+
static struct samsung_pll_clock exynos5x_plls[nr_plls] __initdata = {
[apll] = PLL(pll_2550, CLK_FOUT_APLL, "fout_apll", "fin_pll", APLL_LOCK,
APLL_CON0, NULL),
@@ -1194,7 +1245,7 @@ static struct samsung_pll_clock exynos5x_plls[nr_plls] __initdata = {
KPLL_CON0, NULL),
};
-static struct of_device_id ext_clk_match[] __initdata = {
+static const struct of_device_id ext_clk_match[] __initconst = {
{ .compatible = "samsung,exynos5420-oscclk", .data = (void *)0, },
{ },
};
@@ -1222,6 +1273,12 @@ static void __init exynos5x_clk_init(struct device_node *np,
samsung_clk_of_register_fixed_ext(ctx, exynos5x_fixed_rate_ext_clks,
ARRAY_SIZE(exynos5x_fixed_rate_ext_clks),
ext_clk_match);
+
+ if (_get_rate("fin_pll") == 24 * MHZ) {
+ exynos5x_plls[apll].rate_table = exynos5420_pll2550x_24mhz_tbl;
+ exynos5x_plls[kpll].rate_table = exynos5420_pll2550x_24mhz_tbl;
+ }
+
samsung_clk_register_pll(ctx, exynos5x_plls, ARRAY_SIZE(exynos5x_plls),
reg_base);
samsung_clk_register_fixed_rate(ctx, exynos5x_fixed_rate_clks,
@@ -1253,6 +1310,8 @@ static void __init exynos5x_clk_init(struct device_node *np,
}
exynos5420_clk_sleep_init();
+
+ samsung_clk_of_add_provider(np, ctx);
}
static void __init exynos5420_clk_init(struct device_node *np)