Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 6e1ee9b1 authored by Mike Turquette's avatar Mike Turquette
Browse files

Merge tag 'renesas-clock-for-v3.14' of...

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
parents a5d37d22 92ca6a8c
Loading
Loading
Loading
Loading
+98 −0
Original line number Original line Diff line number Diff line
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 −1
Original line number Original line Diff line number Diff line
obj-$(CONFIG_ARCH_EMEV2)		+= clk-emev2.o
obj-$(CONFIG_ARCH_R8A7790)		+= clk-rcar-gen2.o
obj-$(CONFIG_ARCH_R8A7790)		+= clk-rcar-gen2.o
obj-$(CONFIG_ARCH_R8A7791)		+= 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-div6.o
obj-$(CONFIG_ARCH_SHMOBILE_MULTI)	+= clk-mstp.o
obj-$(CONFIG_ARCH_SHMOBILE_MULTI)	+= clk-mstp.o

# for emply built-in.o
# for emply built-in.o
obj-n	:= dummy
obj-n	:= dummy
+104 −0
Original line number Original line Diff line number Diff line
/*
 * 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);