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

clk: Add TI-Nspire clock drivers

This patch adds a basic clock driver for the TI-Nspire calculator
series.

Changes from v1:
* Removed filename in header comment
* Removed unnecessary #undef EXTRACT statement

Signed-off-by: Daniel Tang <dt.tangr@gmail.com>
Signed-off-by: Mike Turquette <mturquette@linaro.org>
[mturquette@linaro.org: fixed $SUBJECT and changelog max width]

authored by

Daniel Tang and committed by
Mike Turquette
7d1818fa c0431037

+178
+24
Documentation/devicetree/bindings/clock/nspire-clock.txt
··· 1 + TI-NSPIRE Clocks 2 + 3 + Required properties: 4 + - compatible: Valid compatible properties include: 5 + "lsi,nspire-cx-ahb-divider" for the AHB divider in the CX model 6 + "lsi,nspire-classic-ahb-divider" for the AHB divider in the older model 7 + "lsi,nspire-cx-clock" for the base clock in the CX model 8 + "lsi,nspire-classic-clock" for the base clock in the older model 9 + 10 + - reg: Physical base address of the controller and length of memory mapped 11 + region. 12 + 13 + Optional: 14 + - clocks: For the "nspire-*-ahb-divider" compatible clocks, this is the parent 15 + clock where it divides the rate from. 16 + 17 + Example: 18 + 19 + ahb_clk { 20 + #clock-cells = <0>; 21 + compatible = "lsi,nspire-cx-clock"; 22 + reg = <0x900B0000 0x4>; 23 + clocks = <&base_clk>; 24 + };
+1
drivers/clk/Makefile
··· 13 13 obj-$(CONFIG_ARCH_BCM2835) += clk-bcm2835.o 14 14 obj-$(CONFIG_ARCH_NOMADIK) += clk-nomadik.o 15 15 obj-$(CONFIG_ARCH_HIGHBANK) += clk-highbank.o 16 + obj-$(CONFIG_ARCH_NSPIRE) += clk-nspire.o 16 17 obj-$(CONFIG_ARCH_MXS) += mxs/ 17 18 obj-$(CONFIG_ARCH_SOCFPGA) += socfpga/ 18 19 obj-$(CONFIG_PLAT_SPEAR) += spear/
+153
drivers/clk/clk-nspire.c
··· 1 + /* 2 + * 3 + * Copyright (C) 2013 Daniel Tang <tangrs@tangrs.id.au> 4 + * 5 + * This program is free software; you can redistribute it and/or modify 6 + * it under the terms of the GNU General Public License version 2, as 7 + * published by the Free Software Foundation. 8 + * 9 + */ 10 + 11 + #include <linux/clk-provider.h> 12 + #include <linux/err.h> 13 + #include <linux/io.h> 14 + #include <linux/of.h> 15 + #include <linux/of_address.h> 16 + 17 + #define MHZ (1000 * 1000) 18 + 19 + #define BASE_CPU_SHIFT 1 20 + #define BASE_CPU_MASK 0x7F 21 + 22 + #define CPU_AHB_SHIFT 12 23 + #define CPU_AHB_MASK 0x07 24 + 25 + #define FIXED_BASE_SHIFT 8 26 + #define FIXED_BASE_MASK 0x01 27 + 28 + #define CLASSIC_BASE_SHIFT 16 29 + #define CLASSIC_BASE_MASK 0x1F 30 + 31 + #define CX_BASE_SHIFT 15 32 + #define CX_BASE_MASK 0x3F 33 + 34 + #define CX_UNKNOWN_SHIFT 21 35 + #define CX_UNKNOWN_MASK 0x03 36 + 37 + struct nspire_clk_info { 38 + u32 base_clock; 39 + u16 base_cpu_ratio; 40 + u16 base_ahb_ratio; 41 + }; 42 + 43 + 44 + #define EXTRACT(var, prop) (((var)>>prop##_SHIFT) & prop##_MASK) 45 + static void nspire_clkinfo_cx(u32 val, struct nspire_clk_info *clk) 46 + { 47 + if (EXTRACT(val, FIXED_BASE)) 48 + clk->base_clock = 48 * MHZ; 49 + else 50 + clk->base_clock = 6 * EXTRACT(val, CX_BASE) * MHZ; 51 + 52 + clk->base_cpu_ratio = EXTRACT(val, BASE_CPU) * EXTRACT(val, CX_UNKNOWN); 53 + clk->base_ahb_ratio = clk->base_cpu_ratio * (EXTRACT(val, CPU_AHB) + 1); 54 + } 55 + 56 + static void nspire_clkinfo_classic(u32 val, struct nspire_clk_info *clk) 57 + { 58 + if (EXTRACT(val, FIXED_BASE)) 59 + clk->base_clock = 27 * MHZ; 60 + else 61 + clk->base_clock = (300 - 6 * EXTRACT(val, CLASSIC_BASE)) * MHZ; 62 + 63 + clk->base_cpu_ratio = EXTRACT(val, BASE_CPU) * 2; 64 + clk->base_ahb_ratio = clk->base_cpu_ratio * (EXTRACT(val, CPU_AHB) + 1); 65 + } 66 + 67 + static void __init nspire_ahbdiv_setup(struct device_node *node, 68 + void (*get_clkinfo)(u32, struct nspire_clk_info *)) 69 + { 70 + u32 val; 71 + void __iomem *io; 72 + struct clk *clk; 73 + const char *clk_name = node->name; 74 + const char *parent_name; 75 + struct nspire_clk_info info; 76 + 77 + io = of_iomap(node, 0); 78 + if (!io) 79 + return; 80 + val = readl(io); 81 + iounmap(io); 82 + 83 + get_clkinfo(val, &info); 84 + 85 + of_property_read_string(node, "clock-output-names", &clk_name); 86 + parent_name = of_clk_get_parent_name(node, 0); 87 + 88 + clk = clk_register_fixed_factor(NULL, clk_name, parent_name, 0, 89 + 1, info.base_ahb_ratio); 90 + if (!IS_ERR(clk)) 91 + of_clk_add_provider(node, of_clk_src_simple_get, clk); 92 + } 93 + 94 + static void __init nspire_ahbdiv_setup_cx(struct device_node *node) 95 + { 96 + nspire_ahbdiv_setup(node, nspire_clkinfo_cx); 97 + } 98 + 99 + static void __init nspire_ahbdiv_setup_classic(struct device_node *node) 100 + { 101 + nspire_ahbdiv_setup(node, nspire_clkinfo_classic); 102 + } 103 + 104 + CLK_OF_DECLARE(nspire_ahbdiv_cx, "lsi,nspire-cx-ahb-divider", 105 + nspire_ahbdiv_setup_cx); 106 + CLK_OF_DECLARE(nspire_ahbdiv_classic, "lsi,nspire-classic-ahb-divider", 107 + nspire_ahbdiv_setup_classic); 108 + 109 + static void __init nspire_clk_setup(struct device_node *node, 110 + void (*get_clkinfo)(u32, struct nspire_clk_info *)) 111 + { 112 + u32 val; 113 + void __iomem *io; 114 + struct clk *clk; 115 + const char *clk_name = node->name; 116 + struct nspire_clk_info info; 117 + 118 + io = of_iomap(node, 0); 119 + if (!io) 120 + return; 121 + val = readl(io); 122 + iounmap(io); 123 + 124 + get_clkinfo(val, &info); 125 + 126 + of_property_read_string(node, "clock-output-names", &clk_name); 127 + 128 + clk = clk_register_fixed_rate(NULL, clk_name, NULL, CLK_IS_ROOT, 129 + info.base_clock); 130 + if (!IS_ERR(clk)) 131 + of_clk_add_provider(node, of_clk_src_simple_get, clk); 132 + else 133 + return; 134 + 135 + pr_info("TI-NSPIRE Base: %uMHz CPU: %uMHz AHB: %uMHz\n", 136 + info.base_clock / MHZ, 137 + info.base_clock / info.base_cpu_ratio / MHZ, 138 + info.base_clock / info.base_ahb_ratio / MHZ); 139 + } 140 + 141 + static void __init nspire_clk_setup_cx(struct device_node *node) 142 + { 143 + nspire_clk_setup(node, nspire_clkinfo_cx); 144 + } 145 + 146 + static void __init nspire_clk_setup_classic(struct device_node *node) 147 + { 148 + nspire_clk_setup(node, nspire_clkinfo_classic); 149 + } 150 + 151 + CLK_OF_DECLARE(nspire_clk_cx, "lsi,nspire-cx-clock", nspire_clk_setup_cx); 152 + CLK_OF_DECLARE(nspire_clk_classic, "lsi,nspire-classic-clock", 153 + nspire_clk_setup_classic);