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

clk: sunxi-ng: Add A80 USB CCU

Add support for the USB clock controls found on the A80.

Signed-off-by: Chen-Yu Tsai <wens@csie.org>
Acked-by: Rob Herring <robh@kernel.org>
Signed-off-by: Maxime Ripard <maxime.ripard@free-electrons.com>

authored by

Chen-Yu Tsai and committed by
Maxime Ripard
439b65c4 b8eb71dc

+309
+24
Documentation/devicetree/bindings/clock/sun9i-usb.txt
··· 1 + Allwinner A80 USB Clock Control Binding 2 + --------------------------------------- 3 + 4 + Required properties : 5 + - compatible: must contain one of the following compatibles: 6 + - "allwinner,sun9i-a80-usb-clocks" 7 + 8 + - reg: Must contain the registers base address and length 9 + - clocks: phandle to the clocks feeding the USB subsystem. Two are needed: 10 + - "bus": the bus clock for the whole USB subsystem 11 + - "hosc": the high frequency oscillator (usually at 24MHz) 12 + - clock-names: Must contain the clock names described just above 13 + - #clock-cells : must contain 1 14 + - #reset-cells : must contain 1 15 + 16 + Example: 17 + usb_clocks: clock@a08000 { 18 + compatible = "allwinner,sun9i-a80-usb-clks"; 19 + reg = <0x00a08000 0x8>; 20 + clocks = <&ccu CLK_BUS_USB>, <&osc24M>; 21 + clock-names = "bus", "hosc"; 22 + #clock-cells = <1>; 23 + #reset-cells = <1>; 24 + };
+1
drivers/clk/sunxi-ng/Makefile
··· 26 26 obj-$(CONFIG_SUN8I_H3_CCU) += ccu-sun8i-h3.o 27 27 obj-$(CONFIG_SUN8I_V3S_CCU) += ccu-sun8i-v3s.o 28 28 obj-$(CONFIG_SUN9I_A80_CCU) += ccu-sun9i-a80.o 29 + obj-$(CONFIG_SUN9I_A80_CCU) += ccu-sun9i-a80-usb.o
+144
drivers/clk/sunxi-ng/ccu-sun9i-a80-usb.c
··· 1 + /* 2 + * Copyright (c) 2016 Chen-Yu Tsai. All rights reserved. 3 + * 4 + * This software is licensed under the terms of the GNU General Public 5 + * License version 2, as published by the Free Software Foundation, and 6 + * may be copied, distributed, and modified under those terms. 7 + * 8 + * This program is distributed in the hope that it will be useful, 9 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 + * GNU General Public License for more details. 12 + */ 13 + 14 + #include <linux/clk.h> 15 + #include <linux/clk-provider.h> 16 + #include <linux/of_address.h> 17 + #include <linux/platform_device.h> 18 + 19 + #include "ccu_common.h" 20 + #include "ccu_gate.h" 21 + #include "ccu_reset.h" 22 + 23 + #include "ccu-sun9i-a80-usb.h" 24 + 25 + static SUNXI_CCU_GATE(bus_hci0_clk, "bus-hci0", "bus-usb", 0x0, BIT(1), 0); 26 + static SUNXI_CCU_GATE(usb_ohci0_clk, "usb-ohci0", "osc24M", 0x0, BIT(2), 0); 27 + static SUNXI_CCU_GATE(bus_hci1_clk, "bus-hci1", "bus-usb", 0x0, BIT(3), 0); 28 + static SUNXI_CCU_GATE(bus_hci2_clk, "bus-hci2", "bus-usb", 0x0, BIT(5), 0); 29 + static SUNXI_CCU_GATE(usb_ohci2_clk, "usb-ohci2", "osc24M", 0x0, BIT(6), 0); 30 + 31 + static SUNXI_CCU_GATE(usb0_phy_clk, "usb0-phy", "osc24M", 0x4, BIT(1), 0); 32 + static SUNXI_CCU_GATE(usb1_hsic_clk, "usb1-hsic", "osc24M", 0x4, BIT(2), 0); 33 + static SUNXI_CCU_GATE(usb1_phy_clk, "usb1-phy", "osc24M", 0x4, BIT(3), 0); 34 + static SUNXI_CCU_GATE(usb2_hsic_clk, "usb2-hsic", "osc24M", 0x4, BIT(4), 0); 35 + static SUNXI_CCU_GATE(usb2_phy_clk, "usb2-phy", "osc24M", 0x4, BIT(5), 0); 36 + static SUNXI_CCU_GATE(usb_hsic_clk, "usb-hsic", "osc24M", 0x4, BIT(10), 0); 37 + 38 + static struct ccu_common *sun9i_a80_usb_clks[] = { 39 + &bus_hci0_clk.common, 40 + &usb_ohci0_clk.common, 41 + &bus_hci1_clk.common, 42 + &bus_hci2_clk.common, 43 + &usb_ohci2_clk.common, 44 + 45 + &usb0_phy_clk.common, 46 + &usb1_hsic_clk.common, 47 + &usb1_phy_clk.common, 48 + &usb2_hsic_clk.common, 49 + &usb2_phy_clk.common, 50 + &usb_hsic_clk.common, 51 + }; 52 + 53 + static struct clk_hw_onecell_data sun9i_a80_usb_hw_clks = { 54 + .hws = { 55 + [CLK_BUS_HCI0] = &bus_hci0_clk.common.hw, 56 + [CLK_USB_OHCI0] = &usb_ohci0_clk.common.hw, 57 + [CLK_BUS_HCI1] = &bus_hci1_clk.common.hw, 58 + [CLK_BUS_HCI2] = &bus_hci2_clk.common.hw, 59 + [CLK_USB_OHCI2] = &usb_ohci2_clk.common.hw, 60 + 61 + [CLK_USB0_PHY] = &usb0_phy_clk.common.hw, 62 + [CLK_USB1_HSIC] = &usb1_hsic_clk.common.hw, 63 + [CLK_USB1_PHY] = &usb1_phy_clk.common.hw, 64 + [CLK_USB2_HSIC] = &usb2_hsic_clk.common.hw, 65 + [CLK_USB2_PHY] = &usb2_phy_clk.common.hw, 66 + [CLK_USB_HSIC] = &usb_hsic_clk.common.hw, 67 + }, 68 + .num = CLK_NUMBER, 69 + }; 70 + 71 + static struct ccu_reset_map sun9i_a80_usb_resets[] = { 72 + [RST_USB0_HCI] = { 0x0, BIT(17) }, 73 + [RST_USB1_HCI] = { 0x0, BIT(18) }, 74 + [RST_USB2_HCI] = { 0x0, BIT(19) }, 75 + 76 + [RST_USB0_PHY] = { 0x4, BIT(17) }, 77 + [RST_USB1_HSIC] = { 0x4, BIT(18) }, 78 + [RST_USB1_PHY] = { 0x4, BIT(19) }, 79 + [RST_USB2_HSIC] = { 0x4, BIT(20) }, 80 + [RST_USB2_PHY] = { 0x4, BIT(21) }, 81 + }; 82 + 83 + static const struct sunxi_ccu_desc sun9i_a80_usb_clk_desc = { 84 + .ccu_clks = sun9i_a80_usb_clks, 85 + .num_ccu_clks = ARRAY_SIZE(sun9i_a80_usb_clks), 86 + 87 + .hw_clks = &sun9i_a80_usb_hw_clks, 88 + 89 + .resets = sun9i_a80_usb_resets, 90 + .num_resets = ARRAY_SIZE(sun9i_a80_usb_resets), 91 + }; 92 + 93 + static int sun9i_a80_usb_clk_probe(struct platform_device *pdev) 94 + { 95 + struct resource *res; 96 + struct clk *bus_clk; 97 + void __iomem *reg; 98 + int ret; 99 + 100 + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 101 + reg = devm_ioremap_resource(&pdev->dev, res); 102 + if (IS_ERR(reg)) 103 + return PTR_ERR(reg); 104 + 105 + bus_clk = devm_clk_get(&pdev->dev, "bus"); 106 + if (IS_ERR(bus_clk)) { 107 + ret = PTR_ERR(bus_clk); 108 + if (ret != -EPROBE_DEFER) 109 + dev_err(&pdev->dev, "Couldn't get bus clk: %d\n", ret); 110 + return ret; 111 + } 112 + 113 + /* The bus clock needs to be enabled for us to access the registers */ 114 + ret = clk_prepare_enable(bus_clk); 115 + if (ret) { 116 + dev_err(&pdev->dev, "Couldn't enable bus clk: %d\n", ret); 117 + return ret; 118 + } 119 + 120 + ret = sunxi_ccu_probe(pdev->dev.of_node, reg, 121 + &sun9i_a80_usb_clk_desc); 122 + if (ret) 123 + goto err_disable_clk; 124 + 125 + return 0; 126 + 127 + err_disable_clk: 128 + clk_disable_unprepare(bus_clk); 129 + return ret; 130 + } 131 + 132 + static const struct of_device_id sun9i_a80_usb_clk_ids[] = { 133 + { .compatible = "allwinner,sun9i-a80-usb-clks" }, 134 + { } 135 + }; 136 + 137 + static struct platform_driver sun9i_a80_usb_clk_driver = { 138 + .probe = sun9i_a80_usb_clk_probe, 139 + .driver = { 140 + .name = "sun9i-a80-usb-clks", 141 + .of_match_table = sun9i_a80_usb_clk_ids, 142 + }, 143 + }; 144 + builtin_platform_driver(sun9i_a80_usb_clk_driver);
+25
drivers/clk/sunxi-ng/ccu-sun9i-a80-usb.h
··· 1 + /* 2 + * Copyright 2016 Chen-Yu Tsai 3 + * 4 + * Chen-Yu Tsai <wens@csie.org> 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 + #ifndef _CCU_SUN9I_A80_USB_H_ 18 + #define _CCU_SUN9I_A80_USB_H_ 19 + 20 + #include <dt-bindings/clock/sun9i-a80-usb.h> 21 + #include <dt-bindings/reset/sun9i-a80-usb.h> 22 + 23 + #define CLK_NUMBER (CLK_USB_HSIC + 1) 24 + 25 + #endif /* _CCU_SUN9I_A80_USB_H_ */
+59
include/dt-bindings/clock/sun9i-a80-usb.h
··· 1 + /* 2 + * Copyright (C) 2016 Chen-Yu Tsai <wens@csie.org> 3 + * 4 + * This file is dual-licensed: you can use it either under the terms 5 + * of the GPL or the X11 license, at your option. Note that this dual 6 + * licensing only applies to this file, and not this project as a 7 + * whole. 8 + * 9 + * a) This file is free software; you can redistribute it and/or 10 + * modify it under the terms of the GNU General Public License as 11 + * published by the Free Software Foundation; either version 2 of the 12 + * License, or (at your option) any later version. 13 + * 14 + * This file is distributed in the hope that it will be useful, 15 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 16 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 + * GNU General Public License for more details. 18 + * 19 + * Or, alternatively, 20 + * 21 + * b) Permission is hereby granted, free of charge, to any person 22 + * obtaining a copy of this software and associated documentation 23 + * files (the "Software"), to deal in the Software without 24 + * restriction, including without limitation the rights to use, 25 + * copy, modify, merge, publish, distribute, sublicense, and/or 26 + * sell copies of the Software, and to permit persons to whom the 27 + * Software is furnished to do so, subject to the following 28 + * conditions: 29 + * 30 + * The above copyright notice and this permission notice shall be 31 + * included in all copies or substantial portions of the Software. 32 + * 33 + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 34 + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 35 + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 36 + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 37 + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 38 + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 39 + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 40 + * OTHER DEALINGS IN THE SOFTWARE. 41 + */ 42 + 43 + #ifndef _DT_BINDINGS_CLOCK_SUN9I_A80_USB_H_ 44 + #define _DT_BINDINGS_CLOCK_SUN9I_A80_USB_H_ 45 + 46 + #define CLK_BUS_HCI0 0 47 + #define CLK_USB_OHCI0 1 48 + #define CLK_BUS_HCI1 2 49 + #define CLK_BUS_HCI2 3 50 + #define CLK_USB_OHCI2 4 51 + 52 + #define CLK_USB0_PHY 5 53 + #define CLK_USB1_HSIC 6 54 + #define CLK_USB1_PHY 7 55 + #define CLK_USB2_HSIC 8 56 + #define CLK_USB2_PHY 9 57 + #define CLK_USB_HSIC 10 58 + 59 + #endif /* _DT_BINDINGS_CLOCK_SUN9I_A80_USB_H_ */
+56
include/dt-bindings/reset/sun9i-a80-usb.h
··· 1 + /* 2 + * Copyright (C) 2016 Chen-Yu Tsai <wens@csie.org> 3 + * 4 + * This file is dual-licensed: you can use it either under the terms 5 + * of the GPL or the X11 license, at your option. Note that this dual 6 + * licensing only applies to this file, and not this project as a 7 + * whole. 8 + * 9 + * a) This file is free software; you can redistribute it and/or 10 + * modify it under the terms of the GNU General Public License as 11 + * published by the Free Software Foundation; either version 2 of the 12 + * License, or (at your option) any later version. 13 + * 14 + * This file is distributed in the hope that it will be useful, 15 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 16 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 + * GNU General Public License for more details. 18 + * 19 + * Or, alternatively, 20 + * 21 + * b) Permission is hereby granted, free of charge, to any person 22 + * obtaining a copy of this software and associated documentation 23 + * files (the "Software"), to deal in the Software without 24 + * restriction, including without limitation the rights to use, 25 + * copy, modify, merge, publish, distribute, sublicense, and/or 26 + * sell copies of the Software, and to permit persons to whom the 27 + * Software is furnished to do so, subject to the following 28 + * conditions: 29 + * 30 + * The above copyright notice and this permission notice shall be 31 + * included in all copies or substantial portions of the Software. 32 + * 33 + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 34 + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 35 + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 36 + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 37 + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 38 + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 39 + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 40 + * OTHER DEALINGS IN THE SOFTWARE. 41 + */ 42 + 43 + #ifndef _DT_BINDINGS_RESET_SUN9I_A80_USB_H_ 44 + #define _DT_BINDINGS_RESET_SUN9I_A80_USB_H_ 45 + 46 + #define RST_USB0_HCI 0 47 + #define RST_USB1_HCI 1 48 + #define RST_USB2_HCI 2 49 + 50 + #define RST_USB0_PHY 3 51 + #define RST_USB1_HSIC 4 52 + #define RST_USB1_PHY 5 53 + #define RST_USB2_HSIC 6 54 + #define RST_USB2_PHY 7 55 + 56 + #endif /* _DT_BINDINGS_RESET_SUN9I_A80_USB_H_ */