mirror of
https://github.com/torvalds/linux.git
synced 2024-11-07 12:41:55 +00:00
Renesas ARM based SoC Clock updates for v3.14
Add support for using emev2 SMU clocks with DT -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.14 (GNU/Linux) iQIcBAABAgAGBQJSt40hAAoJENfPZGlqN0++JzgP/1E4U6AovB3HxLUvyp6nT4oW xwkPRfAMxiZRWuEi8QnZSBa6XxrAyublAisuZ+5QXFbQDwAbLpPuX/eNZ5sThCqp L4/msoptAUVWk2fiHx/wiTxJBhBH+loDkShAq6SooqGrSg1oP7uhq2WJrhK60XHx GTUgLFDSr7Cjm9yznOYKn74iYiWh5ywv0rIqnpbdjd098Fwv0lC0YcLKq4eXS8+u CBzYgkaezZ1YDs/rsvGiyJPvHhmUnDQ+mo9fMoYSKZ+IR0RWc84vH+5aWuZ8qYZB AtuQSpJxBD6BFRuR+JDNSH1fAnzTyEDZasyEB8mxr3n8qnE1MKkhcxiLbuHUWVeu pVj7dShut+8ovPOMGiaJ4k32D6aQlnSMx99fmxBscBNXcs9dyCJxztpPLMc09Et9 HhMKwmfhzHTyEbfLRAr7zVARcyjjWAd1OnoDVINWB1FBxJH9rMSNeBIjqIphm/Cm H/z1n+Z+DVexClvpayona2eL/TEFmPefPKCXl5cjCmUOwJsyZ7UPmCxMA6srBh6F wYH2zQT5GfbqDx8643RWXxIovTkUPsiiWR4tIydjB9fCV+pg/ZGkKxnzq4nsAkl1 zY7S5SeYYYSMhRngIBsHpXY9JWItdLVw3vC9yybk+OXm/Q+cXIn/DBcIQsDzdAcQ EcmF19/7VTKoeluK99zH =NhhY -----END PGP SIGNATURE----- Merge tag 'renesas-clock-for-v3.14' of git://git.kernel.org/pub/scm/linux/kernel/git/horms/renesas into clk-next-shmobile2 Renesas ARM based SoC Clock updates for v3.14 Add support for using emev2 SMU clocks with DT
This commit is contained in:
commit
6e1ee9b180
98
Documentation/devicetree/bindings/clock/emev2-clock.txt
Normal file
98
Documentation/devicetree/bindings/clock/emev2-clock.txt
Normal file
@ -0,0 +1,98 @@
|
||||
Device tree Clock bindings for Renesas EMMA Mobile EV2
|
||||
|
||||
This binding uses the common clock binding.
|
||||
|
||||
* SMU
|
||||
System Management Unit described in user's manual R19UH0037EJ1000_SMU.
|
||||
This is not a clock provider, but clocks under SMU depend on it.
|
||||
|
||||
Required properties:
|
||||
- compatible: Should be "renesas,emev2-smu"
|
||||
- reg: Address and Size of SMU registers
|
||||
|
||||
* SMU_CLKDIV
|
||||
Function block with an input mux and a divider, which corresponds to
|
||||
"Serial clock generator" in fig."Clock System Overview" of the manual,
|
||||
and "xxx frequency division setting register" (XXXCLKDIV) registers.
|
||||
This makes internal (neither input nor output) clock that is provided
|
||||
to input of xxxGCLK block.
|
||||
|
||||
Required properties:
|
||||
- compatible: Should be "renesas,emev2-smu-clkdiv"
|
||||
- reg: Byte offset from SMU base and Bit position in the register
|
||||
- clocks: Parent clocks. Input clocks as described in clock-bindings.txt
|
||||
- #clock-cells: Should be <0>
|
||||
|
||||
* SMU_GCLK
|
||||
Clock gating node shown as "Clock stop processing block" in the
|
||||
fig."Clock System Overview" of the manual.
|
||||
Registers are "xxx clock gate control register" (XXXGCLKCTRL).
|
||||
|
||||
Required properties:
|
||||
- compatible: Should be "renesas,emev2-smu-gclk"
|
||||
- reg: Byte offset from SMU base and Bit position in the register
|
||||
- clocks: Input clock as described in clock-bindings.txt
|
||||
- #clock-cells: Should be <0>
|
||||
|
||||
Example of provider:
|
||||
|
||||
usia_u0_sclkdiv: usia_u0_sclkdiv {
|
||||
compatible = "renesas,emev2-smu-clkdiv";
|
||||
reg = <0x610 0>;
|
||||
clocks = <&pll3_fo>, <&pll4_fo>, <&pll1_fo>, <&osc1_fo>;
|
||||
#clock-cells = <0>;
|
||||
};
|
||||
|
||||
usia_u0_sclk: usia_u0_sclk {
|
||||
compatible = "renesas,emev2-smu-gclk";
|
||||
reg = <0x4a0 1>;
|
||||
clocks = <&usia_u0_sclkdiv>;
|
||||
#clock-cells = <0>;
|
||||
};
|
||||
|
||||
Example of consumer:
|
||||
|
||||
uart@e1020000 {
|
||||
compatible = "renesas,em-uart";
|
||||
reg = <0xe1020000 0x38>;
|
||||
interrupts = <0 8 0>;
|
||||
clocks = <&usia_u0_sclk>;
|
||||
clock-names = "sclk";
|
||||
};
|
||||
|
||||
Example of clock-tree description:
|
||||
|
||||
This describes a clock path in the clock tree
|
||||
c32ki -> pll3_fo -> usia_u0_sclkdiv -> usia_u0_sclk
|
||||
|
||||
smu@e0110000 {
|
||||
compatible = "renesas,emev2-smu";
|
||||
reg = <0xe0110000 0x10000>;
|
||||
#address-cells = <2>;
|
||||
#size-cells = <0>;
|
||||
|
||||
c32ki: c32ki {
|
||||
compatible = "fixed-clock";
|
||||
clock-frequency = <32768>;
|
||||
#clock-cells = <0>;
|
||||
};
|
||||
pll3_fo: pll3_fo {
|
||||
compatible = "fixed-factor-clock";
|
||||
clocks = <&c32ki>;
|
||||
clock-div = <1>;
|
||||
clock-mult = <7000>;
|
||||
#clock-cells = <0>;
|
||||
};
|
||||
usia_u0_sclkdiv: usia_u0_sclkdiv {
|
||||
compatible = "renesas,emev2-smu-clkdiv";
|
||||
reg = <0x610 0>;
|
||||
clocks = <&pll3_fo>;
|
||||
#clock-cells = <0>;
|
||||
};
|
||||
usia_u0_sclk: usia_u0_sclk {
|
||||
compatible = "renesas,emev2-smu-gclk";
|
||||
reg = <0x4a0 1>;
|
||||
clocks = <&usia_u0_sclkdiv>;
|
||||
#clock-cells = <0>;
|
||||
};
|
||||
};
|
@ -1,7 +1,7 @@
|
||||
obj-$(CONFIG_ARCH_EMEV2) += clk-emev2.o
|
||||
obj-$(CONFIG_ARCH_R8A7790) += clk-rcar-gen2.o
|
||||
obj-$(CONFIG_ARCH_R8A7791) += clk-rcar-gen2.o
|
||||
obj-$(CONFIG_ARCH_SHMOBILE_MULTI) += clk-div6.o
|
||||
obj-$(CONFIG_ARCH_SHMOBILE_MULTI) += clk-mstp.o
|
||||
|
||||
# for emply built-in.o
|
||||
obj-n := dummy
|
||||
|
104
drivers/clk/shmobile/clk-emev2.c
Normal file
104
drivers/clk/shmobile/clk-emev2.c
Normal file
@ -0,0 +1,104 @@
|
||||
/*
|
||||
* EMMA Mobile EV2 common clock framework support
|
||||
*
|
||||
* Copyright (C) 2013 Takashi Yoshii <takashi.yoshii.ze@renesas.com>
|
||||
* Copyright (C) 2012 Magnus Damm
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; version 2 of the License.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
#include <linux/clk-provider.h>
|
||||
#include <linux/clkdev.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/of_address.h>
|
||||
|
||||
/* EMEV2 SMU registers */
|
||||
#define USIAU0_RSTCTRL 0x094
|
||||
#define USIBU1_RSTCTRL 0x0ac
|
||||
#define USIBU2_RSTCTRL 0x0b0
|
||||
#define USIBU3_RSTCTRL 0x0b4
|
||||
#define STI_RSTCTRL 0x124
|
||||
#define STI_CLKSEL 0x688
|
||||
|
||||
static DEFINE_SPINLOCK(lock);
|
||||
|
||||
/* not pretty, but hey */
|
||||
void __iomem *smu_base;
|
||||
|
||||
static void __init emev2_smu_write(unsigned long value, int offs)
|
||||
{
|
||||
BUG_ON(!smu_base || (offs >= PAGE_SIZE));
|
||||
writel_relaxed(value, smu_base + offs);
|
||||
}
|
||||
|
||||
static const struct of_device_id smu_id[] __initconst = {
|
||||
{ .compatible = "renesas,emev2-smu", },
|
||||
{},
|
||||
};
|
||||
|
||||
static void __init emev2_smu_init(void)
|
||||
{
|
||||
struct device_node *np;
|
||||
|
||||
np = of_find_matching_node(NULL, smu_id);
|
||||
BUG_ON(!np);
|
||||
smu_base = of_iomap(np, 0);
|
||||
BUG_ON(!smu_base);
|
||||
of_node_put(np);
|
||||
|
||||
/* setup STI timer to run on 32.768 kHz and deassert reset */
|
||||
emev2_smu_write(0, STI_CLKSEL);
|
||||
emev2_smu_write(1, STI_RSTCTRL);
|
||||
|
||||
/* deassert reset for UART0->UART3 */
|
||||
emev2_smu_write(2, USIAU0_RSTCTRL);
|
||||
emev2_smu_write(2, USIBU1_RSTCTRL);
|
||||
emev2_smu_write(2, USIBU2_RSTCTRL);
|
||||
emev2_smu_write(2, USIBU3_RSTCTRL);
|
||||
}
|
||||
|
||||
static void __init emev2_smu_clkdiv_init(struct device_node *np)
|
||||
{
|
||||
u32 reg[2];
|
||||
struct clk *clk;
|
||||
const char *parent_name = of_clk_get_parent_name(np, 0);
|
||||
if (WARN_ON(of_property_read_u32_array(np, "reg", reg, 2)))
|
||||
return;
|
||||
if (!smu_base)
|
||||
emev2_smu_init();
|
||||
clk = clk_register_divider(NULL, np->name, parent_name, 0,
|
||||
smu_base + reg[0], reg[1], 8, 0, &lock);
|
||||
of_clk_add_provider(np, of_clk_src_simple_get, clk);
|
||||
clk_register_clkdev(clk, np->name, NULL);
|
||||
pr_debug("## %s %s %p\n", __func__, np->name, clk);
|
||||
}
|
||||
CLK_OF_DECLARE(emev2_smu_clkdiv, "renesas,emev2-smu-clkdiv",
|
||||
emev2_smu_clkdiv_init);
|
||||
|
||||
static void __init emev2_smu_gclk_init(struct device_node *np)
|
||||
{
|
||||
u32 reg[2];
|
||||
struct clk *clk;
|
||||
const char *parent_name = of_clk_get_parent_name(np, 0);
|
||||
if (WARN_ON(of_property_read_u32_array(np, "reg", reg, 2)))
|
||||
return;
|
||||
if (!smu_base)
|
||||
emev2_smu_init();
|
||||
clk = clk_register_gate(NULL, np->name, parent_name, 0,
|
||||
smu_base + reg[0], reg[1], 0, &lock);
|
||||
of_clk_add_provider(np, of_clk_src_simple_get, clk);
|
||||
clk_register_clkdev(clk, np->name, NULL);
|
||||
pr_debug("## %s %s %p\n", __func__, np->name, clk);
|
||||
}
|
||||
CLK_OF_DECLARE(emev2_smu_gclk, "renesas,emev2-smu-gclk", emev2_smu_gclk_init);
|
Loading…
Reference in New Issue
Block a user