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 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 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, ®map_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 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