/*
* Copyright (c) 2014 Samsung Electronics Co., Ltd.
* Author: Naveen Krishna Ch <naveenkrishna.ch@gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
*/
#include <linux/clk.h>
#include <linux/clkdev.h>
#include <linux/clk-provider.h>
#include <linux/of.h>
#include "clk.h"
#include <dt-bindings/clock/exynos7-clk.h>
/* Register Offset definitions for CMU_TOPC (0x10570000) */
#define CC_PLL_LOCK 0x0000
#define BUS0_PLL_LOCK 0x0004
#define BUS1_DPLL_LOCK 0x0008
#define MFC_PLL_LOCK 0x000C
#define AUD_PLL_LOCK 0x0010
#define CC_PLL_CON0 0x0100
#define BUS0_PLL_CON0 0x0110
#define BUS1_DPLL_CON0 0x0120
#define MFC_PLL_CON0 0x0130
#define AUD_PLL_CON0 0x0140
#define MUX_SEL_TOPC0 0x0200
#define MUX_SEL_TOPC1 0x0204
#define MUX_SEL_TOPC2 0x0208
#define MUX_SEL_TOPC3 0x020C
#define DIV_TOPC0 0x0600
#define DIV_TOPC1 0x0604
#define DIV_TOPC3 0x060C
#define ENABLE_ACLK_TOPC1 0x0804
static struct samsung_fixed_factor_clock topc_fixed_factor_clks[] __initdata = {
FFACTOR(0, "ffac_topc_bus0_pll_div2", "mout_bus0_pll_ctrl", 1, 2, 0),
FFACTOR(0, "ffac_topc_bus0_pll_div4",
"ffac_topc_bus0_pll_div2", 1, 2, 0),
FFACTOR(0, "ffac_topc_bus1_pll_div2", "mout_bus1_pll_ctrl", 1, 2, 0),
FFACTOR(0, "ffac_topc_cc_pll_div2", "mout_cc_pll_ctrl", 1, 2, 0),
FFACTOR(0, "ffac_topc_mfc_pll_div2", "mout_mfc_pll_ctrl", 1, 2, 0),
};
/* List of parent clocks for Muxes in CMU_TOPC */
PNAME(mout_aud_pll_ctrl_p) = { "fin_pll", "fout_aud_pll" };
PNAME(mout_bus0_pll_ctrl_p) = { "fin_pll", "fout_bus0_pll" };
PNAME(mout_bus1_pll_ctrl_p) = { "fin_pll", "fout_bus1_pll" };
PNAME(mout_cc_pll_ctrl_p) = { "fin_pll", "fout_cc_pll" };
PNAME(mout_mfc_pll_ctrl_p) = { "fin_pll", "fout_mfc_pll" };
PNAME(mout_topc_group2) = { "mout_sclk_bus0_pll_cmuc",
"mout_sclk_bus1_pll_cmuc", "mout_sclk_cc_pll_cmuc",
"mout_sclk_mfc_pll_cmuc" };
PNAME(mout_sclk_bus0_pll_cmuc_p) = { "mout_bus0_pll_ctrl",
"ffac_topc_bus0_pll_div2", "ffac_topc_bus0_pll_div4"};
PNAME(mout_sclk_bus1_pll_cmuc_p) = { "mout_bus1_pll_ctrl",
"ffac_topc_bus1_pll_div2"};
PNAME(mout_sclk_cc_pll_cmuc_p) = { "mout_cc_pll_ctrl",
"ffac_topc_cc_pll_div2"};
PNAME(mout_sclk_mfc_pll_cmuc_p) = { "mout_mfc_pll_ctrl",
"ffac_topc_mfc_pll_div2"};
PNAME(mout_sclk_bus0_pll_out_p) = {"mout_bus0_pll_ctrl",
"ffac_topc_bus0_pll_div2"};
static unsigned long topc_clk_regs[] __initdata = {
CC_PLL_LOCK,
BUS0_PLL_LOCK,
BUS1_DPLL_LOCK,
MFC_PLL_LOCK,
AUD_PLL_LOCK,
CC_PLL_CON0,
BUS0_PLL_CON0,
BUS1_DPLL_CON0,
MFC_PLL_CON0,
AUD_PLL_CON0,
MUX_SEL_TOPC0,
MUX_SEL_TOPC1,
MUX_SEL_TOPC2,
MUX_SEL_TOPC3,
DIV_TOPC0,
DIV_TOPC1,
DIV_TOPC3,
};
static struct samsung_mux_clock topc_mux_clks[] __initdata = {
MUX(0, "mout_bus0_pll_ctrl", mout_bus0_pll_ctrl_p, MUX_SEL_TOPC0, 0, 1),
MUX(0, "mout_bus1_pll_ctrl", mout_bus1_pll_ctrl_p, MUX_SEL_TOPC0, 4, 1),
MUX(0, "mout_cc_pll_ctrl", mout_cc_pll_ctrl_p, MUX_SEL_TOPC0, 8, 1),
MUX(0, "mout_mfc_pll_ctrl", mout_mfc_pll_ctrl_p, MUX_SEL_TOPC0, 12, 1),
MUX(0, "mout_sclk_bus0_pll_cmuc", mout_sclk_bus0_pll_cmuc_p,
MUX_SEL_TOPC0, 16, 2),
MUX(0, "mout_sclk_bus1_pll_cmuc", mout_sclk_bus1_pll_cmuc_p,
MUX_SEL_TOPC0, 20, 1),
MUX(0, "mout_sclk_cc_pll_cmuc", mout_sclk_cc_pll_cmuc_p,
MUX_SEL_TOPC0, 24, 1),
MUX(0, "mout_sclk_mfc_pll_cmuc", mout_sclk_mfc_pll_cmuc_p,
MUX_SEL_TOPC0, 28, 1),
MUX(0, "mout_sclk_bus0_pll_out", mout_sclk_