On Tue, Oct 10, 2017 at 02:38:19PM +0200, Clément Leger wrote: > From ed1cbcd05d5efeb4012d77a9a4ab9c1da0449bdc Mon Sep 17 00:00:00 2001 > From: Clement Leger <clement.leger@xxxxxxxxx> > Date: Tue, 10 Oct 2017 14:29:49 +0200 > Subject: [PATCH] Marvell: implement marvell_of_reg_init > > Implement marvell_of_reg_init in order to use marvell,reg-init property > from device-tree. The code is taken from Linux kernel and slighlty > modify to fit barebox structures. > --- > drivers/net/phy/marvell.c | 73 ++++++++++++++++++++++++++++++++++++++++++++--- > 1 file changed, 69 insertions(+), 4 deletions(-) Applied, thanks Sascha > > diff --git a/drivers/net/phy/marvell.c b/drivers/net/phy/marvell.c > index ea5a4a9..73d6453 100644 > --- a/drivers/net/phy/marvell.c > +++ b/drivers/net/phy/marvell.c > @@ -175,13 +175,78 @@ static inline bool phy_interface_is_rgmii(struct phy_device *phydev) > }; > > /* > - * This same function in the Linux kernel parses the marvell,reg-init dt > - * property and does the necessary register writes. It's kept as an exercise for > - * a future user to implement this. :-) > + * Set and/or override some configuration registers based on the > + * marvell,reg-init property stored in the of_node for the phydev. > + * > + * marvell,reg-init = <reg-page reg mask value>,...; > + * > + * There may be one or more sets of <reg-page reg mask value>: > + * > + * reg-page: which register bank to use. > + * reg: the register. > + * mask: if non-zero, ANDed with existing register value. > + * value: ORed with the masked value and written to the regiser. > + * > */ > static int marvell_of_reg_init(struct phy_device *phydev) > { > - return 0; > + const __be32 *paddr; > + int len, i, saved_page, current_page, page_changed, ret; > + > + if (!phydev->dev.device_node) > + return 0; > + > + paddr = of_get_property(phydev->dev.device_node, > + "marvell,reg-init", &len); > + if (!paddr || len < (4 * sizeof(*paddr))) > + return 0; > + > + saved_page = phy_read(phydev, MII_MARVELL_PHY_PAGE); > + if (saved_page < 0) > + return saved_page; > + page_changed = 0; > + current_page = saved_page; > + > + ret = 0; > + len /= sizeof(*paddr); > + for (i = 0; i < len - 3; i += 4) { > + u16 reg_page = be32_to_cpup(paddr + i); > + u16 reg = be32_to_cpup(paddr + i + 1); > + u16 mask = be32_to_cpup(paddr + i + 2); > + u16 val_bits = be32_to_cpup(paddr + i + 3); > + int val; > + > + if (reg_page != current_page) { > + current_page = reg_page; > + page_changed = 1; > + ret = phy_write(phydev, MII_MARVELL_PHY_PAGE, reg_page); > + if (ret < 0) > + goto err; > + } > + > + val = 0; > + if (mask) { > + val = phy_read(phydev, reg); > + if (val < 0) { > + ret = val; > + goto err; > + } > + val &= mask; > + } > + val |= val_bits; > + > + ret = phy_write(phydev, reg, val); > + if (ret < 0) > + goto err; > + > + } > +err: > + if (page_changed) { > + i = phy_write(phydev, MII_MARVELL_PHY_PAGE, saved_page); > + if (ret == 0) > + ret = i; > + } > + return ret; > } > > static int m88e1121_config_aneg(struct phy_device *phydev) > -- > 1.8.3.1 > > > _______________________________________________ > barebox mailing list > barebox@xxxxxxxxxxxxxxxxxxx > http://lists.infradead.org/mailman/listinfo/barebox > -- Pengutronix e.K. | | Industrial Linux Solutions | http://www.pengutronix.de/ | Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0 | Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-5555 | _______________________________________________ barebox mailing list barebox@xxxxxxxxxxxxxxxxxxx http://lists.infradead.org/mailman/listinfo/barebox