Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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

+203 -1
+98
Documentation/devicetree/bindings/clock/emev2-clock.txt
··· 1 + Device tree Clock bindings for Renesas EMMA Mobile EV2 2 + 3 + This binding uses the common clock binding. 4 + 5 + * SMU 6 + System Management Unit described in user's manual R19UH0037EJ1000_SMU. 7 + This is not a clock provider, but clocks under SMU depend on it. 8 + 9 + Required properties: 10 + - compatible: Should be "renesas,emev2-smu" 11 + - reg: Address and Size of SMU registers 12 + 13 + * SMU_CLKDIV 14 + Function block with an input mux and a divider, which corresponds to 15 + "Serial clock generator" in fig."Clock System Overview" of the manual, 16 + and "xxx frequency division setting register" (XXXCLKDIV) registers. 17 + This makes internal (neither input nor output) clock that is provided 18 + to input of xxxGCLK block. 19 + 20 + Required properties: 21 + - compatible: Should be "renesas,emev2-smu-clkdiv" 22 + - reg: Byte offset from SMU base and Bit position in the register 23 + - clocks: Parent clocks. Input clocks as described in clock-bindings.txt 24 + - #clock-cells: Should be <0> 25 + 26 + * SMU_GCLK 27 + Clock gating node shown as "Clock stop processing block" in the 28 + fig."Clock System Overview" of the manual. 29 + Registers are "xxx clock gate control register" (XXXGCLKCTRL). 30 + 31 + Required properties: 32 + - compatible: Should be "renesas,emev2-smu-gclk" 33 + - reg: Byte offset from SMU base and Bit position in the register 34 + - clocks: Input clock as described in clock-bindings.txt 35 + - #clock-cells: Should be <0> 36 + 37 + Example of provider: 38 + 39 + usia_u0_sclkdiv: usia_u0_sclkdiv { 40 + compatible = "renesas,emev2-smu-clkdiv"; 41 + reg = <0x610 0>; 42 + clocks = <&pll3_fo>, <&pll4_fo>, <&pll1_fo>, <&osc1_fo>; 43 + #clock-cells = <0>; 44 + }; 45 + 46 + usia_u0_sclk: usia_u0_sclk { 47 + compatible = "renesas,emev2-smu-gclk"; 48 + reg = <0x4a0 1>; 49 + clocks = <&usia_u0_sclkdiv>; 50 + #clock-cells = <0>; 51 + }; 52 + 53 + Example of consumer: 54 + 55 + uart@e1020000 { 56 + compatible = "renesas,em-uart"; 57 + reg = <0xe1020000 0x38>; 58 + interrupts = <0 8 0>; 59 + clocks = <&usia_u0_sclk>; 60 + clock-names = "sclk"; 61 + }; 62 + 63 + Example of clock-tree description: 64 + 65 + This describes a clock path in the clock tree 66 + c32ki -> pll3_fo -> usia_u0_sclkdiv -> usia_u0_sclk 67 + 68 + smu@e0110000 { 69 + compatible = "renesas,emev2-smu"; 70 + reg = <0xe0110000 0x10000>; 71 + #address-cells = <2>; 72 + #size-cells = <0>; 73 + 74 + c32ki: c32ki { 75 + compatible = "fixed-clock"; 76 + clock-frequency = <32768>; 77 + #clock-cells = <0>; 78 + }; 79 + pll3_fo: pll3_fo { 80 + compatible = "fixed-factor-clock"; 81 + clocks = <&c32ki>; 82 + clock-div = <1>; 83 + clock-mult = <7000>; 84 + #clock-cells = <0>; 85 + }; 86 + usia_u0_sclkdiv: usia_u0_sclkdiv { 87 + compatible = "renesas,emev2-smu-clkdiv"; 88 + reg = <0x610 0>; 89 + clocks = <&pll3_fo>; 90 + #clock-cells = <0>; 91 + }; 92 + usia_u0_sclk: usia_u0_sclk { 93 + compatible = "renesas,emev2-smu-gclk"; 94 + reg = <0x4a0 1>; 95 + clocks = <&usia_u0_sclkdiv>; 96 + #clock-cells = <0>; 97 + }; 98 + };
+1 -1
drivers/clk/shmobile/Makefile
··· 1 + obj-$(CONFIG_ARCH_EMEV2) += clk-emev2.o 1 2 obj-$(CONFIG_ARCH_R8A7790) += clk-rcar-gen2.o 2 3 obj-$(CONFIG_ARCH_R8A7791) += clk-rcar-gen2.o 3 4 obj-$(CONFIG_ARCH_SHMOBILE_MULTI) += clk-div6.o 4 5 obj-$(CONFIG_ARCH_SHMOBILE_MULTI) += clk-mstp.o 5 - 6 6 # for emply built-in.o 7 7 obj-n := dummy
+104
drivers/clk/shmobile/clk-emev2.c
··· 1 + /* 2 + * EMMA Mobile EV2 common clock framework support 3 + * 4 + * Copyright (C) 2013 Takashi Yoshii <takashi.yoshii.ze@renesas.com> 5 + * Copyright (C) 2012 Magnus Damm 6 + * 7 + * This program is free software; you can redistribute it and/or modify 8 + * it under the terms of the GNU General Public License as published by 9 + * the Free Software Foundation; version 2 of the License. 10 + * 11 + * This program is distributed in the hope that it will be useful, 12 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 + * GNU General Public License for more details. 15 + * 16 + * You should have received a copy of the GNU General Public License 17 + * along with this program; if not, write to the Free Software 18 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 19 + */ 20 + #include <linux/clk-provider.h> 21 + #include <linux/clkdev.h> 22 + #include <linux/io.h> 23 + #include <linux/of.h> 24 + #include <linux/of_address.h> 25 + 26 + /* EMEV2 SMU registers */ 27 + #define USIAU0_RSTCTRL 0x094 28 + #define USIBU1_RSTCTRL 0x0ac 29 + #define USIBU2_RSTCTRL 0x0b0 30 + #define USIBU3_RSTCTRL 0x0b4 31 + #define STI_RSTCTRL 0x124 32 + #define STI_CLKSEL 0x688 33 + 34 + static DEFINE_SPINLOCK(lock); 35 + 36 + /* not pretty, but hey */ 37 + void __iomem *smu_base; 38 + 39 + static void __init emev2_smu_write(unsigned long value, int offs) 40 + { 41 + BUG_ON(!smu_base || (offs >= PAGE_SIZE)); 42 + writel_relaxed(value, smu_base + offs); 43 + } 44 + 45 + static const struct of_device_id smu_id[] __initconst = { 46 + { .compatible = "renesas,emev2-smu", }, 47 + {}, 48 + }; 49 + 50 + static void __init emev2_smu_init(void) 51 + { 52 + struct device_node *np; 53 + 54 + np = of_find_matching_node(NULL, smu_id); 55 + BUG_ON(!np); 56 + smu_base = of_iomap(np, 0); 57 + BUG_ON(!smu_base); 58 + of_node_put(np); 59 + 60 + /* setup STI timer to run on 32.768 kHz and deassert reset */ 61 + emev2_smu_write(0, STI_CLKSEL); 62 + emev2_smu_write(1, STI_RSTCTRL); 63 + 64 + /* deassert reset for UART0->UART3 */ 65 + emev2_smu_write(2, USIAU0_RSTCTRL); 66 + emev2_smu_write(2, USIBU1_RSTCTRL); 67 + emev2_smu_write(2, USIBU2_RSTCTRL); 68 + emev2_smu_write(2, USIBU3_RSTCTRL); 69 + } 70 + 71 + static void __init emev2_smu_clkdiv_init(struct device_node *np) 72 + { 73 + u32 reg[2]; 74 + struct clk *clk; 75 + const char *parent_name = of_clk_get_parent_name(np, 0); 76 + if (WARN_ON(of_property_read_u32_array(np, "reg", reg, 2))) 77 + return; 78 + if (!smu_base) 79 + emev2_smu_init(); 80 + clk = clk_register_divider(NULL, np->name, parent_name, 0, 81 + smu_base + reg[0], reg[1], 8, 0, &lock); 82 + of_clk_add_provider(np, of_clk_src_simple_get, clk); 83 + clk_register_clkdev(clk, np->name, NULL); 84 + pr_debug("## %s %s %p\n", __func__, np->name, clk); 85 + } 86 + CLK_OF_DECLARE(emev2_smu_clkdiv, "renesas,emev2-smu-clkdiv", 87 + emev2_smu_clkdiv_init); 88 + 89 + static void __init emev2_smu_gclk_init(struct device_node *np) 90 + { 91 + u32 reg[2]; 92 + struct clk *clk; 93 + const char *parent_name = of_clk_get_parent_name(np, 0); 94 + if (WARN_ON(of_property_read_u32_array(np, "reg", reg, 2))) 95 + return; 96 + if (!smu_base) 97 + emev2_smu_init(); 98 + clk = clk_register_gate(NULL, np->name, parent_name, 0, 99 + smu_base + reg[0], reg[1], 0, &lock); 100 + of_clk_add_provider(np, of_clk_src_simple_get, clk); 101 + clk_register_clkdev(clk, np->name, NULL); 102 + pr_debug("## %s %s %p\n", __func__, np->name, clk); 103 + } 104 + CLK_OF_DECLARE(emev2_smu_gclk, "renesas,emev2-smu-gclk", emev2_smu_gclk_init);