[PATCH 4/4] phy: miphy365x: Provide support for the MiPHY356x Generic PHY

Lee Jones lee.jones at linaro.org
Thu Feb 13 05:29:55 EST 2014


> > The MiPHY365x is a Generic PHY which can serve various SATA or PCIe
> > devices. It has 2 ports which it can use for either; both SATA, both
> 
> various SATA or PCIe devices in STMicroelectronics STiH41x SoC series?

To tell you the truth, I'm not sure if it is limited to ST's h/w, but
I think it can only be found there, so I'm happy to fixup.

<snip>

> > +config PHY_MIPHY365X
> > +	tristate "STMicroelectronics MIPHY365X PHY driver for STiH41x series"
> > +	depends on ARCH_STI
> > +	depends on GENERIC_PHY
> depends on CONFIG_OF and HAS_IOMEM?

Sure, I'll fix.

<snip>

> > + * Copyright (C) 2014 STMicroelectronics
> > + *
> > + * STMicroelectronics PHY driver MiPHY365 (for SoC STiH416).
> > + *
> > + * Author: Alexandre Torgue <alexandre.torgue at st.com>
> 
> The author of this patch is not Alexandre Torgue?

The history of this driver is long and the authors are many. Alex
did the last internal over-haul and converted it to use Generic PHY. I
took Alex's driver and made significant changes in order to upstream.

<snip>

> > +#define HFC_TIMEOUT		50
> > +
> > +#define SYSCFG_2521		0x824
> > +#define SYSCFG_2522		0x828
> > +#define SYSCFG_PCIE_SATA_MASK	BIT(1)
> > +#define SYSCFG_PCIE_SATA_POS	1
> > +
> > +/* MiPHY365x register definitiona */
> > +#define RESET_REG		0x00
> > +#define RST_PLL			BIT(1)
> 
> There are quite a few alignment problems with these macros. It needs
> to be fixed.

This is just Git playing up.

In reality everything is perfectly aligned and all using tabs.

<snip>

> > +/*
> > + * This function selects the system configuration,
> > + * either two SATA, one SATA and one PCIe, or two PCIe lanes.
> > + */
> > +static int miphy365x_set_path(struct miphy365x_phy *miphy_phy,
> > +			      struct miphy365x_dev *miphy_dev)
> > +{
> > +	u8 config = miphy_phy->type | miphy_phy->port;
> > +	u32 mask  = SYSCFG_PCIE_SATA_MASK;
> > +	u32 reg;
> > +	bool sata;
> > +
> > +	switch (config) {
> > +	case MIPHY_SATA_PORT0:
> > +		reg = SYSCFG_2521;
> > +		sata = true;
> 
> How do we configure PORT1 for SATA here? Do we really support all the system
> configuration?

Good spot eagle-eye!

Actually in the current version there is a h/w bug which only allows
the SATA_PORT0 and PCIE_PORT1 configuration. When a new version fixing
this is released I will add version detection to the driver and we can
support full intended configuration options. 

<snip>

> > +static inline int miphy365x_phy_hfc_not_rdy(struct miphy365x_phy *miphy_phy,
> > +					    struct miphy365x_dev *miphy_dev)
> > +{
> > +	int timeout = HFC_TIMEOUT;
> > +	u8 mask = IDLL_RDY | PLL_RDY;
> > +	u8 regval;
> > +
> > +	do {
> > +		regval = readb_relaxed(miphy_phy->base + STATUS_REG);
> > +		usleep_range(2000, 2500);
> 
> Any comment on how this delay value is obtained?

I don't have any specific comments, I believe the 2000us it taken from
the datasheet and the 2500 is us playing nice with the scheduler.

<snip>

> > +static inline int miphy365x_phy_rdy(struct miphy365x_phy *miphy_phy,
> > +				    struct miphy365x_dev *miphy_dev)
> > +{
> > +	int timeout = HFC_TIMEOUT;
> > +	u8 mask = mask = IDLL_RDY | PLL_RDY;
> 
> just u8 mask = IDLL_RDY | PLL_RDY; would suffice.

Hmm... not sure how this slipped through - will fix.

> > +	u8 regval;
> > +
> > +	do {
> > +		regval = readb_relaxed(miphy_phy->base + STATUS_REG);
> > +		usleep_range(2000, 2500);
> 
> same here.

As above.

<snip>

> > +	mask = DES_BIT_LOCK | DES_SYMBOL_LOCK;
> > +	while ((readb_relaxed(miphy_phy->base + COMP_CTRL1_REG) & mask)	!= mask)
> > +		cpu_relax();
> 
> Don't we need to break from here at some point if the LOCK's are never set?

I'm sure sure that's possible, but I will invesigate and fixup if req'd.

<snip>

> > +static int miphy365x_phy_power_on(struct phy *phy)
> > +{
> > +	return 0;
> > +}
> > +
> > +static int miphy365x_phy_power_off(struct phy *phy)
> > +{
> > +	return 0;
> > +}
> 
> Both these empty functions can be removed.

You're right, I see the NULL checks, thanks.

<snip>

> > +static int miphy365x_phy_get_base_addr(struct platform_device *pdev,
> > +				       struct miphy365x_phy *phy, u8 port)
> > +{
> > +	struct resource *res;
> > +	char sata[16];
> > +	char pcie[16];
> 
> It can be done with a single variable ;-)

Right. :)

<snip>

> Phy provider register should be the last step in registering the PHY.

Okay, will fix, thanks.

-- 
Lee Jones
Linaro STMicroelectronics Landing Team Lead
Linaro.org │ Open source software for ARM SoCs
Follow Linaro: Facebook | Twitter | Blog



More information about the linux-arm-kernel mailing list