-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
clk: tango4: clkgen driver for Tango4 platforms
Provide support for Sigma Designs Tango4 clock generator. NOTE: This driver is incompatible with Tango3 clkgen. Signed-off-by: Marc Gonzalez <marc_gonzalez@sigmadesigns.com> [sboyd@codeaurora.org: Add kernel.h include for panic/sprintf] Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
- Loading branch information
Marc Gonzalez
authored and
Stephen Boyd
committed
Nov 16, 2015
1 parent
a085f87
commit ed12dfc
Showing
3 changed files
with
85 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
* Sigma Designs Tango4 Clock Generator | ||
|
||
The Tango4 clock generator outputs cpu_clk and sys_clk (the latter is used | ||
for RAM and various peripheral devices). The clock binding described here | ||
is applicable to all Tango4 SoCs. | ||
|
||
Required Properties: | ||
|
||
- compatible: should be "sigma,tango4-clkgen". | ||
- reg: physical base address of the device and length of memory mapped region. | ||
- clocks: phandle of the input clock (crystal oscillator). | ||
- clock-output-names: should be "cpuclk" and "sysclk". | ||
- #clock-cells: should be set to 1. | ||
|
||
Example: | ||
|
||
clkgen: clkgen@10000 { | ||
compatible = "sigma,tango4-clkgen"; | ||
reg = <0x10000 0x40>; | ||
clocks = <&xtal>; | ||
clock-output-names = "cpuclk", "sysclk"; | ||
#clock-cells = <1>; | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,61 @@ | ||
#include <linux/kernel.h> | ||
#include <linux/clk-provider.h> | ||
#include <linux/of_address.h> | ||
#include <linux/init.h> | ||
#include <linux/io.h> | ||
|
||
static struct clk *out[2]; | ||
static struct clk_onecell_data clk_data = { out, 2 }; | ||
|
||
#define SYSCLK_CTRL 0x20 | ||
#define CPUCLK_CTRL 0x24 | ||
#define LEGACY_DIV 0x3c | ||
|
||
#define PLL_N(val) (((val) >> 0) & 0x7f) | ||
#define PLL_K(val) (((val) >> 13) & 0x7) | ||
#define PLL_M(val) (((val) >> 16) & 0x7) | ||
#define DIV_INDEX(val) (((val) >> 8) & 0xf) | ||
|
||
static void __init make_pll(int idx, const char *parent, void __iomem *base) | ||
{ | ||
char name[8]; | ||
u32 val, mul, div; | ||
|
||
sprintf(name, "pll%d", idx); | ||
val = readl_relaxed(base + idx*8); | ||
mul = PLL_N(val) + 1; | ||
div = (PLL_M(val) + 1) << PLL_K(val); | ||
clk_register_fixed_factor(NULL, name, parent, 0, mul, div); | ||
} | ||
|
||
static int __init get_div(void __iomem *base) | ||
{ | ||
u8 sysclk_tab[16] = { 2, 4, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4 }; | ||
int idx = DIV_INDEX(readl_relaxed(base + LEGACY_DIV)); | ||
|
||
return sysclk_tab[idx]; | ||
} | ||
|
||
static void __init tango4_clkgen_setup(struct device_node *np) | ||
{ | ||
int div, ret; | ||
void __iomem *base = of_iomap(np, 0); | ||
const char *parent = of_clk_get_parent_name(np, 0); | ||
|
||
if (!base) | ||
panic("%s: invalid address\n", np->full_name); | ||
|
||
make_pll(0, parent, base); | ||
make_pll(1, parent, base); | ||
|
||
out[0] = clk_register_divider(NULL, "cpuclk", "pll0", 0, | ||
base + CPUCLK_CTRL, 8, 8, CLK_DIVIDER_ONE_BASED, NULL); | ||
|
||
div = readl_relaxed(base + SYSCLK_CTRL) & BIT(23) ? get_div(base) : 4; | ||
out[1] = clk_register_fixed_factor(NULL, "sysclk", "pll1", 0, 1, div); | ||
|
||
ret = of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data); | ||
if (IS_ERR(out[0]) || IS_ERR(out[1]) || ret < 0) | ||
panic("%s: clk registration failed\n", np->full_name); | ||
} | ||
CLK_OF_DECLARE(tango4_clkgen, "sigma,tango4-clkgen", tango4_clkgen_setup); |