1 /* 2 * Copyright 2013-2015 Emilio López 3 * 4 * Emilio López <emilio@elopez.com.ar> 5 * 6 * This program is free software; you can redistribute it and/or modify 7 * it under the terms of the GNU General Public License as published by 8 * the Free Software Foundation; either version 2 of the License, or 9 * (at your option) any later version. 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 17 #include <linux/clk.h> 18 #include <linux/clk-provider.h> 19 #include <linux/io.h> 20 #include <linux/of.h> 21 #include <linux/of_address.h> 22 #include <linux/reset-controller.h> 23 #include <linux/slab.h> 24 #include <linux/spinlock.h> 25 26 27 /** 28 * sunxi_usb_reset... - reset bits in usb clk registers handling 29 */ 30 31 struct usb_reset_data { 32 void __iomem *reg; 33 spinlock_t *lock; 34 struct clk *clk; 35 struct reset_controller_dev rcdev; 36 }; 37 38 static int sunxi_usb_reset_assert(struct reset_controller_dev *rcdev, 39 unsigned long id) 40 { 41 struct usb_reset_data *data = container_of(rcdev, 42 struct usb_reset_data, 43 rcdev); 44 unsigned long flags; 45 u32 reg; 46 47 clk_prepare_enable(data->clk); 48 spin_lock_irqsave(data->lock, flags); 49 50 reg = readl(data->reg); 51 writel(reg & ~BIT(id), data->reg); 52 53 spin_unlock_irqrestore(data->lock, flags); 54 clk_disable_unprepare(data->clk); 55 56 return 0; 57 } 58 59 static int sunxi_usb_reset_deassert(struct reset_controller_dev *rcdev, 60 unsigned long id) 61 { 62 struct usb_reset_data *data = container_of(rcdev, 63 struct usb_reset_data, 64 rcdev); 65 unsigned long flags; 66 u32 reg; 67 68 clk_prepare_enable(data->clk); 69 spin_lock_irqsave(data->lock, flags); 70 71 reg = readl(data->reg); 72 writel(reg | BIT(id), data->reg); 73 74 spin_unlock_irqrestore(data->lock, flags); 75 clk_disable_unprepare(data->clk); 76 77 return 0; 78 } 79 80 static const struct reset_control_ops sunxi_usb_reset_ops = { 81 .assert = sunxi_usb_reset_assert, 82 .deassert = sunxi_usb_reset_deassert, 83 }; 84 85 /** 86 * sunxi_usb_clk_setup() - Setup function for usb gate clocks 87 */ 88 89 #define SUNXI_USB_MAX_SIZE 32 90 91 struct usb_clk_data { 92 u32 clk_mask; 93 u32 reset_mask; 94 bool reset_needs_clk; 95 }; 96 97 static void __init sunxi_usb_clk_setup(struct device_node *node, 98 const struct usb_clk_data *data, 99 spinlock_t *lock) 100 { 101 struct clk_onecell_data *clk_data; 102 struct usb_reset_data *reset_data; 103 const char *clk_parent; 104 const char *clk_name; 105 void __iomem *reg; 106 int qty; 107 int i = 0; 108 int j = 0; 109 110 reg = of_io_request_and_map(node, 0, of_node_full_name(node)); 111 if (IS_ERR(reg)) 112 return; 113 114 clk_parent = of_clk_get_parent_name(node, 0); 115 if (!clk_parent) 116 return; 117 118 /* Worst-case size approximation and memory allocation */ 119 qty = find_last_bit((unsigned long *)&data->clk_mask, 120 SUNXI_USB_MAX_SIZE); 121 122 clk_data = kmalloc(sizeof(struct clk_onecell_data), GFP_KERNEL); 123 if (!clk_data) 124 return; 125 126 clk_data->clks = kcalloc(qty + 1, sizeof(struct clk *), GFP_KERNEL); 127 if (!clk_data->clks) { 128 kfree(clk_data); 129 return; 130 } 131 132 for_each_set_bit(i, (unsigned long *)&data->clk_mask, 133 SUNXI_USB_MAX_SIZE) { 134 of_property_read_string_index(node, "clock-output-names", 135 j, &clk_name); 136 clk_data->clks[i] = clk_register_gate(NULL, clk_name, 137 clk_parent, 0, 138 reg, i, 0, lock); 139 WARN_ON(IS_ERR(clk_data->clks[i])); 140 141 j++; 142 } 143 144 /* Adjust to the real max */ 145 clk_data->clk_num = i; 146 147 of_clk_add_provider(node, of_clk_src_onecell_get, clk_data); 148 149 /* Register a reset controller for usb with reset bits */ 150 if (data->reset_mask == 0) 151 return; 152 153 reset_data = kzalloc(sizeof(*reset_data), GFP_KERNEL); 154 if (!reset_data) 155 return; 156 157 if (data->reset_needs_clk) { 158 reset_data->clk = of_clk_get(node, 0); 159 if (IS_ERR(reset_data->clk)) { 160 pr_err("Could not get clock for reset controls\n"); 161 kfree(reset_data); 162 return; 163 } 164 } 165 166 reset_data->reg = reg; 167 reset_data->lock = lock; 168 reset_data->rcdev.nr_resets = __fls(data->reset_mask) + 1; 169 reset_data->rcdev.ops = &sunxi_usb_reset_ops; 170 reset_data->rcdev.of_node = node; 171 reset_controller_register(&reset_data->rcdev); 172 } 173 174 static const struct usb_clk_data sun4i_a10_usb_clk_data __initconst = { 175 .clk_mask = BIT(8) | BIT(7) | BIT(6), 176 .reset_mask = BIT(2) | BIT(1) | BIT(0), 177 }; 178 179 static DEFINE_SPINLOCK(sun4i_a10_usb_lock); 180 181 static void __init sun4i_a10_usb_setup(struct device_node *node) 182 { 183 sunxi_usb_clk_setup(node, &sun4i_a10_usb_clk_data, &sun4i_a10_usb_lock); 184 } 185 CLK_OF_DECLARE(sun4i_a10_usb, "allwinner,sun4i-a10-usb-clk", sun4i_a10_usb_setup); 186 187 static const struct usb_clk_data sun5i_a13_usb_clk_data __initconst = { 188 .clk_mask = BIT(8) | BIT(6), 189 .reset_mask = BIT(1) | BIT(0), 190 }; 191 192 static void __init sun5i_a13_usb_setup(struct device_node *node) 193 { 194 sunxi_usb_clk_setup(node, &sun5i_a13_usb_clk_data, &sun4i_a10_usb_lock); 195 } 196 CLK_OF_DECLARE(sun5i_a13_usb, "allwinner,sun5i-a13-usb-clk", sun5i_a13_usb_setup); 197 198 static const struct usb_clk_data sun6i_a31_usb_clk_data __initconst = { 199 .clk_mask = BIT(18) | BIT(17) | BIT(16) | BIT(10) | BIT(9) | BIT(8), 200 .reset_mask = BIT(2) | BIT(1) | BIT(0), 201 }; 202 203 static void __init sun6i_a31_usb_setup(struct device_node *node) 204 { 205 sunxi_usb_clk_setup(node, &sun6i_a31_usb_clk_data, &sun4i_a10_usb_lock); 206 } 207 CLK_OF_DECLARE(sun6i_a31_usb, "allwinner,sun6i-a31-usb-clk", sun6i_a31_usb_setup); 208 209 static const struct usb_clk_data sun8i_a23_usb_clk_data __initconst = { 210 .clk_mask = BIT(16) | BIT(11) | BIT(10) | BIT(9) | BIT(8), 211 .reset_mask = BIT(2) | BIT(1) | BIT(0), 212 }; 213 214 static void __init sun8i_a23_usb_setup(struct device_node *node) 215 { 216 sunxi_usb_clk_setup(node, &sun8i_a23_usb_clk_data, &sun4i_a10_usb_lock); 217 } 218 CLK_OF_DECLARE(sun8i_a23_usb, "allwinner,sun8i-a23-usb-clk", sun8i_a23_usb_setup); 219 220 static const struct usb_clk_data sun8i_h3_usb_clk_data __initconst = { 221 .clk_mask = BIT(19) | BIT(18) | BIT(17) | BIT(16) | 222 BIT(11) | BIT(10) | BIT(9) | BIT(8), 223 .reset_mask = BIT(3) | BIT(2) | BIT(1) | BIT(0), 224 }; 225 226 static void __init sun8i_h3_usb_setup(struct device_node *node) 227 { 228 sunxi_usb_clk_setup(node, &sun8i_h3_usb_clk_data, &sun4i_a10_usb_lock); 229 } 230 CLK_OF_DECLARE(sun8i_h3_usb, "allwinner,sun8i-h3-usb-clk", sun8i_h3_usb_setup); 231 232 static const struct usb_clk_data sun9i_a80_usb_mod_data __initconst = { 233 .clk_mask = BIT(6) | BIT(5) | BIT(4) | BIT(3) | BIT(2) | BIT(1), 234 .reset_mask = BIT(19) | BIT(18) | BIT(17), 235 .reset_needs_clk = 1, 236 }; 237 238 static DEFINE_SPINLOCK(a80_usb_mod_lock); 239 240 static void __init sun9i_a80_usb_mod_setup(struct device_node *node) 241 { 242 sunxi_usb_clk_setup(node, &sun9i_a80_usb_mod_data, &a80_usb_mod_lock); 243 } 244 CLK_OF_DECLARE(sun9i_a80_usb_mod, "allwinner,sun9i-a80-usb-mod-clk", sun9i_a80_usb_mod_setup); 245 246 static const struct usb_clk_data sun9i_a80_usb_phy_data __initconst = { 247 .clk_mask = BIT(10) | BIT(5) | BIT(4) | BIT(3) | BIT(2) | BIT(1), 248 .reset_mask = BIT(21) | BIT(20) | BIT(19) | BIT(18) | BIT(17), 249 .reset_needs_clk = 1, 250 }; 251 252 static DEFINE_SPINLOCK(a80_usb_phy_lock); 253 254 static void __init sun9i_a80_usb_phy_setup(struct device_node *node) 255 { 256 sunxi_usb_clk_setup(node, &sun9i_a80_usb_phy_data, &a80_usb_phy_lock); 257 } 258 CLK_OF_DECLARE(sun9i_a80_usb_phy, "allwinner,sun9i-a80-usb-phy-clk", sun9i_a80_usb_phy_setup); 259