diff options
author | Stephen Boyd <sboyd@codeaurora.org> | 2015-08-26 00:55:28 +0200 |
---|---|---|
committer | Stephen Boyd <sboyd@codeaurora.org> | 2015-08-26 00:55:28 +0200 |
commit | a7c602bf42f943e717eed92165ebfa6dbaba3029 (patch) | |
tree | 3c32bc1572acb102ba86c53005ca83cf0c632fd1 /drivers/clk/tegra/clk.c | |
parent | clk: qcom: Fix MSM8916 prng clock enable bit (diff) | |
parent | clk: tegra: Add the DFLL as a possible parent of the cclk_g clock (diff) | |
download | linux-a7c602bf42f943e717eed92165ebfa6dbaba3029.tar.xz linux-a7c602bf42f943e717eed92165ebfa6dbaba3029.zip |
Merge tag 'tegra-for-4.3-clk' of git://git.kernel.org/pub/scm/linux/kernel/git/tegra/linux into clk-next
clk: tegra: Changes for v4.3-rc1
This contains the DFLL driver needed to implement CPU frequency scaling
on Tegra.
Diffstat (limited to 'drivers/clk/tegra/clk.c')
-rw-r--r-- | drivers/clk/tegra/clk.c | 39 |
1 files changed, 31 insertions, 8 deletions
diff --git a/drivers/clk/tegra/clk.c b/drivers/clk/tegra/clk.c index 22aa8b18c840..2a3a4fe803d6 100644 --- a/drivers/clk/tegra/clk.c +++ b/drivers/clk/tegra/clk.c @@ -50,7 +50,6 @@ #define RST_DEVICES_L 0x004 #define RST_DEVICES_H 0x008 #define RST_DEVICES_U 0x00C -#define RST_DFLL_DVCO 0x2F4 #define RST_DEVICES_V 0x358 #define RST_DEVICES_W 0x35C #define RST_DEVICES_X 0x28C @@ -80,6 +79,11 @@ static struct clk **clks; static int clk_num; static struct clk_onecell_data clk_data; +/* Handlers for SoC-specific reset lines */ +static int (*special_reset_assert)(unsigned long); +static int (*special_reset_deassert)(unsigned long); +static unsigned int num_special_reset; + static struct tegra_clk_periph_regs periph_regs[] = { [0] = { .enb_reg = CLK_OUT_ENB_L, @@ -153,19 +157,29 @@ static int tegra_clk_rst_assert(struct reset_controller_dev *rcdev, */ tegra_read_chipid(); - writel_relaxed(BIT(id % 32), - clk_base + periph_regs[id / 32].rst_set_reg); + if (id < periph_banks * 32) { + writel_relaxed(BIT(id % 32), + clk_base + periph_regs[id / 32].rst_set_reg); + return 0; + } else if (id < periph_banks * 32 + num_special_reset) { + return special_reset_assert(id); + } - return 0; + return -EINVAL; } static int tegra_clk_rst_deassert(struct reset_controller_dev *rcdev, unsigned long id) { - writel_relaxed(BIT(id % 32), - clk_base + periph_regs[id / 32].rst_clr_reg); + if (id < periph_banks * 32) { + writel_relaxed(BIT(id % 32), + clk_base + periph_regs[id / 32].rst_clr_reg); + return 0; + } else if (id < periph_banks * 32 + num_special_reset) { + return special_reset_deassert(id); + } - return 0; + return -EINVAL; } struct tegra_clk_periph_regs *get_reg_bank(int clkid) @@ -287,10 +301,19 @@ void __init tegra_add_of_provider(struct device_node *np) of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data); rst_ctlr.of_node = np; - rst_ctlr.nr_resets = periph_banks * 32; + rst_ctlr.nr_resets = periph_banks * 32 + num_special_reset; reset_controller_register(&rst_ctlr); } +void __init tegra_init_special_resets(unsigned int num, + int (*assert)(unsigned long), + int (*deassert)(unsigned long)) +{ + num_special_reset = num; + special_reset_assert = assert; + special_reset_deassert = deassert; +} + void __init tegra_register_devclks(struct tegra_devclk *dev_clks, int num) { int i; |