]>
Commit | Line | Data |
---|---|---|
1802d0be | 1 | // SPDX-License-Identifier: GPL-2.0-only |
2fc0a509 SW |
2 | /* |
3 | * Copyright (c) 2017 MediaTek Inc. | |
4 | * Author: Chen Zhong <chen.zhong@mediatek.com> | |
5 | * Sean Wang <sean.wang@mediatek.com> | |
2fc0a509 SW |
6 | */ |
7 | ||
8 | #include <linux/clk-provider.h> | |
9 | #include <linux/of.h> | |
10 | #include <linux/of_address.h> | |
11 | #include <linux/of_device.h> | |
12 | #include <linux/platform_device.h> | |
13 | ||
14 | #include "clk-mtk.h" | |
15 | #include "clk-gate.h" | |
16 | ||
17 | #include <dt-bindings/clock/mt7622-clk.h> | |
18 | ||
19 | #define GATE_PCIE(_id, _name, _parent, _shift) { \ | |
20 | .id = _id, \ | |
21 | .name = _name, \ | |
22 | .parent_name = _parent, \ | |
23 | .regs = &pcie_cg_regs, \ | |
24 | .shift = _shift, \ | |
25 | .ops = &mtk_clk_gate_ops_no_setclr_inv, \ | |
26 | } | |
27 | ||
28 | #define GATE_SSUSB(_id, _name, _parent, _shift) { \ | |
29 | .id = _id, \ | |
30 | .name = _name, \ | |
31 | .parent_name = _parent, \ | |
32 | .regs = &ssusb_cg_regs, \ | |
33 | .shift = _shift, \ | |
34 | .ops = &mtk_clk_gate_ops_no_setclr_inv, \ | |
35 | } | |
36 | ||
37 | static const struct mtk_gate_regs pcie_cg_regs = { | |
38 | .set_ofs = 0x30, | |
39 | .clr_ofs = 0x30, | |
40 | .sta_ofs = 0x30, | |
41 | }; | |
42 | ||
43 | static const struct mtk_gate_regs ssusb_cg_regs = { | |
44 | .set_ofs = 0x30, | |
45 | .clr_ofs = 0x30, | |
46 | .sta_ofs = 0x30, | |
47 | }; | |
48 | ||
49 | static const struct mtk_gate ssusb_clks[] = { | |
50 | GATE_SSUSB(CLK_SSUSB_U2_PHY_1P_EN, "ssusb_u2_phy_1p", | |
51 | "to_u2_phy_1p", 0), | |
52 | GATE_SSUSB(CLK_SSUSB_U2_PHY_EN, "ssusb_u2_phy_en", "to_u2_phy", 1), | |
53 | GATE_SSUSB(CLK_SSUSB_REF_EN, "ssusb_ref_en", "to_usb3_ref", 5), | |
54 | GATE_SSUSB(CLK_SSUSB_SYS_EN, "ssusb_sys_en", "to_usb3_sys", 6), | |
55 | GATE_SSUSB(CLK_SSUSB_MCU_EN, "ssusb_mcu_en", "axi_sel", 7), | |
56 | GATE_SSUSB(CLK_SSUSB_DMA_EN, "ssusb_dma_en", "hif_sel", 8), | |
57 | }; | |
58 | ||
59 | static const struct mtk_gate pcie_clks[] = { | |
60 | GATE_PCIE(CLK_PCIE_P1_AUX_EN, "pcie_p1_aux_en", "p1_1mhz", 12), | |
61 | GATE_PCIE(CLK_PCIE_P1_OBFF_EN, "pcie_p1_obff_en", "free_run_4mhz", 13), | |
62 | GATE_PCIE(CLK_PCIE_P1_AHB_EN, "pcie_p1_ahb_en", "axi_sel", 14), | |
63 | GATE_PCIE(CLK_PCIE_P1_AXI_EN, "pcie_p1_axi_en", "hif_sel", 15), | |
64 | GATE_PCIE(CLK_PCIE_P1_MAC_EN, "pcie_p1_mac_en", "pcie1_mac_en", 16), | |
65 | GATE_PCIE(CLK_PCIE_P1_PIPE_EN, "pcie_p1_pipe_en", "pcie1_pipe_en", 17), | |
66 | GATE_PCIE(CLK_PCIE_P0_AUX_EN, "pcie_p0_aux_en", "p0_1mhz", 18), | |
67 | GATE_PCIE(CLK_PCIE_P0_OBFF_EN, "pcie_p0_obff_en", "free_run_4mhz", 19), | |
68 | GATE_PCIE(CLK_PCIE_P0_AHB_EN, "pcie_p0_ahb_en", "axi_sel", 20), | |
69 | GATE_PCIE(CLK_PCIE_P0_AXI_EN, "pcie_p0_axi_en", "hif_sel", 21), | |
70 | GATE_PCIE(CLK_PCIE_P0_MAC_EN, "pcie_p0_mac_en", "pcie0_mac_en", 22), | |
71 | GATE_PCIE(CLK_PCIE_P0_PIPE_EN, "pcie_p0_pipe_en", "pcie0_pipe_en", 23), | |
72 | GATE_PCIE(CLK_SATA_AHB_EN, "sata_ahb_en", "axi_sel", 26), | |
73 | GATE_PCIE(CLK_SATA_AXI_EN, "sata_axi_en", "hif_sel", 27), | |
74 | GATE_PCIE(CLK_SATA_ASIC_EN, "sata_asic_en", "sata_asic", 28), | |
75 | GATE_PCIE(CLK_SATA_RBC_EN, "sata_rbc_en", "sata_rbc", 29), | |
76 | GATE_PCIE(CLK_SATA_PM_EN, "sata_pm_en", "univpll2_d4", 30), | |
77 | }; | |
78 | ||
79 | static int clk_mt7622_ssusbsys_init(struct platform_device *pdev) | |
80 | { | |
81 | struct clk_onecell_data *clk_data; | |
82 | struct device_node *node = pdev->dev.of_node; | |
83 | int r; | |
84 | ||
85 | clk_data = mtk_alloc_clk_data(CLK_SSUSB_NR_CLK); | |
86 | ||
87 | mtk_clk_register_gates(node, ssusb_clks, ARRAY_SIZE(ssusb_clks), | |
88 | clk_data); | |
89 | ||
90 | r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data); | |
91 | if (r) | |
92 | dev_err(&pdev->dev, | |
93 | "could not register clock provider: %s: %d\n", | |
94 | pdev->name, r); | |
95 | ||
96 | mtk_register_reset_controller(node, 1, 0x34); | |
97 | ||
98 | return r; | |
99 | } | |
100 | ||
101 | static int clk_mt7622_pciesys_init(struct platform_device *pdev) | |
102 | { | |
103 | struct clk_onecell_data *clk_data; | |
104 | struct device_node *node = pdev->dev.of_node; | |
105 | int r; | |
106 | ||
107 | clk_data = mtk_alloc_clk_data(CLK_PCIE_NR_CLK); | |
108 | ||
109 | mtk_clk_register_gates(node, pcie_clks, ARRAY_SIZE(pcie_clks), | |
110 | clk_data); | |
111 | ||
112 | r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data); | |
113 | if (r) | |
114 | dev_err(&pdev->dev, | |
115 | "could not register clock provider: %s: %d\n", | |
116 | pdev->name, r); | |
117 | ||
118 | mtk_register_reset_controller(node, 1, 0x34); | |
119 | ||
120 | return r; | |
121 | } | |
122 | ||
123 | static const struct of_device_id of_match_clk_mt7622_hif[] = { | |
124 | { | |
125 | .compatible = "mediatek,mt7622-pciesys", | |
126 | .data = clk_mt7622_pciesys_init, | |
127 | }, { | |
128 | .compatible = "mediatek,mt7622-ssusbsys", | |
129 | .data = clk_mt7622_ssusbsys_init, | |
130 | }, { | |
131 | /* sentinel */ | |
132 | } | |
133 | }; | |
134 | ||
135 | static int clk_mt7622_hif_probe(struct platform_device *pdev) | |
136 | { | |
137 | int (*clk_init)(struct platform_device *); | |
138 | int r; | |
139 | ||
140 | clk_init = of_device_get_match_data(&pdev->dev); | |
141 | if (!clk_init) | |
142 | return -EINVAL; | |
143 | ||
144 | r = clk_init(pdev); | |
145 | if (r) | |
146 | dev_err(&pdev->dev, | |
147 | "could not register clock provider: %s: %d\n", | |
148 | pdev->name, r); | |
149 | ||
150 | return r; | |
151 | } | |
152 | ||
153 | static struct platform_driver clk_mt7622_hif_drv = { | |
154 | .probe = clk_mt7622_hif_probe, | |
155 | .driver = { | |
156 | .name = "clk-mt7622-hif", | |
157 | .of_match_table = of_match_clk_mt7622_hif, | |
158 | }, | |
159 | }; | |
160 | ||
161 | builtin_platform_driver(clk_mt7622_hif_drv); |