[PATCH 1/3] phy: keystone: serdes driver for gbe 10gbe and pcie

Mark Rutland mark.rutland at arm.com
Tue Oct 13 11:33:27 PDT 2015


On Tue, Oct 13, 2015 at 02:04:22PM -0400, WingMan Kwok wrote:
> On TI's Keystone platforms, several peripherals such as the
> gbe ethernet switch, 10gbe ethernet switch and PCIe controller
> require the use of a SerDes for converting SoC parallel data into
> serialized data that can be output over a high-speed electrical
> interface, and also converting high-speed serial input data
> into parallel data that can be processed by the SoC.  The
> SerDeses used by those peripherals, though they may be different,
> are largely similar in functionality and setup.
> 
> This patch provides a SerDes phy driver implementation that can be
> used by the above mentioned peripheral drivers to configure their
> respective SerDeses.
> 
> Signed-off-by: WingMan Kwok <w-kwok2 at ti.com>
> ---
>  Documentation/devicetree/bindings/phy/ti-phy.txt |  256 +++
>  drivers/phy/Kconfig                              |    8 +
>  drivers/phy/Makefile                             |    1 +
>  drivers/phy/phy-keystone-serdes.c                | 2465 ++++++++++++++++++++++
>  4 files changed, 2730 insertions(+)
>  create mode 100644 drivers/phy/phy-keystone-serdes.c
> 
> diff --git a/Documentation/devicetree/bindings/phy/ti-phy.txt b/Documentation/devicetree/bindings/phy/ti-phy.txt
> index 9cf9446..231716e 100644
> --- a/Documentation/devicetree/bindings/phy/ti-phy.txt
> +++ b/Documentation/devicetree/bindings/phy/ti-phy.txt
> @@ -115,4 +115,260 @@ sata_phy: phy at 4A096000 {
>  	clock-names = "sysclk", "refclk";
>  	syscon-pllreset = <&scm_conf 0x3fc>;
>  	#phy-cells = <0>;
> +
> +TI Keystone SerDes PHY
> +======================
> +
> +Required properties:
> + - compatible: should be one of
> +	* "ti,keystone-serdes-gbe"
> +	* "ti,keystone-serdes-xgbe"
> +	* "ti,keystone-serdes-pcie"
> + - reg:
> +	* base address and length of the SerDes register set
> + - reg-names:
> +	* "reg_serdes"
> +		- name of the reg SerDes register set

Just describe reg in terms of reg-names, and don't bother with the
"reg_" prefix, we know this is a reg entry:

- reg: a list of address and length pairs, corresponding to entires in
  reg-names

- reg-names: should contain:
  * "serdes"

> + - #phy-cells:
> +	* From the generic phy bindings, must be 0;
> + - max-lanes:
> +	* Number of lanes in SerDes.

Why is this not "num-lanes"? Why do you even need this?

> + - phy-type: should be one of
> +	* "sgmii"
> +	* "xge"
> +	* "pcie"
> +
> +Optional properties:
> + - syscon-peripheral:
> +	* Handle to the subsystem register region of the peripheral
> +	  inside which the SerDes exists.
> + - syscon-link:
> +	* Handle to the Link register region of the peripheral inside
> +	  which the SerDes exists.  Example: it is the PCSR register
> +	  region in the case of 10gbe.
> + - refclk-khz:
> +	* Reference clock rate of SerDes in kHz.

Surely this should be an actual clock?

> + - link-rate-kbps:
> +	* SerDes link rate to be configured, in kbps.

Why does this need to be in the binding? How does one derive the correct
value?

> + - control-rate:
> +	* Lane control rate
> +		0: full rate
> +		1: half rate
> +		2: quarter rate

Likewise on both points.

> + - rx-start:
> +	* Initial lane rx equalizer attenuation and boost configurations.
> +	* Must be array of 2 integers.
> + - rx-force:
> +	* Forced lane rx equalizer attenuation and boost configurations.
> +	* Must be array of 2 integers.
> + - tx-coeff:
> +	* Lane c1, c2, cm, attenuation and regulator outpust voltage
> +	  configurations.
> +	* Must be array of 5 integers.

s/outpust/output/

> + - debug:
> +	* enable more debug messages.

NAK.

This is a driver option, and belongs on the kernel command line. It does
not describe the hardware, and does not belong in the DT.

> +Example for Keystone K2E GBE:
> +-----------------------------
> +
> +gbe_serdes0: gbe_serdes at 232a000 {
> +	#phy-cells		= <0>;
> +	compatible		= "ti,keystone-serdes-gbe";
> +	reg			= <0x0232a000 0x2000>;
> +	reg-names		= "reg_serdes";
> +	refclk-khz		= <156250>;
> +	link-rate-kbps		= <1250000>;
> +	phy-type		= "sgmii";
> +	max-lanes		= <4>;
> +	lane0 {
> +		control-rate	= <2>; /* quart */
> +		rx-start	= <7 5>;
> +		rx-force	= <1 1>;
> +		tx-coeff	= <0 0 0 12 4>;
> +		       /* c1 c2 cm att vreg */
> +	};
> +	lane1 {
> +		control-rate	= <2>; /* quart */
> +		rx-start	= <7 5>;
> +		rx-force	= <1 1>;
> +		tx-coeff	= <0 0 0 12 4>;
> +		       /* c1 c2 cm att vreg */
> +	};

The binding didn't describe the sub-nodes, and which properties belong
to them.

Don't use magic names. Define a new address space, and use reg to
identify lanes.

> +	if (of_find_property(np, "disable", NULL))
> +		lc->enable = 0;
> +	else
> +		lc->enable = 1;

This was not described in the binding, and uses the wrong accessor. What
is this for?

> +	if (of_find_property(np, "loopback", NULL))
> +		lc->loopback = 1;
> +	else
> +		lc->loopback = 0;

Likewise.

> +	if (of_property_read_bool(np, "syscon-peripheral")) {
> +		sc->peripheral_regmap =
> +			syscon_regmap_lookup_by_phandle(np,
> +							"syscon-peripheral");

Can't you always call syscon_regmap_lookup_by_phandle, then check the
return value to see if the property existed?

You clearly know that of_property_read_bool exists, why did you not use
it to read properties which are boolean?

> +	if (of_property_read_bool(np, "syscon-link")) {
> +		sc->pcsr_regmap =
> +			syscon_regmap_lookup_by_phandle(np, "syscon-link");

Likewise.

> +	sc->debug = of_property_read_bool(np, "debug");

As stated above, NAK for this property.

> +
> +	if (of_find_property(np, "rx-force-enable", NULL))
> +		sc->rx_force_enable = 1;
> +	else
> +		sc->rx_force_enable = 0;

Not in the binding, and uses the wrong accessor.

> +
> +	for (i = 0; i < sc->lanes; i++) {
> +		sprintf(&name[4], "%d", i);
> +		lp = of_find_node_by_name(np, name);
> +		if (lp) {
> +			if (kserdes_get_lane_bindings(dev, lp, &sc->lane[i]))
> +				return -EINVAL;
> +		}
> +	}

As above, use reg, not magic names.

Thanks,
Mark.



More information about the linux-arm-kernel mailing list