18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-only 28c2ecf20Sopenharmony_ci/* 38c2ecf20Sopenharmony_ci * Copyright (c) 2014 Linaro Ltd. 48c2ecf20Sopenharmony_ci * Copyright (c) 2014 Hisilicon Limited. 58c2ecf20Sopenharmony_ci */ 68c2ecf20Sopenharmony_ci 78c2ecf20Sopenharmony_ci#include <linux/of_address.h> 88c2ecf20Sopenharmony_ci#include <dt-bindings/clock/hix5hd2-clock.h> 98c2ecf20Sopenharmony_ci#include <linux/slab.h> 108c2ecf20Sopenharmony_ci#include <linux/delay.h> 118c2ecf20Sopenharmony_ci#include "clk.h" 128c2ecf20Sopenharmony_ci 138c2ecf20Sopenharmony_cistatic struct hisi_fixed_rate_clock hix5hd2_fixed_rate_clks[] __initdata = { 148c2ecf20Sopenharmony_ci { HIX5HD2_FIXED_1200M, "1200m", NULL, 0, 1200000000, }, 158c2ecf20Sopenharmony_ci { HIX5HD2_FIXED_400M, "400m", NULL, 0, 400000000, }, 168c2ecf20Sopenharmony_ci { HIX5HD2_FIXED_48M, "48m", NULL, 0, 48000000, }, 178c2ecf20Sopenharmony_ci { HIX5HD2_FIXED_24M, "24m", NULL, 0, 24000000, }, 188c2ecf20Sopenharmony_ci { HIX5HD2_FIXED_600M, "600m", NULL, 0, 600000000, }, 198c2ecf20Sopenharmony_ci { HIX5HD2_FIXED_300M, "300m", NULL, 0, 300000000, }, 208c2ecf20Sopenharmony_ci { HIX5HD2_FIXED_75M, "75m", NULL, 0, 75000000, }, 218c2ecf20Sopenharmony_ci { HIX5HD2_FIXED_200M, "200m", NULL, 0, 200000000, }, 228c2ecf20Sopenharmony_ci { HIX5HD2_FIXED_100M, "100m", NULL, 0, 100000000, }, 238c2ecf20Sopenharmony_ci { HIX5HD2_FIXED_40M, "40m", NULL, 0, 40000000, }, 248c2ecf20Sopenharmony_ci { HIX5HD2_FIXED_150M, "150m", NULL, 0, 150000000, }, 258c2ecf20Sopenharmony_ci { HIX5HD2_FIXED_1728M, "1728m", NULL, 0, 1728000000, }, 268c2ecf20Sopenharmony_ci { HIX5HD2_FIXED_28P8M, "28p8m", NULL, 0, 28000000, }, 278c2ecf20Sopenharmony_ci { HIX5HD2_FIXED_432M, "432m", NULL, 0, 432000000, }, 288c2ecf20Sopenharmony_ci { HIX5HD2_FIXED_345P6M, "345p6m", NULL, 0, 345000000, }, 298c2ecf20Sopenharmony_ci { HIX5HD2_FIXED_288M, "288m", NULL, 0, 288000000, }, 308c2ecf20Sopenharmony_ci { HIX5HD2_FIXED_60M, "60m", NULL, 0, 60000000, }, 318c2ecf20Sopenharmony_ci { HIX5HD2_FIXED_750M, "750m", NULL, 0, 750000000, }, 328c2ecf20Sopenharmony_ci { HIX5HD2_FIXED_500M, "500m", NULL, 0, 500000000, }, 338c2ecf20Sopenharmony_ci { HIX5HD2_FIXED_54M, "54m", NULL, 0, 54000000, }, 348c2ecf20Sopenharmony_ci { HIX5HD2_FIXED_27M, "27m", NULL, 0, 27000000, }, 358c2ecf20Sopenharmony_ci { HIX5HD2_FIXED_1500M, "1500m", NULL, 0, 1500000000, }, 368c2ecf20Sopenharmony_ci { HIX5HD2_FIXED_375M, "375m", NULL, 0, 375000000, }, 378c2ecf20Sopenharmony_ci { HIX5HD2_FIXED_187M, "187m", NULL, 0, 187000000, }, 388c2ecf20Sopenharmony_ci { HIX5HD2_FIXED_250M, "250m", NULL, 0, 250000000, }, 398c2ecf20Sopenharmony_ci { HIX5HD2_FIXED_125M, "125m", NULL, 0, 125000000, }, 408c2ecf20Sopenharmony_ci { HIX5HD2_FIXED_2P02M, "2m", NULL, 0, 2000000, }, 418c2ecf20Sopenharmony_ci { HIX5HD2_FIXED_50M, "50m", NULL, 0, 50000000, }, 428c2ecf20Sopenharmony_ci { HIX5HD2_FIXED_25M, "25m", NULL, 0, 25000000, }, 438c2ecf20Sopenharmony_ci { HIX5HD2_FIXED_83M, "83m", NULL, 0, 83333333, }, 448c2ecf20Sopenharmony_ci}; 458c2ecf20Sopenharmony_ci 468c2ecf20Sopenharmony_cistatic const char *const sfc_mux_p[] __initconst = { 478c2ecf20Sopenharmony_ci "24m", "150m", "200m", "100m", "75m", }; 488c2ecf20Sopenharmony_cistatic u32 sfc_mux_table[] = {0, 4, 5, 6, 7}; 498c2ecf20Sopenharmony_ci 508c2ecf20Sopenharmony_cistatic const char *const sdio_mux_p[] __initconst = { 518c2ecf20Sopenharmony_ci "75m", "100m", "50m", "15m", }; 528c2ecf20Sopenharmony_cistatic u32 sdio_mux_table[] = {0, 1, 2, 3}; 538c2ecf20Sopenharmony_ci 548c2ecf20Sopenharmony_cistatic const char *const fephy_mux_p[] __initconst = { "25m", "125m"}; 558c2ecf20Sopenharmony_cistatic u32 fephy_mux_table[] = {0, 1}; 568c2ecf20Sopenharmony_ci 578c2ecf20Sopenharmony_ci 588c2ecf20Sopenharmony_cistatic struct hisi_mux_clock hix5hd2_mux_clks[] __initdata = { 598c2ecf20Sopenharmony_ci { HIX5HD2_SFC_MUX, "sfc_mux", sfc_mux_p, ARRAY_SIZE(sfc_mux_p), 608c2ecf20Sopenharmony_ci CLK_SET_RATE_PARENT, 0x5c, 8, 3, 0, sfc_mux_table, }, 618c2ecf20Sopenharmony_ci { HIX5HD2_MMC_MUX, "mmc_mux", sdio_mux_p, ARRAY_SIZE(sdio_mux_p), 628c2ecf20Sopenharmony_ci CLK_SET_RATE_PARENT, 0xa0, 8, 2, 0, sdio_mux_table, }, 638c2ecf20Sopenharmony_ci { HIX5HD2_SD_MUX, "sd_mux", sdio_mux_p, ARRAY_SIZE(sdio_mux_p), 648c2ecf20Sopenharmony_ci CLK_SET_RATE_PARENT, 0x9c, 8, 2, 0, sdio_mux_table, }, 658c2ecf20Sopenharmony_ci { HIX5HD2_FEPHY_MUX, "fephy_mux", 668c2ecf20Sopenharmony_ci fephy_mux_p, ARRAY_SIZE(fephy_mux_p), 678c2ecf20Sopenharmony_ci CLK_SET_RATE_PARENT, 0x120, 8, 2, 0, fephy_mux_table, }, 688c2ecf20Sopenharmony_ci}; 698c2ecf20Sopenharmony_ci 708c2ecf20Sopenharmony_cistatic struct hisi_gate_clock hix5hd2_gate_clks[] __initdata = { 718c2ecf20Sopenharmony_ci /* sfc */ 728c2ecf20Sopenharmony_ci { HIX5HD2_SFC_CLK, "clk_sfc", "sfc_mux", 738c2ecf20Sopenharmony_ci CLK_SET_RATE_PARENT, 0x5c, 0, 0, }, 748c2ecf20Sopenharmony_ci { HIX5HD2_SFC_RST, "rst_sfc", "clk_sfc", 758c2ecf20Sopenharmony_ci CLK_SET_RATE_PARENT, 0x5c, 4, CLK_GATE_SET_TO_DISABLE, }, 768c2ecf20Sopenharmony_ci /* sdio0 */ 778c2ecf20Sopenharmony_ci { HIX5HD2_SD_BIU_CLK, "clk_sd_biu", "200m", 788c2ecf20Sopenharmony_ci CLK_SET_RATE_PARENT, 0x9c, 0, 0, }, 798c2ecf20Sopenharmony_ci { HIX5HD2_SD_CIU_CLK, "clk_sd_ciu", "sd_mux", 808c2ecf20Sopenharmony_ci CLK_SET_RATE_PARENT, 0x9c, 1, 0, }, 818c2ecf20Sopenharmony_ci { HIX5HD2_SD_CIU_RST, "rst_sd_ciu", "clk_sd_ciu", 828c2ecf20Sopenharmony_ci CLK_SET_RATE_PARENT, 0x9c, 4, CLK_GATE_SET_TO_DISABLE, }, 838c2ecf20Sopenharmony_ci /* sdio1 */ 848c2ecf20Sopenharmony_ci { HIX5HD2_MMC_BIU_CLK, "clk_mmc_biu", "200m", 858c2ecf20Sopenharmony_ci CLK_SET_RATE_PARENT, 0xa0, 0, 0, }, 868c2ecf20Sopenharmony_ci { HIX5HD2_MMC_CIU_CLK, "clk_mmc_ciu", "mmc_mux", 878c2ecf20Sopenharmony_ci CLK_SET_RATE_PARENT, 0xa0, 1, 0, }, 888c2ecf20Sopenharmony_ci { HIX5HD2_MMC_CIU_RST, "rst_mmc_ciu", "clk_mmc_ciu", 898c2ecf20Sopenharmony_ci CLK_SET_RATE_PARENT, 0xa0, 4, CLK_GATE_SET_TO_DISABLE, }, 908c2ecf20Sopenharmony_ci /* gsf */ 918c2ecf20Sopenharmony_ci { HIX5HD2_FWD_BUS_CLK, "clk_fwd_bus", NULL, 0, 0xcc, 0, 0, }, 928c2ecf20Sopenharmony_ci { HIX5HD2_FWD_SYS_CLK, "clk_fwd_sys", "clk_fwd_bus", 0, 0xcc, 5, 0, }, 938c2ecf20Sopenharmony_ci { HIX5HD2_MAC0_PHY_CLK, "clk_fephy", "clk_fwd_sys", 948c2ecf20Sopenharmony_ci CLK_SET_RATE_PARENT, 0x120, 0, 0, }, 958c2ecf20Sopenharmony_ci /* wdg0 */ 968c2ecf20Sopenharmony_ci { HIX5HD2_WDG0_CLK, "clk_wdg0", "24m", 978c2ecf20Sopenharmony_ci CLK_SET_RATE_PARENT, 0x178, 0, 0, }, 988c2ecf20Sopenharmony_ci { HIX5HD2_WDG0_RST, "rst_wdg0", "clk_wdg0", 998c2ecf20Sopenharmony_ci CLK_SET_RATE_PARENT, 0x178, 4, CLK_GATE_SET_TO_DISABLE, }, 1008c2ecf20Sopenharmony_ci /* I2C */ 1018c2ecf20Sopenharmony_ci {HIX5HD2_I2C0_CLK, "clk_i2c0", "100m", 1028c2ecf20Sopenharmony_ci CLK_SET_RATE_PARENT, 0x06c, 4, 0, }, 1038c2ecf20Sopenharmony_ci {HIX5HD2_I2C0_RST, "rst_i2c0", "clk_i2c0", 1048c2ecf20Sopenharmony_ci CLK_SET_RATE_PARENT, 0x06c, 5, CLK_GATE_SET_TO_DISABLE, }, 1058c2ecf20Sopenharmony_ci {HIX5HD2_I2C1_CLK, "clk_i2c1", "100m", 1068c2ecf20Sopenharmony_ci CLK_SET_RATE_PARENT, 0x06c, 8, 0, }, 1078c2ecf20Sopenharmony_ci {HIX5HD2_I2C1_RST, "rst_i2c1", "clk_i2c1", 1088c2ecf20Sopenharmony_ci CLK_SET_RATE_PARENT, 0x06c, 9, CLK_GATE_SET_TO_DISABLE, }, 1098c2ecf20Sopenharmony_ci {HIX5HD2_I2C2_CLK, "clk_i2c2", "100m", 1108c2ecf20Sopenharmony_ci CLK_SET_RATE_PARENT, 0x06c, 12, 0, }, 1118c2ecf20Sopenharmony_ci {HIX5HD2_I2C2_RST, "rst_i2c2", "clk_i2c2", 1128c2ecf20Sopenharmony_ci CLK_SET_RATE_PARENT, 0x06c, 13, CLK_GATE_SET_TO_DISABLE, }, 1138c2ecf20Sopenharmony_ci {HIX5HD2_I2C3_CLK, "clk_i2c3", "100m", 1148c2ecf20Sopenharmony_ci CLK_SET_RATE_PARENT, 0x06c, 16, 0, }, 1158c2ecf20Sopenharmony_ci {HIX5HD2_I2C3_RST, "rst_i2c3", "clk_i2c3", 1168c2ecf20Sopenharmony_ci CLK_SET_RATE_PARENT, 0x06c, 17, CLK_GATE_SET_TO_DISABLE, }, 1178c2ecf20Sopenharmony_ci {HIX5HD2_I2C4_CLK, "clk_i2c4", "100m", 1188c2ecf20Sopenharmony_ci CLK_SET_RATE_PARENT, 0x06c, 20, 0, }, 1198c2ecf20Sopenharmony_ci {HIX5HD2_I2C4_RST, "rst_i2c4", "clk_i2c4", 1208c2ecf20Sopenharmony_ci CLK_SET_RATE_PARENT, 0x06c, 21, CLK_GATE_SET_TO_DISABLE, }, 1218c2ecf20Sopenharmony_ci {HIX5HD2_I2C5_CLK, "clk_i2c5", "100m", 1228c2ecf20Sopenharmony_ci CLK_SET_RATE_PARENT, 0x06c, 0, 0, }, 1238c2ecf20Sopenharmony_ci {HIX5HD2_I2C5_RST, "rst_i2c5", "clk_i2c5", 1248c2ecf20Sopenharmony_ci CLK_SET_RATE_PARENT, 0x06c, 1, CLK_GATE_SET_TO_DISABLE, }, 1258c2ecf20Sopenharmony_ci}; 1268c2ecf20Sopenharmony_ci 1278c2ecf20Sopenharmony_cienum hix5hd2_clk_type { 1288c2ecf20Sopenharmony_ci TYPE_COMPLEX, 1298c2ecf20Sopenharmony_ci TYPE_ETHER, 1308c2ecf20Sopenharmony_ci}; 1318c2ecf20Sopenharmony_ci 1328c2ecf20Sopenharmony_cistruct hix5hd2_complex_clock { 1338c2ecf20Sopenharmony_ci const char *name; 1348c2ecf20Sopenharmony_ci const char *parent_name; 1358c2ecf20Sopenharmony_ci u32 id; 1368c2ecf20Sopenharmony_ci u32 ctrl_reg; 1378c2ecf20Sopenharmony_ci u32 ctrl_clk_mask; 1388c2ecf20Sopenharmony_ci u32 ctrl_rst_mask; 1398c2ecf20Sopenharmony_ci u32 phy_reg; 1408c2ecf20Sopenharmony_ci u32 phy_clk_mask; 1418c2ecf20Sopenharmony_ci u32 phy_rst_mask; 1428c2ecf20Sopenharmony_ci enum hix5hd2_clk_type type; 1438c2ecf20Sopenharmony_ci}; 1448c2ecf20Sopenharmony_ci 1458c2ecf20Sopenharmony_cistruct hix5hd2_clk_complex { 1468c2ecf20Sopenharmony_ci struct clk_hw hw; 1478c2ecf20Sopenharmony_ci u32 id; 1488c2ecf20Sopenharmony_ci void __iomem *ctrl_reg; 1498c2ecf20Sopenharmony_ci u32 ctrl_clk_mask; 1508c2ecf20Sopenharmony_ci u32 ctrl_rst_mask; 1518c2ecf20Sopenharmony_ci void __iomem *phy_reg; 1528c2ecf20Sopenharmony_ci u32 phy_clk_mask; 1538c2ecf20Sopenharmony_ci u32 phy_rst_mask; 1548c2ecf20Sopenharmony_ci}; 1558c2ecf20Sopenharmony_ci 1568c2ecf20Sopenharmony_cistatic struct hix5hd2_complex_clock hix5hd2_complex_clks[] __initdata = { 1578c2ecf20Sopenharmony_ci {"clk_mac0", "clk_fephy", HIX5HD2_MAC0_CLK, 1588c2ecf20Sopenharmony_ci 0xcc, 0xa, 0x500, 0x120, 0, 0x10, TYPE_ETHER}, 1598c2ecf20Sopenharmony_ci {"clk_mac1", "clk_fwd_sys", HIX5HD2_MAC1_CLK, 1608c2ecf20Sopenharmony_ci 0xcc, 0x14, 0xa00, 0x168, 0x2, 0, TYPE_ETHER}, 1618c2ecf20Sopenharmony_ci {"clk_sata", NULL, HIX5HD2_SATA_CLK, 1628c2ecf20Sopenharmony_ci 0xa8, 0x1f, 0x300, 0xac, 0x1, 0x0, TYPE_COMPLEX}, 1638c2ecf20Sopenharmony_ci {"clk_usb", NULL, HIX5HD2_USB_CLK, 1648c2ecf20Sopenharmony_ci 0xb8, 0xff, 0x3f000, 0xbc, 0x7, 0x3f00, TYPE_COMPLEX}, 1658c2ecf20Sopenharmony_ci}; 1668c2ecf20Sopenharmony_ci 1678c2ecf20Sopenharmony_ci#define to_complex_clk(_hw) container_of(_hw, struct hix5hd2_clk_complex, hw) 1688c2ecf20Sopenharmony_ci 1698c2ecf20Sopenharmony_cistatic int clk_ether_prepare(struct clk_hw *hw) 1708c2ecf20Sopenharmony_ci{ 1718c2ecf20Sopenharmony_ci struct hix5hd2_clk_complex *clk = to_complex_clk(hw); 1728c2ecf20Sopenharmony_ci u32 val; 1738c2ecf20Sopenharmony_ci 1748c2ecf20Sopenharmony_ci val = readl_relaxed(clk->ctrl_reg); 1758c2ecf20Sopenharmony_ci val |= clk->ctrl_clk_mask | clk->ctrl_rst_mask; 1768c2ecf20Sopenharmony_ci writel_relaxed(val, clk->ctrl_reg); 1778c2ecf20Sopenharmony_ci val &= ~(clk->ctrl_rst_mask); 1788c2ecf20Sopenharmony_ci writel_relaxed(val, clk->ctrl_reg); 1798c2ecf20Sopenharmony_ci 1808c2ecf20Sopenharmony_ci val = readl_relaxed(clk->phy_reg); 1818c2ecf20Sopenharmony_ci val |= clk->phy_clk_mask; 1828c2ecf20Sopenharmony_ci val &= ~(clk->phy_rst_mask); 1838c2ecf20Sopenharmony_ci writel_relaxed(val, clk->phy_reg); 1848c2ecf20Sopenharmony_ci mdelay(10); 1858c2ecf20Sopenharmony_ci 1868c2ecf20Sopenharmony_ci val &= ~(clk->phy_clk_mask); 1878c2ecf20Sopenharmony_ci val |= clk->phy_rst_mask; 1888c2ecf20Sopenharmony_ci writel_relaxed(val, clk->phy_reg); 1898c2ecf20Sopenharmony_ci mdelay(10); 1908c2ecf20Sopenharmony_ci 1918c2ecf20Sopenharmony_ci val |= clk->phy_clk_mask; 1928c2ecf20Sopenharmony_ci val &= ~(clk->phy_rst_mask); 1938c2ecf20Sopenharmony_ci writel_relaxed(val, clk->phy_reg); 1948c2ecf20Sopenharmony_ci mdelay(30); 1958c2ecf20Sopenharmony_ci return 0; 1968c2ecf20Sopenharmony_ci} 1978c2ecf20Sopenharmony_ci 1988c2ecf20Sopenharmony_cistatic void clk_ether_unprepare(struct clk_hw *hw) 1998c2ecf20Sopenharmony_ci{ 2008c2ecf20Sopenharmony_ci struct hix5hd2_clk_complex *clk = to_complex_clk(hw); 2018c2ecf20Sopenharmony_ci u32 val; 2028c2ecf20Sopenharmony_ci 2038c2ecf20Sopenharmony_ci val = readl_relaxed(clk->ctrl_reg); 2048c2ecf20Sopenharmony_ci val &= ~(clk->ctrl_clk_mask); 2058c2ecf20Sopenharmony_ci writel_relaxed(val, clk->ctrl_reg); 2068c2ecf20Sopenharmony_ci} 2078c2ecf20Sopenharmony_ci 2088c2ecf20Sopenharmony_cistatic const struct clk_ops clk_ether_ops = { 2098c2ecf20Sopenharmony_ci .prepare = clk_ether_prepare, 2108c2ecf20Sopenharmony_ci .unprepare = clk_ether_unprepare, 2118c2ecf20Sopenharmony_ci}; 2128c2ecf20Sopenharmony_ci 2138c2ecf20Sopenharmony_cistatic int clk_complex_enable(struct clk_hw *hw) 2148c2ecf20Sopenharmony_ci{ 2158c2ecf20Sopenharmony_ci struct hix5hd2_clk_complex *clk = to_complex_clk(hw); 2168c2ecf20Sopenharmony_ci u32 val; 2178c2ecf20Sopenharmony_ci 2188c2ecf20Sopenharmony_ci val = readl_relaxed(clk->ctrl_reg); 2198c2ecf20Sopenharmony_ci val |= clk->ctrl_clk_mask; 2208c2ecf20Sopenharmony_ci val &= ~(clk->ctrl_rst_mask); 2218c2ecf20Sopenharmony_ci writel_relaxed(val, clk->ctrl_reg); 2228c2ecf20Sopenharmony_ci 2238c2ecf20Sopenharmony_ci val = readl_relaxed(clk->phy_reg); 2248c2ecf20Sopenharmony_ci val |= clk->phy_clk_mask; 2258c2ecf20Sopenharmony_ci val &= ~(clk->phy_rst_mask); 2268c2ecf20Sopenharmony_ci writel_relaxed(val, clk->phy_reg); 2278c2ecf20Sopenharmony_ci 2288c2ecf20Sopenharmony_ci return 0; 2298c2ecf20Sopenharmony_ci} 2308c2ecf20Sopenharmony_ci 2318c2ecf20Sopenharmony_cistatic void clk_complex_disable(struct clk_hw *hw) 2328c2ecf20Sopenharmony_ci{ 2338c2ecf20Sopenharmony_ci struct hix5hd2_clk_complex *clk = to_complex_clk(hw); 2348c2ecf20Sopenharmony_ci u32 val; 2358c2ecf20Sopenharmony_ci 2368c2ecf20Sopenharmony_ci val = readl_relaxed(clk->ctrl_reg); 2378c2ecf20Sopenharmony_ci val |= clk->ctrl_rst_mask; 2388c2ecf20Sopenharmony_ci val &= ~(clk->ctrl_clk_mask); 2398c2ecf20Sopenharmony_ci writel_relaxed(val, clk->ctrl_reg); 2408c2ecf20Sopenharmony_ci 2418c2ecf20Sopenharmony_ci val = readl_relaxed(clk->phy_reg); 2428c2ecf20Sopenharmony_ci val |= clk->phy_rst_mask; 2438c2ecf20Sopenharmony_ci val &= ~(clk->phy_clk_mask); 2448c2ecf20Sopenharmony_ci writel_relaxed(val, clk->phy_reg); 2458c2ecf20Sopenharmony_ci} 2468c2ecf20Sopenharmony_ci 2478c2ecf20Sopenharmony_cistatic const struct clk_ops clk_complex_ops = { 2488c2ecf20Sopenharmony_ci .enable = clk_complex_enable, 2498c2ecf20Sopenharmony_ci .disable = clk_complex_disable, 2508c2ecf20Sopenharmony_ci}; 2518c2ecf20Sopenharmony_ci 2528c2ecf20Sopenharmony_cistatic void __init 2538c2ecf20Sopenharmony_cihix5hd2_clk_register_complex(struct hix5hd2_complex_clock *clks, int nums, 2548c2ecf20Sopenharmony_ci struct hisi_clock_data *data) 2558c2ecf20Sopenharmony_ci{ 2568c2ecf20Sopenharmony_ci void __iomem *base = data->base; 2578c2ecf20Sopenharmony_ci int i; 2588c2ecf20Sopenharmony_ci 2598c2ecf20Sopenharmony_ci for (i = 0; i < nums; i++) { 2608c2ecf20Sopenharmony_ci struct hix5hd2_clk_complex *p_clk; 2618c2ecf20Sopenharmony_ci struct clk *clk; 2628c2ecf20Sopenharmony_ci struct clk_init_data init; 2638c2ecf20Sopenharmony_ci 2648c2ecf20Sopenharmony_ci p_clk = kzalloc(sizeof(*p_clk), GFP_KERNEL); 2658c2ecf20Sopenharmony_ci if (!p_clk) 2668c2ecf20Sopenharmony_ci return; 2678c2ecf20Sopenharmony_ci 2688c2ecf20Sopenharmony_ci init.name = clks[i].name; 2698c2ecf20Sopenharmony_ci if (clks[i].type == TYPE_ETHER) 2708c2ecf20Sopenharmony_ci init.ops = &clk_ether_ops; 2718c2ecf20Sopenharmony_ci else 2728c2ecf20Sopenharmony_ci init.ops = &clk_complex_ops; 2738c2ecf20Sopenharmony_ci 2748c2ecf20Sopenharmony_ci init.flags = 0; 2758c2ecf20Sopenharmony_ci init.parent_names = 2768c2ecf20Sopenharmony_ci (clks[i].parent_name ? &clks[i].parent_name : NULL); 2778c2ecf20Sopenharmony_ci init.num_parents = (clks[i].parent_name ? 1 : 0); 2788c2ecf20Sopenharmony_ci 2798c2ecf20Sopenharmony_ci p_clk->ctrl_reg = base + clks[i].ctrl_reg; 2808c2ecf20Sopenharmony_ci p_clk->ctrl_clk_mask = clks[i].ctrl_clk_mask; 2818c2ecf20Sopenharmony_ci p_clk->ctrl_rst_mask = clks[i].ctrl_rst_mask; 2828c2ecf20Sopenharmony_ci p_clk->phy_reg = base + clks[i].phy_reg; 2838c2ecf20Sopenharmony_ci p_clk->phy_clk_mask = clks[i].phy_clk_mask; 2848c2ecf20Sopenharmony_ci p_clk->phy_rst_mask = clks[i].phy_rst_mask; 2858c2ecf20Sopenharmony_ci p_clk->hw.init = &init; 2868c2ecf20Sopenharmony_ci 2878c2ecf20Sopenharmony_ci clk = clk_register(NULL, &p_clk->hw); 2888c2ecf20Sopenharmony_ci if (IS_ERR(clk)) { 2898c2ecf20Sopenharmony_ci kfree(p_clk); 2908c2ecf20Sopenharmony_ci pr_err("%s: failed to register clock %s\n", 2918c2ecf20Sopenharmony_ci __func__, clks[i].name); 2928c2ecf20Sopenharmony_ci continue; 2938c2ecf20Sopenharmony_ci } 2948c2ecf20Sopenharmony_ci 2958c2ecf20Sopenharmony_ci data->clk_data.clks[clks[i].id] = clk; 2968c2ecf20Sopenharmony_ci } 2978c2ecf20Sopenharmony_ci} 2988c2ecf20Sopenharmony_ci 2998c2ecf20Sopenharmony_cistatic void __init hix5hd2_clk_init(struct device_node *np) 3008c2ecf20Sopenharmony_ci{ 3018c2ecf20Sopenharmony_ci struct hisi_clock_data *clk_data; 3028c2ecf20Sopenharmony_ci 3038c2ecf20Sopenharmony_ci clk_data = hisi_clk_init(np, HIX5HD2_NR_CLKS); 3048c2ecf20Sopenharmony_ci if (!clk_data) 3058c2ecf20Sopenharmony_ci return; 3068c2ecf20Sopenharmony_ci 3078c2ecf20Sopenharmony_ci hisi_clk_register_fixed_rate(hix5hd2_fixed_rate_clks, 3088c2ecf20Sopenharmony_ci ARRAY_SIZE(hix5hd2_fixed_rate_clks), 3098c2ecf20Sopenharmony_ci clk_data); 3108c2ecf20Sopenharmony_ci hisi_clk_register_mux(hix5hd2_mux_clks, ARRAY_SIZE(hix5hd2_mux_clks), 3118c2ecf20Sopenharmony_ci clk_data); 3128c2ecf20Sopenharmony_ci hisi_clk_register_gate(hix5hd2_gate_clks, 3138c2ecf20Sopenharmony_ci ARRAY_SIZE(hix5hd2_gate_clks), clk_data); 3148c2ecf20Sopenharmony_ci hix5hd2_clk_register_complex(hix5hd2_complex_clks, 3158c2ecf20Sopenharmony_ci ARRAY_SIZE(hix5hd2_complex_clks), 3168c2ecf20Sopenharmony_ci clk_data); 3178c2ecf20Sopenharmony_ci} 3188c2ecf20Sopenharmony_ci 3198c2ecf20Sopenharmony_ciCLK_OF_DECLARE(hix5hd2_clk, "hisilicon,hix5hd2-clock", hix5hd2_clk_init); 320