+static int vsc8531_vsc8541_clkout_config(struct phy_device *phydev)
+{
+ struct ofnode_phandle_args phandle_args;
+ u32 clkout_rate = 0;
+ u16 reg_val;
+ int retval;
+
+ retval = dev_read_phandle_with_args(phydev->dev, "phy-handle", NULL,
+ 0, 0, &phandle_args);
+ if (!retval)
+ clkout_rate = ofnode_read_u32_default(phandle_args.node,
+ "vsc8531,clk-out-frequency", 0);
+
+ switch (clkout_rate) {
+ case 0:
+ reg_val = 0;
+ break;
+ case 25000000:
+ reg_val = CLKOUT_FREQ_25M | CLKOUT_ENABLE;
+ break;
+ case 50000000:
+ reg_val = CLKOUT_FREQ_50M | CLKOUT_ENABLE;
+ break;
+ case 125000000:
+ reg_val = CLKOUT_FREQ_125M | CLKOUT_ENABLE;
+ break;
+ default:
+ printf("PHY 8530/31 invalid clkout rate %u\n",
+ clkout_rate);
+ return -EINVAL;
+ }
+
+ phy_write(phydev, MDIO_DEVAD_NONE, MSCC_EXT_PAGE_ACCESS,
+ MSCC_PHY_PAGE_GPIO);
+ phy_write(phydev, MDIO_DEVAD_NONE, MSCC_CLKOUT_CNTL, reg_val);
+ phy_write(phydev, MDIO_DEVAD_NONE, MSCC_EXT_PAGE_ACCESS,
+ MSCC_PHY_PAGE_STD);
+
+ return 0;
+}
+