xref: /linux/drivers/net/ethernet/qualcomm/ppe/ppe.c (revision 91ec2035134982b98fab0609a9fd8480e8217dc1)
1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3  * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
4  */
5 
6 /* PPE platform device probe, DTSI parser and PPE clock initializations. */
7 
8 #include <linux/clk.h>
9 #include <linux/interconnect.h>
10 #include <linux/kernel.h>
11 #include <linux/module.h>
12 #include <linux/of.h>
13 #include <linux/platform_device.h>
14 #include <linux/regmap.h>
15 #include <linux/reset.h>
16 
17 #include "ppe.h"
18 #include "ppe_config.h"
19 #include "ppe_debugfs.h"
20 
21 #define PPE_PORT_MAX		8
22 #define PPE_CLK_RATE		353000000
23 
24 /* ICC clocks for enabling PPE device. The avg_bw and peak_bw with value 0
25  * will be updated by the clock rate of PPE.
26  */
27 static const struct icc_bulk_data ppe_icc_data[] = {
28 	{
29 		.name = "ppe",
30 		.avg_bw = 0,
31 		.peak_bw = 0,
32 	},
33 	{
34 		.name = "ppe_cfg",
35 		.avg_bw = 0,
36 		.peak_bw = 0,
37 	},
38 	{
39 		.name = "qos_gen",
40 		.avg_bw = 6000,
41 		.peak_bw = 6000,
42 	},
43 	{
44 		.name = "timeout_ref",
45 		.avg_bw = 6000,
46 		.peak_bw = 6000,
47 	},
48 	{
49 		.name = "nssnoc_memnoc",
50 		.avg_bw = 533333,
51 		.peak_bw = 533333,
52 	},
53 	{
54 		.name = "memnoc_nssnoc",
55 		.avg_bw = 533333,
56 		.peak_bw = 533333,
57 	},
58 	{
59 		.name = "memnoc_nssnoc_1",
60 		.avg_bw = 533333,
61 		.peak_bw = 533333,
62 	},
63 };
64 
65 static const struct regmap_range ppe_readable_ranges[] = {
66 	regmap_reg_range(0x0, 0x1ff),		/* Global */
67 	regmap_reg_range(0x400, 0x5ff),		/* LPI CSR */
68 	regmap_reg_range(0x1000, 0x11ff),	/* GMAC0 */
69 	regmap_reg_range(0x1200, 0x13ff),	/* GMAC1 */
70 	regmap_reg_range(0x1400, 0x15ff),	/* GMAC2 */
71 	regmap_reg_range(0x1600, 0x17ff),	/* GMAC3 */
72 	regmap_reg_range(0x1800, 0x19ff),	/* GMAC4 */
73 	regmap_reg_range(0x1a00, 0x1bff),	/* GMAC5 */
74 	regmap_reg_range(0xb000, 0xefff),	/* PRX CSR */
75 	regmap_reg_range(0xf000, 0x1efff),	/* IPE */
76 	regmap_reg_range(0x20000, 0x5ffff),	/* PTX CSR */
77 	regmap_reg_range(0x60000, 0x9ffff),	/* IPE L2 CSR */
78 	regmap_reg_range(0xb0000, 0xeffff),	/* IPO CSR */
79 	regmap_reg_range(0x100000, 0x17ffff),	/* IPE PC */
80 	regmap_reg_range(0x180000, 0x1bffff),	/* PRE IPO CSR */
81 	regmap_reg_range(0x1d0000, 0x1dffff),	/* Tunnel parser */
82 	regmap_reg_range(0x1e0000, 0x1effff),	/* Ingress parse */
83 	regmap_reg_range(0x200000, 0x2fffff),	/* IPE L3 */
84 	regmap_reg_range(0x300000, 0x3fffff),	/* IPE tunnel */
85 	regmap_reg_range(0x400000, 0x4fffff),	/* Scheduler */
86 	regmap_reg_range(0x500000, 0x503fff),	/* XGMAC0 */
87 	regmap_reg_range(0x504000, 0x507fff),	/* XGMAC1 */
88 	regmap_reg_range(0x508000, 0x50bfff),	/* XGMAC2 */
89 	regmap_reg_range(0x50c000, 0x50ffff),	/* XGMAC3 */
90 	regmap_reg_range(0x510000, 0x513fff),	/* XGMAC4 */
91 	regmap_reg_range(0x514000, 0x517fff),	/* XGMAC5 */
92 	regmap_reg_range(0x600000, 0x6fffff),	/* BM */
93 	regmap_reg_range(0x800000, 0x9fffff),	/* QM */
94 	regmap_reg_range(0xb00000, 0xbef800),	/* EDMA */
95 };
96 
97 static const struct regmap_access_table ppe_reg_table = {
98 	.yes_ranges = ppe_readable_ranges,
99 	.n_yes_ranges = ARRAY_SIZE(ppe_readable_ranges),
100 };
101 
102 static const struct regmap_config regmap_config_ipq9574 = {
103 	.reg_bits = 32,
104 	.reg_stride = 4,
105 	.val_bits = 32,
106 	.rd_table = &ppe_reg_table,
107 	.wr_table = &ppe_reg_table,
108 	.max_register = 0xbef800,
109 };
110 
ppe_clock_init_and_reset(struct ppe_device * ppe_dev)111 static int ppe_clock_init_and_reset(struct ppe_device *ppe_dev)
112 {
113 	unsigned long ppe_rate = ppe_dev->clk_rate;
114 	struct device *dev = ppe_dev->dev;
115 	struct reset_control *rstc;
116 	struct clk_bulk_data *clks;
117 	struct clk *clk;
118 	int ret, i;
119 
120 	for (i = 0; i < ppe_dev->num_icc_paths; i++) {
121 		ppe_dev->icc_paths[i].name = ppe_icc_data[i].name;
122 		ppe_dev->icc_paths[i].avg_bw = ppe_icc_data[i].avg_bw ? :
123 					       Bps_to_icc(ppe_rate);
124 
125 		/* PPE does not have an explicit peak bandwidth requirement,
126 		 * so set the peak bandwidth to be equal to the average
127 		 * bandwidth.
128 		 */
129 		ppe_dev->icc_paths[i].peak_bw = ppe_icc_data[i].peak_bw ? :
130 						Bps_to_icc(ppe_rate);
131 	}
132 
133 	ret = devm_of_icc_bulk_get(dev, ppe_dev->num_icc_paths,
134 				   ppe_dev->icc_paths);
135 	if (ret)
136 		return ret;
137 
138 	ret = icc_bulk_set_bw(ppe_dev->num_icc_paths, ppe_dev->icc_paths);
139 	if (ret)
140 		return ret;
141 
142 	/* The PPE clocks have a common parent clock. Setting the clock
143 	 * rate of "ppe" ensures the clock rate of all PPE clocks is
144 	 * configured to the same rate.
145 	 */
146 	clk = devm_clk_get(dev, "ppe");
147 	if (IS_ERR(clk))
148 		return PTR_ERR(clk);
149 
150 	ret = clk_set_rate(clk, ppe_rate);
151 	if (ret)
152 		return ret;
153 
154 	ret = devm_clk_bulk_get_all_enabled(dev, &clks);
155 	if (ret < 0)
156 		return ret;
157 
158 	/* Reset the PPE. */
159 	rstc = devm_reset_control_get_exclusive(dev, NULL);
160 	if (IS_ERR(rstc))
161 		return PTR_ERR(rstc);
162 
163 	ret = reset_control_assert(rstc);
164 	if (ret)
165 		return ret;
166 
167 	/* The delay 10 ms of assert is necessary for resetting PPE. */
168 	usleep_range(10000, 11000);
169 
170 	return reset_control_deassert(rstc);
171 }
172 
qcom_ppe_probe(struct platform_device * pdev)173 static int qcom_ppe_probe(struct platform_device *pdev)
174 {
175 	struct device *dev = &pdev->dev;
176 	struct ppe_device *ppe_dev;
177 	void __iomem *base;
178 	int ret, num_icc;
179 
180 	num_icc = ARRAY_SIZE(ppe_icc_data);
181 	ppe_dev = devm_kzalloc(dev, struct_size(ppe_dev, icc_paths, num_icc),
182 			       GFP_KERNEL);
183 	if (!ppe_dev)
184 		return -ENOMEM;
185 
186 	base = devm_platform_ioremap_resource(pdev, 0);
187 	if (IS_ERR(base))
188 		return dev_err_probe(dev, PTR_ERR(base), "PPE ioremap failed\n");
189 
190 	ppe_dev->regmap = devm_regmap_init_mmio(dev, base, &regmap_config_ipq9574);
191 	if (IS_ERR(ppe_dev->regmap))
192 		return dev_err_probe(dev, PTR_ERR(ppe_dev->regmap),
193 				     "PPE initialize regmap failed\n");
194 	ppe_dev->dev = dev;
195 	ppe_dev->clk_rate = PPE_CLK_RATE;
196 	ppe_dev->num_ports = PPE_PORT_MAX;
197 	ppe_dev->num_icc_paths = num_icc;
198 
199 	ret = ppe_clock_init_and_reset(ppe_dev);
200 	if (ret)
201 		return dev_err_probe(dev, ret, "PPE clock config failed\n");
202 
203 	ret = ppe_hw_config(ppe_dev);
204 	if (ret)
205 		return dev_err_probe(dev, ret, "PPE HW config failed\n");
206 
207 	ppe_debugfs_setup(ppe_dev);
208 	platform_set_drvdata(pdev, ppe_dev);
209 
210 	return 0;
211 }
212 
qcom_ppe_remove(struct platform_device * pdev)213 static void qcom_ppe_remove(struct platform_device *pdev)
214 {
215 	struct ppe_device *ppe_dev;
216 
217 	ppe_dev = platform_get_drvdata(pdev);
218 	ppe_debugfs_teardown(ppe_dev);
219 }
220 
221 static const struct of_device_id qcom_ppe_of_match[] = {
222 	{ .compatible = "qcom,ipq9574-ppe" },
223 	{}
224 };
225 MODULE_DEVICE_TABLE(of, qcom_ppe_of_match);
226 
227 static struct platform_driver qcom_ppe_driver = {
228 	.driver = {
229 		.name = "qcom_ppe",
230 		.of_match_table = qcom_ppe_of_match,
231 	},
232 	.probe	= qcom_ppe_probe,
233 	.remove = qcom_ppe_remove,
234 };
235 module_platform_driver(qcom_ppe_driver);
236 
237 MODULE_LICENSE("GPL");
238 MODULE_DESCRIPTION("Qualcomm Technologies, Inc. IPQ PPE driver");
239