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

Merge branch 'clk-hisi' into clk-next

* clk-hisi:
clk: hisilicon: add CRG driver for Hi3516CV300 SoC
clk: hisilicon: add CRG driver for Hi3798CV200 SoC

+841 -4
+8 -4
Documentation/devicetree/bindings/clock/hi3519-crg.txt Documentation/devicetree/bindings/clock/hisi-crg.txt
··· 1 - * Hisilicon Hi3519 Clock and Reset Generator(CRG) 1 + * HiSilicon Clock and Reset Generator(CRG) 2 2 3 - The Hi3519 CRG module provides clock and reset signals to various 4 - controllers within the SoC. 3 + The CRG module provides clock and reset signals to various 4 + modules within the SoC. 5 5 6 6 This binding uses the following bindings: 7 7 Documentation/devicetree/bindings/clock/clock-bindings.txt ··· 10 10 Required Properties: 11 11 12 12 - compatible: should be one of the following. 13 - - "hisilicon,hi3519-crg" - controller compatible with Hi3519 SoC. 13 + - "hisilicon,hi3516cv300-crg" 14 + - "hisilicon,hi3516cv300-sysctrl" 15 + - "hisilicon,hi3519-crg" 16 + - "hisilicon,hi3798cv200-crg" 17 + - "hisilicon,hi3798cv200-sysctrl" 14 18 15 19 - reg: physical base address of the controller and length of memory mapped 16 20 region.
+16
drivers/clk/hisilicon/Kconfig
··· 1 + config COMMON_CLK_HI3516CV300 2 + tristate "HI3516CV300 Clock Driver" 3 + depends on ARCH_HISI || COMPILE_TEST 4 + select RESET_HISI 5 + default ARCH_HISI 6 + help 7 + Build the clock driver for hi3516cv300. 8 + 1 9 config COMMON_CLK_HI3519 2 10 tristate "Hi3519 Clock Driver" 3 11 depends on ARCH_HISI || COMPILE_TEST ··· 13 5 default ARCH_HISI 14 6 help 15 7 Build the clock driver for hi3519. 8 + 9 + config COMMON_CLK_HI3798CV200 10 + tristate "Hi3798CV200 Clock Driver" 11 + depends on ARCH_HISI || COMPILE_TEST 12 + select RESET_HISI 13 + default ARCH_HISI 14 + help 15 + Build the clock driver for hi3798cv200. 16 16 17 17 config COMMON_CLK_HI6220 18 18 bool "Hi6220 Clock Driver"
+2
drivers/clk/hisilicon/Makefile
··· 7 7 obj-$(CONFIG_ARCH_HI3xxx) += clk-hi3620.o 8 8 obj-$(CONFIG_ARCH_HIP04) += clk-hip04.o 9 9 obj-$(CONFIG_ARCH_HIX5HD2) += clk-hix5hd2.o 10 + obj-$(CONFIG_COMMON_CLK_HI3516CV300) += crg-hi3516cv300.o 10 11 obj-$(CONFIG_COMMON_CLK_HI3519) += clk-hi3519.o 12 + obj-$(CONFIG_COMMON_CLK_HI3798CV200) += crg-hi3798cv200.o 11 13 obj-$(CONFIG_COMMON_CLK_HI6220) += clk-hi6220.o 12 14 obj-$(CONFIG_RESET_HISI) += reset.o 13 15 obj-$(CONFIG_STUB_CLK_HI6220) += clk-hi6220-stub.o
+330
drivers/clk/hisilicon/crg-hi3516cv300.c
··· 1 + /* 2 + * Hi3516CV300 Clock and Reset Generator Driver 3 + * 4 + * Copyright (c) 2016 HiSilicon Technologies Co., Ltd. 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 + * You should have received a copy of the GNU General Public License 17 + * along with this program. If not, see <http://www.gnu.org/licenses/>. 18 + */ 19 + 20 + #include <dt-bindings/clock/hi3516cv300-clock.h> 21 + #include <linux/clk-provider.h> 22 + #include <linux/module.h> 23 + #include <linux/of_device.h> 24 + #include <linux/platform_device.h> 25 + #include "clk.h" 26 + #include "crg.h" 27 + #include "reset.h" 28 + 29 + /* hi3516CV300 core CRG */ 30 + #define HI3516CV300_INNER_CLK_OFFSET 64 31 + #define HI3516CV300_FIXED_3M 65 32 + #define HI3516CV300_FIXED_6M 66 33 + #define HI3516CV300_FIXED_24M 67 34 + #define HI3516CV300_FIXED_49P5 68 35 + #define HI3516CV300_FIXED_50M 69 36 + #define HI3516CV300_FIXED_83P3M 70 37 + #define HI3516CV300_FIXED_99M 71 38 + #define HI3516CV300_FIXED_100M 72 39 + #define HI3516CV300_FIXED_148P5M 73 40 + #define HI3516CV300_FIXED_198M 74 41 + #define HI3516CV300_FIXED_297M 75 42 + #define HI3516CV300_UART_MUX 76 43 + #define HI3516CV300_FMC_MUX 77 44 + #define HI3516CV300_MMC0_MUX 78 45 + #define HI3516CV300_MMC1_MUX 79 46 + #define HI3516CV300_MMC2_MUX 80 47 + #define HI3516CV300_MMC3_MUX 81 48 + #define HI3516CV300_PWM_MUX 82 49 + #define HI3516CV300_CRG_NR_CLKS 128 50 + 51 + static const struct hisi_fixed_rate_clock hi3516cv300_fixed_rate_clks[] = { 52 + { HI3516CV300_FIXED_3M, "3m", NULL, 0, 3000000, }, 53 + { HI3516CV300_FIXED_6M, "6m", NULL, 0, 6000000, }, 54 + { HI3516CV300_FIXED_24M, "24m", NULL, 0, 24000000, }, 55 + { HI3516CV300_FIXED_49P5, "49.5m", NULL, 0, 49500000, }, 56 + { HI3516CV300_FIXED_50M, "50m", NULL, 0, 50000000, }, 57 + { HI3516CV300_FIXED_83P3M, "83.3m", NULL, 0, 83300000, }, 58 + { HI3516CV300_FIXED_99M, "99m", NULL, 0, 99000000, }, 59 + { HI3516CV300_FIXED_100M, "100m", NULL, 0, 100000000, }, 60 + { HI3516CV300_FIXED_148P5M, "148.5m", NULL, 0, 148500000, }, 61 + { HI3516CV300_FIXED_198M, "198m", NULL, 0, 198000000, }, 62 + { HI3516CV300_FIXED_297M, "297m", NULL, 0, 297000000, }, 63 + { HI3516CV300_APB_CLK, "apb", NULL, 0, 50000000, }, 64 + }; 65 + 66 + static const char *const uart_mux_p[] = {"24m", "6m"}; 67 + static const char *const fmc_mux_p[] = { 68 + "24m", "83.3m", "148.5m", "198m", "297m" 69 + }; 70 + static const char *const mmc_mux_p[] = {"49.5m"}; 71 + static const char *const mmc2_mux_p[] = {"99m", "49.5m"}; 72 + static const char *const pwm_mux_p[] = {"3m", "50m", "24m", "24m"}; 73 + 74 + static u32 uart_mux_table[] = {0, 1}; 75 + static u32 fmc_mux_table[] = {0, 1, 2, 3, 4}; 76 + static u32 mmc_mux_table[] = {0}; 77 + static u32 mmc2_mux_table[] = {0, 2}; 78 + static u32 pwm_mux_table[] = {0, 1, 2, 3}; 79 + 80 + static const struct hisi_mux_clock hi3516cv300_mux_clks[] = { 81 + { HI3516CV300_UART_MUX, "uart_mux", uart_mux_p, ARRAY_SIZE(uart_mux_p), 82 + CLK_SET_RATE_PARENT, 0xe4, 19, 1, 0, uart_mux_table, }, 83 + { HI3516CV300_FMC_MUX, "fmc_mux", fmc_mux_p, ARRAY_SIZE(fmc_mux_p), 84 + CLK_SET_RATE_PARENT, 0xc0, 2, 3, 0, fmc_mux_table, }, 85 + { HI3516CV300_MMC0_MUX, "mmc0_mux", mmc_mux_p, ARRAY_SIZE(mmc_mux_p), 86 + CLK_SET_RATE_PARENT, 0xc4, 4, 2, 0, mmc_mux_table, }, 87 + { HI3516CV300_MMC1_MUX, "mmc1_mux", mmc_mux_p, ARRAY_SIZE(mmc_mux_p), 88 + CLK_SET_RATE_PARENT, 0xc4, 12, 2, 0, mmc_mux_table, }, 89 + { HI3516CV300_MMC2_MUX, "mmc2_mux", mmc2_mux_p, ARRAY_SIZE(mmc2_mux_p), 90 + CLK_SET_RATE_PARENT, 0xc4, 20, 2, 0, mmc2_mux_table, }, 91 + { HI3516CV300_MMC3_MUX, "mmc3_mux", mmc_mux_p, ARRAY_SIZE(mmc_mux_p), 92 + CLK_SET_RATE_PARENT, 0xc8, 4, 2, 0, mmc_mux_table, }, 93 + { HI3516CV300_PWM_MUX, "pwm_mux", pwm_mux_p, ARRAY_SIZE(pwm_mux_p), 94 + CLK_SET_RATE_PARENT, 0x38, 2, 2, 0, pwm_mux_table, }, 95 + }; 96 + 97 + static const struct hisi_gate_clock hi3516cv300_gate_clks[] = { 98 + 99 + { HI3516CV300_UART0_CLK, "clk_uart0", "uart_mux", CLK_SET_RATE_PARENT, 100 + 0xe4, 15, 0, }, 101 + { HI3516CV300_UART1_CLK, "clk_uart1", "uart_mux", CLK_SET_RATE_PARENT, 102 + 0xe4, 16, 0, }, 103 + { HI3516CV300_UART2_CLK, "clk_uart2", "uart_mux", CLK_SET_RATE_PARENT, 104 + 0xe4, 17, 0, }, 105 + 106 + { HI3516CV300_SPI0_CLK, "clk_spi0", "100m", CLK_SET_RATE_PARENT, 107 + 0xe4, 13, 0, }, 108 + { HI3516CV300_SPI1_CLK, "clk_spi1", "100m", CLK_SET_RATE_PARENT, 109 + 0xe4, 14, 0, }, 110 + 111 + { HI3516CV300_FMC_CLK, "clk_fmc", "fmc_mux", CLK_SET_RATE_PARENT, 112 + 0xc0, 1, 0, }, 113 + { HI3516CV300_MMC0_CLK, "clk_mmc0", "mmc0_mux", CLK_SET_RATE_PARENT, 114 + 0xc4, 1, 0, }, 115 + { HI3516CV300_MMC1_CLK, "clk_mmc1", "mmc1_mux", CLK_SET_RATE_PARENT, 116 + 0xc4, 9, 0, }, 117 + { HI3516CV300_MMC2_CLK, "clk_mmc2", "mmc2_mux", CLK_SET_RATE_PARENT, 118 + 0xc4, 17, 0, }, 119 + { HI3516CV300_MMC3_CLK, "clk_mmc3", "mmc3_mux", CLK_SET_RATE_PARENT, 120 + 0xc8, 1, 0, }, 121 + 122 + { HI3516CV300_ETH_CLK, "clk_eth", NULL, 0, 0xec, 1, 0, }, 123 + 124 + { HI3516CV300_DMAC_CLK, "clk_dmac", NULL, 0, 0xd8, 5, 0, }, 125 + { HI3516CV300_PWM_CLK, "clk_pwm", "pwm_mux", CLK_SET_RATE_PARENT, 126 + 0x38, 1, 0, }, 127 + 128 + { HI3516CV300_USB2_BUS_CLK, "clk_usb2_bus", NULL, 0, 0xb8, 0, 0, }, 129 + { HI3516CV300_USB2_OHCI48M_CLK, "clk_usb2_ohci48m", NULL, 0, 130 + 0xb8, 1, 0, }, 131 + { HI3516CV300_USB2_OHCI12M_CLK, "clk_usb2_ohci12m", NULL, 0, 132 + 0xb8, 2, 0, }, 133 + { HI3516CV300_USB2_OTG_UTMI_CLK, "clk_usb2_otg_utmi", NULL, 0, 134 + 0xb8, 3, 0, }, 135 + { HI3516CV300_USB2_HST_PHY_CLK, "clk_usb2_hst_phy", NULL, 0, 136 + 0xb8, 4, 0, }, 137 + { HI3516CV300_USB2_UTMI0_CLK, "clk_usb2_utmi0", NULL, 0, 0xb8, 5, 0, }, 138 + { HI3516CV300_USB2_PHY_CLK, "clk_usb2_phy", NULL, 0, 0xb8, 7, 0, }, 139 + }; 140 + 141 + static struct hisi_clock_data *hi3516cv300_clk_register( 142 + struct platform_device *pdev) 143 + { 144 + struct hisi_clock_data *clk_data; 145 + int ret; 146 + 147 + clk_data = hisi_clk_alloc(pdev, HI3516CV300_CRG_NR_CLKS); 148 + if (!clk_data) 149 + return ERR_PTR(-ENOMEM); 150 + 151 + ret = hisi_clk_register_fixed_rate(hi3516cv300_fixed_rate_clks, 152 + ARRAY_SIZE(hi3516cv300_fixed_rate_clks), clk_data); 153 + if (ret) 154 + return ERR_PTR(ret); 155 + 156 + ret = hisi_clk_register_mux(hi3516cv300_mux_clks, 157 + ARRAY_SIZE(hi3516cv300_mux_clks), clk_data); 158 + if (ret) 159 + goto unregister_fixed_rate; 160 + 161 + ret = hisi_clk_register_gate(hi3516cv300_gate_clks, 162 + ARRAY_SIZE(hi3516cv300_gate_clks), clk_data); 163 + if (ret) 164 + goto unregister_mux; 165 + 166 + ret = of_clk_add_provider(pdev->dev.of_node, 167 + of_clk_src_onecell_get, &clk_data->clk_data); 168 + if (ret) 169 + goto unregister_gate; 170 + 171 + return clk_data; 172 + 173 + unregister_gate: 174 + hisi_clk_unregister_gate(hi3516cv300_gate_clks, 175 + ARRAY_SIZE(hi3516cv300_gate_clks), clk_data); 176 + unregister_mux: 177 + hisi_clk_unregister_mux(hi3516cv300_mux_clks, 178 + ARRAY_SIZE(hi3516cv300_mux_clks), clk_data); 179 + unregister_fixed_rate: 180 + hisi_clk_unregister_fixed_rate(hi3516cv300_fixed_rate_clks, 181 + ARRAY_SIZE(hi3516cv300_fixed_rate_clks), clk_data); 182 + return ERR_PTR(ret); 183 + } 184 + 185 + static void hi3516cv300_clk_unregister(struct platform_device *pdev) 186 + { 187 + struct hisi_crg_dev *crg = platform_get_drvdata(pdev); 188 + 189 + of_clk_del_provider(pdev->dev.of_node); 190 + 191 + hisi_clk_unregister_gate(hi3516cv300_gate_clks, 192 + ARRAY_SIZE(hi3516cv300_gate_clks), crg->clk_data); 193 + hisi_clk_unregister_mux(hi3516cv300_mux_clks, 194 + ARRAY_SIZE(hi3516cv300_mux_clks), crg->clk_data); 195 + hisi_clk_unregister_fixed_rate(hi3516cv300_fixed_rate_clks, 196 + ARRAY_SIZE(hi3516cv300_fixed_rate_clks), crg->clk_data); 197 + } 198 + 199 + static const struct hisi_crg_funcs hi3516cv300_crg_funcs = { 200 + .register_clks = hi3516cv300_clk_register, 201 + .unregister_clks = hi3516cv300_clk_unregister, 202 + }; 203 + 204 + /* hi3516CV300 sysctrl CRG */ 205 + #define HI3516CV300_SYSCTRL_NR_CLKS 16 206 + 207 + static const char *wdt_mux_p[] __initconst = { "3m", "apb" }; 208 + static u32 wdt_mux_table[] = {0, 1}; 209 + 210 + static const struct hisi_mux_clock hi3516cv300_sysctrl_mux_clks[] = { 211 + { HI3516CV300_WDT_CLK, "wdt", wdt_mux_p, ARRAY_SIZE(wdt_mux_p), 212 + CLK_SET_RATE_PARENT, 0x0, 23, 1, 0, wdt_mux_table, }, 213 + }; 214 + 215 + static struct hisi_clock_data *hi3516cv300_sysctrl_clk_register( 216 + struct platform_device *pdev) 217 + { 218 + struct hisi_clock_data *clk_data; 219 + int ret; 220 + 221 + clk_data = hisi_clk_alloc(pdev, HI3516CV300_SYSCTRL_NR_CLKS); 222 + if (!clk_data) 223 + return ERR_PTR(-ENOMEM); 224 + 225 + ret = hisi_clk_register_mux(hi3516cv300_sysctrl_mux_clks, 226 + ARRAY_SIZE(hi3516cv300_sysctrl_mux_clks), clk_data); 227 + if (ret) 228 + return ERR_PTR(ret); 229 + 230 + 231 + ret = of_clk_add_provider(pdev->dev.of_node, 232 + of_clk_src_onecell_get, &clk_data->clk_data); 233 + if (ret) 234 + goto unregister_mux; 235 + 236 + return clk_data; 237 + 238 + unregister_mux: 239 + hisi_clk_unregister_mux(hi3516cv300_sysctrl_mux_clks, 240 + ARRAY_SIZE(hi3516cv300_sysctrl_mux_clks), clk_data); 241 + return ERR_PTR(ret); 242 + } 243 + 244 + static void hi3516cv300_sysctrl_clk_unregister(struct platform_device *pdev) 245 + { 246 + struct hisi_crg_dev *crg = platform_get_drvdata(pdev); 247 + 248 + of_clk_del_provider(pdev->dev.of_node); 249 + 250 + hisi_clk_unregister_mux(hi3516cv300_sysctrl_mux_clks, 251 + ARRAY_SIZE(hi3516cv300_sysctrl_mux_clks), 252 + crg->clk_data); 253 + } 254 + 255 + static const struct hisi_crg_funcs hi3516cv300_sysctrl_funcs = { 256 + .register_clks = hi3516cv300_sysctrl_clk_register, 257 + .unregister_clks = hi3516cv300_sysctrl_clk_unregister, 258 + }; 259 + 260 + static const struct of_device_id hi3516cv300_crg_match_table[] = { 261 + { 262 + .compatible = "hisilicon,hi3516cv300-crg", 263 + .data = &hi3516cv300_crg_funcs 264 + }, 265 + { 266 + .compatible = "hisilicon,hi3516cv300-sysctrl", 267 + .data = &hi3516cv300_sysctrl_funcs 268 + }, 269 + { } 270 + }; 271 + MODULE_DEVICE_TABLE(of, hi3516cv300_crg_match_table); 272 + 273 + static int hi3516cv300_crg_probe(struct platform_device *pdev) 274 + { 275 + struct hisi_crg_dev *crg; 276 + 277 + crg = devm_kmalloc(&pdev->dev, sizeof(*crg), GFP_KERNEL); 278 + if (!crg) 279 + return -ENOMEM; 280 + 281 + crg->funcs = of_device_get_match_data(&pdev->dev); 282 + if (!crg->funcs) 283 + return -ENOENT; 284 + 285 + crg->rstc = hisi_reset_init(pdev); 286 + if (!crg->rstc) 287 + return -ENOMEM; 288 + 289 + crg->clk_data = crg->funcs->register_clks(pdev); 290 + if (IS_ERR(crg->clk_data)) { 291 + hisi_reset_exit(crg->rstc); 292 + return PTR_ERR(crg->clk_data); 293 + } 294 + 295 + platform_set_drvdata(pdev, crg); 296 + return 0; 297 + } 298 + 299 + static int hi3516cv300_crg_remove(struct platform_device *pdev) 300 + { 301 + struct hisi_crg_dev *crg = platform_get_drvdata(pdev); 302 + 303 + hisi_reset_exit(crg->rstc); 304 + crg->funcs->unregister_clks(pdev); 305 + return 0; 306 + } 307 + 308 + static struct platform_driver hi3516cv300_crg_driver = { 309 + .probe = hi3516cv300_crg_probe, 310 + .remove = hi3516cv300_crg_remove, 311 + .driver = { 312 + .name = "hi3516cv300-crg", 313 + .of_match_table = hi3516cv300_crg_match_table, 314 + }, 315 + }; 316 + 317 + static int __init hi3516cv300_crg_init(void) 318 + { 319 + return platform_driver_register(&hi3516cv300_crg_driver); 320 + } 321 + core_initcall(hi3516cv300_crg_init); 322 + 323 + static void __exit hi3516cv300_crg_exit(void) 324 + { 325 + platform_driver_unregister(&hi3516cv300_crg_driver); 326 + } 327 + module_exit(hi3516cv300_crg_exit); 328 + 329 + MODULE_LICENSE("GPL v2"); 330 + MODULE_DESCRIPTION("HiSilicon Hi3516CV300 CRG Driver");
+337
drivers/clk/hisilicon/crg-hi3798cv200.c
··· 1 + /* 2 + * Hi3798CV200 Clock and Reset Generator Driver 3 + * 4 + * Copyright (c) 2016 HiSilicon Technologies Co., Ltd. 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 + * You should have received a copy of the GNU General Public License 17 + * along with this program. If not, see <http://www.gnu.org/licenses/>. 18 + */ 19 + 20 + #include <dt-bindings/clock/histb-clock.h> 21 + #include <linux/clk-provider.h> 22 + #include <linux/module.h> 23 + #include <linux/of_device.h> 24 + #include <linux/platform_device.h> 25 + #include "clk.h" 26 + #include "crg.h" 27 + #include "reset.h" 28 + 29 + /* hi3798CV200 core CRG */ 30 + #define HI3798CV200_INNER_CLK_OFFSET 64 31 + #define HI3798CV200_FIXED_24M 65 32 + #define HI3798CV200_FIXED_25M 66 33 + #define HI3798CV200_FIXED_50M 67 34 + #define HI3798CV200_FIXED_75M 68 35 + #define HI3798CV200_FIXED_100M 69 36 + #define HI3798CV200_FIXED_150M 70 37 + #define HI3798CV200_FIXED_200M 71 38 + #define HI3798CV200_FIXED_250M 72 39 + #define HI3798CV200_FIXED_300M 73 40 + #define HI3798CV200_FIXED_400M 74 41 + #define HI3798CV200_MMC_MUX 75 42 + #define HI3798CV200_ETH_PUB_CLK 76 43 + #define HI3798CV200_ETH_BUS_CLK 77 44 + #define HI3798CV200_ETH_BUS0_CLK 78 45 + #define HI3798CV200_ETH_BUS1_CLK 79 46 + #define HI3798CV200_COMBPHY1_MUX 80 47 + 48 + #define HI3798CV200_CRG_NR_CLKS 128 49 + 50 + static const struct hisi_fixed_rate_clock hi3798cv200_fixed_rate_clks[] = { 51 + { HISTB_OSC_CLK, "clk_osc", NULL, 0, 24000000, }, 52 + { HISTB_APB_CLK, "clk_apb", NULL, 0, 100000000, }, 53 + { HISTB_AHB_CLK, "clk_ahb", NULL, 0, 200000000, }, 54 + { HI3798CV200_FIXED_24M, "24m", NULL, 0, 24000000, }, 55 + { HI3798CV200_FIXED_25M, "25m", NULL, 0, 25000000, }, 56 + { HI3798CV200_FIXED_50M, "50m", NULL, 0, 50000000, }, 57 + { HI3798CV200_FIXED_75M, "75m", NULL, 0, 75000000, }, 58 + { HI3798CV200_FIXED_100M, "100m", NULL, 0, 100000000, }, 59 + { HI3798CV200_FIXED_150M, "150m", NULL, 0, 150000000, }, 60 + { HI3798CV200_FIXED_200M, "200m", NULL, 0, 200000000, }, 61 + { HI3798CV200_FIXED_250M, "250m", NULL, 0, 250000000, }, 62 + }; 63 + 64 + static const char *const mmc_mux_p[] = { 65 + "100m", "50m", "25m", "200m", "150m" }; 66 + static u32 mmc_mux_table[] = {0, 1, 2, 3, 6}; 67 + 68 + static const char *const comphy1_mux_p[] = { 69 + "100m", "25m"}; 70 + static u32 comphy1_mux_table[] = {2, 3}; 71 + 72 + static struct hisi_mux_clock hi3798cv200_mux_clks[] = { 73 + { HI3798CV200_MMC_MUX, "mmc_mux", mmc_mux_p, ARRAY_SIZE(mmc_mux_p), 74 + CLK_SET_RATE_PARENT, 0xa0, 8, 3, 0, mmc_mux_table, }, 75 + { HI3798CV200_COMBPHY1_MUX, "combphy1_mux", 76 + comphy1_mux_p, ARRAY_SIZE(comphy1_mux_p), 77 + CLK_SET_RATE_PARENT, 0x188, 10, 2, 0, comphy1_mux_table, }, 78 + }; 79 + 80 + static const struct hisi_gate_clock hi3798cv200_gate_clks[] = { 81 + /* UART */ 82 + { HISTB_UART2_CLK, "clk_uart2", "75m", 83 + CLK_SET_RATE_PARENT, 0x68, 4, 0, }, 84 + /* I2C */ 85 + { HISTB_I2C0_CLK, "clk_i2c0", "clk_apb", 86 + CLK_SET_RATE_PARENT, 0x6C, 4, 0, }, 87 + { HISTB_I2C1_CLK, "clk_i2c1", "clk_apb", 88 + CLK_SET_RATE_PARENT, 0x6C, 8, 0, }, 89 + { HISTB_I2C2_CLK, "clk_i2c2", "clk_apb", 90 + CLK_SET_RATE_PARENT, 0x6C, 12, 0, }, 91 + { HISTB_I2C3_CLK, "clk_i2c3", "clk_apb", 92 + CLK_SET_RATE_PARENT, 0x6C, 16, 0, }, 93 + { HISTB_I2C4_CLK, "clk_i2c4", "clk_apb", 94 + CLK_SET_RATE_PARENT, 0x6C, 20, 0, }, 95 + /* SPI */ 96 + { HISTB_SPI0_CLK, "clk_spi0", "clk_apb", 97 + CLK_SET_RATE_PARENT, 0x70, 0, 0, }, 98 + /* SDIO */ 99 + { HISTB_SDIO0_BIU_CLK, "clk_sdio0_biu", "200m", 100 + CLK_SET_RATE_PARENT, 0x9c, 0, 0, }, 101 + { HISTB_SDIO0_CIU_CLK, "clk_sdio0_ciu", "mmc_mux", 102 + CLK_SET_RATE_PARENT, 0x9c, 1, 0, }, 103 + /* EMMC */ 104 + { HISTB_MMC_BIU_CLK, "clk_mmc_biu", "200m", 105 + CLK_SET_RATE_PARENT, 0xa0, 0, 0, }, 106 + { HISTB_MMC_CIU_CLK, "clk_mmc_ciu", "mmc_mux", 107 + CLK_SET_RATE_PARENT, 0xa0, 1, 0, }, 108 + /* PCIE*/ 109 + { HISTB_PCIE_BUS_CLK, "clk_pcie_bus", "200m", 110 + CLK_SET_RATE_PARENT, 0x18c, 0, 0, }, 111 + { HISTB_PCIE_SYS_CLK, "clk_pcie_sys", "100m", 112 + CLK_SET_RATE_PARENT, 0x18c, 1, 0, }, 113 + { HISTB_PCIE_PIPE_CLK, "clk_pcie_pipe", "250m", 114 + CLK_SET_RATE_PARENT, 0x18c, 2, 0, }, 115 + { HISTB_PCIE_AUX_CLK, "clk_pcie_aux", "24m", 116 + CLK_SET_RATE_PARENT, 0x18c, 3, 0, }, 117 + /* Ethernet */ 118 + { HI3798CV200_ETH_PUB_CLK, "clk_pub", NULL, 119 + CLK_SET_RATE_PARENT, 0xcc, 5, 0, }, 120 + { HI3798CV200_ETH_BUS_CLK, "clk_bus", "clk_pub", 121 + CLK_SET_RATE_PARENT, 0xcc, 0, 0, }, 122 + { HI3798CV200_ETH_BUS0_CLK, "clk_bus_m0", "clk_bus", 123 + CLK_SET_RATE_PARENT, 0xcc, 1, 0, }, 124 + { HI3798CV200_ETH_BUS1_CLK, "clk_bus_m1", "clk_bus", 125 + CLK_SET_RATE_PARENT, 0xcc, 2, 0, }, 126 + { HISTB_ETH0_MAC_CLK, "clk_mac0", "clk_bus_m0", 127 + CLK_SET_RATE_PARENT, 0xcc, 3, 0, }, 128 + { HISTB_ETH0_MACIF_CLK, "clk_macif0", "clk_bus_m0", 129 + CLK_SET_RATE_PARENT, 0xcc, 24, 0, }, 130 + { HISTB_ETH1_MAC_CLK, "clk_mac1", "clk_bus_m1", 131 + CLK_SET_RATE_PARENT, 0xcc, 4, 0, }, 132 + { HISTB_ETH1_MACIF_CLK, "clk_macif1", "clk_bus_m1", 133 + CLK_SET_RATE_PARENT, 0xcc, 25, 0, }, 134 + /* COMBPHY1 */ 135 + { HISTB_COMBPHY1_CLK, "clk_combphy1", "combphy1_mux", 136 + CLK_SET_RATE_PARENT, 0x188, 8, 0, }, 137 + }; 138 + 139 + static struct hisi_clock_data *hi3798cv200_clk_register( 140 + struct platform_device *pdev) 141 + { 142 + struct hisi_clock_data *clk_data; 143 + int ret; 144 + 145 + clk_data = hisi_clk_alloc(pdev, HI3798CV200_CRG_NR_CLKS); 146 + if (!clk_data) 147 + return ERR_PTR(-ENOMEM); 148 + 149 + ret = hisi_clk_register_fixed_rate(hi3798cv200_fixed_rate_clks, 150 + ARRAY_SIZE(hi3798cv200_fixed_rate_clks), 151 + clk_data); 152 + if (ret) 153 + return ERR_PTR(ret); 154 + 155 + ret = hisi_clk_register_mux(hi3798cv200_mux_clks, 156 + ARRAY_SIZE(hi3798cv200_mux_clks), 157 + clk_data); 158 + if (ret) 159 + goto unregister_fixed_rate; 160 + 161 + ret = hisi_clk_register_gate(hi3798cv200_gate_clks, 162 + ARRAY_SIZE(hi3798cv200_gate_clks), 163 + clk_data); 164 + if (ret) 165 + goto unregister_mux; 166 + 167 + ret = of_clk_add_provider(pdev->dev.of_node, 168 + of_clk_src_onecell_get, &clk_data->clk_data); 169 + if (ret) 170 + goto unregister_gate; 171 + 172 + return clk_data; 173 + 174 + unregister_fixed_rate: 175 + hisi_clk_unregister_fixed_rate(hi3798cv200_fixed_rate_clks, 176 + ARRAY_SIZE(hi3798cv200_fixed_rate_clks), 177 + clk_data); 178 + 179 + unregister_mux: 180 + hisi_clk_unregister_mux(hi3798cv200_mux_clks, 181 + ARRAY_SIZE(hi3798cv200_mux_clks), 182 + clk_data); 183 + unregister_gate: 184 + hisi_clk_unregister_gate(hi3798cv200_gate_clks, 185 + ARRAY_SIZE(hi3798cv200_gate_clks), 186 + clk_data); 187 + return ERR_PTR(ret); 188 + } 189 + 190 + static void hi3798cv200_clk_unregister(struct platform_device *pdev) 191 + { 192 + struct hisi_crg_dev *crg = platform_get_drvdata(pdev); 193 + 194 + of_clk_del_provider(pdev->dev.of_node); 195 + 196 + hisi_clk_unregister_gate(hi3798cv200_gate_clks, 197 + ARRAY_SIZE(hi3798cv200_gate_clks), 198 + crg->clk_data); 199 + hisi_clk_unregister_mux(hi3798cv200_mux_clks, 200 + ARRAY_SIZE(hi3798cv200_mux_clks), 201 + crg->clk_data); 202 + hisi_clk_unregister_fixed_rate(hi3798cv200_fixed_rate_clks, 203 + ARRAY_SIZE(hi3798cv200_fixed_rate_clks), 204 + crg->clk_data); 205 + } 206 + 207 + static const struct hisi_crg_funcs hi3798cv200_crg_funcs = { 208 + .register_clks = hi3798cv200_clk_register, 209 + .unregister_clks = hi3798cv200_clk_unregister, 210 + }; 211 + 212 + /* hi3798CV200 sysctrl CRG */ 213 + 214 + #define HI3798CV200_SYSCTRL_NR_CLKS 16 215 + 216 + static const struct hisi_gate_clock hi3798cv200_sysctrl_gate_clks[] = { 217 + { HISTB_IR_CLK, "clk_ir", "100m", 218 + CLK_SET_RATE_PARENT, 0x48, 4, 0, }, 219 + { HISTB_TIMER01_CLK, "clk_timer01", "24m", 220 + CLK_SET_RATE_PARENT, 0x48, 6, 0, }, 221 + { HISTB_UART0_CLK, "clk_uart0", "75m", 222 + CLK_SET_RATE_PARENT, 0x48, 10, 0, }, 223 + }; 224 + 225 + static struct hisi_clock_data *hi3798cv200_sysctrl_clk_register( 226 + struct platform_device *pdev) 227 + { 228 + struct hisi_clock_data *clk_data; 229 + int ret; 230 + 231 + clk_data = hisi_clk_alloc(pdev, HI3798CV200_SYSCTRL_NR_CLKS); 232 + if (!clk_data) 233 + return ERR_PTR(-ENOMEM); 234 + 235 + ret = hisi_clk_register_gate(hi3798cv200_sysctrl_gate_clks, 236 + ARRAY_SIZE(hi3798cv200_sysctrl_gate_clks), 237 + clk_data); 238 + if (ret) 239 + return ERR_PTR(ret); 240 + 241 + ret = of_clk_add_provider(pdev->dev.of_node, 242 + of_clk_src_onecell_get, &clk_data->clk_data); 243 + if (ret) 244 + goto unregister_gate; 245 + 246 + return clk_data; 247 + 248 + unregister_gate: 249 + hisi_clk_unregister_gate(hi3798cv200_sysctrl_gate_clks, 250 + ARRAY_SIZE(hi3798cv200_sysctrl_gate_clks), 251 + clk_data); 252 + return ERR_PTR(ret); 253 + } 254 + 255 + static void hi3798cv200_sysctrl_clk_unregister(struct platform_device *pdev) 256 + { 257 + struct hisi_crg_dev *crg = platform_get_drvdata(pdev); 258 + 259 + of_clk_del_provider(pdev->dev.of_node); 260 + 261 + hisi_clk_unregister_gate(hi3798cv200_sysctrl_gate_clks, 262 + ARRAY_SIZE(hi3798cv200_sysctrl_gate_clks), 263 + crg->clk_data); 264 + } 265 + 266 + static const struct hisi_crg_funcs hi3798cv200_sysctrl_funcs = { 267 + .register_clks = hi3798cv200_sysctrl_clk_register, 268 + .unregister_clks = hi3798cv200_sysctrl_clk_unregister, 269 + }; 270 + 271 + static const struct of_device_id hi3798cv200_crg_match_table[] = { 272 + { .compatible = "hisilicon,hi3798cv200-crg", 273 + .data = &hi3798cv200_crg_funcs }, 274 + { .compatible = "hisilicon,hi3798cv200-sysctrl", 275 + .data = &hi3798cv200_sysctrl_funcs }, 276 + { } 277 + }; 278 + MODULE_DEVICE_TABLE(of, hi3798cv200_crg_match_table); 279 + 280 + static int hi3798cv200_crg_probe(struct platform_device *pdev) 281 + { 282 + struct hisi_crg_dev *crg; 283 + 284 + crg = devm_kmalloc(&pdev->dev, sizeof(*crg), GFP_KERNEL); 285 + if (!crg) 286 + return -ENOMEM; 287 + 288 + crg->funcs = of_device_get_match_data(&pdev->dev); 289 + if (!crg->funcs) 290 + return -ENOENT; 291 + 292 + crg->rstc = hisi_reset_init(pdev); 293 + if (!crg->rstc) 294 + return -ENOMEM; 295 + 296 + crg->clk_data = crg->funcs->register_clks(pdev); 297 + if (IS_ERR(crg->clk_data)) { 298 + hisi_reset_exit(crg->rstc); 299 + return PTR_ERR(crg->clk_data); 300 + } 301 + 302 + platform_set_drvdata(pdev, crg); 303 + return 0; 304 + } 305 + 306 + static int hi3798cv200_crg_remove(struct platform_device *pdev) 307 + { 308 + struct hisi_crg_dev *crg = platform_get_drvdata(pdev); 309 + 310 + hisi_reset_exit(crg->rstc); 311 + crg->funcs->unregister_clks(pdev); 312 + return 0; 313 + } 314 + 315 + static struct platform_driver hi3798cv200_crg_driver = { 316 + .probe = hi3798cv200_crg_probe, 317 + .remove = hi3798cv200_crg_remove, 318 + .driver = { 319 + .name = "hi3798cv200-crg", 320 + .of_match_table = hi3798cv200_crg_match_table, 321 + }, 322 + }; 323 + 324 + static int __init hi3798cv200_crg_init(void) 325 + { 326 + return platform_driver_register(&hi3798cv200_crg_driver); 327 + } 328 + core_initcall(hi3798cv200_crg_init); 329 + 330 + static void __exit hi3798cv200_crg_exit(void) 331 + { 332 + platform_driver_unregister(&hi3798cv200_crg_driver); 333 + } 334 + module_exit(hi3798cv200_crg_exit); 335 + 336 + MODULE_LICENSE("GPL v2"); 337 + MODULE_DESCRIPTION("HiSilicon Hi3798CV200 CRG Driver");
+34
drivers/clk/hisilicon/crg.h
··· 1 + /* 2 + * HiSilicon Clock and Reset Driver Header 3 + * 4 + * Copyright (c) 2016 HiSilicon Limited. 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 __HISI_CRG_H 18 + #define __HISI_CRG_H 19 + 20 + struct hisi_clock_data; 21 + struct hisi_reset_controller; 22 + 23 + struct hisi_crg_funcs { 24 + struct hisi_clock_data* (*register_clks)(struct platform_device *pdev); 25 + void (*unregister_clks)(struct platform_device *pdev); 26 + }; 27 + 28 + struct hisi_crg_dev { 29 + struct hisi_clock_data *clk_data; 30 + struct hisi_reset_controller *rstc; 31 + const struct hisi_crg_funcs *funcs; 32 + }; 33 + 34 + #endif /* __HISI_CRG_H */
+48
include/dt-bindings/clock/hi3516cv300-clock.h
··· 1 + /* 2 + * Copyright (c) 2016 HiSilicon Technologies Co., Ltd. 3 + * 4 + * This program is free software; you can redistribute it and/or modify 5 + * it under the terms of the GNU General Public License as published by 6 + * the Free Software Foundation; either version 2 of the License, or 7 + * (at your option) any later version. 8 + * 9 + * This program is distributed in the hope that it will be useful, 10 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 + * GNU General Public License for more details. 13 + * 14 + * You should have received a copy of the GNU General Public License 15 + * along with this program. If not, see <http://www.gnu.org/licenses/>. 16 + */ 17 + 18 + #ifndef __DTS_HI3516CV300_CLOCK_H 19 + #define __DTS_HI3516CV300_CLOCK_H 20 + 21 + /* hi3516CV300 core CRG */ 22 + #define HI3516CV300_APB_CLK 0 23 + #define HI3516CV300_UART0_CLK 1 24 + #define HI3516CV300_UART1_CLK 2 25 + #define HI3516CV300_UART2_CLK 3 26 + #define HI3516CV300_SPI0_CLK 4 27 + #define HI3516CV300_SPI1_CLK 5 28 + #define HI3516CV300_FMC_CLK 6 29 + #define HI3516CV300_MMC0_CLK 7 30 + #define HI3516CV300_MMC1_CLK 8 31 + #define HI3516CV300_MMC2_CLK 9 32 + #define HI3516CV300_MMC3_CLK 10 33 + #define HI3516CV300_ETH_CLK 11 34 + #define HI3516CV300_ETH_MACIF_CLK 12 35 + #define HI3516CV300_DMAC_CLK 13 36 + #define HI3516CV300_PWM_CLK 14 37 + #define HI3516CV300_USB2_BUS_CLK 15 38 + #define HI3516CV300_USB2_OHCI48M_CLK 16 39 + #define HI3516CV300_USB2_OHCI12M_CLK 17 40 + #define HI3516CV300_USB2_OTG_UTMI_CLK 18 41 + #define HI3516CV300_USB2_HST_PHY_CLK 19 42 + #define HI3516CV300_USB2_UTMI0_CLK 20 43 + #define HI3516CV300_USB2_PHY_CLK 21 44 + 45 + /* hi3516CV300 sysctrl CRG */ 46 + #define HI3516CV300_WDT_CLK 1 47 + 48 + #endif /* __DTS_HI3516CV300_CLOCK_H */
+66
include/dt-bindings/clock/histb-clock.h
··· 1 + /* 2 + * Copyright (c) 2016 HiSilicon Technologies Co., Ltd. 3 + * 4 + * This program is free software; you can redistribute it and/or modify 5 + * it under the terms of the GNU General Public License as published by 6 + * the Free Software Foundation; either version 2 of the License, or 7 + * (at your option) any later version. 8 + * 9 + * This program is distributed in the hope that it will be useful, 10 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 + * GNU General Public License for more details. 13 + * 14 + * You should have received a copy of the GNU General Public License 15 + * along with this program. If not, see <http://www.gnu.org/licenses/>. 16 + */ 17 + 18 + #ifndef __DTS_HISTB_CLOCK_H 19 + #define __DTS_HISTB_CLOCK_H 20 + 21 + /* clocks provided by core CRG */ 22 + #define HISTB_OSC_CLK 0 23 + #define HISTB_APB_CLK 1 24 + #define HISTB_AHB_CLK 2 25 + #define HISTB_UART1_CLK 3 26 + #define HISTB_UART2_CLK 4 27 + #define HISTB_UART3_CLK 5 28 + #define HISTB_I2C0_CLK 6 29 + #define HISTB_I2C1_CLK 7 30 + #define HISTB_I2C2_CLK 8 31 + #define HISTB_I2C3_CLK 9 32 + #define HISTB_I2C4_CLK 10 33 + #define HISTB_I2C5_CLK 11 34 + #define HISTB_SPI0_CLK 12 35 + #define HISTB_SPI1_CLK 13 36 + #define HISTB_SPI2_CLK 14 37 + #define HISTB_SCI_CLK 15 38 + #define HISTB_FMC_CLK 16 39 + #define HISTB_MMC_BIU_CLK 17 40 + #define HISTB_MMC_CIU_CLK 18 41 + #define HISTB_MMC_DRV_CLK 19 42 + #define HISTB_MMC_SAMPLE_CLK 20 43 + #define HISTB_SDIO0_BIU_CLK 21 44 + #define HISTB_SDIO0_CIU_CLK 22 45 + #define HISTB_SDIO0_DRV_CLK 23 46 + #define HISTB_SDIO0_SAMPLE_CLK 24 47 + #define HISTB_PCIE_AUX_CLK 25 48 + #define HISTB_PCIE_PIPE_CLK 26 49 + #define HISTB_PCIE_SYS_CLK 27 50 + #define HISTB_PCIE_BUS_CLK 28 51 + #define HISTB_ETH0_MAC_CLK 29 52 + #define HISTB_ETH0_MACIF_CLK 30 53 + #define HISTB_ETH1_MAC_CLK 31 54 + #define HISTB_ETH1_MACIF_CLK 32 55 + #define HISTB_COMBPHY1_CLK 33 56 + 57 + 58 + /* clocks provided by mcu CRG */ 59 + #define HISTB_MCE_CLK 1 60 + #define HISTB_IR_CLK 2 61 + #define HISTB_TIMER01_CLK 3 62 + #define HISTB_LEDC_CLK 4 63 + #define HISTB_UART0_CLK 5 64 + #define HISTB_LSADC_CLK 6 65 + 66 + #endif /* __DTS_HISTB_CLOCK_H */