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