
Add a driver for RXAUI control on IHS FPGAs.
Signed-off-by: Mario Six mario.six@gdsys.cc ---
drivers/misc/Kconfig | 6 +++ drivers/misc/Makefile | 1 + drivers/misc/gdsys_rxaui_ctrl.c | 107 ++++++++++++++++++++++++++++++++++++++++ include/dm/uclass-id.h | 1 + include/gdsys_rxaui_ctrl.h | 66 +++++++++++++++++++++++++ 5 files changed, 181 insertions(+) create mode 100644 drivers/misc/gdsys_rxaui_ctrl.c create mode 100644 include/gdsys_rxaui_ctrl.h
diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig index c0e4b921b4..dd768e2a7a 100644 --- a/drivers/misc/Kconfig +++ b/drivers/misc/Kconfig @@ -215,4 +215,10 @@ config IHS_VIDEO_OUT help Support for IHS video out.
+config GDSYS_RXAUI_CTRL + bool "Enable gdsys RXAUI control driver" + depends on MISC + help + Support gdsys FPGA's RXAUI control. + endmenu diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile index eab539b739..3ff9e66da2 100644 --- a/drivers/misc/Makefile +++ b/drivers/misc/Makefile @@ -55,3 +55,4 @@ obj-$(CONFIG_ROCKCHIP_EFUSE) += rockchip-efuse.o obj-$(CONFIG_IHS_FPGA) += ihs_fpga.o gdsys_soc.o obj-$(CONFIG_IHS_AXI) += ihs_axi.o obj-$(CONFIG_IHS_VIDEO_OUT) += ihs_video_out.o +obj-$(CONFIG_GDSYS_RXAUI_CTRL) += gdsys_rxaui_ctrl.o diff --git a/drivers/misc/gdsys_rxaui_ctrl.c b/drivers/misc/gdsys_rxaui_ctrl.c new file mode 100644 index 0000000000..37fe76b857 --- /dev/null +++ b/drivers/misc/gdsys_rxaui_ctrl.c @@ -0,0 +1,107 @@ +/* + * (C) Copyright 2015 + * Dirk Eibach, Guntermann & Drunck GmbH, eibach@gdsys.de + * + * (C) Copyright 2017 + * Mario Six, Guntermann & Drunck GmbH, mario.six@gdsys.cc + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <dm.h> +#include <gdsys_soc.h> +#include <ihs_fpga.h> +#include <gdsys_rxaui_ctrl.h> + +DECLARE_GLOBAL_DATA_PTR; + +enum { + REG_RXAUI_GEN_CNT = 0x0, + REG_RXAUI_ERR_CNT = 0x2, + REG_RXAUI_SUCC_CNT = 0x4, + REG_RXAUI_STATUS = 0x6, + REG_RXAUI_CTRL_0 = 0x8, + REG_RXAUI_CTRL_1 = 0xA, +}; + +struct gdsys_rxaui_ctrl_priv { + int addr; +}; + +int rxaui_disable_polarity_inversion(struct udevice *dev) +{ + struct rxaui_ctrl_ops *ops = rxaui_ctrl_get_ops(dev); + + return ops->disable_polarity_inversion(dev); +} + +int rxaui_enable_polarity_inversion(struct udevice *dev) +{ + struct rxaui_ctrl_ops *ops = rxaui_ctrl_get_ops(dev); + + return ops->enable_polarity_inversion(dev); +} + +UCLASS_DRIVER(rxaui_ctrl) = { + .id = UCLASS_RXAUI_CTRL, + .name = "rxaui_ctrl", + .flags = DM_UC_FLAG_SEQ_ALIAS, +}; + +int gdsys_rxaui_disable_polarity_inversion(struct udevice *dev) +{ + struct gdsys_rxaui_ctrl_priv *priv = dev_get_priv(dev); + struct gdsys_soc_child_platdata *pplat = dev_get_parent_platdata(dev); + u16 val; + + val = fpga_in_le16(pplat->fpga, + priv->addr + REG_RXAUI_CTRL_1); + fpga_out_le16(pplat->fpga, priv->addr + REG_RXAUI_CTRL_1, + val & ~0x7800); + + return 0; +} + +int gdsys_rxaui_enable_polarity_inversion(struct udevice *dev) +{ + struct gdsys_rxaui_ctrl_priv *priv = dev_get_priv(dev); + struct gdsys_soc_child_platdata *pplat = dev_get_parent_platdata(dev); + u16 val; + + val = fpga_in_le16(pplat->fpga, + priv->addr + REG_RXAUI_CTRL_1); + fpga_out_le16(pplat->fpga, priv->addr + REG_RXAUI_CTRL_1, + val | 0x7800); + + return 0; +} + +static const struct rxaui_ctrl_ops gdsys_rxaui_ctrl_ops = { + .disable_polarity_inversion = gdsys_rxaui_disable_polarity_inversion, + .enable_polarity_inversion = gdsys_rxaui_enable_polarity_inversion, +}; + +int gdsys_rxaui_ctrl_probe(struct udevice *dev) +{ + struct gdsys_rxaui_ctrl_priv *priv = dev_get_priv(dev); + + priv->addr = fdtdec_get_int(gd->fdt_blob, dev_of_offset(dev), + "reg", -1); + + return 0; +} + +static const struct udevice_id gdsys_rxaui_ctrl_ids[] = { + { .compatible = "gdsys,rxaui_ctrl" }, + { } +}; + +U_BOOT_DRIVER(gdsys_rxaui_ctrl) = { + .name = "gdsys_rxaui_ctrl", + .id = UCLASS_RXAUI_CTRL, + .ops = &gdsys_rxaui_ctrl_ops, + .of_match = gdsys_rxaui_ctrl_ids, + .probe = gdsys_rxaui_ctrl_probe, + .priv_auto_alloc_size = sizeof(struct gdsys_rxaui_ctrl_priv), +}; diff --git a/include/dm/uclass-id.h b/include/dm/uclass-id.h index a40185d2bb..35e478cc74 100644 --- a/include/dm/uclass-id.h +++ b/include/dm/uclass-id.h @@ -73,6 +73,7 @@ enum uclass_id { UCLASS_REMOTEPROC, /* Remote Processor device */ UCLASS_RESET, /* Reset controller device */ UCLASS_RTC, /* Real time clock device */ + UCLASS_RXAUI_CTRL, /* gdsys RXAUI control device */ UCLASS_SCSI, /* SCSI device */ UCLASS_SERIAL, /* Serial UART */ UCLASS_SPI, /* SPI bus */ diff --git a/include/gdsys_rxaui_ctrl.h b/include/gdsys_rxaui_ctrl.h new file mode 100644 index 0000000000..29f26f5f5a --- /dev/null +++ b/include/gdsys_rxaui_ctrl.h @@ -0,0 +1,66 @@ +/* + * (C) Copyright 2017 + * Mario Six, Guntermann & Drunck GmbH, mario.six@gdsys.cc + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef _GDSYS_RXAUI_CTRL_H_ +#define _GDSYS_RXAUI_CTRL_H_ + +/** + * The GDSYS RXAUI control is a driver for the Xilinx LogiCORE IP RXAUI core + * used in gdsys IHS FPGAs, which is a low pin count 10 Gb/s interface intended + * to allow physical separation between the data-link layer and physical layer + * devices in a 10 Gb/s Ethernet system. + */ + +/** + * struct ihs_fpga_ops - driver operations for IHS RXAUI uclass + * + * Drivers should support these operations unless otherwise noted. These + * operations are intended to be used by uclass code, not directly from + * other code. + */ +struct rxaui_ctrl_ops { + /** + * disable_polarity_inversion() - Disable RX and TX polarity inversion + * on the given IHS RXAUI control + * instance + * + * @dev: The IHS RXAUI control instance. + * @return 0 if OK, -ve on error. + */ + int (*disable_polarity_inversion)(struct udevice *dev); + + /** + * enable_polarity_inversion() - Enable RX and TX polarity inversion on + * the given IHS RXAUI control instance + * + * @dev: The IHS RXAUI control instance. + * @return 0 if OK, -ve on error. + */ + int (*enable_polarity_inversion)(struct udevice *dev); +}; + +#define rxaui_ctrl_get_ops(dev) ((struct rxaui_ctrl_ops *)(dev)->driver->ops) + +/** + * rxaui_disable_polarity_inversion() - Disable RX and TX polarity inversion on + * the given IHS RXAUI control instance + * + * @dev: The IHS RXAUI control instance. + * @return 0 if OK, -ve on error. + */ +int rxaui_disable_polarity_inversion(struct udevice *dev); + +/** + * rxaui_enable_polarity_inversion() - Enable RX and TX polarity inversion on + * the given IHS RXAUI control instance + * + * @dev: The IHS RXAUI control instance. + * @return 0 if OK, -ve on error. + */ +int rxaui_enable_polarity_inversion(struct udevice *dev); + +#endif /* _GDSYS_RXAUI_CTRL_H_ */