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

Merge branch 'net-dsa-bcm_sf2-Clock-support'

Florian Fainelli says:

====================
net: dsa: bcm_sf2: Clock support

This patch series adds support for controlling the SF2 switch core and
divider clock (where applicable).
====================

Signed-off-by: David S. Miller <davem@davemloft.net>

+93 -2
+7
Documentation/devicetree/bindings/net/brcm,bcm7445-switch-v4.0.txt
··· 50 50 - reset-names: If the "reset" property is specified, this property should have 51 51 the value "switch" to denote the switch reset line. 52 52 53 + - clocks: when provided, the first phandle is to the switch's main clock and 54 + is valid for both BCM7445 and BCM7278. The second phandle is only applicable 55 + to BCM7445 and is to support dividing the switch core clock. 56 + 57 + - clock-names: when provided, the first phandle must be "sw_switch", and the 58 + second must be named "sw_switch_mdiv". 59 + 53 60 Port subnodes: 54 61 55 62 Optional properties:
+82 -2
drivers/net/dsa/bcm_sf2.c
··· 14 14 #include <linux/phy_fixed.h> 15 15 #include <linux/phylink.h> 16 16 #include <linux/mii.h> 17 + #include <linux/clk.h> 17 18 #include <linux/of.h> 18 19 #include <linux/of_irq.h> 19 20 #include <linux/of_address.h> ··· 31 30 #include "bcm_sf2_regs.h" 32 31 #include "b53/b53_priv.h" 33 32 #include "b53/b53_regs.h" 33 + 34 + /* Return the number of active ports, not counting the IMP (CPU) port */ 35 + static unsigned int bcm_sf2_num_active_ports(struct dsa_switch *ds) 36 + { 37 + struct bcm_sf2_priv *priv = bcm_sf2_to_priv(ds); 38 + unsigned int port, count = 0; 39 + 40 + for (port = 0; port < ARRAY_SIZE(priv->port_sts); port++) { 41 + if (dsa_is_cpu_port(ds, port)) 42 + continue; 43 + if (priv->port_sts[port].enabled) 44 + count++; 45 + } 46 + 47 + return count; 48 + } 49 + 50 + static void bcm_sf2_recalc_clock(struct dsa_switch *ds) 51 + { 52 + struct bcm_sf2_priv *priv = bcm_sf2_to_priv(ds); 53 + unsigned long new_rate; 54 + unsigned int ports_active; 55 + /* Frequenty in Mhz */ 56 + const unsigned long rate_table[] = { 57 + 59220000, 58 + 60820000, 59 + 62500000, 60 + 62500000, 61 + }; 62 + 63 + ports_active = bcm_sf2_num_active_ports(ds); 64 + if (ports_active == 0 || !priv->clk_mdiv) 65 + return; 66 + 67 + /* If we overflow our table, just use the recommended operational 68 + * frequency 69 + */ 70 + if (ports_active > ARRAY_SIZE(rate_table)) 71 + new_rate = 90000000; 72 + else 73 + new_rate = rate_table[ports_active - 1]; 74 + clk_set_rate(priv->clk_mdiv, new_rate); 75 + } 34 76 35 77 static void bcm_sf2_imp_setup(struct dsa_switch *ds, int port) 36 78 { ··· 126 82 reg &= ~(RX_DIS | TX_DIS); 127 83 core_writel(priv, reg, CORE_G_PCTL_PORT(port)); 128 84 } 85 + 86 + priv->port_sts[port].enabled = true; 129 87 } 130 88 131 89 static void bcm_sf2_gphy_enable_set(struct dsa_switch *ds, bool enable) ··· 212 166 213 167 if (!dsa_is_user_port(ds, port)) 214 168 return 0; 169 + 170 + priv->port_sts[port].enabled = true; 171 + 172 + bcm_sf2_recalc_clock(ds); 215 173 216 174 /* Clear the memory power down */ 217 175 reg = core_readl(priv, CORE_MEM_PSM_VDD_CTRL); ··· 310 260 reg = core_readl(priv, CORE_MEM_PSM_VDD_CTRL); 311 261 reg |= P_TXQ_PSM_VDD(port); 312 262 core_writel(priv, reg, CORE_MEM_PSM_VDD_CTRL); 263 + 264 + priv->port_sts[port].enabled = false; 265 + 266 + bcm_sf2_recalc_clock(ds); 313 267 } 314 268 315 269 ··· 804 750 bcm_sf2_port_disable(ds, port); 805 751 } 806 752 753 + if (!priv->wol_ports_mask) 754 + clk_disable_unprepare(priv->clk); 755 + 807 756 return 0; 808 757 } 809 758 ··· 814 757 { 815 758 struct bcm_sf2_priv *priv = bcm_sf2_to_priv(ds); 816 759 int ret; 760 + 761 + if (!priv->wol_ports_mask) 762 + clk_prepare_enable(priv->clk); 817 763 818 764 ret = bcm_sf2_sw_rst(priv); 819 765 if (ret) { ··· 1249 1189 base++; 1250 1190 } 1251 1191 1192 + priv->clk = devm_clk_get_optional(&pdev->dev, "sw_switch"); 1193 + if (IS_ERR(priv->clk)) 1194 + return PTR_ERR(priv->clk); 1195 + 1196 + clk_prepare_enable(priv->clk); 1197 + 1198 + priv->clk_mdiv = devm_clk_get_optional(&pdev->dev, "sw_switch_mdiv"); 1199 + if (IS_ERR(priv->clk_mdiv)) { 1200 + ret = PTR_ERR(priv->clk_mdiv); 1201 + goto out_clk; 1202 + } 1203 + 1204 + clk_prepare_enable(priv->clk_mdiv); 1205 + 1252 1206 ret = bcm_sf2_sw_rst(priv); 1253 1207 if (ret) { 1254 1208 pr_err("unable to software reset switch: %d\n", ret); 1255 - return ret; 1209 + goto out_clk_mdiv; 1256 1210 } 1257 1211 1258 1212 bcm_sf2_gphy_enable_set(priv->dev->ds, true); ··· 1274 1200 ret = bcm_sf2_mdio_register(ds); 1275 1201 if (ret) { 1276 1202 pr_err("failed to register MDIO bus\n"); 1277 - return ret; 1203 + goto out_clk_mdiv; 1278 1204 } 1279 1205 1280 1206 bcm_sf2_gphy_enable_set(priv->dev->ds, false); ··· 1341 1267 1342 1268 out_mdio: 1343 1269 bcm_sf2_mdio_unregister(priv); 1270 + out_clk_mdiv: 1271 + clk_disable_unprepare(priv->clk_mdiv); 1272 + out_clk: 1273 + clk_disable_unprepare(priv->clk); 1344 1274 return ret; 1345 1275 } 1346 1276 ··· 1358 1280 dsa_unregister_switch(priv->dev->ds); 1359 1281 bcm_sf2_cfp_exit(priv->dev->ds); 1360 1282 bcm_sf2_mdio_unregister(priv); 1283 + clk_disable_unprepare(priv->clk_mdiv); 1284 + clk_disable_unprepare(priv->clk); 1361 1285 if (priv->type == BCM7278_DEVICE_ID && !IS_ERR(priv->rcdev)) 1362 1286 reset_control_assert(priv->rcdev); 1363 1287
+4
drivers/net/dsa/bcm_sf2.h
··· 45 45 46 46 struct bcm_sf2_port_status { 47 47 unsigned int link; 48 + bool enabled; 48 49 }; 49 50 50 51 struct bcm_sf2_cfp_priv { ··· 93 92 94 93 /* Mask of ports enabled for Wake-on-LAN */ 95 94 u32 wol_ports_mask; 95 + 96 + struct clk *clk; 97 + struct clk *clk_mdiv; 96 98 97 99 /* MoCA port location */ 98 100 int moca_port;