All of lore.kernel.org
 help / color / mirror / Atom feed
* [U-Boot] [PATCH 00/51] gdsys: Add support for Gazerbeam board
@ 2017-07-14 12:54 Mario Six
  2017-07-14 12:54 ` [U-Boot] [PATCH 01/51] i2c: fsl_i2c: Fix style violations Mario Six
                   ` (50 more replies)
  0 siblings, 51 replies; 138+ messages in thread
From: Mario Six @ 2017-07-14 12:54 UTC (permalink / raw)
  To: u-boot

This patch series adds support for the gdsys Gazerbeam board. This is the first
gdsys board with full DM support, so a number of new DM drivers--as well as
uclasses--are introduced to accomodate the move of driver code from
board/gdsys/common. There are also some minor issues that are addressed that
mostly concern DM-support on the MPC83xx platform.

Finally, style issues are fixed in several locations to improve allover code
quality.

Dirk Eibach (6):
  phy: Allow forcing clause 45 access
  phy: Support Marvell 88X2242
  net:phy:marvell Add hook for m88e1510 board config
  strider,hrcon: Reset CAT phy on CON2 module
  gdsys:phy: Adapt fixup_88e1518() to latest Release Notes
  mpc83xx: Add gazerbeam board

Mario Six (45):
  i2c: fsl_i2c: Fix style violations
  i2c: fsl_i2c: Remove inline declarations
  gdsys: Post ppc4xx removal cleanup
  net: phy: marvell: Fix style violations
  net: phy: marvell 88e151x: Fix handling of bare RGMII interface type
  cmd: Add command for calculating binary operations
  phy: Fix style violations
  powerpc: mpc83xx: Implement get_serial_clock()
  cfi_flash: Fix style violations
  cfi_flash: Clean up code some more
  cfi_flash: Always define cfi_flash_num_flash_banks
  gpio: mpc85xx_gpio: Fix style violations
  gpio: mpc85xx_gpio: Make compatible with MPC8XXX
  cmd: mdio: Fix style violations
  cmd: mdio: Add 'driver' subcommand
  common: board_f: Fix style violations
  common: board_r: Fix style violations
  common: Extend board-specific DT fixup
  gdsys: mpc8308: Fix style violations
  gdsys: mpc8308: Use shadow register for output GPIO values
  gdsys: mpc8308: Move SYS_FPGA{0,1}_{BASE,SIZE} to Kconfig
  gdsys: Introduce GDSYS_LEGACY_DRIVERS
  i2c: ihs_i2c: Prepare DM conversion
  i2c: ihs_i2c: Make DM compatible
  i2c: ihs_i2c: Factor out send_buffer method
  gdsys: mpc8308: Add FPGA flavor option
  drivers: Add ihs_fpga and gdsys_soc drivers
  drivers: Add transmitter uclass
  transmitter: Add Xilinx LogiCore DP TX
  drivers: Add ICS8N3QV01 driver
  drivers: Add ihs_axi driver
  drivers: Add ihs_video_out driver
  gdsys: drivers: Add gdsys_rxaui_ctrl driver
  drivers: Add gdsys_ioep driver
  cmd: Add ihs osd commands
  cmd: Add ihs axi command
  cmd: Add ihs fpga command
  gdsys: cmd_ioloop: Fix style violations
  gdsys: cmd_ioloop: Introduce commenting enum
  gdsys: cmd_ioloop: Make DM compatible
  ihs_mdio: Add support to force clause45 access
  ihs_mdio: Fix style violations
  ihs_mdio: Make DM-compatible
  gazerbeam: Import Linux DT
  gazerbeam: Add u-boot specific dts include file

 arch/powerpc/cpu/mpc83xx/Kconfig             |    3 +
 arch/powerpc/cpu/mpc83xx/speed.c             |    7 +
 arch/powerpc/dts/.gitignore                  |    1 +
 arch/powerpc/dts/Makefile                    |   15 +
 arch/powerpc/dts/gazerbeam.dts               |  541 +++++++
 arch/powerpc/dts/gdsys/gazerbeam-base.dtsi   |  205 +++
 arch/powerpc/dts/gdsys/gazerbeam-uboot.dtsi  |  192 +++
 arch/powerpc/dts/gdsys/mpc8308.dtsi          |  243 ++++
 arch/powerpc/include/asm/arch-mpc83xx/gpio.h |    8 +
 arch/powerpc/include/asm/arch-mpc85xx/gpio.h |    2 +-
 arch/sandbox/dts/sandbox.dts                 |    4 +
 arch/sandbox/dts/test.dts                    |    4 +
 board/gdsys/a38x/controlcenterdc.c           |   20 +-
 board/gdsys/common/Makefile                  |    5 +-
 board/gdsys/common/adv7611.c                 |    4 +
 board/gdsys/common/ch7301.c                  |    4 +
 board/gdsys/common/cmd_ioloop.c              |  316 +++-
 board/gdsys/common/dp501.c                   |    4 +
 board/gdsys/common/fanctrl.c                 |    4 +
 board/gdsys/common/fpga.c                    |    4 +
 board/gdsys/common/ihs_mdio.c                |   75 +-
 board/gdsys/common/ihs_mdio.h                |    6 +
 board/gdsys/common/ioep-fpga.c               |  621 ++++++--
 board/gdsys/common/mclink.c                  |    4 +
 board/gdsys/common/miiphybb.c                |  128 --
 board/gdsys/common/osd.c                     |    4 +
 board/gdsys/common/phy.c                     |    2 -
 board/gdsys/mpc8308/Kconfig                  |   61 +
 board/gdsys/mpc8308/MAINTAINERS              |    2 +
 board/gdsys/mpc8308/Makefile                 |    1 +
 board/gdsys/mpc8308/gazerbeam.c              |  332 +++++
 board/gdsys/mpc8308/hrcon.c                  |   85 +-
 board/gdsys/mpc8308/mpc8308.c                |   33 +-
 board/gdsys/mpc8308/mpc8308.h                |    3 +
 board/gdsys/mpc8308/strider.c                |   73 +-
 board/gdsys/p1022/Kconfig                    |    6 +
 cmd/Kconfig                                  |   28 +
 cmd/Makefile                                 |    5 +
 cmd/binop.c                                  |  176 +++
 cmd/ihs_axi.c                                |  257 ++++
 cmd/ihs_fpga.c                               |  269 ++++
 cmd/ihs_osd.c                                |  167 +++
 cmd/mdio.c                                   |   72 +-
 common/board_f.c                             |   16 +-
 common/board_r.c                             |   37 +-
 configs/gazerbeam_defconfig                  |   76 +
 configs/sandbox_defconfig                    |    2 +
 doc/driver-model/fdt-fixup.txt               |  129 +-
 drivers/Kconfig                              |    2 +
 drivers/Makefile                             |    1 +
 drivers/clk/Kconfig                          |    6 +
 drivers/clk/Makefile                         |    1 +
 drivers/clk/ics8n3qv01.c                     |  184 +++
 drivers/gpio/Kconfig                         |    9 +-
 drivers/gpio/Makefile                        |    2 +-
 drivers/gpio/mpc85xx_gpio.c                  |  251 ----
 drivers/gpio/mpc8xxx_gpio.c                  |  274 ++++
 drivers/i2c/Kconfig                          |    6 +
 drivers/i2c/fsl_i2c.c                        |  109 +-
 drivers/i2c/ihs_i2c.c                        |  285 +++-
 drivers/misc/Kconfig                         |   31 +
 drivers/misc/Makefile                        |    5 +
 drivers/misc/gdsys_ioep.c                    |  301 ++++
 drivers/misc/gdsys_rxaui_ctrl.c              |  107 ++
 drivers/misc/gdsys_soc.c                     |   51 +
 drivers/misc/ihs_axi.c                       |  208 +++
 drivers/misc/ihs_fpga.c                      |  871 +++++++++++
 drivers/misc/ihs_video_out.c                 |  243 ++++
 drivers/mtd/cfi_flash.c                      | 1369 +++++++++---------
 drivers/net/phy/Kconfig                      |   67 +
 drivers/net/phy/Makefile                     |    1 +
 drivers/net/phy/marvell.c                    |   53 +-
 drivers/net/phy/mv88x2.c                     |  846 +++++++++++
 drivers/net/phy/mv88x2.h                     |   12 +
 drivers/net/phy/phy.c                        |   92 +-
 drivers/transmitter/Kconfig                  |   22 +
 drivers/transmitter/Makefile                 |   10 +
 drivers/transmitter/logicore_dp_dpcd.h       |  342 +++++
 drivers/transmitter/logicore_dp_tx.c         | 1984 ++++++++++++++++++++++++++
 drivers/transmitter/logicore_dp_tx.h         |   40 +
 drivers/transmitter/logicore_dp_tx_regif.h   |  365 +++++
 drivers/transmitter/sandbox_transmitter.c    |   74 +
 drivers/transmitter/transmitter-uclass.c     |   36 +
 include/asm-generic/global_data.h            |    7 +
 include/common.h                             |    3 +-
 include/configs/gazerbeam.h                  |  484 +++++++
 include/configs/hrcon.h                      |    7 -
 include/configs/strider.h                    |    7 -
 include/dm/uclass-id.h                       |    7 +
 include/fdt_fixup.h                          |   10 +
 include/gdsys_fpga.h                         |   98 +-
 include/gdsys_ioep.h                         |  196 +++
 include/gdsys_rxaui_ctrl.h                   |   66 +
 include/gdsys_soc.h                          |   29 +
 include/ihs_axi.h                            |   69 +
 include/ihs_fpga.h                           |  111 ++
 include/ihs_video_out.h                      |  146 ++
 include/marvell-phy.h                        |   10 +
 include/phy.h                                |   13 +-
 include/transmitter.h                        |   49 +
 scripts/config_whitelist.txt                 |   13 -
 test/dm/Makefile                             |    1 +
 test/dm/transmitter.c                        |   31 +
 103 files changed, 12203 insertions(+), 1670 deletions(-)
 create mode 100644 arch/powerpc/dts/.gitignore
 create mode 100644 arch/powerpc/dts/Makefile
 create mode 100644 arch/powerpc/dts/gazerbeam.dts
 create mode 100644 arch/powerpc/dts/gdsys/gazerbeam-base.dtsi
 create mode 100644 arch/powerpc/dts/gdsys/gazerbeam-uboot.dtsi
 create mode 100644 arch/powerpc/dts/gdsys/mpc8308.dtsi
 delete mode 100644 board/gdsys/common/miiphybb.c
 create mode 100644 board/gdsys/mpc8308/gazerbeam.c
 create mode 100644 cmd/binop.c
 create mode 100644 cmd/ihs_axi.c
 create mode 100644 cmd/ihs_fpga.c
 create mode 100644 cmd/ihs_osd.c
 create mode 100644 configs/gazerbeam_defconfig
 create mode 100644 drivers/clk/ics8n3qv01.c
 delete mode 100644 drivers/gpio/mpc85xx_gpio.c
 create mode 100644 drivers/gpio/mpc8xxx_gpio.c
 create mode 100644 drivers/misc/gdsys_ioep.c
 create mode 100644 drivers/misc/gdsys_rxaui_ctrl.c
 create mode 100644 drivers/misc/gdsys_soc.c
 create mode 100644 drivers/misc/ihs_axi.c
 create mode 100644 drivers/misc/ihs_fpga.c
 create mode 100644 drivers/misc/ihs_video_out.c
 create mode 100644 drivers/net/phy/mv88x2.c
 create mode 100644 drivers/net/phy/mv88x2.h
 create mode 100644 drivers/transmitter/Kconfig
 create mode 100644 drivers/transmitter/Makefile
 create mode 100644 drivers/transmitter/logicore_dp_dpcd.h
 create mode 100644 drivers/transmitter/logicore_dp_tx.c
 create mode 100644 drivers/transmitter/logicore_dp_tx.h
 create mode 100644 drivers/transmitter/logicore_dp_tx_regif.h
 create mode 100644 drivers/transmitter/sandbox_transmitter.c
 create mode 100644 drivers/transmitter/transmitter-uclass.c
 create mode 100644 include/configs/gazerbeam.h
 create mode 100644 include/fdt_fixup.h
 create mode 100644 include/gdsys_ioep.h
 create mode 100644 include/gdsys_rxaui_ctrl.h
 create mode 100644 include/gdsys_soc.h
 create mode 100644 include/ihs_axi.h
 create mode 100644 include/ihs_fpga.h
 create mode 100644 include/ihs_video_out.h
 create mode 100644 include/marvell-phy.h
 create mode 100644 include/transmitter.h
 create mode 100644 test/dm/transmitter.c

--
2.11.0

^ permalink raw reply	[flat|nested] 138+ messages in thread

* [U-Boot] [PATCH 01/51] i2c: fsl_i2c: Fix style violations
  2017-07-14 12:54 [U-Boot] [PATCH 00/51] gdsys: Add support for Gazerbeam board Mario Six
@ 2017-07-14 12:54 ` Mario Six
  2017-07-18 14:01   ` Simon Glass
  2017-07-14 12:54 ` [U-Boot] [PATCH 02/51] i2c: fsl_i2c: Remove inline declarations Mario Six
                   ` (49 subsequent siblings)
  50 siblings, 1 reply; 138+ messages in thread
From: Mario Six @ 2017-07-14 12:54 UTC (permalink / raw)
  To: u-boot

Fix some style violations in the fsl_i2c I2C driver.

Signed-off-by: Mario Six <mario.six@gdsys.cc>
---

 drivers/i2c/fsl_i2c.c | 109 +++++++++++++++++++++++++-------------------------
 1 file changed, 55 insertions(+), 54 deletions(-)

diff --git a/drivers/i2c/fsl_i2c.c b/drivers/i2c/fsl_i2c.c
index ff3dc25927..3d6808d04e 100644
--- a/drivers/i2c/fsl_i2c.c
+++ b/drivers/i2c/fsl_i2c.c
@@ -116,10 +116,10 @@ static const struct {
  *
  * The return value is the actual bus speed that is set.
  */
-static unsigned int set_i2c_bus_speed(const struct fsl_i2c_base *base,
-	unsigned int i2c_clk, unsigned int speed)
+static uint set_i2c_bus_speed(const struct fsl_i2c_base *base,
+			      uint i2c_clk, uint speed)
 {
-	unsigned short divider = min(i2c_clk / speed, (unsigned int)USHRT_MAX);
+	ushort divider = min(i2c_clk / speed, (uint)USHRT_MAX);
 
 	/*
 	 * We want to choose an FDR/DFSR that generates an I2C bus speed that
@@ -130,8 +130,8 @@ static unsigned int set_i2c_bus_speed(const struct fsl_i2c_base *base,
 #ifdef __PPC__
 	u8 dfsr, fdr = 0x31; /* Default if no FDR found */
 	/* a, b and dfsr matches identifiers A,B and C respectively in AN2919 */
-	unsigned short a, b, ga, gb;
-	unsigned long c_div, est_div;
+	ushort a, b, ga, gb;
+	ulong c_div, est_div;
 
 #ifdef CONFIG_FSL_I2C_CUSTOM_DFSR
 	dfsr = CONFIG_FSL_I2C_CUSTOM_DFSR;
@@ -151,18 +151,21 @@ static unsigned int set_i2c_bus_speed(const struct fsl_i2c_base *base,
 	for (ga = 0x4, a = 10; a <= 30; ga++, a += 2) {
 		for (gb = 0; gb < 8; gb++) {
 			b = 16 << gb;
-			c_div = b * (a + ((3*dfsr)/b)*2);
+			c_div = b * (a + ((3 * dfsr) / b) * 2);
 			if ((c_div > divider) && (c_div < est_div)) {
-				unsigned short bin_gb, bin_ga;
+				ushort bin_gb, bin_ga;
 
 				est_div = c_div;
 				bin_gb = gb << 2;
 				bin_ga = (ga & 0x3) | ((ga & 0x4) << 3);
 				fdr = bin_gb | bin_ga;
 				speed = i2c_clk / est_div;
-				debug("FDR:0x%.2x, div:%ld, ga:0x%x, gb:0x%x, "
-				      "a:%d, b:%d, speed:%d\n",
-				      fdr, est_div, ga, gb, a, b, speed);
+
+				debug("FDR: 0x%.2x, ", fdr);
+				debug("div: %ld, ", est_div);
+				debug("ga: 0x%x, gb: 0x%x, ", ga, gb);
+				debug("a: %d, b: %d, speed: %d\n", a, b, speed);
+
 				/* Condition 2 not accounted for */
 				debug("Tr <= %d ns\n",
 				      (b - 3 * dfsr) * 1000000 /
@@ -174,13 +177,13 @@ static unsigned int set_i2c_bus_speed(const struct fsl_i2c_base *base,
 		if (a == 24)
 			a += 4;
 	}
-	debug("divider:%d, est_div:%ld, DFSR:%d\n", divider, est_div, dfsr);
-	debug("FDR:0x%.2x, speed:%d\n", fdr, speed);
+	debug("divider: %d, est_div: %ld, DFSR: %d\n", divider, est_div, dfsr);
+	debug("FDR: 0x%.2x, speed: %d\n", fdr, speed);
 #endif
 	writeb(dfsr, &base->dfsrr);	/* set default filter */
 	writeb(fdr, &base->fdr);	/* set bus speed */
 #else
-	unsigned int i;
+	uint i;
 
 	for (i = 0; i < ARRAY_SIZE(fsl_i2c_speed_map); i++)
 		if (fsl_i2c_speed_map[i].divider >= divider) {
@@ -197,7 +200,7 @@ static unsigned int set_i2c_bus_speed(const struct fsl_i2c_base *base,
 }
 
 #ifndef CONFIG_DM_I2C
-static unsigned int get_i2c_clock(int bus)
+static uint get_i2c_clock(int bus)
 {
 	if (bus)
 		return gd->arch.i2c2_clk;	/* I2C2 clock */
@@ -211,10 +214,11 @@ static int fsl_i2c_fixup(const struct fsl_i2c_base *base)
 	const unsigned long long timeout = usec2ticks(CONFIG_I2C_MBB_TIMEOUT);
 	unsigned long long timeval = 0;
 	int ret = -1;
-	unsigned int flags = 0;
+	uint flags = 0;
 
 #ifdef CONFIG_SYS_FSL_ERRATUM_I2C_A004447
-	unsigned int svr = get_svr();
+	uint svr = get_svr();
+
 	if ((SVR_SOC_VER(svr) == SVR_8548 && IS_SVR_REV(svr, 3, 1)) ||
 	    (SVR_REV(svr) <= CONFIG_SYS_FSL_A004447_SVR_REV))
 		flags = I2C_CR_BIT6;
@@ -263,7 +267,7 @@ static void __i2c_init(const struct fsl_i2c_base *base, int speed, int
 	/* Call board specific i2c bus reset routine before accessing the
 	 * environment, which might be in a chip on that bus. For details
 	 * about this problem see doc/I2C_Edge_Conditions.
-	*/
+	 */
 	i2c_init_board();
 #endif
 	writeb(0, &base->cr);		/* stop I2C controller */
@@ -286,8 +290,7 @@ static void __i2c_init(const struct fsl_i2c_base *base, int speed, int
 	}
 }
 
-static int
-i2c_wait4bus(const struct fsl_i2c_base *base)
+static int i2c_wait4bus(const struct fsl_i2c_base *base)
 {
 	unsigned long long timeval = get_ticks();
 	const unsigned long long timeout = usec2ticks(CONFIG_I2C_MBB_TIMEOUT);
@@ -300,8 +303,7 @@ i2c_wait4bus(const struct fsl_i2c_base *base)
 	return 0;
 }
 
-static inline int
-i2c_wait(const struct fsl_i2c_base *base, int write)
+static inline int i2c_wait(const struct fsl_i2c_base *base, int write)
 {
 	u32 csr;
 	unsigned long long timeval = get_ticks();
@@ -317,29 +319,29 @@ i2c_wait(const struct fsl_i2c_base *base, int write)
 		writeb(0x0, &base->sr);
 
 		if (csr & I2C_SR_MAL) {
-			debug("i2c_wait: MAL\n");
+			debug("%s: MAL\n", __func__);
 			return -1;
 		}
 
 		if (!(csr & I2C_SR_MCF))	{
-			debug("i2c_wait: unfinished\n");
+			debug("%s: unfinished\n", __func__);
 			return -1;
 		}
 
 		if (write == I2C_WRITE_BIT && (csr & I2C_SR_RXAK)) {
-			debug("i2c_wait: No RXACK\n");
+			debug("%s: No RXACK\n", __func__);
 			return -1;
 		}
 
 		return 0;
 	} while ((get_ticks() - timeval) < timeout);
 
-	debug("i2c_wait: timed out\n");
+	debug("%s: timed out\n", __func__);
 	return -1;
 }
 
-static inline int
-i2c_write_addr(const struct fsl_i2c_base *base, u8 dev, u8 dir, int rsta)
+static inline int i2c_write_addr(const struct fsl_i2c_base *base, u8 dev,
+				 u8 dir, int rsta)
 {
 	writeb(I2C_CR_MEN | I2C_CR_MSTA | I2C_CR_MTX
 	       | (rsta ? I2C_CR_RSTA : 0),
@@ -353,8 +355,8 @@ i2c_write_addr(const struct fsl_i2c_base *base, u8 dev, u8 dir, int rsta)
 	return 1;
 }
 
-static inline int
-__i2c_write_data(const struct fsl_i2c_base *base, u8 *data, int length)
+static inline int __i2c_write_data(const struct fsl_i2c_base *base, u8 *data,
+				   int length)
 {
 	int i;
 
@@ -368,8 +370,8 @@ __i2c_write_data(const struct fsl_i2c_base *base, u8 *data, int length)
 	return i;
 }
 
-static inline int
-__i2c_read_data(const struct fsl_i2c_base *base, u8 *data, int length)
+static inline int __i2c_read_data(const struct fsl_i2c_base *base, u8 *data,
+				  int length)
 {
 	int i;
 
@@ -399,9 +401,8 @@ __i2c_read_data(const struct fsl_i2c_base *base, u8 *data, int length)
 	return i;
 }
 
-static int
-__i2c_read(const struct fsl_i2c_base *base, u8 chip_addr, u8 *offset, int olen,
-	   u8 *data, int dlen)
+static int __i2c_read(const struct fsl_i2c_base *base, u8 chip_addr, u8 *offset,
+		      int olen, u8 *data, int dlen)
 {
 	int ret = -1; /* signal error */
 
@@ -447,9 +448,8 @@ __i2c_read(const struct fsl_i2c_base *base, u8 chip_addr, u8 *offset, int olen,
 	return -1;
 }
 
-static int
-__i2c_write(const struct fsl_i2c_base *base, u8 chip_addr, u8 *offset, int olen,
-	    u8 *data, int dlen)
+static int __i2c_write(const struct fsl_i2c_base *base, u8 chip_addr,
+		       u8 *offset, int olen, u8 *data, int dlen)
 {
 	int ret = -1; /* signal error */
 
@@ -471,10 +471,9 @@ __i2c_write(const struct fsl_i2c_base *base, u8 chip_addr, u8 *offset, int olen,
 	return -1;
 }
 
-static int
-__i2c_probe_chip(const struct fsl_i2c_base *base, uchar chip)
+static int __i2c_probe_chip(const struct fsl_i2c_base *base, uchar chip)
 {
-	/* For unknow reason the controller will ACK when
+	/* For unknown reason the controller will ACK when
 	 * probing for a slave with the same address, so skip
 	 * it.
 	 */
@@ -484,8 +483,8 @@ __i2c_probe_chip(const struct fsl_i2c_base *base, uchar chip)
 	return __i2c_read(base, chip, 0, 0, NULL, 0);
 }
 
-static unsigned int __i2c_set_bus_speed(const struct fsl_i2c_base *base,
-			unsigned int speed, int i2c_clk)
+static uint __i2c_set_bus_speed(const struct fsl_i2c_base *base,
+				uint speed, int i2c_clk)
 {
 	writeb(0, &base->cr);		/* stop controller */
 	set_i2c_bus_speed(base, i2c_clk, speed);
@@ -501,32 +500,30 @@ static void fsl_i2c_init(struct i2c_adapter *adap, int speed, int slaveadd)
 		   get_i2c_clock(adap->hwadapnr), adap->hwadapnr);
 }
 
-static int
-fsl_i2c_probe_chip(struct i2c_adapter *adap, uchar chip)
+static int fsl_i2c_probe_chip(struct i2c_adapter *adap, uchar chip)
 {
 	return __i2c_probe_chip(i2c_base[adap->hwadapnr], chip);
 }
 
-static int
-fsl_i2c_read(struct i2c_adapter *adap, u8 chip_addr, uint offset, int olen,
-	     u8 *data, int dlen)
+static int fsl_i2c_read(struct i2c_adapter *adap, u8 chip_addr, uint offset,
+			int olen, u8 *data, int dlen)
 {
 	u8 *o = (u8 *)&offset;
+
 	return __i2c_read(i2c_base[adap->hwadapnr], chip_addr, &o[4 - olen],
 			  olen, data, dlen);
 }
 
-static int
-fsl_i2c_write(struct i2c_adapter *adap, u8 chip_addr, uint offset, int olen,
-	      u8 *data, int dlen)
+static int fsl_i2c_write(struct i2c_adapter *adap, u8 chip_addr, uint offset,
+			 int olen, u8 *data, int dlen)
 {
 	u8 *o = (u8 *)&offset;
+
 	return __i2c_write(i2c_base[adap->hwadapnr], chip_addr, &o[4 - olen],
 			   olen, data, dlen);
 }
 
-static unsigned int fsl_i2c_set_bus_speed(struct i2c_adapter *adap,
-					  unsigned int speed)
+static uint fsl_i2c_set_bus_speed(struct i2c_adapter *adap, uint speed)
 {
 	return __i2c_set_bus_speed(i2c_base[adap->hwadapnr], speed,
 				   get_i2c_clock(adap->hwadapnr));
@@ -562,12 +559,14 @@ static int fsl_i2c_probe_chip(struct udevice *bus, u32 chip_addr,
 			      u32 chip_flags)
 {
 	struct fsl_i2c_dev *dev = dev_get_priv(bus);
+
 	return __i2c_probe_chip(dev->base, chip_addr);
 }
 
-static int fsl_i2c_set_bus_speed(struct udevice *bus, unsigned int speed)
+static int fsl_i2c_set_bus_speed(struct udevice *bus, uint speed)
 {
 	struct fsl_i2c_dev *dev = dev_get_priv(bus);
+
 	return __i2c_set_bus_speed(dev->base, speed, dev->i2c_clk);
 }
 
@@ -600,6 +599,7 @@ static int fsl_i2c_ofdata_to_platdata(struct udevice *bus)
 static int fsl_i2c_probe(struct udevice *bus)
 {
 	struct fsl_i2c_dev *dev = dev_get_priv(bus);
+
 	__i2c_init(dev->base, dev->speed, dev->slaveadd, dev->i2c_clk,
 		   dev->index);
 	return 0;
@@ -613,7 +613,8 @@ static int fsl_i2c_xfer(struct udevice *bus, struct i2c_msg *msg, int nmsgs)
 	memset(&dummy, 0, sizeof(struct i2c_msg));
 
 	/* We expect either two messages (one with an offset and one with the
-	 * actucal data) or one message (just data) */
+	 * actual data) or one message (just data)
+	 */
 	if (nmsgs > 2 || nmsgs == 0) {
 		debug("%s: Only one or two messages are supported.", __func__);
 		return -1;
-- 
2.11.0

^ permalink raw reply related	[flat|nested] 138+ messages in thread

* [U-Boot] [PATCH 02/51] i2c: fsl_i2c: Remove inline declarations
  2017-07-14 12:54 [U-Boot] [PATCH 00/51] gdsys: Add support for Gazerbeam board Mario Six
  2017-07-14 12:54 ` [U-Boot] [PATCH 01/51] i2c: fsl_i2c: Fix style violations Mario Six
@ 2017-07-14 12:54 ` Mario Six
  2017-07-18 14:01   ` Simon Glass
  2017-07-14 12:54 ` [U-Boot] [PATCH 03/51] gdsys: Post ppc4xx removal cleanup Mario Six
                   ` (48 subsequent siblings)
  50 siblings, 1 reply; 138+ messages in thread
From: Mario Six @ 2017-07-14 12:54 UTC (permalink / raw)
  To: u-boot

Some functions in the fsl_i2c driver are declared as inline, even though
they are quite large, which needlessly increases the size of the
resulting binary.

This patch removes the inline declarations.

Signed-off-by: Mario Six <mario.six@gdsys.cc>
---

 drivers/i2c/fsl_i2c.c | 14 +++++++-------
 1 file changed, 7 insertions(+), 7 deletions(-)

diff --git a/drivers/i2c/fsl_i2c.c b/drivers/i2c/fsl_i2c.c
index 3d6808d04e..6d8ebe7478 100644
--- a/drivers/i2c/fsl_i2c.c
+++ b/drivers/i2c/fsl_i2c.c
@@ -303,7 +303,7 @@ static int i2c_wait4bus(const struct fsl_i2c_base *base)
 	return 0;
 }
 
-static inline int i2c_wait(const struct fsl_i2c_base *base, int write)
+static int i2c_wait(const struct fsl_i2c_base *base, int write)
 {
 	u32 csr;
 	unsigned long long timeval = get_ticks();
@@ -340,8 +340,8 @@ static inline int i2c_wait(const struct fsl_i2c_base *base, int write)
 	return -1;
 }
 
-static inline int i2c_write_addr(const struct fsl_i2c_base *base, u8 dev,
-				 u8 dir, int rsta)
+static int i2c_write_addr(const struct fsl_i2c_base *base, u8 dev,
+			  u8 dir, int rsta)
 {
 	writeb(I2C_CR_MEN | I2C_CR_MSTA | I2C_CR_MTX
 	       | (rsta ? I2C_CR_RSTA : 0),
@@ -355,8 +355,8 @@ static inline int i2c_write_addr(const struct fsl_i2c_base *base, u8 dev,
 	return 1;
 }
 
-static inline int __i2c_write_data(const struct fsl_i2c_base *base, u8 *data,
-				   int length)
+static int __i2c_write_data(const struct fsl_i2c_base *base, u8 *data,
+			    int length)
 {
 	int i;
 
@@ -370,8 +370,8 @@ static inline int __i2c_write_data(const struct fsl_i2c_base *base, u8 *data,
 	return i;
 }
 
-static inline int __i2c_read_data(const struct fsl_i2c_base *base, u8 *data,
-				  int length)
+static int __i2c_read_data(const struct fsl_i2c_base *base, u8 *data,
+			   int length)
 {
 	int i;
 
-- 
2.11.0

^ permalink raw reply related	[flat|nested] 138+ messages in thread

* [U-Boot] [PATCH 03/51] gdsys: Post ppc4xx removal cleanup
  2017-07-14 12:54 [U-Boot] [PATCH 00/51] gdsys: Add support for Gazerbeam board Mario Six
  2017-07-14 12:54 ` [U-Boot] [PATCH 01/51] i2c: fsl_i2c: Fix style violations Mario Six
  2017-07-14 12:54 ` [U-Boot] [PATCH 02/51] i2c: fsl_i2c: Remove inline declarations Mario Six
@ 2017-07-14 12:54 ` Mario Six
  2017-07-18 14:01   ` Simon Glass
  2017-07-14 12:54 ` [U-Boot] [PATCH 04/51] net: phy: marvell: Fix style violations Mario Six
                   ` (47 subsequent siblings)
  50 siblings, 1 reply; 138+ messages in thread
From: Mario Six @ 2017-07-14 12:54 UTC (permalink / raw)
  To: u-boot

The ppc4xx architecture was recently removed, and with it several old
gdsys 44x boards, but some "debris" from these purged boards was left
over.

This patch removes these remnants (mostly entries in Makefiles, some now
superfluous data structures and some now obsolete config variables from
the whitelist).

Signed-off-by: Mario Six <mario.six@gdsys.cc>
---

 board/gdsys/common/Makefile   |   4 --
 board/gdsys/common/miiphybb.c | 128 ------------------------------------------
 include/gdsys_fpga.h          |  96 -------------------------------
 scripts/config_whitelist.txt  |  10 ----
 4 files changed, 238 deletions(-)
 delete mode 100644 board/gdsys/common/miiphybb.c

diff --git a/board/gdsys/common/Makefile b/board/gdsys/common/Makefile
index d4f0e70573..6f2fea207f 100644
--- a/board/gdsys/common/Makefile
+++ b/board/gdsys/common/Makefile
@@ -7,10 +7,6 @@
 
 obj-$(CONFIG_SYS_FPGA_COMMON) += fpga.o
 obj-$(CONFIG_CMD_IOLOOP) += cmd_ioloop.o
-obj-$(CONFIG_IO) += miiphybb.o
-obj-$(CONFIG_IO64) += miiphybb.o
-obj-$(CONFIG_IOCON) += osd.o mclink.o dp501.o phy.o ch7301.o
-obj-$(CONFIG_DLVISION_10G) += osd.o dp501.o
 obj-$(CONFIG_CONTROLCENTERD) += dp501.o
 obj-$(CONFIG_HRCON) += osd.o mclink.o dp501.o phy.o ioep-fpga.o fanctrl.o
 obj-$(CONFIG_STRIDER) += mclink.o dp501.o phy.o ioep-fpga.o adv7611.o ch7301.o
diff --git a/board/gdsys/common/miiphybb.c b/board/gdsys/common/miiphybb.c
deleted file mode 100644
index 310562902b..0000000000
--- a/board/gdsys/common/miiphybb.c
+++ /dev/null
@@ -1,128 +0,0 @@
-/*
- * (C) Copyright 2010
- * Dirk Eibach,  Guntermann & Drunck GmbH, eibach at gdsys.de
- *
- * SPDX-License-Identifier:	GPL-2.0+
- */
-
-#include <common.h>
-#include <miiphy.h>
-
-#include <asm/io.h>
-
-struct io_bb_pinset {
-	int mdio;
-	int mdc;
-};
-
-static int io_bb_mii_init(struct bb_miiphy_bus *bus)
-{
-	return 0;
-}
-
-static int io_bb_mdio_active(struct bb_miiphy_bus *bus)
-{
-	struct io_bb_pinset *pins = bus->priv;
-
-	out_be32((void *)GPIO0_TCR,
-		in_be32((void *)GPIO0_TCR) | pins->mdio);
-
-	return 0;
-}
-
-static int io_bb_mdio_tristate(struct bb_miiphy_bus *bus)
-{
-	struct io_bb_pinset *pins = bus->priv;
-
-	out_be32((void *)GPIO0_TCR,
-		in_be32((void *)GPIO0_TCR) & ~pins->mdio);
-
-	return 0;
-}
-
-static int io_bb_set_mdio(struct bb_miiphy_bus *bus, int v)
-{
-	struct io_bb_pinset *pins = bus->priv;
-
-	if (v)
-		out_be32((void *)GPIO0_OR,
-			in_be32((void *)GPIO0_OR) | pins->mdio);
-	else
-		out_be32((void *)GPIO0_OR,
-			in_be32((void *)GPIO0_OR) & ~pins->mdio);
-
-	return 0;
-}
-
-static int io_bb_get_mdio(struct bb_miiphy_bus *bus, int *v)
-{
-	struct io_bb_pinset *pins = bus->priv;
-
-	*v = ((in_be32((void *)GPIO0_IR) & pins->mdio) != 0);
-
-	return 0;
-}
-
-static int io_bb_set_mdc(struct bb_miiphy_bus *bus, int v)
-{
-	struct io_bb_pinset *pins = bus->priv;
-
-	if (v)
-		out_be32((void *)GPIO0_OR,
-			in_be32((void *)GPIO0_OR) | pins->mdc);
-	else
-		out_be32((void *)GPIO0_OR,
-			in_be32((void *)GPIO0_OR) & ~pins->mdc);
-
-	return 0;
-}
-
-static int io_bb_delay(struct bb_miiphy_bus *bus)
-{
-	udelay(1);
-
-	return 0;
-}
-
-struct io_bb_pinset io_bb_pinsets[] = {
-	{
-		.mdio = CONFIG_SYS_MDIO_PIN,
-		.mdc = CONFIG_SYS_MDC_PIN,
-	},
-#ifdef CONFIG_SYS_GBIT_MII1_BUSNAME
-	{
-		.mdio = CONFIG_SYS_MDIO1_PIN,
-		.mdc = CONFIG_SYS_MDC1_PIN,
-	},
-#endif
-};
-
-struct bb_miiphy_bus bb_miiphy_buses[] = {
-	{
-		.name = CONFIG_SYS_GBIT_MII_BUSNAME,
-		.init = io_bb_mii_init,
-		.mdio_active = io_bb_mdio_active,
-		.mdio_tristate = io_bb_mdio_tristate,
-		.set_mdio = io_bb_set_mdio,
-		.get_mdio = io_bb_get_mdio,
-		.set_mdc = io_bb_set_mdc,
-		.delay = io_bb_delay,
-		.priv = &io_bb_pinsets[0],
-	},
-#ifdef CONFIG_SYS_GBIT_MII1_BUSNAME
-	{
-		.name = CONFIG_SYS_GBIT_MII1_BUSNAME,
-		.init = io_bb_mii_init,
-		.mdio_active = io_bb_mdio_active,
-		.mdio_tristate = io_bb_mdio_tristate,
-		.set_mdio = io_bb_set_mdio,
-		.get_mdio = io_bb_get_mdio,
-		.set_mdc = io_bb_set_mdc,
-		.delay = io_bb_delay,
-		.priv = &io_bb_pinsets[1],
-	},
-#endif
-};
-
-int bb_miiphy_buses_num = sizeof(bb_miiphy_buses) /
-			  sizeof(bb_miiphy_buses[0]);
diff --git a/include/gdsys_fpga.h b/include/gdsys_fpga.h
index bb8e144e04..34d6eeb253 100644
--- a/include/gdsys_fpga.h
+++ b/include/gdsys_fpga.h
@@ -87,81 +87,6 @@ struct ihs_fpga {
 };
 #endif
 
-#ifdef CONFIG_IO
-struct ihs_fpga {
-	u16 reflection_low;	/* 0x0000 */
-	u16 versions;		/* 0x0002 */
-	u16 fpga_features;	/* 0x0004 */
-	u16 fpga_version;	/* 0x0006 */
-	u16 reserved_0[5];	/* 0x0008 */
-	u16 quad_serdes_reset;	/* 0x0012 */
-	u16 reserved_1[8181];	/* 0x0014 */
-	u16 reflection_high;	/* 0x3ffe */
-};
-#endif
-
-#ifdef CONFIG_IO64
-struct ihs_fpga_channel {
-	u16 status_int;
-	u16 config_int;
-	u16 switch_connect_config;
-	u16 tx_destination;
-};
-
-struct ihs_fpga_hicb {
-	u16 status_int;
-	u16 config_int;
-};
-
-struct ihs_fpga {
-	u16 reflection_low;	/* 0x0000 */
-	u16 versions;		/* 0x0002 */
-	u16 fpga_features;	/* 0x0004 */
-	u16 fpga_version;	/* 0x0006 */
-	u16 reserved_0[5];	/* 0x0008 */
-	u16 quad_serdes_reset;	/* 0x0012 */
-	u16 reserved_1[502];	/* 0x0014 */
-	struct ihs_fpga_channel ch[32];		/* 0x0400 */
-	struct ihs_fpga_channel hicb_ch[32];	/* 0x0500 */
-	u16 reserved_2[7487];	/* 0x0580 */
-	u16 reflection_high;	/* 0x3ffe */
-};
-#endif
-
-#ifdef CONFIG_IOCON
-struct ihs_fpga {
-	u16 reflection_low;	/* 0x0000 */
-	u16 versions;		/* 0x0002 */
-	u16 fpga_version;	/* 0x0004 */
-	u16 fpga_features;	/* 0x0006 */
-	u16 reserved_0[1];	/* 0x0008 */
-	u16 top_interrupt;	/* 0x000a */
-	u16 reserved_1[4];	/* 0x000c */
-	struct ihs_gpio gpio;	/* 0x0014 */
-	u16 mpc3w_control;	/* 0x001a */
-	u16 reserved_2[2];	/* 0x001c */
-	struct ihs_io_ep ep;	/* 0x0020 */
-	u16 reserved_3[9];	/* 0x002e */
-	struct ihs_i2c i2c0;	/* 0x0040 */
-	u16 reserved_4[10];	/* 0x004c */
-	u16 mc_int;		/* 0x0060 */
-	u16 mc_int_en;		/* 0x0062 */
-	u16 mc_status;		/* 0x0064 */
-	u16 mc_control;		/* 0x0066 */
-	u16 mc_tx_data;		/* 0x0068 */
-	u16 mc_tx_address;	/* 0x006a */
-	u16 mc_tx_cmd;		/* 0x006c */
-	u16 mc_res;		/* 0x006e */
-	u16 mc_rx_cmd_status;	/* 0x0070 */
-	u16 mc_rx_data;		/* 0x0072 */
-	u16 reserved_5[69];	/* 0x0074 */
-	u16 reflection_high;	/* 0x00fe */
-	struct ihs_osd osd0;	/* 0x0100 */
-	u16 reserved_6[889];	/* 0x010e */
-	u16 videomem0[2048];	/* 0x0800 */
-};
-#endif
-
 #if defined(CONFIG_HRCON) || defined(CONFIG_STRIDER_CON_DP)
 struct ihs_fpga {
 	u16 reflection_low;	/* 0x0000 */
@@ -271,25 +196,4 @@ struct ihs_fpga {
 };
 #endif
 
-#ifdef CONFIG_DLVISION_10G
-struct ihs_fpga {
-	u16 reflection_low;	/* 0x0000 */
-	u16 versions;		/* 0x0002 */
-	u16 fpga_version;	/* 0x0004 */
-	u16 fpga_features;	/* 0x0006 */
-	u16 reserved_0[10];	/* 0x0008 */
-	u16 extended_interrupt; /* 0x001c */
-	u16 reserved_1[29];	/* 0x001e */
-	u16 mpc3w_control;	/* 0x0058 */
-	u16 reserved_2[3];	/* 0x005a */
-	struct ihs_i2c i2c0;	/* 0x0060 */
-	u16 reserved_3[2];	/* 0x006c */
-	struct ihs_i2c i2c1;	/* 0x0070 */
-	u16 reserved_4[194];	/* 0x007c */
-	struct ihs_osd osd0;	/* 0x0200 */
-	u16 reserved_5[761];	/* 0x020e */
-	u16 videomem0[2048];	/* 0x0800 */
-};
-#endif
-
 #endif
diff --git a/scripts/config_whitelist.txt b/scripts/config_whitelist.txt
index e261d02455..4c136a6502 100644
--- a/scripts/config_whitelist.txt
+++ b/scripts/config_whitelist.txt
@@ -499,7 +499,6 @@ CONFIG_DISCONTIGMEM
 CONFIG_DISCOVER_PHY
 CONFIG_DISPLAY_AER_xxxx
 CONFIG_DISPLAY_BOARDINFO_LATE
-CONFIG_DLVISION_10G
 CONFIG_DM9000_BASE
 CONFIG_DM9000_BYTE_SWAPPED
 CONFIG_DM9000_DEBUG
@@ -1167,9 +1166,6 @@ CONFIG_INI_MAX_SECTION
 CONFIG_INTEGRITY
 CONFIG_INTEL_ICH6_GPIO
 CONFIG_INTERRUPTS
-CONFIG_IO
-CONFIG_IO64
-CONFIG_IOCON
 CONFIG_IODELAY_RECALIBRATION
 CONFIG_IOMUX_LPSR
 CONFIG_IOMUX_SHARE_CONF_REG
@@ -3410,8 +3406,6 @@ CONFIG_SYS_GAFR2_L_VAL
 CONFIG_SYS_GAFR2_U_VAL
 CONFIG_SYS_GAFR3_L_VAL
 CONFIG_SYS_GAFR3_U_VAL
-CONFIG_SYS_GBIT_MII1_BUSNAME
-CONFIG_SYS_GBIT_MII_BUSNAME
 CONFIG_SYS_GBL_DATA_OFFSET
 CONFIG_SYS_GBL_DATA_SIZE
 CONFIG_SYS_GENERIC_BOARD
@@ -3857,13 +3851,9 @@ CONFIG_SYS_MCKR_VAL
 CONFIG_SYS_MCLINK_MAX
 CONFIG_SYS_MCMEM0_VAL
 CONFIG_SYS_MCMEM1_VAL
-CONFIG_SYS_MDC1_PIN
 CONFIG_SYS_MDCNFG_VAL
-CONFIG_SYS_MDC_PIN
 CONFIG_SYS_MDIO1_OFFSET
-CONFIG_SYS_MDIO1_PIN
 CONFIG_SYS_MDIO_BASE_ADDR
-CONFIG_SYS_MDIO_PIN
 CONFIG_SYS_MDMRS_VAL
 CONFIG_SYS_MDREFR_VAL
 CONFIG_SYS_MECR_VAL
-- 
2.11.0

^ permalink raw reply related	[flat|nested] 138+ messages in thread

* [U-Boot] [PATCH 04/51] net: phy: marvell: Fix style violations
  2017-07-14 12:54 [U-Boot] [PATCH 00/51] gdsys: Add support for Gazerbeam board Mario Six
                   ` (2 preceding siblings ...)
  2017-07-14 12:54 ` [U-Boot] [PATCH 03/51] gdsys: Post ppc4xx removal cleanup Mario Six
@ 2017-07-14 12:54 ` Mario Six
  2017-07-18 14:01   ` Simon Glass
  2017-07-27 22:15   ` Joe Hershberger
  2017-07-14 12:54 ` [U-Boot] [PATCH 05/51] net: phy: marvell 88e151x: Fix handling of bare RGMII interface type Mario Six
                   ` (46 subsequent siblings)
  50 siblings, 2 replies; 138+ messages in thread
From: Mario Six @ 2017-07-14 12:54 UTC (permalink / raw)
  To: u-boot

Fix some style violations in the Marvell PHY driver.

Signed-off-by: Mario Six <mario.six@gdsys.cc>
---

 drivers/net/phy/marvell.c | 44 ++++++++++++++++++++++----------------------
 1 file changed, 22 insertions(+), 22 deletions(-)

diff --git a/drivers/net/phy/marvell.c b/drivers/net/phy/marvell.c
index b7f300e40f..5d9f50a436 100644
--- a/drivers/net/phy/marvell.c
+++ b/drivers/net/phy/marvell.c
@@ -134,7 +134,7 @@ static int m88e1xxx_parse_status(struct phy_device *phydev)
 	mii_reg = phy_read(phydev, MDIO_DEVAD_NONE, MIIM_88E1xxx_PHY_STATUS);
 
 	if ((mii_reg & MIIM_88E1xxx_PHYSTAT_LINK) &&
-		!(mii_reg & MIIM_88E1xxx_PHYSTAT_SPDDONE)) {
+	    !(mii_reg & MIIM_88E1xxx_PHYSTAT_SPDDONE)) {
 		int i = 0;
 
 		puts("Waiting for PHY realtime link");
@@ -150,10 +150,10 @@ static int m88e1xxx_parse_status(struct phy_device *phydev)
 				putc('.');
 			udelay(1000);
 			mii_reg = phy_read(phydev, MDIO_DEVAD_NONE,
-					MIIM_88E1xxx_PHY_STATUS);
+					   MIIM_88E1xxx_PHY_STATUS);
 		}
 		puts(" done\n");
-		udelay(500000);	/* another 500 ms (results in faster booting) */
+		mdelay(500);	/* another 500 ms (results in faster booting) */
 	} else {
 		if (mii_reg & MIIM_88E1xxx_PHYSTAT_LINK)
 			phydev->link = 1;
@@ -201,9 +201,9 @@ static int m88e1111s_config(struct phy_device *phydev)
 
 	if (phy_interface_is_rgmii(phydev)) {
 		reg = phy_read(phydev,
-			MDIO_DEVAD_NONE, MIIM_88E1111_PHY_EXT_CR);
+			       MDIO_DEVAD_NONE, MIIM_88E1111_PHY_EXT_CR);
 		if ((phydev->interface == PHY_INTERFACE_MODE_RGMII) ||
-			(phydev->interface == PHY_INTERFACE_MODE_RGMII_ID)) {
+		    (phydev->interface == PHY_INTERFACE_MODE_RGMII_ID)) {
 			reg |= (MIIM_88E1111_RX_DELAY | MIIM_88E1111_TX_DELAY);
 		} else if (phydev->interface == PHY_INTERFACE_MODE_RGMII_RXID) {
 			reg &= ~MIIM_88E1111_TX_DELAY;
@@ -214,10 +214,10 @@ static int m88e1111s_config(struct phy_device *phydev)
 		}
 
 		phy_write(phydev,
-			MDIO_DEVAD_NONE, MIIM_88E1111_PHY_EXT_CR, reg);
+			  MDIO_DEVAD_NONE, MIIM_88E1111_PHY_EXT_CR, reg);
 
 		reg = phy_read(phydev,
-			MDIO_DEVAD_NONE, MIIM_88E1111_PHY_EXT_SR);
+			       MDIO_DEVAD_NONE, MIIM_88E1111_PHY_EXT_SR);
 
 		reg &= ~(MIIM_88E1111_HWCFG_MODE_MASK);
 
@@ -227,47 +227,47 @@ static int m88e1111s_config(struct phy_device *phydev)
 			reg |= MIIM_88E1111_HWCFG_MODE_COPPER_RGMII;
 
 		phy_write(phydev,
-			MDIO_DEVAD_NONE, MIIM_88E1111_PHY_EXT_SR, reg);
+			  MDIO_DEVAD_NONE, MIIM_88E1111_PHY_EXT_SR, reg);
 	}
 
 	if (phydev->interface == PHY_INTERFACE_MODE_SGMII) {
 		reg = phy_read(phydev,
-			MDIO_DEVAD_NONE, MIIM_88E1111_PHY_EXT_SR);
+			       MDIO_DEVAD_NONE, MIIM_88E1111_PHY_EXT_SR);
 
 		reg &= ~(MIIM_88E1111_HWCFG_MODE_MASK);
 		reg |= MIIM_88E1111_HWCFG_MODE_SGMII_NO_CLK;
 		reg |= MIIM_88E1111_HWCFG_FIBER_COPPER_AUTO;
 
 		phy_write(phydev, MDIO_DEVAD_NONE,
-			MIIM_88E1111_PHY_EXT_SR, reg);
+			  MIIM_88E1111_PHY_EXT_SR, reg);
 	}
 
 	if (phydev->interface == PHY_INTERFACE_MODE_RTBI) {
 		reg = phy_read(phydev,
-			MDIO_DEVAD_NONE, MIIM_88E1111_PHY_EXT_CR);
+			       MDIO_DEVAD_NONE, MIIM_88E1111_PHY_EXT_CR);
 		reg |= (MIIM_88E1111_RX_DELAY | MIIM_88E1111_TX_DELAY);
 		phy_write(phydev,
-			MDIO_DEVAD_NONE, MIIM_88E1111_PHY_EXT_CR, reg);
+			  MDIO_DEVAD_NONE, MIIM_88E1111_PHY_EXT_CR, reg);
 
 		reg = phy_read(phydev, MDIO_DEVAD_NONE,
-			MIIM_88E1111_PHY_EXT_SR);
+			       MIIM_88E1111_PHY_EXT_SR);
 		reg &= ~(MIIM_88E1111_HWCFG_MODE_MASK |
 			MIIM_88E1111_HWCFG_FIBER_COPPER_RES);
 		reg |= 0x7 | MIIM_88E1111_HWCFG_FIBER_COPPER_AUTO;
 		phy_write(phydev, MDIO_DEVAD_NONE,
-			MIIM_88E1111_PHY_EXT_SR, reg);
+			  MIIM_88E1111_PHY_EXT_SR, reg);
 
 		/* soft reset */
 		phy_reset(phydev);
 
 		reg = phy_read(phydev, MDIO_DEVAD_NONE,
-			MIIM_88E1111_PHY_EXT_SR);
+			       MIIM_88E1111_PHY_EXT_SR);
 		reg &= ~(MIIM_88E1111_HWCFG_MODE_MASK |
-			MIIM_88E1111_HWCFG_FIBER_COPPER_RES);
+			 MIIM_88E1111_HWCFG_FIBER_COPPER_RES);
 		reg |= MIIM_88E1111_HWCFG_MODE_COPPER_RTBI |
 			MIIM_88E1111_HWCFG_FIBER_COPPER_AUTO;
 		phy_write(phydev, MDIO_DEVAD_NONE,
-			MIIM_88E1111_PHY_EXT_SR, reg);
+			  MIIM_88E1111_PHY_EXT_SR, reg);
 	}
 
 	/* soft reset */
@@ -283,7 +283,7 @@ static int m88e1111s_config(struct phy_device *phydev)
  * m88e1518_phy_writebits - write bits to a register
  */
 void m88e1518_phy_writebits(struct phy_device *phydev,
-		   u8 reg_num, u16 offset, u16 len, u16 data)
+			    u8 reg_num, u16 offset, u16 len, u16 data)
 {
 	u16 reg, mask;
 
@@ -446,10 +446,10 @@ static int m88e1121_config(struct phy_device *phydev)
 	/* Switch the page to access the led register */
 	pg = phy_read(phydev, MDIO_DEVAD_NONE, MIIM_88E1121_PHY_PAGE);
 	phy_write(phydev, MDIO_DEVAD_NONE, MIIM_88E1121_PHY_PAGE,
-			MIIM_88E1121_PHY_LED_PAGE);
+		  MIIM_88E1121_PHY_LED_PAGE);
 	/* Configure leds */
 	phy_write(phydev, MDIO_DEVAD_NONE, MIIM_88E1121_PHY_LED_CTRL,
-			MIIM_88E1121_PHY_LED_DEF);
+		  MIIM_88E1121_PHY_LED_DEF);
 	/* Restore the page pointer */
 	phy_write(phydev, MDIO_DEVAD_NONE, MIIM_88E1121_PHY_PAGE, pg);
 
@@ -472,7 +472,7 @@ static int m88e1145_config(struct phy_device *phydev)
 	phy_write(phydev, MDIO_DEVAD_NONE, MIIM_88E1145_PHY_CAL_OV, 0xa2da);
 
 	phy_write(phydev, MDIO_DEVAD_NONE, MIIM_88E1xxx_PHY_SCR,
-			MIIM_88E1xxx_PHY_MDI_X_AUTO);
+		  MIIM_88E1xxx_PHY_MDI_X_AUTO);
 
 	reg = phy_read(phydev, MDIO_DEVAD_NONE, MIIM_88E1145_PHY_EXT_CR);
 	if (phydev->interface == PHY_INTERFACE_MODE_RGMII_ID)
@@ -499,7 +499,7 @@ static int m88e1145_startup(struct phy_device *phydev)
 		return ret;
 
 	phy_write(phydev, MDIO_DEVAD_NONE, MIIM_88E1145_PHY_LED_CONTROL,
-			MIIM_88E1145_PHY_LED_DIRECT);
+		  MIIM_88E1145_PHY_LED_DIRECT);
 	return m88e1xxx_parse_status(phydev);
 }
 
-- 
2.11.0

^ permalink raw reply related	[flat|nested] 138+ messages in thread

* [U-Boot] [PATCH 05/51] net: phy: marvell 88e151x: Fix handling of bare RGMII interface type
  2017-07-14 12:54 [U-Boot] [PATCH 00/51] gdsys: Add support for Gazerbeam board Mario Six
                   ` (3 preceding siblings ...)
  2017-07-14 12:54 ` [U-Boot] [PATCH 04/51] net: phy: marvell: Fix style violations Mario Six
@ 2017-07-14 12:54 ` Mario Six
  2017-07-18 14:01   ` Simon Glass
  2017-07-27 16:55   ` Joe Hershberger
  2017-07-14 12:54 ` [U-Boot] [PATCH 06/51] cmd: Add command for calculating binary operations Mario Six
                   ` (45 subsequent siblings)
  50 siblings, 2 replies; 138+ messages in thread
From: Mario Six @ 2017-07-14 12:54 UTC (permalink / raw)
  To: u-boot

Commit 68e6eca ("net: phy: marvell 88e151x: Fix handling of RGMII
interface types") fixed the initialization of 88e151x phys, but made it
so that interfaces of type PHY_INTERFACE_MODE_RGMII had both RX and TX
delay bits cleared. The default (like in m88e1111s_config) is to have
both bits set.

Hence, this patch changes the behavior in the PHY_INTERFACE_MODE_RGMII
case so that both bits are set.

Signed-off-by: Mario Six <mario.six@gdsys.cc>
---

 drivers/net/phy/marvell.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/net/phy/marvell.c b/drivers/net/phy/marvell.c
index 5d9f50a436..8eddf70c68 100644
--- a/drivers/net/phy/marvell.c
+++ b/drivers/net/phy/marvell.c
@@ -357,7 +357,8 @@ static int m88e1518_config(struct phy_device *phydev)
 
 		reg = phy_read(phydev, MDIO_DEVAD_NONE, MIIM_88E151x_PHY_MSCR);
 		reg &= ~MIIM_88E151x_RGMII_RXTX_DELAY;
-		if (phydev->interface == PHY_INTERFACE_MODE_RGMII_ID)
+		if (phydev->interface == PHY_INTERFACE_MODE_RGMII ||
+		    phydev->interface == PHY_INTERFACE_MODE_RGMII_ID)
 			reg |= MIIM_88E151x_RGMII_RXTX_DELAY;
 		else if (phydev->interface == PHY_INTERFACE_MODE_RGMII_RXID)
 			reg |= MIIM_88E151x_RGMII_RX_DELAY;
-- 
2.11.0

^ permalink raw reply related	[flat|nested] 138+ messages in thread

* [U-Boot] [PATCH 06/51] cmd: Add command for calculating binary operations
  2017-07-14 12:54 [U-Boot] [PATCH 00/51] gdsys: Add support for Gazerbeam board Mario Six
                   ` (4 preceding siblings ...)
  2017-07-14 12:54 ` [U-Boot] [PATCH 05/51] net: phy: marvell 88e151x: Fix handling of bare RGMII interface type Mario Six
@ 2017-07-14 12:54 ` Mario Six
  2017-07-18 14:01   ` Simon Glass
  2017-07-14 12:54 ` [U-Boot] [PATCH 07/51] phy: Allow forcing clause 45 access Mario Six
                   ` (44 subsequent siblings)
  50 siblings, 1 reply; 138+ messages in thread
From: Mario Six @ 2017-07-14 12:54 UTC (permalink / raw)
  To: u-boot

This patch adds a command that enables the calculation of bit operations
(AND, OR, XOR) on binary data from the command line. Memory locations as
well as the contents of environment variables are eligible as sources
and destination of the binary data used in the operations.

The possible applications are manifold: Setting specific bits in
registers using the regular read-OR-write pattern, masking out bits in
bit values, implementation of simple OTP encryption using the XOR
operation, etc.

Signed-off-by: Mario Six <mario.six@gdsys.cc>
---

 cmd/Kconfig  |   6 ++
 cmd/Makefile |   1 +
 cmd/binop.c  | 176 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 183 insertions(+)
 create mode 100644 cmd/binop.c

diff --git a/cmd/Kconfig b/cmd/Kconfig
index c80ac364ea..322e466313 100644
--- a/cmd/Kconfig
+++ b/cmd/Kconfig
@@ -350,6 +350,12 @@ config CMD_MEMORY
 	    base - print or set address offset
 	    loop - initialize loop on address range
 
+config CMD_BINOP
+	bool "binop"
+	help
+	  Compute binary operations (xor, or, and) of data from memory and
+	  store the result in memory or the environment.
+
 config CMD_CRC32
 	bool "crc32"
 	select HASH
diff --git a/cmd/Makefile b/cmd/Makefile
index bd231f24d8..243f9f45d4 100644
--- a/cmd/Makefile
+++ b/cmd/Makefile
@@ -19,6 +19,7 @@ obj-$(CONFIG_SOURCE) += source.o
 obj-$(CONFIG_CMD_SOURCE) += source.o
 obj-$(CONFIG_CMD_BDI) += bdinfo.o
 obj-$(CONFIG_CMD_BEDBUG) += bedbug.o
+obj-$(CONFIG_CMD_BINOP) += binop.o
 obj-$(CONFIG_CMD_BLOCK_CACHE) += blkcache.o
 obj-$(CONFIG_CMD_BMP) += bmp.o
 obj-$(CONFIG_CMD_BOOTEFI) += bootefi.o
diff --git a/cmd/binop.c b/cmd/binop.c
new file mode 100644
index 0000000000..0002c66609
--- /dev/null
+++ b/cmd/binop.c
@@ -0,0 +1,176 @@
+/*
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#include <common.h>
+#include <command.h>
+#include <malloc.h>
+#include <mapmem.h>
+#include <linux/ctype.h>
+
+enum {
+	OP_ID_XOR,
+	OP_ID_AND,
+	OP_ID_OR,
+};
+
+void write_to_env_var(char *varname, u8 *result, ulong len)
+{
+	char *str_output;
+	char *str_ptr;
+	int i;
+
+	str_output = malloc(len * 2 + 1);
+	str_ptr = str_output;
+
+	for (i = 0; i < len; i++) {
+		sprintf(str_ptr, "%02x", result[i]);
+		str_ptr += 2;
+	}
+	*str_ptr = '\0';
+	setenv(varname, str_output);
+
+	free(str_output);
+}
+
+void decode_hexstring(char *hexstr, u8 *result)
+{
+	int i;
+	int acc = 0;
+
+	for (i = 0; i < strlen(hexstr); ++i) {
+		char d = hexstr[i];
+		int value;
+
+		if (isdigit(d))
+			value = (d - '0');
+		else
+			value = (islower(d) ? toupper(d) : d) - 'A' + 10;
+
+		if (i % 2 == 0) {
+			acc = value * 16;
+		} else {
+			result[i / 2] = acc + value;
+			acc = 0;
+		}
+	}
+}
+
+void read_from_env_var(char *varname, u8 *result)
+{
+	char *str_value;
+
+	str_value = getenv(varname);
+	if (str_value)
+		decode_hexstring(str_value, result);
+	else
+		decode_hexstring(varname, result);
+}
+
+void read_from_mem(ulong addr, u8 *result, ulong len)
+{
+	u8 *src;
+
+	src = map_sysmem(addr, len);
+	memcpy(result, src, len);
+	unmap_sysmem(src);
+}
+
+void write_to_mem(char *varname, u8 *result, ulong len)
+{
+	ulong addr;
+	u8 *buf;
+
+	addr = simple_strtoul(varname, NULL, 16);
+	buf = map_sysmem(addr, len);
+	memcpy(buf, result, len);
+	unmap_sysmem(buf);
+}
+
+static int do_binop(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
+{
+	ulong len;
+	u8 *result, *src1, *src2;
+	char *oparg, *lenarg, *src1arg, *src2arg, *destarg;
+	int i, op;
+
+	if (argc < 5)
+		return CMD_RET_USAGE;
+
+	oparg = argv[1];
+	lenarg = argv[2];
+	src1arg = argv[3];
+	src2arg = argv[4];
+
+	if (!strcmp(oparg, "xor"))
+		op = OP_ID_XOR;
+	else if (!strcmp(oparg, "or"))
+		op = OP_ID_OR;
+	else if (!strcmp(oparg, "and"))
+		op = OP_ID_AND;
+	else
+		return CMD_RET_USAGE;
+
+	len = simple_strtoul(lenarg, NULL, 10);
+
+	src1 = malloc(len);
+	src2 = malloc(len);
+
+	if (*src1arg == '*')
+		read_from_mem(simple_strtoul(src1arg + 1, NULL, 16), src1, len);
+	else
+		read_from_env_var(src1arg, src1);
+
+	if (*src2arg == '*')
+		read_from_mem(simple_strtoul(src2arg + 1, NULL, 16), src2, len);
+	else
+		read_from_env_var(src2arg, src2);
+
+	result = malloc(len);
+
+	switch (op) {
+	case OP_ID_XOR:
+		for (i = 0; i < len; i++)
+			result[i] = src1[i] ^ src2[i];
+		break;
+	case OP_ID_OR:
+		for (i = 0; i < len; i++)
+			result[i] = src1[i] | src2[i];
+		break;
+	case OP_ID_AND:
+		for (i = 0; i < len; i++)
+			result[i] = src1[i] & src2[i];
+		break;
+	}
+
+	if (argc == 5) {
+		for (i = 0; i < len; i++) {
+			printf("%02x ", result[i]);
+			if (i % 16 == 15)
+				puts("\n");
+		}
+		puts("\n");
+
+		goto exit;
+	}
+
+	destarg = argv[5];
+
+	if (*destarg == '*')
+		write_to_mem(destarg + 1, result, len); /* Skip asterisk */
+	else
+		write_to_env_var(destarg, result, len);
+exit:
+	free(result);
+	free(src2);
+	free(src1);
+
+	return 0;
+}
+
+U_BOOT_CMD(
+	binop,	6,	1,	do_binop,
+	"compute binary operation",
+	"op count [*]src1 [*]src2 [[*]dest]\n"
+		"    - compute binary operation of data at/in src1 and\n      src2 (either *memaddr, env var name or hex string)\n      and store result in/at dest, where op is one of\n      xor, or, and."
+);
-- 
2.11.0

^ permalink raw reply related	[flat|nested] 138+ messages in thread

* [U-Boot] [PATCH 07/51] phy: Allow forcing clause 45 access
  2017-07-14 12:54 [U-Boot] [PATCH 00/51] gdsys: Add support for Gazerbeam board Mario Six
                   ` (5 preceding siblings ...)
  2017-07-14 12:54 ` [U-Boot] [PATCH 06/51] cmd: Add command for calculating binary operations Mario Six
@ 2017-07-14 12:54 ` Mario Six
  2017-07-18 14:01   ` Simon Glass
  2017-07-14 12:54 ` [U-Boot] [PATCH 08/51] phy: Fix style violations Mario Six
                   ` (43 subsequent siblings)
  50 siblings, 1 reply; 138+ messages in thread
From: Mario Six @ 2017-07-14 12:54 UTC (permalink / raw)
  To: u-boot

From: Dirk Eibach <dirk.eibach@gdsys.cc>

get_phy_device_by_mask() assumes that a clause 45 phy does not respond
to clause 22 requests. That is not true at least for Marvell 88X2242.
So allow forcing clause 45 access to prevent reading bogus device ids.

Signed-off-by: Dirk Eibach <dirk.eibach@gdsys.cc>
Signed-off-by: Mario Six <mario.six@gdsys.cc>
---

 drivers/net/phy/phy.c | 12 +++++++-----
 include/phy.h         | 12 ++++++++++--
 2 files changed, 17 insertions(+), 7 deletions(-)

diff --git a/drivers/net/phy/phy.c b/drivers/net/phy/phy.c
index 97e0bc022b..08ec2f2ad6 100644
--- a/drivers/net/phy/phy.c
+++ b/drivers/net/phy/phy.c
@@ -707,7 +707,7 @@ static struct phy_device *search_for_existing_phy(struct mii_dev *bus,
 }
 
 static struct phy_device *get_phy_device_by_mask(struct mii_dev *bus,
-		unsigned phy_mask, phy_interface_t interface)
+		unsigned phy_mask, phy_interface_t interface, bool force_c45)
 {
 	int i;
 	struct phy_device *phydev;
@@ -718,6 +718,8 @@ static struct phy_device *get_phy_device_by_mask(struct mii_dev *bus,
 	/* Try Standard (ie Clause 22) access */
 	/* Otherwise we have to try Clause 45 */
 	for (i = 0; i < 5; i++) {
+		if (!i && force_c45)
+			continue;
 		phydev = create_phy_by_mask(bus, phy_mask,
 				i ? i : MDIO_DEVAD_NONE, interface);
 		if (IS_ERR(phydev))
@@ -748,7 +750,7 @@ static struct phy_device *get_phy_device_by_mask(struct mii_dev *bus,
 static struct phy_device *get_phy_device(struct mii_dev *bus, int addr,
 					 phy_interface_t interface)
 {
-	return get_phy_device_by_mask(bus, 1 << addr, interface);
+	return get_phy_device_by_mask(bus, 1 << addr, interface, false);
 }
 
 int phy_reset(struct phy_device *phydev)
@@ -817,8 +819,8 @@ int miiphy_reset(const char *devname, unsigned char addr)
 	return phy_reset(phydev);
 }
 
-struct phy_device *phy_find_by_mask(struct mii_dev *bus, unsigned phy_mask,
-		phy_interface_t interface)
+struct phy_device *__phy_find_by_mask(struct mii_dev *bus, unsigned phy_mask,
+		phy_interface_t interface, bool force_c45)
 {
 	/* Reset the bus */
 	if (bus->reset) {
@@ -828,7 +830,7 @@ struct phy_device *phy_find_by_mask(struct mii_dev *bus, unsigned phy_mask,
 		udelay(15000);
 	}
 
-	return get_phy_device_by_mask(bus, phy_mask, interface);
+	return get_phy_device_by_mask(bus, phy_mask, interface, force_c45);
 }
 
 #ifdef CONFIG_DM_ETH
diff --git a/include/phy.h b/include/phy.h
index 4f2094bdf0..75a9ae3314 100644
--- a/include/phy.h
+++ b/include/phy.h
@@ -227,8 +227,16 @@ static inline int is_10g_interface(phy_interface_t interface)
 
 int phy_init(void);
 int phy_reset(struct phy_device *phydev);
-struct phy_device *phy_find_by_mask(struct mii_dev *bus, unsigned phy_mask,
-		phy_interface_t interface);
+struct phy_device *__phy_find_by_mask(struct mii_dev *bus, unsigned phy_mask,
+		phy_interface_t interface, bool force_c45);
+static inline struct phy_device *phy_find_by_mask(struct mii_dev *bus,
+		unsigned phy_mask, phy_interface_t interface) {
+	return __phy_find_by_mask(bus, phy_mask, interface, 0);
+}
+static inline struct phy_device *phy_find_by_mask_c45(struct mii_dev *bus,
+		unsigned phy_mask, phy_interface_t interface) {
+	return __phy_find_by_mask(bus, phy_mask, interface, 1);
+}
 #ifdef CONFIG_DM_ETH
 void phy_connect_dev(struct phy_device *phydev, struct udevice *dev);
 struct phy_device *phy_connect(struct mii_dev *bus, int addr,
-- 
2.11.0

^ permalink raw reply related	[flat|nested] 138+ messages in thread

* [U-Boot] [PATCH 08/51] phy: Fix style violations
  2017-07-14 12:54 [U-Boot] [PATCH 00/51] gdsys: Add support for Gazerbeam board Mario Six
                   ` (6 preceding siblings ...)
  2017-07-14 12:54 ` [U-Boot] [PATCH 07/51] phy: Allow forcing clause 45 access Mario Six
@ 2017-07-14 12:54 ` Mario Six
  2017-07-18 14:01   ` Simon Glass
  2017-07-14 12:54 ` [U-Boot] [PATCH 09/51] phy: Support Marvell 88X2242 Mario Six
                   ` (42 subsequent siblings)
  50 siblings, 1 reply; 138+ messages in thread
From: Mario Six @ 2017-07-14 12:54 UTC (permalink / raw)
  To: u-boot

Fix some style violations in the generic PHY management code.

Signed-off-by: Mario Six <mario.six@gdsys.cc>
---

 drivers/net/phy/phy.c | 83 +++++++++++++++++++++++++++++++--------------------
 1 file changed, 50 insertions(+), 33 deletions(-)

diff --git a/drivers/net/phy/phy.c b/drivers/net/phy/phy.c
index 08ec2f2ad6..a16bb6ca89 100644
--- a/drivers/net/phy/phy.c
+++ b/drivers/net/phy/phy.c
@@ -27,7 +27,7 @@ DECLARE_GLOBAL_DATA_PTR;
 /* Generic PHY support and helper functions */
 
 /**
- * genphy_config_advert - sanitize and advertise auto-negotation parameters
+ * genphy_config_advert - sanitize and advertise auto-negotiation parameters
  * @phydev: target phy_device struct
  *
  * Description: Writes MII_ADVERTISE with the appropriate values,
@@ -117,7 +117,6 @@ static int genphy_config_advert(struct phy_device *phydev)
 	return changed;
 }
 
-
 /**
  * genphy_setup_forced - configures/forces speed/duplex from @phydev
  * @phydev: target phy_device struct
@@ -130,14 +129,15 @@ static int genphy_setup_forced(struct phy_device *phydev)
 	int err;
 	int ctl = BMCR_ANRESTART;
 
-	phydev->pause = phydev->asym_pause = 0;
+	phydev->pause = 0;
+	phydev->asym_pause = 0;
 
-	if (SPEED_1000 == phydev->speed)
+	if (phydev->speed == SPEED_1000)
 		ctl |= BMCR_SPEED1000;
-	else if (SPEED_100 == phydev->speed)
+	else if (phydev->speed == SPEED_100)
 		ctl |= BMCR_SPEED100;
 
-	if (DUPLEX_FULL == phydev->duplex)
+	if (phydev->duplex == DUPLEX_FULL)
 		ctl |= BMCR_FULLDPLX;
 
 	err = phy_write(phydev, MDIO_DEVAD_NONE, MII_BMCR, ctl);
@@ -145,7 +145,6 @@ static int genphy_setup_forced(struct phy_device *phydev)
 	return err;
 }
 
-
 /**
  * genphy_restart_aneg - Enable and Restart Autonegotiation
  * @phydev: target phy_device struct
@@ -169,7 +168,6 @@ int genphy_restart_aneg(struct phy_device *phydev)
 	return ctl;
 }
 
-
 /**
  * genphy_config_aneg - restart auto-negotiation or write BMCR
  * @phydev: target phy_device struct
@@ -182,7 +180,7 @@ int genphy_config_aneg(struct phy_device *phydev)
 {
 	int result;
 
-	if (AUTONEG_ENABLE != phydev->autoneg)
+	if (phydev->autoneg != AUTONEG_ENABLE)
 		return genphy_setup_forced(phydev);
 
 	result = genphy_config_advert(phydev);
@@ -192,7 +190,8 @@ int genphy_config_aneg(struct phy_device *phydev)
 
 	if (result == 0) {
 		/* Advertisment hasn't changed, but maybe aneg was never on to
-		 * begin with?  Or maybe phy was isolated? */
+		 * begin with?  Or maybe phy was isolated?
+		 */
 		int ctl = phy_read(phydev, MDIO_DEVAD_NONE, MII_BMCR);
 
 		if (ctl < 0)
@@ -203,7 +202,8 @@ int genphy_config_aneg(struct phy_device *phydev)
 	}
 
 	/* Only restart aneg if we are advertising something different
-	 * than we were before.	 */
+	 * than we were before.
+	 */
 	if (result > 0)
 		result = genphy_restart_aneg(phydev);
 
@@ -240,7 +240,7 @@ int genphy_update_link(struct phy_device *phydev)
 		int i = 0;
 
 		printf("%s Waiting for PHY auto negotiation to complete",
-			phydev->dev->name);
+		       phydev->dev->name);
 		while (!(mii_reg & BMSR_ANEGCOMPLETE)) {
 			/*
 			 * Timeout reached ?
@@ -305,7 +305,8 @@ int genphy_parse_link(struct phy_device *phydev)
 			 */
 			gblpa = phy_read(phydev, MDIO_DEVAD_NONE, MII_STAT1000);
 			if (gblpa < 0) {
-				debug("Could not read MII_STAT1000. Ignoring gigabit capability\n");
+				debug("Could not read MII_STAT1000. ");
+				debug("Ignoring gigabit capability\n");
 				gblpa = 0;
 			}
 			gblpa &= phy_read(phydev,
@@ -338,8 +339,9 @@ int genphy_parse_link(struct phy_device *phydev)
 			if (lpa & LPA_100FULL)
 				phydev->duplex = DUPLEX_FULL;
 
-		} else if (lpa & LPA_10FULL)
+		} else if (lpa & LPA_10FULL) {
 			phydev->duplex = DUPLEX_FULL;
+		}
 
 		/*
 		 * Extended status may indicate that the PHY supports
@@ -571,7 +573,9 @@ static int phy_probe(struct phy_device *phydev)
 {
 	int err = 0;
 
-	phydev->advertising = phydev->supported = phydev->drv->features;
+	phydev->advertising = phydev->drv->features;
+	phydev->supported = phydev->drv->features;
+
 	phydev->mmds = phydev->drv->mmds;
 
 	if (phydev->drv->probe)
@@ -591,7 +595,7 @@ static struct phy_driver *generic_for_interface(phy_interface_t interface)
 }
 
 static struct phy_driver *get_phy_driver(struct phy_device *phydev,
-				phy_interface_t interface)
+					 phy_interface_t interface)
 {
 	struct list_head *entry;
 	int phy_id = phydev->phy_id;
@@ -614,11 +618,12 @@ static struct phy_device *phy_device_create(struct mii_dev *bus, int addr,
 	struct phy_device *dev;
 
 	/* We allocate the device, and initialize the
-	 * default values */
+	 * default values
+	 */
 	dev = malloc(sizeof(*dev));
 	if (!dev) {
 		printf("Failed to allocate PHY device for %s:%d\n",
-			bus->name, addr);
+		       bus->name, addr);
 		return NULL;
 	}
 
@@ -657,7 +662,8 @@ int __weak get_phy_id(struct mii_dev *bus, int addr, int devad, u32 *phy_id)
 	int phy_reg;
 
 	/* Grab the bits from PHYIR1, and put them
-	 * in the upper half */
+	 * in the upper half
+	 */
 	phy_reg = bus->read(bus, addr, devad, MII_PHYSID1);
 
 	if (phy_reg < 0)
@@ -677,9 +683,11 @@ int __weak get_phy_id(struct mii_dev *bus, int addr, int devad, u32 *phy_id)
 }
 
 static struct phy_device *create_phy_by_mask(struct mii_dev *bus,
-		unsigned phy_mask, int devad, phy_interface_t interface)
+					     uint phy_mask, int devad,
+					     phy_interface_t interface)
 {
 	u32 phy_id = 0xffffffff;
+
 	while (phy_mask) {
 		int addr = ffs(phy_mask) - 1;
 		int r = get_phy_id(bus, addr, devad, &phy_id);
@@ -692,11 +700,13 @@ static struct phy_device *create_phy_by_mask(struct mii_dev *bus,
 }
 
 static struct phy_device *search_for_existing_phy(struct mii_dev *bus,
-		unsigned phy_mask, phy_interface_t interface)
+						  uint phy_mask,
+						  phy_interface_t interface)
 {
 	/* If we have one, return the existing device, with new interface */
 	while (phy_mask) {
 		int addr = ffs(phy_mask) - 1;
+
 		if (bus->phymap[addr]) {
 			bus->phymap[addr]->interface = interface;
 			return bus->phymap[addr];
@@ -707,7 +717,9 @@ static struct phy_device *search_for_existing_phy(struct mii_dev *bus,
 }
 
 static struct phy_device *get_phy_device_by_mask(struct mii_dev *bus,
-		unsigned phy_mask, phy_interface_t interface, bool force_c45)
+						 uint phy_mask,
+						 phy_interface_t interface,
+						 bool force_c45)
 {
 	int i;
 	struct phy_device *phydev;
@@ -721,7 +733,7 @@ static struct phy_device *get_phy_device_by_mask(struct mii_dev *bus,
 		if (!i && force_c45)
 			continue;
 		phydev = create_phy_by_mask(bus, phy_mask,
-				i ? i : MDIO_DEVAD_NONE, interface);
+					    i ? i : MDIO_DEVAD_NONE, interface);
 		if (IS_ERR(phydev))
 			return NULL;
 		if (phydev)
@@ -731,6 +743,7 @@ static struct phy_device *get_phy_device_by_mask(struct mii_dev *bus,
 	debug("\n%s PHY: ", bus->name);
 	while (phy_mask) {
 		int addr = ffs(phy_mask) - 1;
+
 		debug("%d ", addr);
 		phy_mask &= ~(1 << addr);
 	}
@@ -740,7 +753,8 @@ static struct phy_device *get_phy_device_by_mask(struct mii_dev *bus,
 }
 
 /**
- * get_phy_device - reads the specified PHY device and returns its @phy_device struct
+ * get_phy_device - reads the specified PHY device and returns its
+ *                  @phy_device struct
  * @bus: the target MII bus
  * @addr: PHY address on the MII bus
  *
@@ -819,15 +833,15 @@ int miiphy_reset(const char *devname, unsigned char addr)
 	return phy_reset(phydev);
 }
 
-struct phy_device *__phy_find_by_mask(struct mii_dev *bus, unsigned phy_mask,
-		phy_interface_t interface, bool force_c45)
+struct phy_device *__phy_find_by_mask(struct mii_dev *bus, uint phy_mask,
+				      phy_interface_t interface, bool force_c45)
 {
 	/* Reset the bus */
 	if (bus->reset) {
 		bus->reset(bus);
 
 		/* Wait 15ms to make sure the PHY has come out of hard reset */
-		udelay(15000);
+		mdelay(15);
 	}
 
 	return get_phy_device_by_mask(bus, phy_mask, interface, force_c45);
@@ -843,8 +857,8 @@ void phy_connect_dev(struct phy_device *phydev, struct eth_device *dev)
 	phy_reset(phydev);
 	if (phydev->dev && phydev->dev != dev) {
 		printf("%s:%d is connected to %s.  Reconnecting to %s\n",
-				phydev->bus->name, phydev->addr,
-				phydev->dev->name, dev->name);
+		       phydev->bus->name, phydev->addr,
+		       phydev->dev->name, dev->name);
 	}
 	phydev->dev = dev;
 	debug("%s connected to %s\n", dev->name, phydev->drv->name);
@@ -852,20 +866,23 @@ void phy_connect_dev(struct phy_device *phydev, struct eth_device *dev)
 
 #ifdef CONFIG_DM_ETH
 struct phy_device *phy_connect(struct mii_dev *bus, int addr,
-		struct udevice *dev, phy_interface_t interface)
+			       struct udevice *dev,
+			       phy_interface_t interface)
 #else
 struct phy_device *phy_connect(struct mii_dev *bus, int addr,
-		struct eth_device *dev, phy_interface_t interface)
+			       struct eth_device *dev,
+			       phy_interface_t interface)
 #endif
 {
 	struct phy_device *phydev = NULL;
 #ifdef CONFIG_PHY_FIXED
 	int sn;
 	const char *name;
+
 	sn = fdt_first_subnode(gd->fdt_blob, dev_of_offset(dev));
 	while (sn > 0) {
 		name = fdt_get_name(gd->fdt_blob, sn, NULL);
-		if (name != NULL && strcmp(name, "fixed-link") == 0) {
+		if (name && strcmp(name, "fixed-link") == 0) {
 			phydev = phy_device_create(bus,
 						   sn, PHY_FIXED_ID, interface);
 			break;
@@ -873,7 +890,7 @@ struct phy_device *phy_connect(struct mii_dev *bus, int addr,
 		sn = fdt_next_subnode(gd->fdt_blob, sn);
 	}
 #endif
-	if (phydev == NULL)
+	if (!phydev)
 		phydev = phy_find_by_mask(bus, 1 << addr, interface);
 
 	if (phydev)
-- 
2.11.0

^ permalink raw reply related	[flat|nested] 138+ messages in thread

* [U-Boot] [PATCH 09/51] phy: Support Marvell 88X2242
  2017-07-14 12:54 [U-Boot] [PATCH 00/51] gdsys: Add support for Gazerbeam board Mario Six
                   ` (7 preceding siblings ...)
  2017-07-14 12:54 ` [U-Boot] [PATCH 08/51] phy: Fix style violations Mario Six
@ 2017-07-14 12:54 ` Mario Six
  2017-07-18 14:01   ` Simon Glass
  2017-07-14 12:54 ` [U-Boot] [PATCH 10/51] net:phy:marvell Add hook for m88e1510 board config Mario Six
                   ` (41 subsequent siblings)
  50 siblings, 1 reply; 138+ messages in thread
From: Mario Six @ 2017-07-14 12:54 UTC (permalink / raw)
  To: u-boot

From: Dirk Eibach <dirk.eibach@gdsys.cc>

Implement support for the Marvell Alaska X 88X2242P Integrated Dual-port
and Quad-port Multi-speed Ethernet Transceivers.

Signed-off-by: Dirk Eibach <dirk.eibach@gdsys.cc>
Signed-off-by: Mario Six <mario.six@gdsys.cc>
---

 drivers/net/phy/Kconfig   |  67 ++++
 drivers/net/phy/Makefile  |   1 +
 drivers/net/phy/marvell.c |   1 -
 drivers/net/phy/mv88x2.c  | 846 ++++++++++++++++++++++++++++++++++++++++++++++
 drivers/net/phy/mv88x2.h  |  12 +
 drivers/net/phy/phy.c     |   3 +
 include/phy.h             |   1 +
 7 files changed, 930 insertions(+), 1 deletion(-)
 create mode 100644 drivers/net/phy/mv88x2.c
 create mode 100644 drivers/net/phy/mv88x2.h

diff --git a/drivers/net/phy/Kconfig b/drivers/net/phy/Kconfig
index 0230852244..bb21be197f 100644
--- a/drivers/net/phy/Kconfig
+++ b/drivers/net/phy/Kconfig
@@ -55,6 +55,73 @@ config PHY_LXT
 config PHY_MARVELL
 	bool "Marvell Ethernet PHYs support"
 
+
+if PHY_MARVELL
+
+config BOARD_M88E1510_CONFIG
+	bool "M88E1510 board-specific callback"
+
+endif
+
+config PHY_MV88X2
+	depends on PHYLIB_10G
+	bool "Marvell 88X2 PHYs support"
+
+if PHY_MV88X2
+
+config BOARD_MV88X2_CONFIG
+	bool "MV88X2 board-specific callback"
+
+config MV88X2_DEBUG_REGS
+	bool "Debug register printing"
+
+config MV88X2_LINE_10GBASE_R
+	bool "Enable Line 10GBASE-R support"
+
+config MV88X2_HOST_10GBASE_X2
+	bool "Enable Host 10GBASE-X2 support"
+
+config MV88X2_X2_DISPARITY
+	bool "Enable 10GBASE-X2 disparity"
+
+config MV88X2_LED0_BLINK
+	int "LED0 blink behavior"
+	range 0 11
+	default 0
+
+config MV88X2_LED0_SOLID
+	int "LED0 solid behavior"
+	range 0 7
+	default 0
+
+config MV88X2_LED1_BLINK
+	int "LED1 blink behavior"
+	range 0 11
+	default 0
+
+config MV88X2_LED1_SOLID
+	int "LED1 solid behavior"
+	range 0 7
+	default 0
+
+config MV88X2_HOST_LANE_MUX_2_PORT
+	hex "Host side lane muxing (2 ports)"
+	default 0x0
+
+config MV88X2_HOST_LANE_MUX_4_PORT
+	hex "Host side lane muxing (4 ports)"
+	default 0x0
+
+config MV88X2_SFI_POL
+	hex "SFI polarity"
+	default 0x0
+
+config MV88X2_XFI_POL
+	hex "XFI polarity"
+	default 0x0
+
+endif
+
 config PHY_MICREL
 	bool "Micrel Ethernet PHYs support"
 	help
diff --git a/drivers/net/phy/Makefile b/drivers/net/phy/Makefile
index 88c00a5cd3..631797a1f0 100644
--- a/drivers/net/phy/Makefile
+++ b/drivers/net/phy/Makefile
@@ -20,6 +20,7 @@ obj-$(CONFIG_PHY_ET1011C) += et1011c.o
 obj-$(CONFIG_PHY_LXT) += lxt.o
 obj-$(CONFIG_PHY_MARVELL) += marvell.o
 obj-$(CONFIG_PHY_MICREL) += micrel.o
+obj-$(CONFIG_PHY_MV88X2) += mv88x2.o
 obj-$(CONFIG_PHY_NATSEMI) += natsemi.o
 obj-$(CONFIG_PHY_REALTEK) += realtek.o
 obj-$(CONFIG_PHY_SMSC) += smsc.o
diff --git a/drivers/net/phy/marvell.c b/drivers/net/phy/marvell.c
index 8eddf70c68..66107a8af3 100644
--- a/drivers/net/phy/marvell.c
+++ b/drivers/net/phy/marvell.c
@@ -720,6 +720,5 @@ int phy_marvell_init(void)
 	phy_register(&M88E1510_driver);
 	phy_register(&M88E1518_driver);
 	phy_register(&M88E1680_driver);
-
 	return 0;
 }
diff --git a/drivers/net/phy/mv88x2.c b/drivers/net/phy/mv88x2.c
new file mode 100644
index 0000000000..9d04197e47
--- /dev/null
+++ b/drivers/net/phy/mv88x2.c
@@ -0,0 +1,846 @@
+/*
+ * Driver for Marvell 88X2 PHYs
+ * Support for Revision A devices is not included.
+ *
+ * (C) Copyright 2016
+ * Dirk Eibach,  Guntermann & Drunck GmbH, eibach at gdsys.de
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#include <config.h>
+#include <common.h>
+#include <miiphy.h>
+#include <phy.h>
+#include <console.h>
+
+#include "mv88x2.h"
+
+enum {
+	MGD_2140M_A1	= 0x1b,		/* 88X2140M_A1 */
+
+	MGD_22x2M	= 0x31,		/* 88X22x2M */
+	MGD_2242_B0	= 0x311,	/* 88X2242_B0 */
+	MGD_2242M_A0	= 0x312,	/* 88X2242M_A0 (MGD_22x2M + rev=2) */
+	MGD_2242M_B0	= 0x313,	/* 88X2242M_B0 (MGD_22x2M + rev=3) */
+	MGD_2222_B0	= 0x315,	/* 88X2222_B0 (MGD_22x2M + rev=5) */
+	MGD_2222M_B0	= 0x317,	/* 88X2222M_B0 (MGD_22x2M + rev=7) */
+
+	MGD_22x2P	= 0x19,		/* 88X22x2P */
+	MGD_2242P_A0	= 0x191,	/* 88X2242P_A0 (MGD_22x2P + rev=1) */
+	MGD_2222P_A0	= 0x199,	/* 88X2222P_A0 (MGD_22x2P + rev=9) */
+};
+
+enum {
+	MGD_PCS_SPEED_40GBASE_R4	= 0x70,
+	MGD_PCS_SPEED_10GBASE_R		= 0x71,
+	MGD_PCS_SPEED_10GBASE_X2	= 0x72,
+	MGD_PCS_SPEED_10GBASE_X4	= 0x73,
+	MGD_PCS_SPEED_10GBASE_W		= 0x74, /* line side only */
+	MGD_PCS_SPEED_20GBASE_R2	= 0x75,
+	MGD_PCS_SPEED_20GBASE_X4	= 0x76,
+	MGD_PCS_SPEED_2500BASE_X	= 0X76,
+	MGD_PCS_SPEED_20GBASE_R8	= 0x77, /* host side only */
+	MGD_PCS_SPEED_40GBASE_R8	= 0x77, /* host side only */
+	MGD_PCS_SPEED_1000BASE_AN_OFF	= 0x7A,
+	MGD_PCS_SPEED_1000BASE_AN_ON	= 0x7B,
+	MGD_PCS_SPEED_SGMII_MAC_AN_OFF	= 0x7C,
+	MGD_PCS_SPEED_SGMII_MAC_AN_ON	= 0x7D,
+	MGD_PCS_SPEED_SGMII_LINE_AN_OFF	= 0x7E,
+	MGD_PCS_SPEED_SGMII_LINE_AN_ON	= 0x7F,
+	MGD_PCS_SPEED_UNKNOWN		= 0x78, /* temp set reserved */
+};
+
+struct debug_register {
+	int port;
+	int devad;
+	int regnum;
+} debug_registers[] = {
+	/* PCS Registers */
+	{ 0, 31, 0xf002 },
+	/* line side */
+	{ 0, 3, 0xf074 }, /* pwr mgmt TX state control*/
+	{ 0, 3, 0x0001 }, /* PCS status*/
+	{ 0, 3, 0xf002 }, /* PCS port configuration*/
+	{ 0, 3, 0xf010 }, /* Packet generator/CRC checker*/
+	{ 0, 3, 0x3021 }, /* PCS status2 (block lock/High BER)*/
+	/* host side */
+	{ 0, 4, 0xf074 }, /* Power management control*/
+	{ 0, 4, 0x1018 }, /* XAUI/RXAUI alignment and sync*/
+	{ 0, 4, 0x3032 }, /* XAUI/RXAUI block lock per lane*/
+	{ 0, 4, 0x3034 }, /* XAUI/RXAUI alignment*/
+	{ 0, 4, 0x0001 }, /* PCS status*/
+	{ 0, 4, 0xf002 }, /* PCS port configuration*/
+	{ 0, 4, 0xf010 }, /* Packet generator/CRC checker*/
+	{ 0, 4, 0x3021 }, /* PCS status2 (block lock/High BER)*/
+	/* DSP Registers */
+	/* line side */
+	{ 0, 30, 0xb841 },
+	/* port 0 */
+	{ 0, 30, 0xb111 },
+	{ 0, 30, 0xb116 }, /* sfi tx settings*/
+	{ 0, 30, 0xb117 }, /* sfi tx settings*/
+	{ 0, 30, 0xb042 }, /* dsp status*/
+	{ 0, 30, 0xb132 }, /* pga*/
+	{ 0, 30, 0xb000 },
+	{ 0, 30, 0xb001 },
+	{ 0, 30, 0xb1be }, /* snr*/
+	{ 0, 30, 0xb1f1 },
+	{ 0, 30, 0xb1d3 },
+	{ 0, 30, 0xb065 },
+	{ 0, 30, 0xb1bb },
+	{ 0, 30, 0xb1bc },
+	{ 0, 30, 0xb1bf },
+	{ 0, 30, 0xb1b3 },
+	/* port 1 */
+	{ 0, 30, 0xb311 },
+	{ 0, 30, 0xb316 },
+	{ 0, 30, 0xb317 },
+	{ 0, 30, 0xb242 },
+	{ 0, 30, 0xb332 },
+	{ 0, 30, 0xb200 },
+	{ 0, 30, 0xb201 },
+	{ 0, 30, 0xb3be },
+	{ 0, 30, 0xb3f1 },
+	{ 0, 30, 0xb3d3 },
+	{ 0, 30, 0xb265 },
+	{ 0, 30, 0xb3bb },
+	{ 0, 30, 0xb3bc },
+	{ 0, 30, 0xb3bf },
+	{ 0, 30, 0xb3b3 },
+	/* port 2 */
+	{ 0, 30, 0xb511 },
+	{ 0, 30, 0xb516 },
+	{ 0, 30, 0xb517 },
+	{ 0, 30, 0xb442 },
+	{ 0, 30, 0xb532 },
+	{ 0, 30, 0xb400 },
+	{ 0, 30, 0xb401 },
+	{ 0, 30, 0xb5be },
+	{ 0, 30, 0xb5f1 },
+	{ 0, 30, 0xb5d3 },
+	{ 0, 30, 0xb465 },
+	{ 0, 30, 0xb5bb },
+	{ 0, 30, 0xb5bc },
+	{ 0, 30, 0xb5bf },
+	{ 0, 30, 0xb5b3 },
+	/* port 3 */
+	{ 0, 30, 0xb711 },
+	{ 0, 30, 0xb716 },
+	{ 0, 30, 0xb717 },
+	{ 0, 30, 0xb642 },
+	{ 0, 30, 0xb732 },
+	{ 0, 30, 0xb600 },
+	{ 0, 30, 0xb601 },
+	{ 0, 30, 0xb7be },
+	{ 0, 30, 0xb7f1 },
+	{ 0, 30, 0xb7d3 },
+	{ 0, 30, 0xb665 },
+	{ 0, 30, 0xb7bb },
+	{ 0, 30, 0xb7bc },
+	{ 0, 30, 0xb7bf },
+	{ 0, 30, 0xb7b3 },
+	{ 0, 30, 0xb753 },
+	{ 0, 30, 0xb780 },
+	{ 0, 30, 0xb7d4 },
+	{ 0, 30, 0xb7d6 },
+	{ 0, 30, 0xb7ea },
+	/* host side */
+	{ 0, 30, 0x9041 },
+	/* port 0 */
+	{ 0, 30, 0x8111 },
+	{ 0, 30, 0x8116 },
+	{ 0, 30, 0x8117 },
+	{ 0, 30, 0x8042 },
+	{ 0, 30, 0x8132 },
+	{ 0, 30, 0x81d1 },
+	/* port 1 */
+	{ 0, 30, 0x8311 },
+	{ 0, 30, 0x8316 },
+	{ 0, 30, 0x8317 },
+	{ 0, 30, 0x8242 },
+	{ 0, 30, 0x8332 },
+	{ 0, 30, 0x83d1 },
+	/* port 2 */
+	{ 0, 30, 0x8511 },
+	{ 0, 30, 0x8516 },
+	{ 0, 30, 0x8517 },
+	{ 0, 30, 0x8442 },
+	{ 0, 30, 0x8532 },
+	{ 0, 30, 0x85d1 },
+	/* port 3 */
+	{ 0, 30, 0x8711 },
+	{ 0, 30, 0x8716 },
+	{ 0, 30, 0x8717 },
+	{ 0, 30, 0x8642 },
+	{ 0, 30, 0x8732 },
+	{ 0, 30, 0x87d1 },
+};
+
+static const char *get_name(u16 device_id)
+{
+	switch (device_id) {
+	case MGD_2140M_A1:
+		return "MV88X2140M_A1";
+	case MGD_2242_B0:
+		return "MV88X2242_B0";
+	case MGD_2242M_A0:
+		return "MV88X2242M_A0";
+	case MGD_2242M_B0:
+		return "MV88X2242M_B0";
+	case MGD_2222_B0:
+		return "MV88X2222_B0";
+	case MGD_2222M_B0:
+		return "MV88X2222M_B0";
+	case MGD_2242P_A0:
+		return "MV88X2242P_A0";
+	case MGD_2222P_A0:
+		return "MV88X2222P_A0";
+	}
+
+	return "";
+}
+
+static int get_num_ports(u16 device_id)
+{
+	int res = -1;
+
+	switch (device_id) {
+	case MGD_2140M_A1:
+	case MGD_2242M_A0:
+	case MGD_2242M_B0:
+	case MGD_2242_B0:
+	case MGD_2242P_A0:
+		res = 4;
+		break;
+
+	case MGD_2222P_A0:
+	case MGD_2222_B0:
+	case MGD_2222M_B0:
+		res = 2;
+		break;
+	};
+
+	return res;
+}
+
+/*
+ * 88X2 takes 4 consecutive addresses on the mdio bus
+ * this provides access to these port instances
+ */
+static int m88x2_read(struct phy_device *phydev, int port, int devad,
+		      int regnum)
+{
+	struct mii_dev *bus = phydev->bus;
+
+	return bus->read(bus, phydev->addr + port, devad, regnum);
+}
+
+static int m88x2_write(struct phy_device *phydev, int port, int devad,
+		       int regnum, u16 val)
+{
+	struct mii_dev *bus = phydev->bus;
+
+	return bus->write(bus, phydev->addr + port, devad, regnum, val);
+}
+
+static int m88x2_write_mask(struct phy_device *phydev, int port, int devad,
+			    int regnum, u16 mask, u16 val)
+{
+	u16 reg;
+	struct mii_dev *bus = phydev->bus;
+
+	reg = bus->read(bus, phydev->addr + port, devad, regnum);
+	reg &= ~mask;
+	reg |= val;
+
+	return bus->write(bus, phydev->addr + port, devad, regnum, reg);
+}
+
+static int m88x2_write_all(struct phy_device *phydev, int devad, int regnum,
+			   u16 val)
+{
+	unsigned int k;
+
+	for (k = 0; k < 4; ++k) {
+		int res = m88x2_write(phydev, k, devad, regnum, val);
+
+		if (res < 0)
+			return res;
+	}
+
+	return 0;
+}
+
+#ifdef CONFIG_MV88X2_DEBUG_REGS
+static void m88x2_dump_debug(struct phy_device *phydev)
+{
+	unsigned int k;
+
+	for (k = 0; k < ARRAY_SIZE(debug_registers); ++k) {
+		int val;
+		struct debug_register *reg = &debug_registers[k];
+
+		val = m88x2_read(phydev, reg->port, reg->devad, reg->regnum);
+		printf("%2x.%04x %04x\n", reg->devad, reg->regnum, val);
+	}
+}
+#endif
+
+/* 88X2 has a weird way of mixing revision and device id encoding */
+static int get_device_id(struct phy_device *phydev)
+{
+	u16 id2 = phy_read(phydev, 1, 3);
+	u16 device_id_raw = id2 & 0x3FF;
+	u16 device_id_base = device_id_raw >> 4;
+	u16 revision = device_id_raw & 0xF;
+	int res = -1;
+
+	switch (device_id_base) {
+	case MGD_22x2M:
+		switch (revision) {
+		case 1:
+			res = MGD_2242_B0;
+			break;
+		case 2:
+			res = MGD_2242M_A0;
+			break;
+		case 3:
+			res = MGD_2242M_B0;
+			break;
+		case 5:
+			res = MGD_2222_B0;
+			break;
+		case 7:
+			res = MGD_2222M_B0;
+			break;
+		}
+		break;
+	case MGD_22x2P:
+		switch (revision) {
+		case 1:
+			res = MGD_2242P_A0;
+			break;
+		case 9:
+			res = MGD_2222P_A0;
+			break;
+		}
+		break;
+	}
+
+	return res;
+}
+
+static int configure_host_lanes(struct phy_device *phydev, int num_ports)
+{
+	printf("       setup host lane mux for %d ports\n", num_ports);
+
+#ifdef CONFIG_MV88X2_HOST_LANE_MUX_4_PORT
+	if (num_ports == 4) {
+		m88x2_write(phydev, 0, 31, 0xf402,
+			    CONFIG_MV88X2_HOST_LANE_MUX_4_PORT);
+	}
+#endif
+
+#ifdef CONFIG_MV88X2_HOST_LANE_MUX_2_PORT
+	if (num_ports == 2)
+		m88x2_write(phydev, 0, 31, 0xf402,
+			    CONFIG_MV88X2_HOST_LANE_MUX_2_PORT);
+#endif
+
+	m88x2_write_mask(phydev, 0, 31, 0xf404, 0x8000, 0x8000);
+
+	m88x2_write_all(phydev, 31, 0xf003, 0x0080);
+
+	return 0;
+}
+
+static int configure_options(struct phy_device *phydev)
+{
+	struct mv88x2_config_data data;
+
+	printf("       setup board specific options\n");
+
+	memset(&data, 0, sizeof(struct mv88x2_config_data));
+
+	data.led0_blink = CONFIG_MV88X2_LED0_BLINK;
+	data.led0_solid = CONFIG_MV88X2_LED0_SOLID;
+	data.led1_blink = CONFIG_MV88X2_LED1_BLINK;
+	data.led1_solid = CONFIG_MV88X2_LED1_SOLID;
+	data.sfi_pol = CONFIG_MV88X2_SFI_POL;
+	data.xfi_pol = CONFIG_MV88X2_XFI_POL;
+
+#ifdef CONFIG_BOARD_MV88X2_CONFIG
+	board_mv88x2_config(&data);
+#endif
+
+	if (data.sfi_pol)
+		m88x2_write(phydev, 0, 31, 0xf407, data.sfi_pol);
+
+	m88x2_write(phydev, 0, 31, 0xf406, data.xfi_pol);
+
+#ifdef CONFIG_MV88X2_X2_DISPARITY
+	m88x2_write_all(phydev, 4, 0x9000, 0x0002);
+#endif
+
+	m88x2_write_all(phydev, 31, 0xf020, data.led0_blink << 8 |
+					    data.led0_solid << 4);
+
+	m88x2_write_all(phydev, 31, 0xf021, data.led1_blink << 8 |
+					    data.led1_solid << 4);
+	return 0;
+}
+
+static int port_power_up(struct phy_device *phydev, unsigned int device_id,
+			 unsigned int port)
+{
+	printf("       power up port %u\n", port);
+
+	/* power up all ports in config reg */
+	m88x2_write(phydev, 0, 31, 0xf403, 0x0000);
+
+	if (device_id == MGD_2242M_B0 ||
+	    device_id == MGD_2222_B0 ||
+	    device_id == MGD_2222M_B0 ||
+	    device_id == MGD_2242_B0) {
+		m88x2_write(phydev, 0, 31, 0xf400, 0xba98);
+		m88x2_write(phydev, 0, 31, 0xf401, 0xba98);
+	}
+
+	/* power up primary ports */
+	m88x2_write(phydev, port, 3, 0, 0x2040);
+	m88x2_write(phydev, port, 4, 0, 0x2040);
+
+	/* port reset */
+	m88x2_write(phydev, port, 31, 0xf003, 0x8080);
+
+	/* power up line side */
+	m88x2_write_mask(phydev, port, 31, 0xf003, BIT(14), 0);
+	/* power up host side */
+	m88x2_write_mask(phydev, port, 31, 0xf003, BIT(6), 0);
+
+	/* SFI */
+	m88x2_write_mask(phydev, port, 1, 0, BIT(11), 0);
+#ifdef CONFIG_MV88X2_LINE_10GBASE_R
+	m88x2_write_mask(phydev, port, 3, 0, BIT(11), 0);
+#endif
+
+	/* XFI */
+#if defined(CONFIG_MV88X2_HOST_10GBASE_R)
+	m88x2_write_mask(phydev, port, 4, 0, BIT(11), 0);
+#elif defined(CONFIG_MV88X2_HOST_10GBASE_X2) || \
+	defined(CONFIG_MV88X2_HOST_10GBASE_X4)
+	m88x2_write_mask(phydev, port, 4, 0x1000, BIT(11), 0);
+#endif
+
+	return 0;
+}
+
+#if defined(CONFIG_MV88X2_LINE_10GBASE_R) && \
+	defined(CONFIG_MV88X2_HOST_10GBASE_X2)
+/* initialization sequence from Marvell MGD driver Release 2.4 */
+static int init_port_mode_2242m_b0_10gr_10gx2(struct phy_device *phydev,
+					      unsigned int port)
+{
+	printf("       init_port_mode_2242m_b0_10gr_10gx2 port %u\n", port);
+
+	m88x2_write(phydev, 0, 30, 0xb841, 0x0000);
+	m88x2_write(phydev, 0, 30, 0x9041, 0x03aa);
+	udelay(100);
+
+	m88x2_write_mask(phydev, 0, 30, 0xb040 + port * 0x200, 0x4000, 0x4000);
+
+	m88x2_write_mask(phydev, 0, 30, 0x8040 + port * 0x400, 0x4000, 0x4000);
+	udelay(100);
+
+	/* 10GR-10GX2 */
+	m88x2_write(phydev, port, 3, 0xf002,
+		    (0x80 << 8) | MGD_PCS_SPEED_10GBASE_R);
+	m88x2_write(phydev, port, 4, 0xf002,
+		    (0x80 << 8) | MGD_PCS_SPEED_10GBASE_X2);
+
+	m88x2_write(phydev, 0, 30, 0xb108 + port * 0x200, 0xf8d0);
+
+	m88x2_write_mask(phydev, 0, 30, 0xb1e7 + port * 0x200, 0xc000, 0x0000);
+
+	m88x2_write_mask(phydev, 0, 30, 0xb1e8 + port * 0x200, 0x7f00, 0x2000);
+
+	m88x2_write_mask(phydev, 0, 30, 0xb042 + port * 0x200, 0x00f0, 0x00b0);
+
+	m88x2_write(phydev, 0, 30, 0xb1a2 + port * 0x200, 0x00b0);
+	m88x2_write(phydev, 0, 30, 0xb19c + port * 0x200, 0x00a0);
+
+	m88x2_write_mask(phydev, 0, 30, 0xb1b5 + port * 0x200, 0x1000, 0x0000);
+
+	m88x2_write_mask(phydev, 0, 30, 0xb1b4 + port * 0x200, 0x1000, 0x1000);
+
+	m88x2_write_mask(phydev, 0, 30, 0xb181 + port * 0x200, 0xff00, 0x3300);
+
+	m88x2_write(phydev, 0, 30, 0x8141 + port * 0x400, 0x8f1a);
+	m88x2_write(phydev, 0, 30, 0x8131 + port * 0x400, 0x8f1a);
+	m88x2_write(phydev, 0, 30, 0x8077 + port * 0x400, 0x820a);
+
+	m88x2_write_mask(phydev, 0, 30, 0x80a0 + port * 0x400, 0x01ff, 0x0100);
+
+	m88x2_write_mask(phydev, 0, 30, 0x8085 + port * 0x400, 0x3f00, 0x0700);
+
+	m88x2_write_mask(phydev, 0, 30, 0x807b + port * 0x400, 0x0fff, 0x02b2);
+
+	m88x2_write_mask(phydev, 0, 30, 0x80b0 + port * 0x400, 0x0770, 0x0220);
+
+	m88x2_write_mask(phydev, 0, 30, 0x80b1 + port * 0x400, 0x0c30, 0x0820);
+
+	m88x2_write_mask(phydev, 0, 30, 0x8093 + port * 0x400, 0x7f00, 0x4600);
+
+	m88x2_write_mask(phydev, 0, 30, 0x809f + port * 0x400, 0x007f, 0x0079);
+
+	m88x2_write(phydev, 0, 30, 0x805c + port * 0x400, 0x4759);
+	m88x2_write(phydev, 0, 30, 0x805d + port * 0x400, 0x5900);
+	m88x2_write(phydev, port, 31, 0xf016, 0x0010);
+	/* CQ: 00006634 03/21/2016 */
+	m88x2_write_mask(phydev, 0, 30, 0xb153 + port * 0x200, 0x0070, 0x0070);
+	m88x2_write(phydev, port, 31, 0xf003, 0x8080);
+
+	return 0;
+}
+
+/* initialization sequence from Marvell MGD driver Release 2.4 */
+static int init_mode_2242m_b0_10gr_10gx2(struct phy_device *phydev,
+					 int num_ports)
+{
+	ulong mv88x2cfg = getenv_hex("mv88x2cfg", 0xe7);
+
+	printf("       init_mode_2242m_b0_10gr_10gx2\n");
+
+	/* Chip Hardware Reset */
+	m88x2_write(phydev, 0, 31, 0xf404, 0x4000);
+	udelay(100);
+
+	configure_host_lanes(phydev, num_ports);
+	if (mv88x2cfg & BIT(7))
+		configure_options(phydev);
+
+	/* set pcs speed mode */
+	m88x2_write_all(phydev, 31, 0xf002, 0x7172);
+
+	/* Couple Lane Writing Line Side */
+	m88x2_write(phydev, 0, 30, 0xb841, 0xe000);
+	/* Couple Lane Writing Host Side */
+	m88x2_write(phydev, 0, 30, 0x9041, 0x03fe);
+
+	/* LINE: Analog BW and ETA TxPLL */
+	m88x2_write(phydev, 0, 30, 0xb108, 0xf8d0);
+
+	m88x2_write_mask(phydev, 0, 30, 0xb1e7, 0xc000, 0x0000);
+
+	/* Hack pga table index for testing boost adjustment */
+	m88x2_write_mask(phydev, 0, 30, 0xb1e8, 0x7f00, 0x2000);
+
+	/* Enable ramping detection */
+	m88x2_write_mask(phydev, 0, 30, 0xb042, 0x00f0, 0x00b0);
+
+	/* Initial gain */
+	m88x2_write(phydev, 0, 30, 0xb1a2, 0x00b0);
+	/* Initial FFE */
+	m88x2_write(phydev, 0, 30, 0xb19c, 0x00a0);
+
+	/* freeze FFE main tap adaptation */
+	m88x2_write_mask(phydev, 0, 30, 0xb1b5, 0x1000, 0x0000);
+	m88x2_write_mask(phydev, 0, 30, 0xb1b4, 0x1000, 0x1000);
+
+	/* lower FFE mu */
+	m88x2_write_mask(phydev, 0, 30, 0xb181, 0xff00, 0x3300);
+
+	/* Host: Analog BW and ETA TxPLL */
+	m88x2_write(phydev, 0, 30, 0x8141, 0x8f1a);
+	/* Host: Analog BW and ETA RxPll */
+	m88x2_write(phydev, 0, 30, 0x8131, 0x8f1a);
+	/* Change DFE threshold */
+	m88x2_write(phydev, 0, 30, 0x8077, 0x820a);
+
+	/* 3/24/2015 updates */
+	/* Force BLW gain to zero */
+	m88x2_write_mask(phydev, 0, 30, 0x80a0, 0x01ff, 0x0100);
+
+	/* Constrain C0 min */
+	m88x2_write_mask(phydev, 0, 30, 0x8085, 0x3f00, 0x0700);
+
+	/* change C0 min for best veo search */
+	m88x2_write_mask(phydev, 0, 30, 0x807b, 0x0fff, 0x02b2);
+
+	/* Force EQR/EQC value */
+	m88x2_write_mask(phydev, 0, 30, 0x80b0, 0x0770, 0x0220);
+	m88x2_write_mask(phydev, 0, 30, 0x80b1, 0x0c30, 0x0820);
+
+	/* peakdet threshold change before and after startup */
+	m88x2_write_mask(phydev, 0, 30, 0x8093, 0x7f00, 0x4600);
+	m88x2_write_mask(phydev, 0, 30, 0x809f, 0x007f, 0x0079);
+
+	/* kpkf for 6G */
+	m88x2_write(phydev, 0, 30, 0x805c, 0x4759);
+	m88x2_write(phydev, 0, 30, 0x805d, 0x5900);
+
+	/* enable sfp tx_fault, rx_los and mod_abs functions */
+	m88x2_write_all(phydev, 31, 0xf014, 0x0777);
+
+	/* enable sfp tx_disable function */
+	m88x2_write_all(phydev, 31, 0xf016, 0x0010);
+
+	/* enable sfp tx_fault, rx_los and mod_abs interrupts*/
+	m88x2_write_all(phydev, 31, 0xf010, 0x0007);
+
+	/* CQ: 00006634 03/21/2016 */
+	m88x2_write_mask(phydev, 0, 30, 0xb153, 0x0070, 0x0070);
+	m88x2_write_mask(phydev, 0, 30, 0xb353, 0x0070, 0x0070);
+	m88x2_write_mask(phydev, 0, 30, 0xb553, 0x0070, 0x0070);
+	m88x2_write_mask(phydev, 0, 30, 0xb753, 0x0070, 0x0070);
+
+	/* PCS Reset */
+	m88x2_write_all(phydev, 31, 0xf003, 0x8080);
+
+	udelay(2000);
+
+	/* release FFE main tap adaptation */
+	m88x2_write_mask(phydev, 0, 30, 0xb1b5, 0x1000, 0x1000);
+	m88x2_write_mask(phydev, 0, 30, 0xb1b4, 0x1000, 0x1000);
+
+	return 0;
+}
+#endif
+
+static int disable_tx_rx_reset(struct phy_device *phydev, unsigned int port)
+{
+	printf("       %s port %u\n", __func__, port);
+
+	m88x2_write_mask(phydev, port, 3, 0xf074, 0x2000, 0);
+
+	return 0;
+}
+
+static int m88x2_config(struct phy_device *phydev)
+{
+	unsigned int k;
+	int device_id;
+	int num_ports;
+	int sfi_pol;
+
+	/*
+	 * mv88x2cfg environment variable encoding, default: 0xe7
+	 * bit 0: execute init_mode()
+	 * bit 1: execute init_port_mode()
+	 * bit 2: execute port_power_up()
+	 * bit 3: initialize sfi_pol, xfi_pol and disparity before
+	 *        port_power_up()
+	 * bit 4: initialize sfi_pol, xfi_pol and disparity after
+	 *        port_power_up()
+	 * bit 5: initialize lane_mux
+	 * bit 6: disable tx/rx reset mechanism
+	 * bit 7: initialize sfi_pol, xfi_pol and disparity ASAP()
+	 */
+	ulong mv88x2cfg = getenv_hex("mv88x2cfg", 0xe7);
+
+	device_id = get_device_id(phydev);
+	if (device_id < 0)
+		return -1;
+
+	num_ports = get_num_ports(device_id);
+	if (num_ports < 0)
+		return -1;
+
+	printf("%s (%d ports, %02x on %s):\n", get_name(device_id), num_ports,
+	       phydev->addr, phydev->bus->name);
+
+#ifdef CONFIG_MV88X2_LINE_10GBASE_R
+#ifdef CONFIG_MV88X2_HOST_10GBASE_X2
+	if (mv88x2cfg & BIT(0))
+		init_mode_2242m_b0_10gr_10gx2(phydev, num_ports);
+#endif
+#endif
+
+	if (mv88x2cfg & BIT(3))
+		configure_options(phydev);
+
+	for (k = 0; k < 4; ++k) {
+		/* on devices with 2 ports, ports 0 and 2 are active */
+		if ((k % 2) && (num_ports == 2))
+			continue;
+
+#ifdef CONFIG_MV88X2_LINE_10GBASE_R
+#ifdef CONFIG_MV88X2_HOST_10GBASE_X2
+		if (mv88x2cfg & BIT(1))
+			init_port_mode_2242m_b0_10gr_10gx2(phydev, k);
+#endif
+#endif
+
+		if (mv88x2cfg & BIT(6))
+			disable_tx_rx_reset(phydev, k);
+
+		if (mv88x2cfg & BIT(2))
+			port_power_up(phydev, device_id, k);
+	}
+
+	if (mv88x2cfg & BIT(4))
+		configure_options(phydev);
+
+	sfi_pol = m88x2_read(phydev, 0, 31, 0xf407);
+
+	/* Marvells magic SFI input polarity inversion fix */
+	if (sfi_pol & 0x0f00) {
+		puts("       ");
+		puts("apply Marvells magic SFI input polarity inversion fix\n");
+		m88x2_write(phydev, 0, 30, 0xb800, 0);
+		m88x2_write_mask(phydev, 0, 30, 0xb133, 0x0020, 0x0020);
+		m88x2_write_mask(phydev, 0, 30, 0xb333, 0x0020, 0x0020);
+		m88x2_write_mask(phydev, 0, 30, 0xb533, 0x0020, 0x0020);
+		m88x2_write_mask(phydev, 0, 30, 0xb733, 0x0020, 0x0020);
+	}
+
+	return 0;
+};
+
+static int m88x2_startup(struct phy_device *phydev)
+{
+#ifdef CONFIG_MV88X2_DEBUG_REGS
+	m88x2_dump_debug(phydev);
+#endif
+
+	return gen10g_startup(phydev);
+}
+
+static struct phy_driver M88X2_driver = {
+	.name = "Marvell 88X2",
+	.uid = 0x01410f10,
+	.mask = 0xffffff0,
+	.features = PHY_10G_FEATURES,
+	.config = &m88x2_config,
+	.startup = &m88x2_startup,
+	.shutdown = &gen10g_shutdown,
+};
+
+int phy_m88x2_init(void)
+{
+	phy_register(&M88X2_driver);
+
+	return 0;
+}
+
+static int sfi_test(struct phy_device *phydev, int portmask)
+{
+	int port;
+
+	/* PCS Reset */
+	m88x2_write_all(phydev, 31, 0xf003, 0x8080);
+
+	mdelay(2000);
+
+	for (port = 0; port < 4; ++port) {
+		if (!(portmask & BIT(port)))
+			continue;
+		/* pseudo random byte with crc */
+		m88x2_write(phydev, port, 3, 0xf011, 0x00a0);
+		/* continuously generate packets */
+		m88x2_write(phydev, port, 3, 0xf017, 0xffff);
+		/* enable generator and checker */
+		m88x2_write(phydev, port, 3, 0xf010, 0x0003);
+		udelay(200);
+		/* clear counters */
+		m88x2_write(phydev, port, 3, 0xf010, 0x0043);
+	}
+
+	mdelay(4000);
+
+	for (port = 0; port < 4; ++port) {
+		unsigned long long rxcnt, errcnt;
+
+		if (!(portmask & BIT(port)))
+			continue;
+
+		rxcnt = m88x2_read(phydev, port, 3, 0xf021);
+		rxcnt |= (unsigned long long)m88x2_read(phydev, port, 3,
+							0xf022) << 16;
+		rxcnt |= (unsigned long long)m88x2_read(phydev, port, 3,
+							0xf023) << 32;
+
+		errcnt = m88x2_read(phydev, port, 3, 0xf027);
+		errcnt |= (unsigned long long)m88x2_read(phydev, port, 3,
+							 0xf028) << 16;
+		errcnt |= (unsigned long long)m88x2_read(phydev, port, 3,
+							 0xf029) << 32;
+
+		if (errcnt > 1)
+			printf("\033[49;1;31m");
+
+		printf("%d: %llu\033[0m/%llu ", port, errcnt, rxcnt);
+	}
+
+	printf("\n");
+
+	for (port = 0; port < 4; ++port) {
+		if (!(portmask & BIT(port)))
+			continue;
+
+		/* disable generator */
+		m88x2_write(phydev, port, 3, 0xf010, 0x0001);
+	}
+
+	return 0;
+}
+
+static int do_mv88x2(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
+{
+	char op[2];
+	int portmask = 0xf;
+	int pos = argc - 1;
+	struct mii_dev *bus;
+	struct phy_device *phydev = NULL;
+
+	if (argc < 2)
+		return CMD_RET_USAGE;
+
+	/*
+	 * We use the last specified parameters, unless new ones are
+	 * entered.
+	 */
+	op[0] = argv[1][0];
+
+	bus = mdio_get_current_dev();
+
+	switch (op[0]) {
+	case 's':
+		if (pos > 3)
+			portmask = simple_strtoul(argv[pos--], NULL, 16);
+		break;
+	}
+
+	if (pos > 2)
+		bus = miiphy_get_dev_by_name(argv[pos - 1]);
+	if (!bus)
+		return -1;
+
+	if (pos > 1) {
+		unsigned int addr = simple_strtoul(argv[pos], NULL, 16);
+
+		if (addr > 31)
+			return -1;
+		phydev = phy_find_by_mask_c45(bus, BIT(addr),
+					      PHY_INTERFACE_MODE_XGMII);
+	}
+	if (!phydev)
+		return -1;
+
+	switch (op[0]) {
+	case 's':
+		sfi_test(phydev, portmask);
+		break;
+	}
+
+	return 0;
+}
+
+/***************************************************/
+
+U_BOOT_CMD(
+	mv88x2,	6,	0,	do_mv88x2,
+	"MV88X2 utility commands",
+	"sfitest <busname> <addr> [<portmask>] - use PHY packet generator/checker to test SFI ports at <portmask>\n"
+);
diff --git a/drivers/net/phy/mv88x2.h b/drivers/net/phy/mv88x2.h
new file mode 100644
index 0000000000..6cd2073cae
--- /dev/null
+++ b/drivers/net/phy/mv88x2.h
@@ -0,0 +1,12 @@
+struct mv88x2_config_data {
+	ulong sfi_pol;
+	ulong xfi_pol;
+	u16 led0_blink;
+	u16 led0_solid;
+	u16 led1_blink;
+	u16 led1_solid;
+};
+
+#ifdef CONFIG_BOARD_MV88X2_CONFIG
+int board_mv88x2_config(struct mv88x2_config_data *data);
+#endif
diff --git a/drivers/net/phy/phy.c b/drivers/net/phy/phy.c
index a16bb6ca89..f39ab39061 100644
--- a/drivers/net/phy/phy.c
+++ b/drivers/net/phy/phy.c
@@ -493,6 +493,9 @@ int phy_init(void)
 #ifdef CONFIG_PHY_MICREL
 	phy_micrel_init();
 #endif
+#ifdef CONFIG_PHY_MV88X2
+	phy_m88x2_init();
+#endif
 #ifdef CONFIG_PHY_NATSEMI
 	phy_natsemi_init();
 #endif
diff --git a/include/phy.h b/include/phy.h
index 75a9ae3314..1c94f511a7 100644
--- a/include/phy.h
+++ b/include/phy.h
@@ -275,6 +275,7 @@ int phy_et1011c_init(void);
 int phy_lxt_init(void);
 int phy_marvell_init(void);
 int phy_micrel_init(void);
+int phy_m88x2_init(void);
 int phy_natsemi_init(void);
 int phy_realtek_init(void);
 int phy_smsc_init(void);
-- 
2.11.0

^ permalink raw reply related	[flat|nested] 138+ messages in thread

* [U-Boot] [PATCH 10/51] net:phy:marvell Add hook for m88e1510 board config
  2017-07-14 12:54 [U-Boot] [PATCH 00/51] gdsys: Add support for Gazerbeam board Mario Six
                   ` (8 preceding siblings ...)
  2017-07-14 12:54 ` [U-Boot] [PATCH 09/51] phy: Support Marvell 88X2242 Mario Six
@ 2017-07-14 12:54 ` Mario Six
  2017-07-18 14:01   ` Simon Glass
  2017-07-14 12:54 ` [U-Boot] [PATCH 11/51] powerpc: mpc83xx: Implement get_serial_clock() Mario Six
                   ` (40 subsequent siblings)
  50 siblings, 1 reply; 138+ messages in thread
From: Mario Six @ 2017-07-14 12:54 UTC (permalink / raw)
  To: u-boot

From: Dirk Eibach <dirk.eibach@gdsys.cc>

m88e1510_config() is highly board-specific. So add an optional
callback board_m88e1510_config() configurable by
CONFIG_BOARD_M88E1510_CONFIG to support different hardware.

Signed-off-by: Dirk Eibach <dirk.eibach@gdsys.cc>
Signed-off-by: Mario Six <mario.six@gdsys.cc>
---

 drivers/net/phy/marvell.c |  5 +++++
 include/marvell-phy.h     | 10 ++++++++++
 2 files changed, 15 insertions(+)
 create mode 100644 include/marvell-phy.h

diff --git a/drivers/net/phy/marvell.c b/drivers/net/phy/marvell.c
index 66107a8af3..b3d05d5af4 100644
--- a/drivers/net/phy/marvell.c
+++ b/drivers/net/phy/marvell.c
@@ -9,6 +9,7 @@
 #include <config.h>
 #include <common.h>
 #include <errno.h>
+#include <marvell-phy.h>
 #include <phy.h>
 
 #define PHY_AUTONEGOTIATE_TIMEOUT 5000
@@ -381,6 +382,9 @@ static int m88e1518_config(struct phy_device *phydev)
 /* Marvell 88E1510 */
 static int m88e1510_config(struct phy_device *phydev)
 {
+#ifdef CONFIG_BOARD_M88E1510_CONFIG
+	board_m88e1510_config(phydev);
+#else
 	/* Select page 3 */
 	phy_write(phydev, MDIO_DEVAD_NONE, MIIM_88E1118_PHY_PAGE,
 		  MIIM_88E1118_PHY_LED_PAGE);
@@ -401,6 +405,7 @@ static int m88e1510_config(struct phy_device *phydev)
 
 	/* Reset page selection */
 	phy_write(phydev, MDIO_DEVAD_NONE, MIIM_88E1118_PHY_PAGE, 0);
+#endif
 
 	return m88e1518_config(phydev);
 }
diff --git a/include/marvell-phy.h b/include/marvell-phy.h
new file mode 100644
index 0000000000..1cfa5ed557
--- /dev/null
+++ b/include/marvell-phy.h
@@ -0,0 +1,10 @@
+#ifndef _MARVELL_PHY_H
+#define _MARVELL_PHY_H
+
+#include <phy.h>
+
+void m88e1518_phy_writebits(struct phy_device *phydev,
+		   u8 reg_num, u16 offset, u16 len, u16 data);
+int board_m88e1510_config(struct phy_device *phydev);
+
+#endif
-- 
2.11.0

^ permalink raw reply related	[flat|nested] 138+ messages in thread

* [U-Boot] [PATCH 11/51] powerpc: mpc83xx: Implement get_serial_clock()
  2017-07-14 12:54 [U-Boot] [PATCH 00/51] gdsys: Add support for Gazerbeam board Mario Six
                   ` (9 preceding siblings ...)
  2017-07-14 12:54 ` [U-Boot] [PATCH 10/51] net:phy:marvell Add hook for m88e1510 board config Mario Six
@ 2017-07-14 12:54 ` Mario Six
  2017-07-18 14:01   ` Simon Glass
  2017-07-14 12:54 ` [U-Boot] [PATCH 12/51] cfi_flash: Fix style violations Mario Six
                   ` (39 subsequent siblings)
  50 siblings, 1 reply; 138+ messages in thread
From: Mario Six @ 2017-07-14 12:54 UTC (permalink / raw)
  To: u-boot

DM serial drivers on PowerPC determine their clock frequency via the
get_serial_clock function. This function is not Implemented yet for
MPC83xx.

This patch Implements the function so that DM serial drivers work on
MPC83xx.

Signed-off-by: Mario Six <mario.six@gdsys.cc>
---

 arch/powerpc/cpu/mpc83xx/speed.c | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/arch/powerpc/cpu/mpc83xx/speed.c b/arch/powerpc/cpu/mpc83xx/speed.c
index 5498c19e25..5864a4fb57 100644
--- a/arch/powerpc/cpu/mpc83xx/speed.c
+++ b/arch/powerpc/cpu/mpc83xx/speed.c
@@ -515,6 +515,13 @@ ulong get_ddr_freq(ulong dummy)
 	return gd->mem_clk;
 }
 
+#ifdef CONFIG_DM_SERIAL
+int get_serial_clock(void)
+{
+	return get_bus_freq(0);
+}
+#endif
+
 static int do_clocks(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
 {
 	char buf[32];
-- 
2.11.0

^ permalink raw reply related	[flat|nested] 138+ messages in thread

* [U-Boot] [PATCH 12/51] cfi_flash: Fix style violations
  2017-07-14 12:54 [U-Boot] [PATCH 00/51] gdsys: Add support for Gazerbeam board Mario Six
                   ` (10 preceding siblings ...)
  2017-07-14 12:54 ` [U-Boot] [PATCH 11/51] powerpc: mpc83xx: Implement get_serial_clock() Mario Six
@ 2017-07-14 12:54 ` Mario Six
  2017-07-18 14:01   ` Simon Glass
  2017-07-14 12:54 ` [U-Boot] [PATCH 13/51] cfi_flash: Clean up code some more Mario Six
                   ` (38 subsequent siblings)
  50 siblings, 1 reply; 138+ messages in thread
From: Mario Six @ 2017-07-14 12:54 UTC (permalink / raw)
  To: u-boot

Fix style violations in the CFI flash driver.

Signed-off-by: Mario Six <mario.six@gdsys.cc>
---

 drivers/mtd/cfi_flash.c | 889 ++++++++++++++++++++++++------------------------
 1 file changed, 443 insertions(+), 446 deletions(-)

diff --git a/drivers/mtd/cfi_flash.c b/drivers/mtd/cfi_flash.c
index 048a51785e..18be3bee53 100644
--- a/drivers/mtd/cfi_flash.c
+++ b/drivers/mtd/cfi_flash.c
@@ -177,7 +177,9 @@ __maybe_weak u64 flash_read64(void *addr)
 
 /*-----------------------------------------------------------------------
  */
-#if defined(CONFIG_ENV_IS_IN_FLASH) || defined(CONFIG_ENV_ADDR_REDUND) || (CONFIG_SYS_MONITOR_BASE >= CONFIG_SYS_FLASH_BASE)
+#if defined(CONFIG_ENV_IS_IN_FLASH) || \
+	defined(CONFIG_ENV_ADDR_REDUND) || \
+	(CONFIG_SYS_MONITOR_BASE >= CONFIG_SYS_FLASH_BASE)
 flash_info_t *flash_get_info(ulong base)
 {
 	int i;
@@ -205,8 +207,8 @@ unsigned long flash_sector_size(flash_info_t *info, flash_sect_t sect)
 /*-----------------------------------------------------------------------
  * create an address based on the offset and the port width
  */
-static inline void *
-flash_map (flash_info_t * info, flash_sect_t sect, uint offset)
+static inline void *flash_map(flash_info_t *info, flash_sect_t sect,
+			      uint offset)
 {
 	unsigned int byte_offset = offset * info->portwidth;
 
@@ -214,7 +216,7 @@ flash_map (flash_info_t * info, flash_sect_t sect, uint offset)
 }
 
 static inline void flash_unmap(flash_info_t *info, flash_sect_t sect,
-		unsigned int offset, void *addr)
+			       unsigned int offset, void *addr)
 {
 }
 
@@ -230,16 +232,16 @@ static void flash_make_cmd(flash_info_t *info, u32 cmd, void *cmdbuf)
 	u32 cmd_le = cpu_to_le32(cmd);
 #endif
 	uchar val;
-	uchar *cp = (uchar *) cmdbuf;
+	uchar *cp = (uchar *)cmdbuf;
 
-	for (i = info->portwidth; i > 0; i--){
-		cword_offset = (info->portwidth-i)%info->chipwidth;
+	for (i = info->portwidth; i > 0; i--) {
+		cword_offset = (info->portwidth - i) % info->chipwidth;
 #if defined(__LITTLE_ENDIAN) || defined(CONFIG_SYS_WRITE_SWAPPED_DATA)
 		cp_offset = info->portwidth - i;
-		val = *((uchar*)&cmd_le + cword_offset);
+		val = *((uchar *)&cmd_le + cword_offset);
 #else
 		cp_offset = i - 1;
-		val = *((uchar*)&cmd + sizeof(u32) - cword_offset - 1);
+		val = *((uchar *)&cmd + sizeof(u32) - cword_offset - 1);
 #endif
 		cp[cp_offset] = (cword_offset >= sizeof(u32)) ? 0x00 : val;
 	}
@@ -254,12 +256,12 @@ static void print_longlong (char *str, unsigned long long data)
 	int i;
 	char *cp;
 
-	cp = (char *) &data;
+	cp = (char *)&data;
 	for (i = 0; i < 8; i++)
-		sprintf (&str[i * 2], "%2.2x", *cp++);
+		sprintf(&str[i * 2], "%2.2x", *cp++);
 }
 
-static void flash_printqry (struct cfi_qry *qry)
+static void flash_printqry(struct cfi_qry *qry)
 {
 	u8 *p = (u8 *)qry;
 	int x, y;
@@ -271,6 +273,7 @@ static void flash_printqry (struct cfi_qry *qry)
 		debug(" ");
 		for (y = 0; y < 16; y++) {
 			unsigned char c = p[x + y];
+
 			if (c >= 0x20 && c <= 0x7e)
 				debug("%c", c);
 			else
@@ -281,45 +284,43 @@ static void flash_printqry (struct cfi_qry *qry)
 }
 #endif
 
-
 /*-----------------------------------------------------------------------
  * read a character@a port width address
  */
-static inline uchar flash_read_uchar (flash_info_t * info, uint offset)
+static inline uchar flash_read_uchar(flash_info_t *info, uint offset)
 {
 	uchar *cp;
 	uchar retval;
 
-	cp = flash_map (info, 0, offset);
+	cp = flash_map(info, 0, offset);
 #if defined(__LITTLE_ENDIAN) || defined(CONFIG_SYS_WRITE_SWAPPED_DATA)
 	retval = flash_read8(cp);
 #else
 	retval = flash_read8(cp + info->portwidth - 1);
 #endif
-	flash_unmap (info, 0, offset, cp);
+	flash_unmap(info, 0, offset, cp);
 	return retval;
 }
 
 /*-----------------------------------------------------------------------
  * read a word at a port width address, assume 16bit bus
  */
-static inline ushort flash_read_word (flash_info_t * info, uint offset)
+static inline ushort flash_read_word(flash_info_t *info, uint offset)
 {
 	ushort *addr, retval;
 
-	addr = flash_map (info, 0, offset);
-	retval = flash_read16 (addr);
-	flash_unmap (info, 0, offset, addr);
+	addr = flash_map(info, 0, offset);
+	retval = flash_read16(addr);
+	flash_unmap(info, 0, offset, addr);
 	return retval;
 }
 
-
 /*-----------------------------------------------------------------------
  * read a long word by picking the least significant byte of each maximum
  * port size word. Swap for ppc format.
  */
-static ulong flash_read_long (flash_info_t * info, flash_sect_t sect,
-			      uint offset)
+static ulong flash_read_long(flash_info_t *info, flash_sect_t sect,
+			     uint offset)
 {
 	uchar *addr;
 	ulong retval;
@@ -327,14 +328,13 @@ static ulong flash_read_long (flash_info_t * info, flash_sect_t sect,
 #ifdef DEBUG
 	int x;
 #endif
-	addr = flash_map (info, sect, offset);
+	addr = flash_map(info, sect, offset);
 
 #ifdef DEBUG
-	debug ("long addr is at %p info->portwidth = %d\n", addr,
-	       info->portwidth);
-	for (x = 0; x < 4 * info->portwidth; x++) {
-		debug ("addr[%x] = 0x%x\n", x, flash_read8(addr + x));
-	}
+	debug("long addr is at %p info->portwidth = %d\n", addr,
+	      info->portwidth);
+	for (x = 0; x < 4 * info->portwidth; x++)
+		debug("addr[%x] = 0x%x\n", x, flash_read8(addr + x));
 #endif
 #if defined(__LITTLE_ENDIAN) || defined(CONFIG_SYS_WRITE_SWAPPED_DATA)
 	retval = ((flash_read8(addr) << 16) |
@@ -355,31 +355,30 @@ static ulong flash_read_long (flash_info_t * info, flash_sect_t sect,
 /*
  * Write a proper sized command to the correct address
  */
-void flash_write_cmd (flash_info_t * info, flash_sect_t sect,
-		      uint offset, u32 cmd)
+void flash_write_cmd(flash_info_t *info, flash_sect_t sect,
+		     uint offset, u32 cmd)
 {
-
 	void *addr;
 	cfiword_t cword;
 
-	addr = flash_map (info, sect, offset);
-	flash_make_cmd (info, cmd, &cword);
+	addr = flash_map(info, sect, offset);
+	flash_make_cmd(info, cmd, &cword);
 	switch (info->portwidth) {
 	case FLASH_CFI_8BIT:
-		debug ("fwc addr %p cmd %x %x 8bit x %d bit\n", addr, cmd,
-		       cword.w8, info->chipwidth << CFI_FLASH_SHIFT_WIDTH);
+		debug("fwc addr %p cmd %x %x 8bit x %d bit\n", addr, cmd,
+		      cword.w8, info->chipwidth << CFI_FLASH_SHIFT_WIDTH);
 		flash_write8(cword.w8, addr);
 		break;
 	case FLASH_CFI_16BIT:
-		debug ("fwc addr %p cmd %x %4.4x 16bit x %d bit\n", addr,
-		       cmd, cword.w16,
-		       info->chipwidth << CFI_FLASH_SHIFT_WIDTH);
+		debug("fwc addr %p cmd %x %4.4x 16bit x %d bit\n", addr,
+		      cmd, cword.w16,
+		      info->chipwidth << CFI_FLASH_SHIFT_WIDTH);
 		flash_write16(cword.w16, addr);
 		break;
 	case FLASH_CFI_32BIT:
-		debug ("fwc addr %p cmd %x %8.8x 32bit x %d bit\n", addr,
-		       cmd, cword.w32,
-		       info->chipwidth << CFI_FLASH_SHIFT_WIDTH);
+		debug("fwc addr %p cmd %x %8.8x 32bit x %d bit\n", addr,
+		      cmd, cword.w32,
+		      info->chipwidth << CFI_FLASH_SHIFT_WIDTH);
 		flash_write32(cword.w32, addr);
 		break;
 	case FLASH_CFI_64BIT:
@@ -389,9 +388,9 @@ void flash_write_cmd (flash_info_t * info, flash_sect_t sect,
 
 			print_longlong (str, cword.w64);
 
-			debug ("fwrite addr %p cmd %x %s 64 bit x %d bit\n",
-			       addr, cmd, str,
-			       info->chipwidth << CFI_FLASH_SHIFT_WIDTH);
+			debug("fwrite addr %p cmd %x %s 64 bit x %d bit\n",
+			      addr, cmd, str,
+			      info->chipwidth << CFI_FLASH_SHIFT_WIDTH);
 		}
 #endif
 		flash_write64(cword.w64, addr);
@@ -404,36 +403,36 @@ void flash_write_cmd (flash_info_t * info, flash_sect_t sect,
 	flash_unmap(info, sect, offset, addr);
 }
 
-static void flash_unlock_seq (flash_info_t * info, flash_sect_t sect)
+static void flash_unlock_seq(flash_info_t *info, flash_sect_t sect)
 {
-	flash_write_cmd (info, sect, info->addr_unlock1, AMD_CMD_UNLOCK_START);
-	flash_write_cmd (info, sect, info->addr_unlock2, AMD_CMD_UNLOCK_ACK);
+	flash_write_cmd(info, sect, info->addr_unlock1, AMD_CMD_UNLOCK_START);
+	flash_write_cmd(info, sect, info->addr_unlock2, AMD_CMD_UNLOCK_ACK);
 }
 
 /*-----------------------------------------------------------------------
  */
-static int flash_isequal (flash_info_t * info, flash_sect_t sect,
-			  uint offset, uchar cmd)
+static int flash_isequal(flash_info_t *info, flash_sect_t sect,
+			 uint offset, uchar cmd)
 {
 	void *addr;
 	cfiword_t cword;
 	int retval;
 
-	addr = flash_map (info, sect, offset);
-	flash_make_cmd (info, cmd, &cword);
+	addr = flash_map(info, sect, offset);
+	flash_make_cmd(info, cmd, &cword);
 
-	debug ("is= cmd %x(%c) addr %p ", cmd, cmd, addr);
+	debug("is= cmd %x(%c) addr %p ", cmd, cmd, addr);
 	switch (info->portwidth) {
 	case FLASH_CFI_8BIT:
-		debug ("is= %x %x\n", flash_read8(addr), cword.w8);
+		debug("is= %x %x\n", flash_read8(addr), cword.w8);
 		retval = (flash_read8(addr) == cword.w8);
 		break;
 	case FLASH_CFI_16BIT:
-		debug ("is= %4.4x %4.4x\n", flash_read16(addr), cword.w16);
+		debug("is= %4.4x %4.4x\n", flash_read16(addr), cword.w16);
 		retval = (flash_read16(addr) == cword.w16);
 		break;
 	case FLASH_CFI_32BIT:
-		debug ("is= %8.8x %8.8x\n", flash_read32(addr), cword.w32);
+		debug("is= %8.8x %8.8x\n", flash_read32(addr), cword.w32);
 		retval = (flash_read32(addr) == cword.w32);
 		break;
 	case FLASH_CFI_64BIT:
@@ -444,7 +443,7 @@ static int flash_isequal (flash_info_t * info, flash_sect_t sect,
 
 			print_longlong (str1, flash_read64(addr));
 			print_longlong (str2, cword.w64);
-			debug ("is= %s %s\n", str1, str2);
+			debug("is= %s %s\n", str1, str2);
 		}
 #endif
 		retval = (flash_read64(addr) == cword.w64);
@@ -460,15 +459,15 @@ static int flash_isequal (flash_info_t * info, flash_sect_t sect,
 
 /*-----------------------------------------------------------------------
  */
-static int flash_isset (flash_info_t * info, flash_sect_t sect,
-			uint offset, uchar cmd)
+static int flash_isset(flash_info_t *info, flash_sect_t sect,
+		       uint offset, uchar cmd)
 {
 	void *addr;
 	cfiword_t cword;
 	int retval;
 
-	addr = flash_map (info, sect, offset);
-	flash_make_cmd (info, cmd, &cword);
+	addr = flash_map(info, sect, offset);
+	flash_make_cmd(info, cmd, &cword);
 	switch (info->portwidth) {
 	case FLASH_CFI_8BIT:
 		retval = ((flash_read8(addr) & cword.w8) == cword.w8);
@@ -493,15 +492,15 @@ static int flash_isset (flash_info_t * info, flash_sect_t sect,
 
 /*-----------------------------------------------------------------------
  */
-static int flash_toggle (flash_info_t * info, flash_sect_t sect,
-			 uint offset, uchar cmd)
+static int flash_toggle(flash_info_t *info, flash_sect_t sect,
+			uint offset, uchar cmd)
 {
 	void *addr;
 	cfiword_t cword;
 	int retval;
 
-	addr = flash_map (info, sect, offset);
-	flash_make_cmd (info, cmd, &cword);
+	addr = flash_map(info, sect, offset);
+	flash_make_cmd(info, cmd, &cword);
 	switch (info->portwidth) {
 	case FLASH_CFI_8BIT:
 		retval = flash_read8(addr) != flash_read8(addr);
@@ -513,8 +512,8 @@ static int flash_toggle (flash_info_t * info, flash_sect_t sect,
 		retval = flash_read32(addr) != flash_read32(addr);
 		break;
 	case FLASH_CFI_64BIT:
-		retval = ( (flash_read32( addr ) != flash_read32( addr )) ||
-			   (flash_read32(addr+4) != flash_read32(addr+4)) );
+		retval = ((flash_read32(addr) != flash_read32(addr)) ||
+			  (flash_read32(addr+4) != flash_read32(addr+4)));
 		break;
 	default:
 		retval = 0;
@@ -531,7 +530,7 @@ static int flash_toggle (flash_info_t * info, flash_sect_t sect,
  * This routine checks the status of the chip and returns true if the
  * chip is busy.
  */
-static int flash_is_busy (flash_info_t * info, flash_sect_t sect)
+static int flash_is_busy(flash_info_t *info, flash_sect_t sect)
 {
 	int retval;
 
@@ -539,19 +538,19 @@ static int flash_is_busy (flash_info_t * info, flash_sect_t sect)
 	case CFI_CMDSET_INTEL_PROG_REGIONS:
 	case CFI_CMDSET_INTEL_STANDARD:
 	case CFI_CMDSET_INTEL_EXTENDED:
-		retval = !flash_isset (info, sect, 0, FLASH_STATUS_DONE);
+		retval = !flash_isset(info, sect, 0, FLASH_STATUS_DONE);
 		break;
 	case CFI_CMDSET_AMD_STANDARD:
 	case CFI_CMDSET_AMD_EXTENDED:
 #ifdef CONFIG_FLASH_CFI_LEGACY
 	case CFI_CMDSET_AMD_LEGACY:
 #endif
-		retval = flash_toggle (info, sect, 0, AMD_STATUS_TOGGLE);
+		retval = flash_toggle(info, sect, 0, AMD_STATUS_TOGGLE);
 		break;
 	default:
 		retval = 0;
 	}
-	debug ("flash_is_busy: %d\n", retval);
+	debug("%s: %d\n", __func__, retval);
 	return retval;
 }
 
@@ -559,8 +558,8 @@ static int flash_is_busy (flash_info_t * info, flash_sect_t sect)
  *  wait for XSR.7 to be set. Time out with an error if it does not.
  *  This routine does not set the flash to read-array mode.
  */
-static int flash_status_check (flash_info_t * info, flash_sect_t sector,
-			       ulong tout, char *prompt)
+static int flash_status_check(flash_info_t *info, flash_sect_t sector,
+			      ulong tout, char *prompt)
 {
 	ulong start;
 
@@ -575,18 +574,18 @@ static int flash_status_check (flash_info_t * info, flash_sect_t sector,
 #ifdef CONFIG_SYS_LOW_RES_TIMER
 	reset_timer();
 #endif
-	start = get_timer (0);
+	start = get_timer(0);
 	WATCHDOG_RESET();
-	while (flash_is_busy (info, sector)) {
-		if (get_timer (start) > tout) {
-			printf ("Flash %s timeout at address %lx data %lx\n",
-				prompt, info->start[sector],
-				flash_read_long (info, sector, 0));
-			flash_write_cmd (info, sector, 0, info->cmd_reset);
+	while (flash_is_busy(info, sector)) {
+		if (get_timer(start) > tout) {
+			printf("Flash %s timeout at address %lx data %lx\n",
+			       prompt, info->start[sector],
+			       flash_read_long (info, sector, 0));
+			flash_write_cmd(info, sector, 0, info->cmd_reset);
 			udelay(1);
 			return ERR_TIMOUT;
 		}
-		udelay (1);		/* also triggers watchdog */
+		udelay(1);	/* also triggers watchdog */
 	}
 	return ERR_OK;
 }
@@ -597,40 +596,40 @@ static int flash_status_check (flash_info_t * info, flash_sect_t sector,
  *
  * This routine sets the flash to read-array mode.
  */
-static int flash_full_status_check (flash_info_t * info, flash_sect_t sector,
-				    ulong tout, char *prompt)
+static int flash_full_status_check(flash_info_t *info, flash_sect_t sector,
+				   ulong tout, char *prompt)
 {
 	int retcode;
 
-	retcode = flash_status_check (info, sector, tout, prompt);
+	retcode = flash_status_check(info, sector, tout, prompt);
 	switch (info->vendor) {
 	case CFI_CMDSET_INTEL_PROG_REGIONS:
 	case CFI_CMDSET_INTEL_EXTENDED:
 	case CFI_CMDSET_INTEL_STANDARD:
-		if ((retcode == ERR_OK)
-		    && !flash_isset(info, sector, 0, FLASH_STATUS_DONE)) {
+		if ((retcode == ERR_OK) &&
+		    !flash_isset(info, sector, 0, FLASH_STATUS_DONE)) {
 			retcode = ERR_INVAL;
-			printf ("Flash %s error at address %lx\n", prompt,
-				info->start[sector]);
-			if (flash_isset (info, sector, 0, FLASH_STATUS_ECLBS |
-					 FLASH_STATUS_PSLBS)) {
-				puts ("Command Sequence Error.\n");
-			} else if (flash_isset (info, sector, 0,
-						FLASH_STATUS_ECLBS)) {
-				puts ("Block Erase Error.\n");
+			printf("Flash %s error at address %lx\n", prompt,
+			       info->start[sector]);
+			if (flash_isset(info, sector, 0, FLASH_STATUS_ECLBS |
+					FLASH_STATUS_PSLBS)) {
+				puts("Command Sequence Error.\n");
+			} else if (flash_isset(info, sector, 0,
+					       FLASH_STATUS_ECLBS)) {
+				puts("Block Erase Error.\n");
 				retcode = ERR_NOT_ERASED;
-			} else if (flash_isset (info, sector, 0,
-						FLASH_STATUS_PSLBS)) {
-				puts ("Locking Error\n");
+			} else if (flash_isset(info, sector, 0,
+					       FLASH_STATUS_PSLBS)) {
+				puts("Locking Error\n");
 			}
-			if (flash_isset (info, sector, 0, FLASH_STATUS_DPS)) {
-				puts ("Block locked.\n");
+			if (flash_isset(info, sector, 0, FLASH_STATUS_DPS)) {
+				puts("Block locked.\n");
 				retcode = ERR_PROTECTED;
 			}
-			if (flash_isset (info, sector, 0, FLASH_STATUS_VPENS))
-				puts ("Vpp Low Error.\n");
+			if (flash_isset(info, sector, 0, FLASH_STATUS_VPENS))
+				puts("Vpp Low Error.\n");
 		}
-		flash_write_cmd (info, sector, 0, info->cmd_reset);
+		flash_write_cmd(info, sector, 0, info->cmd_reset);
 		udelay(1);
 		break;
 	default:
@@ -702,7 +701,7 @@ static int flash_status_poll(flash_info_t *info, void *src, void *dst,
 
 /*-----------------------------------------------------------------------
  */
-static void flash_add_byte (flash_info_t * info, cfiword_t * cword, uchar c)
+static void flash_add_byte(flash_info_t *info, cfiword_t *cword, uchar c)
 {
 #if defined(__LITTLE_ENDIAN) && !defined(CONFIG_SYS_WRITE_SWAPPED_DATA)
 	unsigned short	w;
@@ -748,7 +747,7 @@ static void flash_add_byte (flash_info_t * info, cfiword_t * cword, uchar c)
  * Loop through the sector table starting from the previously found sector.
  * Searches forwards or backwards, dependent on the passed address.
  */
-static flash_sect_t find_sector (flash_info_t * info, ulong addr)
+static flash_sect_t find_sector(flash_info_t *info, ulong addr)
 {
 	static flash_sect_t saved_sector; /* previously found sector */
 	static flash_info_t *saved_info; /* previously used flash bank */
@@ -757,8 +756,8 @@ static flash_sect_t find_sector (flash_info_t * info, ulong addr)
 	if ((info != saved_info) || (sector >= info->sector_count))
 		sector = 0;
 
-	while ((info->start[sector] < addr)
-			&& (sector < info->sector_count - 1))
+	while ((info->start[sector] < addr) &&
+	       (sector < info->sector_count - 1))
 		sector++;
 	while ((info->start[sector] > addr) && (sector > 0))
 		/*
@@ -774,8 +773,7 @@ static flash_sect_t find_sector (flash_info_t * info, ulong addr)
 
 /*-----------------------------------------------------------------------
  */
-static int flash_write_cfiword (flash_info_t * info, ulong dest,
-				cfiword_t cword)
+static int flash_write_cfiword(flash_info_t *info, ulong dest, cfiword_t cword)
 {
 	void *dstaddr = (void *)dest;
 	int flag;
@@ -804,27 +802,27 @@ static int flash_write_cfiword (flash_info_t * info, ulong dest,
 		return ERR_NOT_ERASED;
 
 	/* Disable interrupts which might cause a timeout here */
-	flag = disable_interrupts ();
+	flag = disable_interrupts();
 
 	switch (info->vendor) {
 	case CFI_CMDSET_INTEL_PROG_REGIONS:
 	case CFI_CMDSET_INTEL_EXTENDED:
 	case CFI_CMDSET_INTEL_STANDARD:
-		flash_write_cmd (info, 0, 0, FLASH_CMD_CLEAR_STATUS);
-		flash_write_cmd (info, 0, 0, FLASH_CMD_WRITE);
+		flash_write_cmd(info, 0, 0, FLASH_CMD_CLEAR_STATUS);
+		flash_write_cmd(info, 0, 0, FLASH_CMD_WRITE);
 		break;
 	case CFI_CMDSET_AMD_EXTENDED:
 	case CFI_CMDSET_AMD_STANDARD:
 		sect = find_sector(info, dest);
-		flash_unlock_seq (info, sect);
-		flash_write_cmd (info, sect, info->addr_unlock1, AMD_CMD_WRITE);
+		flash_unlock_seq(info, sect);
+		flash_write_cmd(info, sect, info->addr_unlock1, AMD_CMD_WRITE);
 		sect_found = 1;
 		break;
 #ifdef CONFIG_FLASH_CFI_LEGACY
 	case CFI_CMDSET_AMD_LEGACY:
 		sect = find_sector(info, dest);
-		flash_unlock_seq (info, 0);
-		flash_write_cmd (info, 0, info->addr_unlock1, AMD_CMD_WRITE);
+		flash_unlock_seq(info, 0);
+		flash_write_cmd(info, 0, info->addr_unlock1, AMD_CMD_WRITE);
 		sect_found = 1;
 		break;
 #endif
@@ -847,10 +845,10 @@ static int flash_write_cfiword (flash_info_t * info, ulong dest,
 
 	/* re-enable interrupts if necessary */
 	if (flag)
-		enable_interrupts ();
+		enable_interrupts();
 
 	if (!sect_found)
-		sect = find_sector (info, dest);
+		sect = find_sector(info, dest);
 
 	if (use_flash_status_poll(info))
 		return flash_status_poll(info, &cword, dstaddr,
@@ -862,8 +860,8 @@ static int flash_write_cfiword (flash_info_t * info, ulong dest,
 
 #ifdef CONFIG_SYS_FLASH_USE_BUFFER_WRITE
 
-static int flash_write_cfibuffer (flash_info_t * info, ulong dest, uchar * cp,
-				  int len)
+static int flash_write_cfibuffer(flash_info_t *info, ulong dest, uchar *cp,
+				 int len)
 {
 	flash_sect_t sector;
 	int cnt;
@@ -926,25 +924,27 @@ static int flash_write_cfibuffer (flash_info_t * info, ulong dest, uchar * cp,
 	}
 
 	src = cp;
-	sector = find_sector (info, dest);
+	sector = find_sector(info, dest);
 
 	switch (info->vendor) {
 	case CFI_CMDSET_INTEL_PROG_REGIONS:
 	case CFI_CMDSET_INTEL_STANDARD:
 	case CFI_CMDSET_INTEL_EXTENDED:
 		write_cmd = (info->vendor == CFI_CMDSET_INTEL_PROG_REGIONS) ?
-					FLASH_CMD_WRITE_BUFFER_PROG : FLASH_CMD_WRITE_TO_BUFFER;
-		flash_write_cmd (info, sector, 0, FLASH_CMD_CLEAR_STATUS);
-		flash_write_cmd (info, sector, 0, FLASH_CMD_READ_STATUS);
-		flash_write_cmd (info, sector, 0, write_cmd);
-		retcode = flash_status_check (info, sector,
-					      info->buffer_write_tout,
-					      "write to buffer");
+			    FLASH_CMD_WRITE_BUFFER_PROG :
+			    FLASH_CMD_WRITE_TO_BUFFER;
+		flash_write_cmd(info, sector, 0, FLASH_CMD_CLEAR_STATUS);
+		flash_write_cmd(info, sector, 0, FLASH_CMD_READ_STATUS);
+		flash_write_cmd(info, sector, 0, write_cmd);
+		retcode = flash_status_check(info, sector,
+					     info->buffer_write_tout,
+					     "write to buffer");
 		if (retcode == ERR_OK) {
-			/* reduce the number of loops by the width of
-			 * the port */
+			/* Reduce the number of loops by the width of
+			 * the port
+			 */
 			cnt = len >> shift;
-			flash_write_cmd (info, sector, 0, cnt - 1);
+			flash_write_cmd(info, sector, 0, cnt - 1);
 			while (cnt-- > 0) {
 				switch (info->portwidth) {
 				case FLASH_CFI_8BIT:
@@ -968,9 +968,9 @@ static int flash_write_cfibuffer (flash_info_t * info, ulong dest, uchar * cp,
 					goto out_unmap;
 				}
 			}
-			flash_write_cmd (info, sector, 0,
-					 FLASH_CMD_WRITE_BUFFER_CONFIRM);
-			retcode = flash_full_status_check (
+			flash_write_cmd(info, sector, 0,
+					FLASH_CMD_WRITE_BUFFER_CONFIRM);
+			retcode = flash_full_status_check(
 				info, sector, info->buffer_write_tout,
 				"buffer write");
 		}
@@ -1018,7 +1018,7 @@ static int flash_write_cfibuffer (flash_info_t * info, ulong dest, uchar * cp,
 			goto out_unmap;
 		}
 
-		flash_write_cmd (info, sector, 0, AMD_CMD_WRITE_BUFFER_CONFIRM);
+		flash_write_cmd(info, sector, 0, AMD_CMD_WRITE_BUFFER_CONFIRM);
 		if (use_flash_status_poll(info))
 			retcode = flash_status_poll(info, src - (1 << shift),
 						    dst - (1 << shift),
@@ -1031,7 +1031,7 @@ static int flash_write_cfibuffer (flash_info_t * info, ulong dest, uchar * cp,
 		break;
 
 	default:
-		debug ("Unknown Command Set\n");
+		debug("Unknown Command Set\n");
 		retcode = ERR_INVAL;
 		break;
 	}
@@ -1041,10 +1041,9 @@ out_unmap:
 }
 #endif /* CONFIG_SYS_FLASH_USE_BUFFER_WRITE */
 
-
 /*-----------------------------------------------------------------------
  */
-int flash_erase (flash_info_t * info, int s_first, int s_last)
+int flash_erase(flash_info_t *info, int s_first, int s_last)
 {
 	int rcode = 0;
 	int prot;
@@ -1052,28 +1051,26 @@ int flash_erase (flash_info_t * info, int s_first, int s_last)
 	int st;
 
 	if (info->flash_id != FLASH_MAN_CFI) {
-		puts ("Can't erase unknown flash type - aborted\n");
+		puts("Can't erase unknown flash type - aborted\n");
 		return 1;
 	}
 	if ((s_first < 0) || (s_first > s_last)) {
-		puts ("- no sectors to erase\n");
+		puts("- no sectors to erase\n");
 		return 1;
 	}
 
 	prot = 0;
 	for (sect = s_first; sect <= s_last; ++sect) {
-		if (info->protect[sect]) {
+		if (info->protect[sect])
 			prot++;
-		}
 	}
 	if (prot) {
-		printf ("- Warning: %d protected sectors will not be erased!\n",
-			prot);
+		printf("- Warning: %d protected sectors will not be erased!\n",
+		       prot);
 	} else if (flash_verbose) {
-		putc ('\n');
+		putc('\n');
 	}
 
-
 	for (sect = s_first; sect <= s_last; sect++) {
 		if (ctrlc()) {
 			printf("\n");
@@ -1111,60 +1108,64 @@ int flash_erase (flash_info_t * info, int s_first, int s_last)
 			case CFI_CMDSET_INTEL_PROG_REGIONS:
 			case CFI_CMDSET_INTEL_STANDARD:
 			case CFI_CMDSET_INTEL_EXTENDED:
-				flash_write_cmd (info, sect, 0,
-						 FLASH_CMD_CLEAR_STATUS);
-				flash_write_cmd (info, sect, 0,
-						 FLASH_CMD_BLOCK_ERASE);
-				flash_write_cmd (info, sect, 0,
-						 FLASH_CMD_ERASE_CONFIRM);
+				flash_write_cmd(info, sect, 0,
+						FLASH_CMD_CLEAR_STATUS);
+				flash_write_cmd(info, sect, 0,
+						FLASH_CMD_BLOCK_ERASE);
+				flash_write_cmd(info, sect, 0,
+						FLASH_CMD_ERASE_CONFIRM);
 				break;
 			case CFI_CMDSET_AMD_STANDARD:
 			case CFI_CMDSET_AMD_EXTENDED:
-				flash_unlock_seq (info, sect);
-				flash_write_cmd (info, sect,
+				flash_unlock_seq(info, sect);
+				flash_write_cmd(info, sect,
 						info->addr_unlock1,
 						AMD_CMD_ERASE_START);
-				flash_unlock_seq (info, sect);
-				flash_write_cmd (info, sect, 0,
-						 info->cmd_erase_sector);
+				flash_unlock_seq(info, sect);
+				flash_write_cmd(info, sect, 0,
+						info->cmd_erase_sector);
 				break;
 #ifdef CONFIG_FLASH_CFI_LEGACY
 			case CFI_CMDSET_AMD_LEGACY:
-				flash_unlock_seq (info, 0);
-				flash_write_cmd (info, 0, info->addr_unlock1,
+				flash_unlock_seq(info, 0);
+				flash_write_cmd(info, 0, info->addr_unlock1,
 						AMD_CMD_ERASE_START);
-				flash_unlock_seq (info, 0);
-				flash_write_cmd (info, sect, 0,
+				flash_unlock_seq(info, 0);
+				flash_write_cmd(info, sect, 0,
 						AMD_CMD_ERASE_SECTOR);
 				break;
 #endif
 			default:
-				debug ("Unkown flash vendor %d\n",
-				       info->vendor);
+				debug("Unknown flash vendor %d\n",
+				      info->vendor);
 				break;
 			}
 
 			if (use_flash_status_poll(info)) {
 				cfiword_t cword;
 				void *dest;
+
 				cword.w64 = 0xffffffffffffffffULL;
 				dest = flash_map(info, sect, 0);
 				st = flash_status_poll(info, &cword, dest,
-						       info->erase_blk_tout, "erase");
+						       info->erase_blk_tout,
+						       "erase");
 				flash_unmap(info, sect, 0, dest);
-			} else
+			} else {
 				st = flash_full_status_check(info, sect,
 							     info->erase_blk_tout,
 							     "erase");
+			}
+
 			if (st)
 				rcode = 1;
 			else if (flash_verbose)
-				putc ('.');
+				putc('.');
 		}
 	}
 
 	if (flash_verbose)
-		puts (" done\n");
+		puts(" done\n");
 
 	return rcode;
 }
@@ -1193,71 +1194,70 @@ static int sector_erased(flash_info_t *info, int i)
 }
 #endif /* CONFIG_SYS_FLASH_EMPTY_INFO */
 
-void flash_print_info (flash_info_t * info)
+void flash_print_info(flash_info_t *info)
 {
 	int i;
 
 	if (info->flash_id != FLASH_MAN_CFI) {
-		puts ("missing or unknown FLASH type\n");
+		puts("missing or unknown FLASH type\n");
 		return;
 	}
 
-	printf ("%s flash (%d x %d)",
-		info->name,
-		(info->portwidth << 3), (info->chipwidth << 3));
-	if (info->size < 1024*1024)
-		printf ("  Size: %ld kB in %d Sectors\n",
-			info->size >> 10, info->sector_count);
+	printf("%s flash (%d x %d)",
+	       info->name,
+	       (info->portwidth << 3), (info->chipwidth << 3));
+	if (info->size < 1024 * 1024)
+		printf("  Size: %ld kB in %d Sectors\n",
+		       info->size >> 10, info->sector_count);
 	else
-		printf ("  Size: %ld MB in %d Sectors\n",
-			info->size >> 20, info->sector_count);
-	printf ("  ");
+		printf("  Size: %ld MB in %d Sectors\n",
+		       info->size >> 20, info->sector_count);
+	printf("  ");
 	switch (info->vendor) {
-		case CFI_CMDSET_INTEL_PROG_REGIONS:
-			printf ("Intel Prog Regions");
-			break;
-		case CFI_CMDSET_INTEL_STANDARD:
-			printf ("Intel Standard");
-			break;
-		case CFI_CMDSET_INTEL_EXTENDED:
-			printf ("Intel Extended");
-			break;
-		case CFI_CMDSET_AMD_STANDARD:
-			printf ("AMD Standard");
-			break;
-		case CFI_CMDSET_AMD_EXTENDED:
-			printf ("AMD Extended");
-			break;
+	case CFI_CMDSET_INTEL_PROG_REGIONS:
+		printf("Intel Prog Regions");
+		break;
+	case CFI_CMDSET_INTEL_STANDARD:
+		printf("Intel Standard");
+		break;
+	case CFI_CMDSET_INTEL_EXTENDED:
+		printf("Intel Extended");
+		break;
+	case CFI_CMDSET_AMD_STANDARD:
+		printf("AMD Standard");
+		break;
+	case CFI_CMDSET_AMD_EXTENDED:
+		printf("AMD Extended");
+		break;
 #ifdef CONFIG_FLASH_CFI_LEGACY
-		case CFI_CMDSET_AMD_LEGACY:
-			printf ("AMD Legacy");
-			break;
+	case CFI_CMDSET_AMD_LEGACY:
+		printf("AMD Legacy");
+		break;
 #endif
-		default:
-			printf ("Unknown (%d)", info->vendor);
-			break;
+	default:
+		printf("Unknown (%d)", info->vendor);
+		break;
 	}
-	printf (" command set, Manufacturer ID: 0x%02X, Device ID: 0x",
-		info->manufacturer_id);
-	printf (info->chipwidth == FLASH_CFI_16BIT ? "%04X" : "%02X",
-		info->device_id);
+	printf(" command set, Manufacturer ID: 0x%02X, Device ID: 0x",
+	       info->manufacturer_id);
+	printf(info->chipwidth == FLASH_CFI_16BIT ? "%04X" : "%02X",
+	       info->device_id);
 	if ((info->device_id & 0xff) == 0x7E) {
 		printf(info->chipwidth == FLASH_CFI_16BIT ? "%04X" : "%02X",
-		info->device_id2);
+		       info->device_id2);
 	}
 	if ((info->vendor == CFI_CMDSET_AMD_STANDARD) && (info->legacy_unlock))
 		printf("\n  Advanced Sector Protection (PPB) enabled");
-	printf ("\n  Erase timeout: %ld ms, write timeout: %ld ms\n",
-		info->erase_blk_tout,
-		info->write_tout);
+	printf("\n  Erase timeout: %ld ms, write timeout: %ld ms\n",
+	       info->erase_blk_tout,
+	       info->write_tout);
 	if (info->buffer_size > 1) {
-		printf ("  Buffer write timeout: %ld ms, "
-			"buffer size: %d bytes\n",
-		info->buffer_write_tout,
-		info->buffer_size);
+		printf("  Buffer write timeout: %ld ms, buffer size: %d bytes\n",
+		       info->buffer_write_tout,
+		       info->buffer_size);
 	}
 
-	puts ("\n  Sector Start Addresses:");
+	puts("\n  Sector Start Addresses:");
 	for (i = 0; i < info->sector_count; ++i) {
 		if (ctrlc())
 			break;
@@ -1265,18 +1265,17 @@ void flash_print_info (flash_info_t * info)
 			putc('\n');
 #ifdef CONFIG_SYS_FLASH_EMPTY_INFO
 		/* print empty and read-only info */
-		printf ("  %08lX %c %s ",
-			info->start[i],
-			sector_erased(info, i) ? 'E' : ' ',
-			info->protect[i] ? "RO" : "  ");
+		printf("  %08lX %c %s ",
+		       info->start[i],
+		       sector_erased(info, i) ? 'E' : ' ',
+		       info->protect[i] ? "RO" : "  ");
 #else	/* ! CONFIG_SYS_FLASH_EMPTY_INFO */
-		printf ("  %08lX   %s ",
-			info->start[i],
-			info->protect[i] ? "RO" : "  ");
+		printf("  %08lX   %s ",
+		       info->start[i],
+		       info->protect[i] ? "RO" : "  ");
 #endif
 	}
-	putc ('\n');
-	return;
+	putc('\n');
 }
 
 /*-----------------------------------------------------------------------
@@ -1291,9 +1290,9 @@ void flash_print_info (flash_info_t * info)
 		dots -= dots_sub; \
 		if ((scale > 0) && (dots <= 0)) { \
 			if ((digit % 5) == 0) \
-				printf ("%d", digit / 5); \
+				printf("%d", digit / 5); \
 			else \
-				putc ('.'); \
+				putc('.'); \
 			digit--; \
 			dots += scale; \
 		} \
@@ -1308,7 +1307,7 @@ void flash_print_info (flash_info_t * info)
  * 1 - write timeout
  * 2 - Flash not erased
  */
-int write_buff (flash_info_t * info, uchar * src, ulong addr, ulong cnt)
+int write_buff(flash_info_t *info, uchar *src, ulong addr, ulong cnt)
 {
 	ulong wp;
 	uchar *p;
@@ -1340,16 +1339,16 @@ int write_buff (flash_info_t * info, uchar * src, ulong addr, ulong cnt)
 		cword.w32 = 0;
 		p = (uchar *)wp;
 		for (i = 0; i < aln; ++i)
-			flash_add_byte (info, &cword, flash_read8(p + i));
+			flash_add_byte(info, &cword, flash_read8(p + i));
 
 		for (; (i < info->portwidth) && (cnt > 0); i++) {
-			flash_add_byte (info, &cword, *src++);
+			flash_add_byte(info, &cword, *src++);
 			cnt--;
 		}
 		for (; (cnt == 0) && (i < info->portwidth); ++i)
-			flash_add_byte (info, &cword, flash_read8(p + i));
+			flash_add_byte(info, &cword, flash_read8(p + i));
 
-		rc = flash_write_cfiword (info, wp, cword);
+		rc = flash_write_cfiword(info, wp, cword);
 		if (rc != 0)
 			return rc;
 
@@ -1366,8 +1365,8 @@ int write_buff (flash_info_t * info, uchar * src, ulong addr, ulong cnt)
 		if (info->buffer_size == 1) {
 			cword.w32 = 0;
 			for (i = 0; i < info->portwidth; i++)
-				flash_add_byte (info, &cword, *src++);
-			if ((rc = flash_write_cfiword (info, wp, cword)) != 0)
+				flash_add_byte(info, &cword, *src++);
+			if ((rc = flash_write_cfiword(info, wp, cword)) != 0)
 				return rc;
 			wp += info->portwidth;
 			cnt -= info->portwidth;
@@ -1378,7 +1377,7 @@ int write_buff (flash_info_t * info, uchar * src, ulong addr, ulong cnt)
 		i = buffered_size - (wp % buffered_size);
 		if (i > cnt)
 			i = cnt;
-		if ((rc = flash_write_cfibuffer (info, wp, src, i)) != ERR_OK)
+		if ((rc = flash_write_cfibuffer(info, wp, src, i)) != ERR_OK)
 			return rc;
 		i -= i & (info->portwidth - 1);
 		wp += i;
@@ -1392,10 +1391,9 @@ int write_buff (flash_info_t * info, uchar * src, ulong addr, ulong cnt)
 #else
 	while (cnt >= info->portwidth) {
 		cword.w32 = 0;
-		for (i = 0; i < info->portwidth; i++) {
-			flash_add_byte (info, &cword, *src++);
-		}
-		if ((rc = flash_write_cfiword (info, wp, cword)) != 0)
+		for (i = 0; i < info->portwidth; i++)
+			flash_add_byte(info, &cword, *src++);
+		if ((rc = flash_write_cfiword(info, wp, cword)) != 0)
 			return rc;
 		wp += info->portwidth;
 		cnt -= info->portwidth;
@@ -1406,9 +1404,8 @@ int write_buff (flash_info_t * info, uchar * src, ulong addr, ulong cnt)
 	}
 #endif /* CONFIG_SYS_FLASH_USE_BUFFER_WRITE */
 
-	if (cnt == 0) {
-		return (0);
-	}
+	if (cnt == 0)
+		return 0;
 
 	/*
 	 * handle unaligned tail bytes
@@ -1416,13 +1413,13 @@ int write_buff (flash_info_t * info, uchar * src, ulong addr, ulong cnt)
 	cword.w32 = 0;
 	p = (uchar *)wp;
 	for (i = 0; (i < info->portwidth) && (cnt > 0); ++i) {
-		flash_add_byte (info, &cword, *src++);
+		flash_add_byte(info, &cword, *src++);
 		--cnt;
 	}
 	for (; i < info->portwidth; ++i)
-		flash_add_byte (info, &cword, flash_read8(p + i));
+		flash_add_byte(info, &cword, flash_read8(p + i));
 
-	return flash_write_cfiword (info, wp, cword);
+	return flash_write_cfiword(info, wp, cword);
 }
 
 static inline int manufact_match(flash_info_t *info, u32 manu)
@@ -1436,8 +1433,8 @@ static inline int manufact_match(flash_info_t *info, u32 manu)
 
 static int cfi_protect_bugfix(flash_info_t *info, long sector, int prot)
 {
-	if (manufact_match(info, INTEL_MANUFACT)
-	    && info->device_id == NUMONYX_256MBIT) {
+	if (manufact_match(info, INTEL_MANUFACT) &&
+	    info->device_id == NUMONYX_256MBIT) {
 		/*
 		 * see errata called
 		 * "Numonyx Axcell P33/P30 Specification Update" :)
@@ -1468,99 +1465,100 @@ static int cfi_protect_bugfix(flash_info_t *info, long sector, int prot)
 	return 0;
 }
 
-int flash_real_protect (flash_info_t * info, long sector, int prot)
+int flash_real_protect(flash_info_t *info, long sector, int prot)
 {
 	int retcode = 0;
 
 	switch (info->vendor) {
-		case CFI_CMDSET_INTEL_PROG_REGIONS:
-		case CFI_CMDSET_INTEL_STANDARD:
-		case CFI_CMDSET_INTEL_EXTENDED:
-			if (!cfi_protect_bugfix(info, sector, prot)) {
-				flash_write_cmd(info, sector, 0,
-					 FLASH_CMD_CLEAR_STATUS);
-				flash_write_cmd(info, sector, 0,
+	case CFI_CMDSET_INTEL_PROG_REGIONS:
+	case CFI_CMDSET_INTEL_STANDARD:
+	case CFI_CMDSET_INTEL_EXTENDED:
+		if (!cfi_protect_bugfix(info, sector, prot)) {
+			flash_write_cmd(info, sector, 0,
+					FLASH_CMD_CLEAR_STATUS);
+			flash_write_cmd(info, sector, 0,
 					FLASH_CMD_PROTECT);
-				if (prot)
-					flash_write_cmd(info, sector, 0,
+			if (prot)
+				flash_write_cmd(info, sector, 0,
 						FLASH_CMD_PROTECT_SET);
-				else
-					flash_write_cmd(info, sector, 0,
+			else
+				flash_write_cmd(info, sector, 0,
 						FLASH_CMD_PROTECT_CLEAR);
-
-			}
-			break;
-		case CFI_CMDSET_AMD_EXTENDED:
-		case CFI_CMDSET_AMD_STANDARD:
-			/* U-Boot only checks the first byte */
-			if (manufact_match(info, ATM_MANUFACT)) {
-				if (prot) {
-					flash_unlock_seq (info, 0);
-					flash_write_cmd (info, 0,
-							info->addr_unlock1,
-							ATM_CMD_SOFTLOCK_START);
-					flash_unlock_seq (info, 0);
-					flash_write_cmd (info, sector, 0,
-							ATM_CMD_LOCK_SECT);
-				} else {
-					flash_write_cmd (info, 0,
-							info->addr_unlock1,
-							AMD_CMD_UNLOCK_START);
-					if (info->device_id == ATM_ID_BV6416)
-						flash_write_cmd (info, sector,
-							0, ATM_CMD_UNLOCK_SECT);
-				}
-			}
-			if (info->legacy_unlock) {
-				int flag = disable_interrupts();
-				int lock_flag;
-
+		}
+		break;
+	case CFI_CMDSET_AMD_EXTENDED:
+	case CFI_CMDSET_AMD_STANDARD:
+		/* U-Boot only checks the first byte */
+		if (manufact_match(info, ATM_MANUFACT)) {
+			if (prot) {
 				flash_unlock_seq(info, 0);
-				flash_write_cmd(info, 0, info->addr_unlock1,
-						AMD_CMD_SET_PPB_ENTRY);
-				lock_flag = flash_isset(info, sector, 0, 0x01);
-				if (prot) {
-					if (lock_flag) {
-						flash_write_cmd(info, sector, 0,
+				flash_write_cmd(info, 0,
+						info->addr_unlock1,
+						ATM_CMD_SOFTLOCK_START);
+				flash_unlock_seq(info, 0);
+				flash_write_cmd(info, sector, 0,
+						ATM_CMD_LOCK_SECT);
+			} else {
+				flash_write_cmd(info, 0,
+						info->addr_unlock1,
+						AMD_CMD_UNLOCK_START);
+				if (info->device_id == ATM_ID_BV6416)
+					flash_write_cmd(info, sector, 0,
+							ATM_CMD_UNLOCK_SECT);
+			}
+		}
+		if (info->legacy_unlock) {
+			int flag = disable_interrupts();
+			int lock_flag;
+
+			flash_unlock_seq(info, 0);
+			flash_write_cmd(info, 0, info->addr_unlock1,
+					AMD_CMD_SET_PPB_ENTRY);
+			lock_flag = flash_isset(info, sector, 0, 0x01);
+			if (prot) {
+				if (lock_flag) {
+					flash_write_cmd(info, sector, 0,
 							AMD_CMD_PPB_LOCK_BC1);
-						flash_write_cmd(info, sector, 0,
+					flash_write_cmd(info, sector, 0,
 							AMD_CMD_PPB_LOCK_BC2);
-					}
-					debug("sector %ld %slocked\n", sector,
-						lock_flag ? "" : "already ");
-				} else {
-					if (!lock_flag) {
-						debug("unlock %ld\n", sector);
-						flash_write_cmd(info, 0, 0,
+				}
+				debug("sector %ld %slocked\n", sector,
+				      lock_flag ? "" : "already ");
+			} else {
+				if (!lock_flag) {
+					debug("unlock %ld\n", sector);
+					flash_write_cmd(info, 0, 0,
 							AMD_CMD_PPB_UNLOCK_BC1);
-						flash_write_cmd(info, 0, 0,
+					flash_write_cmd(info, 0, 0,
 							AMD_CMD_PPB_UNLOCK_BC2);
-					}
-					debug("sector %ld %sunlocked\n", sector,
-						!lock_flag ? "" : "already ");
 				}
-				if (flag)
-					enable_interrupts();
-
-				if (flash_status_check(info, sector,
-						info->erase_blk_tout,
-						prot ? "protect" : "unprotect"))
-					printf("status check error\n");
-
-				flash_write_cmd(info, 0, 0,
-						AMD_CMD_SET_PPB_EXIT_BC1);
-				flash_write_cmd(info, 0, 0,
-						AMD_CMD_SET_PPB_EXIT_BC2);
+				debug("sector %ld %sunlocked\n", sector,
+				      !lock_flag ? "" : "already ");
 			}
-			break;
+			if (flag)
+				enable_interrupts();
+
+			if (flash_status_check(info, sector,
+					       info->erase_blk_tout,
+					       prot ? "protect" : "unprotect"))
+				printf("status check error\n");
+
+			flash_write_cmd(info, 0, 0,
+					AMD_CMD_SET_PPB_EXIT_BC1);
+			flash_write_cmd(info, 0, 0,
+					AMD_CMD_SET_PPB_EXIT_BC2);
+		}
+		break;
 #ifdef CONFIG_FLASH_CFI_LEGACY
-		case CFI_CMDSET_AMD_LEGACY:
-			flash_write_cmd (info, sector, 0, FLASH_CMD_CLEAR_STATUS);
-			flash_write_cmd (info, sector, 0, FLASH_CMD_PROTECT);
-			if (prot)
-				flash_write_cmd (info, sector, 0, FLASH_CMD_PROTECT_SET);
-			else
-				flash_write_cmd (info, sector, 0, FLASH_CMD_PROTECT_CLEAR);
+	case CFI_CMDSET_AMD_LEGACY:
+		flash_write_cmd(info, sector, 0, FLASH_CMD_CLEAR_STATUS);
+		flash_write_cmd(info, sector, 0, FLASH_CMD_PROTECT);
+		if (prot)
+			flash_write_cmd(info, sector, 0,
+					FLASH_CMD_PROTECT_SET);
+		else
+			flash_write_cmd(info, sector, 0,
+					FLASH_CMD_PROTECT_CLEAR);
 #endif
 	};
 
@@ -1570,9 +1568,8 @@ int flash_real_protect (flash_info_t * info, long sector, int prot)
 	 */
 	flash_write_cmd(info, sector, 0, FLASH_CMD_READ_STATUS);
 	if ((retcode =
-	     flash_full_status_check (info, sector, info->erase_blk_tout,
-				      prot ? "protect" : "unprotect")) == 0) {
-
+	     flash_full_status_check(info, sector, info->erase_blk_tout,
+				     prot ? "protect" : "unprotect")) == 0) {
 		info->protect[sector] = prot;
 
 		/*
@@ -1584,7 +1581,7 @@ int flash_real_protect (flash_info_t * info, long sector, int prot)
 
 			for (i = 0; i < info->sector_count; i++) {
 				if (info->protect[i])
-					flash_real_protect (info, i, 1);
+					flash_real_protect(info, i, 1);
 			}
 		}
 	}
@@ -1594,17 +1591,17 @@ int flash_real_protect (flash_info_t * info, long sector, int prot)
 /*-----------------------------------------------------------------------
  * flash_read_user_serial - read the OneTimeProgramming cells
  */
-void flash_read_user_serial (flash_info_t * info, void *buffer, int offset,
-			     int len)
+void flash_read_user_serial(flash_info_t *info, void *buffer, int offset,
+			    int len)
 {
 	uchar *src;
 	uchar *dst;
 
 	dst = buffer;
-	src = flash_map (info, 0, FLASH_OFFSET_USER_PROTECTION);
-	flash_write_cmd (info, 0, 0, FLASH_CMD_READ_ID);
-	memcpy (dst, src + offset, len);
-	flash_write_cmd (info, 0, 0, info->cmd_reset);
+	src = flash_map(info, 0, FLASH_OFFSET_USER_PROTECTION);
+	flash_write_cmd(info, 0, 0, FLASH_CMD_READ_ID);
+	memcpy(dst, src + offset, len);
+	flash_write_cmd(info, 0, 0, info->cmd_reset);
 	udelay(1);
 	flash_unmap(info, 0, FLASH_OFFSET_USER_PROTECTION, src);
 }
@@ -1612,15 +1609,15 @@ void flash_read_user_serial (flash_info_t * info, void *buffer, int offset,
 /*
  * flash_read_factory_serial - read the device Id from the protection area
  */
-void flash_read_factory_serial (flash_info_t * info, void *buffer, int offset,
-				int len)
+void flash_read_factory_serial(flash_info_t *info, void *buffer, int offset,
+			       int len)
 {
 	uchar *src;
 
-	src = flash_map (info, 0, FLASH_OFFSET_INTEL_PROTECTION);
-	flash_write_cmd (info, 0, 0, FLASH_CMD_READ_ID);
-	memcpy (buffer, src + offset, len);
-	flash_write_cmd (info, 0, 0, info->cmd_reset);
+	src = flash_map(info, 0, FLASH_OFFSET_INTEL_PROTECTION);
+	flash_write_cmd(info, 0, 0, FLASH_CMD_READ_ID);
+	memcpy(buffer, src + offset, len);
+	flash_write_cmd(info, 0, 0, info->cmd_reset);
 	udelay(1);
 	flash_unmap(info, 0, FLASH_OFFSET_INTEL_PROTECTION, src);
 }
@@ -1638,10 +1635,10 @@ static void cfi_reverse_geometry(struct cfi_qry *qry)
 	u32 tmp;
 
 	for (i = 0, j = qry->num_erase_regions - 1; i < j; i++, j--) {
-		tmp = get_unaligned(&(qry->erase_region_info[i]));
-		put_unaligned(get_unaligned(&(qry->erase_region_info[j])),
-			      &(qry->erase_region_info[i]));
-		put_unaligned(tmp, &(qry->erase_region_info[j]));
+		tmp = get_unaligned(&qry->erase_region_info[i]);
+		put_unaligned(get_unaligned(&qry->erase_region_info[j]),
+			      &qry->erase_region_info[i]);
+		put_unaligned(tmp, &qry->erase_region_info[j]);
 	}
 }
 
@@ -1660,8 +1657,8 @@ static void cmdset_intel_read_jedec_ids(flash_info_t *info)
 	info->manufacturer_id = flash_read_uchar (info,
 					FLASH_OFFSET_MANUFACTURER_ID);
 	info->device_id = (info->chipwidth == FLASH_CFI_16BIT) ?
-			flash_read_word (info, FLASH_OFFSET_DEVICE_ID) :
-			flash_read_uchar (info, FLASH_OFFSET_DEVICE_ID);
+			flash_read_word(info, FLASH_OFFSET_DEVICE_ID) :
+			flash_read_uchar(info, FLASH_OFFSET_DEVICE_ID);
 	flash_write_cmd(info, 0, 0, FLASH_CMD_RESET);
 }
 
@@ -1686,7 +1683,7 @@ static int cmdset_intel_init(flash_info_t *info, struct cfi_qry *qry)
 static void cmdset_amd_read_jedec_ids(flash_info_t *info)
 {
 	ushort bankId = 0;
-	uchar  manuId;
+	uchar manuId;
 
 	flash_write_cmd(info, 0, 0, AMD_CMD_RESET);
 	flash_unlock_seq(info, 0);
@@ -1697,12 +1694,12 @@ static void cmdset_amd_read_jedec_ids(flash_info_t *info)
 	/* JEDEC JEP106Z specifies ID codes up to bank 7 */
 	while (manuId == FLASH_CONTINUATION_CODE && bankId < 0x800) {
 		bankId += 0x100;
-		manuId = flash_read_uchar (info,
-			bankId | FLASH_OFFSET_MANUFACTURER_ID);
+		manuId = flash_read_uchar(info,
+					  bankId | FLASH_OFFSET_MANUFACTURER_ID);
 	}
 	info->manufacturer_id = manuId;
 
-	switch (info->chipwidth){
+	switch (info->chipwidth) {
 	case FLASH_CFI_8BIT:
 		info->device_id = flash_read_uchar (info,
 						FLASH_OFFSET_DEVICE_ID);
@@ -1716,8 +1713,8 @@ static void cmdset_amd_read_jedec_ids(flash_info_t *info)
 		}
 		break;
 	case FLASH_CFI_16BIT:
-		info->device_id = flash_read_word (info,
-						FLASH_OFFSET_DEVICE_ID);
+		info->device_id = flash_read_word(info,
+						  FLASH_OFFSET_DEVICE_ID);
 		if ((info->device_id & 0xff) == 0x7E) {
 			/* AMD 3-byte (expanded) device ids */
 			info->device_id2 = flash_read_uchar (info,
@@ -1754,7 +1751,7 @@ static int cmdset_amd_init(flash_info_t *info, struct cfi_qry *qry)
 }
 
 #ifdef CONFIG_FLASH_CFI_LEGACY
-static void flash_read_jedec_ids (flash_info_t * info)
+static void flash_read_jedec_ids(flash_info_t *info)
 {
 	info->manufacturer_id = 0;
 	info->device_id       = 0;
@@ -1786,7 +1783,8 @@ static int flash_detect_legacy(phys_addr_t base, int banknum)
 
 	if (board_flash_get_legacy(base, banknum, info)) {
 		/* board code may have filled info completely. If not, we
-		   use JEDEC ID probing. */
+		 * use JEDEC ID probing.
+		 */
 		if (!info->vendor) {
 			int modes[] = {
 				CFI_CMDSET_AMD_STANDARD,
@@ -1800,8 +1798,8 @@ static int flash_detect_legacy(phys_addr_t base, int banknum)
 					(ulong)map_physmem(base,
 							   info->portwidth,
 							   MAP_NOCACHE);
-				if (info->portwidth == FLASH_CFI_8BIT
-					&& info->interface == FLASH_CFI_X8X16) {
+				if (info->portwidth == FLASH_CFI_8BIT &&
+				    info->interface == FLASH_CFI_X8X16) {
 					info->addr_unlock1 = 0x2AAA;
 					info->addr_unlock2 = 0x5555;
 				} else {
@@ -1810,18 +1808,18 @@ static int flash_detect_legacy(phys_addr_t base, int banknum)
 				}
 				flash_read_jedec_ids(info);
 				debug("JEDEC PROBE: ID %x %x %x\n",
-						info->manufacturer_id,
-						info->device_id,
-						info->device_id2);
+				      info->manufacturer_id,
+				      info->device_id,
+				      info->device_id2);
 				if (jedec_flash_match(info, info->start[0]))
 					break;
-				else
-					unmap_physmem((void *)info->start[0],
-						      info->portwidth);
+
+				unmap_physmem((void *)info->start[0],
+					      info->portwidth);
 			}
 		}
 
-		switch(info->vendor) {
+		switch (info->vendor) {
 		case CFI_CMDSET_INTEL_PROG_REGIONS:
 		case CFI_CMDSET_INTEL_STANDARD:
 		case CFI_CMDSET_INTEL_EXTENDED:
@@ -1849,8 +1847,8 @@ static inline int flash_detect_legacy(phys_addr_t base, int banknum)
  * detect if flash is compatible with the Common Flash Interface (CFI)
  * http://www.jedec.org/download/search/jesd68.pdf
  */
-static void flash_read_cfi (flash_info_t *info, void *buf,
-		unsigned int start, size_t len)
+static void flash_read_cfi(flash_info_t *info, void *buf,
+			   unsigned int start, size_t len)
 {
 	u8 *p = buf;
 	unsigned int i;
@@ -1870,10 +1868,11 @@ static void __flash_cmd_reset(flash_info_t *info)
 	udelay(1);
 	flash_write_cmd(info, 0, 0, FLASH_CMD_RESET);
 }
+
 void flash_cmd_reset(flash_info_t *info)
 	__attribute__((weak,alias("__flash_cmd_reset")));
 
-static int __flash_detect_cfi (flash_info_t * info, struct cfi_qry *qry)
+static int __flash_detect_cfi(flash_info_t *info, struct cfi_qry *qry)
 {
 	int cfi_offset;
 
@@ -1882,23 +1881,23 @@ static int __flash_detect_cfi (flash_info_t * info, struct cfi_qry *qry)
 
 	for (cfi_offset = 0; cfi_offset < ARRAY_SIZE(flash_offset_cfi);
 	     cfi_offset++) {
-		flash_write_cmd (info, 0, flash_offset_cfi[cfi_offset],
-				 FLASH_CMD_CFI);
-		if (flash_isequal (info, 0, FLASH_OFFSET_CFI_RESP, 'Q')
-		    && flash_isequal (info, 0, FLASH_OFFSET_CFI_RESP + 1, 'R')
-		    && flash_isequal (info, 0, FLASH_OFFSET_CFI_RESP + 2, 'Y')) {
+		flash_write_cmd(info, 0, flash_offset_cfi[cfi_offset],
+				FLASH_CMD_CFI);
+		if (flash_isequal(info, 0, FLASH_OFFSET_CFI_RESP, 'Q') &&
+		    flash_isequal(info, 0, FLASH_OFFSET_CFI_RESP + 1, 'R') &&
+		    flash_isequal(info, 0, FLASH_OFFSET_CFI_RESP + 2, 'Y')) {
 			flash_read_cfi(info, qry, FLASH_OFFSET_CFI_RESP,
-					sizeof(struct cfi_qry));
+				       sizeof(struct cfi_qry));
 			info->interface	= le16_to_cpu(qry->interface_desc);
 
 			info->cfi_offset = flash_offset_cfi[cfi_offset];
-			debug ("device interface is %d\n",
-			       info->interface);
-			debug ("found port %d chip %d ",
-			       info->portwidth, info->chipwidth);
-			debug ("port %d bits chip %d bits\n",
-			       info->portwidth << CFI_FLASH_SHIFT_WIDTH,
-			       info->chipwidth << CFI_FLASH_SHIFT_WIDTH);
+			debug("device interface is %d\n",
+			      info->interface);
+			debug("found port %d chip %d ",
+			      info->portwidth, info->chipwidth);
+			debug("port %d bits chip %d bits\n",
+			      info->portwidth << CFI_FLASH_SHIFT_WIDTH,
+			      info->chipwidth << CFI_FLASH_SHIFT_WIDTH);
 
 			/* calculate command offsets as in the Linux driver */
 			info->addr_unlock1 = 0x555;
@@ -1908,13 +1907,12 @@ static int __flash_detect_cfi (flash_info_t * info, struct cfi_qry *qry)
 			 * modify the unlock address if we are
 			 * in compatibility mode
 			 */
-			if (	/* x8/x16 in x8 mode */
-				((info->chipwidth == FLASH_CFI_BY8) &&
-					(info->interface == FLASH_CFI_X8X16)) ||
-				/* x16/x32 in x16 mode */
-				((info->chipwidth == FLASH_CFI_BY16) &&
-					(info->interface == FLASH_CFI_X16X32)))
-			{
+			if (/* x8/x16 in x8 mode */
+			    ((info->chipwidth == FLASH_CFI_BY8) &&
+			    (info->interface == FLASH_CFI_X8X16)) ||
+			    /* x16/x32 in x16 mode */
+			    ((info->chipwidth == FLASH_CFI_BY16) &&
+			    (info->interface == FLASH_CFI_X16X32))) {
 				info->addr_unlock1 = 0xaaa;
 				info->addr_unlock2 = 0x555;
 			}
@@ -1927,9 +1925,9 @@ static int __flash_detect_cfi (flash_info_t * info, struct cfi_qry *qry)
 	return 0;
 }
 
-static int flash_detect_cfi (flash_info_t * info, struct cfi_qry *qry)
+static int flash_detect_cfi(flash_info_t *info, struct cfi_qry *qry)
 {
-	debug ("flash detect cfi\n");
+	debug("flash detect cfi\n");
 
 	for (info->portwidth = CONFIG_SYS_FLASH_CFI_WIDTH;
 	     info->portwidth <= FLASH_CFI_64BIT; info->portwidth <<= 1) {
@@ -1939,7 +1937,7 @@ static int flash_detect_cfi (flash_info_t * info, struct cfi_qry *qry)
 			if (__flash_detect_cfi(info, qry))
 				return 1;
 	}
-	debug ("not found\n");
+	debug("not found\n");
 	return 0;
 }
 
@@ -2018,7 +2016,7 @@ static void flash_fixup_sst(flash_info_t *info, struct cfi_qry *qry)
 	if (info->device_id == 0x5D23 || /* SST39VF3201B */
 	    info->device_id == 0x5C23) { /* SST39VF3202B */
 		/* set sector granularity to 4KB */
-		info->cmd_erase_sector=0x50;
+		info->cmd_erase_sector = 0x50;
 	}
 }
 
@@ -2031,13 +2029,12 @@ static void flash_fixup_num(flash_info_t *info, struct cfi_qry *qry)
 	 * So adjust the buffer size for M29EW while operating in 8-bit mode
 	 */
 	if (((qry->max_buf_write_size) > 0x8) &&
-			(info->device_id == 0x7E) &&
-			(info->device_id2 == 0x2201 ||
-			info->device_id2 == 0x2301 ||
-			info->device_id2 == 0x2801 ||
-			info->device_id2 == 0x4801)) {
-		debug("Adjusted buffer size on Numonyx flash"
-			" M29EW family in 8 bit mode\n");
+	    (info->device_id == 0x7E) &&
+	    (info->device_id2 == 0x2201 ||
+	    info->device_id2 == 0x2301 ||
+	    info->device_id2 == 0x2801 ||
+	    info->device_id2 == 0x4801)) {
+		debug("Adjusted buffer size on Numonyx flash M29EW family in 8 bit mode\n");
 		qry->max_buf_write_size = 0x8;
 	}
 }
@@ -2046,7 +2043,7 @@ static void flash_fixup_num(flash_info_t *info, struct cfi_qry *qry)
  * The following code cannot be run from FLASH!
  *
  */
-ulong flash_get_size (phys_addr_t base, int banknum)
+ulong flash_get_size(phys_addr_t base, int banknum)
 {
 	flash_info_t *info = &flash_info[banknum];
 	int i, j;
@@ -2070,20 +2067,20 @@ ulong flash_get_size (phys_addr_t base, int banknum)
 
 	info->start[0] = (ulong)map_physmem(base, info->portwidth, MAP_NOCACHE);
 
-	if (flash_detect_cfi (info, &qry)) {
-		info->vendor = le16_to_cpu(get_unaligned(&(qry.p_id)));
-		info->ext_addr = le16_to_cpu(get_unaligned(&(qry.p_adr)));
+	if (flash_detect_cfi(info, &qry)) {
+		info->vendor = le16_to_cpu(get_unaligned(&qry.p_id));
+		info->ext_addr = le16_to_cpu(get_unaligned(&qry.p_adr));
 		num_erase_regions = qry.num_erase_regions;
 
 		if (info->ext_addr) {
-			info->cfi_version = (ushort) flash_read_uchar (info,
+			info->cfi_version = (ushort)flash_read_uchar (info,
 						info->ext_addr + 3) << 8;
-			info->cfi_version |= (ushort) flash_read_uchar (info,
+			info->cfi_version |= (ushort)flash_read_uchar (info,
 						info->ext_addr + 4);
 		}
 
 #ifdef DEBUG
-		flash_printqry (&qry);
+		flash_printqry(&qry);
 #endif
 
 		switch (info->vendor) {
@@ -2098,7 +2095,7 @@ ulong flash_get_size (phys_addr_t base, int banknum)
 			break;
 		default:
 			printf("CFI: Unknown command set 0x%x\n",
-					info->vendor);
+			       info->vendor);
 			/*
 			 * Unfortunately, this means we don't know how
 			 * to get the chip back to Read mode. Might
@@ -2128,21 +2125,21 @@ ulong flash_get_size (phys_addr_t base, int banknum)
 			break;
 		}
 
-		debug ("manufacturer is %d\n", info->vendor);
-		debug ("manufacturer id is 0x%x\n", info->manufacturer_id);
-		debug ("device id is 0x%x\n", info->device_id);
-		debug ("device id2 is 0x%x\n", info->device_id2);
-		debug ("cfi version is 0x%04x\n", info->cfi_version);
+		debug("manufacturer is %d\n", info->vendor);
+		debug("manufacturer id is 0x%x\n", info->manufacturer_id);
+		debug("device id is 0x%x\n", info->device_id);
+		debug("device id2 is 0x%x\n", info->device_id2);
+		debug("cfi version is 0x%04x\n", info->cfi_version);
 
 		size_ratio = info->portwidth / info->chipwidth;
 		/* if the chip is x8/x16 reduce the ratio by half */
-		if ((info->interface == FLASH_CFI_X8X16)
-		    && (info->chipwidth == FLASH_CFI_BY8)) {
+		if ((info->interface == FLASH_CFI_X8X16) &&
+		    (info->chipwidth == FLASH_CFI_BY8)) {
 			size_ratio >>= 1;
 		}
-		debug ("size_ratio %d port %d bits chip %d bits\n",
-		       size_ratio, info->portwidth << CFI_FLASH_SHIFT_WIDTH,
-		       info->chipwidth << CFI_FLASH_SHIFT_WIDTH);
+		debug("size_ratio %d port %d bits chip %d bits\n",
+		      size_ratio, info->portwidth << CFI_FLASH_SHIFT_WIDTH,
+		      info->chipwidth << CFI_FLASH_SHIFT_WIDTH);
 		info->size = 1 << qry.dev_size;
 		/* multiply the size by the number of chips */
 		info->size *= size_ratio;
@@ -2151,26 +2148,26 @@ ulong flash_get_size (phys_addr_t base, int banknum)
 			debug("[truncated from %ldMiB]", info->size >> 20);
 			info->size = max_size;
 		}
-		debug ("found %d erase regions\n", num_erase_regions);
+		debug("found %d erase regions\n", num_erase_regions);
 		sect_cnt = 0;
 		sector = base;
 		for (i = 0; i < num_erase_regions; i++) {
 			if (i > NUM_ERASE_REGIONS) {
-				printf ("%d erase regions found, only %d used\n",
-					num_erase_regions, NUM_ERASE_REGIONS);
+				printf("%d erase regions found, only %d used\n",
+				       num_erase_regions, NUM_ERASE_REGIONS);
 				break;
 			}
 
 			tmp = le32_to_cpu(get_unaligned(
-						&(qry.erase_region_info[i])));
+						&qry.erase_region_info[i]));
 			debug("erase region %u: 0x%08lx\n", i, tmp);
 
 			erase_region_count = (tmp & 0xffff) + 1;
 			tmp >>= 16;
 			erase_region_size =
 				(tmp & 0xffff) ? ((tmp & 0xffff) * 256) : 128;
-			debug ("erase_region_count = %d erase_region_size = %d\n",
-				erase_region_count, erase_region_size);
+			debug("erase_region_count = %d erase_region_size = %d\n",
+			      erase_region_count, erase_region_size);
 			for (j = 0; j < erase_region_count; j++) {
 				if (sector - base >= info->size)
 					break;
@@ -2200,9 +2197,9 @@ ulong flash_get_size (phys_addr_t base, int banknum)
 					flash_write_cmd(info, sect_cnt, 0,
 							FLASH_CMD_READ_ID);
 					info->protect[sect_cnt] =
-						flash_isset (info, sect_cnt,
-							     FLASH_OFFSET_PROTECT,
-							     FLASH_STATUS_PROTECT);
+						flash_isset(info, sect_cnt,
+							    FLASH_OFFSET_PROTECT,
+							    FLASH_STATUS_PROTECT);
 					flash_write_cmd(info, sect_cnt, 0,
 							FLASH_CMD_RESET);
 					break;
@@ -2257,10 +2254,10 @@ ulong flash_get_size (phys_addr_t base, int banknum)
 			info->portwidth >>= 1;
 		}
 
-		flash_write_cmd (info, 0, 0, info->cmd_reset);
+		flash_write_cmd(info, 0, 0, info->cmd_reset);
 	}
 
-	return (info->size);
+	return info->size;
 }
 
 #ifdef CONFIG_FLASH_CFI_MTD
@@ -2312,25 +2309,25 @@ void flash_protect_default(void)
 #if (CONFIG_SYS_MONITOR_BASE >= CONFIG_SYS_FLASH_BASE) && \
 	(!defined(CONFIG_MONITOR_IS_IN_RAM))
 	flash_protect(FLAG_PROTECT_SET,
-		       CONFIG_SYS_MONITOR_BASE,
-		       CONFIG_SYS_MONITOR_BASE + monitor_flash_len  - 1,
-		       flash_get_info(CONFIG_SYS_MONITOR_BASE));
+		      CONFIG_SYS_MONITOR_BASE,
+		      CONFIG_SYS_MONITOR_BASE + monitor_flash_len  - 1,
+		      flash_get_info(CONFIG_SYS_MONITOR_BASE));
 #endif
 
 	/* Environment protection ON by default */
 #ifdef CONFIG_ENV_IS_IN_FLASH
 	flash_protect(FLAG_PROTECT_SET,
-		       CONFIG_ENV_ADDR,
-		       CONFIG_ENV_ADDR + CONFIG_ENV_SECT_SIZE - 1,
-		       flash_get_info(CONFIG_ENV_ADDR));
+		      CONFIG_ENV_ADDR,
+		      CONFIG_ENV_ADDR + CONFIG_ENV_SECT_SIZE - 1,
+		      flash_get_info(CONFIG_ENV_ADDR));
 #endif
 
 	/* Redundant environment protection ON by default */
 #ifdef CONFIG_ENV_ADDR_REDUND
 	flash_protect(FLAG_PROTECT_SET,
-		       CONFIG_ENV_ADDR_REDUND,
-		       CONFIG_ENV_ADDR_REDUND + CONFIG_ENV_SECT_SIZE - 1,
-		       flash_get_info(CONFIG_ENV_ADDR_REDUND));
+		      CONFIG_ENV_ADDR_REDUND,
+		      CONFIG_ENV_ADDR_REDUND + CONFIG_ENV_SECT_SIZE - 1,
+		      flash_get_info(CONFIG_ENV_ADDR_REDUND));
 #endif
 
 #if defined(CONFIG_SYS_FLASH_AUTOPROTECT_LIST)
@@ -2338,14 +2335,14 @@ void flash_protect_default(void)
 		debug("autoprotecting from %08lx to %08lx\n",
 		      apl[i].start, apl[i].start + apl[i].size - 1);
 		flash_protect(FLAG_PROTECT_SET,
-			       apl[i].start,
-			       apl[i].start + apl[i].size - 1,
-			       flash_get_info(apl[i].start));
+			      apl[i].start,
+			      apl[i].start + apl[i].size - 1,
+			      flash_get_info(apl[i].start));
 	}
 #endif
 }
 
-unsigned long flash_init (void)
+unsigned long flash_init(void)
 {
 	unsigned long size = 0;
 	int i;
@@ -2353,6 +2350,7 @@ unsigned long flash_init (void)
 #ifdef CONFIG_SYS_FLASH_PROTECTION
 	/* read environment from EEPROM */
 	char s[64];
+
 	getenv_f("unlock", s, sizeof(s));
 #endif
 
@@ -2373,10 +2371,9 @@ unsigned long flash_init (void)
 		size += flash_info[i].size;
 		if (flash_info[i].flash_id == FLASH_UNKNOWN) {
 #ifndef CONFIG_SYS_FLASH_QUIET_TEST
-			printf ("## Unknown flash on Bank %d "
-				"- Size = 0x%08lx = %ld MB\n",
-				i+1, flash_info[i].size,
-				flash_info[i].size >> 20);
+			printf("## Unknown flash on Bank %d - Size = 0x%08lx = %ld MB\n",
+			       i + 1, flash_info[i].size,
+			       flash_info[i].size >> 20);
 #endif /* CONFIG_SYS_FLASH_QUIET_TEST */
 		}
 #ifdef CONFIG_SYS_FLASH_PROTECTION
@@ -2405,7 +2402,7 @@ unsigned long flash_init (void)
 				 * unlock only one sector. This will
 				 * unlock all sectors.
 				 */
-				flash_real_protect (&flash_info[i], 0, 0);
+				flash_real_protect(&flash_info[i], 0, 0);
 
 				flash_info[i].legacy_unlock = 1;
 
@@ -2419,11 +2416,11 @@ unsigned long flash_init (void)
 				/*
 				 * No legancy unlocking -> unlock all sectors
 				 */
-				flash_protect (FLAG_PROTECT_CLEAR,
-					       flash_info[i].start[0],
-					       flash_info[i].start[0]
-					       + flash_info[i].size - 1,
-					       &flash_info[i]);
+				flash_protect(FLAG_PROTECT_CLEAR,
+					      flash_info[i].start[0],
+					      flash_info[i].start[0]
+					      + flash_info[i].size - 1,
+					      &flash_info[i]);
 			}
 		}
 #endif /* CONFIG_SYS_FLASH_PROTECTION */
@@ -2434,7 +2431,7 @@ unsigned long flash_init (void)
 	cfi_mtd_init();
 #endif
 
-	return (size);
+	return size;
 }
 
 #ifdef CONFIG_CFI_FLASH /* for driver model */
-- 
2.11.0

^ permalink raw reply related	[flat|nested] 138+ messages in thread

* [U-Boot] [PATCH 13/51] cfi_flash: Clean up code some more
  2017-07-14 12:54 [U-Boot] [PATCH 00/51] gdsys: Add support for Gazerbeam board Mario Six
                   ` (11 preceding siblings ...)
  2017-07-14 12:54 ` [U-Boot] [PATCH 12/51] cfi_flash: Fix style violations Mario Six
@ 2017-07-14 12:54 ` Mario Six
  2017-07-18 14:02   ` Simon Glass
  2017-07-14 12:55 ` [U-Boot] [PATCH 14/51] cfi_flash: Always define cfi_flash_num_flash_banks Mario Six
                   ` (37 subsequent siblings)
  50 siblings, 1 reply; 138+ messages in thread
From: Mario Six @ 2017-07-14 12:54 UTC (permalink / raw)
  To: u-boot

Fix some more style violations (mostly mis-indented case statements),
and reduce the scope of some variables.

Signed-off-by: Mario Six <mario.six@gdsys.cc>
---

 drivers/mtd/cfi_flash.c | 610 ++++++++++++++++++++++++------------------------
 1 file changed, 305 insertions(+), 305 deletions(-)

diff --git a/drivers/mtd/cfi_flash.c b/drivers/mtd/cfi_flash.c
index 18be3bee53..2445632580 100644
--- a/drivers/mtd/cfi_flash.c
+++ b/drivers/mtd/cfi_flash.c
@@ -183,10 +183,10 @@ __maybe_weak u64 flash_read64(void *addr)
 flash_info_t *flash_get_info(ulong base)
 {
 	int i;
-	flash_info_t *info;
 
 	for (i = 0; i < CONFIG_SYS_MAX_FLASH_BANKS; i++) {
-		info = &flash_info[i];
+		flash_info_t *info = &flash_info[i];
+
 		if (info->size && info->start[0] <= base &&
 		    base <= info->start[0] + info->size - 1)
 			return info;
@@ -226,8 +226,6 @@ static inline void flash_unmap(flash_info_t *info, flash_sect_t sect,
 static void flash_make_cmd(flash_info_t *info, u32 cmd, void *cmdbuf)
 {
 	int i;
-	int cword_offset;
-	int cp_offset;
 #if defined(__LITTLE_ENDIAN) || defined(CONFIG_SYS_WRITE_SWAPPED_DATA)
 	u32 cmd_le = cpu_to_le32(cmd);
 #endif
@@ -235,7 +233,8 @@ static void flash_make_cmd(flash_info_t *info, u32 cmd, void *cmdbuf)
 	uchar *cp = (uchar *)cmdbuf;
 
 	for (i = info->portwidth; i > 0; i--) {
-		cword_offset = (info->portwidth - i) % info->chipwidth;
+		int cp_offset;
+		int cword_offset = (info->portwidth - i) % info->chipwidth;
 #if defined(__LITTLE_ENDIAN) || defined(CONFIG_SYS_WRITE_SWAPPED_DATA)
 		cp_offset = info->portwidth - i;
 		val = *((uchar *)&cmd_le + cword_offset);
@@ -1072,96 +1071,94 @@ int flash_erase(flash_info_t *info, int s_first, int s_last)
 	}
 
 	for (sect = s_first; sect <= s_last; sect++) {
+#ifdef CONFIG_SYS_FLASH_CHECK_BLANK_BEFORE_ERASE
+		int k;
+		int size;
+		int erased;
+		u32 *flash;
+#endif
+
 		if (ctrlc()) {
 			printf("\n");
 			return 1;
 		}
 
-		if (info->protect[sect] == 0) { /* not protected */
-#ifdef CONFIG_SYS_FLASH_CHECK_BLANK_BEFORE_ERASE
-			int k;
-			int size;
-			int erased;
-			u32 *flash;
+		if (info->protect[sect] != 0)
+			continue;
 
-			/*
-			 * Check if whole sector is erased
-			 */
-			size = flash_sector_size(info, sect);
-			erased = 1;
-			flash = (u32 *)info->start[sect];
-			/* divide by 4 for longword access */
-			size = size >> 2;
-			for (k = 0; k < size; k++) {
-				if (flash_read32(flash++) != 0xffffffff) {
-					erased = 0;
-					break;
-				}
-			}
-			if (erased) {
-				if (flash_verbose)
-					putc(',');
-				continue;
+#ifdef CONFIG_SYS_FLASH_CHECK_BLANK_BEFORE_ERASE
+		/*
+		 * Check if whole sector is erased
+		 */
+		size = flash_sector_size(info, sect);
+		erased = 1;
+		flash = (u32 *)info->start[sect];
+		/* divide by 4 for longword access */
+		size = size >> 2;
+		for (k = 0; k < size; k++) {
+			if (flash_read32(flash++) != 0xffffffff) {
+				erased = 0;
+				break;
 			}
+		}
+		if (erased) {
+			if (flash_verbose)
+				putc(',');
+			continue;
+		}
 #endif
-			switch (info->vendor) {
-			case CFI_CMDSET_INTEL_PROG_REGIONS:
-			case CFI_CMDSET_INTEL_STANDARD:
-			case CFI_CMDSET_INTEL_EXTENDED:
-				flash_write_cmd(info, sect, 0,
-						FLASH_CMD_CLEAR_STATUS);
-				flash_write_cmd(info, sect, 0,
-						FLASH_CMD_BLOCK_ERASE);
-				flash_write_cmd(info, sect, 0,
-						FLASH_CMD_ERASE_CONFIRM);
-				break;
-			case CFI_CMDSET_AMD_STANDARD:
-			case CFI_CMDSET_AMD_EXTENDED:
-				flash_unlock_seq(info, sect);
-				flash_write_cmd(info, sect,
-						info->addr_unlock1,
-						AMD_CMD_ERASE_START);
-				flash_unlock_seq(info, sect);
-				flash_write_cmd(info, sect, 0,
-						info->cmd_erase_sector);
-				break;
+		switch (info->vendor) {
+		case CFI_CMDSET_INTEL_PROG_REGIONS:
+		case CFI_CMDSET_INTEL_STANDARD:
+		case CFI_CMDSET_INTEL_EXTENDED:
+			flash_write_cmd(info, sect, 0, FLASH_CMD_CLEAR_STATUS);
+			flash_write_cmd(info, sect, 0, FLASH_CMD_BLOCK_ERASE);
+			flash_write_cmd(info, sect, 0, FLASH_CMD_ERASE_CONFIRM);
+			break;
+		case CFI_CMDSET_AMD_STANDARD:
+		case CFI_CMDSET_AMD_EXTENDED:
+			flash_unlock_seq(info, sect);
+			flash_write_cmd(info, sect, info->addr_unlock1,
+					AMD_CMD_ERASE_START);
+			flash_unlock_seq(info, sect);
+			flash_write_cmd(info, sect, 0, info->cmd_erase_sector);
+			break;
 #ifdef CONFIG_FLASH_CFI_LEGACY
-			case CFI_CMDSET_AMD_LEGACY:
-				flash_unlock_seq(info, 0);
-				flash_write_cmd(info, 0, info->addr_unlock1,
-						AMD_CMD_ERASE_START);
-				flash_unlock_seq(info, 0);
-				flash_write_cmd(info, sect, 0,
-						AMD_CMD_ERASE_SECTOR);
-				break;
+		case CFI_CMDSET_AMD_LEGACY:
+			flash_unlock_seq(info, 0);
+			flash_write_cmd(info, 0, info->addr_unlock1,
+					AMD_CMD_ERASE_START);
+			flash_unlock_seq(info, 0);
+			flash_write_cmd(info, sect, 0,
+					AMD_CMD_ERASE_SECTOR);
+			break;
 #endif
-			default:
-				debug("Unknown flash vendor %d\n",
-				      info->vendor);
-				break;
-			}
-
-			if (use_flash_status_poll(info)) {
-				cfiword_t cword;
-				void *dest;
+		default:
+			debug("Unknown flash vendor %d\n",
+			      info->vendor);
+			break;
+		}
 
-				cword.w64 = 0xffffffffffffffffULL;
-				dest = flash_map(info, sect, 0);
-				st = flash_status_poll(info, &cword, dest,
-						       info->erase_blk_tout,
-						       "erase");
-				flash_unmap(info, sect, 0, dest);
-			} else {
-				st = flash_full_status_check(info, sect,
-							     info->erase_blk_tout,
-							     "erase");
-			}
+		if (use_flash_status_poll(info)) {
+			cfiword_t cword;
+			void *dest;
 
-			if (st)
-				rcode = 1;
-			else if (flash_verbose)
-				putc('.');
+			cword.w64 = 0xffffffffffffffffULL;
+			dest = flash_map(info, sect, 0);
+			st = flash_status_poll(info, &cword, dest,
+					       info->erase_blk_tout,
+					       "erase");
+			flash_unmap(info, sect, 0, dest);
+		} else {
+			st = flash_full_status_check(info, sect,
+						     info->erase_blk_tout,
+						     "erase");
 		}
+
+		if (st)
+			rcode = 1;
+		else if (flash_verbose)
+			putc('.');
 	}
 
 	if (flash_verbose)
@@ -1335,7 +1332,8 @@ int write_buff(flash_info_t *info, uchar *src, ulong addr, ulong cnt)
 	wp = (addr & ~(info->portwidth - 1));
 
 	/* handle unaligned start */
-	if ((aln = addr - wp) != 0) {
+	aln = addr - wp;
+	if (aln != 0) {
 		cword.w32 = 0;
 		p = (uchar *)wp;
 		for (i = 0; i < aln; ++i)
@@ -1366,7 +1364,8 @@ int write_buff(flash_info_t *info, uchar *src, ulong addr, ulong cnt)
 			cword.w32 = 0;
 			for (i = 0; i < info->portwidth; i++)
 				flash_add_byte(info, &cword, *src++);
-			if ((rc = flash_write_cfiword(info, wp, cword)) != 0)
+			rc = flash_write_cfiword(info, wp, cword);
+			if (rc != 0)
 				return rc;
 			wp += info->portwidth;
 			cnt -= info->portwidth;
@@ -1377,7 +1376,8 @@ int write_buff(flash_info_t *info, uchar *src, ulong addr, ulong cnt)
 		i = buffered_size - (wp % buffered_size);
 		if (i > cnt)
 			i = cnt;
-		if ((rc = flash_write_cfibuffer(info, wp, src, i)) != ERR_OK)
+		rc = flash_write_cfibuffer(info, wp, src, i);
+		if (rc != ERR_OK)
 			return rc;
 		i -= i & (info->portwidth - 1);
 		wp += i;
@@ -1393,7 +1393,8 @@ int write_buff(flash_info_t *info, uchar *src, ulong addr, ulong cnt)
 		cword.w32 = 0;
 		for (i = 0; i < info->portwidth; i++)
 			flash_add_byte(info, &cword, *src++);
-		if ((rc = flash_write_cfiword(info, wp, cword)) != 0)
+		rc = flash_write_cfiword(info, wp, cword);
+		if (rc != 0)
 			return rc;
 		wp += info->portwidth;
 		cnt -= info->portwidth;
@@ -1567,9 +1568,9 @@ int flash_real_protect(flash_info_t *info, long sector, int prot)
 	 * flash_full_status_check() to work correctly
 	 */
 	flash_write_cmd(info, sector, 0, FLASH_CMD_READ_STATUS);
-	if ((retcode =
-	     flash_full_status_check(info, sector, info->erase_blk_tout,
-				     prot ? "protect" : "unprotect")) == 0) {
+	retcode = flash_full_status_check(info, sector, info->erase_blk_tout,
+					  prot ? "protect" : "unprotect");
+	if (retcode == 0) {
 		info->protect[sector] = prot;
 
 		/*
@@ -1682,22 +1683,22 @@ static int cmdset_intel_init(flash_info_t *info, struct cfi_qry *qry)
 
 static void cmdset_amd_read_jedec_ids(flash_info_t *info)
 {
-	ushort bankId = 0;
-	uchar manuId;
+	ushort bank_id = 0;
+	uchar manu_id;
 
 	flash_write_cmd(info, 0, 0, AMD_CMD_RESET);
 	flash_unlock_seq(info, 0);
 	flash_write_cmd(info, 0, info->addr_unlock1, FLASH_CMD_READ_ID);
 	udelay(1000); /* some flash are slow to respond */
 
-	manuId = flash_read_uchar (info, FLASH_OFFSET_MANUFACTURER_ID);
+	manu_id = flash_read_uchar (info, FLASH_OFFSET_MANUFACTURER_ID);
 	/* JEDEC JEP106Z specifies ID codes up to bank 7 */
-	while (manuId == FLASH_CONTINUATION_CODE && bankId < 0x800) {
-		bankId += 0x100;
-		manuId = flash_read_uchar(info,
-					  bankId | FLASH_OFFSET_MANUFACTURER_ID);
+	while (manu_id == FLASH_CONTINUATION_CODE && bank_id < 0x800) {
+		bank_id += 0x100;
+		manu_id = flash_read_uchar(info,
+					   bank_id | FLASH_OFFSET_MANUFACTURER_ID);
 	}
-	info->manufacturer_id = manuId;
+	info->manufacturer_id = manu_id;
 
 	switch (info->chipwidth) {
 	case FLASH_CFI_8BIT:
@@ -1870,7 +1871,7 @@ static void __flash_cmd_reset(flash_info_t *info)
 }
 
 void flash_cmd_reset(flash_info_t *info)
-	__attribute__((weak,alias("__flash_cmd_reset")));
+	__attribute__((weak, alias("__flash_cmd_reset")));
 
 static int __flash_detect_cfi(flash_info_t *info, struct cfi_qry *qry)
 {
@@ -2052,8 +2053,6 @@ ulong flash_get_size(phys_addr_t base, int banknum)
 	unsigned long tmp;
 	int size_ratio;
 	uchar num_erase_regions;
-	int erase_region_size;
-	int erase_region_count;
 	struct cfi_qry qry;
 	unsigned long max_size;
 
@@ -2067,196 +2066,200 @@ ulong flash_get_size(phys_addr_t base, int banknum)
 
 	info->start[0] = (ulong)map_physmem(base, info->portwidth, MAP_NOCACHE);
 
-	if (flash_detect_cfi(info, &qry)) {
-		info->vendor = le16_to_cpu(get_unaligned(&qry.p_id));
-		info->ext_addr = le16_to_cpu(get_unaligned(&qry.p_adr));
-		num_erase_regions = qry.num_erase_regions;
+	if (!flash_detect_cfi(info, &qry))
+		return info->size;
 
-		if (info->ext_addr) {
-			info->cfi_version = (ushort)flash_read_uchar (info,
-						info->ext_addr + 3) << 8;
-			info->cfi_version |= (ushort)flash_read_uchar (info,
-						info->ext_addr + 4);
-		}
+	info->vendor = le16_to_cpu(get_unaligned(&qry.p_id));
+	info->ext_addr = le16_to_cpu(get_unaligned(&qry.p_adr));
+	num_erase_regions = qry.num_erase_regions;
+
+	if (info->ext_addr) {
+		info->cfi_version = (ushort)flash_read_uchar (info,
+					info->ext_addr + 3) << 8;
+		info->cfi_version |= (ushort)flash_read_uchar (info,
+					info->ext_addr + 4);
+	}
 
 #ifdef DEBUG
-		flash_printqry(&qry);
+	flash_printqry(&qry);
 #endif
 
-		switch (info->vendor) {
-		case CFI_CMDSET_INTEL_PROG_REGIONS:
-		case CFI_CMDSET_INTEL_STANDARD:
-		case CFI_CMDSET_INTEL_EXTENDED:
-			cmdset_intel_init(info, &qry);
-			break;
-		case CFI_CMDSET_AMD_STANDARD:
-		case CFI_CMDSET_AMD_EXTENDED:
-			cmdset_amd_init(info, &qry);
-			break;
-		default:
-			printf("CFI: Unknown command set 0x%x\n",
-			       info->vendor);
-			/*
-			 * Unfortunately, this means we don't know how
-			 * to get the chip back to Read mode. Might
-			 * as well try an Intel-style reset...
-			 */
-			flash_write_cmd(info, 0, 0, FLASH_CMD_RESET);
-			return 0;
-		}
+	switch (info->vendor) {
+	case CFI_CMDSET_INTEL_PROG_REGIONS:
+	case CFI_CMDSET_INTEL_STANDARD:
+	case CFI_CMDSET_INTEL_EXTENDED:
+		cmdset_intel_init(info, &qry);
+		break;
+	case CFI_CMDSET_AMD_STANDARD:
+	case CFI_CMDSET_AMD_EXTENDED:
+		cmdset_amd_init(info, &qry);
+		break;
+	default:
+		printf("CFI: Unknown command set 0x%x\n",
+		       info->vendor);
+		/*
+		 * Unfortunately, this means we don't know how
+		 * to get the chip back to Read mode. Might
+		 * as well try an Intel-style reset...
+		 */
+		flash_write_cmd(info, 0, 0, FLASH_CMD_RESET);
+		return 0;
+	}
 
-		/* Do manufacturer-specific fixups */
-		switch (info->manufacturer_id) {
-		case 0x0001: /* AMD */
-		case 0x0037: /* AMIC */
-			flash_fixup_amd(info, &qry);
-			break;
-		case 0x001f:
-			flash_fixup_atmel(info, &qry);
-			break;
-		case 0x0020:
-			flash_fixup_stm(info, &qry);
-			break;
-		case 0x00bf: /* SST */
-			flash_fixup_sst(info, &qry);
-			break;
-		case 0x0089: /* Numonyx */
-			flash_fixup_num(info, &qry);
+	/* Do manufacturer-specific fixups */
+	switch (info->manufacturer_id) {
+	case 0x0001: /* AMD */
+	case 0x0037: /* AMIC */
+		flash_fixup_amd(info, &qry);
+		break;
+	case 0x001f:
+		flash_fixup_atmel(info, &qry);
+		break;
+	case 0x0020:
+		flash_fixup_stm(info, &qry);
+		break;
+	case 0x00bf: /* SST */
+		flash_fixup_sst(info, &qry);
+		break;
+	case 0x0089: /* Numonyx */
+		flash_fixup_num(info, &qry);
+		break;
+	}
+
+	debug("manufacturer is %d\n", info->vendor);
+	debug("manufacturer id is 0x%x\n", info->manufacturer_id);
+	debug("device id is 0x%x\n", info->device_id);
+	debug("device id2 is 0x%x\n", info->device_id2);
+	debug("cfi version is 0x%04x\n", info->cfi_version);
+
+	size_ratio = info->portwidth / info->chipwidth;
+	/* if the chip is x8/x16 reduce the ratio by half */
+	if ((info->interface == FLASH_CFI_X8X16) &&
+	    (info->chipwidth == FLASH_CFI_BY8)) {
+		size_ratio >>= 1;
+	}
+	debug("size_ratio %d port %d bits chip %d bits\n",
+	      size_ratio, info->portwidth << CFI_FLASH_SHIFT_WIDTH,
+	      info->chipwidth << CFI_FLASH_SHIFT_WIDTH);
+	info->size = 1 << qry.dev_size;
+	/* multiply the size by the number of chips */
+	info->size *= size_ratio;
+	max_size = cfi_flash_bank_size(banknum);
+	if (max_size && (info->size > max_size)) {
+		debug("[truncated from %ldMiB]", info->size >> 20);
+		info->size = max_size;
+	}
+	debug("found %d erase regions\n", num_erase_regions);
+	sect_cnt = 0;
+	sector = base;
+	for (i = 0; i < num_erase_regions; i++) {
+		int erase_region_size;
+		int erase_region_count;
+
+		if (i > NUM_ERASE_REGIONS) {
+			printf("%d erase regions found, only %d used\n",
+			       num_erase_regions, NUM_ERASE_REGIONS);
 			break;
 		}
 
-		debug("manufacturer is %d\n", info->vendor);
-		debug("manufacturer id is 0x%x\n", info->manufacturer_id);
-		debug("device id is 0x%x\n", info->device_id);
-		debug("device id2 is 0x%x\n", info->device_id2);
-		debug("cfi version is 0x%04x\n", info->cfi_version);
-
-		size_ratio = info->portwidth / info->chipwidth;
-		/* if the chip is x8/x16 reduce the ratio by half */
-		if ((info->interface == FLASH_CFI_X8X16) &&
-		    (info->chipwidth == FLASH_CFI_BY8)) {
-			size_ratio >>= 1;
-		}
-		debug("size_ratio %d port %d bits chip %d bits\n",
-		      size_ratio, info->portwidth << CFI_FLASH_SHIFT_WIDTH,
-		      info->chipwidth << CFI_FLASH_SHIFT_WIDTH);
-		info->size = 1 << qry.dev_size;
-		/* multiply the size by the number of chips */
-		info->size *= size_ratio;
-		max_size = cfi_flash_bank_size(banknum);
-		if (max_size && (info->size > max_size)) {
-			debug("[truncated from %ldMiB]", info->size >> 20);
-			info->size = max_size;
-		}
-		debug("found %d erase regions\n", num_erase_regions);
-		sect_cnt = 0;
-		sector = base;
-		for (i = 0; i < num_erase_regions; i++) {
-			if (i > NUM_ERASE_REGIONS) {
-				printf("%d erase regions found, only %d used\n",
-				       num_erase_regions, NUM_ERASE_REGIONS);
+		tmp = le32_to_cpu(get_unaligned(
+					&qry.erase_region_info[i]));
+		debug("erase region %u: 0x%08lx\n", i, tmp);
+
+		erase_region_count = (tmp & 0xffff) + 1;
+		tmp >>= 16;
+		erase_region_size =
+			(tmp & 0xffff) ? ((tmp & 0xffff) * 256) : 128;
+		debug("erase_region_count = %d erase_region_size = %d\n",
+		      erase_region_count, erase_region_size);
+		for (j = 0; j < erase_region_count; j++) {
+			if (sector - base >= info->size)
+				break;
+			if (sect_cnt >= CONFIG_SYS_MAX_FLASH_SECT) {
+				printf("ERROR: too many flash sectors\n");
 				break;
 			}
+			info->start[sect_cnt] =
+				(ulong)map_physmem(sector,
+						   info->portwidth,
+						   MAP_NOCACHE);
+			sector += (erase_region_size * size_ratio);
 
-			tmp = le32_to_cpu(get_unaligned(
-						&qry.erase_region_info[i]));
-			debug("erase region %u: 0x%08lx\n", i, tmp);
-
-			erase_region_count = (tmp & 0xffff) + 1;
-			tmp >>= 16;
-			erase_region_size =
-				(tmp & 0xffff) ? ((tmp & 0xffff) * 256) : 128;
-			debug("erase_region_count = %d erase_region_size = %d\n",
-			      erase_region_count, erase_region_size);
-			for (j = 0; j < erase_region_count; j++) {
-				if (sector - base >= info->size)
-					break;
-				if (sect_cnt >= CONFIG_SYS_MAX_FLASH_SECT) {
-					printf("ERROR: too many flash sectors\n");
-					break;
-				}
-				info->start[sect_cnt] =
-					(ulong)map_physmem(sector,
-							   info->portwidth,
-							   MAP_NOCACHE);
-				sector += (erase_region_size * size_ratio);
-
+			/*
+			 * Only read protection status from
+			 * supported devices (intel...)
+			 */
+			switch (info->vendor) {
+			case CFI_CMDSET_INTEL_PROG_REGIONS:
+			case CFI_CMDSET_INTEL_EXTENDED:
+			case CFI_CMDSET_INTEL_STANDARD:
 				/*
-				 * Only read protection status from
-				 * supported devices (intel...)
+				 * Set flash to read-id mode. Otherwise
+				 * reading protected status is not
+				 * guaranteed.
 				 */
-				switch (info->vendor) {
-				case CFI_CMDSET_INTEL_PROG_REGIONS:
-				case CFI_CMDSET_INTEL_EXTENDED:
-				case CFI_CMDSET_INTEL_STANDARD:
-					/*
-					 * Set flash to read-id mode. Otherwise
-					 * reading protected status is not
-					 * guaranteed.
-					 */
-					flash_write_cmd(info, sect_cnt, 0,
-							FLASH_CMD_READ_ID);
-					info->protect[sect_cnt] =
-						flash_isset(info, sect_cnt,
-							    FLASH_OFFSET_PROTECT,
-							    FLASH_STATUS_PROTECT);
-					flash_write_cmd(info, sect_cnt, 0,
-							FLASH_CMD_RESET);
-					break;
-				case CFI_CMDSET_AMD_EXTENDED:
-				case CFI_CMDSET_AMD_STANDARD:
-					if (!info->legacy_unlock) {
-						/* default: not protected */
-						info->protect[sect_cnt] = 0;
-						break;
-					}
-
-					/* Read protection (PPB) from sector */
-					flash_write_cmd(info, 0, 0,
-							info->cmd_reset);
-					flash_unlock_seq(info, 0);
-					flash_write_cmd(info, 0,
-							info->addr_unlock1,
-							FLASH_CMD_READ_ID);
-					info->protect[sect_cnt] =
-						flash_isset(
-							info, sect_cnt,
-							FLASH_OFFSET_PROTECT,
-							FLASH_STATUS_PROTECT);
-					break;
-				default:
+				flash_write_cmd(info, sect_cnt, 0,
+						FLASH_CMD_READ_ID);
+				info->protect[sect_cnt] =
+					flash_isset(info, sect_cnt,
+						    FLASH_OFFSET_PROTECT,
+						    FLASH_STATUS_PROTECT);
+				flash_write_cmd(info, sect_cnt, 0,
+						FLASH_CMD_RESET);
+				break;
+			case CFI_CMDSET_AMD_EXTENDED:
+			case CFI_CMDSET_AMD_STANDARD:
+				if (!info->legacy_unlock) {
 					/* default: not protected */
 					info->protect[sect_cnt] = 0;
+					break;
 				}
 
-				sect_cnt++;
+				/* Read protection (PPB) from sector */
+				flash_write_cmd(info, 0, 0,
+						info->cmd_reset);
+				flash_unlock_seq(info, 0);
+				flash_write_cmd(info, 0,
+						info->addr_unlock1,
+						FLASH_CMD_READ_ID);
+				info->protect[sect_cnt] =
+					flash_isset(
+						info, sect_cnt,
+						FLASH_OFFSET_PROTECT,
+						FLASH_STATUS_PROTECT);
+				break;
+			default:
+				/* default: not protected */
+				info->protect[sect_cnt] = 0;
 			}
-		}
 
-		info->sector_count = sect_cnt;
-		info->buffer_size = 1 << le16_to_cpu(qry.max_buf_write_size);
-		tmp = 1 << qry.block_erase_timeout_typ;
-		info->erase_blk_tout = tmp *
-			(1 << qry.block_erase_timeout_max);
-		tmp = (1 << qry.buf_write_timeout_typ) *
-			(1 << qry.buf_write_timeout_max);
-
-		/* round up when converting to ms */
-		info->buffer_write_tout = (tmp + 999) / 1000;
-		tmp = (1 << qry.word_write_timeout_typ) *
-			(1 << qry.word_write_timeout_max);
-		/* round up when converting to ms */
-		info->write_tout = (tmp + 999) / 1000;
-		info->flash_id = FLASH_MAN_CFI;
-		if ((info->interface == FLASH_CFI_X8X16) &&
-		    (info->chipwidth == FLASH_CFI_BY8)) {
-			/* XXX - Need to test on x8/x16 in parallel. */
-			info->portwidth >>= 1;
+			sect_cnt++;
 		}
+	}
 
-		flash_write_cmd(info, 0, 0, info->cmd_reset);
+	info->sector_count = sect_cnt;
+	info->buffer_size = 1 << le16_to_cpu(qry.max_buf_write_size);
+	tmp = 1 << qry.block_erase_timeout_typ;
+	info->erase_blk_tout = tmp *
+		(1 << qry.block_erase_timeout_max);
+	tmp = (1 << qry.buf_write_timeout_typ) *
+		(1 << qry.buf_write_timeout_max);
+
+	/* round up when converting to ms */
+	info->buffer_write_tout = (tmp + 999) / 1000;
+	tmp = (1 << qry.word_write_timeout_typ) *
+		(1 << qry.word_write_timeout_max);
+	/* round up when converting to ms */
+	info->write_tout = (tmp + 999) / 1000;
+	info->flash_id = FLASH_MAN_CFI;
+	if ((info->interface == FLASH_CFI_X8X16) &&
+	    (info->chipwidth == FLASH_CFI_BY8)) {
+		/* XXX - Need to test on x8/x16 in parallel. */
+		info->portwidth >>= 1;
 	}
 
+	flash_write_cmd(info, 0, 0, info->cmd_reset);
+
 	return info->size;
 }
 
@@ -2375,54 +2378,51 @@ unsigned long flash_init(void)
 			       i + 1, flash_info[i].size,
 			       flash_info[i].size >> 20);
 #endif /* CONFIG_SYS_FLASH_QUIET_TEST */
+			continue;
 		}
 #ifdef CONFIG_SYS_FLASH_PROTECTION
-		else if (strcmp(s, "yes") == 0) {
+		if (strcmp(s, "yes") != 0)
+			continue;
+
+		/*
+		 * Only the U-Boot image and it's environment is protected, all
+		 * other sectors are unprotected (unlocked) if flash hardware
+		 * protection is used (CONFIG_SYS_FLASH_PROTECTION) and the
+		 * environment variable "unlock" is set to "yes".
+		 */
+		if (flash_info[i].legacy_unlock) {
+			int k;
+
 			/*
-			 * Only the U-Boot image and it's environment
-			 * is protected, all other sectors are
-			 * unprotected (unlocked) if flash hardware
-			 * protection is used (CONFIG_SYS_FLASH_PROTECTION)
-			 * and the environment variable "unlock" is
-			 * set to "yes".
+			 * Disable legacy_unlock temporarily, since
+			 * flash_real_protect would relock all other sectors
+			 * again otherwise.
 			 */
-			if (flash_info[i].legacy_unlock) {
-				int k;
+			flash_info[i].legacy_unlock = 0;
 
-				/*
-				 * Disable legacy_unlock temporarily,
-				 * since flash_real_protect would
-				 * relock all other sectors again
-				 * otherwise.
-				 */
-				flash_info[i].legacy_unlock = 0;
+			/*
+			 * Legacy unlocking (e.g. Intel J3) -> unlock only one
+			 * sector. This will unlock all sectors.
+			 */
+			flash_real_protect(&flash_info[i], 0, 0);
 
-				/*
-				 * Legacy unlocking (e.g. Intel J3) ->
-				 * unlock only one sector. This will
-				 * unlock all sectors.
-				 */
-				flash_real_protect(&flash_info[i], 0, 0);
+			flash_info[i].legacy_unlock = 1;
 
-				flash_info[i].legacy_unlock = 1;
+			/*
+			 * Manually mark other sectors as unlocked (unprotected)
+			 */
+			for (k = 1; k < flash_info[i].sector_count; k++)
+				flash_info[i].protect[k] = 0;
 
-				/*
-				 * Manually mark other sectors as
-				 * unlocked (unprotected)
-				 */
-				for (k = 1; k < flash_info[i].sector_count; k++)
-					flash_info[i].protect[k] = 0;
-			} else {
-				/*
-				 * No legancy unlocking -> unlock all sectors
-				 */
-				flash_protect(FLAG_PROTECT_CLEAR,
-					      flash_info[i].start[0],
-					      flash_info[i].start[0]
-					      + flash_info[i].size - 1,
-					      &flash_info[i]);
-			}
+			continue;
 		}
+
+		/*
+		 * No legacy unlocking -> unlock all sectors
+		 */
+		flash_protect(FLAG_PROTECT_CLEAR, flash_info[i].start[0],
+			      flash_info[i].start[0] + flash_info[i].size - 1,
+			      &flash_info[i]);
 #endif /* CONFIG_SYS_FLASH_PROTECTION */
 	}
 
-- 
2.11.0

^ permalink raw reply related	[flat|nested] 138+ messages in thread

* [U-Boot] [PATCH 14/51] cfi_flash: Always define cfi_flash_num_flash_banks
  2017-07-14 12:54 [U-Boot] [PATCH 00/51] gdsys: Add support for Gazerbeam board Mario Six
                   ` (12 preceding siblings ...)
  2017-07-14 12:54 ` [U-Boot] [PATCH 13/51] cfi_flash: Clean up code some more Mario Six
@ 2017-07-14 12:55 ` Mario Six
  2017-07-18 14:02   ` Simon Glass
  2017-07-14 12:55 ` [U-Boot] [PATCH 15/51] gpio: mpc85xx_gpio: Fix style violations Mario Six
                   ` (36 subsequent siblings)
  50 siblings, 1 reply; 138+ messages in thread
From: Mario Six @ 2017-07-14 12:55 UTC (permalink / raw)
  To: u-boot

The variable cfi_flash_num_flash_banks is defined iff
CONFIG_SYS_MAX_FLASH_BANKS_DETECT is defined, but it is used
unconditionally in the function cfi_flash_init_dm. This leads to a
undefined variable compile error when CONFIG_SYS_MAX_FLASH_BANKS_DETECT
is not defined, but DM is enabled.

Fix this by always defining the cfi_flash_num_flash_banks variable.

Signed-off-by: Mario Six <mario.six@gdsys.cc>
---

 drivers/mtd/cfi_flash.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/mtd/cfi_flash.c b/drivers/mtd/cfi_flash.c
index 2445632580..4f9a88e2a3 100644
--- a/drivers/mtd/cfi_flash.c
+++ b/drivers/mtd/cfi_flash.c
@@ -91,6 +91,8 @@ static u16 cfi_flash_config_reg(int i)
 
 #if defined(CONFIG_SYS_MAX_FLASH_BANKS_DETECT)
 int cfi_flash_num_flash_banks = CONFIG_SYS_MAX_FLASH_BANKS_DETECT;
+#else
+int cfi_flash_num_flash_banks;
 #endif
 
 #ifdef CONFIG_CFI_FLASH /* for driver model */
-- 
2.11.0

^ permalink raw reply related	[flat|nested] 138+ messages in thread

* [U-Boot] [PATCH 15/51] gpio: mpc85xx_gpio: Fix style violations
  2017-07-14 12:54 [U-Boot] [PATCH 00/51] gdsys: Add support for Gazerbeam board Mario Six
                   ` (13 preceding siblings ...)
  2017-07-14 12:55 ` [U-Boot] [PATCH 14/51] cfi_flash: Always define cfi_flash_num_flash_banks Mario Six
@ 2017-07-14 12:55 ` Mario Six
  2017-07-18 14:02   ` Simon Glass
  2017-07-14 12:55 ` [U-Boot] [PATCH 16/51] gpio: mpc85xx_gpio: Make compatible with MPC8XXX Mario Six
                   ` (35 subsequent siblings)
  50 siblings, 1 reply; 138+ messages in thread
From: Mario Six @ 2017-07-14 12:55 UTC (permalink / raw)
  To: u-boot

Fix some style violations in the MPC85XX GPIO driver.

Signed-off-by: Mario Six <mario.six@gdsys.cc>
---

 drivers/gpio/mpc85xx_gpio.c | 42 ++++++++++++++++++++++--------------------
 1 file changed, 22 insertions(+), 20 deletions(-)

diff --git a/drivers/gpio/mpc85xx_gpio.c b/drivers/gpio/mpc85xx_gpio.c
index cfeb6e7632..4566c091b7 100644
--- a/drivers/gpio/mpc85xx_gpio.c
+++ b/drivers/gpio/mpc85xx_gpio.c
@@ -34,11 +34,13 @@ struct mpc85xx_gpio_data {
 	uint gpio_count;
 	/* The GPDAT register cannot be used to determine the value of output
 	 * pins on MPC8572/MPC8536, so we shadow it and use the shadowed value
-	 * for output pins */
+	 * for output pins
+	 */
 	u32 dat_shadow;
 };
 
-inline u32 gpio_mask(unsigned gpio) {
+inline u32 gpio_mask(uint gpio)
+{
 	return (1U << (31 - (gpio)));
 }
 
@@ -92,7 +94,7 @@ static inline void mpc85xx_gpio_open_drain_off(struct ccsr_gpio *base,
 	clrbits_be32(&base->gpodr, gpios);
 }
 
-static int mpc85xx_gpio_direction_input(struct udevice *dev, unsigned gpio)
+static int mpc85xx_gpio_direction_input(struct udevice *dev, uint gpio)
 {
 	struct mpc85xx_gpio_data *data = dev_get_priv(dev);
 
@@ -100,8 +102,7 @@ static int mpc85xx_gpio_direction_input(struct udevice *dev, unsigned gpio)
 	return 0;
 }
 
-static int mpc85xx_gpio_set_value(struct udevice *dev, unsigned gpio,
-				  int value)
+static int mpc85xx_gpio_set_value(struct udevice *dev, uint gpio, int value)
 {
 	struct mpc85xx_gpio_data *data = dev_get_priv(dev);
 
@@ -115,46 +116,46 @@ static int mpc85xx_gpio_set_value(struct udevice *dev, unsigned gpio,
 	return 0;
 }
 
-static int mpc85xx_gpio_direction_output(struct udevice *dev, unsigned gpio,
+static int mpc85xx_gpio_direction_output(struct udevice *dev, uint gpio,
 					 int value)
 {
 	return mpc85xx_gpio_set_value(dev, gpio, value);
 }
 
-static int mpc85xx_gpio_get_value(struct udevice *dev, unsigned gpio)
+static int mpc85xx_gpio_get_value(struct udevice *dev, uint gpio)
 {
 	struct mpc85xx_gpio_data *data = dev_get_priv(dev);
 
 	if (!!mpc85xx_gpio_get_dir(data->base, gpio_mask(gpio))) {
 		/* Output -> use shadowed value */
 		return !!(data->dat_shadow & gpio_mask(gpio));
-	} else {
-		/* Input -> read value from GPDAT register */
-		return !!mpc85xx_gpio_get_val(data->base, gpio_mask(gpio));
 	}
+
+	/* Input -> read value from GPDAT register */
+	return !!mpc85xx_gpio_get_val(data->base, gpio_mask(gpio));
 }
 
-static int mpc85xx_gpio_get_open_drain(struct udevice *dev, unsigned gpio)
+static int mpc85xx_gpio_get_open_drain(struct udevice *dev, uint gpio)
 {
 	struct mpc85xx_gpio_data *data = dev_get_priv(dev);
 
 	return !!mpc85xx_gpio_open_drain_val(data->base, gpio_mask(gpio));
 }
 
-static int mpc85xx_gpio_set_open_drain(struct udevice *dev, unsigned gpio,
+static int mpc85xx_gpio_set_open_drain(struct udevice *dev, uint gpio,
 				       int value)
 {
 	struct mpc85xx_gpio_data *data = dev_get_priv(dev);
 
-	if (value) {
+	if (value)
 		mpc85xx_gpio_open_drain_on(data->base, gpio_mask(gpio));
-	} else {
+	else
 		mpc85xx_gpio_open_drain_off(data->base, gpio_mask(gpio));
-	}
+
 	return 0;
 }
 
-static int mpc85xx_gpio_get_function(struct udevice *dev, unsigned gpio)
+static int mpc85xx_gpio_get_function(struct udevice *dev, uint gpio)
 {
 	struct mpc85xx_gpio_data *data = dev_get_priv(dev);
 	int dir;
@@ -164,14 +165,15 @@ static int mpc85xx_gpio_get_function(struct udevice *dev, unsigned gpio)
 }
 
 #if CONFIG_IS_ENABLED(OF_CONTROL)
-static int mpc85xx_gpio_ofdata_to_platdata(struct udevice *dev) {
+static int mpc85xx_gpio_ofdata_to_platdata(struct udevice *dev)
+{
 	struct mpc85xx_gpio_plat *plat = dev_get_platdata(dev);
 	fdt_addr_t addr;
 	fdt_size_t size;
 
 	addr = fdtdec_get_addr_size_auto_noparent(gd->fdt_blob,
-			dev_of_offset(dev), "reg", 0, &size, false);
-
+						  dev_of_offset(dev),
+						  "reg", 0, &size, false);
 	plat->addr = addr;
 	plat->size = size;
 	plat->ngpios = fdtdec_get_int(gd->fdt_blob, dev_of_offset(dev),
@@ -229,7 +231,7 @@ static const struct dm_gpio_ops gpio_mpc85xx_ops = {
 	.set_value		= mpc85xx_gpio_set_value,
 	.get_open_drain		= mpc85xx_gpio_get_open_drain,
 	.set_open_drain		= mpc85xx_gpio_set_open_drain,
-	.get_function 		= mpc85xx_gpio_get_function,
+	.get_function		= mpc85xx_gpio_get_function,
 };
 
 static const struct udevice_id mpc85xx_gpio_ids[] = {
-- 
2.11.0

^ permalink raw reply related	[flat|nested] 138+ messages in thread

* [U-Boot] [PATCH 16/51] gpio: mpc85xx_gpio: Make compatible with MPC8XXX
  2017-07-14 12:54 [U-Boot] [PATCH 00/51] gdsys: Add support for Gazerbeam board Mario Six
                   ` (14 preceding siblings ...)
  2017-07-14 12:55 ` [U-Boot] [PATCH 15/51] gpio: mpc85xx_gpio: Fix style violations Mario Six
@ 2017-07-14 12:55 ` Mario Six
  2017-07-18 14:02   ` Simon Glass
  2017-07-14 12:55 ` [U-Boot] [PATCH 17/51] cmd: mdio: Fix style violations Mario Six
                   ` (34 subsequent siblings)
  50 siblings, 1 reply; 138+ messages in thread
From: Mario Six @ 2017-07-14 12:55 UTC (permalink / raw)
  To: u-boot

Since the GPIO controllers on MPC8XXX just vary in the number of pins
offered, the DM driver for the MPC85XX SoC can be used for the whole
family.

To reflect this, we rename the mpc85xx_gpio driver to the more generic
mpc8xxx_gpio, and add the needed mpc8xxx_gpio_plat structure to the
mpc83xx gpio.h.

Hence, this driver now also serves as a GPIO DM-driver for the MPC83XX
platform.

Signed-off-by: Mario Six <mario.six@gdsys.cc>
---

 arch/powerpc/include/asm/arch-mpc83xx/gpio.h |   8 +
 arch/powerpc/include/asm/arch-mpc85xx/gpio.h |   2 +-
 drivers/gpio/Kconfig                         |   9 +-
 drivers/gpio/Makefile                        |   2 +-
 drivers/gpio/mpc85xx_gpio.c                  | 253 -------------------------
 drivers/gpio/mpc8xxx_gpio.c                  | 274 +++++++++++++++++++++++++++
 6 files changed, 287 insertions(+), 261 deletions(-)
 delete mode 100644 drivers/gpio/mpc85xx_gpio.c
 create mode 100644 drivers/gpio/mpc8xxx_gpio.c

diff --git a/arch/powerpc/include/asm/arch-mpc83xx/gpio.h b/arch/powerpc/include/asm/arch-mpc83xx/gpio.h
index 40ef2151b8..6ec4f00022 100644
--- a/arch/powerpc/include/asm/arch-mpc83xx/gpio.h
+++ b/arch/powerpc/include/asm/arch-mpc83xx/gpio.h
@@ -19,7 +19,15 @@
 
 #define MAX_NUM_GPIOS (32 * MPC83XX_GPIO_CTRLRS)
 
+struct mpc8xxx_gpio_plat {
+       ulong addr;
+       unsigned long size;
+       uint ngpios;
+};
+
+#ifndef DM_GPIO
 void mpc83xx_gpio_init_f(void);
 void mpc83xx_gpio_init_r(void);
+#endif	/* DM_GPIO */
 
 #endif	/* MPC83XX_GPIO_H_ */
diff --git a/arch/powerpc/include/asm/arch-mpc85xx/gpio.h b/arch/powerpc/include/asm/arch-mpc85xx/gpio.h
index 76faa22c8b..b2ba31e623 100644
--- a/arch/powerpc/include/asm/arch-mpc85xx/gpio.h
+++ b/arch/powerpc/include/asm/arch-mpc85xx/gpio.h
@@ -18,7 +18,7 @@
 #include <asm/mpc85xx_gpio.h>
 #endif
 
-struct mpc85xx_gpio_plat {
+struct mpc8xxx_gpio_plat {
 	ulong addr;
 	unsigned long size;
 	uint ngpios;
diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig
index 15135e538d..4e37e2179e 100644
--- a/drivers/gpio/Kconfig
+++ b/drivers/gpio/Kconfig
@@ -239,11 +239,11 @@ config DM_PCA953X
 	  Now, max 24 bits chips and PCA953X compatible chips are
 	  supported
 
-config MPC85XX_GPIO
-	bool "Freescale MPC85XX GPIO driver"
+config MPC8XXX_GPIO
+	bool "Freescale MPC8XXX GPIO driver"
 	depends on DM_GPIO
 	help
-	  This driver supports the built-in GPIO controller of MPC85XX CPUs.
+	  This driver supports the built-in GPIO controller of MPC8XXX CPUs.
 	  Each GPIO bank is identified by its own entry in the device tree,
 	  i.e.
 
@@ -261,7 +261,4 @@ config MPC85XX_GPIO
 	  Aside from the standard functions of input/output mode, and output
 	  value setting, the open-drain feature, which can configure individual
 	  GPIOs to work as open-drain outputs, is supported.
-
-	  The driver has been tested on MPC85XX, but it is likely that other
-	  PowerQUICC III devices will work as well.
 endmenu
diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile
index 8937e99b47..3f38555ab0 100644
--- a/drivers/gpio/Makefile
+++ b/drivers/gpio/Makefile
@@ -37,7 +37,7 @@ obj-$(CONFIG_DA8XX_GPIO)	+= da8xx_gpio.o
 obj-$(CONFIG_DM644X_GPIO)	+= da8xx_gpio.o
 obj-$(CONFIG_ALTERA_PIO)	+= altera_pio.o
 obj-$(CONFIG_MPC83XX_GPIO)	+= mpc83xx_gpio.o
-obj-$(CONFIG_MPC85XX_GPIO)	+= mpc85xx_gpio.o
+obj-$(CONFIG_MPC8XXX_GPIO)	+= mpc8xxx_gpio.o
 obj-$(CONFIG_SH_GPIO_PFC)	+= sh_pfc.o
 obj-$(CONFIG_OMAP_GPIO)	+= omap_gpio.o
 obj-$(CONFIG_DB8500_GPIO)	+= db8500_gpio.o
diff --git a/drivers/gpio/mpc85xx_gpio.c b/drivers/gpio/mpc85xx_gpio.c
deleted file mode 100644
index 4566c091b7..0000000000
--- a/drivers/gpio/mpc85xx_gpio.c
+++ /dev/null
@@ -1,253 +0,0 @@
-/*
- * (C) Copyright 2016
- * Mario Six, Guntermann & Drunck GmbH, six at gdsys.de
- *
- * based on arch/powerpc/include/asm/mpc85xx_gpio.h, which is
- *
- * Copyright 2010 eXMeritus, A Boeing Company
- *
- * SPDX-License-Identifier:	GPL-2.0+
- */
-
-#include <common.h>
-#include <dm.h>
-#include <asm/gpio.h>
-#include <mapmem.h>
-
-DECLARE_GLOBAL_DATA_PTR;
-
-struct ccsr_gpio {
-	u32	gpdir;
-	u32	gpodr;
-	u32	gpdat;
-	u32	gpier;
-	u32	gpimr;
-	u32	gpicr;
-};
-
-struct mpc85xx_gpio_data {
-	/* The bank's register base in memory */
-	struct ccsr_gpio __iomem *base;
-	/* The address of the registers; used to identify the bank */
-	ulong addr;
-	/* The GPIO count of the bank */
-	uint gpio_count;
-	/* The GPDAT register cannot be used to determine the value of output
-	 * pins on MPC8572/MPC8536, so we shadow it and use the shadowed value
-	 * for output pins
-	 */
-	u32 dat_shadow;
-};
-
-inline u32 gpio_mask(uint gpio)
-{
-	return (1U << (31 - (gpio)));
-}
-
-static inline u32 mpc85xx_gpio_get_val(struct ccsr_gpio *base, u32 mask)
-{
-	return in_be32(&base->gpdat) & mask;
-}
-
-static inline u32 mpc85xx_gpio_get_dir(struct ccsr_gpio *base, u32 mask)
-{
-	return in_be32(&base->gpdir) & mask;
-}
-
-static inline void mpc85xx_gpio_set_in(struct ccsr_gpio *base, u32 gpios)
-{
-	clrbits_be32(&base->gpdat, gpios);
-	/* GPDIR register 0 -> input */
-	clrbits_be32(&base->gpdir, gpios);
-}
-
-static inline void mpc85xx_gpio_set_low(struct ccsr_gpio *base, u32 gpios)
-{
-	clrbits_be32(&base->gpdat, gpios);
-	/* GPDIR register 1 -> output */
-	setbits_be32(&base->gpdir, gpios);
-}
-
-static inline void mpc85xx_gpio_set_high(struct ccsr_gpio *base, u32 gpios)
-{
-	setbits_be32(&base->gpdat, gpios);
-	/* GPDIR register 1 -> output */
-	setbits_be32(&base->gpdir, gpios);
-}
-
-static inline int mpc85xx_gpio_open_drain_val(struct ccsr_gpio *base, u32 mask)
-{
-	return in_be32(&base->gpodr) & mask;
-}
-
-static inline void mpc85xx_gpio_open_drain_on(struct ccsr_gpio *base, u32
-					      gpios)
-{
-	/* GPODR register 1 -> open drain on */
-	setbits_be32(&base->gpodr, gpios);
-}
-
-static inline void mpc85xx_gpio_open_drain_off(struct ccsr_gpio *base,
-					       u32 gpios)
-{
-	/* GPODR register 0 -> open drain off (actively driven) */
-	clrbits_be32(&base->gpodr, gpios);
-}
-
-static int mpc85xx_gpio_direction_input(struct udevice *dev, uint gpio)
-{
-	struct mpc85xx_gpio_data *data = dev_get_priv(dev);
-
-	mpc85xx_gpio_set_in(data->base, gpio_mask(gpio));
-	return 0;
-}
-
-static int mpc85xx_gpio_set_value(struct udevice *dev, uint gpio, int value)
-{
-	struct mpc85xx_gpio_data *data = dev_get_priv(dev);
-
-	if (value) {
-		data->dat_shadow |= gpio_mask(gpio);
-		mpc85xx_gpio_set_high(data->base, gpio_mask(gpio));
-	} else {
-		data->dat_shadow &= ~gpio_mask(gpio);
-		mpc85xx_gpio_set_low(data->base, gpio_mask(gpio));
-	}
-	return 0;
-}
-
-static int mpc85xx_gpio_direction_output(struct udevice *dev, uint gpio,
-					 int value)
-{
-	return mpc85xx_gpio_set_value(dev, gpio, value);
-}
-
-static int mpc85xx_gpio_get_value(struct udevice *dev, uint gpio)
-{
-	struct mpc85xx_gpio_data *data = dev_get_priv(dev);
-
-	if (!!mpc85xx_gpio_get_dir(data->base, gpio_mask(gpio))) {
-		/* Output -> use shadowed value */
-		return !!(data->dat_shadow & gpio_mask(gpio));
-	}
-
-	/* Input -> read value from GPDAT register */
-	return !!mpc85xx_gpio_get_val(data->base, gpio_mask(gpio));
-}
-
-static int mpc85xx_gpio_get_open_drain(struct udevice *dev, uint gpio)
-{
-	struct mpc85xx_gpio_data *data = dev_get_priv(dev);
-
-	return !!mpc85xx_gpio_open_drain_val(data->base, gpio_mask(gpio));
-}
-
-static int mpc85xx_gpio_set_open_drain(struct udevice *dev, uint gpio,
-				       int value)
-{
-	struct mpc85xx_gpio_data *data = dev_get_priv(dev);
-
-	if (value)
-		mpc85xx_gpio_open_drain_on(data->base, gpio_mask(gpio));
-	else
-		mpc85xx_gpio_open_drain_off(data->base, gpio_mask(gpio));
-
-	return 0;
-}
-
-static int mpc85xx_gpio_get_function(struct udevice *dev, uint gpio)
-{
-	struct mpc85xx_gpio_data *data = dev_get_priv(dev);
-	int dir;
-
-	dir = !!mpc85xx_gpio_get_dir(data->base, gpio_mask(gpio));
-	return dir ? GPIOF_OUTPUT : GPIOF_INPUT;
-}
-
-#if CONFIG_IS_ENABLED(OF_CONTROL)
-static int mpc85xx_gpio_ofdata_to_platdata(struct udevice *dev)
-{
-	struct mpc85xx_gpio_plat *plat = dev_get_platdata(dev);
-	fdt_addr_t addr;
-	fdt_size_t size;
-
-	addr = fdtdec_get_addr_size_auto_noparent(gd->fdt_blob,
-						  dev_of_offset(dev),
-						  "reg", 0, &size, false);
-	plat->addr = addr;
-	plat->size = size;
-	plat->ngpios = fdtdec_get_int(gd->fdt_blob, dev_of_offset(dev),
-				      "ngpios", 32);
-
-	return 0;
-}
-#endif
-
-static int mpc85xx_gpio_platdata_to_priv(struct udevice *dev)
-{
-	struct mpc85xx_gpio_data *priv = dev_get_priv(dev);
-	struct mpc85xx_gpio_plat *plat = dev_get_platdata(dev);
-	unsigned long size = plat->size;
-
-	if (size == 0)
-		size = 0x100;
-
-	priv->addr = plat->addr;
-	priv->base = map_sysmem(CONFIG_SYS_IMMR + plat->addr, size);
-
-	if (!priv->base)
-		return -ENOMEM;
-
-	priv->gpio_count = plat->ngpios;
-	priv->dat_shadow = 0;
-
-	return 0;
-}
-
-static int mpc85xx_gpio_probe(struct udevice *dev)
-{
-	struct gpio_dev_priv *uc_priv = dev_get_uclass_priv(dev);
-	struct mpc85xx_gpio_data *data = dev_get_priv(dev);
-	char name[32], *str;
-
-	mpc85xx_gpio_platdata_to_priv(dev);
-
-	snprintf(name, sizeof(name), "MPC@%lx_", data->addr);
-	str = strdup(name);
-
-	if (!str)
-		return -ENOMEM;
-
-	uc_priv->bank_name = str;
-	uc_priv->gpio_count = data->gpio_count;
-
-	return 0;
-}
-
-static const struct dm_gpio_ops gpio_mpc85xx_ops = {
-	.direction_input	= mpc85xx_gpio_direction_input,
-	.direction_output	= mpc85xx_gpio_direction_output,
-	.get_value		= mpc85xx_gpio_get_value,
-	.set_value		= mpc85xx_gpio_set_value,
-	.get_open_drain		= mpc85xx_gpio_get_open_drain,
-	.set_open_drain		= mpc85xx_gpio_set_open_drain,
-	.get_function		= mpc85xx_gpio_get_function,
-};
-
-static const struct udevice_id mpc85xx_gpio_ids[] = {
-	{ .compatible = "fsl,pq3-gpio" },
-	{ /* sentinel */ }
-};
-
-U_BOOT_DRIVER(gpio_mpc85xx) = {
-	.name	= "gpio_mpc85xx",
-	.id	= UCLASS_GPIO,
-	.ops	= &gpio_mpc85xx_ops,
-#if CONFIG_IS_ENABLED(OF_CONTROL)
-	.ofdata_to_platdata = mpc85xx_gpio_ofdata_to_platdata,
-	.platdata_auto_alloc_size = sizeof(struct mpc85xx_gpio_plat),
-	.of_match = mpc85xx_gpio_ids,
-#endif
-	.probe	= mpc85xx_gpio_probe,
-	.priv_auto_alloc_size = sizeof(struct mpc85xx_gpio_data),
-};
diff --git a/drivers/gpio/mpc8xxx_gpio.c b/drivers/gpio/mpc8xxx_gpio.c
new file mode 100644
index 0000000000..0aa72ecd9f
--- /dev/null
+++ b/drivers/gpio/mpc8xxx_gpio.c
@@ -0,0 +1,274 @@
+/*
+ * (C) Copyright 2016
+ * Mario Six, Guntermann & Drunck GmbH, six at gdsys.de
+ *
+ * based on arch/powerpc/include/asm/mpc85xx_gpio.h, which is
+ *
+ * Copyright 2010 eXMeritus, A Boeing Company
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <mapmem.h>
+#include <asm/gpio.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+struct ccsr_gpio {
+	u32	gpdir;
+	u32	gpodr;
+	u32	gpdat;
+	u32	gpier;
+	u32	gpimr;
+	u32	gpicr;
+};
+
+struct mpc8xxx_gpio_data {
+	/* The bank's register base in memory */
+	struct ccsr_gpio __iomem *base;
+	/* The address of the registers; used to identify the bank */
+	ulong addr;
+	/* The GPIO count of the bank */
+	uint gpio_count;
+	/* The GPDAT register cannot be used to determine the value of output
+	 * pins on MPC8572/MPC8536, so we shadow it and use the shadowed value
+	 * for output pins
+	 */
+	u32 dat_shadow;
+	ulong type;
+};
+
+enum {
+	MPC8XXX_GPIO_TYPE,
+	MPC5121_GPIO_TYPE,
+};
+
+inline u32 gpio_mask(uint gpio)
+{
+	return (1U << (31 - (gpio)));
+}
+
+static inline u32 mpc8xxx_gpio_get_val(struct ccsr_gpio *base, u32 mask)
+{
+	return in_be32(&base->gpdat) & mask;
+}
+
+static inline u32 mpc8xxx_gpio_get_dir(struct ccsr_gpio *base, u32 mask)
+{
+	return in_be32(&base->gpdir) & mask;
+}
+
+static inline void mpc8xxx_gpio_set_in(struct ccsr_gpio *base, u32 gpios)
+{
+	clrbits_be32(&base->gpdat, gpios);
+	/* GPDIR register 0 -> input */
+	clrbits_be32(&base->gpdir, gpios);
+}
+
+static inline void mpc8xxx_gpio_set_low(struct ccsr_gpio *base, u32 gpios)
+{
+	clrbits_be32(&base->gpdat, gpios);
+	/* GPDIR register 1 -> output */
+	setbits_be32(&base->gpdir, gpios);
+}
+
+static inline void mpc8xxx_gpio_set_high(struct ccsr_gpio *base, u32 gpios)
+{
+	setbits_be32(&base->gpdat, gpios);
+	/* GPDIR register 1 -> output */
+	setbits_be32(&base->gpdir, gpios);
+}
+
+static inline int mpc8xxx_gpio_open_drain_val(struct ccsr_gpio *base, u32 mask)
+{
+	return in_be32(&base->gpodr) & mask;
+}
+
+static inline void mpc8xxx_gpio_open_drain_on(struct ccsr_gpio *base, u32
+					      gpios)
+{
+	/* GPODR register 1 -> open drain on */
+	setbits_be32(&base->gpodr, gpios);
+}
+
+static inline void mpc8xxx_gpio_open_drain_off(struct ccsr_gpio *base,
+					       u32 gpios)
+{
+	/* GPODR register 0 -> open drain off (actively driven) */
+	clrbits_be32(&base->gpodr, gpios);
+}
+
+static int mpc8xxx_gpio_direction_input(struct udevice *dev, uint gpio)
+{
+	struct mpc8xxx_gpio_data *data = dev_get_priv(dev);
+
+	mpc8xxx_gpio_set_in(data->base, gpio_mask(gpio));
+	return 0;
+}
+
+static int mpc8xxx_gpio_set_value(struct udevice *dev, uint gpio, int value)
+{
+	struct mpc8xxx_gpio_data *data = dev_get_priv(dev);
+
+	if (value) {
+		data->dat_shadow |= gpio_mask(gpio);
+		mpc8xxx_gpio_set_high(data->base, gpio_mask(gpio));
+	} else {
+		data->dat_shadow &= ~gpio_mask(gpio);
+		mpc8xxx_gpio_set_low(data->base, gpio_mask(gpio));
+	}
+	return 0;
+}
+
+static int mpc8xxx_gpio_direction_output(struct udevice *dev, uint gpio,
+					 int value)
+{
+	struct mpc8xxx_gpio_data *data = dev_get_priv(dev);
+
+	/* GPIO 28..31 are input only on MPC5121 */
+	if (data->type == MPC5121_GPIO_TYPE && gpio >= 28)
+		return -EINVAL;
+
+	return mpc8xxx_gpio_set_value(dev, gpio, value);
+}
+
+static int mpc8xxx_gpio_get_value(struct udevice *dev, uint gpio)
+{
+	struct mpc8xxx_gpio_data *data = dev_get_priv(dev);
+
+	if (!!mpc8xxx_gpio_get_dir(data->base, gpio_mask(gpio))) {
+		/* Output -> use shadowed value */
+		return !!(data->dat_shadow & gpio_mask(gpio));
+	}
+
+	/* Input -> read value from GPDAT register */
+	return !!mpc8xxx_gpio_get_val(data->base, gpio_mask(gpio));
+}
+
+static int mpc8xxx_gpio_get_open_drain(struct udevice *dev, uint gpio)
+{
+	struct mpc8xxx_gpio_data *data = dev_get_priv(dev);
+
+	return !!mpc8xxx_gpio_open_drain_val(data->base, gpio_mask(gpio));
+}
+
+static int mpc8xxx_gpio_set_open_drain(struct udevice *dev, uint gpio,
+				       int value)
+{
+	struct mpc8xxx_gpio_data *data = dev_get_priv(dev);
+
+	if (value)
+		mpc8xxx_gpio_open_drain_on(data->base, gpio_mask(gpio));
+	else
+		mpc8xxx_gpio_open_drain_off(data->base, gpio_mask(gpio));
+
+	return 0;
+}
+
+static int mpc8xxx_gpio_get_function(struct udevice *dev, uint gpio)
+{
+	struct mpc8xxx_gpio_data *data = dev_get_priv(dev);
+	int dir;
+
+	dir = !!mpc8xxx_gpio_get_dir(data->base, gpio_mask(gpio));
+	return dir ? GPIOF_OUTPUT : GPIOF_INPUT;
+}
+
+#if CONFIG_IS_ENABLED(OF_CONTROL)
+static int mpc8xxx_gpio_ofdata_to_platdata(struct udevice *dev)
+{
+	struct mpc8xxx_gpio_plat *plat = dev_get_platdata(dev);
+	fdt_addr_t addr;
+	fdt_size_t size;
+
+	addr = fdtdec_get_addr_size_auto_noparent(gd->fdt_blob,
+						  dev_of_offset(dev),
+						  "reg", 0, &size, false);
+	plat->addr = addr;
+	plat->size = size;
+	plat->ngpios = fdtdec_get_int(gd->fdt_blob, dev_of_offset(dev),
+				      "ngpios", 32);
+
+	return 0;
+}
+#endif
+
+static int mpc8xxx_gpio_platdata_to_priv(struct udevice *dev)
+{
+	struct mpc8xxx_gpio_data *priv = dev_get_priv(dev);
+	struct mpc8xxx_gpio_plat *plat = dev_get_platdata(dev);
+	unsigned long size = plat->size;
+	ulong driver_data = dev_get_driver_data(dev);
+
+	if (size == 0)
+		size = 0x100;
+
+	priv->addr = plat->addr;
+	priv->base = map_sysmem(CONFIG_SYS_IMMR + plat->addr, size);
+
+	if (!priv->base)
+		return -ENOMEM;
+
+	priv->gpio_count = plat->ngpios;
+	priv->dat_shadow = 0;
+
+	priv->type = driver_data;
+
+	return 0;
+}
+
+static int mpc8xxx_gpio_probe(struct udevice *dev)
+{
+	struct gpio_dev_priv *uc_priv = dev_get_uclass_priv(dev);
+	struct mpc8xxx_gpio_data *data = dev_get_priv(dev);
+	char name[32], *str;
+
+	mpc8xxx_gpio_platdata_to_priv(dev);
+
+	snprintf(name, sizeof(name), "MPC@%lx_", data->addr);
+	str = strdup(name);
+
+	if (!str)
+		return -ENOMEM;
+
+	uc_priv->bank_name = str;
+	uc_priv->gpio_count = data->gpio_count;
+
+	return 0;
+}
+
+static const struct dm_gpio_ops gpio_mpc8xxx_ops = {
+	.direction_input	= mpc8xxx_gpio_direction_input,
+	.direction_output	= mpc8xxx_gpio_direction_output,
+	.get_value		= mpc8xxx_gpio_get_value,
+	.set_value		= mpc8xxx_gpio_set_value,
+	.get_open_drain		= mpc8xxx_gpio_get_open_drain,
+	.set_open_drain		= mpc8xxx_gpio_set_open_drain,
+	.get_function		= mpc8xxx_gpio_get_function,
+};
+
+static const struct udevice_id mpc8xxx_gpio_ids[] = {
+	{ .compatible = "fsl,pq3-gpio", .data = MPC8XXX_GPIO_TYPE },
+	{ .compatible = "fsl,mpc8308-gpio", .data = MPC8XXX_GPIO_TYPE },
+	{ .compatible = "fsl,mpc8349-gpio", .data = MPC8XXX_GPIO_TYPE },
+	{ .compatible = "fsl,mpc8572-gpio", .data = MPC8XXX_GPIO_TYPE},
+	{ .compatible = "fsl,mpc8610-gpio", .data = MPC8XXX_GPIO_TYPE},
+	{ .compatible = "fsl,mpc5121-gpio", .data = MPC5121_GPIO_TYPE, },
+	{ .compatible = "fsl,qoriq-gpio", .data = MPC8XXX_GPIO_TYPE },
+	{ /* sentinel */ }
+};
+
+U_BOOT_DRIVER(gpio_mpc8xxx) = {
+	.name	= "gpio_mpc8xxx",
+	.id	= UCLASS_GPIO,
+	.ops	= &gpio_mpc8xxx_ops,
+#if CONFIG_IS_ENABLED(OF_CONTROL)
+	.ofdata_to_platdata = mpc8xxx_gpio_ofdata_to_platdata,
+	.platdata_auto_alloc_size = sizeof(struct mpc8xxx_gpio_plat),
+	.of_match = mpc8xxx_gpio_ids,
+#endif
+	.probe	= mpc8xxx_gpio_probe,
+	.priv_auto_alloc_size = sizeof(struct mpc8xxx_gpio_data),
+};
-- 
2.11.0

^ permalink raw reply related	[flat|nested] 138+ messages in thread

* [U-Boot] [PATCH 17/51] cmd: mdio: Fix style violations
  2017-07-14 12:54 [U-Boot] [PATCH 00/51] gdsys: Add support for Gazerbeam board Mario Six
                   ` (15 preceding siblings ...)
  2017-07-14 12:55 ` [U-Boot] [PATCH 16/51] gpio: mpc85xx_gpio: Make compatible with MPC8XXX Mario Six
@ 2017-07-14 12:55 ` Mario Six
  2017-07-18 14:02   ` Simon Glass
  2017-07-14 12:55 ` [U-Boot] [PATCH 18/51] cmd: mdio: Add 'driver' subcommand Mario Six
                   ` (33 subsequent siblings)
  50 siblings, 1 reply; 138+ messages in thread
From: Mario Six @ 2017-07-14 12:55 UTC (permalink / raw)
  To: u-boot

Fix some style violations in the MDIO command.

Signed-off-by: Mario Six <mario.six@gdsys.cc>
---

 cmd/mdio.c | 7 +++----
 1 file changed, 3 insertions(+), 4 deletions(-)

diff --git a/cmd/mdio.c b/cmd/mdio.c
index 21dc103736..3f11963006 100644
--- a/cmd/mdio.c
+++ b/cmd/mdio.c
@@ -14,7 +14,6 @@
 #include <miiphy.h>
 #include <phy.h>
 
-
 static char last_op[2];
 static uint last_data;
 static uint last_addr_lo;
@@ -243,13 +242,13 @@ static int do_mdio(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
 	case 'r':
 		if (pos > 1)
 			if (extract_reg_range(argv[pos--], &devadlo, &devadhi,
-					&reglo, &reghi))
+					      &reglo, &reghi))
 				return -1;
 
 	default:
 		if (pos > 1)
-			if (extract_phy_range(&(argv[2]), pos - 1, &bus,
-					&phydev, &addrlo, &addrhi))
+			if (extract_phy_range(&argv[2], pos - 1, &bus,
+					      &phydev, &addrlo, &addrhi))
 				return -1;
 
 		break;
-- 
2.11.0

^ permalink raw reply related	[flat|nested] 138+ messages in thread

* [U-Boot] [PATCH 18/51] cmd: mdio: Add 'driver' subcommand
  2017-07-14 12:54 [U-Boot] [PATCH 00/51] gdsys: Add support for Gazerbeam board Mario Six
                   ` (16 preceding siblings ...)
  2017-07-14 12:55 ` [U-Boot] [PATCH 17/51] cmd: mdio: Fix style violations Mario Six
@ 2017-07-14 12:55 ` Mario Six
  2017-07-18 14:02   ` Simon Glass
  2017-07-14 12:55 ` [U-Boot] [PATCH 19/51] common: board_f: Fix style violations Mario Six
                   ` (32 subsequent siblings)
  50 siblings, 1 reply; 138+ messages in thread
From: Mario Six @ 2017-07-14 12:55 UTC (permalink / raw)
  To: u-boot

For debug purposes it is sometimes useful to have the ability to
interact with the driver functionality of a phy from the command line
(e.g. to manually issue startup, configuration, or shutdown commands to
the phy device).

This patch adds such a command, which allows issuing the following
commands to a phy:
 * getting the driver's name
 * running the phy's configuration procedure (via calling phy_config)
 * running the phy's startup procedure (via calling phy_startup)
 * running the phy's shutdown procedure (via calling phy_shutdown)

Signed-off-by: Mario Six <mario.six@gdsys.cc>
---

 cmd/Kconfig |  6 ++++++
 cmd/mdio.c  | 65 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 71 insertions(+)

diff --git a/cmd/Kconfig b/cmd/Kconfig
index 322e466313..6425c425d6 100644
--- a/cmd/Kconfig
+++ b/cmd/Kconfig
@@ -835,6 +835,12 @@ config CMD_MII
 	help
 	  Enable MII utility commands.
 
+config CMD_MII_DRIVER
+	bool "mii driver"
+	depends on CMD_MII
+	help
+	  Enable MII driver utility command.
+
 config CMD_PING
 	bool "ping"
 	help
diff --git a/cmd/mdio.c b/cmd/mdio.c
index 3f11963006..abd763ef1c 100644
--- a/cmd/mdio.c
+++ b/cmd/mdio.c
@@ -180,6 +180,37 @@ static int extract_phy_range(char *const argv[], int argc, struct mii_dev **bus,
 	return extract_range(argv[0], addrlo, addrhi);
 }
 
+#ifdef CONFIG_CMD_MII_DRIVER
+static struct phy_device *extract_phydev(char *const argv[], int argc)
+{
+	struct phy_device *phydev;
+	struct mii_dev *bus;
+	int addr;
+
+	if (argc == 1) {
+		phydev = mdio_phydev_for_ethname(argv[0]);
+
+		if (phydev)
+			return phydev;
+
+		bus = mdio_get_current_dev();
+	} else {
+		bus = miiphy_get_dev_by_name(argv[0]);
+	}
+
+	if (!bus)
+		return NULL;
+
+	addr = simple_strtol(argv[1], NULL, 0);
+	if (addr >= PHY_MAX_ADDR)
+		return NULL;
+
+	phydev = bus->phymap[addr];
+
+	return phydev;
+}
+#endif
+
 /* ---------------------------------------------------------------- */
 static int do_mdio(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
 {
@@ -212,6 +243,36 @@ static int do_mdio(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
 	if (flag & CMD_FLAG_REPEAT)
 		op[0] = last_op[0];
 
+#ifdef CONFIG_CMD_MII_DRIVER
+	if (op[0] == 'd') {
+		if ((argc < 4) || (argc > 5) || (strlen(argv[2]) < 2))
+			return CMD_RET_USAGE;
+
+		phydev = extract_phydev(&argv[3], argc - 3);
+		if (!phydev)
+			return CMD_RET_USAGE;
+
+		switch (argv[2][1]) {
+		case 'e': /* g'e't */
+			printf("driver: ");
+			if (phydev->drv)
+				printf("%s", phydev->drv->name);
+			printf("\n");
+			break;
+		case 'o': /* c'o'nfig */
+			phy_config(phydev);
+			break;
+		case 't': /* s't'artup */
+			phy_startup(phydev);
+			break;
+		case 'h': /* s'h'utdown */
+			phy_shutdown(phydev);
+			break;
+		}
+		return 0;
+	}
+#endif
+
 	if (strlen(argv[1]) > 1) {
 		op[1] = argv[1][1];
 		if (op[1] == 'x') {
@@ -304,6 +365,10 @@ U_BOOT_CMD(
 		"read PHY's extended register at <devad>.<reg>\n"
 	"mdio wx <phydev> [<devad>.]<reg> <data> - "
 		"write PHY's extended register at <devad>.<reg>\n"
+#ifdef CONFIG_CMD_MII_DRIVER
+	"mdio driver <get | config | startup | shutdown> <phydev> - "
+		"<get | config | startup | shutdown> phy driver\n"
+#endif
 	"<phydev> may be:\n"
 	"   <busname>  <addr>\n"
 	"   <addr>\n"
-- 
2.11.0

^ permalink raw reply related	[flat|nested] 138+ messages in thread

* [U-Boot] [PATCH 19/51] common: board_f: Fix style violations
  2017-07-14 12:54 [U-Boot] [PATCH 00/51] gdsys: Add support for Gazerbeam board Mario Six
                   ` (17 preceding siblings ...)
  2017-07-14 12:55 ` [U-Boot] [PATCH 18/51] cmd: mdio: Add 'driver' subcommand Mario Six
@ 2017-07-14 12:55 ` Mario Six
  2017-07-18 14:02   ` Simon Glass
  2017-07-14 12:55 ` [U-Boot] [PATCH 20/51] common: board_r: " Mario Six
                   ` (31 subsequent siblings)
  50 siblings, 1 reply; 138+ messages in thread
From: Mario Six @ 2017-07-14 12:55 UTC (permalink / raw)
  To: u-boot

Fix some style violations in the board_f file.

Signed-off-by: Mario Six <mario.six@gdsys.cc>
---

 common/board_f.c | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/common/board_f.c b/common/board_f.c
index ffa84e3566..b258a1a73c 100644
--- a/common/board_f.c
+++ b/common/board_f.c
@@ -50,7 +50,7 @@
 #ifdef XTRN_DECLARE_GLOBAL_DATA_PTR
 #undef	XTRN_DECLARE_GLOBAL_DATA_PTR
 #define XTRN_DECLARE_GLOBAL_DATA_PTR	/* empty = allocate here */
-DECLARE_GLOBAL_DATA_PTR = (gd_t *) (CONFIG_SYS_INIT_GD_ADDR);
+DECLARE_GLOBAL_DATA_PTR = (gd_t *)(CONFIG_SYS_INIT_GD_ADDR);
 #else
 DECLARE_GLOBAL_DATA_PTR;
 #endif
@@ -137,7 +137,7 @@ static int display_text_info(void)
 #endif
 
 	debug("U-Boot code: %08lX -> %08lX  BSS: -> %08lX\n",
-		text_base, bss_start, bss_end);
+	      text_base, bss_start, bss_end);
 #endif
 
 	return 0;
@@ -311,7 +311,7 @@ static int reserve_logbuffer(void)
 	/* reserve kernel log buffer */
 	gd->relocaddr -= LOGBUFF_RESERVE;
 	debug("Reserving %dk for kernel logbuffer at %08lx\n", LOGBUFF_LEN,
-		gd->relocaddr);
+	      gd->relocaddr);
 #endif
 
 	return 0;
@@ -436,7 +436,7 @@ static int reserve_malloc(void)
 {
 	gd->start_addr_sp = gd->start_addr_sp - TOTAL_MALLOC_LEN;
 	debug("Reserving %dk for malloc() at: %08lx\n",
-			TOTAL_MALLOC_LEN >> 10, gd->start_addr_sp);
+	      TOTAL_MALLOC_LEN >> 10, gd->start_addr_sp);
 	return 0;
 }
 
@@ -466,7 +466,7 @@ static int reserve_global_data(void)
 	gd->start_addr_sp -= sizeof(gd_t);
 	gd->new_gd = (gd_t *)map_sysmem(gd->start_addr_sp, sizeof(gd_t));
 	debug("Reserving %zu Bytes for Global Data at: %08lx\n",
-			sizeof(gd_t), gd->start_addr_sp);
+	      sizeof(gd_t), gd->start_addr_sp);
 	return 0;
 }
 
-- 
2.11.0

^ permalink raw reply related	[flat|nested] 138+ messages in thread

* [U-Boot] [PATCH 20/51] common: board_r: Fix style violations
  2017-07-14 12:54 [U-Boot] [PATCH 00/51] gdsys: Add support for Gazerbeam board Mario Six
                   ` (18 preceding siblings ...)
  2017-07-14 12:55 ` [U-Boot] [PATCH 19/51] common: board_f: Fix style violations Mario Six
@ 2017-07-14 12:55 ` Mario Six
  2017-07-18 14:02   ` Simon Glass
  2017-07-14 12:55 ` [U-Boot] [PATCH 21/51] common: Extend board-specific DT fixup Mario Six
                   ` (30 subsequent siblings)
  50 siblings, 1 reply; 138+ messages in thread
From: Mario Six @ 2017-07-14 12:55 UTC (permalink / raw)
  To: u-boot

Fix some style violations in the board_r file.

Signed-off-by: Mario Six <mario.six@gdsys.cc>
---

 common/board_r.c | 27 ++++++++++++++-------------
 1 file changed, 14 insertions(+), 13 deletions(-)

diff --git a/common/board_r.c b/common/board_r.c
index ecca1edb04..199cadbed1 100644
--- a/common/board_r.c
+++ b/common/board_r.c
@@ -161,9 +161,9 @@ static int initr_reloc_global_data(void)
 #endif
 #ifdef CONFIG_OF_EMBED
 	/*
-	* The fdt_blob needs to be moved to new relocation address
-	* incase of FDT blob is embedded with in image
-	*/
+	 * The fdt_blob needs to be moved to new relocation address
+	 * incase of FDT blob is embedded with in image
+	 */
 	gd->fdt_blob += gd->reloc_off;
 #endif
 #ifdef CONFIG_EFI_LOADER
@@ -368,14 +368,16 @@ static int initr_flash(void)
 	print_size(flash_size, "");
 #ifdef CONFIG_SYS_FLASH_CHECKSUM
 	/*
-	* Compute and print flash CRC if flashchecksum is set to 'y'
-	*
-	* NOTE: Maybe we should add some WATCHDOG_RESET()? XXX
-	*/
+	 * Compute and print flash CRC if flashchecksum is set to 'y'
+	 *
+	 * NOTE: Maybe we should add some WATCHDOG_RESET()? XXX
+	 */
 	if (getenv_yesno("flashchecksum") == 1) {
+		const uchar flash_base = CONFIG_SYS_FLASH_BASE;
+
 		printf("  CRC: %08X", crc32(0,
-			(const unsigned char *) CONFIG_SYS_FLASH_BASE,
-			flash_size));
+					    flash_base,
+					    flash_size));
 	}
 #endif /* CONFIG_SYS_FLASH_CHECKSUM */
 	putc('\n');
@@ -392,7 +394,6 @@ static int initr_flash(void)
 	update_flash_size(flash_size);
 #endif
 
-
 #if defined(CONFIG_OXC) || defined(CONFIG_RMU)
 	/* flash mapped at end of memory map */
 	bd->bi_flashoffset = CONFIG_SYS_TEXT_BASE + flash_size;
@@ -657,7 +658,7 @@ int initr_mem(void)
 	/* Also take the logbuffer into account (pram is in kB) */
 	pram += (LOGBUFF_LEN + LOGBUFF_OVERHEAD) / 1024;
 # endif
-	sprintf(memsz, "%ldk", (long int) ((gd->ram_size / 1024) - pram));
+	sprintf(memsz, "%ldk", (long int)((gd->ram_size / 1024) - pram));
 	setenv("mem", memsz);
 
 	return 0;
@@ -710,7 +711,7 @@ static init_fnc_t init_sequence_r[] = {
 	initr_caches,
 	/* Note: For Freescale LS2 SoCs, new MMU table is created in DDR.
 	 *	 A temporary mapping of IFC high region is since removed,
-	 *	 so environmental variables in NOR flash is not availble
+	 *	 so environmental variables in NOR flash is not available
 	 *	 until board_init() is called below to remap IFC to high
 	 *	 region.
 	 */
@@ -775,7 +776,7 @@ static init_fnc_t init_sequence_r[] = {
 #if defined(CONFIG_PCI) && defined(CONFIG_SYS_EARLY_PCI_INIT)
 	/*
 	 * Do early PCI configuration _before_ the flash gets initialised,
-	 * because PCU ressources are crucial for flash access on some boards.
+	 * because PCU resources are crucial for flash access on some boards.
 	 */
 	initr_pci,
 #endif
-- 
2.11.0

^ permalink raw reply related	[flat|nested] 138+ messages in thread

* [U-Boot] [PATCH 21/51] common: Extend board-specific DT fixup
  2017-07-14 12:54 [U-Boot] [PATCH 00/51] gdsys: Add support for Gazerbeam board Mario Six
                   ` (19 preceding siblings ...)
  2017-07-14 12:55 ` [U-Boot] [PATCH 20/51] common: board_r: " Mario Six
@ 2017-07-14 12:55 ` Mario Six
  2017-07-19  9:05   ` Simon Glass
  2017-07-14 12:55 ` [U-Boot] [PATCH 22/51] gdsys: mpc8308: Fix style violations Mario Six
                   ` (29 subsequent siblings)
  50 siblings, 1 reply; 138+ messages in thread
From: Mario Six @ 2017-07-14 12:55 UTC (permalink / raw)
  To: u-boot

Commit 2a79275 ("dm: Add callback to modify the device tree")
implemented a board-specific callback that can modify U-Boot's device
tree before relocation to accomodate a range of hardware variations of
certain boards.

However, this approach only turns out to be useful when the copy of the
device tree before relocation is actually writeable. If e.g. a device
boots out of a NOR flash, this scheme does not work, since the
modification of the flash's contents is not possible, and the unmodified
device tree is relocated and used by U-Boot.

To circumvent this problem, we split the modification process into two
phases.

In phase one we only collect information about the board by querying the
hardware (reading GPIO values, probing I2C chips, etc.), and store the
obtained information in a special, board-specific structure that is part
of the global data structure. This phase runs prior to relocation, and
utilizes the pre-relocation DM to query hardware information.

In phase two, we read the information back from the structure, and do
the actual manipulation of the device tree. This phase occurs *after*
the relocation of the U-Boot image, but before the driver model is
initialized from the device tree. Since the device tree lives in RAM
alongside the U-Boot image after relocation, the tree is definitely
writeable at this point.

Each phase is implemented by a board-specific callback function: phase
one by board_fix_fdt_get_info, which takes no arguments, and phase two
by board_fix_fdt_change, which takes the writeable device tree blob as
its sole argument. Since the structure where the gathered hardware
information is stored is necessarily board-dependent, we create a
include file where the boards utilizing the functionality can define
their individually needed structures.

This commit also adapts the controlcenterdc board's fixup function to
the new scheme.

Signed-off-by: Mario Six <mario.six@gdsys.cc>
---

 board/gdsys/a38x/controlcenterdc.c |  20 +++++-
 common/board_f.c                   |   6 +-
 common/board_r.c                   |  10 +++
 doc/driver-model/fdt-fixup.txt     | 129 ++++++++++++++++++++++++-------------
 include/asm-generic/global_data.h  |   7 ++
 include/common.h                   |   3 +-
 include/fdt_fixup.h                |   5 ++
 7 files changed, 130 insertions(+), 50 deletions(-)
 create mode 100644 include/fdt_fixup.h

diff --git a/board/gdsys/a38x/controlcenterdc.c b/board/gdsys/a38x/controlcenterdc.c
index 32168d3576..05e18bac4c 100644
--- a/board/gdsys/a38x/controlcenterdc.c
+++ b/board/gdsys/a38x/controlcenterdc.c
@@ -236,7 +236,7 @@ int board_late_init(void)
 	return 0;
 }
 
-int board_fix_fdt(void *rw_fdt_blob)
+int board_fix_fdt_get_info(void)
 {
 	struct udevice *bus = NULL;
 	uint k;
@@ -254,7 +254,23 @@ int board_fix_fdt(void *rw_fdt_blob)
 		snprintf(name, 64,
 			 "/soc/internal-regs/i2c at 11000/pca9698@%02x", k);
 
-		if (!dm_i2c_simple_probe(bus, k))
+		gd->board_fixup_data.chip_exists[k - 0x21] = dm_i2c_simple_probe(bus, k);
+	}
+
+	return 0;
+}
+
+int board_fix_fdt_change(void *rw_fdt_blob)
+{
+	struct of_board_fixup_data data = gd->board_fixup_data;
+	uint k;
+	char name[64];
+
+	for (k = 0x21; k <= 0x26; k++) {
+		snprintf(name, 64,
+			 "/soc/internal-regs/i2c@11000/pca9698@%02x", k);
+
+		if (!data.chip_exists[k - 0x21])
 			fdt_disable_by_ofname(rw_fdt_blob, name);
 	}
 
diff --git a/common/board_f.c b/common/board_f.c
index b258a1a73c..b835bd22bc 100644
--- a/common/board_f.c
+++ b/common/board_f.c
@@ -660,9 +660,9 @@ static int setup_reloc(void)
 }
 
 #ifdef CONFIG_OF_BOARD_FIXUP
-static int fix_fdt(void)
+static int fix_fdt_get_info(void)
 {
-	return board_fix_fdt((void *)gd->fdt_blob);
+	return board_fix_fdt_get_info();
 }
 #endif
 
@@ -887,7 +887,7 @@ static const init_fnc_t init_sequence_f[] = {
 #endif
 	display_new_sp,
 #ifdef CONFIG_OF_BOARD_FIXUP
-	fix_fdt,
+	fix_fdt_get_info,
 #endif
 	INIT_FUNC_WATCHDOG_RESET
 	reloc_fdt,
diff --git a/common/board_r.c b/common/board_r.c
index 199cadbed1..25f27f0843 100644
--- a/common/board_r.c
+++ b/common/board_r.c
@@ -694,6 +694,13 @@ static int run_main_loop(void)
 	return 0;
 }
 
+#ifdef CONFIG_OF_BOARD_FIXUP
+static int fix_fdt_change(void)
+{
+	return board_fix_fdt_change((void *)gd->fdt_blob);
+}
+#endif
+
 /*
  * Over time we hope to remove these functions with code fragments and
  * stub funtcions, and instead call the relevant function directly.
@@ -731,6 +738,9 @@ static init_fnc_t init_sequence_r[] = {
 #ifdef CONFIG_OF_LIVE
 	initr_of_live,
 #endif
+#ifdef CONFIG_OF_BOARD_FIXUP
+	fix_fdt_change,
+#endif
 #ifdef CONFIG_DM
 	initr_dm,
 #endif
diff --git a/doc/driver-model/fdt-fixup.txt b/doc/driver-model/fdt-fixup.txt
index 70344bd2c3..9a9467edd8 100644
--- a/doc/driver-model/fdt-fixup.txt
+++ b/doc/driver-model/fdt-fixup.txt
@@ -52,81 +52,122 @@ tree (at least after the relocation) would greatly simplify the solution of
 this problem, it is a non-negligible task to implement it, an a interim
 solution is needed to address the problem at least in the medium-term.
 
-Hence, we propose a solution to this problem by offering a board-specific
-call-back function, which is passed a writeable pointer to the device tree.
-This function is called before the device tree is relocated, and specifically
-before the main U-Boot's driver model is instantiated, hence the main U-Boot
-"sees" all modifications to the device tree made in this function. Furthermore,
-we have the pre-relocation driver model at our disposal at this stage, which
-means that we can query the hardware for the existence and variety of the
-components easily.
+Hence, we propose a solution to this problem by offering a set of two board-specific
+call-back functions:
+
+ * One function which is called prior to relocation that gathers information
+   about the device using the pre-relocation DM instance and stores the
+   collected information in a special data structure within the global data
+   section; using the pre-relocation driver model means that we can query the
+   hardware for the existence and variety of the components easily.
+ * A second function which is called just after relocation, but before the
+   post-relocation DM is instantiated; it is passed a writeable pointer to the
+   device tree, so that it can exectute the actual modifications of the device
+   tree based upon the information gathered by the first function.
+
+Notice that since the "modification function" is called prior to the DM
+instantiation, the main U-Boot "sees" all modifications to the device tree made
+by the function.
 
 2. Implementation
 -----------------
 
 To take advantage of the pre-relocation device tree manipulation mechanism,
-boards have to implement the function board_fix_fdt, which has the following
-signature:
+boards have to implement the functions board_fix_fdt_get_info and
+board_fix_fdt_change, which have the following signatures:
 
-int board_fix_fdt (void *rw_fdt_blob)
+int board_fix_fdt_get_info (void)
+int board_fix_fdt_change (void *rw_fdt_blob)
 
-The passed-in void pointer is a writeable pointer to the device tree, which can
-be used to manipulate the device tree using e.g. functions from
-include/fdt_support.h. The return value should either be 0 in case of
-successful execution of the device tree manipulation or something else for a
+The void pointer passed to board_fix_fdt_change is a writeable pointer to the
+device tree, which can be used to manipulate the device tree using e.g.
+functions from include/fdt_support.h. The return value for both functions
+should either be 0 in case of successful execution of the device information
+gathering and device tree manipulation respectively or something else for a
 failure. Note that returning a non-null value from the function will
 unrecoverably halt the boot process, as with any function from init_sequence_f
-(in common/board_f.c).
+(in common/board_f.c) or init_sequence_r (in common/board_r.c).  .
 
-Furthermore, the Kconfig option OF_BOARD_FIXUP has to be set for the function
+Furthermore, the Kconfig option OF_BOARD_FIXUP has to be set for the functions
 to be called:
 
 Device Tree Control
 -> [*] Board-specific manipulation of Device Tree
 
-+----------------------------------------------------------+
-| WARNING: The actual manipulation of the device tree has  |
-| to be the _last_ set of operations in board_fix_fdt!     |
-| Since the pre-relocation driver model does not adapt to  |
-| changes made to the device tree either, its references   |
-| into the device tree will be invalid after manipulating  |
-| it, and unpredictable behavior might occur when          |
-| functions that rely on them are executed!                |
-+----------------------------------------------------------+
+The transfer of the collected device information is accomplished via the
+board_fixup_data sub-structure in the global data structure. The layout of this
+structure is board-defined, and every user of the mechanism should define a
+suitable set of fields in include/fdt_fixup.h surrounded by preprocessor #ifdef
+instructions. For example, a board with the target Kconfig variable
+CONFIG_TARGET_SAMPLEBOARD that needs to check the existence of two I2C devices
+and has to determine a board variant identified by an int, might add the
+following member declarations for itself:
 
-Hence, the recommended layout of the board_fixup_fdt call-back function is the
-following:
+#ifdef CONFIG_TARGET_SAMPLEBOARD
+    bool chip1_present;
+    bool chip2_present;
+    int variant;
+#endif
 
-int board_fix_fdt(void *rw_fdt_blob)
+A schemetic implementation of the two functions might then look like the following:
+
+int board_fix_fdt_get_info(void)
 {
 	/* Collect information about device's hardware and store them in e.g.
-	   local variables */
+       local variables, e.g. chip1_present, chip2_present, variant. Return a
+       non-zero value if the information gathering failed. */
+
+    /* Store the collected information in the sub-structure, so they will be
+       available to board_fix_fdt_change: */
 
-	/* Do device tree manipulation using the values previously collected */
+    gd->board_fixup_data.chip1_present = chip1_present;
+    gd->board_fixup_data.chip2_present = chip2_present;
+    gd->board_fixup_data.variant = variant;
 
-	/* Return 0 on successful manipulation and non-zero otherwise */
+    return 0;
 }
 
-If this convention is kept, both an "additive" approach, meaning that nodes for
-detected components are added to the device tree, as well as a "subtractive"
-approach, meaning that nodes for absent components are removed from the tree,
-as well as a combination of both approaches should work.
+int board_fix_fdt_change(void *rw_fdt_blob)
+{
+    /* Read back the information from the sub-structure: */
+
+    bool chip1_present = gd->board_fixup_data.chip1_present;
+    bool chip2_present = gd->board_fixup_data.chip2_present;
+    int variant = gd->board_fixup_data.variant;
+
+    /* Employ device tree manipulation based on the information: */
+
+    if (chip1_present) {
+        ...
+    }
+
+    if (chip2_present) {
+        ...
+    }
+
+    switch(variant)
+        ...
+    }
+}
+
+This convention of split functions also enables that both an "additive"
+approach for DT manipulation, meaning that nodes for detected components are
+added to the device tree, as well as a "subtractive" approach, meaning that
+nodes for absent components are removed from the tree, as well as a combination
+of both approaches should work.
 
 3. Example
 ----------
 
-The controlcenterdc board (board/gdsys/a38x/controlcenterdc.c) features a
-board_fix_fdt function, in which six GPIO expanders (which might be present or
+The controlcenterdc board (board/gdsys/a38x/controlcenterdc.c) features
+board_fix_fdt functions, in which six GPIO expanders (which might be present or
 not, since they are on daughter boards) on a I2C bus are queried for, and
 subsequently deactivated in the device tree if they are not present.
 
-Note that the dm_i2c_simple_probe function does not use the device tree, hence
-it is safe to call it after the tree has already been manipulated.
-
 4. Work to be done
 ------------------
 
-* The application of device tree overlay should be possible in board_fixup_fdt,
-  but has not been tested at this stage.
+* The application of device tree overlay should be possible in
+  board_fixup_fdt_change, but has not been tested at this stage.
 
-2017-01-06, Mario Six <mario.six@gdsys.cc>
+2017-07-04, Mario Six <mario.six@gdsys.cc>
diff --git a/include/asm-generic/global_data.h b/include/asm-generic/global_data.h
index fb90be9d3e..731a4163a9 100644
--- a/include/asm-generic/global_data.h
+++ b/include/asm-generic/global_data.h
@@ -24,6 +24,10 @@
 #include <membuff.h>
 #include <linux/list.h>
 
+#ifdef CONFIG_OF_BOARD_FIXUP
+#include <fdt_fixup.h>
+#endif
+
 typedef struct global_data {
 	bd_t *bd;
 	unsigned long flags;
@@ -75,6 +79,9 @@ typedef struct global_data {
 #ifdef CONFIG_OF_LIVE
 	struct device_node *of_root;
 #endif
+#ifdef CONFIG_OF_BOARD_FIXUP
+	struct of_board_fixup_data board_fixup_data;
+#endif
 	struct jt_funcs *jt;		/* jump table */
 	char env_buf[32];		/* buffer for getenv() before reloc. */
 #ifdef CONFIG_TRACE
diff --git a/include/common.h b/include/common.h
index 751665f8a4..80a004d4b4 100644
--- a/include/common.h
+++ b/include/common.h
@@ -416,7 +416,8 @@ extern ssize_t spi_write (uchar *, int, uchar *, int);
 
 /* $(BOARD)/$(BOARD).c */
 int board_early_init_f (void);
-int board_fix_fdt (void *rw_fdt_blob); /* manipulate the U-Boot fdt before its relocation */
+int board_fix_fdt_get_info (void); /* manipulate the U-Boot fdt before its relocation */
+int board_fix_fdt_change (void *rw_fdt_blob); /* manipulate the U-Boot fdt before its relocation */
 int board_late_init (void);
 int board_postclk_init (void); /* after clocks/timebase, before env/serial */
 int board_early_init_r (void);
diff --git a/include/fdt_fixup.h b/include/fdt_fixup.h
new file mode 100644
index 0000000000..9390f0a633
--- /dev/null
+++ b/include/fdt_fixup.h
@@ -0,0 +1,5 @@
+struct of_board_fixup_data {
+#ifdef CONFIG_TARGET_CONTROLCENTERDC
+	bool chip_exists[6];
+#endif
+};
-- 
2.11.0

^ permalink raw reply related	[flat|nested] 138+ messages in thread

* [U-Boot] [PATCH 22/51] gdsys: mpc8308: Fix style violations
  2017-07-14 12:54 [U-Boot] [PATCH 00/51] gdsys: Add support for Gazerbeam board Mario Six
                   ` (20 preceding siblings ...)
  2017-07-14 12:55 ` [U-Boot] [PATCH 21/51] common: Extend board-specific DT fixup Mario Six
@ 2017-07-14 12:55 ` Mario Six
  2017-07-19  9:05   ` Simon Glass
  2017-07-14 12:55 ` [U-Boot] [PATCH 23/51] gdsys: mpc8308: Use shadow register for output GPIO values Mario Six
                   ` (28 subsequent siblings)
  50 siblings, 1 reply; 138+ messages in thread
From: Mario Six @ 2017-07-14 12:55 UTC (permalink / raw)
  To: u-boot

Fix some style violations in the gdsys MPC8308 board files, and make the
code more readable.

Signed-off-by: Mario Six <mario.six@gdsys.cc>
---

 board/gdsys/mpc8308/hrcon.c   | 55 ++++++++++++++++++++++---------------------
 board/gdsys/mpc8308/mpc8308.c | 12 +++++-----
 board/gdsys/mpc8308/strider.c | 49 +++++++++++++++++++-------------------
 3 files changed, 59 insertions(+), 57 deletions(-)

diff --git a/board/gdsys/mpc8308/hrcon.c b/board/gdsys/mpc8308/hrcon.c
index c6566e9196..e8898a793a 100644
--- a/board/gdsys/mpc8308/hrcon.c
+++ b/board/gdsys/mpc8308/hrcon.c
@@ -38,11 +38,11 @@ DECLARE_GLOBAL_DATA_PTR;
 #define MAX_MUX_CHANNELS 2
 
 enum {
-	MCFPGA_DONE = 1 << 0,
-	MCFPGA_INIT_N = 1 << 1,
-	MCFPGA_PROGRAM_N = 1 << 2,
-	MCFPGA_UPDATE_ENABLE_N = 1 << 3,
-	MCFPGA_RESET_N = 1 << 4,
+	MCFPGA_DONE = BIT(0),
+	MCFPGA_INIT_N = BIT(1),
+	MCFPGA_PROGRAM_N = BIT(2),
+	MCFPGA_UPDATE_ENABLE_N = BIT(3),
+	MCFPGA_RESET_N = BIT(4),
 };
 
 enum {
@@ -50,7 +50,7 @@ enum {
 	GPIO_MDIO = 1 << 15,
 };
 
-unsigned int mclink_fpgacount;
+uint mclink_fpgacount;
 struct ihs_fpga *fpga_ptr[] = CONFIG_SYS_FPGA_PTR;
 
 struct {
@@ -110,7 +110,7 @@ int checkboard(void)
 
 	printf("HRCon %s", hw_type_cat ? "CAT" : "Fiber");
 
-	if (s != NULL) {
+	if (s) {
 		puts(", serial# ");
 		puts(s);
 	}
@@ -123,12 +123,11 @@ int checkboard(void)
 int last_stage_init(void)
 {
 	int slaves;
-	unsigned int k;
-	unsigned int mux_ch;
-	unsigned char mclink_controllers[] = { 0x3c, 0x3d, 0x3e };
+	uint k;
+	uchar mclink_controllers[] = { 0x3c, 0x3d, 0x3e };
 	u16 fpga_features;
 	bool hw_type_cat = pca9698_get_value(0x20, 20);
-	bool ch0_rgmii2_present = false;
+	bool ch0_rgmii2_present;
 
 	FPGA_GET_REG(0, fpga_features, &fpga_features);
 
@@ -140,16 +139,16 @@ int last_stage_init(void)
 
 	/* wait for FPGA done, then reset FPGA */
 	for (k = 0; k < ARRAY_SIZE(mclink_controllers); ++k) {
-		unsigned int ctr = 0;
+		uint ctr = 0;
 
 		if (i2c_probe(mclink_controllers[k]))
 			continue;
 
 		while (!(pca953x_get_val(mclink_controllers[k])
 		       & MCFPGA_DONE)) {
-			udelay(100000);
+			mdelay(100);
 			if (ctr++ > 5) {
-				printf("no done for mclink_controller %d\n", k);
+				printf("no done for mclink_controller %u\n", k);
 				break;
 			}
 		}
@@ -162,8 +161,10 @@ int last_stage_init(void)
 	}
 
 	if (hw_type_cat) {
+		uint mux_ch;
 		int retval;
 		struct mii_dev *mdiodev = mdio_alloc();
+
 		if (!mdiodev)
 			return -ENOMEM;
 		strncpy(mdiodev->name, bb_miiphy_buses[0].name, MDIO_NAME_LEN);
@@ -182,7 +183,7 @@ int last_stage_init(void)
 	}
 
 	/* give slave-PLLs and Parade DP501 some time to be up and running */
-	udelay(500000);
+	mdelay(500);
 
 	mclink_fpgacount = CONFIG_SYS_MCLINK_MAX;
 	slaves = mclink_probe();
@@ -210,6 +211,7 @@ int last_stage_init(void)
 		if (hw_type_cat) {
 			int retval;
 			struct mii_dev *mdiodev = mdio_alloc();
+
 			if (!mdiodev)
 				return -ENOMEM;
 			strncpy(mdiodev->name, bb_miiphy_buses[k].name,
@@ -236,17 +238,17 @@ int last_stage_init(void)
  * provide access to fpga gpios and controls (for I2C bitbang)
  * (these may look all too simple but make iocon.h much more readable)
  */
-void fpga_gpio_set(unsigned int bus, int pin)
+void fpga_gpio_set(uint bus, int pin)
 {
 	FPGA_SET_REG(bus >= 4 ? (bus - 4) : bus, gpio.set, pin);
 }
 
-void fpga_gpio_clear(unsigned int bus, int pin)
+void fpga_gpio_clear(uint bus, int pin)
 {
 	FPGA_SET_REG(bus >= 4 ? (bus - 4) : bus, gpio.clear, pin);
 }
 
-int fpga_gpio_get(unsigned int bus, int pin)
+int fpga_gpio_get(uint bus, int pin)
 {
 	u16 val;
 
@@ -255,7 +257,7 @@ int fpga_gpio_get(unsigned int bus, int pin)
 	return val & pin;
 }
 
-void fpga_control_set(unsigned int bus, int pin)
+void fpga_control_set(uint bus, int pin)
 {
 	u16 val;
 
@@ -263,7 +265,7 @@ void fpga_control_set(unsigned int bus, int pin)
 	FPGA_SET_REG(bus >= 4 ? (bus - 4) : bus, control, val | pin);
 }
 
-void fpga_control_clear(unsigned int bus, int pin)
+void fpga_control_clear(uint bus, int pin)
 {
 	u16 val;
 
@@ -276,7 +278,7 @@ void mpc8308_init(void)
 	pca9698_direction_output(0x20, 4, 1);
 }
 
-void mpc8308_set_fpga_reset(unsigned state)
+void mpc8308_set_fpga_reset(uint state)
 {
 	pca9698_set_value(0x20, 4, state ? 0 : 1);
 }
@@ -288,11 +290,11 @@ void mpc8308_setup_hw(void)
 	/*
 	 * set "startup-finished"-gpios
 	 */
-	setbits_be32(&immr->gpio[0].dir, (1 << (31-11)) | (1 << (31-12)));
-	setbits_be32(&immr->gpio[0].dat, 1 << (31-12));
+	setbits_be32(&immr->gpio[0].dir, (BIT(31 - 11) | BIT(31 - 12)));
+	setbits_be32(&immr->gpio[0].dat, BIT(31 - 12));
 }
 
-int mpc8308_get_fpga_done(unsigned fpga)
+int mpc8308_get_fpga_done(uint fpga)
 {
 	return pca9698_get_value(0x20, 19);
 }
@@ -370,7 +372,7 @@ int ft_board_setup(void *blob, bd_t *bd)
  */
 
 struct fpga_mii {
-	unsigned fpga;
+	uint fpga;
 	int mdio;
 } fpga_mii[] = {
 	{ 0, 1},
@@ -497,5 +499,4 @@ struct bb_miiphy_bus bb_miiphy_buses[] = {
 	},
 };
 
-int bb_miiphy_buses_num = sizeof(bb_miiphy_buses) /
-			  sizeof(bb_miiphy_buses[0]);
+int bb_miiphy_buses_num = ARRAY_SIZE(bb_miiphy_buses);
diff --git a/board/gdsys/mpc8308/mpc8308.c b/board/gdsys/mpc8308/mpc8308.c
index 86b257f4de..0b1d4eab22 100644
--- a/board/gdsys/mpc8308/mpc8308.c
+++ b/board/gdsys/mpc8308/mpc8308.c
@@ -25,14 +25,14 @@
 
 DECLARE_GLOBAL_DATA_PTR;
 
-int get_fpga_state(unsigned dev)
+int get_fpga_state(uint dev)
 {
 	return gd->arch.fpga_state[dev];
 }
 
 int board_early_init_f(void)
 {
-	unsigned k;
+	uint k;
 
 	for (k = 0; k < CONFIG_SYS_FPGA_COUNT; ++k)
 		gd->arch.fpga_state[k] = 0;
@@ -42,8 +42,8 @@ int board_early_init_f(void)
 
 int board_early_init_r(void)
 {
-	unsigned k;
-	unsigned ctr;
+	uint k;
+	uint ctr;
 
 	for (k = 0; k < CONFIG_SYS_FPGA_COUNT; ++k)
 		gd->arch.fpga_state[k] = 0;
@@ -60,7 +60,7 @@ int board_early_init_r(void)
 	for (k = 0; k < CONFIG_SYS_FPGA_COUNT; ++k) {
 		ctr = 0;
 		while (!mpc8308_get_fpga_done(k)) {
-			udelay(100000);
+			mdelay(100);
 			if (ctr++ > 5) {
 				gd->arch.fpga_state[k] |=
 					FPGA_STATE_DONE_FAILED;
@@ -87,7 +87,7 @@ int board_early_init_r(void)
 			if (val == REFLECTION_TESTPATTERN_INV)
 				break;
 
-			udelay(100000);
+			mdelay(100);
 			if (ctr++ > 5) {
 				gd->arch.fpga_state[k] |=
 					FPGA_STATE_REFLECTION_FAILED;
diff --git a/board/gdsys/mpc8308/strider.c b/board/gdsys/mpc8308/strider.c
index 34e9d1956e..5197d22f07 100644
--- a/board/gdsys/mpc8308/strider.c
+++ b/board/gdsys/mpc8308/strider.c
@@ -53,7 +53,7 @@ enum {
 	GPIO_MDIO = 1 << 15,
 };
 
-unsigned int mclink_fpgacount;
+uint mclink_fpgacount;
 struct ihs_fpga *fpga_ptr[] = CONFIG_SYS_FPGA_PTR;
 
 struct {
@@ -113,7 +113,7 @@ int checkboard(void)
 
 	printf("Strider %s", hw_type_cat ? "CAT" : "Fiber");
 
-	if (s != NULL) {
+	if (s) {
 		puts(", serial# ");
 		puts(s);
 	}
@@ -126,17 +126,17 @@ int checkboard(void)
 int last_stage_init(void)
 {
 	int slaves;
-	unsigned int k;
-	unsigned int mux_ch;
-	unsigned char mclink_controllers_dvi[] = { 0x3c, 0x3d, 0x3e };
+	uint k;
+	uint mux_ch;
+	uchar mclink_controllers_dvi[] = { 0x3c, 0x3d, 0x3e };
 #ifdef CONFIG_STRIDER_CPU
-	unsigned char mclink_controllers_dp[] = { 0x24, 0x25, 0x26 };
+	uchar mclink_controllers_dp[] = { 0x24, 0x25, 0x26 };
 #endif
 	bool hw_type_cat = pca9698_get_value(0x20, 18);
 #ifdef CONFIG_STRIDER_CON_DP
 	bool is_dh = pca9698_get_value(0x20, 25);
 #endif
-	bool ch0_sgmii2_present = false;
+	bool ch0_sgmii2_present;
 
 	/* Turn on Analog Devices ADV7611 */
 	pca9698_direction_output(0x20, 8, 0);
@@ -149,8 +149,8 @@ int last_stage_init(void)
 
 	/* wait for FPGA done, then reset FPGA */
 	for (k = 0; k < ARRAY_SIZE(mclink_controllers_dvi); ++k) {
-		unsigned int ctr = 0;
-		unsigned char *mclink_controllers = mclink_controllers_dvi;
+		uint ctr = 0;
+		uchar *mclink_controllers = mclink_controllers_dvi;
 
 #ifdef CONFIG_STRIDER_CPU
 		if (i2c_probe(mclink_controllers[k])) {
@@ -164,7 +164,7 @@ int last_stage_init(void)
 #endif
 		while (!(pca953x_get_val(mclink_controllers[k])
 		       & MCFPGA_DONE)) {
-			udelay(100000);
+			mdelay(100);
 			if (ctr++ > 5) {
 				printf("no done for mclink_controller %d\n", k);
 				break;
@@ -181,6 +181,7 @@ int last_stage_init(void)
 	if (hw_type_cat) {
 		int retval;
 		struct mii_dev *mdiodev = mdio_alloc();
+
 		if (!mdiodev)
 			return -ENOMEM;
 		strncpy(mdiodev->name, bb_miiphy_buses[0].name, MDIO_NAME_LEN);
@@ -199,7 +200,7 @@ int last_stage_init(void)
 	}
 
 	/* give slave-PLLs and Parade DP501 some time to be up and running */
-	udelay(500000);
+	mdelay(500);
 
 	mclink_fpgacount = CONFIG_SYS_MCLINK_MAX;
 	slaves = mclink_probe();
@@ -238,7 +239,7 @@ int last_stage_init(void)
 	for (k = 1; k <= slaves; ++k)
 		FPGA_SET_REG(k, extended_control, 0x10); /* enable video */
 
-	udelay(500000);
+	mdelay(500);
 #endif
 
 	for (k = 1; k <= slaves; ++k) {
@@ -263,6 +264,7 @@ int last_stage_init(void)
 		if (hw_type_cat) {
 			int retval;
 			struct mii_dev *mdiodev = mdio_alloc();
+
 			if (!mdiodev)
 				return -ENOMEM;
 			strncpy(mdiodev->name, bb_miiphy_buses[k].name,
@@ -289,17 +291,17 @@ int last_stage_init(void)
  * provide access to fpga gpios (for I2C bitbang)
  * (these may look all too simple but make iocon.h much more readable)
  */
-void fpga_gpio_set(unsigned int bus, int pin)
+void fpga_gpio_set(uint bus, int pin)
 {
 	FPGA_SET_REG(bus, gpio.set, pin);
 }
 
-void fpga_gpio_clear(unsigned int bus, int pin)
+void fpga_gpio_clear(uint bus, int pin)
 {
 	FPGA_SET_REG(bus, gpio.clear, pin);
 }
 
-int fpga_gpio_get(unsigned int bus, int pin)
+int fpga_gpio_get(uint bus, int pin)
 {
 	u16 val;
 
@@ -309,7 +311,7 @@ int fpga_gpio_get(unsigned int bus, int pin)
 }
 
 #ifdef CONFIG_STRIDER_CON_DP
-void fpga_control_set(unsigned int bus, int pin)
+void fpga_control_set(uint bus, int pin)
 {
 	u16 val;
 
@@ -317,7 +319,7 @@ void fpga_control_set(unsigned int bus, int pin)
 	FPGA_SET_REG(bus, control, val | pin);
 }
 
-void fpga_control_clear(unsigned int bus, int pin)
+void fpga_control_clear(uint bus, int pin)
 {
 	u16 val;
 
@@ -331,7 +333,7 @@ void mpc8308_init(void)
 	pca9698_direction_output(0x20, 26, 1);
 }
 
-void mpc8308_set_fpga_reset(unsigned state)
+void mpc8308_set_fpga_reset(uint state)
 {
 	pca9698_set_value(0x20, 26, state ? 0 : 1);
 }
@@ -343,11 +345,11 @@ void mpc8308_setup_hw(void)
 	/*
 	 * set "startup-finished"-gpios
 	 */
-	setbits_be32(&immr->gpio[0].dir, (1 << (31-11)) | (1 << (31-12)));
-	setbits_be32(&immr->gpio[0].dat, 1 << (31-12));
+	setbits_be32(&immr->gpio[0].dir, BIT(31 - 11) | BIT(31 - 12));
+	setbits_be32(&immr->gpio[0].dat, BIT(31 - 12));
 }
 
-int mpc8308_get_fpga_done(unsigned fpga)
+int mpc8308_get_fpga_done(uint fpga)
 {
 	return pca9698_get_value(0x20, 20);
 }
@@ -425,7 +427,7 @@ int ft_board_setup(void *blob, bd_t *bd)
  */
 
 struct fpga_mii {
-	unsigned fpga;
+	uint fpga;
 	int mdio;
 } fpga_mii[] = {
 	{ 0, 1},
@@ -552,5 +554,4 @@ struct bb_miiphy_bus bb_miiphy_buses[] = {
 	},
 };
 
-int bb_miiphy_buses_num = sizeof(bb_miiphy_buses) /
-			  sizeof(bb_miiphy_buses[0]);
+int bb_miiphy_buses_num = ARRAY_SIZE(bb_miiphy_buses);
-- 
2.11.0

^ permalink raw reply related	[flat|nested] 138+ messages in thread

* [U-Boot] [PATCH 23/51] gdsys: mpc8308: Use shadow register for output GPIO values
  2017-07-14 12:54 [U-Boot] [PATCH 00/51] gdsys: Add support for Gazerbeam board Mario Six
                   ` (21 preceding siblings ...)
  2017-07-14 12:55 ` [U-Boot] [PATCH 22/51] gdsys: mpc8308: Fix style violations Mario Six
@ 2017-07-14 12:55 ` Mario Six
  2017-07-19  9:05   ` Simon Glass
  2017-07-14 12:55 ` [U-Boot] [PATCH 24/51] gdsys: mpc8308: Move SYS_FPGA{0, 1}_{BASE, SIZE} to Kconfig Mario Six
                   ` (27 subsequent siblings)
  50 siblings, 1 reply; 138+ messages in thread
From: Mario Six @ 2017-07-14 12:55 UTC (permalink / raw)
  To: u-boot

Since gpio output status on MPC8xxx cannot be read back, it has to be
buffered locally.

Signed-off-by: Dirk Eibach <dirk.eibach@gdsys.cc>
Signed-off-by: Mario Six <mario.six@gdsys.cc>
---

 board/gdsys/mpc8308/hrcon.c   |  4 ++--
 board/gdsys/mpc8308/mpc8308.c | 19 +++++++++++++++++++
 board/gdsys/mpc8308/mpc8308.h |  3 +++
 board/gdsys/mpc8308/strider.c |  2 +-
 4 files changed, 25 insertions(+), 3 deletions(-)

diff --git a/board/gdsys/mpc8308/hrcon.c b/board/gdsys/mpc8308/hrcon.c
index e8898a793a..bbe93a3488 100644
--- a/board/gdsys/mpc8308/hrcon.c
+++ b/board/gdsys/mpc8308/hrcon.c
@@ -290,8 +290,8 @@ void mpc8308_setup_hw(void)
 	/*
 	 * set "startup-finished"-gpios
 	 */
-	setbits_be32(&immr->gpio[0].dir, (BIT(31 - 11) | BIT(31 - 12)));
-	setbits_be32(&immr->gpio[0].dat, BIT(31 - 12));
+	setbits_be32(&immr->gpio[0].dir, BIT(31 - 11) | BIT(31 - 12));
+	setbits_gpio0_out(BIT(31 - 12));
 }
 
 int mpc8308_get_fpga_done(uint fpga)
diff --git a/board/gdsys/mpc8308/mpc8308.c b/board/gdsys/mpc8308/mpc8308.c
index 0b1d4eab22..8d6a49f86a 100644
--- a/board/gdsys/mpc8308/mpc8308.c
+++ b/board/gdsys/mpc8308/mpc8308.c
@@ -25,6 +25,25 @@
 
 DECLARE_GLOBAL_DATA_PTR;
 
+/* as gpio output status cannot be read back, we have to buffer it locally */
+u32 gpio0_out;
+
+void setbits_gpio0_out(u32 mask)
+{
+	immap_t *immr = (immap_t *)CONFIG_SYS_IMMR;
+
+	gpio0_out |= mask;
+	out_be32(&immr->gpio[0].dat, gpio0_out);
+}
+
+void clrbits_gpio0_out(u32 mask)
+{
+	immap_t *immr = (immap_t *)CONFIG_SYS_IMMR;
+
+	gpio0_out &= ~mask;
+	out_be32(&immr->gpio[0].dat, gpio0_out);
+}
+
 int get_fpga_state(uint dev)
 {
 	return gd->arch.fpga_state[dev];
diff --git a/board/gdsys/mpc8308/mpc8308.h b/board/gdsys/mpc8308/mpc8308.h
index dc07d564eb..1e4f24fb2a 100644
--- a/board/gdsys/mpc8308/mpc8308.h
+++ b/board/gdsys/mpc8308/mpc8308.h
@@ -1,6 +1,9 @@
 #ifndef __MPC8308_H_
 #define __MPC8308_H_
 
+void setbits_gpio0_out(u32 mask);
+void clrbits_gpio0_out(u32 mask);
+
 /* functions to be provided by board implementation */
 void mpc8308_init(void);
 void mpc8308_set_fpga_reset(unsigned state);
diff --git a/board/gdsys/mpc8308/strider.c b/board/gdsys/mpc8308/strider.c
index 5197d22f07..ac785da8e6 100644
--- a/board/gdsys/mpc8308/strider.c
+++ b/board/gdsys/mpc8308/strider.c
@@ -346,7 +346,7 @@ void mpc8308_setup_hw(void)
 	 * set "startup-finished"-gpios
 	 */
 	setbits_be32(&immr->gpio[0].dir, BIT(31 - 11) | BIT(31 - 12));
-	setbits_be32(&immr->gpio[0].dat, BIT(31 - 12));
+	setbits_gpio0_out(BIT(31 - 12));
 }
 
 int mpc8308_get_fpga_done(uint fpga)
-- 
2.11.0

^ permalink raw reply related	[flat|nested] 138+ messages in thread

* [U-Boot] [PATCH 24/51] gdsys: mpc8308: Move SYS_FPGA{0, 1}_{BASE, SIZE} to Kconfig
  2017-07-14 12:54 [U-Boot] [PATCH 00/51] gdsys: Add support for Gazerbeam board Mario Six
                   ` (22 preceding siblings ...)
  2017-07-14 12:55 ` [U-Boot] [PATCH 23/51] gdsys: mpc8308: Use shadow register for output GPIO values Mario Six
@ 2017-07-14 12:55 ` Mario Six
  2017-07-19  9:05   ` Simon Glass
  2017-07-14 12:55 ` [U-Boot] [PATCH 25/51] gdsys: Introduce GDSYS_LEGACY_DRIVERS Mario Six
                   ` (26 subsequent siblings)
  50 siblings, 1 reply; 138+ messages in thread
From: Mario Six @ 2017-07-14 12:55 UTC (permalink / raw)
  To: u-boot

Move CONFIG_SYS_FPGA0_BASE, CONFIG_SYS_FPGA0_SIZE, CONFIG_SYS_FPGA1_BASE, and
CONFIG_SYS_FPGA1_SIZE to Kconfig.

Signed-off-by: Mario Six <mario.six@gdsys.cc>
---

 board/gdsys/mpc8308/Kconfig  | 23 +++++++++++++++++++++++
 include/configs/hrcon.h      |  7 -------
 include/configs/strider.h    |  7 -------
 scripts/config_whitelist.txt |  2 --
 4 files changed, 23 insertions(+), 16 deletions(-)

diff --git a/board/gdsys/mpc8308/Kconfig b/board/gdsys/mpc8308/Kconfig
index cb29c25c65..c0247214a9 100644
--- a/board/gdsys/mpc8308/Kconfig
+++ b/board/gdsys/mpc8308/Kconfig
@@ -1,3 +1,26 @@
+
+config SYS_FPGA0_BASE
+	hex
+	default E0600000
+	help
+	  The base address of the first FPGA's register map.
+
+config SYS_FPGA0_SIZE
+	hex
+	default 1
+	help
+	  The base address of the first FPGA's register map.
+
+config SYS_FPGA1_BASE
+	hex
+	help
+	  The base address of the second FPGA's register map.
+
+config SYS_FPGA1_SIZE
+	hex
+	help
+	  The base address of the second FPGA's register map.
+
 if TARGET_HRCON
 
 config SYS_BOARD
diff --git a/include/configs/hrcon.h b/include/configs/hrcon.h
index 405129b7e2..5db623d28e 100644
--- a/include/configs/hrcon.h
+++ b/include/configs/hrcon.h
@@ -243,12 +243,6 @@
 #define CONFIG_SYS_FLASH_ERASE_TOUT	60000 /* Flash Erase Timeout (ms) */
 #define CONFIG_SYS_FLASH_WRITE_TOUT	500 /* Flash Write Timeout (ms) */
 
-/*
- * FPGA
- */
-#define CONFIG_SYS_FPGA0_BASE		0xE0600000
-#define CONFIG_SYS_FPGA0_SIZE		1 /* FPGA size is 1M */
-
 /* Window base at FPGA base */
 #define CONFIG_SYS_LBLAWBAR1_PRELIM	CONFIG_SYS_FPGA0_BASE
 #define CONFIG_SYS_LBLAWAR1_PRELIM	(LBLAWAR_EN | LBLAWAR_1MB)
@@ -266,7 +260,6 @@
 				| OR_GPCM_TRLX_SET \
 				| OR_GPCM_EHTR_SET)
 
-#define CONFIG_SYS_FPGA_BASE(k)		CONFIG_SYS_FPGA0_BASE
 #define CONFIG_SYS_FPGA_DONE(k)		0x0010
 
 #define CONFIG_SYS_FPGA_COUNT		1
diff --git a/include/configs/strider.h b/include/configs/strider.h
index 994ac73e13..8487a188a7 100644
--- a/include/configs/strider.h
+++ b/include/configs/strider.h
@@ -243,12 +243,6 @@
 #define CONFIG_SYS_FLASH_ERASE_TOUT	60000 /* Flash Erase Timeout (ms) */
 #define CONFIG_SYS_FLASH_WRITE_TOUT	500 /* Flash Write Timeout (ms) */
 
-/*
- * FPGA
- */
-#define CONFIG_SYS_FPGA0_BASE		0xE0600000
-#define CONFIG_SYS_FPGA0_SIZE		1 /* FPGA size is 1M */
-
 /* Window base at FPGA base */
 #define CONFIG_SYS_LBLAWBAR1_PRELIM	CONFIG_SYS_FPGA0_BASE
 #define CONFIG_SYS_LBLAWAR1_PRELIM	(LBLAWAR_EN | LBLAWAR_1MB)
@@ -265,7 +259,6 @@
 				| OR_GPCM_TRLX_CLEAR \
 				| OR_GPCM_EHTR_CLEAR)
 
-#define CONFIG_SYS_FPGA_BASE(k)		CONFIG_SYS_FPGA0_BASE
 #define CONFIG_SYS_FPGA_DONE(k)		0x0010
 
 #define CONFIG_SYS_FPGA_COUNT		1
diff --git a/scripts/config_whitelist.txt b/scripts/config_whitelist.txt
index 4c136a6502..64a4b1190e 100644
--- a/scripts/config_whitelist.txt
+++ b/scripts/config_whitelist.txt
@@ -3086,8 +3086,6 @@ CONFIG_SYS_FORM_PMC
 CONFIG_SYS_FORM_PMC_XMC
 CONFIG_SYS_FORM_VME
 CONFIG_SYS_FORM_XMC
-CONFIG_SYS_FPGA0_BASE
-CONFIG_SYS_FPGA0_SIZE
 CONFIG_SYS_FPGAREG_DATE
 CONFIG_SYS_FPGAREG_DIPSW
 CONFIG_SYS_FPGAREG_FREQ
-- 
2.11.0

^ permalink raw reply related	[flat|nested] 138+ messages in thread

* [U-Boot] [PATCH 25/51] gdsys: Introduce GDSYS_LEGACY_DRIVERS
  2017-07-14 12:54 [U-Boot] [PATCH 00/51] gdsys: Add support for Gazerbeam board Mario Six
                   ` (23 preceding siblings ...)
  2017-07-14 12:55 ` [U-Boot] [PATCH 24/51] gdsys: mpc8308: Move SYS_FPGA{0, 1}_{BASE, SIZE} to Kconfig Mario Six
@ 2017-07-14 12:55 ` Mario Six
  2017-07-19  9:05   ` Simon Glass
  2017-07-14 12:55 ` [U-Boot] [PATCH 26/51] strider, hrcon: Reset CAT phy on CON2 module Mario Six
                   ` (25 subsequent siblings)
  50 siblings, 1 reply; 138+ messages in thread
From: Mario Six @ 2017-07-14 12:55 UTC (permalink / raw)
  To: u-boot

Future gdsys boards will switch from the legacy drivers in board/gdsys/common
to DM-based drivers.

Define a Kconfig option that disables the legacy drivers.

Signed-off-by: Mario Six <mario.six@gdsys.cc>
---

 board/gdsys/common/adv7611.c   | 4 ++++
 board/gdsys/common/ch7301.c    | 4 ++++
 board/gdsys/common/dp501.c     | 4 ++++
 board/gdsys/common/fanctrl.c   | 4 ++++
 board/gdsys/common/fpga.c      | 4 ++++
 board/gdsys/common/ihs_mdio.c  | 4 ++++
 board/gdsys/common/ioep-fpga.c | 4 ++++
 board/gdsys/common/mclink.c    | 4 ++++
 board/gdsys/common/osd.c       | 4 ++++
 board/gdsys/mpc8308/Kconfig    | 8 ++++++++
 board/gdsys/mpc8308/mpc8308.c  | 2 ++
 board/gdsys/p1022/Kconfig      | 6 ++++++
 include/gdsys_fpga.h           | 2 ++
 13 files changed, 54 insertions(+)

diff --git a/board/gdsys/common/adv7611.c b/board/gdsys/common/adv7611.c
index b728274cce..4ed9b09cd2 100644
--- a/board/gdsys/common/adv7611.c
+++ b/board/gdsys/common/adv7611.c
@@ -5,6 +5,8 @@
  * SPDX-License-Identifier:	GPL-2.0+
  */
 
+#ifdef CONFIG_GDSYS_LEGACY_DRIVERS
+
 #include <common.h>
 #include <i2c.h>
 
@@ -175,3 +177,5 @@ out:
 
 	return res;
 }
+
+#endif /* CONFIG_GDSYS_LEGACY_DRIVERS */
diff --git a/board/gdsys/common/ch7301.c b/board/gdsys/common/ch7301.c
index c054e55cf7..b38b485b13 100644
--- a/board/gdsys/common/ch7301.c
+++ b/board/gdsys/common/ch7301.c
@@ -7,6 +7,8 @@
 
 /* Chrontel CH7301C DVI Transmitter */
 
+#ifdef CONFIG_GDSYS_LEGACY_DRIVERS
+
 #include <common.h>
 #include <asm/io.h>
 #include <errno.h>
@@ -62,3 +64,5 @@ int ch7301_probe(unsigned screen, bool power)
 
 	return 0;
 }
+
+#endif /* CONFIG_GDSYS_LEGACY_DRIVERS */
diff --git a/board/gdsys/common/dp501.c b/board/gdsys/common/dp501.c
index 54e7f63f69..232ea13e68 100644
--- a/board/gdsys/common/dp501.c
+++ b/board/gdsys/common/dp501.c
@@ -7,6 +7,8 @@
 
 /* Parade Technologies Inc. DP501 DisplayPort DVI/HDMI Transmitter */
 
+#ifdef CONFIG_GDSYS_LEGACY_DRIVERS
+
 #include <common.h>
 #include <asm/io.h>
 #include <errno.h>
@@ -156,3 +158,5 @@ int dp501_probe(unsigned screen, bool power)
 
 	return 0;
 }
+
+#endif /* CONFIG_GDSYS_LEGACY_DRIVERS */
diff --git a/board/gdsys/common/fanctrl.c b/board/gdsys/common/fanctrl.c
index 44569bb1ab..20bb187cdd 100644
--- a/board/gdsys/common/fanctrl.c
+++ b/board/gdsys/common/fanctrl.c
@@ -5,6 +5,8 @@
  * SPDX-License-Identifier:	GPL-2.0+
  */
 
+#ifdef CONFIG_GDSYS_LEGACY_DRIVERS
+
 #include <common.h>
 #include <i2c.h>
 
@@ -30,3 +32,5 @@ void init_fan_controller(u8 addr)
 	val = i2c_reg_read(addr, FAN_CONFIG) | 0x04;
 	i2c_reg_write(addr, FAN_CONFIG, val);
 }
+
+#endif /* CONFIG_GDSYS_LEGACY_DRIVERS */
diff --git a/board/gdsys/common/fpga.c b/board/gdsys/common/fpga.c
index e10c105feb..cfb6a9d583 100644
--- a/board/gdsys/common/fpga.c
+++ b/board/gdsys/common/fpga.c
@@ -5,6 +5,8 @@
  * SPDX-License-Identifier:	GPL-2.0+
  */
 
+#ifdef CONFIG_GDSYS_LEGACY_DRIVERS
+
 #include <common.h>
 #include <gdsys_fpga.h>
 
@@ -23,3 +25,5 @@ int fpga_get_reg(u32 fpga, u16 *reg, off_t regoff, u16 *data)
 
 	return 0;
 }
+
+#endif /* CONFIG_GDSYS_LEGACY_DRIVERS */
diff --git a/board/gdsys/common/ihs_mdio.c b/board/gdsys/common/ihs_mdio.c
index 262ead5516..d67ec7d38a 100644
--- a/board/gdsys/common/ihs_mdio.c
+++ b/board/gdsys/common/ihs_mdio.c
@@ -5,6 +5,8 @@
  * SPDX-License-Identifier:	GPL-2.0+
  */
 
+#ifdef CONFIG_GDSYS_LEGACY_DRIVERS
+
 #include <common.h>
 
 #include <gdsys_fpga.h>
@@ -86,3 +88,5 @@ int ihs_mdio_init(struct ihs_mdio_info *info)
 
 	return mdio_register(bus);
 }
+
+#endif /* CONFIG_GDSYS_LEGACY_DRIVERS */
diff --git a/board/gdsys/common/ioep-fpga.c b/board/gdsys/common/ioep-fpga.c
index f72a01e5b2..a666b93445 100644
--- a/board/gdsys/common/ioep-fpga.c
+++ b/board/gdsys/common/ioep-fpga.c
@@ -5,6 +5,8 @@
  * SPDX-License-Identifier:	GPL-2.0+
  */
 
+#ifdef CONFIG_GDSYS_LEGACY_DRIVERS
+
 #include <common.h>
 
 #include <gdsys_fpga.h>
@@ -235,3 +237,5 @@ void ioep_fpga_print_info(unsigned int fpga)
 
 	printf(", %d video channel(s)\n", feature_video_channels);
 }
+
+#endif /* CONFIG_GDSYS_LEGACY_DRIVERS */
diff --git a/board/gdsys/common/mclink.c b/board/gdsys/common/mclink.c
index 9f230c9a97..6b1faf4696 100644
--- a/board/gdsys/common/mclink.c
+++ b/board/gdsys/common/mclink.c
@@ -5,6 +5,8 @@
  * SPDX-License-Identifier:	GPL-2.0+
  */
 
+#ifdef CONFIG_GDSYS_LEGACY_DRIVERS
+
 #include <common.h>
 #include <asm/io.h>
 #include <errno.h>
@@ -135,3 +137,5 @@ int mclink_receive(u8 slave, u16 addr, u16 *data)
 
 	return 0;
 }
+
+#endif /* CONFIG_GDSYS_LEGACY_DRIVERS */
diff --git a/board/gdsys/common/osd.c b/board/gdsys/common/osd.c
index add9574369..60e7f460a7 100644
--- a/board/gdsys/common/osd.c
+++ b/board/gdsys/common/osd.c
@@ -5,6 +5,8 @@
  * SPDX-License-Identifier:	GPL-2.0+
  */
 
+#ifdef CONFIG_GDSYS_LEGACY_DRIVERS
+
 #include <common.h>
 #include <i2c.h>
 #include <malloc.h>
@@ -498,3 +500,5 @@ U_BOOT_CMD(
 	"size_x(max. " __stringify(MAX_X_CHARS)
 	") size_y(max. " __stringify(MAX_Y_CHARS) ")\n"
 );
+
+#endif /* CONFIG_GDSYS_LEGACY_DRIVERS */
\ No newline at end of file
diff --git a/board/gdsys/mpc8308/Kconfig b/board/gdsys/mpc8308/Kconfig
index c0247214a9..e913e94b3a 100644
--- a/board/gdsys/mpc8308/Kconfig
+++ b/board/gdsys/mpc8308/Kconfig
@@ -1,3 +1,5 @@
+config GDSYS_LEGACY_DRIVERS
+	bool
 
 config SYS_FPGA0_BASE
 	hex
@@ -32,6 +34,9 @@ config SYS_VENDOR
 config SYS_CONFIG_NAME
 	default "hrcon"
 
+config GDSYS_LEGACY_DRIVERS
+	default y
+
 endif
 
 if TARGET_STRIDER
@@ -45,6 +50,9 @@ config SYS_VENDOR
 config SYS_CONFIG_NAME
 	default "strider"
 
+config GDSYS_LEGACY_DRIVERS
+	default y
+
 endif
 
 config CMD_IOLOOP
diff --git a/board/gdsys/mpc8308/mpc8308.c b/board/gdsys/mpc8308/mpc8308.c
index 8d6a49f86a..3b57494493 100644
--- a/board/gdsys/mpc8308/mpc8308.c
+++ b/board/gdsys/mpc8308/mpc8308.c
@@ -25,6 +25,7 @@
 
 DECLARE_GLOBAL_DATA_PTR;
 
+#ifdef CONFIG_GDSYS_LEGACY_DRIVERS
 /* as gpio output status cannot be read back, we have to buffer it locally */
 u32 gpio0_out;
 
@@ -117,3 +118,4 @@ int board_early_init_r(void)
 
 	return 0;
 }
+#endif
diff --git a/board/gdsys/p1022/Kconfig b/board/gdsys/p1022/Kconfig
index 8514d086b9..8fef636136 100644
--- a/board/gdsys/p1022/Kconfig
+++ b/board/gdsys/p1022/Kconfig
@@ -1,3 +1,6 @@
+config GDSYS_LEGACY_DRIVERS
+	bool
+
 if TARGET_CONTROLCENTERD
 
 config SYS_BOARD
@@ -9,4 +12,7 @@ config SYS_VENDOR
 config SYS_CONFIG_NAME
 	default "controlcenterd"
 
+config GDSYS_LEGACY_DRIVERS
+	default y
+
 endif
diff --git a/include/gdsys_fpga.h b/include/gdsys_fpga.h
index 34d6eeb253..19a6e6ca3f 100644
--- a/include/gdsys_fpga.h
+++ b/include/gdsys_fpga.h
@@ -8,6 +8,7 @@
 #ifndef __GDSYS_FPGA_H
 #define __GDSYS_FPGA_H
 
+#ifdef CONFIG_GDSYS_LEGACY_DRIVERS
 int init_func_fpga(void);
 
 enum {
@@ -34,6 +35,7 @@ extern struct ihs_fpga *fpga_ptr[];
 		     &fpga_ptr[ix]->fld, \
 		     offsetof(struct ihs_fpga, fld), \
 		     val)
+#endif
 
 struct ihs_gpio {
 	u16 read;
-- 
2.11.0

^ permalink raw reply related	[flat|nested] 138+ messages in thread

* [U-Boot] [PATCH 26/51] strider, hrcon: Reset CAT phy on CON2 module
  2017-07-14 12:54 [U-Boot] [PATCH 00/51] gdsys: Add support for Gazerbeam board Mario Six
                   ` (24 preceding siblings ...)
  2017-07-14 12:55 ` [U-Boot] [PATCH 25/51] gdsys: Introduce GDSYS_LEGACY_DRIVERS Mario Six
@ 2017-07-14 12:55 ` Mario Six
  2017-07-19  9:05   ` Simon Glass
  2017-07-14 12:55 ` [U-Boot] [PATCH 27/51] gdsys:phy: Adapt fixup_88e1518() to latest Release Notes Mario Six
                   ` (24 subsequent siblings)
  50 siblings, 1 reply; 138+ messages in thread
From: Mario Six @ 2017-07-14 12:55 UTC (permalink / raw)
  To: u-boot

From: Dirk Eibach <dirk.eibach@gdsys.cc>

The phy on the CON2 module needs a defined reset pulse of at least 10 ms
to work reliably.

Signed-off-by: Dirk Eibach <dirk.eibach@gdsys.cc>
Signed-off-by: Mario Six <mario.six@gdsys.cc>
---

 board/gdsys/mpc8308/hrcon.c   | 30 ++++++++++++++++++++++++++++++
 board/gdsys/mpc8308/strider.c | 24 ++++++++++++++++++++++++
 2 files changed, 54 insertions(+)

diff --git a/board/gdsys/mpc8308/hrcon.c b/board/gdsys/mpc8308/hrcon.c
index bbe93a3488..d2acd1a677 100644
--- a/board/gdsys/mpc8308/hrcon.c
+++ b/board/gdsys/mpc8308/hrcon.c
@@ -58,6 +58,26 @@ struct {
 	u8 addr;
 } hrcon_fans[] = CONFIG_HRCON_FANS;
 
+#ifdef CONFIG_HRCON_DH
+struct {
+	u8 bus;
+	u8 addr;
+	u16 mask;
+} rgmii2_reset[] = { { 0, 0x23, 0x0100},
+		     {10, 0x23, 0x0100},
+		     {11, 0x23, 0x0100},
+		     {12, 0x23, 0x0100} };
+#else
+struct {
+	u8 bus;
+	u8 addr;
+	u16 mask;
+} rgmii2_reset[] = { {0, 0x23, 0x0100},
+		     {6, 0x23, 0x0100},
+		     {7, 0x23, 0x0100},
+		     {8, 0x23, 0x0100} };
+#endif
+
 int fpga_set_reg(u32 fpga, u16 *reg, off_t regoff, u16 data)
 {
 	int res;
@@ -160,6 +180,16 @@ int last_stage_init(void)
 				MCFPGA_RESET_N);
 	}
 
+	if (hw_type_cat && ch0_rgmii2_present) {
+		i2c_set_bus_num(rgmii2_reset[0].bus);
+		pca953x_set_val(rgmii2_reset[0].addr, rgmii2_reset[0].mask, 0);
+		pca953x_set_dir(rgmii2_reset[0].addr, rgmii2_reset[0].mask, 0);
+		mdelay(10);
+		pca953x_set_dir(rgmii2_reset[0].addr, rgmii2_reset[0].mask,
+				rgmii2_reset[0].mask);
+		i2c_set_bus_num(0);
+	}
+
 	if (hw_type_cat) {
 		uint mux_ch;
 		int retval;
diff --git a/board/gdsys/mpc8308/strider.c b/board/gdsys/mpc8308/strider.c
index ac785da8e6..e838913268 100644
--- a/board/gdsys/mpc8308/strider.c
+++ b/board/gdsys/mpc8308/strider.c
@@ -61,6 +61,17 @@ struct {
 	u8 addr;
 } strider_fans[] = CONFIG_STRIDER_FANS;
 
+#if defined(CONFIG_STRIDER_CON) || defined(CONFIG_STRIDER_CON_DP)
+struct {
+	u8 bus;
+	u8 addr;
+	u16 mask;
+} sgmii2_reset[] = { { 0, 0x23, 0x0100},
+		     {10, 0x23, 0x0100},
+		     {11, 0x23, 0x0100},
+		     {12, 0x23, 0x0100} };
+#endif
+
 int fpga_set_reg(u32 fpga, u16 *reg, off_t regoff, u16 data)
 {
 	int res;
@@ -178,6 +189,18 @@ int last_stage_init(void)
 				MCFPGA_RESET_N);
 	}
 
+#if defined(CONFIG_STRIDER_CON) || defined(CONFIG_STRIDER_CON_DP)
+	if (hw_type_cat && ch0_sgmii2_present) {
+		i2c_set_bus_num(sgmii2_reset[0].bus);
+		pca953x_set_val(sgmii2_reset[0].addr, sgmii2_reset[0].mask, 0);
+		pca953x_set_dir(sgmii2_reset[0].addr, sgmii2_reset[0].mask, 0);
+		mdelay(10);
+		pca953x_set_dir(sgmii2_reset[0].addr, sgmii2_reset[0].mask,
+				sgmii2_reset[0].mask);
+		i2c_set_bus_num(0);
+	}
+#endif
+
 	if (hw_type_cat) {
 		int retval;
 		struct mii_dev *mdiodev = mdio_alloc();
@@ -261,6 +284,7 @@ int last_stage_init(void)
 		ch7301_probe(k, false);
 		dp501_probe(k, false);
 #endif
+
 		if (hw_type_cat) {
 			int retval;
 			struct mii_dev *mdiodev = mdio_alloc();
-- 
2.11.0

^ permalink raw reply related	[flat|nested] 138+ messages in thread

* [U-Boot] [PATCH 27/51] gdsys:phy: Adapt fixup_88e1518() to latest Release Notes
  2017-07-14 12:54 [U-Boot] [PATCH 00/51] gdsys: Add support for Gazerbeam board Mario Six
                   ` (25 preceding siblings ...)
  2017-07-14 12:55 ` [U-Boot] [PATCH 26/51] strider, hrcon: Reset CAT phy on CON2 module Mario Six
@ 2017-07-14 12:55 ` Mario Six
  2017-07-19  9:05   ` Simon Glass
  2017-07-14 12:55 ` [U-Boot] [PATCH 28/51] i2c: ihs_i2c: Prepare DM conversion Mario Six
                   ` (23 subsequent siblings)
  50 siblings, 1 reply; 138+ messages in thread
From: Mario Six @ 2017-07-14 12:55 UTC (permalink / raw)
  To: u-boot

From: Dirk Eibach <dirk.eibach@gdsys.cc>

The initialization sequence described in the latest Release Notes
MV-S302033-00 for the Marvell 88E1518 phy omits two register writes.

Use this new sequence for the setup of this phy.

Signed-off-by: Dirk Eibach <dirk.eibach@gdsys.cc>
Signed-off-by: Mario Six <mario.six@gdsys.cc>
---

 board/gdsys/common/phy.c | 2 --
 1 file changed, 2 deletions(-)

diff --git a/board/gdsys/common/phy.c b/board/gdsys/common/phy.c
index fb92658178..e45f923fed 100644
--- a/board/gdsys/common/phy.c
+++ b/board/gdsys/common/phy.c
@@ -46,8 +46,6 @@ struct mii_setupcmd fixup_88e1518[] = {
 	{ MIICMD_SET, 16, 0x214d },
 	{ MIICMD_SET, 17, 0xcc0c },
 	{ MIICMD_SET, 16, 0x2159 },
-	{ MIICMD_SET, 22, 0x00fb },
-	{ MIICMD_SET,  7, 0xc00d },
 	{ MIICMD_SET, 22, 0x0000 },
 };
 
-- 
2.11.0

^ permalink raw reply related	[flat|nested] 138+ messages in thread

* [U-Boot] [PATCH 28/51] i2c: ihs_i2c: Prepare DM conversion
  2017-07-14 12:54 [U-Boot] [PATCH 00/51] gdsys: Add support for Gazerbeam board Mario Six
                   ` (26 preceding siblings ...)
  2017-07-14 12:55 ` [U-Boot] [PATCH 27/51] gdsys:phy: Adapt fixup_88e1518() to latest Release Notes Mario Six
@ 2017-07-14 12:55 ` Mario Six
  2017-07-19  9:05   ` Simon Glass
  2017-07-14 12:55 ` [U-Boot] [PATCH 29/51] i2c: ihs_i2c: Make DM compatible Mario Six
                   ` (22 subsequent siblings)
  50 siblings, 1 reply; 138+ messages in thread
From: Mario Six @ 2017-07-14 12:55 UTC (permalink / raw)
  To: u-boot

Prepare the function interface of the ihs_i2c driver for DM conversion
in a future patch.

While we're at it, fix some style violations, and make the code more readable.

Signed-off-by: Mario Six <mario.six@gdsys.cc>
---

 drivers/i2c/ihs_i2c.c | 74 +++++++++++++++++++++++++++++++--------------------
 1 file changed, 45 insertions(+), 29 deletions(-)

diff --git a/drivers/i2c/ihs_i2c.c b/drivers/i2c/ihs_i2c.c
index 29612e69fe..e066ad53db 100644
--- a/drivers/i2c/ihs_i2c.c
+++ b/drivers/i2c/ihs_i2c.c
@@ -41,30 +41,38 @@ DECLARE_GLOBAL_DATA_PTR;
 #endif
 
 enum {
-	I2CINT_ERROR_EV = 1 << 13,
-	I2CINT_TRANSMIT_EV = 1 << 14,
-	I2CINT_RECEIVE_EV = 1 << 15,
+	I2CINT_ERROR_EV = BIT(13),
+	I2CINT_TRANSMIT_EV = BIT(14),
+	I2CINT_RECEIVE_EV = BIT(15),
 };
 
 enum {
+	I2CMB_READ = 0 << 10,
 	I2CMB_WRITE = 1 << 10,
+	I2CMB_1BYTE = 0 << 11,
 	I2CMB_2BYTE = 1 << 11,
+	I2CMB_DONT_HOLD_BUS = 0 << 13,
 	I2CMB_HOLD_BUS = 1 << 13,
 	I2CMB_NATIVE = 2 << 14,
 };
 
+enum {
+	I2COP_WRITE = 0,
+	I2COP_READ = 1,
+};
+
 static int wait_for_int(bool read)
 {
 	u16 val;
-	unsigned int ctr = 0;
+	uint ctr = 0;
 
 	I2C_GET_REG(interrupt_status, &val);
+	/* Wait until error or receive/transmit interrupt was raised */
 	while (!(val & (I2CINT_ERROR_EV
 	       | (read ? I2CINT_RECEIVE_EV : I2CINT_TRANSMIT_EV)))) {
 		udelay(10);
-		if (ctr++ > 5000) {
+		if (ctr++ > 5000)
 			return 1;
-		}
 		I2C_GET_REG(interrupt_status, &val);
 	}
 
@@ -76,10 +84,12 @@ static int ihs_i2c_transfer(uchar chip, uchar *buffer, int len, bool read,
 {
 	u16 val;
 
+	/* Clear interrupt status */
 	I2C_SET_REG(interrupt_status, I2CINT_ERROR_EV
 		     | I2CINT_RECEIVE_EV | I2CINT_TRANSMIT_EV);
 	I2C_GET_REG(interrupt_status, &val);
 
+	/* If we want to write and have data, write the bytes to the mailbox */
 	if (!read && len) {
 		val = buffer[0];
 
@@ -98,6 +108,7 @@ static int ihs_i2c_transfer(uchar chip, uchar *buffer, int len, bool read,
 	if (wait_for_int(read))
 		return 1;
 
+	/* If we want to read, get the bytes from the mailbox */
 	if (read) {
 		I2C_GET_REG(read_mailbox_ext, &val);
 		buffer[0] = val & 0xff;
@@ -108,55 +119,44 @@ static int ihs_i2c_transfer(uchar chip, uchar *buffer, int len, bool read,
 	return 0;
 }
 
-static int ihs_i2c_address(uchar chip, uint addr, int alen, bool hold_bus)
+static int ihs_i2c_address(uchar chip, u8 *addr, int alen, bool hold_bus)
 {
-	int shift = (alen-1) * 8;
-
 	while (alen) {
 		int transfer = min(alen, 2);
-		uchar buf[2];
 		bool is_last = alen <= transfer;
 
-		buf[0] = addr >> shift;
-		if (alen > 1)
-			buf[1] = addr >> (shift - 8);
-
-		if (ihs_i2c_transfer(chip, buf, transfer, false,
+		if (ihs_i2c_transfer(chip, addr, transfer, I2COP_WRITE,
 				     hold_bus ? false : is_last))
 			return 1;
 
-		shift -= 16;
 		alen -= transfer;
 	}
 
 	return 0;
 }
 
-static int ihs_i2c_access(struct i2c_adapter *adap, uchar chip, uint addr,
-			  int alen, uchar *buffer, int len, bool read)
+static int ihs_i2c_access(struct i2c_adapter *adap, uchar chip, u8 *addr,
+			  int alen, uchar *buffer, int len, int read)
 {
-	if (len <= 0)
-		return 1;
-
-	if (ihs_i2c_address(chip, addr, alen, len))
+	/* Don't hold the bus if length of data to send/receive is zero */
+	if (len <= 0 || ihs_i2c_address(chip, addr, alen, len))
 		return 1;
 
 	while (len) {
 		int transfer = min(len, 2);
+		bool is_last = len <= transfer;
 
 		if (ihs_i2c_transfer(chip, buffer, transfer, read,
-				     len <= transfer))
-			return 1;
+				     is_last))
+			return 2;
 
 		buffer += transfer;
-		addr += transfer;
 		len -= transfer;
 	}
 
 	return 0;
 }
 
-
 static void ihs_i2c_init(struct i2c_adapter *adap, int speed, int slaveaddr)
 {
 #ifdef CONFIG_SYS_I2C_INIT_BOARD
@@ -173,7 +173,7 @@ static int ihs_i2c_probe(struct i2c_adapter *adap, uchar chip)
 {
 	uchar buffer[2];
 
-	if (ihs_i2c_transfer(chip, buffer, 0, true, true))
+	if (ihs_i2c_transfer(chip, buffer, 0, I2COP_READ, true))
 		return 1;
 
 	return 0;
@@ -182,13 +182,29 @@ static int ihs_i2c_probe(struct i2c_adapter *adap, uchar chip)
 static int ihs_i2c_read(struct i2c_adapter *adap, uchar chip, uint addr,
 			int alen, uchar *buffer, int len)
 {
-	return ihs_i2c_access(adap, chip, addr, alen, buffer, len, true);
+	u8 addr_bytes[4];
+
+	addr_bytes[0] = (addr >> 0) & 0xFF;
+	addr_bytes[1] = (addr >> 8) & 0xFF;
+	addr_bytes[2] = (addr >> 16) & 0xFF;
+	addr_bytes[3] = (addr >> 24) & 0xFF;
+
+	return ihs_i2c_access(adap, chip, addr_bytes, alen, buffer, len,
+			      I2COP_READ);
 }
 
 static int ihs_i2c_write(struct i2c_adapter *adap, uchar chip, uint addr,
 			 int alen, uchar *buffer, int len)
 {
-	return ihs_i2c_access(adap, chip, addr, alen, buffer, len, false);
+	u8 addr_bytes[4];
+
+	addr_bytes[0] = (addr >> 0) & 0xFF;
+	addr_bytes[1] = (addr >> 8) & 0xFF;
+	addr_bytes[2] = (addr >> 16) & 0xFF;
+	addr_bytes[3] = (addr >> 24) & 0xFF;
+
+	return ihs_i2c_access(adap, chip, addr_bytes, alen, buffer, len,
+			      I2COP_WRITE);
 }
 
 static unsigned int ihs_i2c_set_bus_speed(struct i2c_adapter *adap,
-- 
2.11.0

^ permalink raw reply related	[flat|nested] 138+ messages in thread

* [U-Boot] [PATCH 29/51] i2c: ihs_i2c: Make DM compatible
  2017-07-14 12:54 [U-Boot] [PATCH 00/51] gdsys: Add support for Gazerbeam board Mario Six
                   ` (27 preceding siblings ...)
  2017-07-14 12:55 ` [U-Boot] [PATCH 28/51] i2c: ihs_i2c: Prepare DM conversion Mario Six
@ 2017-07-14 12:55 ` Mario Six
  2017-07-19  9:05   ` Simon Glass
  2017-07-14 12:55 ` [U-Boot] [PATCH 30/51] i2c: ihs_i2c: Factor out send_buffer method Mario Six
                   ` (21 subsequent siblings)
  50 siblings, 1 reply; 138+ messages in thread
From: Mario Six @ 2017-07-14 12:55 UTC (permalink / raw)
  To: u-boot

Make the ihs_i2c driver DM-compatible; for legacy boards, the old functions are
retained within #ifdefs.

No board uses the new DM driver yet; this patch only lays the foundation for
future support.

Signed-off-by: Mario Six <mario.six@gdsys.cc>
---

 drivers/i2c/Kconfig          |   6 ++
 drivers/i2c/ihs_i2c.c        | 197 ++++++++++++++++++++++++++++++++++++++++++-
 scripts/config_whitelist.txt |   1 -
 3 files changed, 200 insertions(+), 4 deletions(-)

diff --git a/drivers/i2c/Kconfig b/drivers/i2c/Kconfig
index 8ac1cc6a15..12901f544e 100644
--- a/drivers/i2c/Kconfig
+++ b/drivers/i2c/Kconfig
@@ -201,6 +201,12 @@ config TEGRA186_BPMP_I2C
 	  by the BPMP, and can only be accessed by the main CPU via IPC
 	  requests to the BPMP. This driver covers the latter case.
 
+config SYS_I2C_IHS
+	bool "gdsys IHS I2C driver"
+	depends on DM_I2C
+	help
+	  Support for gdsys IHS I2C driver on FPGA bus.
+
 source "drivers/i2c/muxes/Kconfig"
 
 endmenu
diff --git a/drivers/i2c/ihs_i2c.c b/drivers/i2c/ihs_i2c.c
index e066ad53db..6aeda52cfa 100644
--- a/drivers/i2c/ihs_i2c.c
+++ b/drivers/i2c/ihs_i2c.c
@@ -3,18 +3,38 @@
  * Dirk Eibach,  Guntermann & Drunck GmbH, eibach at gdsys.de
  *
  * SPDX-License-Identifier:	GPL-2.0+
- *
- * NOTE: This driver should be converted to driver model before June 2017.
- * Please see doc/driver-model/i2c-howto.txt for instructions.
  */
 
 #include <common.h>
 #include <i2c.h>
+#ifdef CONFIG_DM_I2C
+#include <dm.h>
+#include <gdsys_soc.h>
+#include <ihs_fpga.h>
+#else
 #include <gdsys_fpga.h>
+#endif
 
 DECLARE_GLOBAL_DATA_PTR;
 
+#ifdef CONFIG_DM_I2C
+struct ihs_i2c_priv {
+	uint speed;
+	phys_addr_t addr;
+};
+
+enum {
+	REG_INTERRUPT_STATUS = 0x00,
+	REG_INTERRUPT_ENABLE_CONTROL = 0x02,
+	REG_WRITE_MAILBOX_EXT = 0x04,
+	REG_WRITE_MAILBOX = 0x06,
+	REG_READ_MAILBOX_EXT = 0x08,
+	REG_READ_MAILBOX = 0x0A,
+};
+
+#else /* !CONFIG_DM_I2C */
 #ifdef CONFIG_SYS_I2C_IHS_DUAL
+
 #define I2C_SET_REG(fld, val) \
 	do { \
 		if (I2C_ADAP_HWNR & 0x10) \
@@ -39,6 +59,7 @@ DECLARE_GLOBAL_DATA_PTR;
 #define I2C_GET_REG(fld, val) \
 		FPGA_GET_REG(I2C_ADAP_HWNR, i2c0.fld, val)
 #endif
+#endif /* CONFIG_DM_I2C */
 
 enum {
 	I2CINT_ERROR_EV = BIT(13),
@@ -61,33 +82,67 @@ enum {
 	I2COP_READ = 1,
 };
 
+#ifdef CONFIG_DM_I2C
+static int wait_for_int(struct udevice *dev, int read)
+#else
 static int wait_for_int(bool read)
+#endif
 {
 	u16 val;
 	uint ctr = 0;
+#ifdef CONFIG_DM_I2C
+	struct ihs_i2c_priv *priv = dev_get_priv(dev);
+	struct gdsys_soc_child_platdata *pplat = dev_get_parent_platdata(dev);
+#endif
 
+#ifdef CONFIG_DM_I2C
+	val = fpga_in_le16(pplat->fpga,
+			   priv->addr + REG_INTERRUPT_STATUS);
+#else
 	I2C_GET_REG(interrupt_status, &val);
+#endif
 	/* Wait until error or receive/transmit interrupt was raised */
 	while (!(val & (I2CINT_ERROR_EV
 	       | (read ? I2CINT_RECEIVE_EV : I2CINT_TRANSMIT_EV)))) {
 		udelay(10);
 		if (ctr++ > 5000)
 			return 1;
+#ifdef CONFIG_DM_I2C
+		val = fpga_in_le16(pplat->fpga,
+				   priv->addr + REG_INTERRUPT_STATUS);
+#else
 		I2C_GET_REG(interrupt_status, &val);
+#endif
 	}
 
 	return (val & I2CINT_ERROR_EV) ? 1 : 0;
 }
 
+#ifdef CONFIG_DM_I2C
+static int ihs_i2c_transfer(struct udevice *dev, uchar chip,
+			    uchar *buffer, int len, int read, bool is_last)
+#else
 static int ihs_i2c_transfer(uchar chip, uchar *buffer, int len, bool read,
 			    bool is_last)
+#endif
 {
 	u16 val;
+#ifdef CONFIG_DM_I2C
+	struct ihs_i2c_priv *priv = dev_get_priv(dev);
+	struct gdsys_soc_child_platdata *pplat = dev_get_parent_platdata(dev);
+#endif
 
 	/* Clear interrupt status */
+#ifdef CONFIG_DM_I2C
+	fpga_out_le16(pplat->fpga, priv->addr + REG_INTERRUPT_STATUS,
+		      I2CINT_ERROR_EV | I2CINT_RECEIVE_EV | I2CINT_TRANSMIT_EV);
+	val = fpga_in_le16(pplat->fpga,
+			   priv->addr + REG_INTERRUPT_STATUS);
+#else
 	I2C_SET_REG(interrupt_status, I2CINT_ERROR_EV
 		     | I2CINT_RECEIVE_EV | I2CINT_TRANSMIT_EV);
 	I2C_GET_REG(interrupt_status, &val);
+#endif
 
 	/* If we want to write and have data, write the bytes to the mailbox */
 	if (!read && len) {
@@ -95,22 +150,45 @@ static int ihs_i2c_transfer(uchar chip, uchar *buffer, int len, bool read,
 
 		if (len > 1)
 			val |= buffer[1] << 8;
+#ifdef CONFIG_DM_I2C
+		fpga_out_le16(pplat->fpga,
+			      priv->addr + REG_WRITE_MAILBOX_EXT, val);
+#else
 		I2C_SET_REG(write_mailbox_ext, val);
+#endif
 	}
 
+#ifdef CONFIG_DM_I2C
+	fpga_out_le16(pplat->fpga, priv->addr + REG_WRITE_MAILBOX,
+		      I2CMB_NATIVE
+		      | (read ? I2CMB_READ : I2CMB_WRITE)
+		      | (chip << 1)
+		      | ((len > 1) ? I2CMB_2BYTE : I2CMB_1BYTE)
+		      | (!is_last ? I2CMB_HOLD_BUS : I2CMB_DONT_HOLD_BUS));
+#else
 	I2C_SET_REG(write_mailbox,
 		    I2CMB_NATIVE
 		    | (read ? 0 : I2CMB_WRITE)
 		    | (chip << 1)
 		    | ((len > 1) ? I2CMB_2BYTE : 0)
 		    | (is_last ? 0 : I2CMB_HOLD_BUS));
+#endif
 
+#ifdef CONFIG_DM_I2C
+	if (wait_for_int(dev, read))
+#else
 	if (wait_for_int(read))
+#endif
 		return 1;
 
 	/* If we want to read, get the bytes from the mailbox */
 	if (read) {
+#ifdef CONFIG_DM_I2C
+		val = fpga_in_le16(pplat->fpga,
+				   priv->addr + REG_READ_MAILBOX_EXT);
+#else
 		I2C_GET_REG(read_mailbox_ext, &val);
+#endif
 		buffer[0] = val & 0xff;
 		if (len > 1)
 			buffer[1] = val >> 8;
@@ -119,15 +197,25 @@ static int ihs_i2c_transfer(uchar chip, uchar *buffer, int len, bool read,
 	return 0;
 }
 
+#ifdef CONFIG_DM_I2C
+static int ihs_i2c_address(struct udevice *dev, uchar chip, u8 *addr, int alen, bool hold_bus)
+#else
 static int ihs_i2c_address(uchar chip, u8 *addr, int alen, bool hold_bus)
+#endif
 {
 	while (alen) {
 		int transfer = min(alen, 2);
 		bool is_last = alen <= transfer;
 
+#ifdef CONFIG_DM_I2C
+		if (ihs_i2c_transfer(dev, chip, addr, transfer, I2COP_WRITE,
+				     hold_bus ? false : is_last))
+			return 1;
+#else
 		if (ihs_i2c_transfer(chip, addr, transfer, I2COP_WRITE,
 				     hold_bus ? false : is_last))
 			return 1;
+#endif
 
 		alen -= transfer;
 	}
@@ -135,20 +223,36 @@ static int ihs_i2c_address(uchar chip, u8 *addr, int alen, bool hold_bus)
 	return 0;
 }
 
+#ifdef CONFIG_DM_I2C
+static int ihs_i2c_access(struct udevice *dev, uchar chip, u8 *addr,
+			  int alen, uchar *buffer, int len, int read)
+#else
 static int ihs_i2c_access(struct i2c_adapter *adap, uchar chip, u8 *addr,
 			  int alen, uchar *buffer, int len, int read)
+#endif
 {
 	/* Don't hold the bus if length of data to send/receive is zero */
+#ifdef CONFIG_DM_I2C
+	if (len <= 0 || ihs_i2c_address(dev, chip, addr, alen, len))
+		return 1;
+#else
 	if (len <= 0 || ihs_i2c_address(chip, addr, alen, len))
 		return 1;
+#endif
 
 	while (len) {
 		int transfer = min(len, 2);
 		bool is_last = len <= transfer;
 
+#ifdef CONFIG_DM_I2C
+		if (ihs_i2c_transfer(dev, chip, buffer, transfer, read,
+				     is_last))
+			return 2;
+#else
 		if (ihs_i2c_transfer(chip, buffer, transfer, read,
 				     is_last))
 			return 2;
+#endif
 
 		buffer += transfer;
 		len -= transfer;
@@ -157,6 +261,92 @@ static int ihs_i2c_access(struct i2c_adapter *adap, uchar chip, u8 *addr,
 	return 0;
 }
 
+#ifdef CONFIG_DM_I2C
+
+int ihs_i2c_probe(struct udevice *bus)
+{
+	struct ihs_i2c_priv *priv = dev_get_priv(bus);
+	int addr;
+
+	addr = fdtdec_get_int(gd->fdt_blob, dev_of_offset(bus), "reg", -1);
+
+	priv->addr = addr;
+
+	return 0;
+}
+
+static int ihs_i2c_set_bus_speed(struct udevice *bus, uint speed)
+{
+	struct ihs_i2c_priv *priv = dev_get_priv(bus);
+
+	if (speed != priv->speed && priv->speed != 0)
+		return 1;
+
+	priv->speed = speed;
+
+	return 0;
+}
+
+static int ihs_i2c_xfer(struct udevice *bus, struct i2c_msg *msg, int nmsgs)
+{
+	struct i2c_msg *dmsg, *omsg, dummy;
+
+	memset(&dummy, 0, sizeof(struct i2c_msg));
+
+	/* We expect either two messages (one with an offset and one with the
+	 * actucal data) or one message (just data)
+	 */
+	if (nmsgs > 2 || nmsgs == 0) {
+		debug("%s: Only one or two messages are supported.", __func__);
+		return -1;
+	}
+
+	omsg = nmsgs == 1 ? &dummy : msg;
+	dmsg = nmsgs == 1 ? msg : msg + 1;
+
+	if (dmsg->flags & I2C_M_RD)
+		return ihs_i2c_access(bus, dmsg->addr, omsg->buf,
+				      omsg->len, dmsg->buf, dmsg->len,
+				      I2COP_READ);
+	else
+		return ihs_i2c_access(bus, dmsg->addr, omsg->buf,
+				      omsg->len, dmsg->buf, dmsg->len,
+				      I2COP_WRITE);
+}
+
+static int ihs_i2c_probe_chip(struct udevice *bus, u32 chip_addr,
+			      u32 chip_flags)
+{
+	uchar buffer[2];
+
+	if (ihs_i2c_transfer(bus, chip_addr, buffer, 0, I2COP_READ, true))
+		return 1;
+
+	return 0;
+}
+
+static const struct dm_i2c_ops ihs_i2c_ops = {
+	.xfer           = ihs_i2c_xfer,
+	.probe_chip     = ihs_i2c_probe_chip,
+	.set_bus_speed  = ihs_i2c_set_bus_speed,
+};
+
+static const struct udevice_id ihs_i2c_ids[] = {
+	{ .compatible = "gdsys,ihs_i2cmaster", },
+	{ /* sentinel */ }
+};
+
+U_BOOT_DRIVER(i2c_ihs) = {
+	.name = "i2c_ihs",
+	.id = UCLASS_I2C,
+	.of_match = ihs_i2c_ids,
+	.probe = ihs_i2c_probe,
+	.priv_auto_alloc_size = sizeof(struct ihs_i2c_priv),
+	.ops = &ihs_i2c_ops,
+};
+
+#else /* CONFIG_DM_I2C */
+
 static void ihs_i2c_init(struct i2c_adapter *adap, int speed, int slaveaddr)
 {
 #ifdef CONFIG_SYS_I2C_INIT_BOARD
@@ -274,3 +464,4 @@ U_BOOT_I2C_ADAP_COMPLETE(ihs3_1, ihs_i2c_init, ihs_i2c_probe,
 			 CONFIG_SYS_I2C_IHS_SLAVE_3_1, 19)
 #endif
 #endif
+#endif /* CONFIG_DM_I2C */
diff --git a/scripts/config_whitelist.txt b/scripts/config_whitelist.txt
index 64a4b1190e..e0cb57e972 100644
--- a/scripts/config_whitelist.txt
+++ b/scripts/config_whitelist.txt
@@ -3500,7 +3500,6 @@ CONFIG_SYS_I2C_G762_ADDR
 CONFIG_SYS_I2C_GENERIC_MAC
 CONFIG_SYS_I2C_IDT6V49205B
 CONFIG_SYS_I2C_IFDR_DIV
-CONFIG_SYS_I2C_IHS
 CONFIG_SYS_I2C_IHS_CH0
 CONFIG_SYS_I2C_IHS_CH0_1
 CONFIG_SYS_I2C_IHS_CH1
-- 
2.11.0

^ permalink raw reply related	[flat|nested] 138+ messages in thread

* [U-Boot] [PATCH 30/51] i2c: ihs_i2c: Factor out send_buffer method
  2017-07-14 12:54 [U-Boot] [PATCH 00/51] gdsys: Add support for Gazerbeam board Mario Six
                   ` (28 preceding siblings ...)
  2017-07-14 12:55 ` [U-Boot] [PATCH 29/51] i2c: ihs_i2c: Make DM compatible Mario Six
@ 2017-07-14 12:55 ` Mario Six
  2017-07-19  9:05   ` Simon Glass
  2017-07-14 12:55 ` [U-Boot] [PATCH 31/51] gdsys: mpc8308: Add FPGA flavor option Mario Six
                   ` (20 subsequent siblings)
  50 siblings, 1 reply; 138+ messages in thread
From: Mario Six @ 2017-07-14 12:55 UTC (permalink / raw)
  To: u-boot

Simplify the driver logic by extracting a common send_buffer method.

Signed-off-by: Mario Six <mario.six@gdsys.cc>
---

 drivers/i2c/ihs_i2c.c | 50 ++++++++++++++++++++++++++------------------------
 1 file changed, 26 insertions(+), 24 deletions(-)

diff --git a/drivers/i2c/ihs_i2c.c b/drivers/i2c/ihs_i2c.c
index 6aeda52cfa..aa15608065 100644
--- a/drivers/i2c/ihs_i2c.c
+++ b/drivers/i2c/ihs_i2c.c
@@ -198,32 +198,48 @@ static int ihs_i2c_transfer(uchar chip, uchar *buffer, int len, bool read,
 }
 
 #ifdef CONFIG_DM_I2C
-static int ihs_i2c_address(struct udevice *dev, uchar chip, u8 *addr, int alen, bool hold_bus)
+static int ihs_i2c_send_buffer(struct udevice *dev, uchar chip, u8 *data, int len, bool hold_bus, int read)
 #else
-static int ihs_i2c_address(uchar chip, u8 *addr, int alen, bool hold_bus)
+static int ihs_i2c_send_buffer(uchar chip, u8 *data, int len, bool hold_bus,
+			       int read)
 #endif
 {
-	while (alen) {
-		int transfer = min(alen, 2);
-		bool is_last = alen <= transfer;
+	while (len) {
+		int transfer = min(len, 2);
+		bool is_last = len <= transfer;
 
 #ifdef CONFIG_DM_I2C
-		if (ihs_i2c_transfer(dev, chip, addr, transfer, I2COP_WRITE,
+		if (ihs_i2c_transfer(dev, chip, data, transfer, read,
 				     hold_bus ? false : is_last))
 			return 1;
 #else
-		if (ihs_i2c_transfer(chip, addr, transfer, I2COP_WRITE,
+		if (ihs_i2c_transfer(chip, data, transfer, read,
 				     hold_bus ? false : is_last))
 			return 1;
 #endif
 
-		alen -= transfer;
+		data += transfer;
+		len -= transfer;
 	}
 
 	return 0;
 }
 
 #ifdef CONFIG_DM_I2C
+static int ihs_i2c_address(struct udevice *dev, uchar chip, u8 *addr, int alen,
+			   bool hold_bus)
+#else
+static int ihs_i2c_address(uchar chip, u8 *addr, int alen, bool hold_bus)
+#endif
+{
+#ifdef CONFIG_DM_I2C
+	return ihs_i2c_send_buffer(dev, chip, addr, alen, hold_bus, I2COP_WRITE);
+#else
+	return ihs_i2c_send_buffer(chip, addr, alen, hold_bus, I2COP_WRITE);
+#endif
+}
+
+#ifdef CONFIG_DM_I2C
 static int ihs_i2c_access(struct udevice *dev, uchar chip, u8 *addr,
 			  int alen, uchar *buffer, int len, int read)
 #else
@@ -240,25 +256,11 @@ static int ihs_i2c_access(struct i2c_adapter *adap, uchar chip, u8 *addr,
 		return 1;
 #endif
 
-	while (len) {
-		int transfer = min(len, 2);
-		bool is_last = len <= transfer;
-
 #ifdef CONFIG_DM_I2C
-		if (ihs_i2c_transfer(dev, chip, buffer, transfer, read,
-				     is_last))
-			return 2;
+	return ihs_i2c_send_buffer(dev, chip, buffer, len, false, read);
 #else
-		if (ihs_i2c_transfer(chip, buffer, transfer, read,
-				     is_last))
-			return 2;
+	return ihs_i2c_send_buffer(chip, buffer, len, false, read);
 #endif
-
-		buffer += transfer;
-		len -= transfer;
-	}
-
-	return 0;
 }
 
 #ifdef CONFIG_DM_I2C
-- 
2.11.0

^ permalink raw reply related	[flat|nested] 138+ messages in thread

* [U-Boot] [PATCH 31/51] gdsys: mpc8308: Add FPGA flavor option
  2017-07-14 12:54 [U-Boot] [PATCH 00/51] gdsys: Add support for Gazerbeam board Mario Six
                   ` (29 preceding siblings ...)
  2017-07-14 12:55 ` [U-Boot] [PATCH 30/51] i2c: ihs_i2c: Factor out send_buffer method Mario Six
@ 2017-07-14 12:55 ` Mario Six
  2017-07-19  9:05   ` Simon Glass
  2017-07-14 12:55 ` [U-Boot] [PATCH 32/51] drivers: Add ihs_fpga and gdsys_soc drivers Mario Six
                   ` (19 subsequent siblings)
  50 siblings, 1 reply; 138+ messages in thread
From: Mario Six @ 2017-07-14 12:55 UTC (permalink / raw)
  To: u-boot

More recent versions of IHS FPGAs feature a different memory layout.

Add a Kconfig option to differentiate between the legacy layout, and the
new layout (which is used on the upcoming "Gazerbeam" and later boards).

Signed-off-by: Mario Six <mario.six@gdsys.cc>
---

 board/gdsys/mpc8308/Kconfig | 11 +++++++++++
 1 file changed, 11 insertions(+)

diff --git a/board/gdsys/mpc8308/Kconfig b/board/gdsys/mpc8308/Kconfig
index e913e94b3a..80ac1a0f8a 100644
--- a/board/gdsys/mpc8308/Kconfig
+++ b/board/gdsys/mpc8308/Kconfig
@@ -55,6 +55,17 @@ config GDSYS_LEGACY_DRIVERS
 
 endif
 
+choice
+	prompt "FPGA flavor selection"
+
+config SYS_FPGA_FLAVOR_LEGACY
+	bool "Legacy flavor"
+
+config SYS_FPGA_FLAVOR_GAZERBEAM
+	bool "Gazerbeam flavor"
+
+endchoice
+
 config CMD_IOLOOP
 	bool "Enable 'ioloop' and 'ioreflect' commands"
 	help
-- 
2.11.0

^ permalink raw reply related	[flat|nested] 138+ messages in thread

* [U-Boot] [PATCH 32/51] drivers: Add ihs_fpga and gdsys_soc drivers
  2017-07-14 12:54 [U-Boot] [PATCH 00/51] gdsys: Add support for Gazerbeam board Mario Six
                   ` (30 preceding siblings ...)
  2017-07-14 12:55 ` [U-Boot] [PATCH 31/51] gdsys: mpc8308: Add FPGA flavor option Mario Six
@ 2017-07-14 12:55 ` Mario Six
  2017-07-19  9:06   ` Simon Glass
  2017-07-14 12:55 ` [U-Boot] [PATCH 33/51] drivers: Add transmitter uclass Mario Six
                   ` (18 subsequent siblings)
  50 siblings, 1 reply; 138+ messages in thread
From: Mario Six @ 2017-07-14 12:55 UTC (permalink / raw)
  To: u-boot

This patch adds DM drivers for IHS FPGAs and their associated busses, as
well as uclasses for both.

Signed-off-by: Mario Six <mario.six@gdsys.cc>
---

 drivers/misc/Kconfig     |   6 +
 drivers/misc/Makefile    |   1 +
 drivers/misc/gdsys_soc.c |  51 +++
 drivers/misc/ihs_fpga.c  | 871 +++++++++++++++++++++++++++++++++++++++++++++++
 include/dm/uclass-id.h   |   2 +
 include/gdsys_soc.h      |  29 ++
 include/ihs_fpga.h       | 111 ++++++
 7 files changed, 1071 insertions(+)
 create mode 100644 drivers/misc/gdsys_soc.c
 create mode 100644 drivers/misc/ihs_fpga.c
 create mode 100644 include/gdsys_soc.h
 create mode 100644 include/ihs_fpga.h

diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig
index d1ddbbe157..8b59a444ce 100644
--- a/drivers/misc/Kconfig
+++ b/drivers/misc/Kconfig
@@ -196,4 +196,10 @@ config I2C_EEPROM
 	depends on MISC
 	help
 	  Enable a generic driver for EEPROMs attached via I2C.
+
+config IHS_FPGA
+	bool "Enable IHS FPGA driver"
+	depends on MISC
+	help
+	  Support for IHS FPGA.
 endmenu
diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile
index 10265c8fb4..d2e46fc7d6 100644
--- a/drivers/misc/Makefile
+++ b/drivers/misc/Makefile
@@ -52,3 +52,4 @@ obj-$(CONFIG_FSL_DEVICE_DISABLE) += fsl_devdis.o
 obj-$(CONFIG_WINBOND_W83627) += winbond_w83627.o
 obj-$(CONFIG_QFW) += qfw.o
 obj-$(CONFIG_ROCKCHIP_EFUSE) += rockchip-efuse.o
+obj-$(CONFIG_IHS_FPGA) += ihs_fpga.o gdsys_soc.o
diff --git a/drivers/misc/gdsys_soc.c b/drivers/misc/gdsys_soc.c
new file mode 100644
index 0000000000..34b06d44bd
--- /dev/null
+++ b/drivers/misc/gdsys_soc.c
@@ -0,0 +1,51 @@
+/*
+ * (C) Copyright 2017
+ * Mario Six,  Guntermann & Drunck GmbH, mario.six at gdsys.cc
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <dm/device-internal.h>
+#include <dm/lists.h>
+#include <gdsys_soc.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+static int gdsys_soc_child_post_bind(struct udevice *dev)
+{
+	struct gdsys_soc_child_platdata *pplat = dev_get_parent_platdata(dev);
+	struct udevice *fpga;
+
+	if (uclass_get_device_by_phandle(UCLASS_IHS_FPGA, dev->parent, "fpga",
+					 &fpga)) {
+		printf("%s: Could not find 'fpga' phandle.\n",
+		       dev->parent->name);
+		return 1;
+	}
+
+	pplat->fpga = fpga;
+
+	return 0;
+}
+
+UCLASS_DRIVER(gdsys_soc) = {
+	.id		= UCLASS_GDSYS_SOC,
+	.name		= "gdsys_soc",
+	.post_probe	= dm_scan_fdt_dev,
+	.child_post_bind = gdsys_soc_child_post_bind,
+	.per_child_platdata_auto_alloc_size =
+		sizeof(struct gdsys_soc_child_platdata),
+};
+
+static const struct udevice_id gdsys_soc_ids[] = {
+	{ .compatible = "gdsys,soc" },
+	{ /* sentinel */ }
+};
+
+U_BOOT_DRIVER(gdsys_soc_bus) = {
+	.name           = "gdsys_soc_bus",
+	.id             = UCLASS_GDSYS_SOC,
+	.of_match       = gdsys_soc_ids,
+};
diff --git a/drivers/misc/ihs_fpga.c b/drivers/misc/ihs_fpga.c
new file mode 100644
index 0000000000..a2b5d3f58c
--- /dev/null
+++ b/drivers/misc/ihs_fpga.c
@@ -0,0 +1,871 @@
+/*
+ * (C) Copyright 2017
+ * Mario Six,  Guntermann & Drunck GmbH, mario.six at gdsys.cc
+ *
+ * based on the ioep-fpga driver, which is
+ *
+ * (C) Copyright 2014
+ * Dirk Eibach,  Guntermann & Drunck GmbH, eibach at gdsys.de
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <dm/device-internal.h>
+#include <dm/uclass-internal.h>
+#include <dm/lists.h>
+#include <ihs_fpga.h>
+#include <misc.h>
+#include <mapmem.h>
+#include <asm/gpio.h>
+#include <linux/bitops.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+struct reg_spec {
+	uint addr;
+	uint shift;
+	ulong mask;
+};
+
+struct ihs_fpga_priv {
+	u8 *regs;
+	fdt_addr_t addr;
+	struct gpio_desc reset_gpio;
+	struct gpio_desc done_gpio;
+	struct gpio_desc startupfin_gpios[2];
+	int regmap_node;
+	bool has_osd;
+};
+
+const u16 reflection_testpattern = 0xdede;
+
+enum pcb_video_type {
+	PCB_DVI_SL,
+	PCB_DP_165MPIX,
+	PCB_DP_300MPIX,
+	PCB_HDMI,
+	PCB_DP_1_2,
+	PCB_HDMI_2_0,
+};
+
+enum pcb_transmission_type {
+	PCB_CAT_1G,
+	PCB_FIBER_3G,
+	PCB_CAT_10G,
+	PCB_FIBER_10G,
+};
+
+enum carrier_speed {
+	CARRIER_SPEED_1G,
+	CARRIER_SPEED_3G,
+	CARRIER_SPEED_2_5G = CARRIER_SPEED_3G,
+	CARRIER_SPEED_10G,
+};
+
+enum ram_config {
+	RAM_DDR2_32BIT_295MBPS,
+	RAM_DDR3_32BIT_590MBPS,
+	RAM_DDR3_48BIT_590MBPS,
+	RAM_DDR3_64BIT_1800MBPS,
+	RAM_DDR3_48BIT_1800MBPS,
+};
+
+enum sysclock {
+	SYSCLK_147456,
+};
+
+struct fpga_versions {
+	bool video_channel;
+	bool con_side;
+	enum pcb_video_type pcb_video_type;
+	enum pcb_transmission_type pcb_transmission_type;
+	unsigned int hw_version;
+};
+
+struct fpga_features {
+	u8 video_channels;
+	u8 carriers;
+	enum carrier_speed carrier_speed;
+	enum ram_config ram_config;
+	enum sysclock sysclock;
+
+	bool pcm_tx;
+	bool pcm_rx;
+	bool spdif_tx;
+	bool spdif_rx;
+	bool usb2;
+	bool rs232;
+	bool compression_type1;
+	bool compression_type2;
+	bool compression_type3;
+	bool interlace;
+	bool osd;
+	bool compression_pipes;
+};
+
+int fpga_set_reg(struct udevice *dev, const char *compat,
+		 uint value)
+{
+	struct ihs_fpga_ops *ops = ihs_fpga_get_ops(dev);
+
+	return ops->set_reg(dev, compat, value);
+}
+
+int fpga_get_reg(struct udevice *dev, const char *compat,
+		 uint *value)
+{
+	struct ihs_fpga_ops *ops = ihs_fpga_get_ops(dev);
+
+	return ops->get_reg(dev, compat, value);
+}
+
+u16 fpga_in_le16(struct udevice *dev, phys_addr_t addr)
+{
+	struct ihs_fpga_ops *ops = ihs_fpga_get_ops(dev);
+
+	return ops->in_le16(dev, addr);
+}
+
+void fpga_out_le16(struct udevice *dev, phys_addr_t addr, u16 value)
+{
+	struct ihs_fpga_ops *ops = ihs_fpga_get_ops(dev);
+
+	return ops->out_le16(dev, addr, value);
+}
+
+#ifdef CONFIG_SYS_FPGA_FLAVOR_GAZERBEAM
+
+static int get_versions(struct udevice *dev, struct fpga_versions *versions)
+{
+	enum {
+		VERSIONS_FPGA_VIDEO_CHANNEL = BIT(12),
+		VERSIONS_FPGA_CON_SIDE = BIT(13),
+		VERSIONS_FPGA_SC = BIT(14),
+		VERSIONS_PCB_CON = BIT(9),
+		VERSIONS_PCB_SC = BIT(8),
+		VERSIONS_PCB_VIDEO_MASK = 0x3 << 6,
+		VERSIONS_PCB_VIDEO_DP_1_2 = 0x0 << 6,
+		VERSIONS_PCB_VIDEO_HDMI_2_0 = 0x1 << 6,
+		VERSIONS_PCB_TRANSMISSION_MASK = 0x3 << 4,
+		VERSIONS_PCB_TRANSMISSION_FIBER_10G = 0x0 << 4,
+		VERSIONS_PCB_TRANSMISSION_CAT_10G = 0x1 << 4,
+		VERSIONS_PCB_TRANSMISSION_FIBER_3G = 0x2 << 4,
+		VERSIONS_PCB_TRANSMISSION_CAT_1G = 0x3 << 4,
+		VERSIONS_HW_VER_MASK = 0xf << 0,
+	};
+	uint raw_versions;
+
+	memset(versions, 0, sizeof(struct fpga_versions));
+
+	fpga_get_reg(dev, "versions", &raw_versions);
+
+	versions->video_channel = raw_versions & VERSIONS_FPGA_VIDEO_CHANNEL;
+	versions->con_side = raw_versions & VERSIONS_FPGA_CON_SIDE;
+
+	switch (raw_versions & VERSIONS_PCB_VIDEO_MASK) {
+	case VERSIONS_PCB_VIDEO_DP_1_2:
+		versions->pcb_video_type = PCB_DP_1_2;
+		break;
+
+	case VERSIONS_PCB_VIDEO_HDMI_2_0:
+		versions->pcb_video_type = PCB_HDMI_2_0;
+		break;
+	}
+
+	switch (raw_versions & VERSIONS_PCB_TRANSMISSION_MASK) {
+	case VERSIONS_PCB_TRANSMISSION_FIBER_10G:
+		versions->pcb_transmission_type = PCB_FIBER_10G;
+		break;
+
+	case VERSIONS_PCB_TRANSMISSION_CAT_10G:
+		versions->pcb_transmission_type = PCB_CAT_10G;
+		break;
+
+	case VERSIONS_PCB_TRANSMISSION_FIBER_3G:
+		versions->pcb_transmission_type = PCB_FIBER_3G;
+		break;
+
+	case VERSIONS_PCB_TRANSMISSION_CAT_1G:
+		versions->pcb_transmission_type = PCB_CAT_1G;
+		break;
+	}
+
+	versions->hw_version = raw_versions & VERSIONS_HW_VER_MASK;
+
+	return 0;
+}
+
+static int get_features(struct udevice *dev, struct fpga_features *features)
+{
+	enum {
+		FEATURE_SPDIF_RX = BIT(15),
+		FEATURE_SPDIF_TX = BIT(14),
+		FEATURE_PCM_RX = BIT(13),
+		FEATURE_PCM_TX = BIT(12),
+		FEATURE_RAM_MASK = GENMASK(11, 8),
+		FEATURE_RAM_DDR2_32BIT_295MBPS = 0x0 << 8,
+		FEATURE_RAM_DDR3_32BIT_590MBPS = 0x1 << 8,
+		FEATURE_RAM_DDR3_48BIT_590MBPS = 0x2 << 8,
+		FEATURE_RAM_DDR3_64BIT_1800MBPS = 0x3 << 8,
+		FEATURE_RAM_DDR3_48BIT_1800MBPS = 0x4 << 8,
+		FEATURE_CARRIER_SPEED_MASK = GENMASK(7, 6),
+		FEATURE_CARRIER_SPEED_1G = 0x0 << 6,
+		FEATURE_CARRIER_SPEED_2_5G = 0x1 << 6,
+		FEATURE_CARRIER_SPEED_10G = 0x2 << 6,
+		FEATURE_CARRIERS_MASK = GENMASK(5, 4),
+		FEATURE_CARRIERS_0 = 0x0 << 4,
+		FEATURE_CARRIERS_1 = 0x1 << 4,
+		FEATURE_CARRIERS_2 = 0x2 << 4,
+		FEATURE_CARRIERS_4 = 0x3 << 4,
+		FEATURE_USB2 = BIT(3),
+		FEATURE_VIDEOCHANNELS_MASK = GENMASK(2, 0),
+		FEATURE_VIDEOCHANNELS_0 = 0x0 << 0,
+		FEATURE_VIDEOCHANNELS_1 = 0x1 << 0,
+		FEATURE_VIDEOCHANNELS_1_1 = 0x2 << 0,
+		FEATURE_VIDEOCHANNELS_2 = 0x3 << 0,
+	};
+
+	enum {
+		EXT_FEATURE_OSD = BIT(15),
+		EXT_FEATURE_ETHERNET = BIT(9),
+		EXT_FEATURE_INTERLACE = BIT(8),
+		EXT_FEATURE_RS232 = BIT(7),
+		EXT_FEATURE_COMPRESSION_PERF_MASK = GENMASK(6, 4),
+		EXT_FEATURE_COMPRESSION_PERF_1X = 0x0 << 4,
+		EXT_FEATURE_COMPRESSION_PERF_2X = 0x1 << 4,
+		EXT_FEATURE_COMPRESSION_PERF_4X = 0x2 << 4,
+		EXT_FEATURE_COMPRESSION_TYPE1 = BIT(0),
+		EXT_FEATURE_COMPRESSION_TYPE2 = BIT(1),
+		EXT_FEATURE_COMPRESSION_TYPE3 = BIT(2),
+	};
+
+	uint raw_features;
+	uint raw_extended_features;
+
+	memset(features, 0, sizeof(struct fpga_features));
+
+	fpga_get_reg(dev, "fpga-features", &raw_features);
+	fpga_get_reg(dev, "fpga-ext-features", &raw_extended_features);
+
+	switch (raw_features & FEATURE_VIDEOCHANNELS_MASK) {
+	case FEATURE_VIDEOCHANNELS_0:
+		features->video_channels = 0;
+		break;
+
+	case FEATURE_VIDEOCHANNELS_1:
+		features->video_channels = 1;
+		break;
+
+	case FEATURE_VIDEOCHANNELS_1_1:
+	case FEATURE_VIDEOCHANNELS_2:
+		features->video_channels = 2;
+		break;
+	};
+
+	switch (raw_features & FEATURE_CARRIERS_MASK) {
+	case FEATURE_CARRIERS_0:
+		features->carriers = 0;
+		break;
+
+	case FEATURE_CARRIERS_1:
+		features->carriers = 1;
+		break;
+
+	case FEATURE_CARRIERS_2:
+		features->carriers = 2;
+		break;
+
+	case FEATURE_CARRIERS_4:
+		features->carriers = 4;
+		break;
+	}
+
+	switch (raw_features & FEATURE_CARRIER_SPEED_MASK) {
+	case FEATURE_CARRIER_SPEED_1G:
+		features->carrier_speed = CARRIER_SPEED_1G;
+		break;
+	case FEATURE_CARRIER_SPEED_2_5G:
+		features->carrier_speed = CARRIER_SPEED_2_5G;
+		break;
+	case FEATURE_CARRIER_SPEED_10G:
+		features->carrier_speed = CARRIER_SPEED_10G;
+		break;
+	}
+
+	switch (raw_features & FEATURE_RAM_MASK) {
+	case FEATURE_RAM_DDR2_32BIT_295MBPS:
+		features->ram_config = RAM_DDR2_32BIT_295MBPS;
+		break;
+
+	case FEATURE_RAM_DDR3_32BIT_590MBPS:
+		features->ram_config = RAM_DDR3_32BIT_590MBPS;
+		break;
+
+	case FEATURE_RAM_DDR3_48BIT_590MBPS:
+		features->ram_config = RAM_DDR3_48BIT_590MBPS;
+		break;
+
+	case FEATURE_RAM_DDR3_64BIT_1800MBPS:
+		features->ram_config = RAM_DDR3_64BIT_1800MBPS;
+		break;
+
+	case FEATURE_RAM_DDR3_48BIT_1800MBPS:
+		features->ram_config = RAM_DDR3_48BIT_1800MBPS;
+		break;
+	}
+
+	features->pcm_tx = raw_features & FEATURE_PCM_TX;
+	features->pcm_rx = raw_features & FEATURE_PCM_RX;
+	features->spdif_tx = raw_features & FEATURE_SPDIF_TX;
+	features->spdif_rx = raw_features & FEATURE_SPDIF_RX;
+	features->usb2 = raw_features & FEATURE_USB2;
+	features->rs232 = raw_extended_features & EXT_FEATURE_RS232;
+	features->compression_type1 = raw_extended_features &
+					EXT_FEATURE_COMPRESSION_TYPE1;
+	features->compression_type2 = raw_extended_features &
+					EXT_FEATURE_COMPRESSION_TYPE2;
+	features->compression_type3 = raw_extended_features &
+					EXT_FEATURE_COMPRESSION_TYPE3;
+	features->interlace = raw_extended_features & EXT_FEATURE_INTERLACE;
+	features->osd = raw_extended_features & EXT_FEATURE_OSD;
+	features->compression_pipes = raw_extended_features &
+					EXT_FEATURE_COMPRESSION_PERF_MASK;
+
+	return 0;
+}
+
+#else
+
+static int get_versions(unsigned int fpga, struct fpga_versions *versions)
+{
+	enum {
+		/* HW version encoding is a mess, leave it for the moment */
+		VERSIONS_HW_VER_MASK = 0xf << 0,
+		VERSIONS_PIX_CLOCK_GEN_IDT8N3QV01 = BIT(4),
+		VERSIONS_SFP = BIT(5),
+		VERSIONS_VIDEO_MASK = 0x7 << 6,
+		VERSIONS_VIDEO_DVI = 0x0 << 6,
+		VERSIONS_VIDEO_DP_165 = 0x1 << 6,
+		VERSIONS_VIDEO_DP_300 = 0x2 << 6,
+		VERSIONS_VIDEO_HDMI = 0x3 << 6,
+		VERSIONS_UT_MASK = 0xf << 12,
+		VERSIONS_UT_MAIN_SERVER = 0x0 << 12,
+		VERSIONS_UT_MAIN_USER = 0x1 << 12,
+		VERSIONS_UT_VIDEO_SERVER = 0x2 << 12,
+		VERSIONS_UT_VIDEO_USER = 0x3 << 12,
+	};
+	u16 raw_versions;
+
+	memset(versions, 0, sizeof(struct fpga_versions));
+
+	FPGA_GET_REG(fpga, versions, &raw_versions);
+
+	switch (raw_versions & VERSIONS_UT_MASK) {
+	case VERSIONS_UT_MAIN_SERVER:
+		versions->video_channel = false;
+		versions->con_side = false;
+		break;
+
+	case VERSIONS_UT_MAIN_USER:
+		versions->video_channel = false;
+		versions->con_side = true;
+		break;
+
+	case VERSIONS_UT_VIDEO_SERVER:
+		versions->video_channel = true;
+		versions->con_side = false;
+		break;
+
+	case VERSIONS_UT_VIDEO_USER:
+		versions->video_channel = true;
+		versions->con_side = true;
+		break;
+	}
+
+	switch (raw_versions & VERSIONS_VIDEO_MASK) {
+	case VERSIONS_VIDEO_DVI:
+		versions->pcb_video_type = PCB_DVI_SL;
+		break;
+
+	case VERSIONS_VIDEO_DP_165:
+		versions->pcb_video_type = PCB_DP_165MPIX;
+		break;
+
+	case VERSIONS_VIDEO_DP_300:
+		versions->pcb_video_type = PCB_DP_300MPIX;
+		break;
+
+	case VERSIONS_VIDEO_HDMI:
+		versions->pcb_video_type = PCB_HDMI;
+		break;
+	}
+
+	versions->hw_version = raw_versions & VERSIONS_HW_VER_MASK;
+
+	if (raw_versions & VERSIONS_SFP)
+		versions->pcb_transmission_type = PCB_FIBER_3G;
+	else
+		versions->pcb_transmission_type = PCB_CAT_1G;
+
+	return 0;
+}
+
+static int get_features(unsigned int fpga, struct fpga_features *features)
+{
+	enum {
+		FEATURE_CARRIER_SPEED_2_5 = BIT(4),
+		FEATURE_RAM_MASK = 0x7 << 5,
+		FEATURE_RAM_DDR2_32BIT = 0x0 << 5,
+		FEATURE_RAM_DDR3_32BIT = 0x1 << 5,
+		FEATURE_RAM_DDR3_48BIT = 0x2 << 5,
+		FEATURE_PCM_AUDIO_TX = BIT(9),
+		FEATURE_PCM_AUDIO_RX = BIT(10),
+		FEATURE_OSD = BIT(11),
+		FEATURE_USB20 = BIT(12),
+		FEATURE_COMPRESSION_MASK = 7 << 13,
+		FEATURE_COMPRESSION_TYPE1 = 0x1 << 13,
+		FEATURE_COMPRESSION_TYPE1_TYPE2 = 0x3 << 13,
+		FEATURE_COMPRESSION_TYPE1_TYPE2_TYPE3 = 0x7 << 13,
+	};
+
+	enum {
+		EXTENDED_FEATURE_SPDIF_AUDIO_TX = BIT(0),
+		EXTENDED_FEATURE_SPDIF_AUDIO_RX = BIT(1),
+		EXTENDED_FEATURE_RS232 = BIT(2),
+		EXTENDED_FEATURE_COMPRESSION_PIPES = BIT(3),
+		EXTENDED_FEATURE_INTERLACE = BIT(4),
+	};
+
+	u16 raw_features;
+	u16 raw_extended_features;
+
+	memset(features, 0, sizeof(struct fpga_features));
+
+	FPGA_GET_REG(fpga, fpga_features, &raw_features);
+	FPGA_GET_REG(fpga, fpga_ext_features, &raw_extended_features);
+
+	features->video_channels = raw_features & 0x3;
+	features->carriers = (raw_features >> 2) & 0x3;
+
+	features->carrier_speed = (raw_features & FEATURE_CARRIER_SPEED_2_5)
+		? CARRIER_SPEED_2_5G : CARRIER_SPEED_1G;
+
+	switch (raw_features & FEATURE_RAM_MASK) {
+	case FEATURE_RAM_DDR2_32BIT:
+		features->ram_config = RAM_DDR2_32BIT_295MBPS;
+		break;
+
+	case FEATURE_RAM_DDR3_32BIT:
+		features->ram_config = RAM_DDR3_32BIT_590MBPS;
+		break;
+
+	case FEATURE_RAM_DDR3_48BIT:
+		features->ram_config = RAM_DDR3_48BIT_590MBPS;
+		break;
+	}
+
+	features->pcm_tx = raw_features & FEATURE_PCM_AUDIO_TX;
+	features->pcm_rx = raw_features & FEATURE_PCM_AUDIO_RX;
+	features->spdif_tx = raw_extended_features &
+				EXTENDED_FEATURE_SPDIF_AUDIO_TX;
+	features->spdif_rx = raw_extended_features &
+				EXTENDED_FEATURE_SPDIF_AUDIO_RX;
+
+	features->usb2 = raw_features & FEATURE_USB20;
+	features->rs232 = raw_extended_features & EXTENDED_FEATURE_RS232;
+
+	features->compression_type1 = false;
+	features->compression_type2 = false;
+	features->compression_type3 = false;
+	switch (raw_features & FEATURE_COMPRESSION_MASK) {
+	case FEATURE_COMPRESSION_TYPE1_TYPE2_TYPE3:
+		features->compression_type3 = true;
+	case FEATURE_COMPRESSION_TYPE1_TYPE2:
+		features->compression_type2 = true;
+	case FEATURE_COMPRESSION_TYPE1:
+		features->compression_type1 = true;
+		break;
+	}
+
+	features->interlace = raw_extended_features &
+				EXTENDED_FEATURE_INTERLACE;
+	features->osd = raw_features & FEATURE_OSD;
+	features->compression_pipes = raw_extended_features &
+					EXTENDED_FEATURE_COMPRESSION_PIPES;
+
+	return 0;
+}
+
+#endif
+
+static void fpga_print_info(struct udevice *dev)
+{
+	struct ihs_fpga_priv *priv = dev_get_priv(dev);
+	uint fpga_version;
+	struct fpga_versions versions;
+	struct fpga_features features;
+
+	fpga_get_reg(dev, "fpga-version", &fpga_version);
+	get_versions(dev, &versions);
+	get_features(dev, &features);
+
+	priv->has_osd = features.osd;
+
+	if (versions.video_channel)
+		printf("Videochannel");
+	else
+		printf("Mainchannel");
+
+	if (versions.con_side)
+		printf(" User");
+	else
+		printf(" Server");
+
+// FIXME
+#if 0
+		if (versions & (1<<4))
+			printf(" UC");
+#endif
+
+	switch (versions.pcb_transmission_type) {
+	case PCB_CAT_1G:
+	case PCB_CAT_10G:
+		printf(" CAT");
+		break;
+	case PCB_FIBER_3G:
+	case PCB_FIBER_10G:
+		printf(" Fiber");
+		break;
+	};
+
+	switch (versions.pcb_video_type) {
+	case PCB_DVI_SL:
+		printf(" DVI,");
+		break;
+	case PCB_DP_165MPIX:
+		printf(" DP 165MPix/s,");
+		break;
+	case PCB_DP_300MPIX:
+		printf(" DP 300MPix/s,");
+		break;
+	case PCB_HDMI:
+		printf(" HDMI,");
+		break;
+	case PCB_DP_1_2:
+		printf(" DP 1.2,");
+		break;
+	case PCB_HDMI_2_0:
+		printf(" HDMI 2.0,");
+		break;
+	}
+
+	printf(" FPGA V %d.%02d\n       features: ",
+	       fpga_version / 100, fpga_version % 100);
+
+	if (!features.compression_type1 &&
+	    !features.compression_type2 &&
+	    !features.compression_type3)
+		printf("no compression, ");
+
+	if (features.compression_type1)
+		printf("type1-deltacompression, ");
+
+	if (features.compression_type2)
+		printf("type2-inlinecompression, ");
+
+	if (features.compression_type3)
+		printf("type3-intempocompression, ");
+
+	printf("%sosd", features.osd ? "" : "no ");
+
+	if (features.pcm_rx && features.pcm_tx)
+		printf(", pcm rx+tx");
+	else if (features.pcm_rx)
+		printf(", pcm rx");
+	else if (features.pcm_tx)
+		printf(", pcm tx");
+
+	if (features.spdif_rx && features.spdif_tx)
+		printf(", spdif rx+tx");
+	else if (features.spdif_rx)
+		printf(", spdif rx");
+	else if (features.spdif_tx)
+		printf(", spdif tx");
+
+	puts(",\n       ");
+
+	switch (features.sysclock) {
+	case SYSCLK_147456:
+		printf("clock 147.456 MHz");
+		break;
+	}
+
+	switch (features.ram_config) {
+	case RAM_DDR2_32BIT_295MBPS:
+		printf(", RAM 32 bit DDR2");
+		break;
+	case RAM_DDR3_32BIT_590MBPS:
+		printf(", RAM 32 bit DDR3");
+		break;
+	case RAM_DDR3_48BIT_590MBPS:
+	case RAM_DDR3_48BIT_1800MBPS:
+		printf(", RAM 48 bit DDR3");
+		break;
+	case RAM_DDR3_64BIT_1800MBPS:
+		printf(", RAM 64 bit DDR3");
+		break;
+	}
+
+	printf(", %d carrier(s)", features.carriers);
+
+	switch (features.carrier_speed) {
+	case CARRIER_SPEED_1G:
+		printf(", 1Gbit/s");
+		break;
+	case CARRIER_SPEED_3G:
+		printf(", 3Gbit/s");
+		break;
+	case CARRIER_SPEED_10G:
+		printf(", 10Gbit/s");
+		break;
+	}
+
+	printf(", %d video channel(s)\n", features.video_channels);
+}
+
+static void signal_startup_finished(struct udevice *dev)
+{
+	struct ihs_fpga_priv *priv = dev_get_priv(dev);
+
+	gpio_request_list_by_name(dev, "startupfin-gpios",
+				  priv->startupfin_gpios, 2, GPIOD_IS_OUT);
+	if (!priv->startupfin_gpios[0].dev) {
+		printf("%s: Could not get startupfin-GPIOs.\n", dev->name);
+		return;
+	}
+
+	/* Inverted */
+	dm_gpio_set_value(&priv->startupfin_gpios[0], 0);
+	/* Non-inverted */
+	dm_gpio_set_value(&priv->startupfin_gpios[1], 1);
+}
+
+static int do_reflection_test(struct udevice *dev)
+{
+	int ctr = 0;
+
+	while (1) {
+		uint val;
+
+		fpga_set_reg(dev, "reflection-low", reflection_testpattern);
+
+		fpga_get_reg(dev, "reflection-low", &val);
+		if (val == (~reflection_testpattern & 0xffff))
+			return 1;
+
+		mdelay(100);
+		if (ctr++ > 5)
+			return 0;
+	}
+}
+
+UCLASS_DRIVER(ihs_fpga) = {
+	.id		= UCLASS_IHS_FPGA,
+	.name		= "ihs_fpga",
+	.flags		= DM_UC_FLAG_SEQ_ALIAS,
+};
+
+static int get_reg_spec(struct udevice *dev, const char *compat,
+			struct reg_spec *spec)
+{
+	struct ihs_fpga_priv *priv = dev_get_priv(dev);
+	int childnode;
+
+	fdt_for_each_subnode(childnode, gd->fdt_blob, priv->regmap_node) {
+		const struct fdt_property *compatprop;
+		u32 reg[3];
+		uint start_bit, end_bit;
+
+		compatprop = fdt_get_property(gd->fdt_blob, childnode,
+					      "compatible", NULL);
+
+		if (!strcmp(compatprop->data, compat)) {
+			fdtdec_get_int_array(gd->fdt_blob, childnode, "reg",
+					     reg, 3);
+			start_bit = reg[1];
+			end_bit = reg[1] - reg[2] + 1;
+
+			spec->mask = GENMASK(start_bit, end_bit);
+			spec->addr = reg[0];
+			spec->shift = end_bit;
+
+			return 0;
+		}
+	}
+
+	return 1;
+}
+
+static int ihs_fpga_set_reg(struct udevice *dev, const char *compat,
+			    uint value)
+{
+	struct ihs_fpga_priv *priv = dev_get_priv(dev);
+	struct reg_spec spec;
+
+	if (get_reg_spec(dev, compat, &spec)) {
+		printf("%s: Could not get %s regspec for '%s'.\n", __func__,
+		       dev->name, compat);
+		return -ENODEV;
+	}
+
+	out_le16((void *)(priv->regs + spec.addr), value << spec.shift);
+
+	return 0;
+}
+
+static int ihs_fpga_get_reg(struct udevice *dev, const char *compat,
+			    uint *value)
+{
+	struct ihs_fpga_priv *priv = dev_get_priv(dev);
+	struct reg_spec spec;
+	uint tmp;
+
+	if (get_reg_spec(dev, compat, &spec)) {
+		printf("%s: Could not get %s regspec for '%s'.\n", __func__,
+		       dev->name, compat);
+		return -ENODEV;
+	}
+
+	tmp = in_le16((void *)(priv->regs + spec.addr));
+	*value = (tmp & spec.mask) >> spec.shift;
+
+	return 0;
+}
+
+static u16 ihs_fpga_in_le16(struct udevice *dev, phys_addr_t addr)
+{
+	struct ihs_fpga_priv *priv = dev_get_priv(dev);
+
+	/* TODO: MCLink transfer */
+
+	return in_le16((void *)(priv->regs + addr));
+}
+
+static void ihs_fpga_out_le16(struct udevice *dev, phys_addr_t addr, u16 value)
+{
+	struct ihs_fpga_priv *priv = dev_get_priv(dev);
+
+	/* TODO: MCLink transfer */
+
+	out_le16((void *)(priv->regs + addr), value);
+}
+
+static const struct ihs_fpga_ops ihs_fpga_ops = {
+	.set_reg = ihs_fpga_set_reg,
+	.get_reg = ihs_fpga_get_reg,
+	.in_le16 = ihs_fpga_in_le16,
+	.out_le16 = ihs_fpga_out_le16,
+};
+
+static int ihs_fpga_probe(struct udevice *dev)
+{
+	struct ihs_fpga_priv *priv = dev_get_priv(dev);
+	fdt_addr_t addr;
+	struct fdtdec_phandle_args phandle_args;
+	struct fdtdec_phandle_args args;
+	struct udevice *busdev = NULL;
+	struct udevice *child = NULL;
+	uint mem_width;
+
+	if (fdtdec_parse_phandle_with_args(gd->fdt_blob, dev_of_offset(dev),
+					   "regmap", NULL, 0, 0, &args)) {
+		printf("%s: Could not get regmap.\n", dev->name);
+		return 1;
+	}
+
+	priv->regmap_node = args.node;
+
+	addr = devfdt_get_addr(dev);
+
+	priv->addr = addr;
+	priv->regs = map_sysmem(addr, mem_width);
+
+	gpio_request_by_name(dev, "reset-gpios", 0, &priv->reset_gpio,
+			     GPIOD_IS_OUT);
+	if (!priv->reset_gpio.dev)
+		printf("%s: Could not get reset-GPIO.\n", dev->name);
+
+	gpio_request_by_name(dev, "done-gpios", 0, &priv->done_gpio,
+			     GPIOD_IS_IN);
+	if (!priv->done_gpio.dev)
+		printf("%s: Could not get done-GPIO.\n", dev->name);
+
+	dm_gpio_set_value(&priv->reset_gpio, 1);
+
+	signal_startup_finished(dev);
+
+	if (!do_reflection_test(dev)) {
+		int ctr = 0;
+
+		dm_gpio_set_value(&priv->reset_gpio, 0);
+
+		while (!dm_gpio_get_value(&priv->done_gpio)) {
+			mdelay(100);
+			if (ctr++ > 5) {
+				printf("Initializing FPGA failed\n");
+				break;
+			}
+		}
+
+		udelay(10);
+
+		dm_gpio_set_value(&priv->reset_gpio, 1);
+
+		if (!do_reflection_test(dev)) {
+			printf("%s: Reflection test FAILED.\n", dev->name);
+			return -1;
+		}
+	}
+
+	printf("%s: Reflection test passed.\n", dev->name);
+
+	if (fdtdec_parse_phandle_with_args(gd->fdt_blob, dev_of_offset(dev), "bus",
+					   NULL, 0, 0, &phandle_args))
+		return -1;
+
+	lists_bind_fdt(dev, offset_to_ofnode(phandle_args.node), &busdev);
+
+	fpga_print_info(dev);
+
+	/* TODO: Check if this should be gazerbeam-specific */
+	if (priv->has_osd) {
+		/* Disable softcore, select external pixclock */
+		fpga_set_reg(dev, "control", 0x8000);
+	}
+
+	device_probe(busdev);
+
+	for (device_find_first_child(busdev, &child);
+	     child;
+	     device_find_next_child(&child))
+		device_probe(child);
+
+	return 0;
+}
+
+static const struct udevice_id ihs_fpga_ids[] = {
+	{ .compatible = "gdsys,iocon_fpga" },
+	{ .compatible = "gdsys,iocpu_fpga" },
+	{ }
+};
+
+U_BOOT_DRIVER(ihs_fpga_bus) = {
+	.name           = "ihs_fpga_bus",
+	.id             = UCLASS_IHS_FPGA,
+	.ops		= &ihs_fpga_ops,
+	.of_match       = ihs_fpga_ids,
+	.probe          = ihs_fpga_probe,
+	.priv_auto_alloc_size = sizeof(struct ihs_fpga_priv),
+};
diff --git a/include/dm/uclass-id.h b/include/dm/uclass-id.h
index 2e6498b7dc..56fbedaa9d 100644
--- a/include/dm/uclass-id.h
+++ b/include/dm/uclass-id.h
@@ -35,12 +35,14 @@ enum uclass_id {
 	UCLASS_DISPLAY,		/* Display (e.g. DisplayPort, HDMI) */
 	UCLASS_DMA,		/* Direct Memory Access */
 	UCLASS_ETH,		/* Ethernet device */
+	UCLASS_GDSYS_SOC,	/* gdsys soc buses */
 	UCLASS_GPIO,		/* Bank of general-purpose I/O pins */
 	UCLASS_FIRMWARE,	/* Firmware */
 	UCLASS_I2C,		/* I2C bus */
 	UCLASS_I2C_EEPROM,	/* I2C EEPROM device */
 	UCLASS_I2C_GENERIC,	/* Generic I2C device */
 	UCLASS_I2C_MUX,		/* I2C multiplexer */
+	UCLASS_IHS_FPGA,	/* gdsys IHS FPGAs */
 	UCLASS_IRQ,		/* Interrupt controller */
 	UCLASS_KEYBOARD,	/* Keyboard input device */
 	UCLASS_LED,		/* Light-emitting diode (LED) */
diff --git a/include/gdsys_soc.h b/include/gdsys_soc.h
new file mode 100644
index 0000000000..2164651f62
--- /dev/null
+++ b/include/gdsys_soc.h
@@ -0,0 +1,29 @@
+/*
+ * (C) Copyright 2017
+ * Mario Six,  Guntermann & Drunck GmbH, mario.six at gdsys.cc
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#ifndef _GDSYS_SOC_H_
+#define _GDSYS_SOC_H_
+
+/**
+ * struct gdsys_soc_child_platdata - platform data for devices on gdsys soc
+ * 				     buses
+ *
+ * To access their register maps, devices on gdsys soc buses usually have
+ * facilitate the accessor function of the IHS FPGA their parent bus is
+ * attached to. To pass the FPGA device down to the bus' children, a pointer to
+ * it is contained in this structure.
+ *
+ * To obtain this structure, use dev_get_parent_platdata(dev) where dev is a
+ * device on the gdsys soc bus.
+ *
+ * @fpga:	The IHS FPGA that controls the bus the device is attached to.
+ */
+struct gdsys_soc_child_platdata {
+	struct udevice *fpga;
+};
+
+#endif /* _GDSYS_SOC_H_ */
diff --git a/include/ihs_fpga.h b/include/ihs_fpga.h
new file mode 100644
index 0000000000..552583cbe1
--- /dev/null
+++ b/include/ihs_fpga.h
@@ -0,0 +1,111 @@
+/*
+ * (C) Copyright 2017
+ * Mario Six,  Guntermann & Drunck GmbH, mario.six at gdsys.cc
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#ifndef _IHS_FPGA_H_
+#define _IHS_FPGA_H_
+
+/**
+ * struct ihs_fpga_ops - driver operations for IHS FPGA 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 ihs_fpga_ops {
+	/**
+	 * get_reg() - Get value of a named FPGA register
+	 *
+	 * To accommodate possible future memory layout changes, the registers
+	 * of a IHS FPGA are described in the device tree, and each is given a
+	 * distinct compatible string to address them with.
+	 *
+	 * @dev:	FPGA device to read from.
+	 * @compat:	The compatible string of the register to write to.
+	 * @value:	Pointer to a variable that takes the value read from the
+	 * 		register.
+	 * @return 0 if OK, -ENODEV if no named register with the given
+	 *  compatibility string exists.
+	 */
+	int (*get_reg)(struct udevice *dev, const char *compat, uint *value);
+
+	/**
+	 * set_reg() - Set value of a named FPGA register
+	 *
+	 * To accommodate possible future memory layout changes, the registers
+	 * of a IHS FPGA are described in the device tree, and each is given a
+	 * distinct compatible string to address them with.
+	 *
+	 * @dev:	FPGA device to write to.
+	 * @compat:	The compatible string of the register to write to.
+	 * @value:	Value to write to the register.
+	 * @return 0 if OK, -ENODEV if no named register with the given
+	 * 	compatibility string exists.
+	 */
+	int (*set_reg)(struct udevice *dev, const char *compat, uint value);
+
+	/**
+	 * in_le16() - Read 16 bit value from address in FPGA register space
+	 *
+	 * @dev:	FPGA device to read from.
+	 * @addr:	Address in the FPGA register space to read from.
+	 * @return 0 if OK, -ve on error.
+	 */
+	u16 (*in_le16)(struct udevice *dev, phys_addr_t addr);
+
+	/**
+	 * out_le16() - Write 16 bit value to address in FPGA register space
+	 *
+	 * @dev:	FPGA device to write to.
+	 * @addr:	Address in the FPGA register space to write to.
+	 * @return 0 if OK, -ve on error.
+	 */
+	void (*out_le16)(struct udevice *dev, phys_addr_t addr, u16 value);
+};
+
+#define ihs_fpga_get_ops(dev)	((struct ihs_fpga_ops *)(dev)->driver->ops)
+
+/**
+ * fpga_get_reg() - Get value of a named FPGA register
+ *
+ * @dev:	FPGA device to read from.
+ * @compat:	The compatible string of the register to write to.
+ * @value:	Pointer to a variable that takes the value read from the register.
+ * @return 0 if OK, -ENODEV if no named register with the given compatibility
+ *  string exists.
+ */
+int fpga_get_reg(struct udevice *dev, const char *compat, uint *value);
+
+/**
+ * fpga_set_reg() - Set value of a named FPGA register
+ *
+ * @dev:	FPGA device to write to.
+ * @compat:	The compatible string of the register to write to.
+ * @value:	Value to write to the register.
+ * @return 0 if OK, -ENODEV if no named register with the given compatibility
+ *  string exists.
+ */
+int fpga_set_reg(struct udevice *dev, const char *compat, uint value);
+
+/**
+ * fpga_in_le16() - Read 16 bit value from address in FPGA register space
+ *
+ * @dev:	FPGA device to read from.
+ * @addr:	Address in the FPGA register space to read from.
+ * @return 0 if OK, -ve on error.
+ */
+u16 fpga_in_le16(struct udevice *dev, phys_addr_t addr);
+
+/**
+ * fpga_out_le16() - Write 16 bit value to address in FPGA register space
+ *
+ * @dev:	FPGA device to write to.
+ * @addr:	Address in the FPGA register space to write to.
+ * @return 0 if OK, -ve on error.
+ */
+void fpga_out_le16(struct udevice *dev, phys_addr_t addr, u16 value);
+
+#endif /* !_IHS_FPGA_H_ */
-- 
2.11.0

^ permalink raw reply related	[flat|nested] 138+ messages in thread

* [U-Boot] [PATCH 33/51] drivers: Add transmitter uclass
  2017-07-14 12:54 [U-Boot] [PATCH 00/51] gdsys: Add support for Gazerbeam board Mario Six
                   ` (31 preceding siblings ...)
  2017-07-14 12:55 ` [U-Boot] [PATCH 32/51] drivers: Add ihs_fpga and gdsys_soc drivers Mario Six
@ 2017-07-14 12:55 ` Mario Six
  2017-07-19  9:05   ` Simon Glass
  2017-07-14 12:55 ` [U-Boot] [PATCH 34/51] transmitter: Add Xilinx LogiCore DP TX Mario Six
                   ` (17 subsequent siblings)
  50 siblings, 1 reply; 138+ messages in thread
From: Mario Six @ 2017-07-14 12:55 UTC (permalink / raw)
  To: u-boot

This patch adds a simple transmitter uclass meant for DVI or DisplayPort
transmitters. The only driver functionality implemented are power_on and
power_off methods for powering the transmitter device on and off,
respectively.

Signed-off-by: Mario Six <mario.six@gdsys.cc>
---

 arch/sandbox/dts/sandbox.dts              |  4 ++
 arch/sandbox/dts/test.dts                 |  4 ++
 configs/sandbox_defconfig                 |  2 +
 drivers/Kconfig                           |  2 +
 drivers/Makefile                          |  1 +
 drivers/transmitter/Kconfig               | 16 +++++++
 drivers/transmitter/Makefile              |  9 ++++
 drivers/transmitter/sandbox_transmitter.c | 74 +++++++++++++++++++++++++++++++
 drivers/transmitter/transmitter-uclass.c  | 36 +++++++++++++++
 include/dm/uclass-id.h                    |  1 +
 include/transmitter.h                     | 49 ++++++++++++++++++++
 test/dm/Makefile                          |  1 +
 test/dm/transmitter.c                     | 31 +++++++++++++
 13 files changed, 230 insertions(+)
 create mode 100644 drivers/transmitter/Kconfig
 create mode 100644 drivers/transmitter/Makefile
 create mode 100644 drivers/transmitter/sandbox_transmitter.c
 create mode 100644 drivers/transmitter/transmitter-uclass.c
 create mode 100644 include/transmitter.h
 create mode 100644 test/dm/transmitter.c

diff --git a/arch/sandbox/dts/sandbox.dts b/arch/sandbox/dts/sandbox.dts
index 0aba6c9a6d..0e84b840e7 100644
--- a/arch/sandbox/dts/sandbox.dts
+++ b/arch/sandbox/dts/sandbox.dts
@@ -238,6 +238,10 @@
 		compatible = "google,sandbox-tpm";
 	};
 
+	transmitter {
+		compatible = "sandbox,transmitter";
+	};
+
 	triangle {
 		compatible = "demo-shape";
 		colour = "cyan";
diff --git a/arch/sandbox/dts/test.dts b/arch/sandbox/dts/test.dts
index 65b2f8ecda..36255809d3 100644
--- a/arch/sandbox/dts/test.dts
+++ b/arch/sandbox/dts/test.dts
@@ -392,6 +392,10 @@
 		clock-frequency = <1000000>;
 	};
 
+	transmitter {
+		compatible = "sandbox,transmitter";
+	};
+
 	uart0: serial {
 		compatible = "sandbox,serial";
 		u-boot,dm-pre-reloc;
diff --git a/configs/sandbox_defconfig b/configs/sandbox_defconfig
index 7a1b9ef052..7e1eebee67 100644
--- a/configs/sandbox_defconfig
+++ b/configs/sandbox_defconfig
@@ -167,6 +167,8 @@ CONFIG_TIMER=y
 CONFIG_TIMER_EARLY=y
 CONFIG_SANDBOX_TIMER=y
 CONFIG_TPM_TIS_SANDBOX=y
+CONFIG_TRANSMITTER=y
+CONFIG_SANDBOX_TRANSMITTER=y
 CONFIG_USB=y
 CONFIG_DM_USB=y
 CONFIG_USB_EMUL=y
diff --git a/drivers/Kconfig b/drivers/Kconfig
index 2e03133c43..2d15e4ea09 100644
--- a/drivers/Kconfig
+++ b/drivers/Kconfig
@@ -90,6 +90,8 @@ source "drivers/timer/Kconfig"
 
 source "drivers/tpm/Kconfig"
 
+source "drivers/transmitter/Kconfig"
+
 source "drivers/usb/Kconfig"
 
 source "drivers/video/Kconfig"
diff --git a/drivers/Makefile b/drivers/Makefile
index 8624bd86f1..37cd6396fa 100644
--- a/drivers/Makefile
+++ b/drivers/Makefile
@@ -87,6 +87,7 @@ obj-y += sound/
 obj-y += spmi/
 obj-y += sysreset/
 obj-y += timer/
+obj-y += transmitter/
 obj-y += tpm/
 obj-y += video/
 obj-y += watchdog/
diff --git a/drivers/transmitter/Kconfig b/drivers/transmitter/Kconfig
new file mode 100644
index 0000000000..64ca08f8b8
--- /dev/null
+++ b/drivers/transmitter/Kconfig
@@ -0,0 +1,16 @@
+#
+# Transmitter drivers configuration
+#
+
+menuconfig TRANSMITTER
+	bool "DVI/DP Transmitters"
+
+if TRANSMITTER
+
+config SANDBOX_TRANSMITTER
+	bool "Enable sandbox transmitter driver"
+	depends on DM
+	help
+	  Enable the dummy transmitter for the sandbox.
+
+endif
diff --git a/drivers/transmitter/Makefile b/drivers/transmitter/Makefile
new file mode 100644
index 0000000000..b873e63e28
--- /dev/null
+++ b/drivers/transmitter/Makefile
@@ -0,0 +1,9 @@
+#
+# (C) Copyright 2017
+# Mario Six,  Guntermann & Drunck GmbH, mario.six at gdsys.cc
+#
+# SPDX-License-Identifier:	GPL-2.0+
+#
+
+obj-y += transmitter-uclass.o
+obj-$(CONFIG_SANDBOX_TRANSMITTER) += sandbox_transmitter.o
diff --git a/drivers/transmitter/sandbox_transmitter.c b/drivers/transmitter/sandbox_transmitter.c
new file mode 100644
index 0000000000..cb4c1e81e8
--- /dev/null
+++ b/drivers/transmitter/sandbox_transmitter.c
@@ -0,0 +1,74 @@
+/*
+ * (C) Copyright 2017
+ * Mario Six,  Guntermann & Drunck GmbH, mario.six at gdsys.cc
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <transmitter.h>
+
+struct sandbox_transmitter_priv {
+	int power_state;
+};
+
+void sandbox_transmitter_set_state(struct udevice *dev, int power_state)
+{
+	struct sandbox_transmitter_priv *priv = dev_get_priv(dev);
+
+	priv->power_state = power_state;
+}
+
+int sandbox_transmitter_get_state(struct udevice *dev)
+{
+	struct sandbox_transmitter_priv *priv = dev_get_priv(dev);
+
+	return priv->power_state;
+}
+
+int sandbox_transmitter_power_on(struct udevice *dev, void *data)
+{
+	struct sandbox_transmitter_priv *priv = dev_get_priv(dev);
+
+	priv->power_state = 1;
+
+	return 0;
+}
+
+int sandbox_transmitter_power_off(struct udevice *dev)
+{
+	struct sandbox_transmitter_priv *priv = dev_get_priv(dev);
+
+	priv->power_state = 0;
+
+	return 0;
+}
+
+int sandbox_transmitter_probe(struct udevice *dev)
+{
+	struct sandbox_transmitter_priv *priv = dev_get_priv(dev);
+
+	priv->power_state = 0;
+
+	return 0;
+}
+
+struct transmitter_ops sandbox_transmitter_ops = {
+	.power_on = sandbox_transmitter_power_on,
+	.power_off = sandbox_transmitter_power_off,
+};
+
+static const struct udevice_id sandbox_transmitter_ids[] = {
+	{ .compatible = "sandbox,transmitter" },
+	{ /* sentinel */ }
+};
+
+U_BOOT_DRIVER(sandbox_transmitter) = {
+	.name			= "sandbox_transmitter",
+	.id			= UCLASS_TRANSMITTER,
+	.of_match		= sandbox_transmitter_ids,
+	.probe			= sandbox_transmitter_probe,
+	.priv_auto_alloc_size	= sizeof(struct sandbox_transmitter_priv),
+	.ops			= &sandbox_transmitter_ops,
+};
diff --git a/drivers/transmitter/transmitter-uclass.c b/drivers/transmitter/transmitter-uclass.c
new file mode 100644
index 0000000000..cfcb8ed178
--- /dev/null
+++ b/drivers/transmitter/transmitter-uclass.c
@@ -0,0 +1,36 @@
+/*
+ * (C) Copyright 2017
+ * Mario Six,  Guntermann & Drunck GmbH, mario.six at gdsys.cc
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <errno.h>
+#include <transmitter.h>
+
+int transmitter_power_on(struct udevice *dev, void *data)
+{
+	const struct transmitter_ops *ops = device_get_ops(dev);
+
+	if (!ops->power_on)
+		return -ENOSYS;
+
+	return ops->power_on(dev, data);
+}
+
+int transmitter_power_off(struct udevice *dev)
+{
+	const struct transmitter_ops *ops = device_get_ops(dev);
+
+	if (!ops->power_off)
+		return -ENOSYS;
+
+	return ops->power_off(dev);
+}
+
+UCLASS_DRIVER(transmitter) = {
+	.id		= UCLASS_TRANSMITTER,
+	.name		= "transmitter",
+};
diff --git a/include/dm/uclass-id.h b/include/dm/uclass-id.h
index 56fbedaa9d..8eee8534ab 100644
--- a/include/dm/uclass-id.h
+++ b/include/dm/uclass-id.h
@@ -82,6 +82,7 @@ enum uclass_id {
 	UCLASS_THERMAL,		/* Thermal sensor */
 	UCLASS_TIMER,		/* Timer device */
 	UCLASS_TPM,		/* Trusted Platform Module TIS interface */
+	UCLASS_TRANSMITTER,	/* DVI and DP transmitters*/
 	UCLASS_USB,		/* USB bus */
 	UCLASS_USB_DEV_GENERIC,	/* USB generic device */
 	UCLASS_USB_HUB,		/* USB hub */
diff --git a/include/transmitter.h b/include/transmitter.h
new file mode 100644
index 0000000000..4765c1f17e
--- /dev/null
+++ b/include/transmitter.h
@@ -0,0 +1,49 @@
+/*
+ * (C) Copyright 2017
+ * Mario Six,  Guntermann & Drunck GmbH, mario.six at gdsys.cc
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#ifndef _TRANSMITTER_H_
+#define _TRANSMITTER_H_
+
+struct transmitter_ops {
+	/*
+	 * Power on the transmitter device.
+	 *
+	 * This function is optional.
+	 *
+	 * @dev: The transmitter device to power on.
+	 * @return: 0 if OK, -ve on error
+	 */
+	int (*power_on)(struct udevice *dev, void *data);
+
+	/*
+	 * Power off the transmitter device.
+	 *
+	 * This function is optional.
+	 *
+	 * @dev: The transmitter device to power off.
+	 * @return: 0 if OK, -ve on error
+	 */
+	int (*power_off)(struct udevice *dev);
+};
+
+/*
+ * Power on a transmitter device.
+ *
+ * @dev: The transmitter device to power on.
+ * @return: 0 if OK, -ve on error
+ */
+int transmitter_power_on(struct udevice *dev, void *data);
+
+/*
+ * Power off a transmitter device.
+ *
+ * @dev: The transmitter device to power off.
+ * @return: 0 if OK, -ve on error
+ */
+int transmitter_power_off(struct udevice *dev);
+
+#endif	/* _TRANSMITTER_H_ */
diff --git a/test/dm/Makefile b/test/dm/Makefile
index 513c4561ad..fcc9432c26 100644
--- a/test/dm/Makefile
+++ b/test/dm/Makefile
@@ -44,4 +44,5 @@ obj-$(CONFIG_DM_VIDEO) += video.o
 obj-$(CONFIG_ADC) += adc.o
 obj-$(CONFIG_SPMI) += spmi.o
 obj-$(CONFIG_WDT) += wdt.o
+obj-$(CONFIG_TRANSMITTER) += transmitter.o
 endif
diff --git a/test/dm/transmitter.c b/test/dm/transmitter.c
new file mode 100644
index 0000000000..6ea74a06b7
--- /dev/null
+++ b/test/dm/transmitter.c
@@ -0,0 +1,31 @@
+/*
+ * (C) Copyright 2017
+ * Mario Six,  Guntermann & Drunck GmbH, mario.six at gdsys.cc
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <dm/test.h>
+#include <test/ut.h>
+
+static int dm_test_transmitter(struct unit_test_state *uts)
+{
+	struct udevice *dev;
+
+	ut_assertok(uclass_get_device_by_name(UCLASS_TRANSMITTER, "transmitter",
+					      &dev));
+
+	sandbox_transmitter_set_state(dev, 0);
+	ut_asserteq(0, sandbox_transmitter_get_state(dev));
+
+	ut_assertok(sandbox_transmitter_power_on(dev));
+	ut_asserteq(1, sandbox_transmitter_get_state(dev));
+
+	ut_assertok(sandbox_transmitter_power_off(dev));
+	ut_asserteq(0, sandbox_transmitter_get_state(dev));
+
+	return 0;
+}
+DM_TEST(dm_test_transmitter, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
-- 
2.11.0

^ permalink raw reply related	[flat|nested] 138+ messages in thread

* [U-Boot] [PATCH 34/51] transmitter: Add Xilinx LogiCore DP TX
  2017-07-14 12:54 [U-Boot] [PATCH 00/51] gdsys: Add support for Gazerbeam board Mario Six
                   ` (32 preceding siblings ...)
  2017-07-14 12:55 ` [U-Boot] [PATCH 33/51] drivers: Add transmitter uclass Mario Six
@ 2017-07-14 12:55 ` Mario Six
  2017-07-19  9:06   ` Simon Glass
  2017-07-14 12:55 ` [U-Boot] [PATCH 35/51] drivers: Add ICS8N3QV01 driver Mario Six
                   ` (16 subsequent siblings)
  50 siblings, 1 reply; 138+ messages in thread
From: Mario Six @ 2017-07-14 12:55 UTC (permalink / raw)
  To: u-boot

Add a driver for the TX side of the Xilinx LogiCore DisplayPort IP core.

Signed-off-by: Mario Six <mario.six@gdsys.cc>
---

 drivers/transmitter/Kconfig                |    6 +
 drivers/transmitter/Makefile               |    1 +
 drivers/transmitter/logicore_dp_dpcd.h     |  342 +++++
 drivers/transmitter/logicore_dp_tx.c       | 1984 ++++++++++++++++++++++++++++
 drivers/transmitter/logicore_dp_tx.h       |   40 +
 drivers/transmitter/logicore_dp_tx_regif.h |  365 +++++
 6 files changed, 2738 insertions(+)
 create mode 100644 drivers/transmitter/logicore_dp_dpcd.h
 create mode 100644 drivers/transmitter/logicore_dp_tx.c
 create mode 100644 drivers/transmitter/logicore_dp_tx.h
 create mode 100644 drivers/transmitter/logicore_dp_tx_regif.h

diff --git a/drivers/transmitter/Kconfig b/drivers/transmitter/Kconfig
index 64ca08f8b8..e5613586a3 100644
--- a/drivers/transmitter/Kconfig
+++ b/drivers/transmitter/Kconfig
@@ -13,4 +13,10 @@ config SANDBOX_TRANSMITTER
 	help
 	  Enable the dummy transmitter for the sandbox.
 
+config LOGICORE_DP_TX
+	bool "Enable Logicore DP TX driver"
+	depends on DM
+	help
+	  Enabled the driver for the Logicore DP TX display port transmitter.
+
 endif
diff --git a/drivers/transmitter/Makefile b/drivers/transmitter/Makefile
index b873e63e28..088922d992 100644
--- a/drivers/transmitter/Makefile
+++ b/drivers/transmitter/Makefile
@@ -7,3 +7,4 @@
 
 obj-y += transmitter-uclass.o
 obj-$(CONFIG_SANDBOX_TRANSMITTER) += sandbox_transmitter.o
+obj-$(CONFIG_LOGICORE_DP_TX) += logicore_dp_tx.o
diff --git a/drivers/transmitter/logicore_dp_dpcd.h b/drivers/transmitter/logicore_dp_dpcd.h
new file mode 100644
index 0000000000..6858294551
--- /dev/null
+++ b/drivers/transmitter/logicore_dp_dpcd.h
@@ -0,0 +1,342 @@
+/*
+ * logicore_dp_dpcd.h
+ *
+ * DPCD interface definition for XILINX LogiCore DisplayPort v6.1
+ * based on Xilinx dp_v3_1 driver sources
+ *
+ * (C) Copyright 2016
+ * Dirk Eibach,  Guntermann & Drunck GmbH, dirk.eibach at gdsys.cc
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#ifndef __GDSYS_LOGICORE_DP_DPCD_H__
+#define __GDSYS_LOGICORE_DP_DPCD_H__
+
+/* receiver capability field */
+#define DPCD_REV						0x00000
+#define DPCD_MAX_LINK_RATE					0x00001
+#define DPCD_MAX_LANE_COUNT					0x00002
+#define DPCD_MAX_DOWNSPREAD					0x00003
+#define DPCD_NORP_PWR_V_CAP					0x00004
+#define DPCD_DOWNSP_PRESENT					0x00005
+#define DPCD_ML_CH_CODING_CAP					0x00006
+#define DPCD_DOWNSP_COUNT_MSA_OUI				0x00007
+#define	DPCD_RX_PORT0_CAP_0					0x00008
+#define	DPCD_RX_PORT0_CAP_1					0x00009
+#define	DPCD_RX_PORT1_CAP_0					0x0000A
+#define	DPCD_RX_PORT1_CAP_1					0x0000B
+#define DPCD_I2C_SPEED_CTL_CAP					0x0000C
+#define DPCD_EDP_CFG_CAP					0x0000D
+#define DPCD_TRAIN_AUX_RD_INTERVAL				0x0000E
+#define DPCD_ADAPTER_CAP					0x0000F
+#define DPCD_FAUX_CAP						0x00020
+#define DPCD_MSTM_CAP						0x00021
+#define DPCD_NUM_AUDIO_EPS					0x00022
+#define	DPCD_AV_GRANULARITY					0x00023
+#define DPCD_AUD_DEC_LAT_7_0					0x00024
+#define DPCD_AUD_DEC_LAT_15_8					0x00025
+#define DPCD_AUD_PP_LAT_7_0					0x00026
+#define DPCD_AUD_PP_LAT_15_8					0x00027
+#define DPCD_VID_INTER_LAT					0x00028
+#define DPCD_VID_PROG_LAT					0x00029
+#define DPCD_REP_LAT						0x0002A
+#define DPCD_AUD_DEL_INS_7_0					0x0002B
+#define DPCD_AUD_DEL_INS_15_8					0x0002C
+#define DPCD_AUD_DEL_INS_23_16					0x0002D
+#define DPCD_GUID						0x00030
+#define DPCD_RX_GTC_VALUE_7_0					0x00054
+#define DPCD_RX_GTC_VALUE_15_8					0x00055
+#define DPCD_RX_GTC_VALUE_23_16					0x00056
+#define DPCD_RX_GTC_VALUE_31_24					0x00057
+#define DPCD_RX_GTC_MSTR_REQ					0x00058
+#define DPCD_RX_GTC_FREQ_LOCK_DONE				0x00059
+#define DPCD_DOWNSP_0_CAP					0x00080
+#define DPCD_DOWNSP_1_CAP					0x00081
+#define DPCD_DOWNSP_2_CAP					0x00082
+#define DPCD_DOWNSP_3_CAP					0x00083
+#define DPCD_DOWNSP_0_DET_CAP					0x00080
+#define DPCD_DOWNSP_1_DET_CAP					0x00084
+#define DPCD_DOWNSP_2_DET_CAP					0x00088
+#define DPCD_DOWNSP_3_DET_CAP					0x0008C
+
+/* link configuration field */
+#define DPCD_LINK_BW_SET					0x00100
+#define DPCD_LANE_COUNT_SET					0x00101
+#define DPCD_TP_SET						0x00102
+#define DPCD_TRAINING_LANE0_SET					0x00103
+#define DPCD_TRAINING_LANE1_SET					0x00104
+#define DPCD_TRAINING_LANE2_SET					0x00105
+#define DPCD_TRAINING_LANE3_SET					0x00106
+#define DPCD_DOWNSPREAD_CTRL					0x00107
+#define DPCD_ML_CH_CODING_SET					0x00108
+#define DPCD_I2C_SPEED_CTL_SET					0x00109
+#define DPCD_EDP_CFG_SET					0x0010A
+#define DPCD_LINK_QUAL_LANE0_SET				0x0010B
+#define DPCD_LINK_QUAL_LANE1_SET				0x0010C
+#define DPCD_LINK_QUAL_LANE2_SET				0x0010D
+#define DPCD_LINK_QUAL_LANE3_SET				0x0010E
+#define DPCD_TRAINING_LANE0_1_SET2				0x0010F
+#define DPCD_TRAINING_LANE2_3_SET2				0x00110
+#define DPCD_MSTM_CTRL						0x00111
+#define DPCD_AUDIO_DELAY_7_0					0x00112
+#define DPCD_AUDIO_DELAY_15_8					0x00113
+#define DPCD_AUDIO_DELAY_23_6					0x00114
+#define DPCD_UPSTREAM_DEVICE_DP_PWR_NEED			0x00118
+#define DPCD_FAUX_MODE_CTRL					0x00120
+#define DPCD_FAUX_FORWARD_CH_DRIVE_SET				0x00121
+#define DPCD_BACK_CH_STATUS					0x00122
+#define DPCD_FAUX_BACK_CH_SYMBOL_ERROR_COUNT			0x00123
+#define DPCD_FAUX_BACK_CH_TRAINING_PATTERN_TIME			0x00125
+#define DPCD_TX_GTC_VALUE_7_0					0x00154
+#define DPCD_TX_GTC_VALUE_15_8					0x00155
+#define DPCD_TX_GTC_VALUE_23_16					0x00156
+#define DPCD_TX_GTC_VALUE_31_24					0x00157
+#define DPCD_RX_GTC_VALUE_PHASE_SKEW_EN				0x00158
+#define DPCD_TX_GTC_FREQ_LOCK_DONE				0x00159
+#define DPCD_ADAPTER_CTRL					0x001A0
+#define DPCD_BRANCH_DEVICE_CTRL					0x001A1
+#define DPCD_PAYLOAD_ALLOCATE_SET				0x001C0
+#define DPCD_PAYLOAD_ALLOCATE_START_TIME_SLOT			0x001C1
+#define DPCD_PAYLOAD_ALLOCATE_TIME_SLOT_COUNT			0x001C2
+
+/* link/sink status field */
+#define DPCD_SINK_COUNT						0x00200
+#define DPCD_DEVICE_SERVICE_IRQ					0x00201
+#define DPCD_STATUS_LANE_0_1					0x00202
+#define DPCD_STATUS_LANE_2_3					0x00203
+#define DPCD_LANE_ALIGN_STATUS_UPDATED				0x00204
+#define DPCD_SINK_STATUS					0x00205
+#define DPCD_ADJ_REQ_LANE_0_1					0x00206
+#define DPCD_ADJ_REQ_LANE_2_3					0x00207
+#define DPCD_TRAINING_SCORE_LANE_0				0x00208
+#define DPCD_TRAINING_SCORE_LANE_1				0x00209
+#define DPCD_TRAINING_SCORE_LANE_2				0x0020A
+#define DPCD_TRAINING_SCORE_LANE_3				0x0020B
+#define DPCD_ADJ_REQ_PC2					0x0020C
+#define DPCD_FAUX_FORWARD_CH_SYMBOL_ERROR_COUNT			0x0020D
+#define DPCD_SYMBOL_ERROR_COUNT_LANE_0				0x00210
+#define DPCD_SYMBOL_ERROR_COUNT_LANE_1				0x00212
+#define DPCD_SYMBOL_ERROR_COUNT_LANE_2				0x00214
+#define DPCD_SYMBOL_ERROR_COUNT_LANE_3				0x00216
+
+/* automated testing sub-field */
+#define DPCD_FAUX_FORWARD_CH_STATUS				0x00280
+#define DPCD_FAUX_BACK_CH_DRIVE_SET				0x00281
+#define DPCD_FAUX_BACK_CH_SYM_ERR_COUNT_CTRL			0x00282
+#define DPCD_PAYLOAD_TABLE_UPDATE_STATUS			0x002C0
+#define DPCD_VC_PAYLOAD_ID_SLOT(SlotNum) \
+			(DPCD_PAYLOAD_TABLE_UPDATE_STATUS + SlotNum)
+
+/* sink control field */
+#define DPCD_SET_POWER_DP_PWR_VOLTAGE				0x00600
+
+/* sideband message buffers */
+#define DPCD_DOWN_REQ						0x01000
+#define DPCD_UP_REP						0x01200
+#define DPCD_DOWN_REP						0x01400
+#define DPCD_UP_REQ						0x01600
+
+/* event status indicator field */
+#define DPCD_SINK_COUNT_ESI					0x02002
+#define DPCD_SINK_DEVICE_SERVICE_IRQ_VECTOR_ESI0		0x02003
+#define DPCD_SINK_DEVICE_SERVICE_IRQ_VECTOR_ESI1		0x02004
+#define DPCD_SINK_LINK_SERVICE_IRQ_VECTOR_ESI0			0x02005
+#define DPCD_SINK_LANE0_1_STATUS				0x0200C
+#define DPCD_SINK_LANE2_3_STATUS				0x0200D
+#define DPCD_SINK_ALIGN_STATUS_UPDATED_ESI			0x0200E
+#define DPCD_SINK_STATUS_ESI					0x0200F
+
+/*
+ * field addresses and sizes.
+ */
+#define DPCD_RECEIVER_CAP_FIELD_START		DPCD_REV
+#define DPCD_RECEIVER_CAP_FIELD_SIZE			0x100
+#define DPCD_LINK_CFG_FIELD_START		DPCD_LINK_BW_SET
+#define DPCD_LINK_CFG_FIELD_SIZE				0x100
+#define DPCD_LINK_SINK_STATUS_FIELD_START	DPCD_SINK_COUNT
+#define DPCD_LINK_SINK_STATUS_FIELD_SIZE			0x17
+/* 0x00000: DPCD_REV */
+#define DPCD_REV_MNR_MASK					0x0F
+#define DPCD_REV_MJR_MASK					0xF0
+#define DPCD_REV_MJR_SHIFT					4
+/* 0x00001: MAX_LINK_RATE */
+#define DPCD_MAX_LINK_RATE_162GBPS				0x06
+#define DPCD_MAX_LINK_RATE_270GBPS				0x0A
+#define DPCD_MAX_LINK_RATE_540GBPS				0x14
+/* 0x00002: MAX_LANE_COUNT */
+#define DPCD_MAX_LANE_COUNT_MASK				0x1F
+#define DPCD_MAX_LANE_COUNT_1					0x01
+#define DPCD_MAX_LANE_COUNT_2					0x02
+#define DPCD_MAX_LANE_COUNT_4					0x04
+#define DPCD_TPS3_SUPPORT_MASK					0x40
+#define DPCD_ENHANCED_FRAME_SUPPORT_MASK			0x80
+/* 0x00003: MAX_DOWNSPREAD */
+#define DPCD_MAX_DOWNSPREAD_MASK				0x01
+#define DPCD_NO_AUX_HANDSHAKE_LINK_TRAIN_MASK			0x40
+/* 0x00005: DOWNSP_PRESENT */
+#define DPCD_DOWNSP_PRESENT_MASK				0x01
+#define DPCD_DOWNSP_TYPE_MASK					0x06
+#define DPCD_DOWNSP_TYPE_SHIFT					1
+#define DPCD_DOWNSP_TYPE_DP					0x0
+#define DPCD_DOWNSP_TYPE_AVGA_ADVII				0x1
+#define DPCD_DOWNSP_TYPE_DVI_HDMI_DPPP				0x2
+#define DPCD_DOWNSP_TYPE_OTHERS					0x3
+#define DPCD_DOWNSP_FORMAT_CONV_MASK				0x08
+#define DPCD_DOWNSP_DCAP_INFO_AVAIL_MASK			0x10
+/* 0x00006, 0x00108: ML_CH_CODING_SUPPORT, ML_CH_CODING_SET */
+#define DPCD_ML_CH_CODING_MASK					0x01
+/* 0x00007: DOWNSP_COUNT_MSA_OUI */
+#define DPCD_DOWNSP_COUNT_MASK					0x0F
+#define DPCD_MSA_TIMING_PAR_IGNORED_MASK			0x40
+#define DPCD_OUI_SUPPORT_MASK					0x80
+/* 0x00008, 0x0000A: RX_PORT[0-1]_CAP_0 */
+#define DPCD_RX_PORTX_CAP_0_LOCAL_EDID_PRESENT_MASK		0x02
+#define DPCD_RX_PORTX_CAP_0_ASSOC_TO_PRECEDING_PORT_MASK	0x04
+/* 0x0000C, 0x00109: I2C_SPEED_CTL_CAP, I2C_SPEED_CTL_SET */
+#define DPCD_I2C_SPEED_CTL_NONE					0x00
+#define DPCD_I2C_SPEED_CTL_1KBIPS				0x01
+#define DPCD_I2C_SPEED_CTL_5KBIPS				0x02
+#define DPCD_I2C_SPEED_CTL_10KBIPS				0x04
+#define DPCD_I2C_SPEED_CTL_100KBIPS				0x08
+#define DPCD_I2C_SPEED_CTL_400KBIPS				0x10
+#define DPCD_I2C_SPEED_CTL_1MBIPS				0x20
+/* 0x0000E: TRAIN_AUX_RD_INTERVAL */
+#define DPCD_TRAIN_AUX_RD_INT_100_400US				0x00
+#define DPCD_TRAIN_AUX_RD_INT_4MS				0x01
+#define DPCD_TRAIN_AUX_RD_INT_8MS				0x02
+#define DPCD_TRAIN_AUX_RD_INT_12MS				0x03
+#define DPCD_TRAIN_AUX_RD_INT_16MS				0x04
+/* 0x00020: DPCD_FAUX_CAP */
+#define DPCD_FAUX_CAP_MASK					0x01
+/* 0x00021: MSTM_CAP */
+#define DPCD_MST_CAP_MASK					0x01
+/* 0x00080, 0x00081|4, 0x00082|8, 0x00083|C: DOWNSP_X_(DET_)CAP */
+#define DPCD_DOWNSP_X_CAP_TYPE_MASK				0x07
+#define DPCD_DOWNSP_X_CAP_TYPE_DP				0x0
+#define DPCD_DOWNSP_X_CAP_TYPE_AVGA				0x1
+#define DPCD_DOWNSP_X_CAP_TYPE_DVI				0x2
+#define DPCD_DOWNSP_X_CAP_TYPE_HDMI				0x3
+#define DPCD_DOWNSP_X_CAP_TYPE_OTHERS				0x4
+#define DPCD_DOWNSP_X_CAP_TYPE_DPPP				0x5
+#define DPCD_DOWNSP_X_CAP_HPD_MASK				0x80
+#define DPCD_DOWNSP_X_CAP_NON_EDID_ATTR_MASK			0xF0
+#define DPCD_DOWNSP_X_CAP_NON_EDID_ATTR_SHIFT			4
+#define DPCD_DOWNSP_X_CAP_NON_EDID_ATTR_720_480_I_60		0x1
+#define DPCD_DOWNSP_X_CAP_NON_EDID_ATTR_720_480_I_50		0x2
+#define DPCD_DOWNSP_X_CAP_NON_EDID_ATTR_1920_1080_I_60		0x3
+#define DPCD_DOWNSP_X_CAP_NON_EDID_ATTR_1920_1080_I_50		0x4
+#define DPCD_DOWNSP_X_CAP_NON_EDID_ATTR_1280_720_P_60		0x5
+#define DPCD_DOWNSP_X_CAP_NON_EDID_ATTR_1280_720_P_50		0x7
+/* 0x00082, 0x00086, 0x0008A, 0x0008E: DOWNSP_X_(DET_)CAP2 */
+#define DPCD_DOWNSP_X_DCAP_MAX_BPC_MASK				0x03
+#define DPCD_DOWNSP_X_DCAP_MAX_BPC_8				0x0
+#define DPCD_DOWNSP_X_DCAP_MAX_BPC_10				0x1
+#define DPCD_DOWNSP_X_DCAP_MAX_BPC_12				0x2
+#define DPCD_DOWNSP_X_DCAP_MAX_BPC_16				0x3
+/* 0x00082, 0x00086, 0x0008A, 0x0008E: DOWNSP_X_(DET_)CAP2 */
+#define DPCD_DOWNSP_X_DCAP_HDMI_DPPP_FS2FP_MASK			0x01
+#define DPCD_DOWNSP_X_DCAP_DVI_DL_MASK				0x02
+#define DPCD_DOWNSP_X_DCAP_DVI_HCD_MASK				0x04
+
+/* link configuration field masks, shifts, and register values */
+/* 0x00100: DPCD_LINK_BW_SET */
+#define DPCD_LINK_BW_SET_162GBPS				0x06
+#define DPCD_LINK_BW_SET_270GBPS				0x0A
+#define DPCD_LINK_BW_SET_540GBPS				0x14
+/* 0x00101: LANE_COUNT_SET */
+#define DPCD_LANE_COUNT_SET_MASK				0x1F
+#define DPCD_LANE_COUNT_SET_1					0x01
+#define DPCD_LANE_COUNT_SET_2					0x02
+#define DPCD_LANE_COUNT_SET_4					0x04
+#define DPCD_ENHANCED_FRAME_EN_MASK				0x80
+/* 0x00102: TP_SET */
+#define DPCD_TP_SEL_MASK					0x03
+#define DPCD_TP_SEL_OFF						0x0
+#define DPCD_TP_SEL_TP1						0x1
+#define DPCD_TP_SEL_TP2						0x2
+#define DPCD_TP_SEL_TP3						0x3
+#define DPCD_TP_SET_LQP_MASK					0x06
+#define DPCD_TP_SET_LQP_SHIFT					2
+#define DPCD_TP_SET_LQP_OFF					0x0
+#define DPCD_TP_SET_LQP_D102_TEST				0x1
+#define DPCD_TP_SET_LQP_SER_MES					0x2
+#define DPCD_TP_SET_LQP_PRBS7					0x3
+#define DPCD_TP_SET_REC_CLK_OUT_EN_MASK				0x10
+#define DPCD_TP_SET_SCRAMB_DIS_MASK				0x20
+#define DPCD_TP_SET_SE_COUNT_SEL_MASK				0xC0
+#define DPCD_TP_SET_SE_COUNT_SEL_SHIFT				6
+#define DPCD_TP_SET_SE_COUNT_SEL_DE_ISE				0x0
+#define DPCD_TP_SET_SE_COUNT_SEL_DE				0x1
+#define DPCD_TP_SET_SE_COUNT_SEL_ISE				0x2
+/* 0x00103-0x00106: TRAINING_LANE[0-3]_SET */
+#define DPCD_TRAINING_LANEX_SET_VS_MASK				0x03
+#define DPCD_TRAINING_LANEX_SET_MAX_VS_MASK			0x04
+#define DPCD_TRAINING_LANEX_SET_PE_MASK				0x18
+#define DPCD_TRAINING_LANEX_SET_PE_SHIFT			3
+#define DPCD_TRAINING_LANEX_SET_MAX_PE_MASK			0x20
+/* 0x00107: DOWNSPREAD_CTRL */
+#define DPCD_SPREAD_AMP_MASK					0x10
+#define DPCD_MSA_TIMING_PAR_IGNORED_EN_MASK			0x80
+/* 0x00108: ML_CH_CODING_SET - Same as 0x00006: ML_CH_CODING_SUPPORT */
+/* 0x00109: I2C_SPEED_CTL_SET - Same as 0x0000C: I2C_SPEED_CTL_CAP */
+/* 0x0010F-0x00110: TRAINING_LANE[0_1-2_3]_SET2 */
+#define DPCD_TRAINING_LANE_0_2_SET_PC2_MASK			0x03
+#define DPCD_TRAINING_LANE_0_2_SET_MAX_PC2_MASK			0x04
+#define DPCD_TRAINING_LANE_1_3_SET_PC2_MASK			0x30
+#define DPCD_TRAINING_LANE_1_3_SET_PC2_SHIFT			4
+#define DPCD_TRAINING_LANE_1_3_SET_MAX_PC2_MASK			0x40
+/* 0x00111: MSTM_CTRL */
+#define DPCD_MST_EN_MASK					0x01
+#define DPCD_UP_REQ_EN_MASK					0x02
+#define DPCD_UP_IS_SRC_MASK					0x03
+
+/* link/sink status field masks, shifts, and register values */
+/* 0x00200: SINK_COUNT */
+#define DPCD_SINK_COUNT_LOW_MASK				0x3F
+#define DPCD_SINK_CP_READY_MASK					0x40
+#define DPCD_SINK_COUNT_HIGH_MASK				0x80
+#define DPCD_SINK_COUNT_HIGH_LOW_SHIFT				1
+/* 0x00202: STATUS_LANE_0_1 */
+#define DPCD_STATUS_LANE_0_CR_DONE_MASK				0x01
+#define DPCD_STATUS_LANE_0_CE_DONE_MASK				0x02
+#define DPCD_STATUS_LANE_0_SL_DONE_MASK				0x04
+#define DPCD_STATUS_LANE_1_CR_DONE_MASK				0x10
+#define DPCD_STATUS_LANE_1_CE_DONE_MASK				0x20
+#define DPCD_STATUS_LANE_1_SL_DONE_MASK				0x40
+/* 0x00202: STATUS_LANE_2_3 */
+#define DPCD_STATUS_LANE_2_CR_DONE_MASK				0x01
+#define DPCD_STATUS_LANE_2_CE_DONE_MASK				0x02
+#define DPCD_STATUS_LANE_2_SL_DONE_MASK				0x04
+#define DPCD_STATUS_LANE_3_CR_DONE_MASK				0x10
+#define DPCD_STATUS_LANE_3_CE_DONE_MASK				0x20
+#define DPCD_STATUS_LANE_3_SL_DONE_MASK				0x40
+/* 0x00204: LANE_ALIGN_STATUS_UPDATED */
+#define DPCD_LANE_ALIGN_STATUS_UPDATED_IA_DONE_MASK \
+								0x01
+#define DPCD_LANE_ALIGN_STATUS_UPDATED_DOWNSP_STATUS_CHANGED_MASK \
+								0x40
+#define DPCD_LANE_ALIGN_STATUS_UPDATED_LINK_STATUS_UPDATED_MASK \
+								0x80
+/* 0x00205: SINK_STATUS */
+#define DPCD_SINK_STATUS_RX_PORT0_SYNC_STATUS_MASK		0x01
+#define DPCD_SINK_STATUS_RX_PORT1_SYNC_STATUS_MASK		0x02
+
+/* 0x00206, 0x00207: ADJ_REQ_LANE_[0,2]_[1,3] */
+#define DPCD_ADJ_REQ_LANE_0_2_VS_MASK				0x03
+#define DPCD_ADJ_REQ_LANE_0_2_PE_MASK				0x0C
+#define DPCD_ADJ_REQ_LANE_0_2_PE_SHIFT				2
+#define DPCD_ADJ_REQ_LANE_1_3_VS_MASK				0x30
+#define DPCD_ADJ_REQ_LANE_1_3_VS_SHIFT				4
+#define DPCD_ADJ_REQ_LANE_1_3_PE_MASK				0xC0
+#define DPCD_ADJ_REQ_LANE_1_3_PE_SHIFT				6
+/* 0x0020C: ADJ_REQ_PC2 */
+#define DPCD_ADJ_REQ_PC2_LANE_0_MASK				0x03
+#define DPCD_ADJ_REQ_PC2_LANE_1_MASK				0x0C
+#define DPCD_ADJ_REQ_PC2_LANE_1_SHIFT				2
+#define DPCD_ADJ_REQ_PC2_LANE_2_MASK				0x30
+#define DPCD_ADJ_REQ_PC2_LANE_2_SHIFT				4
+#define DPCD_ADJ_REQ_PC2_LANE_3_MASK				0xC0
+#define DPCD_ADJ_REQ_PC2_LANE_3_SHIFT				6
+
+#endif /* __GDSYS_LOGICORE_DP_DPCD_H__ */
diff --git a/drivers/transmitter/logicore_dp_tx.c b/drivers/transmitter/logicore_dp_tx.c
new file mode 100644
index 0000000000..b61159cd89
--- /dev/null
+++ b/drivers/transmitter/logicore_dp_tx.c
@@ -0,0 +1,1984 @@
+/*
+ * logicore_dp_tx.c
+ *
+ * Driver for XILINX LogiCore DisplayPort v6.1 TX (Source)
+ * based on Xilinx dp_v3_1 driver sources, updated to dp_v4_0
+ *
+ * (C) Copyright 2016
+ * Dirk Eibach,  Guntermann & Drunck GmbH, dirk.eibach at gdsys.cc
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#include <common.h>
+#include <clk.h>
+#include <dm.h>
+#include <errno.h>
+#include <transmitter.h>
+
+#include "ihs_axi.h"
+
+#include "logicore_dp_dpcd.h"
+#include "logicore_dp_tx_regif.h"
+#include "logicore_dp_tx.h"
+
+DECLARE_GLOBAL_DATA_PTR;
+
+#define S_AXI_CLK_DEFAULT 100000000
+
+#define PHY_CLOCK_SELECT_DEFAULT PHY_CLOCK_SELECT_540GBPS
+
+/* The maximum voltage swing level is 3. */
+#define MAXIMUM_VS_LEVEL 3
+/* The maximum pre-emphasis level is 3. */
+#define MAXIMUM_PE_LEVEL 3
+
+/* Error out if an AUX request yields a defer reply more than 50 times. */
+#define AUX_MAX_DEFER_COUNT 50
+/* Error out if an AUX request times out more than 50 times awaiting a reply. */
+#define AUX_MAX_TIMEOUT_COUNT 50
+/* Error out if checking for a connected device times out more than 50 times. */
+#define IS_CONNECTED_MAX_TIMEOUT_COUNT 50
+
+enum {
+	TS_CLOCK_RECOVERY,
+	TS_CHANNEL_EQUALIZATION,
+	TS_ADJUST_LINK_RATE,
+	TS_ADJUST_LANE_COUNT,
+	TS_FAILURE,
+	TS_SUCCESS
+};
+
+struct aux_transaction {
+	u16 cmd_code;
+	u8 num_bytes;
+	u32 address;
+	u8 *data;
+};
+
+/*
+ * all porch parameters have been removed because our videodata is hstart/vstart
+ * based and there is no benefit in keeping the porches
+ */
+
+struct main_stream_attributes {
+	/* Pixel clock of the stream (in Hz). */
+	u32 pixel_clock_hz;
+	/* Miscellaneous stream attributes 0 as specified by the DisplayPort
+	 * 1.2 specification.
+	 */
+	u32 misc_0;
+	/* Miscellaneous stream attributes 1 as specified by the DisplayPort
+	 * 1.2 specification.
+	 */
+	u32 misc_1;
+	/* N value for the video stream. */
+	u32 n_vid;
+	/* M value used to recover the video clock from the link clock. */
+	u32 m_vid;
+	/* Width of the user data input port. */
+	u32 user_pixel_width;
+	/* Used to translate the number of pixels per line to the native
+	 * internal 16-bit datapath.
+	 */
+	u32 data_per_lane;
+	/* Average number of bytes per transfer unit, scaled up by a factor of
+	 * 1000.
+	 */
+	u32 avg_bytes_per_tu;
+	/* Size of the transfer unit in the framing logic. In MST mode, this is
+	 * also the number of time slots that are alloted in the payload ID
+	 * table.
+	 */
+	u32 transfer_unit_size;
+	/* Number of initial wait cycles at the start of a new line by the
+	 * framing logic.
+	 */
+	u32 init_wait;
+	/* Bits per color component. */
+	u32 bits_per_color;
+	/* The component format currently in use by the video stream. */
+	u8 component_format;
+	/* The dynamic range currently in use by the video stream. */
+	u8 dynamic_range;
+	/* The YCbCr colorimetry currently in use by the video stream. */
+	u8 y_cb_cr_colorimetry;
+	/* Synchronous clock mode is currently in use by the video stream. */
+	u8 synchronous_clock_mode;
+	/* If set to 1, the value stored for user_pixel_width will be used as
+	 * the pixel width.
+	 */
+	u8 override_user_pixel_width;
+	/* Horiz. blank start (pixels). */
+	u32 h_start;
+	/* Horiz. active resolution (pixels) */
+	u16 h_active;
+	/* Horiz. sync width (pixels) */
+	u16 h_sync_width;
+	/* Horiz. total (pixels) */
+	u16 h_total;
+	/* Horiz. sync polarity (0=neg|1=pos) */
+	bool h_sync_polarity;
+	/* Vert. blank start (in lines). */
+	u32 v_start;
+	/* Vert. active resolution (lines) */
+	u16 v_active;
+	/* Vert. sync width (lines) */
+	u16 v_sync_width;
+	/* Vert. total (lines) */
+	u16 v_total;
+	/* Vert. sync polarity (0=neg|1=pos) */
+	bool v_sync_polarity;
+};
+
+struct link_config {
+	u8 lane_count;
+	u8 link_rate;
+	bool scrambler_en;
+	bool enhanced_framing_mode;
+	bool downspread_control;
+	u8 max_lane_count;
+	u8 max_link_rate;
+	bool support_enhanced_framing_mode;
+	bool support_downspread_control;
+	u8 vs_level; /* voltage swing for each lane */
+	u8 pe_level; /* pre-emphasis/cursor level for each lane */
+	u8 pattern;
+};
+
+struct dp_tx {
+	u32 base;
+
+	u32 s_axi_clk;
+
+	bool train_adaptive;
+
+	u8 max_link_rate;
+	u8 max_lane_count;
+
+	u8 dpcd_rx_caps[16];
+
+	/* This is a raw read of the RX device's status registers. The first 4
+	 * bytes correspond to the lane status associated with clock recovery,
+	 * channel equalization, symbol lock, and interlane alignment. The
+	 * remaining 2 bytes represent the pre-emphasis and voltage swing level
+	 * adjustments requested by the RX device.
+	 */
+	u8 lane_status_ajd_reqs[6];
+
+	struct link_config link_config;
+	struct main_stream_attributes main_stream_attributes;
+};
+
+/*
+ * internal API
+ */
+
+static u32 get_reg(struct udevice *dev, u32 reg)
+{
+	struct dp_tx *dp_tx = dev_get_priv(dev);
+	u32 value = 0;
+	int res;
+
+	// TODO error handling
+	res = axi_read(dev->parent, dp_tx->base + reg, &value);
+	if (res < 0)
+		printf("%s() failed; res = %d\n", __func__, res);
+
+	return value;
+}
+
+static void set_reg(struct udevice *dev, u32 reg, u32 value)
+{
+	struct dp_tx *dp_tx = dev_get_priv(dev);
+
+	axi_write(dev->parent, dp_tx->base + reg, value);
+}
+
+/*
+ * Check if there is a connected RX device.
+ * The Xilinx original calls msleep_interruptible at least once,
+ * ignoring status.
+ */
+bool is_connected(struct udevice *dev)
+{
+	u8 retries = 0;
+
+	do {
+		int status = get_reg(dev, REG_INTERRUPT_SIG_STATE) &
+			     INTERRUPT_SIG_STATE_HPD_STATE_MASK;
+		if (status)
+			return true;
+
+		udelay(1000);
+	} while (retries++ < IS_CONNECTED_MAX_TIMEOUT_COUNT);
+
+	return false;
+}
+
+/*
+ * Wait for the DisplayPort PHY to come out of reset.
+ */
+static int wait_phy_ready(struct udevice *dev, u32 mask)
+{
+	u16 timeout = 20000;
+	u32 phy_status;
+
+	/* Wait until the PHY is ready. */
+	do {
+		phy_status = get_reg(dev, REG_PHY_STATUS) & mask;
+
+		/* Protect against an infinite loop. */
+		if (!timeout--)
+			return -ETIMEDOUT;
+
+		udelay(20);
+	} while (phy_status != mask);
+
+	return 0;
+}
+
+/* AUX channel access */
+
+/*
+ * Wait until another request is no longer in progress.
+ */
+static int aux_wait_ready(struct udevice *dev)
+{
+	int status;
+	u32 timeout = 100;
+
+	/* Wait until the DisplayPort TX core is ready. */
+	do {
+		status = get_reg(dev, REG_INTERRUPT_SIG_STATE);
+
+		/* Protect against an infinite loop. */
+		if (!timeout--)
+			return -ETIMEDOUT;
+		udelay(20);
+	} while (status & REPLY_STATUS_REPLY_IN_PROGRESS_MASK);
+
+	return 0;
+}
+
+/*
+ * Wait for a reply indicating that the most recent AUX request
+ * has been received by the RX device.
+ */
+static int aux_wait_reply(struct udevice *dev)
+{
+	u32 timeout = 100;
+
+	while (timeout > 0) {
+		int status = get_reg(dev, REG_REPLY_STATUS);
+
+		/* Check for error. */
+		if (status & REPLY_STATUS_REPLY_ERROR_MASK)
+			return -ETIMEDOUT;
+
+		/* Check for a reply. */
+		if ((status & REPLY_STATUS_REPLY_RECEIVED_MASK) &&
+		    !(status &
+		      REPLY_STATUS_REQUEST_IN_PROGRESS_MASK) &&
+		    !(status &
+		      REPLY_STATUS_REPLY_IN_PROGRESS_MASK)) {
+			return 0;
+		}
+
+		timeout--;
+		udelay(20);
+	}
+
+	return -ETIMEDOUT;
+}
+
+/*
+ * Submit the supplied AUX request to the RX device over the AUX
+ * channel by writing the command, the destination address, (the write buffer
+ * for write commands), and the data size to the DisplayPort TX core.
+ */
+static int aux_request_send(struct udevice *dev,
+			    struct aux_transaction *request)
+{
+	u32 timeout_count;
+	int status;
+	u8 index;
+
+	/* Ensure that any pending AUX transactions have completed. */
+	timeout_count = 0;
+	do {
+		status = get_reg(dev, REG_REPLY_STATUS);
+
+		udelay(20);
+		timeout_count++;
+		if (timeout_count >= AUX_MAX_TIMEOUT_COUNT)
+			return -ETIMEDOUT;
+	} while ((status & REPLY_STATUS_REQUEST_IN_PROGRESS_MASK) ||
+		 (status & REPLY_STATUS_REPLY_IN_PROGRESS_MASK));
+
+	set_reg(dev, REG_AUX_ADDRESS, request->address);
+
+	if ((request->cmd_code == AUX_CMD_WRITE) ||
+	    (request->cmd_code == AUX_CMD_I2C_WRITE) ||
+	    (request->cmd_code == AUX_CMD_I2C_WRITE_MOT)) {
+		/* Feed write data into the DisplayPort TX core's write FIFO. */
+		for (index = 0; index < request->num_bytes; index++) {
+			set_reg(dev,
+				REG_AUX_WRITE_FIFO, request->data[index]);
+		}
+	}
+
+	/* Submit the command and the data size. */
+	set_reg(dev, REG_AUX_CMD,
+		((request->cmd_code << AUX_CMD_SHIFT) |
+		 ((request->num_bytes - 1) &
+		  AUX_CMD_NBYTES_TRANSFER_MASK)));
+
+	/* Check for a reply from the RX device to the submitted request. */
+	status = aux_wait_reply(dev);
+	if (status)
+		/* Waiting for a reply timed out. */
+		return -ETIMEDOUT;
+
+	/* Analyze the reply. */
+	status = get_reg(dev, REG_AUX_REPLY_CODE);
+	if ((status == AUX_REPLY_CODE_DEFER) ||
+	    (status == AUX_REPLY_CODE_I2C_DEFER)) {
+		/* The request was deferred. */
+		return -EAGAIN;
+	} else if ((status == AUX_REPLY_CODE_NACK) ||
+		   (status == AUX_REPLY_CODE_I2C_NACK)) {
+		/* The request was not acknowledged. */
+		return -EIO;
+	}
+
+	/* The request was acknowledged. */
+
+	if ((request->cmd_code == AUX_CMD_READ) ||
+	    (request->cmd_code == AUX_CMD_I2C_READ) ||
+	    (request->cmd_code == AUX_CMD_I2C_READ_MOT)) {
+		/* Wait until all data has been received. */
+		timeout_count = 0;
+		do {
+			status = get_reg(dev, REG_REPLY_DATA_COUNT);
+
+			udelay(100);
+			timeout_count++;
+			if (timeout_count >= AUX_MAX_TIMEOUT_COUNT)
+				return -ETIMEDOUT;
+		} while (status != request->num_bytes);
+
+		/* Obtain the read data from the reply FIFO. */
+		for (index = 0; index < request->num_bytes; index++)
+			request->data[index] = get_reg(dev, REG_AUX_REPLY_DATA);
+	}
+
+	return 0;
+}
+
+/*
+ * Submit the supplied AUX request to the RX device over the AUX
+ * channel. If waiting for a reply times out, or if the DisplayPort TX core
+ * indicates that the request was deferred, the request is sent again (up to a
+ * maximum specified by AUX_MAX_DEFER_COUNT|AUX_MAX_TIMEOUT_COUNT).
+ */
+static int aux_request(struct udevice *dev, struct aux_transaction *request)
+{
+	u32 defer_count = 0;
+	u32 timeout_count = 0;
+
+	while ((defer_count < AUX_MAX_DEFER_COUNT) &&
+	       (timeout_count < AUX_MAX_TIMEOUT_COUNT)) {
+		int status = aux_wait_ready(dev);
+
+		if (status) {
+			/* The RX device isn't ready yet. */
+			timeout_count++;
+			continue;
+		}
+
+		status = aux_request_send(dev, request);
+		if (status == -EAGAIN) {
+			/* The request was deferred. */
+			defer_count++;
+		} else if (status == -ETIMEDOUT) {
+			/* Waiting for a reply timed out. */
+			timeout_count++;
+		} else {
+			/* -EIO indicates that the request was NACK'ed,
+			 * 0 indicates that the request was ACK'ed.
+			 */
+			return status;
+		}
+
+		udelay(100);
+	}
+
+	/* The request was not successfully received by the RX device. */
+	return -ETIMEDOUT;
+}
+
+/*
+ * Common sequence of submitting an AUX command for
+ * AUX read, AUX write, I2C-over-AUX read, and I2C-over-AUX write transactions.
+ * If required, the reads and writes are split into multiple requests, each
+ * acting on a maximum of 16 bytes.
+ */
+static int aux_common(struct udevice *dev, u32 cmd_type, u32 address,
+		      u32 num_bytes, u8 *data)
+{
+	struct aux_transaction request;
+	u32 bytes_left;
+
+	/*
+	 * set the start address for AUX transactions. For I2C transactions,
+	 * this is the address of the I2C bus.
+	 */
+	request.address = address;
+
+	bytes_left = num_bytes;
+	while (bytes_left) {
+		int status;
+
+		request.cmd_code = cmd_type;
+
+		if ((cmd_type == AUX_CMD_READ) ||
+		    (cmd_type == AUX_CMD_WRITE)) {
+			/* Increment address for normal AUX transactions. */
+			request.address = address + (num_bytes - bytes_left);
+		}
+
+		/* Increment the pointer to the supplied data buffer. */
+		request.data = &data[num_bytes - bytes_left];
+
+		request.num_bytes = (bytes_left > 16) ? 16 : bytes_left;
+		bytes_left -= request.num_bytes;
+
+		if ((cmd_type == AUX_CMD_I2C_READ) && bytes_left) {
+			/* Middle of a transaction I2C read request. Override
+			 * the command code that was set to cmd_type.
+			 */
+			request.cmd_code = AUX_CMD_I2C_READ_MOT;
+		} else if ((cmd_type == AUX_CMD_I2C_WRITE) && bytes_left) {
+			/* Middle of a transaction I2C write request. Override
+			 * the command code that was set to cmd_type.
+			 */
+			request.cmd_code = AUX_CMD_I2C_WRITE_MOT;
+		}
+
+		status = aux_request(dev, &request);
+		if (status)
+			return status;
+	}
+
+	return 0;
+}
+
+/*
+ * Issue a read request over the AUX channel that will read from
+ * the RX device's DisplayPort Configuration data (DPCD) address space. The read
+ * message will be divided into multiple transactions which read a maximum of 16
+ * bytes each.
+ */
+static int aux_read(struct udevice *dev, u32 dpcd_address, u32 bytes_to_read,
+		    void *read_data)
+{
+	int status;
+
+	if (!is_connected(dev))
+		return -ENODEV;
+
+	/* Send AUX read transaction. */
+	status = aux_common(dev, AUX_CMD_READ, dpcd_address,
+			    bytes_to_read, (u8 *)read_data);
+
+	return status;
+}
+
+/*
+ * Issue a write request over the AUX channel that will write to
+ * the RX device's DisplayPort Configuration data (DPCD) address space. The
+ * write message will be divided into multiple transactions which write a
+ * maximum of 16 bytes each.
+ */
+static int aux_write(struct udevice *dev, u32 dpcd_address, u32 bytes_to_write,
+		     void *write_data)
+{
+	int status;
+
+	if (!is_connected(dev))
+		return -ENODEV;
+
+	/* Send AUX write transaction. */
+	status = aux_common(dev, AUX_CMD_WRITE, dpcd_address,
+			    bytes_to_write, (u8 *)write_data);
+
+	return status;
+}
+
+/* core initialization */
+
+static int initialize(struct udevice *dev)
+{
+	struct dp_tx *dp_tx = dev_get_priv(dev);
+	u32 val;
+	u32 phy_config;
+	unsigned int k;
+
+	/* place the PHY (and GTTXRESET) into reset. */
+	phy_config = get_reg(dev, REG_PHY_CONFIG);
+	set_reg(dev, REG_PHY_CONFIG, phy_config | PHY_CONFIG_GT_ALL_RESET_MASK);
+
+	/* reset the video streams and AUX logic. */
+	set_reg(dev, REG_SOFT_RESET,
+		SOFT_RESET_VIDEO_STREAM_ALL_MASK |
+		SOFT_RESET_AUX_MASK);
+
+	/* disable the DisplayPort TX core. */
+	set_reg(dev, REG_ENABLE, 0);
+
+	/* set the clock divider. */
+	val = get_reg(dev, REG_AUX_CLK_DIVIDER);
+	val &= ~AUX_CLK_DIVIDER_VAL_MASK;
+	val |= dp_tx->s_axi_clk / 1000000;
+	set_reg(dev, REG_AUX_CLK_DIVIDER, val);
+
+	/* set the DisplayPort TX core's clock speed. */
+	set_reg(dev, REG_PHY_CLOCK_SELECT, PHY_CLOCK_SELECT_DEFAULT);
+
+	/* bring the PHY (and GTTXRESET) out of reset. */
+	set_reg(dev, REG_PHY_CONFIG,
+		phy_config & ~PHY_CONFIG_GT_ALL_RESET_MASK);
+
+	/* enable the DisplayPort TX core. */
+	set_reg(dev, REG_ENABLE, 1);
+
+	/* Unmask Hot-Plug-Detect (HPD) interrupts. */
+	set_reg(dev, REG_INTERRUPT_MASK,
+		~INTERRUPT_MASK_HPD_PULSE_DETECTED_MASK &
+		~INTERRUPT_MASK_HPD_EVENT_MASK &
+		~INTERRUPT_MASK_HPD_IRQ_MASK);
+
+	for (k = 0; k < 4; k++) {
+		/* Disable pre-cursor levels. */
+		set_reg(dev, REG_PHY_PRECURSOR_LANE_0 + 4 * k, 0);
+
+		/* Write default voltage swing levels to the TX registers. */
+		set_reg(dev, REG_PHY_VOLTAGE_DIFF_LANE_0 + 4 * k, 0);
+
+		/* Write default pre-emphasis levels to the TX registers. */
+		set_reg(dev, REG_PHY_POSTCURSOR_LANE_0 + 4 * k, 0);
+	}
+
+	return 0;
+}
+
+bool is_link_rate_valid(struct udevice *dev, u8 link_rate)
+{
+	struct dp_tx *dp_tx = dev_get_priv(dev);
+	bool valid = true;
+
+	if ((link_rate != LINK_BW_SET_162GBPS) &&
+	    (link_rate != LINK_BW_SET_270GBPS) &&
+	    (link_rate != LINK_BW_SET_540GBPS))
+		valid = false;
+	else if (link_rate > dp_tx->link_config.max_link_rate)
+		valid = false;
+
+	return valid;
+}
+
+bool is_lane_count_valid(struct udevice *dev, u8 lane_count)
+{
+	struct dp_tx *dp_tx = dev_get_priv(dev);
+	bool valid = true;
+
+	if ((lane_count != LANE_COUNT_SET_1) &&
+	    (lane_count != LANE_COUNT_SET_2) &&
+	    (lane_count != LANE_COUNT_SET_4))
+		valid = false;
+	else if (lane_count > dp_tx->link_config.max_lane_count)
+		valid = false;
+
+	return valid;
+}
+
+static int get_rx_capabilities(struct udevice *dev)
+{
+	struct dp_tx *dp_tx = dev_get_priv(dev);
+	int status;
+	u8 rx_max_link_rate;
+	u8 rx_max_lane_count;
+
+	if (!is_connected(dev))
+		return -ENODEV;
+
+	status = aux_read(dev, DPCD_RECEIVER_CAP_FIELD_START, 16,
+			  dp_tx->dpcd_rx_caps);
+	if (status)
+		return -EIO;
+
+	rx_max_link_rate = dp_tx->dpcd_rx_caps[DPCD_MAX_LINK_RATE];
+	rx_max_lane_count = dp_tx->dpcd_rx_caps[DPCD_MAX_LANE_COUNT] &
+			    DPCD_MAX_LANE_COUNT_MASK;
+
+	dp_tx->link_config.max_link_rate =
+		(rx_max_link_rate > dp_tx->max_link_rate) ?
+		dp_tx->max_link_rate : rx_max_link_rate;
+	if (!is_link_rate_valid(dev, rx_max_link_rate))
+		return -EINVAL;
+
+	dp_tx->link_config.max_lane_count =
+		(rx_max_lane_count > dp_tx->max_lane_count) ?
+		dp_tx->max_lane_count : rx_max_lane_count;
+	if (!is_lane_count_valid(dev, rx_max_lane_count))
+		return -EINVAL;
+
+	dp_tx->link_config.support_enhanced_framing_mode =
+		dp_tx->dpcd_rx_caps[DPCD_MAX_LANE_COUNT] &
+		DPCD_ENHANCED_FRAME_SUPPORT_MASK;
+	dp_tx->link_config.support_downspread_control =
+		dp_tx->dpcd_rx_caps[DPCD_MAX_DOWNSPREAD] &
+		DPCD_MAX_DOWNSPREAD_MASK;
+
+	return 0;
+}
+
+static void enable_main_link(struct udevice *dev)
+{
+	/* reset the scrambler. */
+	set_reg(dev, REG_FORCE_SCRAMBLER_RESET, 0x1);
+
+	/* enable the main stream. */
+	set_reg(dev, REG_ENABLE_MAIN_STREAM, 0x1);
+}
+
+static void disable_main_link(struct udevice *dev)
+{
+	/* reset the scrambler. */
+	set_reg(dev, REG_FORCE_SCRAMBLER_RESET, 0x1);
+
+	/* Disable the main stream. */
+	set_reg(dev, REG_ENABLE_MAIN_STREAM, 0x0);
+}
+
+static void reset_dp_phy(struct udevice *dev, u32 reset)
+{
+	struct dp_tx *dp_tx = dev_get_priv(dev);
+	u32 val;
+
+	set_reg(dev, REG_ENABLE, 0x0);
+
+	val = get_reg(dev, REG_PHY_CONFIG);
+
+	/* Apply reset. */
+	set_reg(dev, REG_PHY_CONFIG, val | reset);
+
+	/* Remove reset. */
+	set_reg(dev, REG_PHY_CONFIG, val);
+
+	/* Wait for the PHY to be ready. */
+	wait_phy_ready(dev, PHY_STATUS_LANES_READY_MASK(dp_tx->max_lane_count));
+
+	set_reg(dev, REG_ENABLE, 0x1);
+}
+
+/*
+ * enable or disable the enhanced framing symbol sequence for
+ * both the DisplayPort TX core and the RX device.
+ */
+static int set_enhanced_frame_mode(struct udevice *dev, u8 enable)
+{
+	struct dp_tx *dp_tx = dev_get_priv(dev);
+	int status;
+	u8 val;
+
+	if (!is_connected(dev))
+		return -ENODEV;
+
+	if (dp_tx->link_config.support_enhanced_framing_mode)
+		dp_tx->link_config.enhanced_framing_mode = enable;
+	else
+		dp_tx->link_config.enhanced_framing_mode = false;
+
+	/* Write enhanced frame mode enable to the DisplayPort TX core. */
+	set_reg(dev, REG_ENHANCED_FRAME_EN,
+		dp_tx->link_config.enhanced_framing_mode);
+
+	/* Write enhanced frame mode enable to the RX device. */
+	status = aux_read(dev, DPCD_LANE_COUNT_SET, 0x1, &val);
+	if (status)
+		return -EIO;
+
+	if (dp_tx->link_config.enhanced_framing_mode)
+		val |= DPCD_ENHANCED_FRAME_EN_MASK;
+	else
+		val &= ~DPCD_ENHANCED_FRAME_EN_MASK;
+
+	status = aux_write(dev, DPCD_LANE_COUNT_SET, 0x1, &val);
+	if (status)
+		return -EIO;
+
+	return 0;
+}
+
+/*
+ * Set the number of lanes to be used by the main link for both
+ * the DisplayPort TX core and the RX device.
+ */
+static int set_lane_count(struct udevice *dev, u8 lane_count)
+{
+	struct dp_tx *dp_tx = dev_get_priv(dev);
+	int status;
+	u8 val;
+
+	if (!is_connected(dev))
+		return -ENODEV;
+
+	printf("       set lane count to %u\n", lane_count);
+
+	dp_tx->link_config.lane_count = lane_count;
+
+	/* Write the new lane count to the DisplayPort TX core. */
+	set_reg(dev, REG_LANE_COUNT_SET, dp_tx->link_config.lane_count);
+
+	/* Write the new lane count to the RX device. */
+	status = aux_read(dev, DPCD_LANE_COUNT_SET, 0x1, &val);
+	if (status)
+		return -EIO;
+	val &= ~DPCD_LANE_COUNT_SET_MASK;
+	val |= dp_tx->link_config.lane_count;
+
+	status = aux_write(dev, DPCD_LANE_COUNT_SET, 0x1, &val);
+	if (status)
+		return -EIO;
+
+	return 0;
+}
+
+/*
+ * Set the clock frequency for the DisplayPort PHY corresponding
+ * to a desired data rate.
+ */
+static int set_clk_speed(struct udevice *dev, u32 speed)
+{
+	struct dp_tx *dp_tx = dev_get_priv(dev);
+	int status;
+	u32 val;
+
+	/* Disable the DisplayPort TX core first. */
+	val = get_reg(dev, REG_ENABLE);
+	set_reg(dev, REG_ENABLE, 0x0);
+
+	/* Change speed of the feedback clock. */
+	set_reg(dev, REG_PHY_CLOCK_SELECT, speed);
+
+	/* Re-enable the DisplayPort TX core if it was previously enabled. */
+	if (val)
+		set_reg(dev, REG_ENABLE, 0x1);
+
+	/* Wait until the PHY is ready. */
+	status = wait_phy_ready(dev, PHY_STATUS_LANES_READY_MASK(dp_tx->max_lane_count));
+	if (status)
+		return -EIO;
+
+	return 0;
+}
+
+/*
+ * Set the data rate to be used by the main link for both the
+ * DisplayPort TX core and the RX device.
+ */
+static int set_link_rate(struct udevice *dev, u8 link_rate)
+{
+	struct dp_tx *dp_tx = dev_get_priv(dev);
+	int status;
+
+	/* Write a corresponding clock frequency to the DisplayPort TX core. */
+	switch (link_rate) {
+	case LINK_BW_SET_162GBPS:
+		printf("       set link rate to 1.62 Gb/s\n");
+		status = set_clk_speed(dev, PHY_CLOCK_SELECT_162GBPS);
+		break;
+	case LINK_BW_SET_270GBPS:
+		printf("       set link rate to 2.70 Gb/s\n");
+		status = set_clk_speed(dev, PHY_CLOCK_SELECT_270GBPS);
+		break;
+	case LINK_BW_SET_540GBPS:
+		printf("       set link rate to 5.40 Gb/s\n");
+		status = set_clk_speed(dev, PHY_CLOCK_SELECT_540GBPS);
+		break;
+	default:
+		return -EINVAL;
+	}
+	if (status)
+		return -EIO;
+
+	dp_tx->link_config.link_rate = link_rate;
+
+	/* Write new link rate to the DisplayPort TX core. */
+	set_reg(dev, REG_LINK_BW_SET, dp_tx->link_config.link_rate);
+
+	/* Write new link rate to the RX device. */
+	status = aux_write(dev, DPCD_LINK_BW_SET, 1,
+			   &dp_tx->link_config.link_rate);
+	if (status)
+		return -EIO;
+
+	return 0;
+}
+
+/* link training */
+
+/*
+ * Determine what the RX device's required training delay is for
+ * link training.
+ */
+static int get_training_delay(struct udevice *dev, int training_state)
+{
+	struct dp_tx *dp_tx = dev_get_priv(dev);
+	u16 delay;
+
+	switch (dp_tx->dpcd_rx_caps[DPCD_TRAIN_AUX_RD_INTERVAL]) {
+	case DPCD_TRAIN_AUX_RD_INT_100_400US:
+		if (training_state == TS_CLOCK_RECOVERY)
+			/* delay for the clock recovery phase. */
+			delay = 100;
+		else
+			/* delay for the channel equalization phase. */
+			delay = 400;
+		break;
+	case DPCD_TRAIN_AUX_RD_INT_4MS:
+		delay = 4000;
+		break;
+	case DPCD_TRAIN_AUX_RD_INT_8MS:
+		delay = 8000;
+		break;
+	case DPCD_TRAIN_AUX_RD_INT_12MS:
+		delay = 12000;
+		break;
+	case DPCD_TRAIN_AUX_RD_INT_16MS:
+		delay = 16000;
+		break;
+	default:
+		/* Default to 20 ms. */
+		delay = 20000;
+		break;
+	}
+
+	return delay;
+}
+
+/*
+ * Set current voltage swing and pre-emphasis level settings from
+ * the link_config structure to hardware.
+ */
+static void set_vswing_preemp(struct udevice *dev, u8 *aux_data)
+{
+	struct dp_tx *dp_tx = dev_get_priv(dev);
+	u8 data;
+	u8 vs_level_rx = dp_tx->link_config.vs_level;
+	u8 pe_level_rx = dp_tx->link_config.pe_level;
+
+	/* Set up the data buffer for writing to the RX device. */
+	data = (pe_level_rx << DPCD_TRAINING_LANEX_SET_PE_SHIFT) | vs_level_rx;
+	/* The maximum voltage swing has been reached. */
+	if (vs_level_rx == MAXIMUM_VS_LEVEL)
+		data |= DPCD_TRAINING_LANEX_SET_MAX_VS_MASK;
+
+	/* The maximum pre-emphasis level has been reached. */
+	if (pe_level_rx == MAXIMUM_PE_LEVEL)
+		data |= DPCD_TRAINING_LANEX_SET_MAX_PE_MASK;
+	memset(aux_data, data, 4);
+}
+
+/*
+ * Set new voltage swing and pre-emphasis levels using the
+ * adjustment requests obtained from the RX device.
+ */
+static int adj_vswing_preemp(struct udevice *dev)
+{
+	struct dp_tx *dp_tx = dev_get_priv(dev);
+	int status;
+	u8 index;
+	u8 vs_level_adj_req[4];
+	u8 pe_level_adj_req[4];
+	u8 aux_data[4];
+	u8 *ajd_reqs = &dp_tx->lane_status_ajd_reqs[4];
+
+	/* Analyze the adjustment requests for changes in voltage swing and
+	 * pre-emphasis levels.
+	 */
+	vs_level_adj_req[0] = ajd_reqs[0] & DPCD_ADJ_REQ_LANE_0_2_VS_MASK;
+	vs_level_adj_req[1] = (ajd_reqs[0] & DPCD_ADJ_REQ_LANE_1_3_VS_MASK) >>
+			      DPCD_ADJ_REQ_LANE_1_3_VS_SHIFT;
+	vs_level_adj_req[2] = ajd_reqs[1] & DPCD_ADJ_REQ_LANE_0_2_VS_MASK;
+	vs_level_adj_req[3] = (ajd_reqs[1] & DPCD_ADJ_REQ_LANE_1_3_VS_MASK) >>
+			      DPCD_ADJ_REQ_LANE_1_3_VS_SHIFT;
+	pe_level_adj_req[0] = (ajd_reqs[0] & DPCD_ADJ_REQ_LANE_0_2_PE_MASK) >>
+			      DPCD_ADJ_REQ_LANE_0_2_PE_SHIFT;
+	pe_level_adj_req[1] = (ajd_reqs[0] & DPCD_ADJ_REQ_LANE_1_3_PE_MASK) >>
+			      DPCD_ADJ_REQ_LANE_1_3_PE_SHIFT;
+	pe_level_adj_req[2] = (ajd_reqs[1] & DPCD_ADJ_REQ_LANE_0_2_PE_MASK) >>
+			      DPCD_ADJ_REQ_LANE_0_2_PE_SHIFT;
+	pe_level_adj_req[3] = (ajd_reqs[1] & DPCD_ADJ_REQ_LANE_1_3_PE_MASK) >>
+			      DPCD_ADJ_REQ_LANE_1_3_PE_SHIFT;
+
+	/* Change the drive settings to match the adjustment requests. Use the
+	 * greatest level requested.
+	 */
+	dp_tx->link_config.vs_level = 0;
+	dp_tx->link_config.pe_level = 0;
+	for (index = 0; index < dp_tx->link_config.lane_count; index++) {
+		if (vs_level_adj_req[index] > dp_tx->link_config.vs_level)
+			dp_tx->link_config.vs_level = vs_level_adj_req[index];
+		if (pe_level_adj_req[index] > dp_tx->link_config.pe_level)
+			dp_tx->link_config.pe_level = pe_level_adj_req[index];
+	}
+
+	/* Verify that the voltage swing and pre-emphasis combination is
+	 * allowed. Some combinations will result in a differential peak-to-peak
+	 * voltage that is outside the permissible range. See the VESA
+	 * DisplayPort v1.2 Specification, section 3.1.5.2.
+	 * The valid combinations are:
+	 *      PE=0    PE=1    PE=2    PE=3
+	 * VS=0 valid   valid   valid   valid
+	 * VS=1 valid   valid   valid
+	 * VS=2 valid   valid
+	 * VS=3 valid
+	 *
+	 * NOTE:
+	 * Xilinix dp_v3_1 driver seems to have an off by one error when
+	 * limiting pe_level which is fixed here.
+	 */
+	if (dp_tx->link_config.pe_level > (3 - dp_tx->link_config.vs_level))
+		dp_tx->link_config.pe_level = 3 - dp_tx->link_config.vs_level;
+
+	/* Make the adjustments to both the DisplayPort TX core and the RX
+	 * device.
+	 */
+	set_vswing_preemp(dev, aux_data);
+	/* Write the voltage swing and pre-emphasis levels for each lane to the
+	 * RX device.
+	 */
+	status = aux_write(dev, DPCD_TRAINING_LANE0_SET, 4, aux_data);
+	if (status)
+		return -EIO;
+
+	return 0;
+}
+
+/*
+ * Do a burst AUX read from the RX device over the AUX
+ * channel. The contents of the status registers will be stored for later use by
+ * check_clock_recovery, check_channel_equalization, and
+ * adj_vswing_preemp.
+ */
+static int get_lane_status_adj_reqs(struct udevice *dev)
+{
+	struct dp_tx *dp_tx = dev_get_priv(dev);
+	int status;
+
+	/* Read and store 4 bytes of lane status and 2 bytes of adjustment
+	 * requests.
+	 */
+	status = aux_read(dev, DPCD_STATUS_LANE_0_1, 6,
+			  dp_tx->lane_status_ajd_reqs);
+	if (status)
+		return -EIO;
+
+	return 0;
+}
+
+/*
+ * Check if the RX device's DisplayPort Configuration data (DPCD)
+ * indicates that the clock recovery sequence during link training was
+ * successful - the RX device's link clock and data recovery unit has realized
+ * and maintained the frequency lock for all lanes currently in use.
+ */
+static int check_clock_recovery(struct udevice *dev, u8 lane_count)
+{
+	struct dp_tx *dp_tx = dev_get_priv(dev);
+	u8 *lane_status = dp_tx->lane_status_ajd_reqs;
+
+	/* Check that all LANEx_CR_DONE bits are set. */
+	switch (lane_count) {
+	case LANE_COUNT_SET_4:
+		if (!(lane_status[1] & DPCD_STATUS_LANE_3_CR_DONE_MASK))
+			goto out_fail;
+		if (!(lane_status[1] & DPCD_STATUS_LANE_2_CR_DONE_MASK))
+			goto out_fail;
+	/* Drop through and check lane 1. */
+	case LANE_COUNT_SET_2:
+		if (!(lane_status[0] & DPCD_STATUS_LANE_1_CR_DONE_MASK))
+			goto out_fail;
+	/* Drop through and check lane 0. */
+	case LANE_COUNT_SET_1:
+		if (!(lane_status[0] & DPCD_STATUS_LANE_0_CR_DONE_MASK))
+			goto out_fail;
+	default:
+		/* All (lane_count) lanes have achieved clock recovery. */
+		break;
+	}
+
+	return 0;
+
+out_fail:
+	return -EIO;
+}
+
+/*
+ * Check if the RX device's DisplayPort Configuration data (DPCD)
+ * indicates that the channel equalization sequence during link training was
+ * successful - the RX device has achieved channel equalization, symbol lock,
+ * and interlane alignment for all lanes currently in use.
+ */
+static int check_channel_equalization(struct udevice *dev, u8 lane_count)
+{
+	struct dp_tx *dp_tx = dev_get_priv(dev);
+	u8 *lane_status = dp_tx->lane_status_ajd_reqs;
+
+	/* Check that all LANEx_CHANNEL_EQ_DONE bits are set. */
+	switch (lane_count) {
+	case LANE_COUNT_SET_4:
+		if (!(lane_status[1] & DPCD_STATUS_LANE_3_CE_DONE_MASK))
+			goto out_fail;
+		if (!(lane_status[1] & DPCD_STATUS_LANE_2_CE_DONE_MASK))
+			goto out_fail;
+	/* Drop through and check lane 1. */
+	case LANE_COUNT_SET_2:
+		if (!(lane_status[0] & DPCD_STATUS_LANE_1_CE_DONE_MASK))
+			goto out_fail;
+	/* Drop through and check lane 0. */
+	case LANE_COUNT_SET_1:
+		if (!(lane_status[0] & DPCD_STATUS_LANE_0_CE_DONE_MASK))
+			goto out_fail;
+	default:
+		/* All (lane_count) lanes have achieved channel equalization. */
+		break;
+	}
+
+	/* Check that all LANEx_SYMBOL_LOCKED bits are set. */
+	switch (lane_count) {
+	case LANE_COUNT_SET_4:
+		if (!(lane_status[1] & DPCD_STATUS_LANE_3_SL_DONE_MASK))
+			goto out_fail;
+		if (!(lane_status[1] & DPCD_STATUS_LANE_2_SL_DONE_MASK))
+			goto out_fail;
+	/* Drop through and check lane 1. */
+	case LANE_COUNT_SET_2:
+		if (!(lane_status[0] & DPCD_STATUS_LANE_1_SL_DONE_MASK))
+			goto out_fail;
+	/* Drop through and check lane 0. */
+	case LANE_COUNT_SET_1:
+		if (!(lane_status[0] & DPCD_STATUS_LANE_0_SL_DONE_MASK))
+			goto out_fail;
+	default:
+		/* All (lane_count) lanes have achieved symbol lock. */
+		break;
+	}
+
+	/* Check that interlane alignment is done. */
+	if (!(lane_status[2] & DPCD_LANE_ALIGN_STATUS_UPDATED_IA_DONE_MASK))
+		goto out_fail;
+
+	return 0;
+
+out_fail:
+	return -EIO;
+}
+
+/*
+ * Set the training pattern to be used during link training for
+ * both the DisplayPort TX core and the RX device.
+ */
+static int set_training_pattern(struct udevice *dev, u32 pattern)
+{
+	struct dp_tx *dp_tx = dev_get_priv(dev);
+	int status;
+	u8 aux_data[5];
+
+	/* Write to the DisplayPort TX core. */
+	set_reg(dev, REG_TRAINING_PATTERN_SET, pattern);
+
+	aux_data[0] = pattern;
+
+	/* Write scrambler disable to the DisplayPort TX core. */
+	switch (pattern) {
+	case TRAINING_PATTERN_SET_OFF:
+		set_reg(dev, REG_SCRAMBLING_DISABLE, 0);
+		dp_tx->link_config.scrambler_en = 1;
+		break;
+	case TRAINING_PATTERN_SET_TP1:
+	case TRAINING_PATTERN_SET_TP2:
+	case TRAINING_PATTERN_SET_TP3:
+		aux_data[0] |= DPCD_TP_SET_SCRAMB_DIS_MASK;
+		set_reg(dev, REG_SCRAMBLING_DISABLE, 1);
+		dp_tx->link_config.scrambler_en = 0;
+		break;
+	default:
+		break;
+	}
+
+	/* Make the adjustments to both the DisplayPort TX core and the RX
+	 * device.
+	 */
+	set_vswing_preemp(dev, &aux_data[1]);
+	/* Write the voltage swing and pre-emphasis levels for each lane to the
+	 * RX device.
+	 */
+	if  (pattern == TRAINING_PATTERN_SET_OFF)
+		status = aux_write(dev, DPCD_TP_SET, 1, aux_data);
+	else
+		status = aux_write(dev, DPCD_TP_SET, 5, aux_data);
+	if (status)
+		return -EIO;
+
+	return 0;
+}
+
+/*
+ * Run the clock recovery sequence as part of link training. The
+ * sequence is as follows:
+ *	0) Start signaling at the minimum voltage swing, pre-emphasis, and post-
+ *	   cursor levels.
+ *	1) Transmit training pattern 1 over the main link with symbol scrambling
+ *	   disabled.
+ *	2) The clock recovery loop. If clock recovery is unsuccessful after
+ *	   MaxIterations loop iterations, return.
+ *	2a) Wait for at least the period of time specified in the RX device's
+ *	    DisplayPort Configuration data (DPCD) register,
+ *	    TRAINING_AUX_RD_INTERVAL.
+ *	2b) Check if all lanes have achieved clock recovery lock. If so, return.
+ *	2c) Check if the same voltage swing level has been used 5 consecutive
+ *	    times or if the maximum level has been reached. If so, return.
+ *	2d) Adjust the voltage swing, pre-emphasis, and post-cursor levels as
+ *	    requested by the RX device.
+ *	2e) Loop back to 2a.
+ * For a more detailed description of the clock recovery sequence, see section
+ * 3.5.1.2.1 of the DisplayPort 1.2a specification document.
+ */
+static unsigned int training_state_clock_recovery(struct udevice *dev)
+{
+	struct dp_tx *dp_tx = dev_get_priv(dev);
+	int status;
+	u32 delay_us;
+	u8 prev_vs_level = 0;
+	u8 same_vs_level_count = 0;
+
+	/* Obtain the required delay for clock recovery as specified by the
+	 * RX device.
+	 */
+	delay_us = get_training_delay(dev, TS_CLOCK_RECOVERY);
+
+	/* Start CRLock. */
+
+	/* Transmit training pattern 1. */
+	/* Disable the scrambler. */
+	/* Start from minimal voltage swing and pre-emphasis levels. */
+	dp_tx->link_config.vs_level = 0;
+	dp_tx->link_config.pe_level = 0;
+	status = set_training_pattern(dev, TRAINING_PATTERN_SET_TP1);
+	if (status)
+		return TS_FAILURE;
+
+	while (1) {
+		/* Wait delay specified in TRAINING_AUX_RD_INTERVAL. */
+		udelay(delay_us);
+
+		/* Get lane and adjustment requests. */
+		status = get_lane_status_adj_reqs(dev);
+		if (status)
+			return TS_FAILURE;
+
+		/* Check if all lanes have realized and maintained the frequency
+		 * lock and get adjustment requests.
+		 */
+		status = check_clock_recovery(dev,
+					      dp_tx->link_config.lane_count);
+		if (!status)
+			return TS_CHANNEL_EQUALIZATION;
+
+		/* Check if the same voltage swing for each lane has been used 5
+		 * consecutive times.
+		 */
+		if (prev_vs_level == dp_tx->link_config.vs_level) {
+			same_vs_level_count++;
+		} else {
+			same_vs_level_count = 0;
+			prev_vs_level = dp_tx->link_config.vs_level;
+		}
+		if (same_vs_level_count >= 5)
+			break;
+
+		/* Only try maximum voltage swing once. */
+		if (dp_tx->link_config.vs_level == MAXIMUM_VS_LEVEL)
+			break;
+
+		/* Adjust the drive settings as requested by the RX device. */
+		status = adj_vswing_preemp(dev);
+		if (status)
+			/* The AUX write failed. */
+			return TS_FAILURE;
+	}
+
+	return TS_ADJUST_LINK_RATE;
+}
+
+/*
+ * Run the channel equalization sequence as part of link
+ * training. The sequence is as follows:
+ *	0) Start signaling with the same drive settings used at the end of the
+ *	   clock recovery sequence.
+ *	1) Transmit training pattern 2 (or 3) over the main link with symbol
+ *	   scrambling disabled.
+ *	2) The channel equalization loop. If channel equalization is
+ *	   unsuccessful after 5 loop iterations, return.
+ *	2a) Wait for at least the period of time specified in the RX device's
+ *	    DisplayPort Configuration data (DPCD) register,
+ *	    TRAINING_AUX_RD_INTERVAL.
+ *	2b) Check if all lanes have achieved channel equalization, symbol lock,
+ *	    and interlane alignment. If so, return.
+ *	2c) Check if the same voltage swing level has been used 5 consecutive
+ *	    times or if the maximum level has been reached. If so, return.
+ *	2d) Adjust the voltage swing, pre-emphasis, and post-cursor levels as
+ *	    requested by the RX device.
+ *	2e) Loop back to 2a.
+ * For a more detailed description of the channel equalization sequence, see
+ * section 3.5.1.2.2 of the DisplayPort 1.2a specification document.
+ */
+static int training_state_channel_equalization(struct udevice *dev)
+{
+	struct dp_tx *dp_tx = dev_get_priv(dev);
+	int status;
+	u32 delay_us;
+	u32 iteration_count = 0;
+
+	/* Obtain the required delay for channel equalization as specified by
+	 * the RX device.
+	 */
+	delay_us = get_training_delay(dev, TS_CHANNEL_EQUALIZATION);
+
+	/* Start channel equalization. */
+
+	/* Write the current drive settings. */
+	/* Transmit training pattern 2/3. */
+	if (dp_tx->dpcd_rx_caps[DPCD_MAX_LANE_COUNT] & DPCD_TPS3_SUPPORT_MASK)
+		status = set_training_pattern(dev, TRAINING_PATTERN_SET_TP3);
+	else
+		status = set_training_pattern(dev, TRAINING_PATTERN_SET_TP2);
+
+	if (status)
+		return TS_FAILURE;
+
+	while (iteration_count < 5) {
+		/* Wait delay specified in TRAINING_AUX_RD_INTERVAL. */
+		udelay(delay_us);
+
+		/* Get lane and adjustment requests. */
+		status = get_lane_status_adj_reqs(dev);
+		if (status)
+			/* The AUX read failed. */
+			return TS_FAILURE;
+
+		/* Check that all lanes still have their clocks locked. */
+		status = check_clock_recovery(dev,
+					      dp_tx->link_config.lane_count);
+		if (status)
+			break;
+
+		/* Check if all lanes have accomplished channel equalization,
+		 * symbol lock, and interlane alignment.
+		 */
+		status =
+		    check_channel_equalization(dev,
+					       dp_tx->link_config.lane_count);
+		if (!status)
+			return TS_SUCCESS;
+
+		/* Adjust the drive settings as requested by the RX device. */
+		status = adj_vswing_preemp(dev);
+		if (status)
+			/* The AUX write failed. */
+			return TS_FAILURE;
+
+		iteration_count++;
+	}
+
+	/* Tried 5 times with no success. Try a reduced bitrate first, then
+	 * reduce the number of lanes.
+	 */
+	return TS_ADJUST_LINK_RATE;
+}
+
+/*
+ * This function is reached if either the clock recovery or the channel
+ * equalization process failed during training. As a result, the data rate will
+ * be downshifted, and training will be re-attempted (starting with clock
+ * recovery) at the reduced data rate. If the data rate is already at 1.62 Gbps,
+ * a downshift in lane count will be attempted.
+ */
+static int training_state_adjust_link_rate(struct udevice *dev)
+{
+	struct dp_tx *dp_tx = dev_get_priv(dev);
+	int status;
+
+	switch (dp_tx->link_config.link_rate) {
+	case LINK_BW_SET_540GBPS:
+		status = set_link_rate(dev, LINK_BW_SET_270GBPS);
+		if (status) {
+			status = TS_FAILURE;
+			break;
+		}
+		status = TS_CLOCK_RECOVERY;
+		break;
+	case LINK_BW_SET_270GBPS:
+		status = set_link_rate(dev, LINK_BW_SET_162GBPS);
+		if (status) {
+			status = TS_FAILURE;
+			break;
+		}
+		status = TS_CLOCK_RECOVERY;
+		break;
+	default:
+		/* Already at the lowest link rate. Try reducing the lane
+		 * count next.
+		 */
+		status = TS_ADJUST_LANE_COUNT;
+		break;
+	}
+
+	return status;
+}
+
+/*
+ * This function is reached if either the clock recovery or the channel
+ * equalization process failed during training, and a minimal data rate of 1.62
+ * Gbps was being used. As a result, the number of lanes in use will be reduced,
+ * and training will be re-attempted (starting with clock recovery) at this
+ * lower lane count.
+ */
+static int trainig_state_adjust_lane_count(struct udevice *dev)
+{
+	struct dp_tx *dp_tx = dev_get_priv(dev);
+	int status;
+
+	switch (dp_tx->link_config.lane_count) {
+	case LANE_COUNT_SET_4:
+		status = set_lane_count(dev, LANE_COUNT_SET_2);
+		if (status) {
+			status = TS_FAILURE;
+			break;
+		}
+
+		status = set_link_rate(dev, dp_tx->link_config.max_link_rate);
+		if (status) {
+			status = TS_FAILURE;
+			break;
+		}
+		status = TS_CLOCK_RECOVERY;
+		break;
+	case LANE_COUNT_SET_2:
+		status = set_lane_count(dev, LANE_COUNT_SET_1);
+		if (status) {
+			status = TS_FAILURE;
+			break;
+		}
+
+		status = set_link_rate(dev, dp_tx->link_config.max_link_rate);
+		if (status) {
+			status = TS_FAILURE;
+			break;
+		}
+		status = TS_CLOCK_RECOVERY;
+		break;
+	default:
+		/* Already at the lowest lane count. Training has failed at the
+		 * lowest lane count and link rate.
+		 */
+		status = TS_FAILURE;
+		break;
+	}
+
+	return status;
+}
+
+/*
+ * Check if the receiver's DisplayPort Configuration data (DPCD)
+ * indicates the receiver has achieved and maintained clock recovery, channel
+ * equalization, symbol lock, and interlane alignment for all lanes currently in
+ * use.
+ */
+static int check_link_status(struct udevice *dev, u8 lane_count)
+{
+	u8 retry_count = 0;
+
+	if (!is_connected(dev))
+		return -ENODEV;
+
+	/* Retrieve AUX info. */
+	do {
+		int status;
+
+		/* Get lane and adjustment requests. */
+		status = get_lane_status_adj_reqs(dev);
+		if (status)
+			return -EIO;
+
+		/* Check if the link needs training. */
+		if ((check_clock_recovery(dev, lane_count) == 0) &&
+		    (check_channel_equalization(dev, lane_count) == 0))
+			return 0;
+
+		retry_count++;
+	} while (retry_count < 5); /* Retry up to 5 times. */
+
+	return -EIO;
+}
+
+/*
+ * Run the link training process. It is implemented as a state
+ * machine, with each state returning the next state. First, the clock recovery
+ * sequence will be run; if successful, the channel equalization sequence will
+ * run. If either the clock recovery or channel equalization sequence failed,
+ * the link rate or the number of lanes used will be reduced and training will
+ * be re-attempted. If training fails@the minimal data rate, 1.62 Gbps with
+ * a single lane, training will no longer re-attempt and fail.
+ *
+ * ### Here be dragons ###
+ * There are undocumented timeout constraints in the link training process.
+ * In DP v1.2a spec, Chapter 3.5.1.2.2 a 10ms limit for the complete training
+ * process is mentioned. Which individual timeouts are derived and implemented
+ * by sink manufacturers is unknown. So each step should be as short as possible
+ * and link training should start as soon as possible after HPD.
+ */
+static int run_training(struct udevice *dev)
+{
+	struct dp_tx *dp_tx = dev_get_priv(dev);
+	int status;
+	int training_state = TS_CLOCK_RECOVERY;
+
+	while (1) {
+		switch (training_state) {
+		case TS_CLOCK_RECOVERY:
+			training_state =
+				training_state_clock_recovery(dev);
+			break;
+		case TS_CHANNEL_EQUALIZATION:
+			training_state =
+				training_state_channel_equalization(dev);
+			break;
+		case TS_ADJUST_LINK_RATE:
+			training_state =
+				training_state_adjust_link_rate(dev);
+			break;
+		case TS_ADJUST_LANE_COUNT:
+			training_state =
+				trainig_state_adjust_lane_count(dev);
+			break;
+		default:
+			break;
+		}
+
+		if (training_state == TS_SUCCESS)
+			break;
+		else if (training_state == TS_FAILURE)
+			return -EIO;
+
+		if ((training_state == TS_ADJUST_LINK_RATE) ||
+		    (training_state == TS_ADJUST_LANE_COUNT)) {
+			if (!dp_tx->train_adaptive)
+				return -EIO;
+
+			status = set_training_pattern(dev,
+						      TRAINING_PATTERN_SET_OFF);
+			if (status)
+				return -EIO;
+		}
+	}
+
+	/* Final status check. */
+	status = check_link_status(dev, dp_tx->link_config.lane_count);
+	if (status)
+		return -EIO;
+
+	return 0;
+}
+
+/* link policy maker */
+
+/**
+ * Determine the common capabilities between the DisplayPort TX
+ * core and the RX device.
+ */
+static int cfg_main_link_max(struct udevice *dev)
+{
+	struct dp_tx *dp_tx = dev_get_priv(dev);
+	int status;
+
+	if (!is_connected(dev))
+		return -ENODEV;
+
+	/* Configure the main link to the maximum common link rate between the
+	 * DisplayPort TX core and the RX device.
+	 */
+	status = set_link_rate(dev, dp_tx->link_config.max_link_rate);
+	if (status)
+		return status;
+
+	/* Configure the main link to the maximum common lane count between the
+	 * DisplayPort TX core and the RX device.
+	 */
+	status = set_lane_count(dev, dp_tx->link_config.max_lane_count);
+	if (status)
+		return status;
+
+	return 0;
+}
+
+/*
+ * Check if the link needs training and runs the training
+ * sequence if training is required.
+ */
+static int establish_link(struct udevice *dev)
+{
+	struct dp_tx *dp_tx = dev_get_priv(dev);
+	int status;
+	int status2;
+
+	reset_dp_phy(dev, PHY_CONFIG_PHY_RESET_MASK);
+
+	/* Disable main link during training. */
+	disable_main_link(dev);
+
+	/* Wait for the PHY to be ready. */
+	status = wait_phy_ready(dev, PHY_STATUS_LANES_READY_MASK(dp_tx->max_lane_count));
+	if (status)
+		return -EIO;
+
+	/* Train main link. */
+	status = run_training(dev);
+
+	/* Turn off the training pattern and enable scrambler. */
+	status2 = set_training_pattern(dev, TRAINING_PATTERN_SET_OFF);
+	if (status || status2)
+		return -EIO;
+
+	return 0;
+}
+
+/*
+ * Stream policy maker
+ */
+
+/*
+ * Calculate the following Main Stream Attributes (MSA):
+ *	- Transfer unit size
+ *	- User pixel width
+ *	- Horizontal total clock
+ *	- Vertical total clock
+ *	- misc_0
+ *	- misc_1
+ *	- Data per lane
+ *	- Average number of bytes per transfer unit
+ *	- Number of initial wait cycles
+ * These values are derived from:
+ *	- Bits per color
+ *	- Horizontal resolution
+ *	- Vertical resolution
+ *	- Horizontal blank start
+ *	- Vertical blank start
+ *	- Pixel clock (in KHz)
+ *	- Horizontal sync polarity
+ *	- Vertical sync polarity
+ *	- Horizontal sync pulse width
+ *	- Vertical sync pulse width
+ */
+static void cfg_msa_recalculate(struct udevice *dev)
+{
+	struct dp_tx *dp_tx = dev_get_priv(dev);
+	u32 video_bw;
+	u32 link_bw;
+	u32 words_per_line;
+	u8 bits_per_pixel;
+	struct main_stream_attributes *msa_config;
+	struct link_config *link_config;
+
+	msa_config = &dp_tx->main_stream_attributes;
+	link_config = &dp_tx->link_config;
+
+	/* Set the user pixel width to handle clocks that exceed the
+	 * capabilities of the DisplayPort TX core.
+	 */
+	if (msa_config->override_user_pixel_width == 0) {
+		if ((msa_config->pixel_clock_hz > 300000000) &&
+		    (link_config->lane_count == LANE_COUNT_SET_4)) {
+			msa_config->user_pixel_width = 4;
+		} /* Xilinx driver used 75 MHz as a limit here, 150 MHZ should
+		   * be more sane
+		   */
+		else if ((msa_config->pixel_clock_hz > 150000000) &&
+			 (link_config->lane_count != LANE_COUNT_SET_1)) {
+			msa_config->user_pixel_width = 2;
+		} else {
+			msa_config->user_pixel_width = 1;
+		}
+	}
+
+	/* Compute the rest of the MSA values. */
+	msa_config->n_vid = 27 * 1000 * link_config->link_rate;
+
+	/* Miscellaneous attributes. */
+	if (msa_config->bits_per_color == 6)
+		msa_config->misc_0 = MAIN_STREAMX_MISC0_BDC_6BPC;
+	else if (msa_config->bits_per_color == 8)
+		msa_config->misc_0 = MAIN_STREAMX_MISC0_BDC_8BPC;
+	else if (msa_config->bits_per_color == 10)
+		msa_config->misc_0 = MAIN_STREAMX_MISC0_BDC_10BPC;
+	else if (msa_config->bits_per_color == 12)
+		msa_config->misc_0 = MAIN_STREAMX_MISC0_BDC_12BPC;
+	else if (msa_config->bits_per_color == 16)
+		msa_config->misc_0 = MAIN_STREAMX_MISC0_BDC_16BPC;
+
+	msa_config->misc_0 = (msa_config->misc_0 <<
+			      MAIN_STREAMX_MISC0_BDC_SHIFT) |
+			     (msa_config->y_cb_cr_colorimetry <<
+			      MAIN_STREAMX_MISC0_YCBCR_COLORIMETRY_SHIFT) |
+			     (msa_config->dynamic_range <<
+			      MAIN_STREAMX_MISC0_DYNAMIC_RANGE_SHIFT) |
+			     (msa_config->component_format <<
+			      MAIN_STREAMX_MISC0_COMPONENT_FORMAT_SHIFT) |
+			     (msa_config->synchronous_clock_mode);
+
+	msa_config->misc_1 = 0;
+
+	/* Determine the number of bits per pixel for the specified color
+	 * component format.
+	 */
+	if (msa_config->component_format ==
+	    MAIN_STREAMX_MISC0_COMPONENT_FORMAT_YCBCR422)
+		/* YCbCr422 color component format. */
+		bits_per_pixel = msa_config->bits_per_color * 2;
+	else
+		/* RGB or YCbCr 4:4:4 color component format. */
+		bits_per_pixel = msa_config->bits_per_color * 3;
+
+	/* Calculate the data per lane. */
+	words_per_line = (msa_config->h_active * bits_per_pixel);
+	if (words_per_line % 16)
+		words_per_line += 16;
+	words_per_line /= 16;
+
+	msa_config->data_per_lane = words_per_line - link_config->lane_count;
+	if (words_per_line % link_config->lane_count)
+		msa_config->data_per_lane += (words_per_line %
+					      link_config->lane_count);
+
+	/* Allocate a fixed size for single-stream transport (SST)
+	 * operation.
+	 */
+	msa_config->transfer_unit_size = 64;
+
+	/* Calculate the average number of bytes per transfer unit.
+	 * Note: Both the integer and the fractional part is stored in
+	 * avg_bytes_per_tu.
+	 */
+	video_bw = ((msa_config->pixel_clock_hz / 1000) * bits_per_pixel) / 8;
+	link_bw = (link_config->lane_count * link_config->link_rate * 27);
+	msa_config->avg_bytes_per_tu = (video_bw *
+					msa_config->transfer_unit_size) /
+					link_bw;
+
+	/* The number of initial wait cycles at the start of a new line
+	 * by the framing logic. This allows enough data to be buffered
+	 * in the input FIFO before video is sent.
+	 */
+	if ((msa_config->avg_bytes_per_tu / 1000) <= 4)
+		msa_config->init_wait = 64;
+	else
+		msa_config->init_wait = msa_config->transfer_unit_size -
+					(msa_config->avg_bytes_per_tu / 1000);
+}
+
+/*
+ * Disable/enable the end of line reset to the internal video pipe in case of
+ * reduced blanking as required.
+ */
+static void set_line_reset(struct udevice *dev)
+{
+	struct dp_tx *dp_tx = dev_get_priv(dev);
+	u32 reg_val;
+	u16 h_blank;
+	u16 h_reduced_blank;
+	struct main_stream_attributes *msa_config =
+		&dp_tx->main_stream_attributes;
+
+	h_blank = msa_config->h_total - msa_config->h_active;
+	/* Reduced blanking starts at ceil(0.2 * HTotal). */
+	h_reduced_blank = 2 * msa_config->h_total;
+	if (h_reduced_blank % 10)
+		h_reduced_blank += 10;
+	h_reduced_blank /= 10;
+
+	/* CVT spec. states h_blank is either 80 or 160 for reduced blanking. */
+	reg_val = get_reg(dev, REG_LINE_RESET_DISABLE);
+	if ((h_blank < h_reduced_blank) &&
+	    ((h_blank == 80) || (h_blank == 160))) {
+		reg_val |= LINE_RESET_DISABLE_MASK;
+	} else {
+		reg_val &= ~LINE_RESET_DISABLE_MASK;
+	}
+	set_reg(dev, REG_LINE_RESET_DISABLE, reg_val);
+}
+
+/*
+ * Clear the main stream attributes registers of the DisplayPort
+ * TX core.
+ */
+static void clear_msa_values(struct udevice *dev)
+{
+	set_reg(dev, REG_MAIN_STREAM_HTOTAL, 0);
+	set_reg(dev, REG_MAIN_STREAM_VTOTAL, 0);
+	set_reg(dev, REG_MAIN_STREAM_POLARITY, 0);
+	set_reg(dev, REG_MAIN_STREAM_HSWIDTH, 0);
+	set_reg(dev, REG_MAIN_STREAM_VSWIDTH, 0);
+	set_reg(dev, REG_MAIN_STREAM_HRES, 0);
+	set_reg(dev, REG_MAIN_STREAM_VRES, 0);
+	set_reg(dev, REG_MAIN_STREAM_HSTART, 0);
+	set_reg(dev, REG_MAIN_STREAM_VSTART, 0);
+	set_reg(dev, REG_MAIN_STREAM_MISC0, 0);
+	set_reg(dev, REG_MAIN_STREAM_MISC1, 0);
+	set_reg(dev, REG_USER_PIXEL_WIDTH, 0);
+	set_reg(dev, REG_USER_DATA_COUNT_PER_LANE, 0);
+	set_reg(dev, REG_M_VID, 0);
+	set_reg(dev, REG_N_VID, 0);
+
+	set_reg(dev, REG_STREAM1, 0);
+	set_reg(dev, REG_TU_SIZE, 0);
+	set_reg(dev, REG_MIN_BYTES_PER_TU, 0);
+	set_reg(dev, REG_FRAC_BYTES_PER_TU, 0);
+	set_reg(dev, REG_INIT_WAIT, 0);
+}
+
+/*
+ * Set the main stream attributes registers of the DisplayPort TX
+ * core with the values specified in the main stream attributes configuration
+ * structure.
+ */
+static void set_msa_values(struct udevice *dev)
+{
+	struct dp_tx *dp_tx = dev_get_priv(dev);
+	struct main_stream_attributes *msa_config =
+		&dp_tx->main_stream_attributes;
+
+	printf("       set MSA %u x %u\n", msa_config->h_active,
+	       msa_config->v_active);
+
+	set_reg(dev, REG_MAIN_STREAM_HTOTAL, msa_config->h_total);
+	set_reg(dev, REG_MAIN_STREAM_VTOTAL, msa_config->v_total);
+	set_reg(dev, REG_MAIN_STREAM_POLARITY,
+		msa_config->h_sync_polarity |
+		(msa_config->v_sync_polarity <<
+		 MAIN_STREAMX_POLARITY_VSYNC_POL_SHIFT));
+	set_reg(dev, REG_MAIN_STREAM_HSWIDTH, msa_config->h_sync_width);
+	set_reg(dev, REG_MAIN_STREAM_VSWIDTH, msa_config->v_sync_width);
+	set_reg(dev, REG_MAIN_STREAM_HRES, msa_config->h_active);
+	set_reg(dev, REG_MAIN_STREAM_VRES, msa_config->v_active);
+	set_reg(dev, REG_MAIN_STREAM_HSTART, msa_config->h_start);
+	set_reg(dev, REG_MAIN_STREAM_VSTART, msa_config->v_start);
+	set_reg(dev, REG_MAIN_STREAM_MISC0, msa_config->misc_0);
+	set_reg(dev, REG_MAIN_STREAM_MISC1, msa_config->misc_1);
+	set_reg(dev, REG_USER_PIXEL_WIDTH, msa_config->user_pixel_width);
+
+	set_reg(dev, REG_M_VID, msa_config->pixel_clock_hz / 1000);
+	set_reg(dev, REG_N_VID, msa_config->n_vid);
+	set_reg(dev, REG_USER_DATA_COUNT_PER_LANE, msa_config->data_per_lane);
+
+	set_line_reset(dev);
+
+	set_reg(dev, REG_TU_SIZE, msa_config->transfer_unit_size);
+	set_reg(dev, REG_MIN_BYTES_PER_TU, msa_config->avg_bytes_per_tu / 1000);
+	set_reg(dev, REG_FRAC_BYTES_PER_TU,
+		(msa_config->avg_bytes_per_tu % 1000) * 1024 / 1000);
+	set_reg(dev, REG_INIT_WAIT, msa_config->init_wait);
+}
+
+static void logicore_dp_tx_set_msa(struct udevice *dev,
+				   struct logicore_dp_tx_msa *msa)
+{
+	struct dp_tx *dp_tx = dev_get_priv(dev);
+
+	memset(&dp_tx->main_stream_attributes, 0,
+	       sizeof(struct main_stream_attributes));
+
+	dp_tx->main_stream_attributes.pixel_clock_hz = msa->pixel_clock_hz;
+	dp_tx->main_stream_attributes.bits_per_color = msa->bits_per_color;
+	dp_tx->main_stream_attributes.h_active = msa->h_active;
+	dp_tx->main_stream_attributes.h_start = msa->h_start;
+	dp_tx->main_stream_attributes.h_sync_polarity = msa->h_sync_polarity;
+	dp_tx->main_stream_attributes.h_sync_width = msa->h_sync_width;
+	dp_tx->main_stream_attributes.h_total = msa->h_total;
+	dp_tx->main_stream_attributes.v_active = msa->v_active;
+	dp_tx->main_stream_attributes.v_start = msa->v_start;
+	dp_tx->main_stream_attributes.v_sync_polarity = msa->v_sync_polarity;
+	dp_tx->main_stream_attributes.v_sync_width = msa->v_sync_width;
+	dp_tx->main_stream_attributes.v_total = msa->v_total;
+	dp_tx->main_stream_attributes.override_user_pixel_width =
+		msa->override_user_pixel_width;
+	dp_tx->main_stream_attributes.user_pixel_width = msa->user_pixel_width;
+	dp_tx->main_stream_attributes.synchronous_clock_mode = 0;
+}
+
+/*
+ * external API
+ */
+
+int logicore_dp_tx_video_enable(struct udevice *dev,
+				struct logicore_dp_tx_msa *msa)
+{
+	struct dp_tx *dp_tx = dev_get_priv(dev);
+	int res;
+	u8 power = 0x01;
+
+	if (!is_connected(dev)) {
+		printf("       no DP sink connected\n");
+		return -EIO;
+	}
+
+	initialize(dev);
+
+	disable_main_link(dev);
+
+	logicore_dp_tx_set_msa(dev, msa);
+
+	get_rx_capabilities(dev);
+
+	printf("       DP sink connected\n");
+	aux_write(dev, DPCD_SET_POWER_DP_PWR_VOLTAGE, 1, &power);
+	set_enhanced_frame_mode(dev, true);
+	cfg_main_link_max(dev);
+	res = establish_link(dev);
+	printf("       establish_link: %s, vs: %d, pe: %d\n",
+	       res ? "failed" : "ok", dp_tx->link_config.vs_level,
+	       dp_tx->link_config.pe_level);
+
+	cfg_msa_recalculate(dev);
+
+	clear_msa_values(dev);
+	set_msa_values(dev);
+
+	enable_main_link(dev);
+
+	return 0;
+}
+
+int logicore_dp_tx_power_on(struct udevice *dev, void *data)
+{
+	struct clk pixclock;
+	struct logicore_dp_tx_msa *msa;
+	struct logicore_dp_tx_msa mode_640_480_60 = {
+		.pixel_clock_hz = 25175000,
+		.bits_per_color = 8,
+		.h_active = 640,
+		.h_start = 144,
+		.h_sync_polarity = false,
+		.h_sync_width = 96,
+		.h_total = 800,
+		.v_active = 480,
+		.v_start = 35,
+		.v_sync_polarity = false,
+		.v_sync_width = 2,
+		.v_total = 525,
+		.override_user_pixel_width = false,
+		.user_pixel_width = 0,
+	};
+
+	struct logicore_dp_tx_msa mode_720_400_70 = {
+		.pixel_clock_hz = 28300000,
+		.bits_per_color = 8,
+		.h_active = 720,
+		.h_start = 162,
+		.h_sync_polarity = false,
+		.h_sync_width = 108,
+		.h_total = 900,
+		.v_active = 400,
+		.v_start = 37,
+		.v_sync_polarity = true,
+		.v_sync_width = 2,
+		.v_total = 449,
+		.override_user_pixel_width = false,
+		.user_pixel_width = 0,
+	};
+
+	struct logicore_dp_tx_msa mode_1024_768_60 = {
+		.pixel_clock_hz = 65000000,
+		.bits_per_color = 8,
+		.h_active = 1024,
+		.h_start = 296,
+		.h_sync_polarity = false,
+		.h_sync_width = 136,
+		.h_total = 1344,
+		.v_active = 768,
+		.v_start = 35,
+		.v_sync_polarity = false,
+		.v_sync_width = 2,
+		.v_total = 806,
+		.override_user_pixel_width = false,
+		.user_pixel_width = 0,
+	};
+
+	if (!strcmp(data, "1024_768_60"))
+		msa = &mode_1024_768_60;
+	else if (!strcmp(data, "720_400_70"))
+		msa = &mode_720_400_70;
+	else
+		msa = &mode_640_480_60;
+
+	if (clk_get_by_index(dev, 0, &pixclock)) {
+		printf("%s: Could not get pixelclock\n", dev->name);
+		return -1;
+	}
+	clk_set_rate(&pixclock, msa->pixel_clock_hz);
+
+	return logicore_dp_tx_video_enable(dev, msa);
+}
+
+int logicore_dp_tx_power_off(struct udevice *dev)
+{
+	return 0;
+}
+
+int logicore_dp_tx_probe(struct udevice *dev)
+{
+	struct dp_tx *dp_tx = dev_get_priv(dev);
+
+	dp_tx->s_axi_clk = S_AXI_CLK_DEFAULT;
+	dp_tx->train_adaptive = false;
+	dp_tx->max_link_rate = DPCD_MAX_LINK_RATE_540GBPS;
+	dp_tx->max_lane_count = DPCD_MAX_LANE_COUNT_4;
+
+	dp_tx->base = fdtdec_get_int(gd->fdt_blob, dev_of_offset(dev),
+				     "reg", -1);
+
+	return 0;
+}
+
+struct transmitter_ops logicore_dp_tx_ops = {
+	.power_on = logicore_dp_tx_power_on,
+	.power_off = logicore_dp_tx_power_off,
+};
+
+static const struct udevice_id logicore_dp_tx_ids[] = {
+	{ .compatible = "gdsys,logicore_dp_tx" },
+	{ /* sentinel */ }
+};
+
+U_BOOT_DRIVER(logicore_dp_tx) = {
+	.name			= "logicore_dp_tx",
+	.id			= UCLASS_TRANSMITTER,
+	.of_match		= logicore_dp_tx_ids,
+	.probe			= logicore_dp_tx_probe,
+	//.ofdata_to_platdata	= logicore_dp_tx_ofdata_to_platdata,
+	.priv_auto_alloc_size	= sizeof(struct dp_tx),
+	.ops			= &logicore_dp_tx_ops,
+};
diff --git a/drivers/transmitter/logicore_dp_tx.h b/drivers/transmitter/logicore_dp_tx.h
new file mode 100644
index 0000000000..32f9649b9c
--- /dev/null
+++ b/drivers/transmitter/logicore_dp_tx.h
@@ -0,0 +1,40 @@
+/*
+ * logicore_dp_tx.h
+ *
+ * Driver for XILINX LogiCore DisplayPort v6.1 TX (Source)
+ *
+ * (C) Copyright 2016
+ * Dirk Eibach,  Guntermann & Drunck GmbH, dirk.eibach at gdsys.cc
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#ifndef __GDSYS_LOGICORE_DP_TX_H__
+#define __GDSYS_LOGICORE_DP_TX_H__
+
+/*
+ * this is a stripped down version of struct main_stream_attributes that contains
+ * only the parameters that are not set by cfg_msa_recalculate()
+ */
+struct logicore_dp_tx_msa {
+	u32 pixel_clock_hz;		/* The pixel clock of the stream (in Hz). */
+	u32 bits_per_color;		/* Number of bits per color component. */
+	u16 h_active;			/* Horizontal active resolution (pixels) */
+	u32 h_start;			/* Horizontal blank start (in pixels). */
+	bool h_sync_polarity;		/* Horizontal sync polarity (0=negative|1=positive) */
+	u16 h_sync_width;		/* Horizontal sync width (pixels) */
+	u16 h_total;			/* Horizontal total (pixels) */
+	u16 v_active;			/* Vertical active resolution (lines) */
+	u32 v_start;			/* Vertical blank start (in lines). */
+	bool v_sync_polarity;		/* Vertical sync polarity (0=negative|1=positive) */
+	u16 v_sync_width;		/* Vertical sync width (lines) */
+	u16 v_total;			/* Vertical total (lines) */
+	bool override_user_pixel_width;	/* If true, the value stored for
+					   user_pixel_width will be used as
+					   the pixel width. */
+	u32 user_pixel_width;		/* The width of the user data input port. */
+};
+
+int logicore_dp_tx_video_enable(struct udevice *dev, struct logicore_dp_tx_msa *msa);
+
+#endif /* __GDSYS_LOGICORE_DP_TX_H__ */
diff --git a/drivers/transmitter/logicore_dp_tx_regif.h b/drivers/transmitter/logicore_dp_tx_regif.h
new file mode 100644
index 0000000000..c4105605c9
--- /dev/null
+++ b/drivers/transmitter/logicore_dp_tx_regif.h
@@ -0,0 +1,365 @@
+/*
+ * logicore_dp_tx_regif.h
+ *
+ * Register interface definition for XILINX LogiCore DisplayPort v6.1 TX (Source)
+ * based on Xilinx dp_v3_1 driver sources
+ *
+ * (C) Copyright 2016
+ * Dirk Eibach,  Guntermann & Drunck GmbH, dirk.eibach at gdsys.cc
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#ifndef __GDSYS_LOGICORE_DP_TX_REGIF_H__
+#define __GDSYS_LOGICORE_DP_TX_REGIF_H__
+
+enum {
+	/* link configuration field */
+	REG_LINK_BW_SET =		0x000,
+	REG_LANE_COUNT_SET =		0x004,
+	REG_ENHANCED_FRAME_EN =		0x008,
+	REG_TRAINING_PATTERN_SET =	0x00C,
+	REG_LINK_QUAL_PATTERN_SET =	0x010,
+	REG_SCRAMBLING_DISABLE =	0x014,
+	REG_DOWNSPREAD_CTRL =		0x018,
+	REG_SOFT_RESET =		0x01C,
+
+	/* core enables */
+	REG_ENABLE =			0x080,
+	REG_ENABLE_MAIN_STREAM =	0x084,
+	REG_ENABLE_SEC_STREAM =		0x088,
+	REG_FORCE_SCRAMBLER_RESET =	0x0C0,
+	REG_MST_CONFIG =		0x0D0,
+	REG_LINE_RESET_DISABLE =	0x0F0,
+
+	/* core ID */
+	REG_VERSION = 			0x0F8,
+	REG_CORE_ID = 			0x0FC,
+
+	/* AUX channel interface */
+	REG_AUX_CMD =			0x100,
+	REG_AUX_WRITE_FIFO =		0x104,
+	REG_AUX_ADDRESS =		0x108,
+	REG_AUX_CLK_DIVIDER =		0x10C,
+	REG_USER_FIFO_OVERFLOW =	0x110,
+	REG_INTERRUPT_SIG_STATE =	0x130,
+	REG_AUX_REPLY_DATA =		0x134,
+	REG_AUX_REPLY_CODE =		0x138,
+	REG_AUX_REPLY_COUNT =		0x13C,
+	REG_INTERRUPT_STATUS =		0x140,
+	REG_INTERRUPT_MASK =		0x144,
+	REG_REPLY_DATA_COUNT =		0x148,
+	REG_REPLY_STATUS =		0x14C,
+	REG_HPD_DURATION =		0x150,
+
+	/* main stream attributes for SST / MST STREAM1 */
+	REG_STREAM1_MSA_START =		0x180,
+	REG_MAIN_STREAM_HTOTAL =	0x180,
+	REG_MAIN_STREAM_VTOTAL =	0x184,
+	REG_MAIN_STREAM_POLARITY =	0x188,
+	REG_MAIN_STREAM_HSWIDTH =	0x18C,
+	REG_MAIN_STREAM_VSWIDTH =	0x190,
+	REG_MAIN_STREAM_HRES =		0x194,
+	REG_MAIN_STREAM_VRES =		0x198,
+	REG_MAIN_STREAM_HSTART =	0x19C,
+	REG_MAIN_STREAM_VSTART =	0x1A0,
+	REG_MAIN_STREAM_MISC0 =		0x1A4,
+	REG_MAIN_STREAM_MISC1 =		0x1A8,
+	REG_M_VID =			0x1AC,
+	REG_TU_SIZE =			0x1B0,
+	REG_N_VID =			0x1B4,
+	REG_USER_PIXEL_WIDTH =		0x1B8,
+	REG_USER_DATA_COUNT_PER_LANE =0x1BC,
+	REG_MAIN_STREAM_INTERLACED =	0x1C0,
+	REG_MIN_BYTES_PER_TU =		0x1C4,
+	REG_FRAC_BYTES_PER_TU =		0x1C8,
+	REG_INIT_WAIT =			0x1CC,
+	REG_STREAM1 =			0x1D0,
+	REG_STREAM2 =			0x1D4,
+	REG_STREAM3 =			0x1D8,
+	REG_STREAM4 =			0x1DC,
+
+	/* PHY configuration status */
+	REG_PHY_CONFIG =		0x200,
+	REG_PHY_VOLTAGE_DIFF_LANE_0 =	0x220,
+	REG_PHY_VOLTAGE_DIFF_LANE_1 =	0x224,
+	REG_PHY_VOLTAGE_DIFF_LANE_2 =	0x228,
+	REG_PHY_VOLTAGE_DIFF_LANE_3 =	0x22C,
+	REG_PHY_TRANSMIT_PRBS7 =	0x230,
+	REG_PHY_CLOCK_SELECT =		0x234,
+	REG_PHY_POWER_DOWN =		0x238,
+	REG_PHY_PRECURSOR_LANE_0 =	0x23C,
+	REG_PHY_PRECURSOR_LANE_1 =	0x240,
+	REG_PHY_PRECURSOR_LANE_2 =	0x244,
+	REG_PHY_PRECURSOR_LANE_3 =	0x248,
+	REG_PHY_POSTCURSOR_LANE_0 =	0x24C,
+	REG_PHY_POSTCURSOR_LANE_1 =	0x250,
+	REG_PHY_POSTCURSOR_LANE_2 =	0x254,
+	REG_PHY_POSTCURSOR_LANE_3 =	0x258,
+	REG_PHY_STATUS =		0x280,
+	REG_GT_DRP_COMMAND =		0x2A0,
+	REG_GT_DRP_READ_DATA =		0x2A4,
+	REG_GT_DRP_CHANNEL_STATUS =	0x2A8,
+
+	/* DisplayPort audio */
+	REG_AUDIO_CONTROL =		0x300,
+	REG_AUDIO_CHANNELS =		0x304,
+	REG_AUDIO_INFO_DATA =		0x308,
+	REG_AUDIO_MAUD =		0x328,
+	REG_AUDIO_NAUD =		0x32C,
+	REG_AUDIO_EXT_DATA =		0x330,
+
+	/* HDCP */
+	REG_HDCP_ENABLE =		0x400,
+
+	/* main stream attributes for MST STREAM2, 3, and 4 */
+	REG_STREAM2_MSA_START =		0x500,
+	REG_STREAM3_MSA_START =		0x550,
+	REG_STREAM4_MSA_START =		0x5A0,
+
+	REG_VC_PAYLOAD_BUFFER_ADDR =	0x800,
+};
+
+enum {
+	LINK_BW_SET_162GBPS =	0x06,
+	LINK_BW_SET_270GBPS =	0x0A,
+	LINK_BW_SET_540GBPS =	0x14,
+};
+
+enum {
+	LANE_COUNT_SET_1 =		0x1,
+	LANE_COUNT_SET_2 =		0x2,
+	LANE_COUNT_SET_4 =		0x4,
+};
+
+enum {
+	TRAINING_PATTERN_SET_OFF =	0x0,
+	/* training pattern 1 used for clock recovery */
+	TRAINING_PATTERN_SET_TP1 =	0x1,
+	/* training pattern 2 used for channel equalization */
+	TRAINING_PATTERN_SET_TP2 =	0x2,
+	/* training pattern 3 used for channel equalization for cores with DP v1.2 */
+	TRAINING_PATTERN_SET_TP3 =	0x3,
+};
+
+enum {
+	LINK_QUAL_PATTERN_SET_OFF =		0x0,
+	/* D10.2 unscrambled test pattern transmitted */
+	LINK_QUAL_PATTERN_SET_D102_TEST =	0x1,
+	/* symbol error rate measurement pattern transmitted */
+	LINK_QUAL_PATTERN_SET_SER_MES =		0x2,
+	/* pseudo random bit sequence 7 transmitted */
+	LINK_QUAL_PATTERN_SET_PRBS7 =		0x3,
+};
+
+enum {
+	SOFT_RESET_VIDEO_STREAM1_MASK =		0x00000001,
+	SOFT_RESET_VIDEO_STREAM2_MASK =		0x00000002,
+	SOFT_RESET_VIDEO_STREAM3_MASK =		0x00000004,
+	SOFT_RESET_VIDEO_STREAM4_MASK =		0x00000008,
+	SOFT_RESET_AUX_MASK =			0x00000080,
+	SOFT_RESET_VIDEO_STREAM_ALL_MASK =	0x0000000F,
+};
+
+enum {
+	MST_CONFIG_MST_EN_MASK = 	0x00000001,
+};
+
+enum {
+	LINE_RESET_DISABLE_MASK =	0x1,
+};
+
+#define AUX_CMD_NBYTES_TRANSFER_MASK	0x0000000F
+
+#define AUX_CMD_SHIFT		8
+#define AUX_CMD_MASK			0x00000F00
+enum {
+	AUX_CMD_I2C_WRITE =		0x0,
+	AUX_CMD_I2C_READ =		0x1,
+	AUX_CMD_I2C_WRITE_STATUS =	0x2,
+	AUX_CMD_I2C_WRITE_MOT =		0x4,
+	AUX_CMD_I2C_READ_MOT =		0x5,
+	AUX_CMD_I2C_WRITE_STATUS_MOT = 	0x6,
+	AUX_CMD_WRITE =			0x8,
+	AUX_CMD_READ =			0x9,
+};
+
+#define AUX_CLK_DIVIDER_VAL_MASK 		0x00FF
+
+#define AUX_CLK_DIVIDER_AUX_SIG_WIDTH_FILT_SHIFT 8
+#define AUX_CLK_DIVIDER_AUX_SIG_WIDTH_FILT_MASK 0xFF00
+
+enum {
+	INTERRUPT_SIG_STATE_HPD_STATE_MASK =		0x00000001,
+	INTERRUPT_SIG_STATE_REQUEST_STATE_MASK =	0x00000002,
+	INTERRUPT_SIG_STATE_REPLY_STATE_MASK =		0x00000004,
+	INTERRUPT_SIG_STATE_REPLY_TIMEOUT_MASK =	0x00000008,
+};
+
+enum {
+	AUX_REPLY_CODE_ACK =		0x0,
+	AUX_REPLY_CODE_I2C_ACK =	0x0,
+	AUX_REPLY_CODE_NACK =		0x1,
+	AUX_REPLY_CODE_DEFER =		0x2,
+	AUX_REPLY_CODE_I2C_NACK =	0x4,
+	AUX_REPLY_CODE_I2C_DEFER =	0x8,
+};
+
+enum {
+	INTERRUPT_STATUS_HPD_IRQ_MASK = 		0x00000001,
+	INTERRUPT_STATUS_HPD_EVENT_MASK = 		0x00000002,
+	INTERRUPT_STATUS_REPLY_RECEIVED_MASK = 		0x00000004,
+	INTERRUPT_STATUS_REPLY_TIMEOUT_MASK = 		0x00000008,
+	INTERRUPT_STATUS_HPD_PULSE_DETECTED_MASK = 	0x00000010,
+	INTERRUPT_STATUS_EXT_PKT_TXD_MASK = 		0x00000020,
+};
+
+enum {
+	INTERRUPT_MASK_HPD_IRQ_MASK =			0x00000001,
+	INTERRUPT_MASK_HPD_EVENT_MASK =			0x00000002,
+	INTERRUPT_MASK_REPLY_RECEIVED_MASK =		0x00000004,
+	INTERRUPT_MASK_REPLY_TIMEOUT_MASK =		0x00000008,
+	INTERRUPT_MASK_HPD_PULSE_DETECTED_MASK =	0x00000010,
+	INTERRUPT_MASK_EXT_PKT_TXD_MASK =		0x00000020,
+};
+
+#define REPLY_STATUS_REPLY_STATUS_STATE_SHIFT 4
+#define REPLY_STATUS_REPLY_STATUS_STATE_MASK	0x00000FF0
+enum {
+	REPLY_STATUS_REPLY_RECEIVED_MASK =	0x00000001,
+	REPLY_STATUS_REPLY_IN_PROGRESS_MASK =	0x00000002,
+	REPLY_STATUS_REQUEST_IN_PROGRESS_MASK =	0x00000004,
+	REPLY_STATUS_REPLY_ERROR_MASK =		0x00000008,
+};
+
+#define MAIN_STREAMX_POLARITY_VSYNC_POL_SHIFT 1
+enum {
+	MAIN_STREAMX_POLARITY_HSYNC_POL_MASK =	0x00000001,
+	MAIN_STREAMX_POLARITY_VSYNC_POL_MASK =	0x00000002,
+};
+
+enum {
+	MAIN_STREAMX_MISC0_SYNC_CLK_MASK = 0x00000001,
+};
+
+#define MAIN_STREAMX_MISC0_COMPONENT_FORMAT_SHIFT 1
+#define MAIN_STREAMX_MISC0_COMPONENT_FORMAT_MASK 0x00000006
+enum {
+	MAIN_STREAMX_MISC0_COMPONENT_FORMAT_RGB =	0x0,
+	MAIN_STREAMX_MISC0_COMPONENT_FORMAT_YCBCR422 =	0x1,
+	MAIN_STREAMX_MISC0_COMPONENT_FORMAT_YCBCR444 =	0x2,
+};
+
+#define MAIN_STREAMX_MISC0_DYNAMIC_RANGE_SHIFT 3
+#define MAIN_STREAMX_MISC0_DYNAMIC_RANGE_MASK 0x00000008
+
+#define MAIN_STREAMX_MISC0_YCBCR_COLORIMETRY_SHIFT 4
+#define MAIN_STREAMX_MISC0_YCBCR_COLORIMETRY_MASK 0x00000010
+
+#define MAIN_STREAMX_MISC0_BDC_SHIFT 5
+#define MAIN_STREAMX_MISC0_BDC_MASK 0x000000E0
+enum {
+	MAIN_STREAMX_MISC0_BDC_6BPC =	0x0,
+	MAIN_STREAMX_MISC0_BDC_8BPC =	0x1,
+	MAIN_STREAMX_MISC0_BDC_10BPC =	0x2,
+	MAIN_STREAMX_MISC0_BDC_12BPC =	0x3,
+	MAIN_STREAMX_MISC0_BDC_16BPC =	0x4,
+};
+
+enum {
+	PHY_CONFIG_PHY_RESET_ENABLE_MASK =		0x0000000,
+	PHY_CONFIG_PHY_RESET_MASK =			0x0000001,
+	PHY_CONFIG_GTTX_RESET_MASK =			0x0000002,
+	PHY_CONFIG_GT_ALL_RESET_MASK =			0x0000003,
+	PHY_CONFIG_TX_PHY_PMA_RESET_MASK =		0x0000100,
+	PHY_CONFIG_TX_PHY_PCS_RESET_MASK =		0x0000200,
+	PHY_CONFIG_TX_PHY_POLARITY_MASK =		0x0000800,
+	PHY_CONFIG_TX_PHY_PRBSFORCEERR_MASK =		0x0001000,
+	PHY_CONFIG_TX_PHY_POLARITY_IND_LANE_MASK =	0x0010000,
+	PHY_CONFIG_TX_PHY_POLARITY_LANE0_MASK =		0x0020000,
+	PHY_CONFIG_TX_PHY_POLARITY_LANE1_MASK =		0x0040000,
+	PHY_CONFIG_TX_PHY_POLARITY_LANE2_MASK =		0x0080000,
+	PHY_CONFIG_TX_PHY_POLARITY_LANE3_MASK =		0x0100000,
+	PHY_CONFIG_TX_PHY_8B10BEN_MASK =		0x0200000,
+};
+
+#define PHY_CONFIG_TX_PHY_LOOPBACK_SHIFT 13
+#define PHY_CONFIG_TX_PHY_LOOPBACK_MASK 0x000E000
+
+enum {
+	PHY_CLOCK_SELECT_162GBPS =	0x1,
+	PHY_CLOCK_SELECT_270GBPS =	0x3,
+	PHY_CLOCK_SELECT_540GBPS =	0x5,
+};
+
+enum {
+	VS_LEVEL_0	= 0x2,
+	VS_LEVEL_1	= 0x5,
+	VS_LEVEL_2	= 0x8,
+	VS_LEVEL_3	= 0xF,
+	VS_LEVEL_OFFSET	= 0x4,
+};
+
+enum {
+	PE_LEVEL_0 =	0x00,
+	PE_LEVEL_1 =	0x0E,
+	PE_LEVEL_2 =	0x14,
+	PE_LEVEL_3 =	0x1B,
+};
+
+enum {
+	PHY_STATUS_RESET_LANE_2_3_DONE_SHIFT =		2,
+	PHY_STATUS_TX_ERROR_LANE_0_SHIFT =		18,
+	PHY_STATUS_TX_BUFFER_STATUS_LANE_1_SHIFT =	20,
+	PHY_STATUS_TX_ERROR_LANE_1_SHIFT =		22,
+	PHY_STATUS_TX_BUFFER_STATUS_LANE_0_SHIFT =	16,
+	PHY_STATUS_TX_BUFFER_STATUS_LANE_2_SHIFT =	24,
+	PHY_STATUS_TX_ERROR_LANE_2_SHIFT =		26,
+	PHY_STATUS_TX_BUFFER_STATUS_LANE_3_SHIFT =	28,
+	PHY_STATUS_TX_ERROR_LANE_3_SHIFT =		30,
+};
+
+enum {
+	PHY_STATUS_RESET_LANE_0_DONE_MASK =		0x00000001,
+	PHY_STATUS_RESET_LANE_1_DONE_MASK =		0x00000002,
+	PHY_STATUS_RESET_LANE_2_3_DONE_MASK =		0x0000000C,
+	PHY_STATUS_PLL_LANE0_1_LOCK_MASK =		0x00000010,
+	PHY_STATUS_PLL_LANE2_3_LOCK_MASK =		0x00000020,
+	PHY_STATUS_PLL_FABRIC_LOCK_MASK =		0x00000040,
+	PHY_STATUS_TX_BUFFER_STATUS_LANE_0_MASK =	0x00030000,
+	PHY_STATUS_TX_ERROR_LANE_0_MASK =		0x000C0000,
+	PHY_STATUS_TX_BUFFER_STATUS_LANE_1_MASK =	0x00300000,
+	PHY_STATUS_TX_ERROR_LANE_1_MASK =		0x00C00000,
+	PHY_STATUS_TX_BUFFER_STATUS_LANE_2_MASK =	0x03000000,
+	PHY_STATUS_TX_ERROR_LANE_2_MASK =		0x0C000000,
+	PHY_STATUS_TX_BUFFER_STATUS_LANE_3_MASK =	0x30000000,
+	PHY_STATUS_TX_ERROR_LANE_3_MASK =		0xC0000000,
+};
+
+#define PHY_STATUS_LANE_0_READY_MASK \
+	(PHY_STATUS_RESET_LANE_0_DONE_MASK | \
+	PHY_STATUS_PLL_LANE0_1_LOCK_MASK)
+#define PHY_STATUS_LANES_0_1_READY_MASK \
+	(PHY_STATUS_LANE_0_READY_MASK | \
+	PHY_STATUS_RESET_LANE_1_DONE_MASK)
+/*
+ * PHY_STATUS_ALL_LANES_READY_MASK seems zo be missing lanes 0 and 1 in
+ * Xilinx dp_v3_0 implementation
+ */
+#define PHY_STATUS_ALL_LANES_READY_MASK \
+	(PHY_STATUS_LANES_0_1_READY_MASK | \
+	PHY_STATUS_RESET_LANE_2_3_DONE_MASK | \
+	PHY_STATUS_PLL_LANE2_3_LOCK_MASK)
+#define PHY_STATUS_LANES_READY_MASK(n) \
+	(((n) > 2) ? PHY_STATUS_ALL_LANES_READY_MASK : \
+	((n) == 2) ? PHY_STATUS_LANES_0_1_READY_MASK : \
+	PHY_STATUS_LANE_0_READY_MASK)
+
+#define GT_DRP_COMMAND_DRP_ADDR_MASK	0x000F
+#define GT_DRP_COMMAND_DRP_RW_CMD_MASK	0x0080
+#define GT_DRP_COMMAND_DRP_W_DATA_SHIFT 16
+#define GT_DRP_COMMAND_DRP_W_DATA_MASK	0xFF00
+
+#define HDCP_ENABLE_BYPASS_DISABLE_MASK	0x0001
+
+#endif /* __GDSYS_LOGICORE_DP_TX_REGIF_H__ */
-- 
2.11.0

^ permalink raw reply related	[flat|nested] 138+ messages in thread

* [U-Boot] [PATCH 35/51] drivers: Add ICS8N3QV01 driver
  2017-07-14 12:54 [U-Boot] [PATCH 00/51] gdsys: Add support for Gazerbeam board Mario Six
                   ` (33 preceding siblings ...)
  2017-07-14 12:55 ` [U-Boot] [PATCH 34/51] transmitter: Add Xilinx LogiCore DP TX Mario Six
@ 2017-07-14 12:55 ` Mario Six
  2017-07-19  9:05   ` Simon Glass
  2017-07-14 12:55 ` [U-Boot] [PATCH 36/51] drivers: Add ihs_axi driver Mario Six
                   ` (15 subsequent siblings)
  50 siblings, 1 reply; 138+ messages in thread
From: Mario Six @ 2017-07-14 12:55 UTC (permalink / raw)
  To: u-boot

Add a driver for the ICS8N3QV01 Quad-Frequency Programmable VCXO.

Signed-off-by: Mario Six <mario.six@gdsys.cc>
---

 drivers/clk/Kconfig      |   6 ++
 drivers/clk/Makefile     |   1 +
 drivers/clk/ics8n3qv01.c | 184 +++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 191 insertions(+)
 create mode 100644 drivers/clk/ics8n3qv01.c

diff --git a/drivers/clk/Kconfig b/drivers/clk/Kconfig
index 44da716b26..f6f3810b64 100644
--- a/drivers/clk/Kconfig
+++ b/drivers/clk/Kconfig
@@ -56,4 +56,10 @@ source "drivers/clk/uniphier/Kconfig"
 source "drivers/clk/exynos/Kconfig"
 source "drivers/clk/at91/Kconfig"
 
+config ICS8N3QV01
+	bool "Enable ICS8N3QV01 VCXO driver"
+	depends on CLK
+	help
+	  Support for the ICS8N3QV01 VCXO.
+
 endmenu
diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile
index 2746a8016a..d7cc486d23 100644
--- a/drivers/clk/Makefile
+++ b/drivers/clk/Makefile
@@ -21,3 +21,4 @@ obj-$(CONFIG_CLK_BCM6345) += clk_bcm6345.o
 obj-$(CONFIG_CLK_BOSTON) += clk_boston.o
 obj-$(CONFIG_ARCH_ASPEED) += aspeed/
 obj-$(CONFIG_STM32F7) += clk_stm32f7.o
+obj-$(CONFIG_ICS8N3QV01) += ics8n3qv01.o
diff --git a/drivers/clk/ics8n3qv01.c b/drivers/clk/ics8n3qv01.c
new file mode 100644
index 0000000000..f5f4b74982
--- /dev/null
+++ b/drivers/clk/ics8n3qv01.c
@@ -0,0 +1,184 @@
+/*
+ * (C) Copyright 2017
+ * Mario Six,  Guntermann & Drunck GmbH, mario.six at gdsys.cc
+ *
+ * based on the gdsys osd driver, which is
+ *
+ * (C) Copyright 2010
+ * Dirk Eibach,  Guntermann & Drunck GmbH, eibach at gdsys.de
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <clk-uclass.h>
+#include <i2c.h>
+
+const long long ICS8N3QV01_FREF = 114285000;
+const long long ICS8N3QV01_FREF_LL = 114285000LL;
+const long long ICS8N3QV01_F_DEFAULT_0 = 156250000LL;
+const long long ICS8N3QV01_F_DEFAULT_1 = 125000000LL;
+const long long ICS8N3QV01_F_DEFAULT_2 = 100000000LL;
+const long long ICS8N3QV01_F_DEFAULT_3 = 25175000LL;
+
+struct ics8n3qv01_priv {
+	ulong rate;
+};
+
+static uint ics8n3qv01_get_fout_calc(struct udevice *dev, uint index)
+{
+	u64 n, mint, mfrac;
+	u8 reg_a, reg_b, reg_c, reg_d, reg_f;
+	u64 fout_calc;
+
+	if (index > 3)
+		return 0;
+
+	reg_a = dm_i2c_reg_read(dev, 0 + index);
+	reg_b = dm_i2c_reg_read(dev, 4 + index);
+	reg_c = dm_i2c_reg_read(dev, 8 + index);
+	reg_d = dm_i2c_reg_read(dev, 12 + index);
+	reg_f = dm_i2c_reg_read(dev, 20 + index);
+
+	mint = ((reg_a >> 1) & 0x1f) | (reg_f & 0x20);
+	mfrac = ((reg_a & 0x01) << 17) | (reg_b << 9) | (reg_c << 1)
+		| (reg_d >> 7);
+	n = reg_d & 0x7f;
+
+	fout_calc = (mint * ICS8N3QV01_FREF_LL
+		     + mfrac * ICS8N3QV01_FREF_LL / 262144LL
+		     + ICS8N3QV01_FREF_LL / 524288LL
+		     + n / 2)
+		    / n
+		    * 1000000
+		    / (1000000 - 100);
+
+	return fout_calc;
+}
+
+static void ics8n3qv01_calc_parameters(uint fout, uint *_mint, uint *_mfrac,
+				       uint *_n)
+{
+	uint n, foutiic, fvcoiic, mint;
+	u64 mfrac;
+
+	n = (2215000000U + fout / 2) / fout;
+	if ((n & 1) && (n > 5))
+		n -= 1;
+
+	foutiic = fout - (fout / 10000);
+	fvcoiic = foutiic * n;
+
+	mint = fvcoiic / 114285000;
+	if ((mint < 17) || (mint > 63))
+		printf("ics8n3qv01_calc_parameters: cannot determine mint\n");
+
+	mfrac = ((u64)fvcoiic % 114285000LL) * 262144LL
+		/ 114285000LL;
+
+	*_mint = mint;
+	*_mfrac = mfrac;
+	*_n = n;
+}
+
+static ulong ics8n3qv01_set_rate(struct clk *clk, ulong fout)
+{
+	struct ics8n3qv01_priv *priv = dev_get_priv(clk->dev);
+	uint n, mint, mfrac, fout_calc;
+	u64 fout_prog;
+	long long off_ppm;
+	u8 reg0, reg4, reg8, reg12, reg18, reg20;
+
+	priv->rate = fout;
+
+	fout_calc = ics8n3qv01_get_fout_calc(clk->dev, 1);
+	off_ppm = (fout_calc - ICS8N3QV01_F_DEFAULT_1) * 1000000
+		  / ICS8N3QV01_F_DEFAULT_1;
+	printf("%s: PLL is off by %lld ppm\n", clk->dev->name, off_ppm);
+	fout_prog = (u64)fout * (u64)fout_calc
+		    / ICS8N3QV01_F_DEFAULT_1;
+	ics8n3qv01_calc_parameters(fout_prog, &mint, &mfrac, &n);
+
+	reg0 = dm_i2c_reg_read(clk->dev, 0) & 0xc0;
+	reg0 |= (mint & 0x1f) << 1;
+	reg0 |= (mfrac >> 17) & 0x01;
+	dm_i2c_reg_write(clk->dev, 0, reg0);
+
+	reg4 = mfrac >> 9;
+	dm_i2c_reg_write(clk->dev, 4, reg4);
+
+	reg8 = mfrac >> 1;
+	dm_i2c_reg_write(clk->dev, 8, reg8);
+
+	reg12 = mfrac << 7;
+	reg12 |= n & 0x7f;
+	dm_i2c_reg_write(clk->dev, 12, reg12);
+
+	reg18 = dm_i2c_reg_read(clk->dev, 18) & 0x03;
+	reg18 |= 0x20;
+	dm_i2c_reg_write(clk->dev, 18, reg18);
+
+	reg20 = dm_i2c_reg_read(clk->dev, 20) & 0x1f;
+	reg20 |= mint & (1 << 5);
+	dm_i2c_reg_write(clk->dev, 20, reg20);
+
+	return 0;
+}
+
+static int ics8n3qv01_request(struct clk *clock)
+{
+	return 0;
+}
+
+static ulong ics8n3qv01_get_rate(struct clk *clk)
+{
+	struct ics8n3qv01_priv *priv = dev_get_priv(clk->dev);
+
+	return priv->rate;
+}
+
+static int ics8n3qv01_enable(struct clk *clk)
+{
+	return 0;
+}
+
+static int ics8n3qv01_disable(struct clk *clk)
+{
+	return 0;
+}
+
+static const struct clk_ops ics8n3qv01_ops = {
+	.request = ics8n3qv01_request,
+	.get_rate = ics8n3qv01_get_rate,
+	.set_rate = ics8n3qv01_set_rate,
+	.enable = ics8n3qv01_enable,
+	.disable = ics8n3qv01_disable,
+};
+
+static const struct udevice_id ics8n3qv01_ids[] = {
+	{ .compatible = "idt,ics8n3qv01" },
+	{ /* sentinel */ }
+};
+
+int ics8n3qv01_probe(struct udevice *dev)
+{
+	struct dm_i2c_chip *chip = dev_get_parent_platdata(dev);
+	struct udevice *dummy;
+
+	if (dm_i2c_probe(dev->parent, chip->chip_addr, chip->flags, &dummy)) {
+		printf("ics8n3qv01: I2C probe did not succeed.\n");
+		return -1;
+	}
+
+	return 0;
+}
+
+U_BOOT_DRIVER(ics8n3qv01) = {
+	.name           = "ics8n3qv01",
+	.id             = UCLASS_CLK,
+	.ops		= &ics8n3qv01_ops,
+	.of_match       = ics8n3qv01_ids,
+	.probe		= ics8n3qv01_probe,
+	.priv_auto_alloc_size	= sizeof(struct ics8n3qv01_priv),
+};
-- 
2.11.0

^ permalink raw reply related	[flat|nested] 138+ messages in thread

* [U-Boot] [PATCH 36/51] drivers: Add ihs_axi driver
  2017-07-14 12:54 [U-Boot] [PATCH 00/51] gdsys: Add support for Gazerbeam board Mario Six
                   ` (34 preceding siblings ...)
  2017-07-14 12:55 ` [U-Boot] [PATCH 35/51] drivers: Add ICS8N3QV01 driver Mario Six
@ 2017-07-14 12:55 ` Mario Six
  2017-07-19  9:06   ` Simon Glass
  2017-07-14 12:55 ` [U-Boot] [PATCH 37/51] drivers: Add ihs_video_out driver Mario Six
                   ` (14 subsequent siblings)
  50 siblings, 1 reply; 138+ messages in thread
From: Mario Six @ 2017-07-14 12:55 UTC (permalink / raw)
  To: u-boot

Add a driver for the IHS AXI bus on IHS FPGAs.

Signed-off-by: Mario Six <mario.six@gdsys.cc>
---

 drivers/misc/Kconfig   |   7 ++
 drivers/misc/Makefile  |   1 +
 drivers/misc/ihs_axi.c | 208 +++++++++++++++++++++++++++++++++++++++++++++++++
 include/dm/uclass-id.h |   1 +
 include/ihs_axi.h      |  69 ++++++++++++++++
 5 files changed, 286 insertions(+)
 create mode 100644 drivers/misc/ihs_axi.c
 create mode 100644 include/ihs_axi.h

diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig
index 8b59a444ce..c53f9f195e 100644
--- a/drivers/misc/Kconfig
+++ b/drivers/misc/Kconfig
@@ -202,4 +202,11 @@ config IHS_FPGA
 	depends on MISC
 	help
 	  Support for IHS FPGA.
+
+config IHS_AXI
+	bool "Enable IHS AXI driver"
+	depends on MISC
+	help
+	  Support for IHS AXI bus.
+
 endmenu
diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile
index d2e46fc7d6..a6c71acedd 100644
--- a/drivers/misc/Makefile
+++ b/drivers/misc/Makefile
@@ -53,3 +53,4 @@ obj-$(CONFIG_WINBOND_W83627) += winbond_w83627.o
 obj-$(CONFIG_QFW) += qfw.o
 obj-$(CONFIG_ROCKCHIP_EFUSE) += rockchip-efuse.o
 obj-$(CONFIG_IHS_FPGA) += ihs_fpga.o gdsys_soc.o
+obj-$(CONFIG_IHS_AXI) += ihs_axi.o
diff --git a/drivers/misc/ihs_axi.c b/drivers/misc/ihs_axi.c
new file mode 100644
index 0000000000..07150e2262
--- /dev/null
+++ b/drivers/misc/ihs_axi.c
@@ -0,0 +1,208 @@
+/*
+ * (C) Copyright 2016
+ * Dirk Eibach,  Guntermann & Drunck GmbH, dirk.eibach at gdsys.cc
+ *
+ * (C) Copyright 2017
+ * Mario Six,  Guntermann & Drunck GmbH, mario.six at gdsys.cc
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <dm/device-internal.h>
+#include <ihs_axi.h>
+#include <ihs_fpga.h>
+#include <gdsys_soc.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+enum {
+	REG_INTERRUPT_STATUS = 0x00,
+	REG_INTERRUPT_ENABLE_CONTROL = 0x02,
+	REG_ADDRESS_LSB = 0x04,
+	REG_ADDRESS_MSB = 0x06,
+	REG_WRITE_DATA_LSB = 0x08,
+	REG_WRITE_DATA_MSB = 0x0A,
+	REG_READ_DATA_LSB = 0x0C,
+	REG_READ_DATA_MSB = 0x0E,
+};
+
+struct ihs_axi_priv {
+	fdt_addr_t addr;
+};
+
+enum {
+	STATUS_EVENT_MASK = GENMASK(15, 12),
+
+	STATUS_READ_COMPLETE_EVENT = BIT(15),
+	STATUS_WRITE_COMPLETE_EVENT = BIT(14),
+	STATUS_TIMEOUT_EVENT = BIT(13),
+	STATUS_ERROR_EVENT = BIT(12),
+	STATUS_AXI_INT = BIT(11),
+	STATUS_READ_DATA_AVAILABLE = BIT(7),
+	STATUS_BUSY = BIT(6),
+	STATUS_INIT_DONE = BIT(5),
+};
+
+enum {
+	CONTROL_EVENT_ENABLE_MASK = GENMASK(15, 11),
+	CONTROL_CMD_MASK = GENMASK(3, 0),
+
+	CONTROL_READ_COMPLETE_EVENT_ENABLE = BIT(15),
+	CONTROL_WRITE_COMPLETE_EVENT_ENABLE = BIT(14),
+	CONTROL_TIMEOUT_EVENT_ENABLE = BIT(13),
+	CONTROL_ERROR_EVENT_ENABLE = BIT(12),
+	CONTROL_AXI_INT_ENABLE = BIT(11),
+
+	CONTROL_CMD_NOP = 0x0,
+	CONTROL_CMD_WRITE = 0x8,
+	CONTROL_CMD_WRITE_POST_INC = 0x9,
+	CONTROL_CMD_READ = 0xa,
+	CONTROL_CMD_READ_POST_INC = 0xb,
+
+};
+
+static int axi_transfer(struct udevice *bus, u32 address, u16 cmd,
+			u16 complete_flag)
+{
+	struct ihs_axi_priv *priv = dev_get_priv(bus);
+	struct gdsys_soc_child_platdata *pplat = dev_get_parent_platdata(bus);
+	u16 wait_mask = complete_flag | STATUS_TIMEOUT_EVENT |
+			STATUS_ERROR_EVENT;
+	u16 status;
+	uint k;
+
+	cmd &= CONTROL_CMD_MASK;
+
+	fpga_out_le16(pplat->fpga, priv->addr + REG_ADDRESS_LSB,
+		      address & 0xffff);
+	fpga_out_le16(pplat->fpga, priv->addr + REG_ADDRESS_MSB,
+		      (address >> 16) & 0xffff);
+
+	fpga_out_le16(pplat->fpga, priv->addr + REG_INTERRUPT_STATUS,
+		      wait_mask);
+	fpga_out_le16(pplat->fpga, priv->addr + REG_INTERRUPT_ENABLE_CONTROL,
+		      cmd);
+
+	for (k = 10; k > 0; --k) {
+		status = fpga_in_le16(pplat->fpga,
+				      priv->addr + REG_INTERRUPT_STATUS);
+		if (status & wait_mask)
+			break;
+		udelay(1);
+	}
+
+	if (!k)
+		status = fpga_in_le16(pplat->fpga,
+				      priv->addr + REG_INTERRUPT_STATUS);
+
+	if (status & complete_flag)
+		return 0;
+
+	if (status & STATUS_ERROR_EVENT)
+		return -EIO;
+
+	return -ETIMEDOUT;
+}
+
+int axi_read(struct udevice *dev, u32 address, u32 *data)
+{
+	struct ihs_axi_ops *ops = ihs_axi_get_ops(dev);
+
+	return ops->read(dev, address, data);
+}
+
+int axi_write(struct udevice *dev, u32 address, u32 data)
+{
+	struct ihs_axi_ops *ops = ihs_axi_get_ops(dev);
+
+	return ops->write(dev, address, data);
+}
+
+/*
+ * API
+ */
+
+int ihs_axi_read(struct udevice *dev, u32 address, u32 *data)
+{
+	struct ihs_axi_priv *priv = dev_get_priv(dev);
+	struct gdsys_soc_child_platdata *pplat = dev_get_parent_platdata(dev);
+	int res = 0;
+	u16 data_lsb, data_msb;
+
+	res = axi_transfer(dev, address, CONTROL_CMD_READ,
+			   STATUS_READ_COMPLETE_EVENT);
+	if (res < 0)
+		return res;
+
+	data_lsb = fpga_in_le16(pplat->fpga,
+				priv->addr + REG_READ_DATA_LSB);
+	data_msb = fpga_in_le16(pplat->fpga,
+				priv->addr + REG_READ_DATA_MSB);
+
+	*data = (data_msb << 16) | data_lsb;
+
+	return res;
+}
+
+int ihs_axi_write(struct udevice *dev, u32 address, u32 data)
+{
+	struct ihs_axi_priv *priv = dev_get_priv(dev);
+	struct gdsys_soc_child_platdata *pplat = dev_get_parent_platdata(dev);
+	int res = 0;
+
+	fpga_out_le16(pplat->fpga, priv->addr + REG_READ_DATA_LSB,
+		      data & 0xffff);
+	fpga_out_le16(pplat->fpga, priv->addr + REG_READ_DATA_MSB,
+		      (data >> 16) & 0xffff);
+
+	res = axi_transfer(dev, address, CONTROL_CMD_WRITE,
+			   STATUS_WRITE_COMPLETE_EVENT);
+
+	return res;
+}
+
+UCLASS_DRIVER(ihs_axi) = {
+	.id		= UCLASS_IHS_AXI,
+	.name		= "ihs_axi",
+	.post_bind	= dm_scan_fdt_dev,
+	.flags		= DM_UC_FLAG_SEQ_ALIAS,
+};
+
+static const struct udevice_id ihs_axi_ids[] = {
+	{ .compatible = "gdsys,ihs_axi" },
+	{ /* sentinel */ }
+};
+
+static const struct ihs_axi_ops ihs_axi_ops = {
+	.read = ihs_axi_read,
+	.write = ihs_axi_write,
+};
+
+int ihs_axi_probe(struct udevice *dev)
+{
+	struct ihs_axi_priv *priv = dev_get_priv(dev);
+	struct udevice *child = NULL;
+	int addr;
+
+	addr = fdtdec_get_int(gd->fdt_blob, dev_of_offset(dev), "reg", -1);
+
+	priv->addr = addr;
+
+	for (device_find_first_child(dev, &child);
+	     child;
+	     device_find_next_child(&child))
+		device_probe(child);
+
+	return 0;
+}
+
+U_BOOT_DRIVER(ihs_axi_bus) = {
+	.name           = "ihs_axi_bus",
+	.id             = UCLASS_IHS_AXI,
+	.of_match       = ihs_axi_ids,
+	.ops		= &ihs_axi_ops,
+	.priv_auto_alloc_size = sizeof(struct ihs_axi_priv),
+	.probe          = ihs_axi_probe,
+};
diff --git a/include/dm/uclass-id.h b/include/dm/uclass-id.h
index 8eee8534ab..1a24de10b4 100644
--- a/include/dm/uclass-id.h
+++ b/include/dm/uclass-id.h
@@ -42,6 +42,7 @@ enum uclass_id {
 	UCLASS_I2C_EEPROM,	/* I2C EEPROM device */
 	UCLASS_I2C_GENERIC,	/* Generic I2C device */
 	UCLASS_I2C_MUX,		/* I2C multiplexer */
+	UCLASS_IHS_AXI,		/* gdsys IHS AXI bus */
 	UCLASS_IHS_FPGA,	/* gdsys IHS FPGAs */
 	UCLASS_IRQ,		/* Interrupt controller */
 	UCLASS_KEYBOARD,	/* Keyboard input device */
diff --git a/include/ihs_axi.h b/include/ihs_axi.h
new file mode 100644
index 0000000000..8640d45a0a
--- /dev/null
+++ b/include/ihs_axi.h
@@ -0,0 +1,69 @@
+/*
+ * (C) Copyright 2017
+ * Mario Six,  Guntermann & Drunck GmbH, mario.six at gdsys.cc
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#ifndef _AXI_H_
+#define _AXI_H_
+
+/**
+ * struct ihs_axi_ops - driver operations for IHS AXI 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 ihs_axi_ops {
+	/**
+	 * read() - Read a single 32 bit value from a specified address on a
+	 * 	    IHS AXI bus
+	 *
+	 * @dev:	IHS AXI bus to read from.
+	 * @address:	The address to read from.
+	 * @data:	Pointer to a variable that takes the data value read
+	 * 		from the address on the IHS AXI bus.
+	 * @return 0 if OK, -ve on error.
+	 */
+	int (*read)(struct udevice *dev, u32 address, u32* data);
+
+	/**
+	 * write() - Write a single 32 bit value to a specified address on a
+	 *           IHS AXI bus
+	 *
+	 * @dev:	IHS AXI bus to write to.
+	 * @address:	The address to write to.
+	 * @data:	Data value to be written to the address on the IHS AXI
+	 *              bus.
+	 * @return 0 if OK, -ve on error.
+	 */
+	int (*write)(struct udevice *dev, u32 address, u32 data);
+};
+
+#define ihs_axi_get_ops(dev)	((struct ihs_axi_ops *)(dev)->driver->ops)
+
+/**
+ * axi_read() - Read a single 32 bit value from a specified address on a
+ *              IHS AXI bus
+ *
+ * @dev:	IHS AXI bus to read from.
+ * @address:	The address to read from.
+ * @data:	Pointer to a variable that takes the data value read from the
+ *              address on the IHS AXI bus.
+ * @return 0 if OK, -ve on error.
+ */
+int axi_read(struct udevice *dev, u32 address, u32* data);
+
+/**
+ * axi_write() - Write a single 32 bit value to a specified address on a
+ * 		 IHS AXI bus
+ *
+ * @dev:	IHS AXI bus to write to.
+ * @address:	The address to write to.
+ * @data:	Data value to be written to the address on the IHS AXI bus.
+ * @return 0 if OK, -ve on error.
+ */
+int axi_write(struct udevice *dev, u32 address, u32 data);
+
+#endif
-- 
2.11.0

^ permalink raw reply related	[flat|nested] 138+ messages in thread

* [U-Boot] [PATCH 37/51] drivers: Add ihs_video_out driver
  2017-07-14 12:54 [U-Boot] [PATCH 00/51] gdsys: Add support for Gazerbeam board Mario Six
                   ` (35 preceding siblings ...)
  2017-07-14 12:55 ` [U-Boot] [PATCH 36/51] drivers: Add ihs_axi driver Mario Six
@ 2017-07-14 12:55 ` Mario Six
  2017-07-19  9:06   ` Simon Glass
  2017-07-14 12:55 ` [U-Boot] [PATCH 38/51] gdsys: drivers: Add gdsys_rxaui_ctrl driver Mario Six
                   ` (13 subsequent siblings)
  50 siblings, 1 reply; 138+ messages in thread
From: Mario Six @ 2017-07-14 12:55 UTC (permalink / raw)
  To: u-boot

Add a driver for IHS OSDs on IHS FPGAs.

Signed-off-by: Mario Six <mario.six@gdsys.cc>
---

 drivers/misc/Kconfig         |   6 ++
 drivers/misc/Makefile        |   1 +
 drivers/misc/ihs_video_out.c | 243 +++++++++++++++++++++++++++++++++++++++++++
 include/dm/uclass-id.h       |   1 +
 include/ihs_video_out.h      | 146 ++++++++++++++++++++++++++
 5 files changed, 397 insertions(+)
 create mode 100644 drivers/misc/ihs_video_out.c
 create mode 100644 include/ihs_video_out.h

diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig
index c53f9f195e..c0e4b921b4 100644
--- a/drivers/misc/Kconfig
+++ b/drivers/misc/Kconfig
@@ -209,4 +209,10 @@ config IHS_AXI
 	help
 	  Support for IHS AXI bus.
 
+config IHS_VIDEO_OUT
+	bool "Enable IHS video out driver"
+	depends on MISC
+	help
+	  Support for IHS video out.
+
 endmenu
diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile
index a6c71acedd..eab539b739 100644
--- a/drivers/misc/Makefile
+++ b/drivers/misc/Makefile
@@ -54,3 +54,4 @@ obj-$(CONFIG_QFW) += qfw.o
 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
diff --git a/drivers/misc/ihs_video_out.c b/drivers/misc/ihs_video_out.c
new file mode 100644
index 0000000000..a7e855f054
--- /dev/null
+++ b/drivers/misc/ihs_video_out.c
@@ -0,0 +1,243 @@
+/*
+ * (C) Copyright 2017
+ * Mario Six,  Guntermann & Drunck GmbH, mario.six at gdsys.cc
+ *
+ * based on the gdsys osd driver, which is
+ *
+ * (C) Copyright 2010
+ * Dirk Eibach,  Guntermann & Drunck GmbH, eibach at gdsys.de
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <dm/device-internal.h>
+#include <dm/uclass-internal.h>
+#include <gdsys_soc.h>
+#include <ihs_fpga.h>
+#include <ihs_video_out.h>
+#include <transmitter.h>
+#include <asm/gpio.h>
+
+#include "../transmitter/logicore_dp_tx.h"
+
+DECLARE_GLOBAL_DATA_PTR;
+
+enum {
+	REG_VERSION = 0x00,
+	REG_FEATURES = 0x02,
+	REG_CONTROL = 0x04,
+	REG_XY_SIZE = 0x06,
+	REG_XY_SCALE = 0x08,
+	REG_X_POS = 0x0A,
+	REG_Y_POS = 0x0C,
+};
+
+struct ihs_video_out_priv {
+	int addr;
+	int osd_base;
+	int osd_buffer_base;
+	uint base_width;
+	uint base_height;
+	int sync_src;
+	struct udevice *dp_tx;
+	struct udevice *clk_gen;
+};
+
+UCLASS_DRIVER(ihs_video_out) = {
+	.id		= UCLASS_IHS_VIDEO_OUT,
+	.name		= "ihs_video_out",
+	.flags		= DM_UC_FLAG_SEQ_ALIAS,
+};
+
+static const struct udevice_id ihs_video_out_ids[] = {
+	{ .compatible = "gdsys,ihs_video_out" },
+	{ }
+};
+
+int video_out_get_data(struct udevice *dev, struct ihs_video_out_data *data)
+{
+	struct ihs_video_out_ops *ops = ihs_video_out_get_ops(dev);
+
+	return ops->get_data(dev, data);
+}
+
+int video_out_set_mem(struct udevice *dev, uint x, uint y, u16 *buf,
+		      size_t buflen)
+{
+	struct ihs_video_out_ops *ops = ihs_video_out_get_ops(dev);
+
+	return ops->set_mem(dev, x, y, buf, buflen);
+}
+
+int video_out_set_control(struct udevice *dev, u16 value)
+{
+	struct ihs_video_out_ops *ops = ihs_video_out_get_ops(dev);
+
+	return ops->set_control(dev, value);
+}
+
+int video_out_set_size(struct udevice *dev, u16 xy_size, u16 x_pos, u16 y_pos)
+{
+	struct ihs_video_out_ops *ops = ihs_video_out_get_ops(dev);
+
+	return ops->set_size(dev, xy_size, x_pos, y_pos);
+}
+
+void print_info(struct udevice *dev)
+{
+	struct ihs_video_out_priv *priv = dev_get_priv(dev);
+	struct gdsys_soc_child_platdata *pplat = dev_get_parent_platdata(dev);
+	u16 version;
+	u16 features;
+	u16 control = 0x49;
+
+	version = fpga_in_le16(pplat->fpga, priv->osd_base + REG_VERSION);
+	features = fpga_in_le16(pplat->fpga, priv->osd_base + REG_FEATURES);
+
+	if (priv->sync_src)
+		control |= ((priv->sync_src & 0x7) << 8);
+
+	fpga_out_le16(pplat->fpga, priv->osd_base + REG_CONTROL, control);
+
+	priv->base_width = ((features & 0x3f00) >> 8) + 1;
+	priv->base_height = (features & 0x001f) + 1;
+
+	printf("OSD-%s: Digital-OSD version %01d.%02d, %d x %d characters\n",
+	       dev->name, version / 100, version % 100,
+	       priv->base_width, priv->base_height);
+}
+
+int ihs_video_out_get_data(struct udevice *dev, struct ihs_video_out_data *data)
+{
+	struct ihs_video_out_priv *priv = dev_get_priv(dev);
+
+	data->width = priv->base_width;
+	data->height = priv->base_height;
+
+	return 0;
+}
+
+int ihs_video_out_set_mem(struct udevice *dev, uint x, uint y, u16 *buf,
+			  size_t buflen)
+{
+	struct ihs_video_out_priv *priv = dev_get_priv(dev);
+	struct gdsys_soc_child_platdata *pplat = dev_get_parent_platdata(dev);
+	uint offset = y * priv->base_width + x;
+	uint k;
+
+	for (k = 0; k < buflen; ++k) {
+		if (offset + k >= priv->base_width * priv->base_height)
+			return -ENXIO;
+
+		fpga_out_le16(pplat->fpga,
+			      priv->osd_buffer_base + offset + k, buf[k]);
+	}
+
+	return buflen;
+}
+
+int ihs_video_out_set_control(struct udevice *dev, u16 value)
+{
+	struct ihs_video_out_priv *priv = dev_get_priv(dev);
+	struct gdsys_soc_child_platdata *pplat = dev_get_parent_platdata(dev);
+
+	fpga_out_le16(pplat->fpga, priv->addr + REG_CONTROL, value);
+
+	return 0;
+}
+
+int ihs_video_out_set_size(struct udevice *dev, u16 xy_size,
+			   u16 x_pos, u16 y_pos)
+{
+	struct ihs_video_out_priv *priv = dev_get_priv(dev);
+	struct gdsys_soc_child_platdata *pplat = dev_get_parent_platdata(dev);
+
+	fpga_out_le16(pplat->fpga, priv->addr + REG_XY_SIZE, xy_size);
+	fpga_out_le16(pplat->fpga, priv->addr + REG_X_POS, x_pos);
+	fpga_out_le16(pplat->fpga, priv->addr + REG_Y_POS, y_pos);
+
+	return 0;
+}
+
+static const struct ihs_video_out_ops ihs_video_out_ops = {
+	.get_data = ihs_video_out_get_data,
+	.set_mem = ihs_video_out_set_mem,
+	.set_control = ihs_video_out_set_control,
+	.set_size = ihs_video_out_set_size,
+};
+
+int ihs_video_out_probe(struct udevice *dev)
+{
+	struct ihs_video_out_priv *priv = dev_get_priv(dev);
+	int len = 0;
+	struct fdtdec_phandle_args phandle_args;
+	char *mode;
+
+	priv->addr = fdtdec_get_int(gd->fdt_blob, dev_of_offset(dev),
+				    "reg", -1);
+
+	priv->osd_base = fdtdec_get_int(gd->fdt_blob, dev_of_offset(dev),
+					"osd_base", -1);
+
+	priv->osd_buffer_base = fdtdec_get_int(gd->fdt_blob, dev_of_offset(dev),
+					       "osd_buffer_base", -1);
+
+	priv->sync_src = fdtdec_get_bool(gd->fdt_blob, dev_of_offset(dev),
+			"sync-source");
+
+	print_info(dev);
+
+	if (fdtdec_parse_phandle_with_args(gd->fdt_blob, dev_of_offset(dev),
+					   "clk_gen", NULL, 0, 0,
+					   &phandle_args)) {
+		printf("%s: Could not get clk_gen node.\n", dev->name);
+		return -1;
+	}
+
+	if (device_get_global_by_of_offset(phandle_args.node, &priv->clk_gen)) {
+		printf("%s: Could not get clk_gen dev.\n", dev->name);
+		return -1;
+	}
+
+	if (fdtdec_parse_phandle_with_args(gd->fdt_blob, dev_of_offset(dev),
+					   "dp_tx", NULL, 0, 0,
+					   &phandle_args)) {
+		printf("%s: Could not get dp_tx.\n", dev->name);
+		return -1;
+	}
+
+	if (device_get_global_by_of_offset(phandle_args.node, &priv->dp_tx)) {
+		printf("%s: Could not get dp_tx dev.\n", dev->name);
+		return -1;
+	}
+
+	mode = (char *)fdt_getprop(gd->fdt_blob, dev_of_offset(dev),
+				   "mode", &len);
+
+	if (!mode) {
+		printf("%s: Could not read mode property.\n", dev->name);
+		return -1;
+	}
+
+	if (!strcmp(mode, "1024_768_60"))
+		priv->sync_src = 2;
+	else if (!strcmp(mode, "720_400_70"))
+		priv->sync_src = 1;
+	else
+		priv->sync_src = 0;
+
+	transmitter_power_on(priv->dp_tx, mode);
+
+	return 0;
+}
+
+U_BOOT_DRIVER(ihs_video_out_drv) = {
+	.name           = "ihs_video_out_drv",
+	.id             = UCLASS_IHS_VIDEO_OUT,
+	.ops		= &ihs_video_out_ops,
+	.of_match       = ihs_video_out_ids,
+	.probe          = ihs_video_out_probe,
+	.priv_auto_alloc_size = sizeof(struct ihs_video_out_priv),
+};
diff --git a/include/dm/uclass-id.h b/include/dm/uclass-id.h
index 1a24de10b4..a40185d2bb 100644
--- a/include/dm/uclass-id.h
+++ b/include/dm/uclass-id.h
@@ -44,6 +44,7 @@ enum uclass_id {
 	UCLASS_I2C_MUX,		/* I2C multiplexer */
 	UCLASS_IHS_AXI,		/* gdsys IHS AXI bus */
 	UCLASS_IHS_FPGA,	/* gdsys IHS FPGAs */
+	UCLASS_IHS_VIDEO_OUT,	/* gdsys IHS video output */
 	UCLASS_IRQ,		/* Interrupt controller */
 	UCLASS_KEYBOARD,	/* Keyboard input device */
 	UCLASS_LED,		/* Light-emitting diode (LED) */
diff --git a/include/ihs_video_out.h b/include/ihs_video_out.h
new file mode 100644
index 0000000000..e3dcdad8c5
--- /dev/null
+++ b/include/ihs_video_out.h
@@ -0,0 +1,146 @@
+/*
+ * (C) Copyright 2017
+ * Mario Six,  Guntermann & Drunck GmbH, mario.six at gdsys.cc
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#ifndef _IHS_VIDEO_OUT_H_
+#define _IHS_VIDEO_OUT_H_
+
+/*
+ * The IHS OSD is a character-oriented on-screen display of gdsys devices built
+ * into a IHS FPGA. It is controlled via a set of registers in the FPGA's
+ * register space, as well as a memory buffer that holds character data
+ * (line-wise, left-to-right, 16 bit per character) that constitute the data to
+ * be displayed by the OSD.
+ */
+
+/**
+ * struct ihs_video_out_data - information about a IHS OSD instance
+ *
+ * @width	Maximum width of the OSD screen in characters.
+ * @heigth	Maximum height of the OSD screen in characters.
+ */
+struct ihs_video_out_data {
+	uint width;
+	uint height;
+};
+
+/**
+ * struct ihs_video_out_ops - driver operations for IHS OSD 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 ihs_video_out_ops {
+	/**
+	 * get_data() - Get information about a IHS OSD instance
+	 *
+	 * A IHS OSD instance keeps some internal data about itself. This
+	 * function can be used to access this data.
+	 *
+	 * @dev:	IHS OSD instance to query.
+	 * @data:	Pointer to a struct ihs_video_out_data structure that
+	 * 		takes the information read from the OSD instance.
+	 * @return 0 if OK, -ve on error.
+	 */
+	int (*get_data)(struct udevice *dev, struct ihs_video_out_data *data);
+
+	/**
+	 * set_mem() - Write pixel data to OSD memory
+	 *
+	 * Each 16 bit word of data encodes the display information for a
+	 * single character. The data are written to a given character position
+	 * (x/y coordinates), which are written left-to-right, line-wise,
+	 * continuing to the next line if the data are longer than the current
+	 * line.
+	 *
+	 * @dev:	IHS OSD instance to query.
+	 * @x:		Horizontal character coordinate to write to.
+	 * @y:		Vertical character coordinate to write to.
+	 * @buf:	Array containing 16 bit words to write to the specified
+	 * 		address in the IHS OSD memory.
+	 * @buflen:	Length of the data in the passed buffer (in 16 bit
+	 * 		words).
+	 * @return 0 if OK, -ve on error.
+	 */
+	int (*set_mem)(struct udevice *dev, uint x, uint y, u16 *buf, size_t buflen);
+
+	/**
+	 * set_control() - Set the value of the IHS OSD's control register
+	 *
+	 * @dev:	IHS OSD instance to write to.
+	 * @value:	Value to write to the IHS OSD's control register.
+	 * @return 0 if OK, -ve on error.
+	 */
+	int (*set_control)(struct udevice *dev, u16 value);
+
+	/**
+	 * set_size() - Set the position and dimension of the IHS OSD's
+	 *              writeable window
+	 *
+	 * @dev:	IHS OSD instance to write to.
+	 * @xy_size:	The number of characters in a row and a column,
+	 * 		combined into a 16 bit value.
+	 * @x_pos:	The horizontal position of the upper left corner of the
+	 * 		OSD's writeable window in pixels.
+	 * @y_pos:	The vertical position of the upper left corner of the
+	 * 		OSD's writeable window in pixels.
+	 * @return 0 if OK, -ve on error.
+	 */
+	int (*set_size)(struct udevice *dev, u16 xy_size, u16 x_pos, u16 y_pos);
+};
+
+#define ihs_video_out_get_ops(dev)	((struct ihs_video_out_ops *)(dev)->driver->ops)
+
+/**
+ * video_out_get_data() - Get information about a IHS OSD instance
+ *
+ * @dev:	IHS OSD instance to query.
+ * @data:	Pointer to a struct ihs_video_out_data structure that takes the
+ * 		information read from the OSD instance.
+ * @return 0 if OK, -ve on error.
+ */
+int video_out_get_data(struct udevice *dev, struct ihs_video_out_data *data);
+
+/**
+ * video_out_set_mem() - Write pixel data to OSD memory
+ *
+ * @dev:	IHS OSD instance to query.
+ * @x:		Horizontal character coordinate to write to.
+ * @y:		Vertical character coordinate to write to.
+ * @buf:	Array containing 16 bit words to write to the specified address
+ * 		in the IHS OSD memory.
+ * @buflen:	Length of the data in the passed buffer (in 16 bit words).
+ * @return 0 if OK, -ve on error.
+ */
+int video_out_set_mem(struct udevice *dev, uint x, uint y, u16 *buf,
+		      size_t buflen);
+
+/**
+ * video_out_set_control() - Set the value of the IHS OSD's control register
+ *
+ * @dev:	IHS OSD instance to write to.
+ * @value:	Value to write to the IHS OSD's control register.
+ * @return 0 if OK, -ve on error.
+ */
+int video_out_set_control(struct udevice *dev, u16 value);
+
+/**
+ * video_out_set_size() - Set the position and dimension of the IHS OSD's
+ * 			  writeable window
+ *
+ * @dev:	IHS OSD instance to write to.
+ * @xy_size:	The number of characters in a row and a column, combined into a
+ * 		16 bit value.
+ * @x_pos:	The horizontal position of the upper left corner of the OSD's
+ * 		writeable window in pixels.
+ * @y_pos:	The vertical position of the upper left corner of the OSD's
+ * 		writeable window in pixels.
+ * @return 0 if OK, -ve on error.
+ */
+int video_out_set_size(struct udevice *dev, u16 xy_size, u16 x_pos, u16 y_pos);
+
+#endif /* !_IHS_VIDEO_OUT_H_ */
-- 
2.11.0

^ permalink raw reply related	[flat|nested] 138+ messages in thread

* [U-Boot] [PATCH 38/51] gdsys: drivers: Add gdsys_rxaui_ctrl driver
  2017-07-14 12:54 [U-Boot] [PATCH 00/51] gdsys: Add support for Gazerbeam board Mario Six
                   ` (36 preceding siblings ...)
  2017-07-14 12:55 ` [U-Boot] [PATCH 37/51] drivers: Add ihs_video_out driver Mario Six
@ 2017-07-14 12:55 ` Mario Six
  2017-07-19  9:06   ` Simon Glass
  2017-07-14 12:55 ` [U-Boot] [PATCH 39/51] drivers: Add gdsys_ioep driver Mario Six
                   ` (12 subsequent siblings)
  50 siblings, 1 reply; 138+ messages in thread
From: Mario Six @ 2017-07-14 12:55 UTC (permalink / raw)
  To: u-boot

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 at gdsys.de
+ *
+ * (C) Copyright 2017
+ * Mario Six,  Guntermann & Drunck GmbH, mario.six at 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 at 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_ */
-- 
2.11.0

^ permalink raw reply related	[flat|nested] 138+ messages in thread

* [U-Boot] [PATCH 39/51] drivers: Add gdsys_ioep driver
  2017-07-14 12:54 [U-Boot] [PATCH 00/51] gdsys: Add support for Gazerbeam board Mario Six
                   ` (37 preceding siblings ...)
  2017-07-14 12:55 ` [U-Boot] [PATCH 38/51] gdsys: drivers: Add gdsys_rxaui_ctrl driver Mario Six
@ 2017-07-14 12:55 ` Mario Six
  2017-07-19  9:06   ` Simon Glass
  2017-07-14 12:55 ` [U-Boot] [PATCH 40/51] cmd: Add ihs osd commands Mario Six
                   ` (11 subsequent siblings)
  50 siblings, 1 reply; 138+ messages in thread
From: Mario Six @ 2017-07-14 12:55 UTC (permalink / raw)
  To: u-boot

Add driver for the IHS IO endpoint on IHS FPGAs.

Signed-off-by: Mario Six <mario.six@gdsys.cc>
---

 drivers/misc/Kconfig      |   6 +
 drivers/misc/Makefile     |   1 +
 drivers/misc/gdsys_ioep.c | 301 ++++++++++++++++++++++++++++++++++++++++++++++
 include/dm/uclass-id.h    |   1 +
 include/gdsys_ioep.h      | 196 ++++++++++++++++++++++++++++++
 5 files changed, 505 insertions(+)
 create mode 100644 drivers/misc/gdsys_ioep.c
 create mode 100644 include/gdsys_ioep.h

diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig
index dd768e2a7a..f8885380d0 100644
--- a/drivers/misc/Kconfig
+++ b/drivers/misc/Kconfig
@@ -221,4 +221,10 @@ config GDSYS_RXAUI_CTRL
 	help
 	  Support gdsys FPGA's RXAUI control.
 
+config GDSYS_IOEP
+	bool "Enable gdsys IOEP driver"
+	depends on MISC
+	help
+	  Support gdsys FPGA's IO endpoint driver.
+
 endmenu
diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile
index 3ff9e66da2..40788c9acc 100644
--- a/drivers/misc/Makefile
+++ b/drivers/misc/Makefile
@@ -56,3 +56,4 @@ 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
+obj-$(CONFIG_GDSYS_IOEP) += gdsys_ioep.o
diff --git a/drivers/misc/gdsys_ioep.c b/drivers/misc/gdsys_ioep.c
new file mode 100644
index 0000000000..5bf1796a40
--- /dev/null
+++ b/drivers/misc/gdsys_ioep.c
@@ -0,0 +1,301 @@
+/*
+ * (C) Copyright 2017
+ * Mario Six,  Guntermann & Drunck GmbH, mario.six at gdsys.cc
+ *
+ * based on the cmd_ioloop driver/command, which is
+ *
+ * (C) Copyright 2014
+ * Dirk Eibach, Guntermann & Drunck GmbH, dirk.eibach at gdsys.cc
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <gdsys_soc.h>
+#include <ihs_fpga.h>
+#include <gdsys_ioep.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+enum {
+	REG_TRANSMIT_DATA = 0x0,
+	REG_TX_CONTROL = 0x2,
+	REG_RECEIVE_DATA = 0x4,
+	REG_RX_TX_STATUS = 0x6,
+	REG_DEVICE_ADDRESS = 0xA,
+	REG_TARGET_ADDRESS = 0xC,
+	REG_INT_ENABLE = 0xE,
+};
+
+enum {
+	STATE_TX_PACKET_BUILDING = BIT(0),
+	STATE_TX_TRANSMITTING = BIT(1),
+	STATE_TX_BUFFER_FULL = BIT(2),
+	STATE_TX_ERR = BIT(3),
+	STATE_RECEIVE_TIMEOUT = BIT(4),
+	STATE_PROC_RX_STORE_TIMEOUT = BIT(5),
+	STATE_PROC_RX_RECEIVE_TIMEOUT = BIT(6),
+	STATE_RX_DIST_ERR = BIT(7),
+	STATE_RX_LENGTH_ERR = BIT(8),
+	STATE_RX_FRAME_CTR_ERR = BIT(9),
+	STATE_RX_FCS_ERR = BIT(10),
+	STATE_RX_PACKET_DROPPED = BIT(11),
+	STATE_RX_DATA_LAST = BIT(12),
+	STATE_RX_DATA_FIRST = BIT(13),
+	STATE_RX_DATA_AVAILABLE = BIT(15),
+};
+
+enum {
+	CTRL_PROC_RECEIVE_ENABLE = BIT(12),
+	CTRL_FLUSH_TRANSMIT_BUFFER = BIT(15),
+};
+
+enum {
+	IRQ_CPU_TRANSMITBUFFER_FREE_STATUS = BIT(5),
+	IRQ_CPU_PACKET_TRANSMITTED_EVENT = BIT(6),
+	IRQ_NEW_CPU_PACKET_RECEIVED_EVENT = BIT(7),
+	IRQ_CPU_RECEIVE_DATA_AVAILABLE_STATUS = BIT(8),
+};
+
+struct gdsys_ioep_priv {
+	int addr;
+};
+
+int ioep_enable_receive(struct udevice *dev)
+{
+	struct ioep_ops *ops = ioep_get_ops(dev);
+
+	return ops->enable_receive(dev);
+}
+
+int ioep_disable_receive(struct udevice *dev)
+{
+	struct ioep_ops *ops = ioep_get_ops(dev);
+
+	return ops->disable_receive(dev);
+}
+
+int ioep_send(struct udevice *dev, struct io_generic_packet *header, u16 *data)
+{
+	struct ioep_ops *ops = ioep_get_ops(dev);
+
+	return ops->send(dev, header, data);
+}
+
+int ioep_receive(struct udevice *dev, struct io_generic_packet *header,
+		 u16 *data)
+{
+	struct ioep_ops *ops = ioep_get_ops(dev);
+
+	return ops->receive(dev, header, data);
+}
+
+int ioep_set_address(struct udevice *dev, u16 addr)
+{
+	struct ioep_ops *ops = ioep_get_ops(dev);
+
+	return ops->set_address(dev, addr);
+}
+
+bool ioep_data_available(struct udevice *dev)
+{
+	struct ioep_ops *ops = ioep_get_ops(dev);
+
+	return ops->data_available(dev);
+}
+
+int ioep_reset_status(struct udevice *dev, bool print_status)
+{
+	struct ioep_ops *ops = ioep_get_ops(dev);
+
+	return ops->reset_status(dev, print_status);
+}
+
+UCLASS_DRIVER(ioep) = {
+	.id		= UCLASS_IOEP,
+	.name		= "ioep",
+	.flags		= DM_UC_FLAG_SEQ_ALIAS,
+};
+
+int gdsys_ioep_enable_receive(struct udevice *dev)
+{
+	struct gdsys_ioep_priv *priv = dev_get_priv(dev);
+	struct gdsys_soc_child_platdata *pplat = dev_get_parent_platdata(dev);
+
+	fpga_out_le16(pplat->fpga, priv->addr + REG_TX_CONTROL,
+		      CTRL_PROC_RECEIVE_ENABLE);
+
+	return 0;
+}
+
+int gdsys_ioep_disable_receive(struct udevice *dev)
+{
+	struct gdsys_ioep_priv *priv = dev_get_priv(dev);
+	struct gdsys_soc_child_platdata *pplat = dev_get_parent_platdata(dev);
+
+	fpga_out_le16(pplat->fpga, priv->addr + REG_TX_CONTROL,
+		      ~CTRL_PROC_RECEIVE_ENABLE);
+
+	return 0;
+}
+
+int gdsys_ioep_send(struct udevice *dev, struct io_generic_packet *header,
+		    u16 *data)
+{
+	struct gdsys_ioep_priv *priv = dev_get_priv(dev);
+	struct gdsys_soc_child_platdata *pplat = dev_get_parent_platdata(dev);
+	int k;
+	u16 *p;
+
+	p = (u16 *)header;
+
+	for (k = 0; k < sizeof(struct io_generic_packet) / 2; ++k)
+		fpga_out_le16(pplat->fpga,
+			      priv->addr + REG_TRANSMIT_DATA, *p++);
+
+	p = (u16 *)data;
+
+	for (k = 0; k < (header->packet_length + 1) / 2; ++k)
+		fpga_out_le16(pplat->fpga,
+			      priv->addr + REG_TRANSMIT_DATA, *p++);
+
+	fpga_out_le16(pplat->fpga, priv->addr + REG_TX_CONTROL,
+		      CTRL_PROC_RECEIVE_ENABLE | CTRL_FLUSH_TRANSMIT_BUFFER);
+
+	return 0;
+}
+
+int receive_byte_buffer(struct udevice *dev, uint len, u16 *buffer)
+{
+	struct gdsys_ioep_priv *priv = dev_get_priv(dev);
+	struct gdsys_soc_child_platdata *pplat = dev_get_parent_platdata(dev);
+	int k;
+	int res = -EIO;
+
+	for (k = 0; k < len; ++k) {
+		u16 rx_tx_status;
+
+		*buffer++ = fpga_in_le16(pplat->fpga,
+				    priv->addr + REG_RECEIVE_DATA);
+
+		rx_tx_status = fpga_in_le16(pplat->fpga,
+					    priv->addr + REG_RX_TX_STATUS);
+		if (k == len && rx_tx_status & STATE_RX_DATA_LAST)
+			res = 0;
+	}
+
+	return res;
+}
+
+int gdsys_ioep_receive(struct udevice *dev, struct io_generic_packet *header,
+		       u16 *data)
+{
+	int res1, res2;
+	u16 *p = (u16 *)header;
+
+	res1 = receive_byte_buffer(dev,
+				   sizeof(struct io_generic_packet) / 2, p);
+
+	if (!res1)
+		res2 = receive_byte_buffer(dev, header->packet_length + 1,
+					   data);
+
+	return res1 ? res1 : res2;
+}
+
+int gdsys_ioep_set_address(struct udevice *dev, u16 addr)
+{
+	struct gdsys_ioep_priv *priv = dev_get_priv(dev);
+	struct gdsys_soc_child_platdata *pplat = dev_get_parent_platdata(dev);
+
+	/* Set device address */
+	fpga_out_le16(pplat->fpga, priv->addr + REG_DEVICE_ADDRESS, addr);
+
+	return 0;
+}
+
+bool gdsys_ioep_data_available(struct udevice *dev)
+{
+	struct gdsys_ioep_priv *priv = dev_get_priv(dev);
+	struct gdsys_soc_child_platdata *pplat = dev_get_parent_platdata(dev);
+	u16 rx_tx_status;
+
+	rx_tx_status = fpga_in_le16(pplat->fpga, priv->addr + REG_RX_TX_STATUS);
+
+	return rx_tx_status & STATE_RX_DATA_AVAILABLE;
+}
+
+int gdsys_ioep_reset_status(struct udevice *dev, bool print_status)
+{
+	struct gdsys_ioep_priv *priv = dev_get_priv(dev);
+	struct gdsys_soc_child_platdata *pplat = dev_get_parent_platdata(dev);
+	u16 mask = STATE_RX_DIST_ERR | STATE_RX_LENGTH_ERR |
+		   STATE_RX_FRAME_CTR_ERR | STATE_RX_FCS_ERR |
+		   STATE_RX_PACKET_DROPPED | STATE_TX_ERR;
+
+	u16 status = fpga_in_le16(pplat->fpga, priv->addr + REG_RX_TX_STATUS);
+
+	if (!(status & mask)) {
+		fpga_out_le16(pplat->fpga, priv->addr + REG_RX_TX_STATUS,
+			      status);
+		return 0;
+	}
+
+	fpga_out_le16(pplat->fpga, priv->addr + REG_RX_TX_STATUS, status);
+
+	if (!print_status)
+		return 1;
+
+	if (status & STATE_RX_PACKET_DROPPED)
+		printf("RX_PACKET_DROPPED, status %04x\n", status);
+
+	if (status & STATE_RX_DIST_ERR)
+		printf("RX_DIST_ERR\n");
+	if (status & STATE_RX_LENGTH_ERR)
+		printf("RX_LENGTH_ERR\n");
+	if (status & STATE_RX_FRAME_CTR_ERR)
+		printf("RX_FRAME_CTR_ERR\n");
+	if (status & STATE_RX_FCS_ERR)
+		printf("RX_FCS_ERR\n");
+
+	if (status & STATE_TX_ERR)
+		printf("TX_ERR\n");
+
+	return 1;
+}
+
+static const struct ioep_ops gdsys_ioep_ops = {
+	.enable_receive = gdsys_ioep_enable_receive,
+	.disable_receive = gdsys_ioep_disable_receive,
+	.send = gdsys_ioep_send,
+	.receive = gdsys_ioep_receive,
+	.set_address = gdsys_ioep_set_address,
+	.data_available = gdsys_ioep_data_available,
+	.reset_status = gdsys_ioep_reset_status,
+};
+
+int gdsys_ioep_probe(struct udevice *dev)
+{
+	struct gdsys_ioep_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_ioep_ids[] = {
+	{ .compatible = "gdsys,io-endpoint" },
+	{ }
+};
+
+U_BOOT_DRIVER(gdsys_ioep) = {
+	.name           = "gdsys_ioep",
+	.id             = UCLASS_IOEP,
+	.ops		= &gdsys_ioep_ops,
+	.flags		= DM_UC_FLAG_SEQ_ALIAS,
+	.of_match       = gdsys_ioep_ids,
+	.probe          = gdsys_ioep_probe,
+	.priv_auto_alloc_size = sizeof(struct gdsys_ioep_priv),
+};
diff --git a/include/dm/uclass-id.h b/include/dm/uclass-id.h
index 35e478cc74..7bf8857799 100644
--- a/include/dm/uclass-id.h
+++ b/include/dm/uclass-id.h
@@ -45,6 +45,7 @@ enum uclass_id {
 	UCLASS_IHS_AXI,		/* gdsys IHS AXI bus */
 	UCLASS_IHS_FPGA,	/* gdsys IHS FPGAs */
 	UCLASS_IHS_VIDEO_OUT,	/* gdsys IHS video output */
+	UCLASS_IOEP,		/* gdsys IHS IO endpoint */
 	UCLASS_IRQ,		/* Interrupt controller */
 	UCLASS_KEYBOARD,	/* Keyboard input device */
 	UCLASS_LED,		/* Light-emitting diode (LED) */
diff --git a/include/gdsys_ioep.h b/include/gdsys_ioep.h
new file mode 100644
index 0000000000..6edf44d528
--- /dev/null
+++ b/include/gdsys_ioep.h
@@ -0,0 +1,196 @@
+/*
+ * (C) Copyright 2017
+ * Mario Six,  Guntermann & Drunck GmbH, mario.six at gdsys.cc
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#ifndef _GDSYS_IOEP_CTRL_H_
+#define _GDSYS_IOEP_CTRL_H_
+
+/**
+ * The GDSYS IO endpoint is a IHS FPGA interface used by gdsys devices to send
+ * and receive special data packets via a proprietary protocol.
+ */
+
+/**
+ * struct io_generic_packet - header structure for GDSYS IOEP packets
+ *
+ * @target_address:	Target protocol address of the packet.
+ * @source_address:	Source protocol address of the packet.
+ * @packet_type:	Packet type.
+ * @bc:			Block counter (filled in by FPGA).
+ * @packet_length:	Length of the packet's payload in 16 bit words.
+ */
+struct io_generic_packet {
+	u16 target_address;
+	u16 source_address;
+	u8 packet_type;
+	u8 bc;
+	u16 packet_length;
+} __attribute__((__packed__));
+
+/**
+ * struct ioep_ops - driver operations for GDSYS IOEP 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 ioep_ops {
+	/**
+	 * enable_receive() - Enable the receive path of a given GDSYS IOEP
+	 * 		      instance
+	 *
+	 * @dev:	GDSYS IOEP instance to use.
+	 * @return 0 if OK, -ve on error.
+	 */
+	int (*enable_receive)(struct udevice *dev);
+
+	/**
+	 * disable_receive() - Disable the receive path of a given GDSYS IOEP
+	 * 		       instance
+	 *
+	 * @dev:	GDSYS IOEP instance to use.
+	 * @return 0 if OK, -ve on error.
+	 */
+	int (*disable_receive)(struct udevice *dev);
+
+	/**
+	 * send() - Send a data packet through the GDSYS IOEP instance
+	 *
+	 * @dev:	GDSYS IOEP instance to use.
+	 * @header:	Header data for the packet to send (have to be filled
+	 * 		before calling this method).
+	 * @data:	Payload data for the packet as an array of 16 bit
+	 * 		values.
+	 * @return 0 if OK, -ve on error.
+	 */
+	int (*send)(struct udevice *dev, struct io_generic_packet *header,
+		    u16 *data);
+
+	/**
+	 * receive() - Receive a data packet through the GDSYS IOEP instance
+	 *
+	 * @dev:	GDSYS IOEP instance to use.
+	 * @header:	A pointer to a header data structure, which is filled
+	 * 		with the data from the received packet.
+	 * @data:	A pointer to a 16 bit array, which receives the payload
+	 * 		data from the received packet (must be large enough for
+	 * 		the data).
+	 * @return 0 if OK, -ve on error.
+	 */
+	int (*receive)(struct udevice *dev, struct io_generic_packet *header,
+		       u16 *data);
+
+	/**
+	 * set_address() - Set the protocol address for this GDSYS IOEP
+	 * 		   instance
+	 *
+	 * @dev:	GDSYS IOEP instance to use.
+	 * @addr:	The address to set (a 16 bit value)
+	 * @return 0 if OK, -ve on error.
+	 */
+	int (*set_address)(struct udevice *dev, u16 addr);
+
+	/**
+	 * data_available() - Check if a packet can be read from thie GDSYS
+	 * 		      IOEP instance.
+	 *
+	 * The packet can be read via the receive() method.
+	 *
+	 * @dev:	GDSYS IOEP instance to use.
+	 * @return true is a package can be read, false if not.
+	 */
+	bool (*data_available)(struct udevice *dev);
+
+	/**
+	 * reset_status() - Reset the error status of a GDSYS IOEP instance
+	 *
+	 * The error status *prior* to the status reset may optionally be
+	 * printed.
+	 *
+	 * @dev:		GDSYS IOEP instance to use.
+	 * @print_status:	Flag that, if set, makes the function print the
+	 * 			error status prior to resetting.
+	 * @return 0 if the instance was signalling an error prior to reset, 1
+	 *  if no error was signaled.
+	 */
+	int (*reset_status)(struct udevice *dev, bool print_status);
+};
+
+#define ioep_get_ops(dev)	((struct ioep_ops *)(dev)->driver->ops)
+
+/**
+ * ioep_enable_receive() - Enable the receive path of a given GDSYS IOEP
+ * 			   instance
+ *
+ * @dev:	GDSYS IOEP instance to use.
+ * @return 0 if OK, -ve on error.
+ */
+int ioep_enable_receive(struct udevice *dev);
+
+/**
+ * ioep_disable_receive() - Disable the receive path of a given GDSYS IOEP
+ * 			    instance
+ *
+ * @dev:	GDSYS IOEP instance to use.
+ * @return 0 if OK, -ve on error.
+ */
+int ioep_disable_receive(struct udevice *dev);
+
+/**
+ * ioep_send() - Send a data packet through the GDSYS IOEP instance
+ *
+ * @dev:	GDSYS IOEP instance to use.
+ * @header:	Header data for the packet to send (have to be filled before
+ * 		calling this method).
+ * @data:	Payload data for the packet as an array of 16 bit values.
+ * @return 0 if OK, -ve on error.
+ */
+int ioep_send(struct udevice *dev, struct io_generic_packet *header,
+	      u16 *data);
+
+/**
+ * ioep_receive() - Receive a data packet through the GDSYS IOEP instance
+ *
+ * @dev:	GDSYS IOEP instance to use.
+ * @header:	A pointer to a header data structure, which is filled with the
+ * 		data from the received packet.
+ * @data:	A pointer to a 16 bit array, which receives the payload data
+ * 		from the received packet (must be large enough for the data).
+ * @return 0 if OK, -ve on error.
+ */
+int ioep_receive(struct udevice *dev, struct io_generic_packet *header,
+		 u16 *data);
+
+/**
+ * ioep_set_address() - Set the protocol address for this GDSYS IOEP instance
+ *
+ * @dev:	GDSYS IOEP instance to use.
+ * @addr:	The address to set (a 16 bit value)
+ * @return 0 if OK, -ve on error.
+ */
+int ioep_set_address(struct udevice *dev, u16 addr);
+
+/**
+ * ioep_data_available() - Check if a packet can be read from thie GDSYS IOEP
+ * 			   instance.
+ *
+ * @dev:	GDSYS IOEP instance to use.
+ * @return true is a package can be read, false if not.
+ */
+bool ioep_data_available(struct udevice *dev);
+
+/**
+ * ioep_reset_status() - Reset the error status of a GDSYS IOEP instance
+ *
+ * @dev:		GDSYS IOEP instance to use.
+ * @print_status:	Flag that, if set, makes the function print the
+ * 			error status prior to resetting.
+ * @return 0 if the instance was signalling an error prior to reset, 1
+ *  if no error was signaled.
+ */
+int ioep_reset_status(struct udevice *dev, bool print_status);
+
+#endif /* _GDSYS_IOEP_CTRL_H_ */
-- 
2.11.0

^ permalink raw reply related	[flat|nested] 138+ messages in thread

* [U-Boot] [PATCH 40/51] cmd: Add ihs osd commands
  2017-07-14 12:54 [U-Boot] [PATCH 00/51] gdsys: Add support for Gazerbeam board Mario Six
                   ` (38 preceding siblings ...)
  2017-07-14 12:55 ` [U-Boot] [PATCH 39/51] drivers: Add gdsys_ioep driver Mario Six
@ 2017-07-14 12:55 ` Mario Six
  2017-07-19  9:06   ` Simon Glass
  2017-07-14 12:55 ` [U-Boot] [PATCH 41/51] cmd: Add ihs axi command Mario Six
                   ` (10 subsequent siblings)
  50 siblings, 1 reply; 138+ messages in thread
From: Mario Six @ 2017-07-14 12:55 UTC (permalink / raw)
  To: u-boot

Add command to query information from and write text to IHS OSDs.

Signed-off-by: Mario Six <mario.six@gdsys.cc>
---

 cmd/Kconfig   |   6 +++
 cmd/Makefile  |   1 +
 cmd/ihs_osd.c | 167 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 174 insertions(+)
 create mode 100644 cmd/ihs_osd.c

diff --git a/cmd/Kconfig b/cmd/Kconfig
index 6425c425d6..b632049022 100644
--- a/cmd/Kconfig
+++ b/cmd/Kconfig
@@ -933,6 +933,12 @@ config CMD_DISPLAY
 	  displayed on a simple board-specific display. Implement
 	  display_putc() to use it.
 
+config CMD_IHS_OSD
+	bool "ihs osd"
+	help
+	  Enable the 'osd' command which allows to query information from and
+	  write text data to a gdsys OSD.
+
 config CMD_LED
 	bool "led"
 	default y if LED
diff --git a/cmd/Makefile b/cmd/Makefile
index 243f9f45d4..c30511982b 100644
--- a/cmd/Makefile
+++ b/cmd/Makefile
@@ -62,6 +62,7 @@ obj-$(CONFIG_CMD_FS_GENERIC) += fs.o
 obj-$(CONFIG_CMD_FUSE) += fuse.o
 obj-$(CONFIG_CMD_GETTIME) += gettime.o
 obj-$(CONFIG_CMD_GPIO) += gpio.o
+obj-$(CONFIG_CMD_IHS_OSD) += ihs_osd.o
 obj-$(CONFIG_CMD_I2C) += i2c.o
 obj-$(CONFIG_CMD_IOTRACE) += iotrace.o
 obj-$(CONFIG_CMD_HASH) += hash.o
diff --git a/cmd/ihs_osd.c b/cmd/ihs_osd.c
new file mode 100644
index 0000000000..01ef3eee83
--- /dev/null
+++ b/cmd/ihs_osd.c
@@ -0,0 +1,167 @@
+/*
+ * (C) Copyright 2017
+ * Mario Six,  Guntermann & Drunck GmbH, mario.six at gdsys.cc
+ *
+ * based on the gdsys osd driver, which is
+ *
+ * (C) Copyright 2010
+ * Dirk Eibach,  Guntermann & Drunck GmbH, eibach at gdsys.de
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <dm/uclass-internal.h>
+#include <i2c.h>
+#include <ihs_video_out.h>
+#include <malloc.h>
+
+#define MAX_VIDEOMEM_WIDTH 64
+#define MAX_VIDEOMEM_HEIGHT 32
+#define MAX_X_CHARS 53
+#define MAX_Y_CHARS 26
+
+size_t hexstr_to_u16_array(char *hexstr, u16 *array, size_t arrsize)
+{
+	size_t pos;
+
+	for (pos = 0; pos < arrsize; ++pos) {
+		char substr[5];
+
+		memcpy(substr, hexstr, 4);
+		substr[4] = 0;
+		*array = simple_strtoul(substr, NULL, 16);
+
+		hexstr += 4;
+		array++;
+		if (*hexstr == 0)
+			break;
+	}
+
+	return pos;
+}
+
+int do_osd_write(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
+{
+	struct udevice *dev;
+	uint x, y;
+	uint count;
+	char *hexstr;
+	u16 buffer[MAX_VIDEOMEM_WIDTH];
+	size_t buflen;
+
+	if ((argc < 4) || (strlen(argv[3]) % 4)) {
+		cmd_usage(cmdtp);
+		return 1;
+	}
+
+	x = simple_strtoul(argv[1], NULL, 16);
+	y = simple_strtoul(argv[2], NULL, 16);
+	hexstr = argv[3];
+	count = (argc > 4) ? simple_strtoul(argv[4], NULL, 16) : 1;
+
+	buflen = hexstr_to_u16_array(hexstr, buffer, MAX_VIDEOMEM_WIDTH);
+
+	for (uclass_find_first_device(UCLASS_IHS_VIDEO_OUT, &dev);
+	     dev;
+	     uclass_find_next_device(&dev)) {
+		uint k;
+
+		for (k = 0; k < count; ++k)
+			video_out_set_mem(dev, x + k * buflen, y, buffer,
+					  buflen);
+
+		video_out_set_control(dev, 0x0049);
+	}
+
+	return 0;
+}
+
+static int do_osd_print(cmd_tbl_t *cmdtp, int flag, int argc,
+			char * const argv[])
+{
+	struct udevice *dev;
+	u16 buffer[MAX_VIDEOMEM_WIDTH];
+	uint x, y, charcount, len;
+	u8 color;
+	uint k;
+	char *text;
+
+	if (argc < 5) {
+		cmd_usage(cmdtp);
+		return 1;
+	}
+
+	x = simple_strtoul(argv[1], NULL, 16);
+	y = simple_strtoul(argv[2], NULL, 16);
+	color = simple_strtoul(argv[3], NULL, 16);
+	text = argv[4];
+	charcount = strlen(text);
+	len = min(charcount, (uint)MAX_VIDEOMEM_WIDTH);
+
+	for (uclass_find_first_device(UCLASS_IHS_VIDEO_OUT, &dev);
+	     dev;
+	     uclass_find_next_device(&dev)) {
+		int res;
+
+		for (k = 0; k < len; ++k)
+			buffer[k] = (text[k] << 8) | color;
+
+		res = video_out_set_mem(dev, x, y, buffer, len);
+
+		if (res < 0)
+			return res;
+
+		video_out_set_control(dev, 0x0049);
+	}
+
+	return 0;
+}
+
+int do_osd_size(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
+{
+	struct udevice *dev;
+	uint x, y;
+
+	if (argc < 3) {
+		cmd_usage(cmdtp);
+		return 1;
+	}
+
+	x = simple_strtoul(argv[1], NULL, 16);
+	y = simple_strtoul(argv[2], NULL, 16);
+
+	if (!x || (x > 64) || (x > MAX_X_CHARS) ||
+	    !y || (y > 32) || (y > MAX_Y_CHARS)) {
+		cmd_usage(cmdtp);
+		return 1;
+	}
+
+	for (uclass_find_first_device(UCLASS_IHS_VIDEO_OUT, &dev);
+	     dev;
+	     uclass_find_next_device(&dev))
+		video_out_set_size(dev, ((x - 1) << 8) | (y - 1),
+				   32767 * (640 - 12 * x) / 65535,
+				   32767 * (480 - 18 * x) / 65535);
+
+	return 0;
+}
+
+U_BOOT_CMD(
+	osdw, 5, 0, do_osd_write,
+	"write 16-bit hex encoded buffer to osd memory",
+	"osd write [pos_x] [pos_y] [buffer] [count] - write 16-bit hex encoded buffer to osd memory\n"
+);
+
+U_BOOT_CMD(
+	osdp, 5, 0, do_osd_print,
+	"write ASCII buffer to osd memory",
+	"osd print [pos_x] [pos_y] [color] [text] - write ASCII buffer to osd memory\n"
+);
+
+U_BOOT_CMD(
+	osdsize, 3, 0, do_osd_size,
+	"set OSD XY size in characters",
+	"osd size [size_x] [size_y] - set OSD XY size in characters\n"
+);
-- 
2.11.0

^ permalink raw reply related	[flat|nested] 138+ messages in thread

* [U-Boot] [PATCH 41/51] cmd: Add ihs axi command
  2017-07-14 12:54 [U-Boot] [PATCH 00/51] gdsys: Add support for Gazerbeam board Mario Six
                   ` (39 preceding siblings ...)
  2017-07-14 12:55 ` [U-Boot] [PATCH 40/51] cmd: Add ihs osd commands Mario Six
@ 2017-07-14 12:55 ` Mario Six
  2017-07-19  9:06   ` Simon Glass
  2017-07-14 12:55 ` [U-Boot] [PATCH 42/51] cmd: Add ihs fpga command Mario Six
                   ` (9 subsequent siblings)
  50 siblings, 1 reply; 138+ messages in thread
From: Mario Six @ 2017-07-14 12:55 UTC (permalink / raw)
  To: u-boot

Add a command to debug the IHS AXI bus.

Signed-off-by: Mario Six <mario.six@gdsys.cc>
---

 cmd/Kconfig   |   5 ++
 cmd/Makefile  |   2 +
 cmd/ihs_axi.c | 257 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 264 insertions(+)
 create mode 100644 cmd/ihs_axi.c

diff --git a/cmd/Kconfig b/cmd/Kconfig
index b632049022..4bbe9d435c 100644
--- a/cmd/Kconfig
+++ b/cmd/Kconfig
@@ -753,6 +753,11 @@ config CMD_SATA
 	  Attachment, where AT refers to an IBM AT (Advanced Technology)
 	  computer released in 1984.
 
+config CMD_IHS_AXI
+	bool "axi"
+	help
+	  Enable the GDSYS IHS AXI command for accessing the AXI bus.
+
 endmenu
 
 
diff --git a/cmd/Makefile b/cmd/Makefile
index c30511982b..0baaf76b47 100644
--- a/cmd/Makefile
+++ b/cmd/Makefile
@@ -144,6 +144,8 @@ obj-$(CONFIG_CMD_DFU) += dfu.o
 obj-$(CONFIG_CMD_GPT) += gpt.o
 obj-$(CONFIG_CMD_ETHSW) += ethsw.o
 
+obj-$(CONFIG_CMD_IHS_AXI) += ihs_axi.o
+
 # Power
 obj-$(CONFIG_CMD_PMIC) += pmic.o
 obj-$(CONFIG_CMD_REGULATOR) += regulator.o
diff --git a/cmd/ihs_axi.c b/cmd/ihs_axi.c
new file mode 100644
index 0000000000..336c239fae
--- /dev/null
+++ b/cmd/ihs_axi.c
@@ -0,0 +1,257 @@
+/*
+ * (C) Copyright 2016
+ * Dirk Eibach,  Guntermann & Drunck GmbH, dirk.eibach at gdsys.cc
+ *
+ * (C) Copyright 2017
+ * Mario Six,  Guntermann & Drunck GmbH, mario.six at gdsys.cc
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <command.h>
+#include <console.h>
+#include <ihs_axi.h>
+
+static struct udevice *axi_cur_bus;
+static uint dp_last_addr;
+static uint dp_last_length = 0x40;
+
+static void show_bus(struct udevice *bus)
+{
+	struct udevice *dev;
+
+	printf("Bus %d:\t%s", bus->req_seq, bus->name);
+	if (device_active(bus))
+		printf("  (active %d)", bus->seq);
+	printf("\n");
+	for (device_find_first_child(bus, &dev);
+	     dev;
+	     device_find_next_child(&dev)) {
+		//struct dm_i2c_chip *chip = dev_get_parent_platdata(dev);
+
+		//printf("   %02x: %s, offset len %x, flags %x\n",
+		       //chip->chip_addr, dev->name, chip->offset_len,
+		       //chip->flags);
+		printf("  %s\n", dev->name);
+	}
+}
+
+static int do_axi_show_bus(cmd_tbl_t *cmdtp, int flag, int argc,
+			   char * const argv[])
+{
+	if (argc == 1) {
+		/* show all busses */
+		struct udevice *bus;
+		struct uclass *uc;
+		int ret;
+
+		ret = uclass_get(UCLASS_IHS_AXI, &uc);
+		if (ret)
+			return CMD_RET_FAILURE;
+		uclass_foreach_dev(bus, uc)
+			show_bus(bus);
+	} else {
+		int i;
+
+		/* show specific bus */
+		i = simple_strtoul(argv[1], NULL, 10);
+
+		struct udevice *bus;
+		int ret;
+
+		ret = uclass_get_device_by_seq(UCLASS_IHS_AXI, i, &bus);
+		if (ret) {
+			printf("Invalid bus %d: err=%d\n", i, ret);
+			return CMD_RET_FAILURE;
+		}
+		show_bus(bus);
+	}
+
+	return 0;
+}
+
+static int cmd_axi_set_bus_num(unsigned int busnum)
+{
+	struct udevice *bus;
+	int ret;
+
+	ret = uclass_get_device_by_seq(UCLASS_IHS_AXI, busnum, &bus);
+	if (ret) {
+		debug("%s: No bus %d\n", __func__, busnum);
+		return ret;
+	}
+	axi_cur_bus = bus;
+
+	return 0;
+}
+
+static int axi_get_cur_bus(struct udevice **busp)
+{
+	if (!axi_cur_bus) {
+		puts("No AXI bus selected\n");
+		return ENODEV;
+	}
+	*busp = axi_cur_bus;
+
+	return 0;
+}
+
+static int do_axi_bus_num(cmd_tbl_t *cmdtp, int flag, int argc,
+			  char * const argv[])
+{
+	int		ret = 0;
+	int	bus_no;
+
+	if (argc == 1) {
+		/* querying current setting */
+		struct udevice *bus;
+
+		if (!axi_get_cur_bus(&bus))
+			bus_no = bus->seq;
+		else
+			bus_no = -1;
+		printf("Current bus is %d\n", bus_no);
+	} else {
+		bus_no = simple_strtoul(argv[1], NULL, 10);
+		printf("Setting bus to %d\n", bus_no);
+
+		ret = cmd_axi_set_bus_num(bus_no);
+
+		if (ret)
+			printf("Failure changing bus number (%d)\n", ret);
+	}
+
+	return ret ? CMD_RET_FAILURE : 0;
+}
+
+#define DISP_LINE_LEN	16
+
+int do_axi_md(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
+{
+	unsigned int k;
+	ulong	addr, length;
+	int rc = 0;
+	u32 linebuf[DISP_LINE_LEN / sizeof(u32)];
+	ulong nbytes;
+
+	/*
+	 * We use the last specified parameters, unless new ones are
+	 * entered.
+	 */
+	addr = dp_last_addr;
+	length = dp_last_length;
+
+	if (argc < 2)
+		return CMD_RET_USAGE;
+
+	if (!axi_cur_bus) {
+		puts("No AXI bus selected\n");
+		return ENODEV;
+	}
+
+	if ((flag & CMD_FLAG_REPEAT) == 0) {
+		/*
+		 * Address is specified since argc > 3
+		 */
+		addr = simple_strtoul(argv[1], NULL, 16);
+
+		/*
+		 * If another parameter, it is the length to display.
+		 * Length is the number of objects, not number of bytes.
+		 */
+		if (argc > 2)
+			length = simple_strtoul(argv[2], NULL, 16);
+	}
+
+	nbytes = length * sizeof(u32);
+	do {
+		ulong linebytes = (nbytes > DISP_LINE_LEN) ?
+				  DISP_LINE_LEN : nbytes;
+
+		for (k = 0; k < linebytes / sizeof(u32); ++k)
+			axi_read(axi_cur_bus, addr + k * sizeof(u32),
+				 &linebuf[k]);
+		print_buffer(addr, (void *)linebuf, sizeof(u32),
+			     linebytes / sizeof(u32),
+			     DISP_LINE_LEN / sizeof(u32));
+
+		nbytes -= linebytes;
+		addr += linebytes;
+		if (ctrlc()) {
+			rc = 1;
+			break;
+		}
+	} while (nbytes > 0);
+
+	dp_last_addr = addr;
+	dp_last_length = length;
+
+	return rc;
+}
+
+static int do_axi_mw(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
+{
+	u32 writeval;
+	ulong addr, count;
+
+	if ((argc < 3) || (argc > 4))
+		return CMD_RET_USAGE;
+
+	/* Address is specified since argc > 3 */
+	addr = simple_strtoul(argv[1], NULL, 16);
+
+	/* Get the value to write.  */
+	writeval = simple_strtoul(argv[2], NULL, 16);
+
+	/* Count ? */
+	if (argc == 4)
+		count = simple_strtoul(argv[3], NULL, 16);
+	else
+		count = 1;
+
+	while (count-- > 0)
+		axi_write(axi_cur_bus, addr + count * sizeof(u32), writeval);
+
+	return 0;
+}
+
+static cmd_tbl_t cmd_axi_sub[] = {
+	U_BOOT_CMD_MKENT(bus, 1, 1, do_axi_show_bus, "", ""),
+	U_BOOT_CMD_MKENT(dev, 1, 1, do_axi_bus_num, "", ""),
+	U_BOOT_CMD_MKENT(md, 3, 1, do_axi_md, "", ""),
+	U_BOOT_CMD_MKENT(mw, 4, 1, do_axi_mw, "", ""),
+};
+
+static int do_ihs_axi(cmd_tbl_t *cmdtp, int flag, int argc,
+		      char * const argv[])
+{
+	cmd_tbl_t *c;
+
+	if (argc < 2)
+		return CMD_RET_USAGE;
+
+	/* Strip off leading 'axi' command argument */
+	argc--;
+	argv++;
+
+	c = find_cmd_tbl(argv[0], &cmd_axi_sub[0], ARRAY_SIZE(cmd_axi_sub));
+
+	if (c)
+		return c->cmd(cmdtp, flag, argc, argv);
+	else
+		return CMD_RET_USAGE;
+}
+
+static char axi_help_text[] =
+	"bus  - show AXI bus info\n"
+	"axi dev [dev] - show or set current AXI bus\n"
+	"axi md address [# of objects] - read from AXI device\n"
+	"axi mw address value [count] - write to AXI device (fill)\n";
+
+U_BOOT_CMD(
+	axi, 7, 1, do_ihs_axi,
+	"AXI sub-system",
+	axi_help_text
+);
-- 
2.11.0

^ permalink raw reply related	[flat|nested] 138+ messages in thread

* [U-Boot] [PATCH 42/51] cmd: Add ihs fpga command
  2017-07-14 12:54 [U-Boot] [PATCH 00/51] gdsys: Add support for Gazerbeam board Mario Six
                   ` (40 preceding siblings ...)
  2017-07-14 12:55 ` [U-Boot] [PATCH 41/51] cmd: Add ihs axi command Mario Six
@ 2017-07-14 12:55 ` Mario Six
  2017-07-19  9:06   ` Simon Glass
  2017-07-14 12:55 ` [U-Boot] [PATCH 43/51] gdsys: cmd_ioloop: Fix style violations Mario Six
                   ` (8 subsequent siblings)
  50 siblings, 1 reply; 138+ messages in thread
From: Mario Six @ 2017-07-14 12:55 UTC (permalink / raw)
  To: u-boot

Add a comman to debug the IHS FPGA's bus.

Signed-off-by: Mario Six <mario.six@gdsys.cc>
---

 cmd/Kconfig    |   5 ++
 cmd/Makefile   |   1 +
 cmd/ihs_fpga.c | 269 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 275 insertions(+)
 create mode 100644 cmd/ihs_fpga.c

diff --git a/cmd/Kconfig b/cmd/Kconfig
index 4bbe9d435c..6d13c681cb 100644
--- a/cmd/Kconfig
+++ b/cmd/Kconfig
@@ -753,6 +753,11 @@ config CMD_SATA
 	  Attachment, where AT refers to an IBM AT (Advanced Technology)
 	  computer released in 1984.
 
+config CMD_IHS_FPGA
+	bool "fpga"
+	help
+	  Enable the GDSYS IHS FPGA command for accessing the FPGA's regisers.
+
 config CMD_IHS_AXI
 	bool "axi"
 	help
diff --git a/cmd/Makefile b/cmd/Makefile
index 0baaf76b47..79abe8f877 100644
--- a/cmd/Makefile
+++ b/cmd/Makefile
@@ -145,6 +145,7 @@ obj-$(CONFIG_CMD_GPT) += gpt.o
 obj-$(CONFIG_CMD_ETHSW) += ethsw.o
 
 obj-$(CONFIG_CMD_IHS_AXI) += ihs_axi.o
+obj-$(CONFIG_CMD_IHS_FPGA) += ihs_fpga.o
 
 # Power
 obj-$(CONFIG_CMD_PMIC) += pmic.o
diff --git a/cmd/ihs_fpga.c b/cmd/ihs_fpga.c
new file mode 100644
index 0000000000..6d0c599d96
--- /dev/null
+++ b/cmd/ihs_fpga.c
@@ -0,0 +1,269 @@
+/*
+ * (C) Copyright 2017
+ * Mario Six,  Guntermann & Drunck GmbH, mario.six at gdsys.cc
+ *
+ * based on the fpgad command, which is
+ *
+ * (C) Copyright 2013
+ * Dirk Eibach,  Guntermann & Drunck GmbH, dirk.eibach at gdsys.cc
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <command.h>
+#include <console.h>
+#include <ihs_fpga.h>
+
+static struct udevice *fpga_cur;
+static uint dp_last_addr;
+static uint dp_last_length = 0x40;
+
+static void show_fpga(struct udevice *fpga)
+{
+	struct udevice *dev;
+
+	printf("Bus %d:\t%s", fpga->req_seq, fpga->name);
+	if (device_active(fpga))
+		printf("  (active %d)", fpga->seq);
+	printf("\n");
+	for (device_find_first_child(fpga, &dev);
+	     dev;
+	     device_find_next_child(&dev)) {
+		//struct dm_i2c_chip *chip = dev_get_parent_platdata(dev);
+
+		//printf("   %02x: %s, offset len %x, flags %x\n",
+		       //chip->chip_addr, dev->name, chip->offset_len,
+		       //chip->flags);
+		printf("  %s\n", dev->name);
+	}
+}
+
+static int do_fpga_show_fpga(cmd_tbl_t *cmdtp, int flag, int argc,
+			     char * const argv[])
+{
+	if (argc == 1) {
+		/* show all FPGAs */
+		struct udevice *fpga;
+		struct uclass *uc;
+		int ret;
+
+		ret = uclass_get(UCLASS_IHS_FPGA, &uc);
+		if (ret)
+			return CMD_RET_FAILURE;
+		uclass_foreach_dev(fpga, uc)
+			show_fpga(fpga);
+	} else {
+		int i;
+
+		/* show specific fpga */
+		i = simple_strtoul(argv[1], NULL, 10);
+
+		struct udevice *fpga;
+		int ret;
+
+		ret = uclass_get_device_by_seq(UCLASS_IHS_FPGA, i, &fpga);
+		if (ret) {
+			printf("Invalid fpga %d: err=%d\n", i, ret);
+			return CMD_RET_FAILURE;
+		}
+		show_fpga(fpga);
+	}
+
+	return 0;
+}
+
+static int cmd_fpga_set_fpga_num(unsigned int fpganum)
+{
+	struct udevice *fpga;
+	int ret;
+
+	ret = uclass_get_device_by_seq(UCLASS_IHS_FPGA, fpganum, &fpga);
+	if (ret) {
+		debug("%s: No fpga %d\n", __func__, fpganum);
+		return ret;
+	}
+	fpga_cur = fpga;
+
+	return 0;
+}
+
+static int fpga_get_cur_fpga(struct udevice **fpgap)
+{
+	if (!fpga_cur) {
+		puts("No fpga selected\n");
+		return -ENODEV;
+	}
+	*fpgap = fpga_cur;
+
+	return 0;
+}
+
+static int do_fpga_fpga_num(cmd_tbl_t *cmdtp, int flag, int argc,
+			    char * const argv[])
+{
+	int ret = 0;
+	int fpga_no;
+
+	if (argc == 1) {
+		/* querying current setting */
+		struct udevice *fpga;
+
+		if (!fpga_get_cur_fpga(&fpga))
+			fpga_no = fpga->seq;
+		else
+			fpga_no = -1;
+		printf("Current fpga is %d\n", fpga_no);
+	} else {
+		fpga_no = simple_strtoul(argv[1], NULL, 10);
+		printf("Setting fpga to %d\n", fpga_no);
+
+		ret = cmd_fpga_set_fpga_num(fpga_no);
+
+		if (ret)
+			printf("Failure changing fpga number (%d)\n", ret);
+	}
+
+	return ret ? CMD_RET_FAILURE : 0;
+}
+
+#define DISP_LINE_LEN	16
+
+int do_fpga_md(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
+{
+	unsigned int k;
+	ulong	addr, length;
+	int rc = 0;
+	u16 linebuf[DISP_LINE_LEN / sizeof(u16)];
+	ulong nbytes;
+
+	/*
+	 * We use the last specified parameters, unless new ones are
+	 * entered.
+	 */
+	addr = dp_last_addr;
+	length = dp_last_length;
+
+	if (argc < 2)
+		return CMD_RET_USAGE;
+
+	if (!fpga_cur) {
+		puts("No fpga selected\n");
+		return -ENODEV;
+	}
+
+	if ((flag & CMD_FLAG_REPEAT) == 0) {
+		/*
+		 * Address is specified since argc > 3
+		 */
+		addr = simple_strtoul(argv[1], NULL, 16);
+
+		/*
+		 * If another parameter, it is the length to display.
+		 * Length is the number of objects, not number of bytes.
+		 */
+		if (argc > 2)
+			length = simple_strtoul(argv[2], NULL, 16);
+	}
+
+	nbytes = length * sizeof(u16);
+	do {
+		ulong linebytes = (nbytes > DISP_LINE_LEN) ?
+				  DISP_LINE_LEN : nbytes;
+
+		for (k = 0; k < linebytes / sizeof(u16); ++k)
+			linebuf[k] = fpga_in_le16(fpga_cur,
+						  addr / sizeof(u16) + k);
+
+		print_buffer(addr, (void *)linebuf, sizeof(u16),
+			     linebytes / sizeof(u16),
+			     DISP_LINE_LEN / sizeof(u16));
+		if (rc)
+			break;
+
+		nbytes -= linebytes;
+		addr += linebytes;
+		if (ctrlc()) {
+			rc = 1;
+			break;
+		}
+	} while (nbytes > 0);
+
+	dp_last_addr = addr;
+	dp_last_length = length;
+
+	return rc;
+}
+
+static int do_fpga_mw(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
+{
+	u16 writeval;
+	ulong addr, count;
+
+	if ((argc < 3) || (argc > 4))
+		return CMD_RET_USAGE;
+
+	if (!fpga_cur) {
+		puts("No fpga selected\n");
+		return -ENODEV;
+	}
+
+	/* Address is specified since argc > 3 */
+	addr = simple_strtoul(argv[1], NULL, 16);
+
+	/* Get the value to write.  */
+	writeval = simple_strtoul(argv[2], NULL, 16);
+
+	/* Count ? */
+	if (argc == 4)
+		count = simple_strtoul(argv[3], NULL, 16);
+	else
+		count = 1;
+
+	while (count-- > 0)
+		fpga_out_le16(fpga_cur,
+			      addr / sizeof(u16) + count,
+			      writeval);
+
+	return 0;
+}
+
+static cmd_tbl_t cmd_fpga_sub[] = {
+	U_BOOT_CMD_MKENT(show, 1, 1, do_fpga_show_fpga, "", ""),
+	U_BOOT_CMD_MKENT(dev, 1, 1, do_fpga_fpga_num, "", ""),
+	U_BOOT_CMD_MKENT(md, 3, 1, do_fpga_md, "", ""),
+	U_BOOT_CMD_MKENT(mw, 4, 1, do_fpga_mw, "", ""),
+};
+
+static int do_ihs_fpga(cmd_tbl_t *cmdtp, int flag, int argc,
+		       char * const argv[])
+{
+	cmd_tbl_t *c;
+
+	if (argc < 2)
+		return CMD_RET_USAGE;
+
+	/* Strip off leading 'fpga' command argument */
+	argc--;
+	argv++;
+
+	c = find_cmd_tbl(argv[0], &cmd_fpga_sub[0], ARRAY_SIZE(cmd_fpga_sub));
+
+	if (c)
+		return c->cmd(cmdtp, flag, argc, argv);
+	else
+		return CMD_RET_USAGE;
+}
+
+static char fpga_help_text[] =
+	"show  - show FPGA info\n"
+	"fpga dev [dev] - show or set current FPGA\n"
+	"fpga md address [# of objects] - read from FPGA device\n"
+	"fpga mw address value [count] - write to FPGA device (fill)\n";
+
+U_BOOT_CMD(
+	fpga, 7, 1, do_ihs_fpga,
+	"FPGA sub-system",
+	fpga_help_text
+);
-- 
2.11.0

^ permalink raw reply related	[flat|nested] 138+ messages in thread

* [U-Boot] [PATCH 43/51] gdsys: cmd_ioloop: Fix style violations
  2017-07-14 12:54 [U-Boot] [PATCH 00/51] gdsys: Add support for Gazerbeam board Mario Six
                   ` (41 preceding siblings ...)
  2017-07-14 12:55 ` [U-Boot] [PATCH 42/51] cmd: Add ihs fpga command Mario Six
@ 2017-07-14 12:55 ` Mario Six
  2017-07-19  9:06   ` Simon Glass
  2017-07-14 12:55 ` [U-Boot] [PATCH 44/51] gdsys: cmd_ioloop: Introduce commenting enum Mario Six
                   ` (7 subsequent siblings)
  50 siblings, 1 reply; 138+ messages in thread
From: Mario Six @ 2017-07-14 12:55 UTC (permalink / raw)
  To: u-boot

Fix some style violations in the ioloop command, and make the code more
readable where possible.

Signed-off-by: Mario Six <mario.six@gdsys.cc>
---

 board/gdsys/common/cmd_ioloop.c | 78 ++++++++++++++++++++---------------------
 1 file changed, 38 insertions(+), 40 deletions(-)

diff --git a/board/gdsys/common/cmd_ioloop.c b/board/gdsys/common/cmd_ioloop.c
index 0e81c9d9e4..a052b24501 100644
--- a/board/gdsys/common/cmd_ioloop.c
+++ b/board/gdsys/common/cmd_ioloop.c
@@ -12,33 +12,33 @@
 #include <gdsys_fpga.h>
 
 enum {
-	STATE_TX_PACKET_BUILDING = 1<<0,
-	STATE_TX_TRANSMITTING = 1<<1,
-	STATE_TX_BUFFER_FULL = 1<<2,
-	STATE_TX_ERR = 1<<3,
-	STATE_RECEIVE_TIMEOUT = 1<<4,
-	STATE_PROC_RX_STORE_TIMEOUT = 1<<5,
-	STATE_PROC_RX_RECEIVE_TIMEOUT = 1<<6,
-	STATE_RX_DIST_ERR = 1<<7,
-	STATE_RX_LENGTH_ERR = 1<<8,
-	STATE_RX_FRAME_CTR_ERR = 1<<9,
-	STATE_RX_FCS_ERR = 1<<10,
-	STATE_RX_PACKET_DROPPED = 1<<11,
-	STATE_RX_DATA_LAST = 1<<12,
-	STATE_RX_DATA_FIRST = 1<<13,
-	STATE_RX_DATA_AVAILABLE = 1<<15,
+	STATE_TX_PACKET_BUILDING = BIT(0),
+	STATE_TX_TRANSMITTING = BIT(1),
+	STATE_TX_BUFFER_FULL = BIT(2),
+	STATE_TX_ERR = BIT(3),
+	STATE_RECEIVE_TIMEOUT = BIT(4),
+	STATE_PROC_RX_STORE_TIMEOUT = BIT(5),
+	STATE_PROC_RX_RECEIVE_TIMEOUT = BIT(6),
+	STATE_RX_DIST_ERR = BIT(7),
+	STATE_RX_LENGTH_ERR = BIT(8),
+	STATE_RX_FRAME_CTR_ERR = BIT(9),
+	STATE_RX_FCS_ERR = BIT(10),
+	STATE_RX_PACKET_DROPPED = BIT(11),
+	STATE_RX_DATA_LAST = BIT(12),
+	STATE_RX_DATA_FIRST = BIT(13),
+	STATE_RX_DATA_AVAILABLE = BIT(15),
 };
 
 enum {
-	CTRL_PROC_RECEIVE_ENABLE = 1<<12,
-	CTRL_FLUSH_TRANSMIT_BUFFER = 1<<15,
+	CTRL_PROC_RECEIVE_ENABLE = BIT(12),
+	CTRL_FLUSH_TRANSMIT_BUFFER = BIT(15),
 };
 
 enum {
-	IRQ_CPU_TRANSMITBUFFER_FREE_STATUS = 1<<5,
-	IRQ_CPU_PACKET_TRANSMITTED_EVENT = 1<<6,
-	IRQ_NEW_CPU_PACKET_RECEIVED_EVENT = 1<<7,
-	IRQ_CPU_RECEIVE_DATA_AVAILABLE_STATUS = 1<<8,
+	IRQ_CPU_TRANSMITBUFFER_FREE_STATUS = BIT(5),
+	IRQ_CPU_PACKET_TRANSMITTED_EVENT = BIT(6),
+	IRQ_NEW_CPU_PACKET_RECEIVED_EVENT = BIT(7),
+	IRQ_CPU_RECEIVE_DATA_AVAILABLE_STATUS = BIT(8),
 };
 
 struct io_generic_packet {
@@ -53,7 +53,7 @@ unsigned long long rx_ctr;
 unsigned long long tx_ctr;
 unsigned long long err_ctr;
 
-static void io_check_status(unsigned int fpga, u16 status, bool silent)
+static void io_check_status(uint fpga, u16 status, bool silent)
 {
 	u16 mask = STATE_RX_DIST_ERR | STATE_RX_LENGTH_ERR |
 		   STATE_RX_FRAME_CTR_ERR | STATE_RX_FCS_ERR |
@@ -86,9 +86,9 @@ static void io_check_status(unsigned int fpga, u16 status, bool silent)
 		printf("TX_ERR\n");
 }
 
-static void io_send(unsigned int fpga, unsigned int size)
+static void io_send(uint fpga, uint size)
 {
-	unsigned int k;
+	uint k;
 	struct io_generic_packet packet = {
 		.source_address = 1,
 		.packet_type = 1,
@@ -108,9 +108,8 @@ static void io_send(unsigned int fpga, unsigned int size)
 	tx_ctr++;
 }
 
-static void io_receive(unsigned int fpga)
+static void io_receive(uint fpga)
 {
-	unsigned int k = 0;
 	u16 rx_tx_status;
 
 	FPGA_GET_REG(fpga, ep.rx_tx_status, &rx_tx_status);
@@ -124,17 +123,15 @@ static void io_receive(unsigned int fpga)
 		FPGA_GET_REG(fpga, ep.receive_data, &rx);
 
 		FPGA_GET_REG(fpga, ep.rx_tx_status, &rx_tx_status);
-
-		++k;
 	}
 }
 
-static void io_reflect(unsigned int fpga)
+static void io_reflect(uint fpga)
 {
 	u16 buffer[128];
 
-	unsigned int k = 0;
-	unsigned int n;
+	uint k = 0;
+	uint n;
 	u16 rx_tx_status;
 
 	FPGA_GET_REG(fpga, ep.rx_tx_status, &rx_tx_status);
@@ -167,8 +164,8 @@ static void io_reflect(unsigned int fpga)
  */
 int do_ioreflect(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
 {
-	unsigned int fpga;
-	unsigned int rate = 0;
+	uint fpga;
+	uint rate = 0;
 	unsigned long long last_seen = 0;
 
 	if (argc < 2)
@@ -182,10 +179,10 @@ int do_ioreflect(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
 	if (argc > 2)
 		rate = simple_strtoul(argv[2], NULL, 10);
 
-	/* enable receive path */
+	/* Enable receive path */
 	FPGA_SET_REG(fpga, ep.rx_tx_control, CTRL_PROC_RECEIVE_ENABLE);
 
-	/* set device address to dummy 1*/
+	/* Set device address to dummy 1*/
 	FPGA_SET_REG(fpga, ep.device_address, 1);
 
 	rx_ctr = 0; tx_ctr = 0; err_ctr = 0;
@@ -216,18 +213,19 @@ int do_ioreflect(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
 	return 0;
 }
 
+#define DISP_LINE_LEN	16
+
 /*
  * FPGA io-endpoint looptest
  *
  * Syntax:
  *	ioloop {fpga} {size} {rate}
  */
-#define DISP_LINE_LEN	16
 int do_ioloop(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
 {
-	unsigned int fpga;
-	unsigned int size;
-	unsigned int rate = 0;
+	uint fpga;
+	uint size;
+	uint rate = 0;
 
 	if (argc < 3)
 		return CMD_RET_USAGE;
@@ -274,7 +272,7 @@ int do_ioloop(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
 				break;
 			udelay(1000000 / rate);
 			if (!(tx_ctr % rate))
-				printf("d %lld, tx %llu, rx %llu, err %llu\n",
+				printf("d %llu, tx %llu, rx %llu, err %llu\n",
 				       tx_ctr - rx_ctr, tx_ctr, rx_ctr,
 				       err_ctr);
 		}
-- 
2.11.0

^ permalink raw reply related	[flat|nested] 138+ messages in thread

* [U-Boot] [PATCH 44/51] gdsys: cmd_ioloop: Introduce commenting enum
  2017-07-14 12:54 [U-Boot] [PATCH 00/51] gdsys: Add support for Gazerbeam board Mario Six
                   ` (42 preceding siblings ...)
  2017-07-14 12:55 ` [U-Boot] [PATCH 43/51] gdsys: cmd_ioloop: Fix style violations Mario Six
@ 2017-07-14 12:55 ` Mario Six
  2017-07-19  9:06   ` Simon Glass
  2017-07-14 12:55 ` [U-Boot] [PATCH 45/51] gdsys: cmd_ioloop: Make DM compatible Mario Six
                   ` (6 subsequent siblings)
  50 siblings, 1 reply; 138+ messages in thread
From: Mario Six @ 2017-07-14 12:55 UTC (permalink / raw)
  To: u-boot

Replace the boolean parameter of io_check_status that controls whether
the status is printed or not with a documenting enum.

Signed-off-by: Mario Six <mario.six@gdsys.cc>
---

 board/gdsys/common/cmd_ioloop.c | 13 +++++++++----
 1 file changed, 9 insertions(+), 4 deletions(-)

diff --git a/board/gdsys/common/cmd_ioloop.c b/board/gdsys/common/cmd_ioloop.c
index a052b24501..2ea8bc8670 100644
--- a/board/gdsys/common/cmd_ioloop.c
+++ b/board/gdsys/common/cmd_ioloop.c
@@ -11,6 +11,11 @@
 
 #include <gdsys_fpga.h>
 
+enum status_print_type {
+	STATUS_LOUD = 0,
+	STATUS_SILENT = 1,
+};
+
 enum {
 	STATE_TX_PACKET_BUILDING = BIT(0),
 	STATE_TX_TRANSMITTING = BIT(1),
@@ -53,7 +58,7 @@ unsigned long long rx_ctr;
 unsigned long long tx_ctr;
 unsigned long long err_ctr;
 
-static void io_check_status(uint fpga, u16 status, bool silent)
+static void io_check_status(uint fpga, u16 status, enum status_print_type type)
 {
 	u16 mask = STATE_RX_DIST_ERR | STATE_RX_LENGTH_ERR |
 		   STATE_RX_FRAME_CTR_ERR | STATE_RX_FCS_ERR |
@@ -67,7 +72,7 @@ static void io_check_status(uint fpga, u16 status, bool silent)
 	err_ctr++;
 	FPGA_SET_REG(fpga, ep.rx_tx_status, status);
 
-	if (silent)
+	if (type == STATUS_SILENT)
 		return;
 
 	if (status & STATE_RX_PACKET_DROPPED)
@@ -194,7 +199,7 @@ int do_ioreflect(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
 		FPGA_GET_REG(fpga, top_interrupt, &top_int);
 		FPGA_GET_REG(fpga, ep.rx_tx_status, &rx_tx_status);
 
-		io_check_status(fpga, rx_tx_status, true);
+		io_check_status(fpga, rx_tx_status, STATUS_SILENT);
 		if ((top_int & IRQ_CPU_RECEIVE_DATA_AVAILABLE_STATUS) &&
 		    (top_int & IRQ_CPU_TRANSMITBUFFER_FREE_STATUS))
 			io_reflect(fpga);
@@ -261,7 +266,7 @@ int do_ioloop(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
 		FPGA_GET_REG(fpga, top_interrupt, &top_int);
 		FPGA_GET_REG(fpga, ep.rx_tx_status, &rx_tx_status);
 
-		io_check_status(fpga, rx_tx_status, false);
+		io_check_status(fpga, rx_tx_status, STATUS_LOUD);
 		if (top_int & IRQ_CPU_TRANSMITBUFFER_FREE_STATUS)
 			io_send(fpga, size);
 		if (top_int & IRQ_CPU_RECEIVE_DATA_AVAILABLE_STATUS)
-- 
2.11.0

^ permalink raw reply related	[flat|nested] 138+ messages in thread

* [U-Boot] [PATCH 45/51] gdsys: cmd_ioloop: Make DM compatible
  2017-07-14 12:54 [U-Boot] [PATCH 00/51] gdsys: Add support for Gazerbeam board Mario Six
                   ` (43 preceding siblings ...)
  2017-07-14 12:55 ` [U-Boot] [PATCH 44/51] gdsys: cmd_ioloop: Introduce commenting enum Mario Six
@ 2017-07-14 12:55 ` Mario Six
  2017-07-19  9:06   ` Simon Glass
  2017-07-14 12:55 ` [U-Boot] [PATCH 46/51] ihs_mdio: Add support to force clause45 access Mario Six
                   ` (5 subsequent siblings)
  50 siblings, 1 reply; 138+ messages in thread
From: Mario Six @ 2017-07-14 12:55 UTC (permalink / raw)
  To: u-boot

Make the ioloop command DM compatible, while keeping the old
functionality for not-yet-converted boards.

Signed-off-by: Mario Six <mario.six@gdsys.cc>
---

 board/gdsys/common/cmd_ioloop.c | 241 ++++++++++++++++++++++++++++++++++++++--
 1 file changed, 234 insertions(+), 7 deletions(-)

diff --git a/board/gdsys/common/cmd_ioloop.c b/board/gdsys/common/cmd_ioloop.c
index 2ea8bc8670..b767c4d174 100644
--- a/board/gdsys/common/cmd_ioloop.c
+++ b/board/gdsys/common/cmd_ioloop.c
@@ -11,12 +11,27 @@
 
 #include <gdsys_fpga.h>
 
+#ifndef CONFIG_GDSYS_LEGACY_DRIVERS
+#include <dm.h>
+#include <gdsys_ioep.h>
+#include <gdsys_soc.h>
+#include <ihs_fpga.h>
+#endif /* !CONFIG_GDSYS_LEGACY_DRIVERS */
+
 enum status_print_type {
 	STATUS_LOUD = 0,
 	STATUS_SILENT = 1,
 };
 
 enum {
+	IRQ_CPU_TRANSMITBUFFER_FREE_STATUS = BIT(5),
+	IRQ_CPU_PACKET_TRANSMITTED_EVENT = BIT(6),
+	IRQ_NEW_CPU_PACKET_RECEIVED_EVENT = BIT(7),
+	IRQ_CPU_RECEIVE_DATA_AVAILABLE_STATUS = BIT(8),
+};
+
+#ifdef CONFIG_GDSYS_LEGACY_DRIVERS
+enum {
 	STATE_TX_PACKET_BUILDING = BIT(0),
 	STATE_TX_TRANSMITTING = BIT(1),
 	STATE_TX_BUFFER_FULL = BIT(2),
@@ -39,13 +54,6 @@ enum {
 	CTRL_FLUSH_TRANSMIT_BUFFER = BIT(15),
 };
 
-enum {
-	IRQ_CPU_TRANSMITBUFFER_FREE_STATUS = BIT(5),
-	IRQ_CPU_PACKET_TRANSMITTED_EVENT = BIT(6),
-	IRQ_NEW_CPU_PACKET_RECEIVED_EVENT = BIT(7),
-	IRQ_CPU_RECEIVE_DATA_AVAILABLE_STATUS = BIT(8),
-};
-
 struct io_generic_packet {
 	u16 target_address;
 	u16 source_address;
@@ -53,11 +61,16 @@ struct io_generic_packet {
 	u8 bc;
 	u16 packet_length;
 } __attribute__((__packed__));
+#endif /* CONFIG_GDSYS_LEGACY_DRIVERS */
 
 unsigned long long rx_ctr;
 unsigned long long tx_ctr;
 unsigned long long err_ctr;
+#ifndef CONFIG_GDSYS_LEGACY_DRIVERS
+struct udevice *dev;
+#endif /* !CONFIG_GDSYS_LEGACY_DRIVERS */
 
+#ifdef CONFIG_GDSYS_LEGACY_DRIVERS
 static void io_check_status(uint fpga, u16 status, enum status_print_type type)
 {
 	u16 mask = STATE_RX_DIST_ERR | STATE_RX_LENGTH_ERR |
@@ -90,7 +103,15 @@ static void io_check_status(uint fpga, u16 status, enum status_print_type type)
 	if (status & STATE_TX_ERR)
 		printf("TX_ERR\n");
 }
+#else
+static void io_check_status(struct udevice *dev, enum status_print_type type)
+{
+	if (ioep_reset_status(dev, type == STATUS_LOUD))
+		err_ctr++;
+}
+#endif /* CONFIG_GDSYS_LEGACY_DRIVERS */
 
+#ifdef CONFIG_GDSYS_LEGACY_DRIVERS
 static void io_send(uint fpga, uint size)
 {
 	uint k;
@@ -112,7 +133,27 @@ static void io_send(uint fpga, uint size)
 
 	tx_ctr++;
 }
+#else
+static void io_send(struct udevice *dev, uint size)
+{
+	uint k;
+	u16 buffer[128];
+	struct io_generic_packet header = {
+		.source_address = 1,
+		.packet_type = 1,
+		.packet_length = size,
+	};
+
+	for (k = 0; k < size; ++k)
+		buffer[k] = k;
+
+	ioep_send(dev, &header, buffer);
+
+	tx_ctr++;
+}
+#endif /* CONFIG_GDSYS_LEGACY_DRIVERS */
 
+#ifdef CONFIG_GDSYS_LEGACY_DRIVERS
 static void io_receive(uint fpga)
 {
 	u16 rx_tx_status;
@@ -130,7 +171,18 @@ static void io_receive(uint fpga)
 		FPGA_GET_REG(fpga, ep.rx_tx_status, &rx_tx_status);
 	}
 }
+#else
+static void io_receive(struct udevice *dev)
+{
+	u16 buffer[128];
+	struct io_generic_packet header;
 
+	if (!ioep_receive(dev, &header, buffer))
+		rx_ctr++;
+}
+#endif /* CONFIG_GDSYS_LEGACY_DRIVERS */
+
+#ifdef CONFIG_GDSYS_LEGACY_DRIVERS
 static void io_reflect(uint fpga)
 {
 	u16 buffer[128];
@@ -160,7 +212,20 @@ static void io_reflect(uint fpga)
 
 	tx_ctr++;
 }
+#else
+static void io_reflect(struct udevice *dev)
+{
+	u16 buffer[128];
+	struct io_generic_packet header;
+
+	if (ioep_receive(dev, &header, buffer))
+		return;
+
+	ioep_send(dev, &header, buffer);
+}
+#endif /* CONFIG_GDSYS_LEGACY_DRIVERS */
 
+#ifdef CONFIG_GDSYS_LEGACY_DRIVERS
 /*
  * FPGA io-endpoint reflector
  *
@@ -217,9 +282,54 @@ int do_ioreflect(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
 
 	return 0;
 }
+#else
+/*
+ * FPGA io-endpoint reflector
+ *
+ * Syntax:
+ *	ioreflect {reportrate}
+ */
+int do_ioreflect(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
+{
+	struct gdsys_soc_child_platdata *pplat = dev_get_parent_platdata(dev);
+	uint rate = 0;
+	unsigned long long last_seen = 0;
+
+	/* Enable receive path */
+	ioep_enable_receive(dev);
+
+	/* Set device address to dummy 1*/
+	ioep_set_address(dev, 1);
+
+	rx_ctr = 0; tx_ctr = 0; err_ctr = 0;
+
+	while (1) {
+		uint top_int;
+
+		fpga_get_reg(pplat->fpga, "top-interrupt", &top_int);
+		io_check_status(dev, STATUS_SILENT);
+		if ((top_int & IRQ_CPU_RECEIVE_DATA_AVAILABLE_STATUS) &&
+		    (top_int & IRQ_CPU_TRANSMITBUFFER_FREE_STATUS))
+			io_reflect(dev);
+
+		if (rate) {
+			if (!(tx_ctr % rate) && (tx_ctr != last_seen))
+				printf("refl %llu, err %llu\n", tx_ctr,
+				       err_ctr);
+			last_seen = tx_ctr;
+		}
+
+		if (ctrlc())
+			break;
+	}
+
+	return 0;
+}
+#endif /* CONFIG_GDSYS_LEGACY_DRIVERS */
 
 #define DISP_LINE_LEN	16
 
+#ifdef CONFIG_GDSYS_LEGACY_DRIVERS
 /*
  * FPGA io-endpoint looptest
  *
@@ -285,7 +395,105 @@ int do_ioloop(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
 
 	return 0;
 }
+#else
+/*
+ * FPGA io-endpoint looptest
+ *
+ * Syntax:
+ *	ioloop {size} {rate}
+ */
+int do_ioloop(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
+{
+	uint size;
+	uint rate = 0;
+	struct gdsys_soc_child_platdata *pplat = dev_get_parent_platdata(dev);
+
+	if (argc < 2)
+		return CMD_RET_USAGE;
+
+	/*
+	 * packet size is specified since argc > 1
+	 */
+	size = simple_strtoul(argv[2], NULL, 10);
+
+	/*
+	 * If another parameter, it is the test rate in packets per second.
+	 */
+	if (argc > 2)
+		rate = simple_strtoul(argv[3], NULL, 10);
+
+	/* Enable receive path */
+	ioep_enable_receive(dev);
+
+	/* Set device address to dummy 1*/
+	ioep_set_address(dev, 1);
+
+	rx_ctr = 0; tx_ctr = 0; err_ctr = 0;
+
+	while (1) {
+		uint top_int;
+
+		fpga_get_reg(pplat->fpga, "top-interrupt", &top_int);
+
+		io_check_status(dev, STATUS_LOUD);
+		if (top_int & IRQ_CPU_TRANSMITBUFFER_FREE_STATUS)
+			io_send(dev, size);
+		if (top_int & IRQ_CPU_RECEIVE_DATA_AVAILABLE_STATUS)
+			io_receive(dev);
+
+		if (rate) {
+			if (ctrlc())
+				break;
+			udelay(1000000 / rate);
+			if (!(tx_ctr % rate))
+				printf("d %llu, tx %llu, rx %llu, err %llu\n",
+				       tx_ctr - rx_ctr, tx_ctr, rx_ctr,
+				       err_ctr);
+		}
+	}
+	return 0;
+}
+#endif /* CONFIG_GDSYS_LEGACY_DRIVERS */
+
+#ifndef CONFIG_GDSYS_LEGACY_DRIVERS
+int do_iodev(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
+{
+	struct udevice *ioep;
+
+	if (argc > 1) {
+		int i = simple_strtoul(argv[1], NULL, 10);
+		int ret;
+
+		ret = uclass_get_device_by_seq(UCLASS_IOEP, i, &ioep);
+		if (ret) {
+			printf("Invalid IOEP %d: err=%d\n", i, ret);
+			return CMD_RET_FAILURE;
+		}
+
+		dev = ioep;
+	} else {
+		struct uclass *uc;
+		int ret;
+
+		ret = uclass_get(UCLASS_IOEP, &uc);
+		if (ret)
+			return CMD_RET_FAILURE;
+
+		uclass_foreach_dev(ioep, uc) {
+			printf("IOEP %d:\t%s\n", ioep->seq, ioep->name);
+		}
+
+		if (dev)
+			printf("\nSelected IOEP: %d\n", dev->seq);
+		else
+			puts("\nNo IOEP selected.\n");
+	}
+
+	return 0;
+}
+#endif /* !CONFIG_GDSYS_LEGACY_DRIVERS */
 
+#ifdef CONFIG_GDSYS_LEGACY_DRIVERS
 U_BOOT_CMD(
 	ioloop,	4,	0,	do_ioloop,
 	"fpga io-endpoint looptest",
@@ -297,3 +505,22 @@ U_BOOT_CMD(
 	"fpga io-endpoint reflector",
 	"fpga reportrate"
 );
+#else
+U_BOOT_CMD(
+	ioloop,	3,	0,	do_ioloop,
+	"fpga io-endpoint looptest",
+	"packetsize [packets/sec]"
+);
+
+U_BOOT_CMD(
+	ioreflect, 2,	0,	do_ioreflect,
+	"fpga io-endpoint reflector",
+	"reportrate"
+);
+
+U_BOOT_CMD(
+	iodev, 2,	0,	do_iodev,
+	"fpga io-endpoint listing/selection",
+	"[ioep device to select]"
+);
+#endif /* CONFIG_GDSYS_LEGACY_DRIVERS */
-- 
2.11.0

^ permalink raw reply related	[flat|nested] 138+ messages in thread

* [U-Boot] [PATCH 46/51] ihs_mdio: Add support to force clause45 access
  2017-07-14 12:54 [U-Boot] [PATCH 00/51] gdsys: Add support for Gazerbeam board Mario Six
                   ` (44 preceding siblings ...)
  2017-07-14 12:55 ` [U-Boot] [PATCH 45/51] gdsys: cmd_ioloop: Make DM compatible Mario Six
@ 2017-07-14 12:55 ` Mario Six
  2017-07-19  9:06   ` Simon Glass
  2017-07-14 12:55 ` [U-Boot] [PATCH 47/51] ihs_mdio: Fix style violations Mario Six
                   ` (4 subsequent siblings)
  50 siblings, 1 reply; 138+ messages in thread
From: Mario Six @ 2017-07-14 12:55 UTC (permalink / raw)
  To: u-boot

Add support to ihs_mdio to force clause 45 access (in addition to
clause 22 access).

Signed-off-by: Mario Six <mario.six@gdsys.cc>
---

 board/gdsys/common/ihs_mdio.c | 26 +++++++++++++++++++++++---
 board/gdsys/common/ihs_mdio.h |  1 +
 2 files changed, 24 insertions(+), 3 deletions(-)

diff --git a/board/gdsys/common/ihs_mdio.c b/board/gdsys/common/ihs_mdio.c
index d67ec7d38a..85a804d5cd 100644
--- a/board/gdsys/common/ihs_mdio.c
+++ b/board/gdsys/common/ihs_mdio.c
@@ -37,6 +37,16 @@ static int ihs_mdio_reset(struct mii_dev *bus)
 	return 0;
 }
 
+static int ihs_mdio_address(struct ihs_mdio_info *info, int addr, int dev_addr,
+			 int regnum)
+{
+	FPGA_SET_REG(info->fpga, mdio.address_data, regnum);
+	FPGA_SET_REG(info->fpga, mdio.control,
+		     ((addr & 0x1f) << 5) | (dev_addr & 0x1f) | (0 << 10));
+
+	return 0;
+}
+
 static int ihs_mdio_read(struct mii_dev *bus, int addr, int dev_addr,
 			 int regnum)
 {
@@ -45,8 +55,13 @@ static int ihs_mdio_read(struct mii_dev *bus, int addr, int dev_addr,
 
 	ihs_mdio_idle(bus);
 
+	if (info->clause45) {
+		ihs_mdio_address(info, addr, dev_addr, regnum);
+		ihs_mdio_idle(bus);
+	}
+
 	FPGA_SET_REG(info->fpga, mdio.control,
-		     ((addr & 0x1f) << 5) | (regnum & 0x1f) | (2 << 10));
+		     ((addr & 0x1f) << 5) | ((info->clause45 ? dev_addr : regnum) & 0x1f) | (2 << 10));
 
 	/* wait for rx data available */
 	udelay(100);
@@ -63,9 +78,14 @@ static int ihs_mdio_write(struct mii_dev *bus, int addr, int dev_addr,
 
 	ihs_mdio_idle(bus);
 
+	if (info->clause45) {
+		ihs_mdio_address(info, addr, dev_addr, regnum);
+		ihs_mdio_idle(bus);
+	}
+
 	FPGA_SET_REG(info->fpga, mdio.address_data, value);
 	FPGA_SET_REG(info->fpga, mdio.control,
-		     ((addr & 0x1f) << 5) | (regnum & 0x1f) | (1 << 10));
+		     ((addr & 0x1f) << 5) | ((info->clause45 ? dev_addr : regnum) & 0x1f) | (1 << 10));
 
 	return 0;
 }
@@ -75,7 +95,7 @@ int ihs_mdio_init(struct ihs_mdio_info *info)
 	struct mii_dev *bus = mdio_alloc();
 
 	if (!bus) {
-		printf("Failed to allocate FSL MDIO bus\n");
+		printf("Failed to allocate IHS MDIO bus\n");
 		return -1;
 	}
 
diff --git a/board/gdsys/common/ihs_mdio.h b/board/gdsys/common/ihs_mdio.h
index 64b4049378..372f07569c 100644
--- a/board/gdsys/common/ihs_mdio.h
+++ b/board/gdsys/common/ihs_mdio.h
@@ -11,6 +11,7 @@
 struct ihs_mdio_info {
 	u32 fpga;
 	char *name;
+	bool clause45;
 };
 
 int ihs_mdio_init(struct ihs_mdio_info *info);
-- 
2.11.0

^ permalink raw reply related	[flat|nested] 138+ messages in thread

* [U-Boot] [PATCH 47/51] ihs_mdio: Fix style violations
  2017-07-14 12:54 [U-Boot] [PATCH 00/51] gdsys: Add support for Gazerbeam board Mario Six
                   ` (45 preceding siblings ...)
  2017-07-14 12:55 ` [U-Boot] [PATCH 46/51] ihs_mdio: Add support to force clause45 access Mario Six
@ 2017-07-14 12:55 ` Mario Six
  2017-07-19  9:06   ` Simon Glass
  2017-07-14 12:55 ` [U-Boot] [PATCH 48/51] ihs_mdio: Make DM-compatible Mario Six
                   ` (3 subsequent siblings)
  50 siblings, 1 reply; 138+ messages in thread
From: Mario Six @ 2017-07-14 12:55 UTC (permalink / raw)
  To: u-boot

Fix some style violations in the ihs_mdio driver, and make the code more
readable where possible.

Signed-off-by: Mario Six <mario.six@gdsys.cc>
---

 board/gdsys/common/ihs_mdio.c | 10 +++++++---
 1 file changed, 7 insertions(+), 3 deletions(-)

diff --git a/board/gdsys/common/ihs_mdio.c b/board/gdsys/common/ihs_mdio.c
index 85a804d5cd..4e3bcd406f 100644
--- a/board/gdsys/common/ihs_mdio.c
+++ b/board/gdsys/common/ihs_mdio.c
@@ -38,7 +38,7 @@ static int ihs_mdio_reset(struct mii_dev *bus)
 }
 
 static int ihs_mdio_address(struct ihs_mdio_info *info, int addr, int dev_addr,
-			 int regnum)
+			    int regnum)
 {
 	FPGA_SET_REG(info->fpga, mdio.address_data, regnum);
 	FPGA_SET_REG(info->fpga, mdio.control,
@@ -61,7 +61,9 @@ static int ihs_mdio_read(struct mii_dev *bus, int addr, int dev_addr,
 	}
 
 	FPGA_SET_REG(info->fpga, mdio.control,
-		     ((addr & 0x1f) << 5) | ((info->clause45 ? dev_addr : regnum) & 0x1f) | (2 << 10));
+		     ((addr & 0x1f) << 5) |
+		      ((info->clause45 ? dev_addr : regnum) & 0x1f) |
+		      (2 << 10));
 
 	/* wait for rx data available */
 	udelay(100);
@@ -85,7 +87,9 @@ static int ihs_mdio_write(struct mii_dev *bus, int addr, int dev_addr,
 
 	FPGA_SET_REG(info->fpga, mdio.address_data, value);
 	FPGA_SET_REG(info->fpga, mdio.control,
-		     ((addr & 0x1f) << 5) | ((info->clause45 ? dev_addr : regnum) & 0x1f) | (1 << 10));
+		     ((addr & 0x1f) << 5) |
+		      ((info->clause45 ? dev_addr : regnum) & 0x1f) |
+		      (1 << 10));
 
 	return 0;
 }
-- 
2.11.0

^ permalink raw reply related	[flat|nested] 138+ messages in thread

* [U-Boot] [PATCH 48/51] ihs_mdio: Make DM-compatible
  2017-07-14 12:54 [U-Boot] [PATCH 00/51] gdsys: Add support for Gazerbeam board Mario Six
                   ` (46 preceding siblings ...)
  2017-07-14 12:55 ` [U-Boot] [PATCH 47/51] ihs_mdio: Fix style violations Mario Six
@ 2017-07-14 12:55 ` Mario Six
  2017-07-19  9:06   ` Simon Glass
  2017-07-14 12:55 ` [U-Boot] [PATCH 49/51] gazerbeam: Import Linux DT Mario Six
                   ` (2 subsequent siblings)
  50 siblings, 1 reply; 138+ messages in thread
From: Mario Six @ 2017-07-14 12:55 UTC (permalink / raw)
  To: u-boot

Make the ihs_mdio driver DM-compatible, while retaining the old
functionality for not-yet-converted boards.

Signed-off-by: Mario Six <mario.six@gdsys.cc>
---

 board/gdsys/common/ihs_mdio.c | 49 ++++++++++++++++++++++++++++++++++++++-----
 board/gdsys/common/ihs_mdio.h |  5 +++++
 2 files changed, 49 insertions(+), 5 deletions(-)

diff --git a/board/gdsys/common/ihs_mdio.c b/board/gdsys/common/ihs_mdio.c
index 4e3bcd406f..4609e9f8c2 100644
--- a/board/gdsys/common/ihs_mdio.c
+++ b/board/gdsys/common/ihs_mdio.c
@@ -5,15 +5,25 @@
  * SPDX-License-Identifier:	GPL-2.0+
  */
 
-#ifdef CONFIG_GDSYS_LEGACY_DRIVERS
-
 #include <common.h>
 
-#include <gdsys_fpga.h>
 #include <miiphy.h>
+#ifdef CONFIG_GDSYS_LEGACY_DRIVERS
+#include <gdsys_fpga.h>
+#else
+#include <ihs_fpga.h>
+#endif
 
 #include "ihs_mdio.h"
 
+#ifndef CONFIG_GDSYS_LEGACY_DRIVERS
+enum {
+	REG_MDIO_CONTROL = 0x0,
+	REG_MDIO_ADDR_DATA = 0x2,
+	REG_MDIO_RX_DATA = 0x4,
+};
+#endif
+
 static int ihs_mdio_idle(struct mii_dev *bus)
 {
 	struct ihs_mdio_info *info = bus->priv;
@@ -21,7 +31,11 @@ static int ihs_mdio_idle(struct mii_dev *bus)
 	unsigned int ctr = 0;
 
 	do {
+#ifdef CONFIG_GDSYS_LEGACY_DRIVERS
 		FPGA_GET_REG(info->fpga, mdio.control, &val);
+#else
+		val = fpga_in_le16(info->fpga, info->base + REG_MDIO_CONTROL);
+#endif
 		udelay(100);
 		if (ctr++ > 10)
 			return -1;
@@ -40,9 +54,17 @@ static int ihs_mdio_reset(struct mii_dev *bus)
 static int ihs_mdio_address(struct ihs_mdio_info *info, int addr, int dev_addr,
 			    int regnum)
 {
+#ifdef CONFIG_GDSYS_LEGACY_DRIVERS
 	FPGA_SET_REG(info->fpga, mdio.address_data, regnum);
 	FPGA_SET_REG(info->fpga, mdio.control,
 		     ((addr & 0x1f) << 5) | (dev_addr & 0x1f) | (0 << 10));
+#else
+	fpga_out_le16(info->fpga, info->base + REG_MDIO_ADDR_DATA, regnum);
+	fpga_out_le16(info->fpga, info->base + REG_MDIO_CONTROL,
+		      ((addr & 0x1f) << 5) |
+		       (dev_addr & 0x1f) |
+		       (0 << 10));
+#endif
 
 	return 0;
 }
@@ -60,15 +82,26 @@ static int ihs_mdio_read(struct mii_dev *bus, int addr, int dev_addr,
 		ihs_mdio_idle(bus);
 	}
 
+#ifdef CONFIG_GDSYS_LEGACY_DRIVERS
 	FPGA_SET_REG(info->fpga, mdio.control,
 		     ((addr & 0x1f) << 5) |
 		      ((info->clause45 ? dev_addr : regnum) & 0x1f) |
 		      (2 << 10));
+#else
+	fpga_out_le16(info->fpga, info->base + REG_MDIO_CONTROL,
+		      ((addr & 0x1f) << 5) |
+		       ((info->clause45 ? dev_addr : regnum) & 0x1f) |
+		       (2 << 10));
+#endif
 
 	/* wait for rx data available */
 	udelay(100);
 
+#ifdef CONFIG_GDSYS_LEGACY_DRIVERS
 	FPGA_GET_REG(info->fpga, mdio.rx_data, &val);
+#else
+	val = fpga_in_le16(info->fpga, info->base + REG_MDIO_RX_DATA);
+#endif
 
 	return val;
 }
@@ -85,11 +118,19 @@ static int ihs_mdio_write(struct mii_dev *bus, int addr, int dev_addr,
 		ihs_mdio_idle(bus);
 	}
 
+#ifdef CONFIG_GDSYS_LEGACY_DRIVERS
 	FPGA_SET_REG(info->fpga, mdio.address_data, value);
 	FPGA_SET_REG(info->fpga, mdio.control,
 		     ((addr & 0x1f) << 5) |
 		      ((info->clause45 ? dev_addr : regnum) & 0x1f) |
 		      (1 << 10));
+#else
+	fpga_out_le16(info->fpga, info->base + REG_MDIO_ADDR_DATA, value);
+	fpga_out_le16(info->fpga, info->base + REG_MDIO_CONTROL,
+		      ((addr & 0x1f) << 5) |
+		       ((info->clause45 ? dev_addr : regnum) & 0x1f) |
+		       (1 << 10));
+#endif
 
 	return 0;
 }
@@ -112,5 +153,3 @@ int ihs_mdio_init(struct ihs_mdio_info *info)
 
 	return mdio_register(bus);
 }
-
-#endif /* CONFIG_GDSYS_LEGACY_DRIVERS */
diff --git a/board/gdsys/common/ihs_mdio.h b/board/gdsys/common/ihs_mdio.h
index 372f07569c..e787dc1642 100644
--- a/board/gdsys/common/ihs_mdio.h
+++ b/board/gdsys/common/ihs_mdio.h
@@ -9,7 +9,12 @@
 #define _IHS_MDIO_H_
 
 struct ihs_mdio_info {
+#ifdef CONFIG_GDSYS_LEGACY_DRIVERS
 	u32 fpga;
+#else
+	struct udevice *fpga;
+	int base;
+#endif
 	char *name;
 	bool clause45;
 };
-- 
2.11.0

^ permalink raw reply related	[flat|nested] 138+ messages in thread

* [U-Boot] [PATCH 49/51] gazerbeam: Import Linux DT
  2017-07-14 12:54 [U-Boot] [PATCH 00/51] gdsys: Add support for Gazerbeam board Mario Six
                   ` (47 preceding siblings ...)
  2017-07-14 12:55 ` [U-Boot] [PATCH 48/51] ihs_mdio: Make DM-compatible Mario Six
@ 2017-07-14 12:55 ` Mario Six
  2017-07-19  9:07   ` Simon Glass
  2017-07-14 12:55 ` [U-Boot] [PATCH 50/51] gazerbeam: Add u-boot specific dts include file Mario Six
  2017-07-14 12:55 ` [U-Boot] [PATCH 51/51] mpc83xx: Add gazerbeam board Mario Six
  50 siblings, 1 reply; 138+ messages in thread
From: Mario Six @ 2017-07-14 12:55 UTC (permalink / raw)
  To: u-boot

Import the Linux device tree for the Gazerbeam board.

Signed-off-by: Mario Six <mario.six@gdsys.cc>
---

 arch/powerpc/dts/gazerbeam.dts             | 539 +++++++++++++++++++++++++++++
 arch/powerpc/dts/gdsys/gazerbeam-base.dtsi | 205 +++++++++++
 arch/powerpc/dts/gdsys/mpc8308.dtsi        | 243 +++++++++++++
 3 files changed, 987 insertions(+)
 create mode 100644 arch/powerpc/dts/gazerbeam.dts
 create mode 100644 arch/powerpc/dts/gdsys/gazerbeam-base.dtsi
 create mode 100644 arch/powerpc/dts/gdsys/mpc8308.dtsi

diff --git a/arch/powerpc/dts/gazerbeam.dts b/arch/powerpc/dts/gazerbeam.dts
new file mode 100644
index 0000000000..35b7af4173
--- /dev/null
+++ b/arch/powerpc/dts/gazerbeam.dts
@@ -0,0 +1,539 @@
+/*
+ * Gazerbeam CON Device Tree Source
+ *
+ * (C) Copyright 2015
+ * Dirk Eibach, Guntermann & Drunck GmbH, eibach at gdsys.de
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ */
+
+/include/ "gdsys/mpc8308.dtsi"
+
+/include/ "gdsys/gazerbeam-base.dtsi"
+
+/ {
+};
+
+&board_lbc {
+	FPGA0:iocon_uart at 1,0 {
+		reg = <0x1 0x0 0x100000>;
+		interrupts = <48 0x8>;
+		interrupt-parent = <&ipic>;
+	};
+
+	FPGA1:iocon_uart at 2,0 {
+		reg = <0x2 0x0 0x100000>;
+		interrupts = <17 0x8>;
+		interrupt-parent = <&ipic>;
+	};
+};
+
+&FPGA0 {
+	compatible = "gdsys,iocon_fpga";
+	#gpio-cells = <2>;
+	gpio-controller;
+	bus = <&FPGA0BUS>;
+	unit_id = <0>;
+	fpga-type = <1>;
+	rs232_base = <0x0050>;
+	usb_base = <0x0080>;
+	audio_base = <0x0040>;
+	/*
+	 * for every interrupt source there must be a dataset specifying
+	 * 1. type (1: standard)
+	 * 2. status register offset
+	 * 3. mask register offset
+	 * 4. default mask
+	 */
+	fpga_interrupt_sources =
+		<1 0x000a 0x000c 0x4000>, /* 0: TOP_INTERRUPT */
+		<1 0x001c 0x001e 0x0000>; /* 1: EXTENDED_INTERRUPT */
+	/*
+	 * for every interrupt there must be a dataset specifying
+	 * 1. type (1: status, 2: event)
+	 * 2. interrupt source index
+	 * 3. interrupt register bit
+	 * 4. mask register bit
+	 */
+	 #fpga_interrupt_map-cells = <4>;
+	fpga_interrupt_map =
+		<1 0 14 14>, /*  0: EXTENDED_INTERRUPT */
+		<1 0  0  0>, /*  1: VIDEO 0 */
+		<1 0  1  1>, /*  2: VIDEO 1 */
+		<1 0  2  2>, /*  3: VIDEO IC 0 */
+		<1 0  3  3>, /*  4: VIDEO IC 1 */
+		<1 0  4  4>, /*  5: IIC MAIN */
+		<1 0  6  6>, /*  6: IIC VIDEO 0 */
+		<1 0  7  7>, /*  7: IIC VIDEO 1 */
+		<1 1  0  0>, /*  8: OSD 0 */
+		<1 1  1  1>, /*  9: OSD 1 */
+		<1 1  2  2>, /* 10: SPDIF 0 */
+		<1 1  3  3>, /* 11: SPDIF 1 */
+		<1 0 12 12>, /* 12: COMM 0 */
+		<1 0 13 13>, /* 13: COMM 1 */
+		<1 0 10 10>, /* 14: COMM 2 */
+		<1 0 11 11>, /* 15: COMM 3 */
+		<2 0  5  5>, /* 16: MDIO */
+		<1 0  8  8>, /* 17: PHY */
+		<1 1  4  4>, /* 18: RS232 */
+		<1 1  5  5>, /* 19: AUDIO */
+		<1 1  8  8>, /* 20: PROC_AUDIO */
+		<1 1  7  7>, /* 21: USB/ETH-UART INT */
+		<2 1 10 10>, /* 22: AXI Bridge 0 */
+		<2 1 11 11>, /* 23: AXI Bridge 1 */
+		<2 1  9  9>, /* 24: USB/ETH-Secondary IIC */
+		<>;
+};
+
+&FPGA1 {
+	compatible = "gdsys,iocon_fpga";
+	#gpio-cells = <2>;
+	gpio-controller;
+	bus = <&FPGA1BUS>;
+	unit_id = <1>;
+	fpga-type = <1>;
+	rs232_base = <0x0050>;
+	usb_base = <0x0070>;
+	audio_base = <0x0040>;
+	/*
+	 * for every interrupt source there must be a dataset specifying
+	 * 1. type (1: standard)
+	 * 2. status register offset
+	 * 3. mask register offset
+	 * 4. default mask
+	 */
+	fpga_interrupt_sources =
+		<1 0x000a 0x000c 0x4000>, /* 0: TOP_INTERRUPT */
+		<1 0x001c 0x001e 0x0000>; /* 1: EXTENDED_INTERRUPT */
+	/*
+	 * for every interrupt there must be a dataset specifying
+	 * 1. type (1: status, 2: event)
+	 * 2. interrupt source index
+	 * 3. interrupt register bit
+	 * 4. mask register bit
+	 */
+	 #fpga_interrupt_map-cells = <4>;
+	fpga_interrupt_map =
+		<1 0 14 14>, /*  0: EXTENDED_INTERRUPT */
+		<1 0  0  0>, /*  1: VIDEO 0 */
+		<1 0  1  1>, /*  2: VIDEO 1 */
+		<1 0  2  2>, /*  3: VIDEO IC 0 */
+		<1 0  3  3>, /*  4: VIDEO IC 1 */
+		<1 0  4  4>, /*  5: IIC MAIN */
+		<1 0  6  6>, /*  6: IIC VIDEO 0 */
+		<1 0  7  7>, /*  7: IIC VIDEO 1 */
+		<1 1  0  0>, /*  8: OSD 0 */
+		<1 1  1  1>, /*  9: OSD 1 */
+		<1 1  2  2>, /* 10: SPDIF 0 */
+		<1 1  3  3>, /* 11: SPDIF 1 */
+		<1 0 12 12>, /* 12: COMM 0 */
+		<1 0 13 13>, /* 13: COMM 1 */
+		<1 0 10 10>, /* 14: COMM 2 */
+		<1 0 11 11>, /* 15: COMM 3 */
+		<2 0  5  5>, /* 16: MDIO */
+		<1 0  8  8>, /* 17: PHY */
+		<1 1  4  4>, /* 18: RS232 */
+		<1 1  5  5>, /* 19: AUDIO */
+		<1 1  8  8>, /* 20: PROC_AUDIO */
+		<1 1  7  7>, /* 21: USB/ETH-UART INT */
+		<2 1 10 10>, /* 22: AXI Bridge 0 */
+		<2 1 11 11>, /* 23: AXI Bridge 1 */
+		<2 1  9  9>, /* 24: USB/ETH-Secondary IIC */
+		<>;
+};
+
+/ {
+	FPGA0BUS: fpga0bus {
+		#address-cells = <1>;
+		#size-cells = <1>;
+		ranges = <0 0 0x00002000>;
+
+		compatible = "gdsys,soc";
+
+		fpga0_uart_usb {
+			compatible = "gdsys,ihs_simple_uart";
+			reg = <0xa0 0x08>;
+			fpga_interrupts = <21>;
+			line = <0>;
+		};
+
+		fpga0_iic_main {
+			compatible = "gdsys,ihs_i2cmaster";
+			reg = <0x60 0x10>;
+			fpga_interrupts = <5>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+
+			fpga0_dp_video0_redriver: fpga0_dp_video0_redriver {
+				compatible = "ti,sn75dp130";
+				reg = <0x2c>;
+				eq-i2c-enable = <3 2 1 0
+						 3 2 1 0
+						 3 2 1 0
+						 3 2 1 0>; /* 3.5 dB for all pe values for all lanes */
+			};
+			fpga0_dp_video1_redriver: fpga0_dp_video1_redriver {
+				compatible = "ti,sn75dp130";
+				reg = <0x2e>;
+				eq-i2c-enable = <3 2 1 0
+						 3 2 1 0
+						 3 2 1 0
+						 3 2 1 0>; /* 3.5 dB for all pe values for all lanes */
+			};
+			lm77 at 48 {
+				compatible = "national,lm77";
+				reg = <0x48>;
+			};
+			ads1015 at 49 {
+				compatible = "ti,ads1015";
+				reg = <0x49>;
+			};
+			ads1015 at 4b {
+				compatible = "ti,ads1015";
+				reg = <0x4b>;
+			};
+		};
+
+		fpga0_video0 {
+			compatible = "gdsys,ihs_video_out";
+			reg = <0x100 0x40>;
+			fpga_interrupts = <1 8>; /* VIDEO OSD */
+			osd_base = <0x180>;
+			osd_buffer_base = <0x1000>;
+			video_id = <0>;
+			fpga-force-pos-pol;
+			sync-source;
+			dp_tx = <&fpga0_dp_video0>;
+			clk_gen = <&fpga0_video0_clkgen>;
+		};
+
+		fpga0_iic_video0  {
+			compatible = "gdsys,ihs_i2cmaster";
+			reg = <0x1c0 0x10>;
+			fpga_interrupts = <6>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+
+			fpga0_video0_clkgen: fpga0_video0_clkgen {
+				compatible = "idt,ics8n3qv01";
+				reg = <0x6e>;
+				channel = <0>;
+			};
+		};
+
+		fpga0_axi_video0 {
+			#address-cells = <1>;
+			#size-cells = <1>;
+			compatible = "gdsys,ihs_axi";
+			reg = <0x170 0x10>;
+			fpga_interrupts = <22>;
+
+			fpga0_dp_video0: fpga0_dp_video0 {
+				compatible = "gdsys,logicore_dp_tx";
+				reg = <0x44a10000 0x1000>;
+				redriver = <&fpga0_dp_video0_redriver>;
+				video_id = <0>;
+			};
+		};
+
+		fpga0_video1 {
+			compatible = "gdsys,ihs_video_out";
+			reg = <0x200 0x40>;
+			fpga_interrupts = <2 9>; /* VIDEO OSD */
+			osd_base = <0x280>;
+			osd_buffer_base = <0x2000>;
+			video_id = <1>;
+			fpga-force-pos-pol;
+			sync-source;
+			dp_tx = <&fpga0_dp_video1>;
+			clk_gen = <&fpga0_video1_clkgen>;
+		};
+
+		fpga0_iic_video1  {
+			compatible = "gdsys,ihs_i2cmaster";
+			reg = <0x2c0 0x10>;
+			fpga_interrupts = <7>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+
+			fpga0_video1_clkgen: fpga0_video1_clkgen {
+				compatible = "idt,ics8n3qv01";
+				reg = <0x6e>;
+				channel = <1>;
+			};
+		};
+
+		fpga0_axi_video1 {
+			#address-cells = <1>;
+			#size-cells = <1>;
+			compatible = "gdsys,ihs_axi";
+			reg = <0x270 0x10>;
+			fpga_interrupts = <23>;
+
+			fpga0_dp_video1: fpga0_dp_video1 {
+				compatible = "gdsys,logicore_dp_tx";
+				reg = <0x44a10000 0x1000>;
+				redriver = <&fpga0_dp_video1_redriver>;
+				video_id = <1>;
+			};
+		};
+
+		fpga0_iic_usb {
+			compatible = "gdsys,ihs_i2cmaster";
+			reg = <0xb0 0x10>;
+			fpga_interrupts = <24>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+
+			pca9555 at 20 {
+				compatible = "nxp,pca9555";
+				reg = <0x20>;
+				#gpio-cells = <2>;
+				gpio-controller;
+			};
+		};
+
+		fpga0_ep0 {
+			compatible = "gdsys,io-endpoint";
+			reg = < 0x020 0x10
+				0x320 0x10
+				0x340 0x10
+				0x360 0x10>;
+			irq-model-local;
+			fpga_interrupts = <12 13 14 15>;
+			pollcycle = <200>;
+			nprot_channel = <16>;
+			uart_line = <0>;
+			ep_index = <0>;
+			line_protocol = <1>;
+		};
+
+		fpga0_mdio {
+			compatible = "gdsys,ihs_mdiomaster";
+			reg = <0x0058 0x10>;
+			fpga_interrupts = <16>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+
+			fpga0_phy0 {
+				compatible = "ethernet-phy-ieee802.3-c45";
+				device_type ="ethernet-phy";
+				reg = <0>;
+			};
+			fpga0_phy1 {
+				compatible = "ethernet-phy-ieee802.3-c45";
+				device_type ="ethernet-phy";
+				reg = <1>;
+			};
+			fpga0_phy2 {
+				compatible = "ethernet-phy-ieee802.3-c45";
+				device_type ="ethernet-phy";
+				reg = <2>;
+			};
+			fpga0_phy3 {
+				compatible = "ethernet-phy-ieee802.3-c45";
+				device_type ="ethernet-phy";
+				reg = <3>;
+			};
+		};
+
+	};
+
+
+	FPGA1BUS: fpga1bus {
+		#address-cells = <1>;
+		#size-cells = <1>;
+		ranges = <0 0 0x00002000>;
+
+		compatible = "gdsys,soc";
+
+		fpga1_uart_usb {
+			compatible = "gdsys,ihs_simple_uart";
+			reg = <0xa0 0x08>;
+			fpga_interrupts = <21>;
+			line = <4>; /* TODO check and FIX */
+		};
+
+		fpga1_iic_main {
+			compatible = "gdsys,ihs_i2cmaster";
+			reg = <0x60 0x10>;
+			fpga_interrupts = <5>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+
+			fpga1_dp_video0_redriver: fpga1_dp_video0_redriver {
+				compatible = "ti,sn75dp130";
+				reg = <0x2c>;
+				eq-i2c-enable = <3 2 1 0
+						 3 2 1 0
+						 3 2 1 0
+						 3 2 1 0>; /* 3.5 dB for all pe values for all lanes */
+			};
+			fpga1_dp_video1_redriver: fpga1_dp_video1_redriver {
+				compatible = "ti,sn75dp130";
+				reg = <0x2e>;
+				eq-i2c-enable = <3 2 1 0
+						 3 2 1 0
+						 3 2 1 0
+						 3 2 1 0>; /* 3.5 dB for all pe values for all lanes */
+			};
+			lm77 at 48 {
+				compatible = "national,lm77";
+				reg = <0x48>;
+			};
+			ads1015 at 49 {
+				compatible = "ti,ads1015";
+				reg = <0x49>;
+			};
+			ads1015 at 4b {
+				compatible = "ti,ads1015";
+				reg = <0x4b>;
+			};
+		};
+
+		fpga1_video0 {
+			compatible = "gdsys,ihs_video_out";
+			reg = <0x100 0x40>;
+			fpga_interrupts = <1 8>; /* VIDEO OSD */
+			osd_base = <0x180>;
+			osd_buffer_base = <0x1000>;
+			video_id = <4>;
+			fpga-force-pos-pol;
+			dp_tx = <&fpga1_dp_video0>;
+			clk_gen = <&fpga1_video0_clkgen>;
+		};
+
+		fpga1_iic_video0  {
+			compatible = "gdsys,ihs_i2cmaster";
+			reg = <0x1c0 0x10>;
+			fpga_interrupts = <6>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+
+			fpga1_video0_clkgen: fpga1_video0_clkgen {
+				compatible = "idt,ics8n3qv01";
+				reg = <0x6e>;
+				channel = <4>;
+			};
+		};
+
+		fpga1_axi_video0 {
+			#address-cells = <1>;
+			#size-cells = <1>;
+			compatible = "gdsys,ihs_axi";
+			reg = <0x170 0x10>;
+			fpga_interrupts = <22>;
+
+			fpga1_dp_video0: fpga1_dp_video0 {
+				compatible = "gdsys,logicore_dp_tx";
+				reg = <0x44a10000 0x1000>;
+				redriver = <&fpga1_dp_video0_redriver>;
+				video_id = <4>;
+			};
+		};
+
+		fpga1_video1 {
+			compatible = "gdsys,ihs_video_out";
+			reg = <0x200 0x40>;
+			fpga_interrupts = <2 9>; /* VIDEO OSD */
+			osd_base = <0x280>;
+			osd_buffer_base = <0x2000>;
+			video_id = <5>;
+			dp_tx = <&fpga1_dp_video1>;
+			clk_gen = <&fpga1_video1_clkgen>;
+		};
+
+		fpga1_iic_video1  {
+			compatible = "gdsys,ihs_i2cmaster";
+			reg = <0x2c0 0x10>;
+			fpga_interrupts = <7>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+
+			fpga1_video1_clkgen: fpga1_video1_clkgen {
+				compatible = "idt,ics8n3qv01";
+				reg = <0x6e>;
+				channel = <5>;
+			};
+		};
+
+		fpga1_axi_video1 {
+			#address-cells = <1>;
+			#size-cells = <1>;
+			compatible = "gdsys,ihs_axi";
+			reg = <0x270 0x10>;
+			fpga_interrupts = <23>;
+
+			fpga1_dp_video1: fpga1_dp_video1 {
+				compatible = "gdsys,logicore_dp_tx";
+				reg = <0x44a10000 0x1000>;
+				redriver = <&fpga1_dp_video1_redriver>;
+				video_id = <5>;
+			};
+		};
+
+		fpga1_iic_usb {
+			compatible = "gdsys,ihs_i2cmaster";
+			reg = <0xb0 0x10>;
+			fpga_interrupts = <24>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+
+			pca9555 at 20 {
+				compatible = "nxp,pca9555";
+				reg = <0x20>;
+				#gpio-cells = <2>;
+				gpio-controller;
+			};
+		};
+
+		fpga1_ep0 {
+			compatible = "gdsys,io-endpoint";
+			reg = < 0x020 0x10
+				0x320 0x10
+				0x340 0x10
+				0x360 0x10>;
+			irq-model-local;
+			fpga_interrupts = <12 13 14 15>;
+			pollcycle = <200>;
+			nprot_channel = <17>;
+			uart_line = <1>;
+			ep_index = <0>;
+			line_protocol = <1>;
+		};
+
+		fpga1_mdio {
+			compatible = "gdsys,ihs_mdiomaster";
+			reg = <0x0058 0x10>;
+			fpga_interrupts = <16>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+
+			fpga1_phy0 {
+				compatible = "ethernet-phy-ieee802.3-c45";
+				device_type ="ethernet-phy";
+				reg = <0>;
+			};
+			fpga1_phy1 {
+				compatible = "ethernet-phy-ieee802.3-c45";
+				device_type ="ethernet-phy";
+				reg = <1>;
+			};
+			fpga1_phy2 {
+				compatible = "ethernet-phy-ieee802.3-c45";
+				device_type ="ethernet-phy";
+				reg = <2>;
+			};
+			fpga1_phy3 {
+				compatible = "ethernet-phy-ieee802.3-c45";
+				device_type ="ethernet-phy";
+				reg = <3>;
+			};
+		};
+
+	};
+
+};
diff --git a/arch/powerpc/dts/gdsys/gazerbeam-base.dtsi b/arch/powerpc/dts/gdsys/gazerbeam-base.dtsi
new file mode 100644
index 0000000000..9382107186
--- /dev/null
+++ b/arch/powerpc/dts/gdsys/gazerbeam-base.dtsi
@@ -0,0 +1,205 @@
+/*
+ * Gazerbeam Device Tree Source
+ *
+ * (C) Copyright 2015
+ * Dirk Eibach, Guntermann & Drunck GmbH, eibach at gdsys.de
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ */
+
+/ {
+	model = "gdsys,gazerbeam";
+	compatible = "fsl,mpc8308rdb";
+
+	aliases {
+		ethernet0 = &enet0;
+		ethernet1 = &enet1;
+	};
+
+	memory {
+		device_type = "memory";
+	};
+
+	chosen {
+		stdout-path = "/immr at e0000000/serial at 4600";
+	};
+};
+
+&board_lbc {
+	ranges = <0x0 0x0 0xfe000000 0x00800000
+	          0x1 0x0 0xe0600000 0x00003000
+		  0x2 0x0 0xe0700000 0x00003000>;
+
+	flash at 0,0 {
+		#address-cells = <1>;
+		#size-cells = <1>;
+		compatible = "cfi-flash";
+		reg = <0x0 0x0 0x100000>;
+		bank-width = <2>;
+		device-width = <1>;
+
+		u-boot at 0 {
+			reg = <0x0 0x60000>;
+		};
+		env at 60000 {
+			reg = <0x60000 0x10000>;
+		};
+		env1 at 70000 {
+			reg = <0x70000 0x10000>;
+		};
+		spare at 80000 {
+			reg = <0x80000 0x80000>;
+		};
+	};
+};
+
+&enet1 {
+	status = "okay";
+};
+
+&IIC {
+	fsl,preserve-clocking;
+
+	at97sc3205t at 29 {
+		compatible = "atmel,at97sc3204t";
+		reg = <0x29>;
+	};
+
+	lm77 at 48 {
+		compatible = "national,lm77";
+		reg = <0x48>;
+	};
+
+	ads1015 at 49 {
+		compatible = "ti,ads1015";
+		reg = <0x49>;
+	};
+
+	lm77 at 4a {
+		compatible = "national,lm77";
+		reg = <0x4a>;
+	};
+
+	emc2305 at 4c {
+		compatible = "smsc,emc2305";
+		#address-cells = <1>;
+		#size-cells = <0>;
+		reg = <0x4c>;
+		fan at 0 {
+			reg = <0>;
+		};
+		fan at 1 {
+			reg = <1>;
+		};
+		fan at 2 {
+			reg = <2>;
+		};
+		fan at 3 {
+			reg = <3>;
+		};
+		fan at 4 {
+			reg = <4>;
+		};
+	};
+
+	cs4265 at 4f {
+		compatible = "cirrus,cs4265";
+		reg = <0x0000004f>;
+	};
+
+	at24c512 at 54 {
+		compatible = "atmel,24c512";
+		reg = <0x54>;
+	};
+
+	ds1339 at 68 {
+		compatible = "dallas,ds1339";
+		reg = <0x68>;
+	};
+
+	/* PPC-Board */
+	pca9698 at 22 {
+		compatible = "nxp,pca9698";
+		reg = <0x22>;
+		#gpio-cells = <2>;
+		gpio-controller;
+	};
+
+	/* IO-Board */
+	pca9698 at 20 {
+		compatible = "nxp,pca9698";
+		reg = <0x20>;
+		#gpio-cells = <2>;
+		gpio-controller;
+	};
+};
+
+&IIC2 {
+	fsl,preserve-clocking;
+
+	status = "okay";
+
+	/* MC2/SC-Board */
+	GPIO_VB0: pca9698 at 20 {
+		compatible = "nxp,pca9698";
+		reg = <0x20>;
+		#gpio-cells = <2>;
+		gpio-controller;
+	};
+
+	/* MC4-Board */
+	GPIO_VB1: pca9698 at 22 {
+		compatible = "nxp,pca9698";
+		reg = <0x22>;
+		#gpio-cells = <2>;
+		gpio-controller;
+	};
+};
+
+&SPI {
+	gpios = < /*SPI-CSS-FPGA-U-FLASH#*/ &gpio0 8 0
+		  /*SPI-CSS-FPGA-O-FLASH#*/ &gpio0 6 0
+		  /*SPI-CSS-STDP1_U-FLASH#*/ &gpio0 12 0
+		  /*SPI-CSS-STDP2_U-FLASH#*/ &gpio0 11 0
+		  /*SPI-CSS-STDP1_O-FLASH#*/ &gpio0 15 0
+		  /*SPI-CSS-STDP2_O-FLASH#*/ &gpio0 3 0>;
+
+	m25p16 at 0 {
+		compatible = "st,n25q128a11";
+		reg = <0x0>;
+		spi-max-frequency = <20000000>;
+	};
+
+	m25p16 at 1 {
+		compatible = "st,n25q128a11";
+		reg = <0x1>;
+		spi-max-frequency = <20000000>;
+	};
+
+	m25p16 at 2 {
+		compatible = "st,m25p40";
+		reg = <0x2>;
+		spi-max-frequency = <20000000>;
+	};
+
+	m25p16 at 3 {
+		compatible = "st,m25p40";
+		reg = <0x3>;
+		spi-max-frequency = <20000000>;
+	};
+
+	m25p16 at 4 {
+		compatible = "st,m25p40";
+		reg = <0x4>;
+		spi-max-frequency = <20000000>;
+	};
+
+	m25p16 at 5 {
+		compatible = "st,m25p40";
+		reg = <0x5>;
+		spi-max-frequency = <20000000>;
+	};
+};
diff --git a/arch/powerpc/dts/gdsys/mpc8308.dtsi b/arch/powerpc/dts/gdsys/mpc8308.dtsi
new file mode 100644
index 0000000000..61017fdb02
--- /dev/null
+++ b/arch/powerpc/dts/gdsys/mpc8308.dtsi
@@ -0,0 +1,243 @@
+/*
+ * Basic platform for gdsys mpc8308 based devices
+ *
+ * (C) Copyright 2014
+ * Dirk Eibach,  Guntermann & Drunck GmbH, eibach at gdsys.de
+ *
+ * based on mpc8308rdb
+ * Copyright 2009 Freescale Semiconductor Inc.
+ * Copyright 2010 Ilya Yanok, Emcraft Systems, yanok at emcraft.com
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ */
+
+/dts-v1/;
+
+/ {
+	#address-cells = <1>;
+	#size-cells = <1>;
+
+	aliases {
+		serial0 = &serial0;
+		serial1 = &serial1;
+	};
+
+	cpus {
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		PowerPC,8308 at 0 {
+			device_type = "cpu";
+			reg = <0x0>;
+			d-cache-line-size = <32>;
+			i-cache-line-size = <32>;
+			d-cache-size = <16384>;
+			i-cache-size = <16384>;
+			timebase-frequency = <0>;	// from bootloader
+			bus-frequency = <0>;		// from bootloader
+			clock-frequency = <0>;		// from bootloader
+		};
+	};
+
+	board_lbc: localbus at e0005000 {
+		#address-cells = <2>;
+		#size-cells = <1>;
+		compatible = "fsl,mpc8315-elbc", "fsl,elbc", "simple-bus";
+		reg = <0xe0005000 0x1000>;
+		interrupts = <77 0x8>;
+		interrupt-parent = <&ipic>;
+	};
+
+	board_soc: immr at e0000000 {
+		#address-cells = <1>;
+		#size-cells = <1>;
+		device_type = "soc";
+		compatible = "fsl,mpc8308-immr", "simple-bus";
+		ranges = <0 0xe0000000 0x00100000>;
+		reg = <0xe0000000 0x00000200>;
+		bus-frequency = <0>;
+
+		wdt at 200 {
+			device_type = "watchdog";
+			compatible = "mpc83xx_wdt";
+			reg = <0x200 0x100>;
+		};
+
+		IIC:i2c at 3000 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			cell-index = <0>;
+			compatible = "fsl-i2c";
+			reg = <0x3000 0x100>;
+			interrupts = <14 0x8>;
+			interrupt-parent = <&ipic>;
+			dfsrr;
+		};
+
+		IIC2: i2c at 3100 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			compatible = "fsl-i2c";
+			reg = <0x3100 0x100>;
+			interrupts = <15 0x8>;
+			interrupt-parent = <&ipic>;
+			dfsrr;
+			status = "disabled";
+		};
+
+		SPI:spi at 7000 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			cell-index = <0>;
+			compatible = "fsl,spi";
+			reg = <0x7000 0x1000>;
+			interrupts = <16 0x8>;
+			interrupt-parent = <&ipic>;
+			mode = "cpu";
+		};
+
+		sdhc at 2e000 {
+			compatible = "fsl,esdhc", "fsl,mpc8308-esdhc";
+			reg = <0x2e000 0x1000>;
+			interrupts = <42 0x2>;
+			interrupt-parent = <&ipic>;
+			sdhci,auto-cmd12;
+			/* Filled in by U-Boot */
+			clock-frequency = <0>;
+		};
+
+		serial0: serial at 4500 {
+			cell-index = <0>;
+			device_type = "serial";
+			compatible = "fsl,ns16550", "ns16550";
+			reg = <0x4500 0x100>;
+			clock-frequency = <133333333>;
+			interrupts = <9 0x8>;
+			interrupt-parent = <&ipic>;
+		};
+
+		serial1: serial at 4600 {
+			cell-index = <1>;
+			device_type = "serial";
+			compatible = "fsl,ns16550", "ns16550";
+			reg = <0x4600 0x100>;
+			clock-frequency = <133333333>;
+			interrupts = <10 0x8>;
+			interrupt-parent = <&ipic>;
+		};
+
+		gpio0: gpio at c00 {
+			#gpio-cells = <2>;
+			device_type = "gpio";
+			compatible = "fsl,mpc8308-gpio", "fsl,mpc8349-gpio";
+			reg = <0xc00 0x18>;
+			interrupts = <74 0x8>;
+			interrupt-parent = <&ipic>;
+			gpio-controller;
+		};
+
+		/* IPIC
+		 * interrupts cell = <intr #, sense>
+		 * sense values match linux IORESOURCE_IRQ_* defines:
+		 * sense == 8: Level, low assertion
+		 * sense == 2: Edge, high-to-low change
+		 */
+		ipic: interrupt-controller at 700 {
+			compatible = "fsl,ipic";
+			interrupt-controller;
+			#address-cells = <0>;
+			#interrupt-cells = <2>;
+			reg = <0x700 0x100>;
+			device_type = "ipic";
+		};
+
+		ipic-msi at 7c0 {
+			compatible = "fsl,ipic-msi";
+			reg = <0x7c0 0x40>;
+			msi-available-ranges = <0x0 0x100>;
+			interrupts = < 0x43 0x8
+					0x4  0x8
+					0x51 0x8
+					0x52 0x8
+					0x56 0x8
+					0x57 0x8
+					0x58 0x8
+					0x59 0x8 >;
+			interrupt-parent = < &ipic >;
+		};
+
+		dma at 2c000 {
+			compatible = "fsl,mpc8308-dma", "fsl,mpc5121-dma";
+			reg = <0x2c000 0x1800>;
+			interrupts = <3 0x8
+					94 0x8>;
+			interrupt-parent = < &ipic >;
+		};
+
+		enet0: ethernet at 24000 {
+			#address-cells = <1>;
+			#size-cells = <1>;
+			ranges = <0x0 0x24000 0x1000>;
+
+			cell-index = <0>;
+			device_type = "network";
+			model = "eTSEC";
+			compatible = "gianfar";
+			reg = <0x24000 0x1000>;
+			local-mac-address = [ 00 00 00 00 00 00 ];
+			interrupts = <32 0x8 33 0x8 34 0x8>;
+			interrupt-parent = <&ipic>;
+			tbi-handle = < &tbi0 >;
+			phy-handle = < &phy1 >;
+			fsl,magic-packet;
+
+			mdio at 520 {
+				#address-cells = <1>;
+				#size-cells = <0>;
+				compatible = "fsl,gianfar-mdio";
+				reg = <0x520 0x20>;
+				phy1: ethernet-phy at 1 {
+					reg = <0x1>;
+				};
+				phy2: ethernet-phy at 0 {
+					reg = <0x0>;
+					device_type = "ethernet-phy";
+				};
+				tbi0: tbi-phy at 11 {
+					reg = <0x11>;
+					device_type = "tbi-phy";
+				};
+			};
+		};
+
+		enet1: ethernet at 25000 {
+			#address-cells = <1>;
+			#size-cells = <1>;
+			cell-index = <1>;
+			device_type = "network";
+			model = "eTSEC";
+			compatible = "gianfar";
+			reg = <0x25000 0x1000>;
+			ranges = <0x0 0x25000 0x1000>;
+			local-mac-address = [ 00 00 00 00 00 00 ];
+			interrupts = <35 0x8 36 0x8 37 0x8>;
+			interrupt-parent = <&ipic>;
+			phy-handle = < &phy2 >;
+			status = "disabled";
+
+			mdio at 520 {
+				#address-cells = <1>;
+				#size-cells = <0>;
+				compatible = "fsl,gianfar-tbi";
+				reg = <0x520 0x20>;
+				tbi1: tbi-phy at 11 {
+					reg = <0x11>;
+					device_type = "tbi-phy";
+				};
+			};
+		};
+	};
+};
-- 
2.11.0

^ permalink raw reply related	[flat|nested] 138+ messages in thread

* [U-Boot] [PATCH 50/51] gazerbeam: Add u-boot specific dts include file
  2017-07-14 12:54 [U-Boot] [PATCH 00/51] gdsys: Add support for Gazerbeam board Mario Six
                   ` (48 preceding siblings ...)
  2017-07-14 12:55 ` [U-Boot] [PATCH 49/51] gazerbeam: Import Linux DT Mario Six
@ 2017-07-14 12:55 ` Mario Six
  2017-07-19  9:07   ` Simon Glass
  2017-07-14 12:55 ` [U-Boot] [PATCH 51/51] mpc83xx: Add gazerbeam board Mario Six
  50 siblings, 1 reply; 138+ messages in thread
From: Mario Six @ 2017-07-14 12:55 UTC (permalink / raw)
  To: u-boot

Add a U-Boot specific dts file, which encapsulates the needed
modifications to the Gazerbeam Linux device tree.

Signed-off-by: Mario Six <mario.six@gdsys.cc>
---

 arch/powerpc/dts/gazerbeam.dts              |   2 +
 arch/powerpc/dts/gdsys/gazerbeam-uboot.dtsi | 192 ++++++++++++++++++++++++++++
 2 files changed, 194 insertions(+)
 create mode 100644 arch/powerpc/dts/gdsys/gazerbeam-uboot.dtsi

diff --git a/arch/powerpc/dts/gazerbeam.dts b/arch/powerpc/dts/gazerbeam.dts
index 35b7af4173..df0081e5c4 100644
--- a/arch/powerpc/dts/gazerbeam.dts
+++ b/arch/powerpc/dts/gazerbeam.dts
@@ -537,3 +537,5 @@
 	};
 
 };
+
+/include/ "gdsys/gazerbeam-uboot.dtsi"
diff --git a/arch/powerpc/dts/gdsys/gazerbeam-uboot.dtsi b/arch/powerpc/dts/gdsys/gazerbeam-uboot.dtsi
new file mode 100644
index 0000000000..37a5d78283
--- /dev/null
+++ b/arch/powerpc/dts/gdsys/gazerbeam-uboot.dtsi
@@ -0,0 +1,192 @@
+/ {
+	aliases {
+		i2c0 = &IIC;
+		i2c1 = &IIC2;
+		i2c2 = "/fpga0bus/fpga0_iic_main";
+		i2c3 = "/fpga0bus/fpga0_iic_video0";
+		i2c4 = "/fpga0bus/fpga0_iic_video1";
+		i2c5 = "/fpga0bus/fpga0_iic_usb";
+	};
+
+	REGMAP0: registermap {
+		compatible = "gdsys,ihs-fpga-regmap";
+		#address-cells = <2>;
+		#size-cells = <1>;
+
+		reflection-low at 0,15 {
+			compatible = "reflection-low";
+			reg = <0x0 15 16>;
+		};
+
+		versions at 2,15 {
+			compatible = "versions";
+			reg = <0x2 15 16>;
+		};
+
+		fpga-version at 4,15 {
+			compatible = "fpga-version";
+			reg = <0x4 15 16>;
+		};
+
+		fpga-features at 6,15 {
+			compatible = "fpga-features";
+			reg = <0x6 15 16>;
+		};
+
+		fpga-ext-features at 8,15 {
+			compatible = "fpga-ext-features";
+			reg = <0x8 15 16>;
+		};
+
+		control at 10,15 {
+			compatible = "control";
+			reg = <0x2 15 16>;
+		};
+
+		top-interrupt at A,15 {
+			compatible = "top-interrupt";
+			reg = <0xA 15 16>;
+		};
+	};
+};
+
+&FPGA0 {
+	regmap = <&REGMAP0>;
+
+	reset-gpios = <&IOPCA 26 0>;
+	done-gpios = <&GPIO_VB0 19 0>;
+	startupfin-gpios = <&gpio0 1 0 &gpio0 2 0>;
+};
+
+&FPGA0BUS {
+	ranges = <0x0 0xe0600000 0x00004000>;
+	fpga = <&FPGA0>;
+
+	fpga0_rxaui at fc0 {
+		compatible = "gdsys,rxaui_ctrl";
+		reg = <0x0fc0 0x10>;
+	};
+
+	fpga0_rxaui at fd0 {
+		compatible = "gdsys,rxaui_ctrl";
+		reg = <0x0fd0 0x10>;
+	};
+
+	fpga0_rxaui at fe0 {
+		compatible = "gdsys,rxaui_ctrl";
+		reg = <0x0fe0 0x10>;
+	};
+
+	fpga0_rxaui at ff0 {
+		compatible = "gdsys,rxaui_ctrl";
+		reg = <0x0ff0 0x10>;
+	};
+
+	fpga0_video0 {
+		mode = "640_480_60";
+	};
+
+	fpga0_axi_video0 {
+		fpga0_dp_video0 {
+			clocks = <&fpga0_video0_clkgen>;
+		};
+	};
+
+	fpga0_iic_video0  {
+		fpga0_video0_clkgen {
+			#clock-cells = <0>;
+		};
+	};
+
+	fpga0_video1 {
+		mode = "640_480_60";
+	};
+
+	fpga0_axi_video1 {
+		fpga0_dp_video1 {
+			clocks = <&fpga0_video0_clkgen>;
+		};
+	};
+
+	fpga0_iic_video1  {
+		fpga0_video1_clkgen {
+			#clock-cells = <0>;
+		};
+	};
+};
+
+&FPGA1BUS {
+	fpga1_video0 {
+		mode = "640_480_60";
+	};
+
+	fpga1_axi_video0 {
+		fpga1_dp_video0 {
+			clocks = <&fpga0_video0_clkgen>;
+		};
+	};
+
+	fpga1_iic_video0  {
+		fpga1_video0_clkgen {
+			#clock-cells = <0>;
+		};
+	};
+
+	fpga1_video1 {
+		mode = "640_480_60";
+	};
+
+	fpga1_axi_video1 {
+		fpga1_dp_video1 {
+			clocks = <&fpga0_video0_clkgen>;
+		};
+	};
+
+	fpga1_iic_video1  {
+		fpga1_video1_clkgen {
+			#clock-cells = <0>;
+		};
+	};
+};
+
+&board_soc {
+	u-boot,dm-pre-reloc;
+};
+
+&IIC {
+	compatible = "fsl-i2c";
+	u-boot,dm-pre-reloc;
+
+	IOPCA: pca9698 at 20 {
+		u-boot,dm-pre-reloc;
+	};
+
+	PPCPCA: pca9698 at 22 {
+		u-boot,dm-pre-reloc;
+	};
+
+	at97sc3205t at 29 {
+		u-boot,i2c-offset-len = <0>;
+	};
+};
+
+&IIC2 {
+	compatible = "fsl-i2c";
+	u-boot,dm-pre-reloc;
+
+	GPIO_VB0: pca9698 at 20 {
+		u-boot,dm-pre-reloc;
+	};
+
+	GPIO_VB1: pca9698 at 22 {
+		u-boot,dm-pre-reloc;
+	};
+};
+
+&GPIO_VB0 {
+	u-boot,dm-pre-reloc;
+};
+
+&gpio0 {
+	ngpios = <24>;
+};
-- 
2.11.0

^ permalink raw reply related	[flat|nested] 138+ messages in thread

* [U-Boot] [PATCH 51/51] mpc83xx: Add gazerbeam board
  2017-07-14 12:54 [U-Boot] [PATCH 00/51] gdsys: Add support for Gazerbeam board Mario Six
                   ` (49 preceding siblings ...)
  2017-07-14 12:55 ` [U-Boot] [PATCH 50/51] gazerbeam: Add u-boot specific dts include file Mario Six
@ 2017-07-14 12:55 ` Mario Six
  2017-07-19  9:07   ` Simon Glass
  50 siblings, 1 reply; 138+ messages in thread
From: Mario Six @ 2017-07-14 12:55 UTC (permalink / raw)
  To: u-boot

From: Dirk Eibach <dirk.eibach@gdsys.cc>

The gdsys gazerbeam board is based on a Freescale MPC8308 SOC.
It boots from NOR-Flash, kernel and rootfs are stored on
SD-Card.

On board peripherals include:
- 2x 10/100 Mbit/s Ethernet (optional)

Signed-off-by: Dirk Eibach <dirk.eibach@gdsys.cc>
Signed-off-by: Mario Six <mario.six@gdsys.cc>
---

 arch/powerpc/cpu/mpc83xx/Kconfig |   3 +
 arch/powerpc/dts/.gitignore      |   1 +
 arch/powerpc/dts/Makefile        |  15 +
 board/gdsys/common/Makefile      |   1 +
 board/gdsys/common/ioep-fpga.c   | 617 ++++++++++++++++++++++++++++++---------
 board/gdsys/mpc8308/Kconfig      |  19 ++
 board/gdsys/mpc8308/MAINTAINERS  |   2 +
 board/gdsys/mpc8308/Makefile     |   1 +
 board/gdsys/mpc8308/gazerbeam.c  | 332 +++++++++++++++++++++
 configs/gazerbeam_defconfig      |  76 +++++
 include/configs/gazerbeam.h      | 484 ++++++++++++++++++++++++++++++
 include/fdt_fixup.h              |   5 +
 12 files changed, 1416 insertions(+), 140 deletions(-)
 create mode 100644 arch/powerpc/dts/.gitignore
 create mode 100644 arch/powerpc/dts/Makefile
 create mode 100644 board/gdsys/mpc8308/gazerbeam.c
 create mode 100644 configs/gazerbeam_defconfig
 create mode 100644 include/configs/gazerbeam.h

diff --git a/arch/powerpc/cpu/mpc83xx/Kconfig b/arch/powerpc/cpu/mpc83xx/Kconfig
index cdd21a253a..0790b47aa4 100644
--- a/arch/powerpc/cpu/mpc83xx/Kconfig
+++ b/arch/powerpc/cpu/mpc83xx/Kconfig
@@ -91,6 +91,9 @@ config TARGET_STRIDER
 	bool "Support strider"
 	select SYS_FSL_ERRATUM_ESDHC111
 
+config TARGET_GAZERBEAM
+	bool "Support gazerbeam"
+
 endchoice
 
 source "board/esd/vme8349/Kconfig"
diff --git a/arch/powerpc/dts/.gitignore b/arch/powerpc/dts/.gitignore
new file mode 100644
index 0000000000..b60ed208c7
--- /dev/null
+++ b/arch/powerpc/dts/.gitignore
@@ -0,0 +1 @@
+*.dtb
diff --git a/arch/powerpc/dts/Makefile b/arch/powerpc/dts/Makefile
new file mode 100644
index 0000000000..7a0c61ffaa
--- /dev/null
+++ b/arch/powerpc/dts/Makefile
@@ -0,0 +1,15 @@
+#
+# SPDX-License-Identifier:      GPL-2.0+
+#
+
+dtb-$(CONFIG_TARGET_GAZERBEAM) += gazerbeam.dtb
+
+targets += $(dtb-y)
+
+DTC_FLAGS += -R 4 -p 0x1000
+
+PHONY += dtbs
+dtbs: $(addprefix $(obj)/, $(dtb-y))
+        @:
+
+clean-files := *.dtb
diff --git a/board/gdsys/common/Makefile b/board/gdsys/common/Makefile
index 6f2fea207f..52561db2e1 100644
--- a/board/gdsys/common/Makefile
+++ b/board/gdsys/common/Makefile
@@ -13,3 +13,4 @@ obj-$(CONFIG_STRIDER) += mclink.o dp501.o phy.o ioep-fpga.o adv7611.o ch7301.o
 obj-$(CONFIG_STRIDER) += fanctrl.o
 obj-$(CONFIG_STRIDER_CON) += osd.o
 obj-$(CONFIG_STRIDER_CON_DP) += osd.o
+obj-$(CONFIG_TARGET_GAZERBEAM) += osd.o ihs_mdio.o ioep-fpga.o
diff --git a/board/gdsys/common/ioep-fpga.c b/board/gdsys/common/ioep-fpga.c
index a666b93445..24585672f6 100644
--- a/board/gdsys/common/ioep-fpga.c
+++ b/board/gdsys/common/ioep-fpga.c
@@ -11,231 +11,568 @@
 
 #include <gdsys_fpga.h>
 
-enum {
-	UNITTYPE_MAIN_SERVER = 0,
-	UNITTYPE_MAIN_USER = 1,
-	UNITTYPE_VIDEO_SERVER = 2,
-	UNITTYPE_VIDEO_USER = 3,
+enum pcb_video_type {
+	PCB_DVI_SL,
+	PCB_DP_165MPIX,
+	PCB_DP_300MPIX,
+	PCB_HDMI,
+	PCB_DP_1_2,
+	PCB_HDMI_2_0,
 };
 
-enum {
-	UNITTYPEPCB_DVI = 0,
-	UNITTYPEPCB_DP_165 = 1,
-	UNITTYPEPCB_DP_300 = 2,
-	UNITTYPEPCB_HDMI = 3,
+enum pcb_transmission_type {
+	PCB_CAT_1G,
+	PCB_FIBER_3G,
+	PCB_CAT_10G,
+	PCB_FIBER_10G,
 };
 
-enum {
-	COMPRESSION_NONE = 0,
-	COMPRESSION_TYPE_1 = 1,
-	COMPRESSION_TYPE_1_2 = 3,
-	COMPRESSION_TYPE_1_2_3 = 7,
+enum carrier_speed {
+	CARRIER_SPEED_1G,
+	CARRIER_SPEED_3G,
+	CARRIER_SPEED_2_5G = CARRIER_SPEED_3G,
+	CARRIER_SPEED_10G,
 };
 
-enum {
-	AUDIO_NONE = 0,
-	AUDIO_TX = 1,
-	AUDIO_RX = 2,
-	AUDIO_RXTX = 3,
+enum ram_config {
+	RAM_DDR2_32BIT_295MBPS,
+	RAM_DDR3_32BIT_590MBPS,
+	RAM_DDR3_48BIT_590MBPS,
+	RAM_DDR3_64BIT_1800MBPS,
+	RAM_DDR3_48BIT_1800MBPS,
 };
 
-enum {
-	SYSCLK_147456 = 0,
+enum sysclock {
+	SYSCLK_147456,
 };
 
-enum {
-	RAM_DDR2_32 = 0,
-	RAM_DDR3_32 = 1,
-	RAM_DDR3_48 = 2,
+struct fpga_versions {
+	bool video_channel;
+	bool con_side;
+	enum pcb_video_type pcb_video_type;
+	enum pcb_transmission_type pcb_transmission_type;
+	unsigned int hw_version;
 };
 
-enum {
-	CARRIER_SPEED_1G = 0,
-	CARRIER_SPEED_2_5G = 1,
+struct fpga_features {
+	u8 video_channels;
+	u8 carriers;
+	enum carrier_speed carrier_speed;
+	enum ram_config ram_config;
+	enum sysclock sysclock;
+
+	bool pcm_tx;
+	bool pcm_rx;
+	bool spdif_tx;
+	bool spdif_rx;
+	bool usb2;
+	bool rs232;
+	bool compression_type1;
+	bool compression_type2;
+	bool compression_type3;
+	bool interlace;
+	bool osd;
+	bool compression_pipes;
 };
 
-bool ioep_fpga_has_osd(unsigned int fpga)
+#ifdef CONFIG_SYS_FPGA_FLAVOR_GAZERBEAM
+
+static int get_versions(unsigned int fpga, struct fpga_versions *versions)
 {
-	u16 fpga_features;
-	unsigned feature_osd;
+	enum {
+		VERSIONS_FPGA_VIDEO_CHANNEL = BIT(12),
+		VERSIONS_FPGA_CON_SIDE = BIT(13),
+		VERSIONS_FPGA_SC = BIT(14),
+		VERSIONS_PCB_CON = BIT(9),
+		VERSIONS_PCB_SC = BIT(8),
+		VERSIONS_PCB_VIDEO_MASK = 0x3 << 6,
+		VERSIONS_PCB_VIDEO_DP_1_2 = 0x0 << 6,
+		VERSIONS_PCB_VIDEO_HDMI_2_0 = 0x1 << 6,
+		VERSIONS_PCB_TRANSMISSION_MASK = 0x3 << 4,
+		VERSIONS_PCB_TRANSMISSION_FIBER_10G = 0x0 << 4,
+		VERSIONS_PCB_TRANSMISSION_CAT_10G = 0x1 << 4,
+		VERSIONS_PCB_TRANSMISSION_FIBER_3G = 0x2 << 4,
+		VERSIONS_PCB_TRANSMISSION_CAT_1G = 0x3 << 4,
+		VERSIONS_HW_VER_MASK = 0xf << 0,
+	};
+	u16 raw_versions;
+
+	memset(versions, 0, sizeof(struct fpga_versions));
+
+	FPGA_GET_REG(fpga, versions, &raw_versions);
+
+	versions->video_channel = raw_versions & VERSIONS_FPGA_VIDEO_CHANNEL;
+	versions->con_side = raw_versions & VERSIONS_FPGA_CON_SIDE;
+
+	switch (raw_versions & VERSIONS_PCB_VIDEO_MASK) {
+	case VERSIONS_PCB_VIDEO_DP_1_2:
+		versions->pcb_video_type = PCB_DP_1_2;
+		break;
+
+	case VERSIONS_PCB_VIDEO_HDMI_2_0:
+		versions->pcb_video_type = PCB_HDMI_2_0;
+		break;
+	}
+
+	switch (raw_versions & VERSIONS_PCB_TRANSMISSION_MASK) {
+	case VERSIONS_PCB_TRANSMISSION_FIBER_10G:
+		versions->pcb_transmission_type = PCB_FIBER_10G;
+		break;
+
+	case VERSIONS_PCB_TRANSMISSION_CAT_10G:
+		versions->pcb_transmission_type = PCB_CAT_10G;
+		break;
+
+	case VERSIONS_PCB_TRANSMISSION_FIBER_3G:
+		versions->pcb_transmission_type = PCB_FIBER_3G;
+		break;
+
+	case VERSIONS_PCB_TRANSMISSION_CAT_1G:
+		versions->pcb_transmission_type = PCB_CAT_1G;
+		break;
+
+	}
 
-	FPGA_GET_REG(0, fpga_features, &fpga_features);
-	feature_osd = fpga_features & (1<<11);
+	versions->hw_version = raw_versions & VERSIONS_HW_VER_MASK;
 
-	return feature_osd;
+	return 0;
 }
 
-void ioep_fpga_print_info(unsigned int fpga)
+static int get_features(unsigned int fpga, struct fpga_features *features)
 {
-	u16 versions;
-	u16 fpga_version;
-	u16 fpga_features;
-	unsigned unit_type;
-	unsigned unit_type_pcb_video;
-	unsigned feature_compression;
-	unsigned feature_osd;
-	unsigned feature_audio;
-	unsigned feature_sysclock;
-	unsigned feature_ramconfig;
-	unsigned feature_carrier_speed;
-	unsigned feature_carriers;
-	unsigned feature_video_channels;
-
-	FPGA_GET_REG(fpga, versions, &versions);
-	FPGA_GET_REG(fpga, fpga_version, &fpga_version);
-	FPGA_GET_REG(fpga, fpga_features, &fpga_features);
-
-	unit_type = (versions & 0xf000) >> 12;
-	unit_type_pcb_video = (versions & 0x01c0) >> 6;
-	feature_compression = (fpga_features & 0xe000) >> 13;
-	feature_osd = fpga_features & (1<<11);
-	feature_audio = (fpga_features & 0x0600) >> 9;
-	feature_sysclock = (fpga_features & 0x0180) >> 7;
-	feature_ramconfig = (fpga_features & 0x0060) >> 5;
-	feature_carrier_speed = fpga_features & (1<<4);
-	feature_carriers = (fpga_features & 0x000c) >> 2;
-	feature_video_channels = fpga_features & 0x0003;
-
-	switch (unit_type) {
-	case UNITTYPE_MAIN_SERVER:
-	case UNITTYPE_MAIN_USER:
-		printf("Mainchannel");
+	enum {
+		FEATURE_SPDIF_RX = BIT(15),
+		FEATURE_SPDIF_TX = BIT(14),
+		FEATURE_PCM_RX = BIT(13),
+		FEATURE_PCM_TX = BIT(12),
+		FEATURE_RAM_MASK = GENMASK(11, 8),
+		FEATURE_RAM_DDR2_32BIT_295MBPS = 0x0 << 8,
+		FEATURE_RAM_DDR3_32BIT_590MBPS = 0x1 << 8,
+		FEATURE_RAM_DDR3_48BIT_590MBPS = 0x2 << 8,
+		FEATURE_RAM_DDR3_64BIT_1800MBPS = 0x3 << 8,
+		FEATURE_RAM_DDR3_48BIT_1800MBPS = 0x4 << 8,
+		FEATURE_CARRIER_SPEED_MASK = GENMASK(7, 6),
+		FEATURE_CARRIER_SPEED_1G = 0x0 << 6,
+		FEATURE_CARRIER_SPEED_2_5G = 0x1 << 6,
+		FEATURE_CARRIER_SPEED_10G = 0x2 << 6,
+		FEATURE_CARRIERS_MASK = GENMASK(5, 4),
+		FEATURE_CARRIERS_0 = 0x0 << 4,
+		FEATURE_CARRIERS_1 = 0x1 << 4,
+		FEATURE_CARRIERS_2 = 0x2 << 4,
+		FEATURE_CARRIERS_4 = 0x3 << 4,
+		FEATURE_USB2 = BIT(3),
+		FEATURE_VIDEOCHANNELS_MASK = GENMASK(2, 0),
+		FEATURE_VIDEOCHANNELS_0 = 0x0 << 0,
+		FEATURE_VIDEOCHANNELS_1 = 0x1 << 0,
+		FEATURE_VIDEOCHANNELS_1_1 = 0x2 << 0,
+		FEATURE_VIDEOCHANNELS_2 = 0x3 << 0,
+	};
+
+	enum {
+		EXT_FEATURE_OSD = BIT(15),
+		EXT_FEATURE_ETHERNET = BIT(9),
+		EXT_FEATURE_INTERLACE = BIT(8),
+		EXT_FEATURE_RS232 = BIT(7),
+		EXT_FEATURE_COMPRESSION_PERF_MASK = GENMASK(6, 4),
+		EXT_FEATURE_COMPRESSION_PERF_1X = 0x0 << 4,
+		EXT_FEATURE_COMPRESSION_PERF_2X = 0x1 << 4,
+		EXT_FEATURE_COMPRESSION_PERF_4X = 0x2 << 4,
+		EXT_FEATURE_COMPRESSION_TYPE1 = BIT(0),
+		EXT_FEATURE_COMPRESSION_TYPE2 = BIT(1),
+		EXT_FEATURE_COMPRESSION_TYPE3 = BIT(2),
+	};
+
+	u16 raw_features;
+	u16 raw_extended_features;
+
+	memset(features, 0, sizeof(struct fpga_features));
+
+	FPGA_GET_REG(fpga, fpga_features, &raw_features);
+	FPGA_GET_REG(fpga, fpga_ext_features, &raw_extended_features);
+
+	switch (raw_features & FEATURE_VIDEOCHANNELS_MASK) {
+	case FEATURE_VIDEOCHANNELS_0:
+		features->video_channels = 0;
 		break;
 
-	case UNITTYPE_VIDEO_SERVER:
-	case UNITTYPE_VIDEO_USER:
-		printf("Videochannel");
+	case FEATURE_VIDEOCHANNELS_1:
+		features->video_channels = 1;
 		break;
 
-	default:
-		printf("UnitType %d(not supported)", unit_type);
+	case FEATURE_VIDEOCHANNELS_1_1:
+	case FEATURE_VIDEOCHANNELS_2:
+		features->video_channels = 2;
 		break;
-	}
+	};
 
-	switch (unit_type) {
-	case UNITTYPE_MAIN_SERVER:
-	case UNITTYPE_VIDEO_SERVER:
-		printf(" Server");
-		if (versions & (1<<4))
-			printf(" UC");
+	switch (raw_features & FEATURE_CARRIERS_MASK) {
+	case FEATURE_CARRIERS_0:
+		features->carriers = 0;
 		break;
 
-	case UNITTYPE_MAIN_USER:
-	case UNITTYPE_VIDEO_USER:
-		printf(" User");
+	case FEATURE_CARRIERS_1:
+		features->carriers = 1;
 		break;
 
-	default:
+	case FEATURE_CARRIERS_2:
+		features->carriers = 2;
+		break;
+
+	case FEATURE_CARRIERS_4:
+		features->carriers = 4;
 		break;
 	}
 
-	if (versions & (1<<5))
-		printf(" Fiber");
-	else
-		printf(" CAT");
+	switch (raw_features & FEATURE_CARRIER_SPEED_MASK) {
+	case FEATURE_CARRIER_SPEED_1G:
+		features->carrier_speed = CARRIER_SPEED_1G;
+		break;
+	case FEATURE_CARRIER_SPEED_2_5G:
+		features->carrier_speed = CARRIER_SPEED_2_5G;
+		break;
+	case FEATURE_CARRIER_SPEED_10G:
+		features->carrier_speed = CARRIER_SPEED_10G;
+		break;
+	}
 
-	switch (unit_type_pcb_video) {
-	case UNITTYPEPCB_DVI:
-		printf(" DVI,");
+	switch (raw_features & FEATURE_RAM_MASK) {
+	case FEATURE_RAM_DDR2_32BIT_295MBPS:
+		features->ram_config = RAM_DDR2_32BIT_295MBPS;
 		break;
 
-	case UNITTYPEPCB_DP_165:
-		printf(" DP 165MPix/s,");
+	case FEATURE_RAM_DDR3_32BIT_590MBPS:
+		features->ram_config = RAM_DDR3_32BIT_590MBPS;
 		break;
 
-	case UNITTYPEPCB_DP_300:
-		printf(" DP 300MPix/s,");
+	case FEATURE_RAM_DDR3_48BIT_590MBPS:
+		features->ram_config = RAM_DDR3_48BIT_590MBPS;
 		break;
 
-	case UNITTYPEPCB_HDMI:
-		printf(" HDMI,");
+	case FEATURE_RAM_DDR3_64BIT_1800MBPS:
+		features->ram_config = RAM_DDR3_64BIT_1800MBPS;
+		break;
+
+	case FEATURE_RAM_DDR3_48BIT_1800MBPS:
+		features->ram_config = RAM_DDR3_48BIT_1800MBPS;
 		break;
 	}
 
-	printf(" FPGA V %d.%02d\n       features:",
-	       fpga_version / 100, fpga_version % 100);
+	features->pcm_tx = raw_features & FEATURE_PCM_TX;
+	features->pcm_rx = raw_features & FEATURE_PCM_RX;
+	features->spdif_tx = raw_features & FEATURE_SPDIF_TX;
+	features->spdif_rx = raw_features & FEATURE_SPDIF_RX;
+	features->usb2 = raw_features & FEATURE_USB2;
+	features->rs232 = raw_extended_features & EXT_FEATURE_RS232;
+	features->compression_type1 = raw_extended_features & EXT_FEATURE_COMPRESSION_TYPE1;
+	features->compression_type2 = raw_extended_features & EXT_FEATURE_COMPRESSION_TYPE2;
+	features->compression_type3 = raw_extended_features & EXT_FEATURE_COMPRESSION_TYPE3;
+	features->interlace = raw_extended_features & EXT_FEATURE_INTERLACE;
+	features->osd = raw_extended_features & EXT_FEATURE_OSD;
+	features->compression_pipes = raw_extended_features & EXT_FEATURE_COMPRESSION_PERF_MASK;
+
+	return 0;
+}
+
+#else
+
+static int get_versions(unsigned int fpga, struct fpga_versions *versions)
+{
+	enum {
+		/* HW version encoding is a mess, leave it for the moment */
+		VERSIONS_HW_VER_MASK = 0xf << 0,
+		VERSIONS_PIX_CLOCK_GEN_IDT8N3QV01 = BIT(4),
+		VERSIONS_SFP = BIT(5),
+		VERSIONS_VIDEO_MASK = 0x7 << 6,
+		VERSIONS_VIDEO_DVI = 0x0 << 6,
+		VERSIONS_VIDEO_DP_165 = 0x1 << 6,
+		VERSIONS_VIDEO_DP_300 = 0x2 << 6,
+		VERSIONS_VIDEO_HDMI = 0x3 << 6,
+		VERSIONS_UT_MASK = 0xf << 12,
+		VERSIONS_UT_MAIN_SERVER = 0x0 << 12,
+		VERSIONS_UT_MAIN_USER = 0x1 << 12,
+		VERSIONS_UT_VIDEO_SERVER = 0x2 << 12,
+		VERSIONS_UT_VIDEO_USER = 0x3 << 12,
+	};
+	u16 raw_versions;
+
+	memset(versions, 0, sizeof(struct fpga_versions));
+
+	FPGA_GET_REG(fpga, versions, &raw_versions);
+
+	switch (raw_versions & VERSIONS_UT_MASK) {
+	case VERSIONS_UT_MAIN_SERVER:
+		versions->video_channel = false;
+		versions->con_side = false;
+		break;
+
+	case VERSIONS_UT_MAIN_USER:
+		versions->video_channel = false;
+		versions->con_side = true;
+		break;
 
+	case VERSIONS_UT_VIDEO_SERVER:
+		versions->video_channel = true;
+		versions->con_side = false;
+		break;
 
-	switch (feature_compression) {
-	case COMPRESSION_NONE:
-		printf(" no compression");
+	case VERSIONS_UT_VIDEO_USER:
+		versions->video_channel = true;
+		versions->con_side = true;
 		break;
 
-	case COMPRESSION_TYPE_1:
-		printf(" compression type1(delta)");
+	}
+
+	switch (raw_versions & VERSIONS_VIDEO_MASK) {
+	case VERSIONS_VIDEO_DVI:
+		versions->pcb_video_type = PCB_DVI_SL;
 		break;
 
-	case COMPRESSION_TYPE_1_2:
-		printf(" compression type1(delta), type2(inline)");
+	case VERSIONS_VIDEO_DP_165:
+		versions->pcb_video_type = PCB_DP_165MPIX;
 		break;
 
-	case COMPRESSION_TYPE_1_2_3:
-		printf(" compression type1(delta), type2(inline), type3(intempo)");
+	case VERSIONS_VIDEO_DP_300:
+		versions->pcb_video_type = PCB_DP_300MPIX;
 		break;
 
-	default:
-		printf(" compression %d(not supported)", feature_compression);
+	case VERSIONS_VIDEO_HDMI:
+		versions->pcb_video_type = PCB_HDMI;
 		break;
 	}
 
-	printf(", %sosd", feature_osd ? "" : "no ");
+	versions->hw_version = raw_versions & VERSIONS_HW_VER_MASK;
 
-	switch (feature_audio) {
-	case AUDIO_NONE:
-		printf(", no audio");
+	if (raw_versions & VERSIONS_SFP)
+		versions->pcb_transmission_type = PCB_FIBER_3G;
+	else
+		versions->pcb_transmission_type = PCB_CAT_1G;
+
+	return 0;
+}
+
+static int get_features(unsigned int fpga, struct fpga_features *features)
+{
+	enum {
+		FEATURE_CARRIER_SPEED_2_5 = BIT(4),
+		FEATURE_RAM_MASK = 0x7 << 5,
+		FEATURE_RAM_DDR2_32BIT = 0x0 << 5,
+		FEATURE_RAM_DDR3_32BIT = 0x1 << 5,
+		FEATURE_RAM_DDR3_48BIT = 0x2 << 5,
+		FEATURE_PCM_AUDIO_TX = BIT(9),
+		FEATURE_PCM_AUDIO_RX = BIT(10),
+		FEATURE_OSD = BIT(11),
+		FEATURE_USB20 = BIT(12),
+		FEATURE_COMPRESSION_MASK = 7 << 13,
+		FEATURE_COMPRESSION_TYPE1 = 0x1 << 13,
+		FEATURE_COMPRESSION_TYPE1_TYPE2 = 0x3 << 13,
+		FEATURE_COMPRESSION_TYPE1_TYPE2_TYPE3 = 0x7 << 13,
+	};
+
+	enum {
+		EXTENDED_FEATURE_SPDIF_AUDIO_TX = BIT(0),
+		EXTENDED_FEATURE_SPDIF_AUDIO_RX = BIT(1),
+		EXTENDED_FEATURE_RS232 = BIT(2),
+		EXTENDED_FEATURE_COMPRESSION_PIPES = BIT(3),
+		EXTENDED_FEATURE_INTERLACE = BIT(4),
+	};
+
+	u16 raw_features;
+	u16 raw_extended_features;
+
+	memset(features, 0, sizeof(struct fpga_features));
+
+	FPGA_GET_REG(fpga, fpga_features, &raw_features);
+	FPGA_GET_REG(fpga, fpga_ext_features, &raw_extended_features);
+
+	features->video_channels = raw_features & 0x3;
+	features->carriers = (raw_features >> 2) & 0x3;
+
+	features->carrier_speed = (raw_features & FEATURE_CARRIER_SPEED_2_5)
+		? CARRIER_SPEED_2_5G : CARRIER_SPEED_1G;
+
+	switch (raw_features & FEATURE_RAM_MASK) {
+	case FEATURE_RAM_DDR2_32BIT:
+		features->ram_config = RAM_DDR2_32BIT_295MBPS;
 		break;
 
-	case AUDIO_TX:
-		printf(", audio tx");
+	case FEATURE_RAM_DDR3_32BIT:
+		features->ram_config = RAM_DDR3_32BIT_590MBPS;
 		break;
 
-	case AUDIO_RX:
-		printf(", audio rx");
+	case FEATURE_RAM_DDR3_48BIT:
+		features->ram_config = RAM_DDR3_48BIT_590MBPS;
 		break;
+	}
 
-	case AUDIO_RXTX:
-		printf(", audio rx+tx");
+	features->pcm_tx = raw_features & FEATURE_PCM_AUDIO_TX;
+	features->pcm_rx = raw_features & FEATURE_PCM_AUDIO_RX;
+	features->spdif_tx = raw_extended_features & EXTENDED_FEATURE_SPDIF_AUDIO_TX;
+	features->spdif_rx = raw_extended_features & EXTENDED_FEATURE_SPDIF_AUDIO_RX;
+
+	features->usb2 = raw_features & FEATURE_USB20;
+	features->rs232 = raw_extended_features & EXTENDED_FEATURE_RS232;
+
+	features->compression_type1 = false;
+	features->compression_type2 = false;
+	features->compression_type3 = false;
+	switch (raw_features & FEATURE_COMPRESSION_MASK) {
+	case FEATURE_COMPRESSION_TYPE1_TYPE2_TYPE3:
+		features->compression_type3 = true;
+	case FEATURE_COMPRESSION_TYPE1_TYPE2:
+		features->compression_type2 = true;
+	case FEATURE_COMPRESSION_TYPE1:
+		features->compression_type1 = true;
 		break;
+	}
+
+	features->interlace = raw_extended_features & EXTENDED_FEATURE_INTERLACE;
+	features->osd = raw_features & FEATURE_OSD;
+	features->compression_pipes = raw_extended_features & EXTENDED_FEATURE_COMPRESSION_PIPES;
 
-	default:
-		printf(", audio %d(not supported)", feature_audio);
+	return 0;
+}
+
+#endif
+
+bool ioep_fpga_has_osd(unsigned int fpga)
+{
+	struct fpga_features features;
+
+	get_features(fpga, &features);
+
+	return features.osd;
+}
+
+void ioep_fpga_print_info(unsigned int fpga)
+{
+	u16 fpga_version;
+	struct fpga_versions versions;
+	struct fpga_features features;
+
+	FPGA_GET_REG(fpga, fpga_version, &fpga_version);
+	get_versions(fpga, &versions);
+	get_features(fpga, &features);
+
+	if (versions.video_channel)
+		printf("Videochannel");
+	else
+		printf("Mainchannel");
+
+	if (versions.con_side)
+		printf(" User");
+	else
+		printf(" Server");
+
+// FIXME
+#if 0
+		if (versions & (1<<4))
+			printf(" UC");
+#endif
+
+	switch(versions.pcb_transmission_type) {
+	case PCB_CAT_1G:
+	case PCB_CAT_10G:
+		printf(" CAT");
+		break;
+	case PCB_FIBER_3G:
+	case PCB_FIBER_10G:
+		printf(" Fiber");
+		break;
+	};
+
+	switch (versions.pcb_video_type) {
+	case PCB_DVI_SL:
+		printf(" DVI,");
+		break;
+	case PCB_DP_165MPIX:
+		printf(" DP 165MPix/s,");
+		break;
+	case PCB_DP_300MPIX:
+		printf(" DP 300MPix/s,");
+		break;
+	case PCB_HDMI:
+		printf(" HDMI,");
+		break;
+	case PCB_DP_1_2:
+		printf(" DP 1.2,");
+		break;
+	case PCB_HDMI_2_0:
+		printf(" HDMI 2.0,");
 		break;
 	}
 
+	printf(" FPGA V %d.%02d\n       features: ",
+	       fpga_version / 100, fpga_version % 100);
+
+	if (!features.compression_type1 &&
+	    !features.compression_type2 &&
+	    !features.compression_type3)
+		printf("no compression, ");
+
+	if (features.compression_type1)
+		printf("type1-deltacompression, ");
+
+	if (features.compression_type2)
+		printf("type2-inlinecompression, ");
+
+	if (features.compression_type3)
+		printf("type3-intempocompression, ");
+
+	printf("%sosd", features.osd ? "" : "no ");
+
+	if (features.pcm_rx && features.pcm_tx)
+		printf(", pcm rx+tx");
+	else if(features.pcm_rx)
+		printf(", pcm rx");
+	else if(features.pcm_tx)
+		printf(", pcm tx");
+
+	if (features.spdif_rx && features.spdif_tx)
+		printf(", spdif rx+tx");
+	else if(features.spdif_rx)
+		printf(", spdif rx");
+	else if(features.spdif_tx)
+		printf(", spdif tx");
+
 	puts(",\n       ");
 
-	switch (feature_sysclock) {
+	switch (features.sysclock) {
 	case SYSCLK_147456:
 		printf("clock 147.456 MHz");
 		break;
-
-	default:
-		printf("clock %d(not supported)", feature_sysclock);
-		break;
 	}
 
-	switch (feature_ramconfig) {
-	case RAM_DDR2_32:
+	switch (features.ram_config) {
+	case RAM_DDR2_32BIT_295MBPS:
 		printf(", RAM 32 bit DDR2");
 		break;
-
-	case RAM_DDR3_32:
+	case RAM_DDR3_32BIT_590MBPS:
 		printf(", RAM 32 bit DDR3");
 		break;
-
-	case RAM_DDR3_48:
+	case RAM_DDR3_48BIT_590MBPS:
+	case RAM_DDR3_48BIT_1800MBPS:
 		printf(", RAM 48 bit DDR3");
 		break;
-
-	default:
-		printf(", RAM %d(not supported)", feature_ramconfig);
+	case RAM_DDR3_64BIT_1800MBPS:
+		printf(", RAM 64 bit DDR3");
 		break;
 	}
 
-	printf(", %d carrier(s) %s", feature_carriers,
-	       feature_carrier_speed ? "2.5Gbit/s" : "1Gbit/s");
+	printf(", %d carrier(s)", features.carriers);
+
+	switch(features.carrier_speed) {
+	case CARRIER_SPEED_1G:
+		printf(", 1Gbit/s");
+		break;
+	case CARRIER_SPEED_3G:
+		printf(", 3Gbit/s");
+		break;
+	case CARRIER_SPEED_10G:
+		printf(", 10Gbit/s");
+		break;
+	}
 
-	printf(", %d video channel(s)\n", feature_video_channels);
+	printf(", %d video channel(s)\n", features.video_channels);
 }
 
 #endif /* CONFIG_GDSYS_LEGACY_DRIVERS */
diff --git a/board/gdsys/mpc8308/Kconfig b/board/gdsys/mpc8308/Kconfig
index 80ac1a0f8a..79d0dc9829 100644
--- a/board/gdsys/mpc8308/Kconfig
+++ b/board/gdsys/mpc8308/Kconfig
@@ -55,6 +55,25 @@ config GDSYS_LEGACY_DRIVERS
 
 endif
 
+if TARGET_GAZERBEAM
+
+config SYS_BOARD
+	default "mpc8308"
+
+config SYS_VENDOR
+	default "gdsys"
+
+config SYS_CONFIG_NAME
+	default "gazerbeam"
+
+config SYS_FPGA1_BASE
+	default E0700000
+
+config SYS_FPGA1_SIZE
+	default 1
+
+endif
+
 choice
 	prompt "FPGA flavor selection"
 
diff --git a/board/gdsys/mpc8308/MAINTAINERS b/board/gdsys/mpc8308/MAINTAINERS
index 3895b01732..a986ae3664 100644
--- a/board/gdsys/mpc8308/MAINTAINERS
+++ b/board/gdsys/mpc8308/MAINTAINERS
@@ -6,5 +6,7 @@ F:	include/configs/hrcon.h
 F:	configs/hrcon_defconfig
 F:	configs/hrcon_dh_defconfig
 F:	include/configs/strider.h
+F:	configs/strider_defconfig
 F:	configs/strider_cpu_defconfig
 F:	configs/strider_con_defconfig
+F:	configs/gazerbeam_defconfig
diff --git a/board/gdsys/mpc8308/Makefile b/board/gdsys/mpc8308/Makefile
index 42702fb967..bafb9beaaf 100644
--- a/board/gdsys/mpc8308/Makefile
+++ b/board/gdsys/mpc8308/Makefile
@@ -8,3 +8,4 @@
 obj-y := mpc8308.o sdram.o
 obj-$(CONFIG_HRCON) += hrcon.o
 obj-$(CONFIG_STRIDER) += strider.o
+obj-$(CONFIG_TARGET_GAZERBEAM) += gazerbeam.o
diff --git a/board/gdsys/mpc8308/gazerbeam.c b/board/gdsys/mpc8308/gazerbeam.c
new file mode 100644
index 0000000000..a86333d92c
--- /dev/null
+++ b/board/gdsys/mpc8308/gazerbeam.c
@@ -0,0 +1,332 @@
+/*
+ * (C) Copyright 2015
+ * Dirk Eibach,  Guntermann & Drunck GmbH, eibach@gdsys.de
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <dm/device-internal.h>
+#include <dm/uclass-internal.h>
+#include <fsl_esdhc.h>
+#include <gdsys_rxaui_ctrl.h>
+#include <marvell-phy.h>
+#include <miiphy.h>
+#include <tpm.h>
+#include <i2c.h>
+#include <asm/fsl_mpc83xx_serdes.h>
+#include <asm/gpio.h>
+
+#include "../../../drivers/net/phy/mv88x2.h"
+#include "../common/ihs_mdio.h"
+
+DECLARE_GLOBAL_DATA_PTR;
+
+struct ihs_mdio_info ihs_mdio_info[] = {
+	{ .fpga = NULL, .name = "ihs0", .clause45 = true, .base = 0x58 },
+	{ .fpga = NULL, .name = "ihs1", .clause45 = true, .base = 0x58 },
+};
+
+int child_find_by_name(struct udevice *parent, const char *dev_name,
+		       struct udevice **child)
+{
+	struct udevice *dev = NULL;
+
+	for (device_find_first_child(parent, &dev);
+	     dev;
+	     device_find_next_child(&dev)) {
+		if (!strncmp(dev->name, dev_name, strlen(dev_name))) {
+			*child = dev;
+			return 0;
+		}
+	}
+
+	return -1;
+}
+
+int request_gpio_by_dev(struct gpio_desc *gpio, struct udevice *gpio_dev,
+			uint offset, char *gpio_name)
+{
+	gpio->dev = gpio_dev;
+	gpio->offset = offset;
+	gpio->flags = 0;
+
+	return dm_gpio_request(gpio, gpio_name);
+}
+
+void determine_board_type(struct of_board_fixup_data *data)
+{
+	struct udevice *i2c_bus;
+	struct udevice *dummy;
+	struct udevice *gpio_dev = NULL;
+	struct gpio_desc gpio;
+	char name[16];
+
+	uclass_get_device_by_name(UCLASS_I2C, "i2c at 3100", &i2c_bus);
+
+	if (!i2c_bus) {
+		puts("Could not get I2C bus\n");
+		return;
+	}
+
+	data->mc2 = !dm_i2c_probe(i2c_bus, 0x20, 0, &dummy);
+	data->mc4 = !dm_i2c_probe(i2c_bus, 0x22, 0, &dummy);
+
+	if (data->mc2 && data->mc4) {
+		puts("Board hardware configuration inconsistent.");
+		return;
+	}
+
+	snprintf(name, sizeof(name), "pca9698@%x", data->mc4 ? 0x22 : 0x20);
+
+	if (child_find_by_name(i2c_bus, name, &gpio_dev)) {
+		printf("Could not find child %s of device %s\n", name,
+		       i2c_bus->name);
+		return;
+	}
+
+	device_probe(gpio_dev);
+
+	if (!data->mc4) {
+		if (!request_gpio_by_dev(&gpio, gpio_dev, 0, "var-mc_sc"))
+			data->mc2 = !dm_gpio_get_value(&gpio);
+		else
+			puts("Could not query var-mc_sc GPIO.\n");
+
+		dm_gpio_free(gpio_dev, &gpio);
+	}
+
+	if (!request_gpio_by_dev(&gpio, gpio_dev, 11, "var-con"))
+		data->var_con = dm_gpio_get_value(&gpio);
+	else
+		puts("Could not query var-con GPIO.\n");
+
+	dm_gpio_free(gpio_dev, &gpio);
+}
+
+int board_fix_fdt_get_info(void)
+{
+	struct of_board_fixup_data data;
+
+	determine_board_type(&data);
+
+	gd->board_fixup_data.var_con = data.var_con;
+	gd->board_fixup_data.mc2 = data.mc2;
+	gd->board_fixup_data.mc4 = data.mc4;
+
+	return 0;
+}
+
+int fdt_disable_by_ofname(void *rw_fdt_blob, char *ofname)
+{
+	int offset = fdt_path_offset(rw_fdt_blob, ofname);
+
+	return fdt_status_disabled(rw_fdt_blob, offset);
+}
+
+int board_fix_fdt_change(void *rw_fdt_blob)
+{
+	struct of_board_fixup_data data = gd->board_fixup_data;
+
+	if (!data.mc4) {
+		fdt_disable_by_ofname(rw_fdt_blob,
+				      "/localbus at e0005000/iocon_uart at 2,0");
+		fdt_disable_by_ofname(rw_fdt_blob, "/fpga1bus");
+	}
+
+	if (!data.mc2 || !data.var_con) {
+		fdt_disable_by_ofname(rw_fdt_blob, "/fpga0bus/fpga0_video1");
+		fdt_disable_by_ofname(rw_fdt_blob, "/fpga0bus/fpga0_iic_video1");
+		fdt_disable_by_ofname(rw_fdt_blob, "/fpga0bus/fpga0_axi_video1");
+	}
+
+	if (!data.var_con) {
+		fdt_disable_by_ofname(rw_fdt_blob, "/fpga0bus/fpga0_video0");
+		fdt_disable_by_ofname(rw_fdt_blob, "/fpga0bus/fpga0_iic_video0");
+		fdt_disable_by_ofname(rw_fdt_blob, "/fpga0bus/fpga0_axi_video0");
+	}
+
+	return 0;
+}
+
+int checkboard(void)
+{
+	struct of_board_fixup_data data = gd->board_fixup_data;
+	char *s = getenv("serial#");
+
+	puts("Board: Gazerbeam ");
+	printf("%s ", data.mc4 ? "MC4" : data.mc2 ? "MC2" : "SC");
+	printf("%s", data.var_con ? "CON" : "CPU");
+
+	if (s) {
+		puts(", serial# ");
+		puts(s);
+	}
+
+	puts("\n");
+
+	return 0;
+}
+
+int last_stage_init(void)
+{
+	uint fpga_hw_rev = 0;
+	uint k = 0;
+	struct udevice *fpga;
+	struct udevice *rxaui;
+	struct udevice *i2c_bus;
+	struct udevice *gpio_dev;
+	char name[16];
+
+	uclass_get_device_by_name(UCLASS_I2C, "i2c at 3000", &i2c_bus);
+
+	if (child_find_by_name(i2c_bus, "pca9698 at 20", &gpio_dev)) {
+		printf("Could not find child %s of device %s\n", name,
+		       i2c_bus->name);
+		return -1;
+	}
+
+	device_probe(gpio_dev);
+
+	for (k = 0; k < 4; ++k) {
+		struct gpio_desc gpio;
+
+		snprintf(name, sizeof(name), "fpga_hw_rev%d", k);
+
+		if (!request_gpio_by_dev(&gpio, gpio_dev, 12 + k, name))
+			fpga_hw_rev |= dm_gpio_get_value(&gpio) ? BIT(k) : 0;
+	}
+
+	setenv_ulong("fpga_hw_rev", fpga_hw_rev);
+
+	if (tpm_init() || tpm_startup(TPM_ST_CLEAR) ||
+	    tpm_continue_self_test()) {
+		printf("TPM init failed\n");
+	}
+
+	if (fpga_hw_rev >= 4) {
+		for (uclass_find_first_device(UCLASS_RXAUI_CTRL, &rxaui);
+		     rxaui;
+		     uclass_find_next_device(&rxaui)) {
+			rxaui_disable_polarity_inversion(rxaui);
+		}
+	}
+
+	for (uclass_find_first_device(UCLASS_IHS_FPGA, &fpga);
+	     fpga;
+	     uclass_find_next_device(&fpga)) {
+		struct mii_dev *bus;
+
+		device_probe(fpga);
+
+		if (fpga->seq < 0)
+			continue;
+
+		ihs_mdio_info[fpga->seq].fpga = fpga;
+
+		ihs_mdio_init(&ihs_mdio_info[fpga->seq]);
+		bus = miiphy_get_dev_by_name(fpga->seq ? "ihs1" : "ihs0");
+		if (bus) {
+			struct phy_device *phydev;
+
+			phydev = phy_find_by_mask_c45(bus, 1,
+						      PHY_INTERFACE_MODE_XGMII);
+			if (phydev)
+				phy_config(phydev);
+		}
+	}
+
+	return 0;
+}
+
+#ifdef CONFIG_FSL_ESDHC
+int board_mmc_init(bd_t *bd)
+{
+	immap_t *immr = (immap_t *)CONFIG_SYS_IMMR;
+	sysconf83xx_t *sysconf = &immr->sysconf;
+
+	/* Enable cache snooping in eSDHC system configuration register */
+	out_be32(&sysconf->sdhccr, 0x02000000);
+
+	return fsl_esdhc_mmc_init(bd);
+}
+#endif
+
+static struct pci_region pcie_regions_0[] = {
+	{
+		.bus_start = CONFIG_SYS_PCIE1_MEM_BASE,
+		.phys_start = CONFIG_SYS_PCIE1_MEM_PHYS,
+		.size = CONFIG_SYS_PCIE1_MEM_SIZE,
+		.flags = PCI_REGION_MEM,
+	},
+	{
+		.bus_start = CONFIG_SYS_PCIE1_IO_BASE,
+		.phys_start = CONFIG_SYS_PCIE1_IO_PHYS,
+		.size = CONFIG_SYS_PCIE1_IO_SIZE,
+		.flags = PCI_REGION_IO,
+	},
+};
+
+void pci_init_board(void)
+{
+	immap_t *immr = (immap_t *)CONFIG_SYS_IMMR;
+	sysconf83xx_t *sysconf = &immr->sysconf;
+	law83xx_t *pcie_law = sysconf->pcielaw;
+	struct pci_region *pcie_reg[] = { pcie_regions_0 };
+
+	fsl_setup_serdes(CONFIG_FSL_SERDES1, FSL_SERDES_PROTO_PEX,
+			 FSL_SERDES_CLK_100, FSL_SERDES_VDD_1V);
+
+	/* Deassert the resets in the control register */
+	out_be32(&sysconf->pecr1, 0xE0008000);
+	udelay(2000);
+
+	/* Configure PCI Express Local Access Windows */
+	out_be32(&pcie_law[0].bar, CONFIG_SYS_PCIE1_BASE & LAWBAR_BAR);
+	out_be32(&pcie_law[0].ar, LBLAWAR_EN | LBLAWAR_512MB);
+
+	mpc83xx_pcie_init(1, pcie_reg);
+}
+
+ulong board_flash_get_legacy(ulong base, int banknum, flash_info_t *info)
+{
+	info->portwidth = FLASH_CFI_16BIT;
+	info->chipwidth = FLASH_CFI_BY16;
+	info->interface = FLASH_CFI_X16;
+	return 1;
+}
+
+#if defined(CONFIG_OF_BOARD_SETUP)
+int ft_board_setup(void *blob, bd_t *bd)
+{
+	ft_cpu_setup(blob, bd);
+	fsl_fdt_fixup_dr_usb(blob, bd);
+	fdt_fixup_esdhc(blob, bd);
+
+	return 0;
+}
+#endif
+
+int board_m88e1510_config(struct phy_device *phydev)
+{
+	/* Select page 3 */
+	phy_write(phydev, MDIO_DEVAD_NONE, 22, 3);
+
+	/* Configure LEDs */
+	m88e1518_phy_writebits(phydev, 16, 0, 4, 4);
+	m88e1518_phy_writebits(phydev, 16, 4, 4, 8);
+	m88e1518_phy_writebits(phydev, 16, 8, 4, 0);
+
+	/* Reset page selection */
+	phy_write(phydev, MDIO_DEVAD_NONE, 22, 0);
+
+	return 0;
+}
+
+int board_mv88x2_config(struct mv88x2_config_data *data)
+{
+	data->sfi_pol = (getenv_ulong("fpga_hw_rev", 10, 0) < 4) ? 0x0f03 : 0;
+
+	return 0;
+}
diff --git a/configs/gazerbeam_defconfig b/configs/gazerbeam_defconfig
new file mode 100644
index 0000000000..4fc92ea19b
--- /dev/null
+++ b/configs/gazerbeam_defconfig
@@ -0,0 +1,76 @@
+CONFIG_PPC=y
+CONFIG_SYS_MALLOC_F_LEN=0x600
+CONFIG_IDENT_STRING=" gazerbeam 0.01"
+CONFIG_MPC83xx=y
+CONFIG_TARGET_GAZERBEAM=y
+CONFIG_SYS_FPGA_FLAVOR_GAZERBEAM=y
+CONFIG_CMD_IOLOOP=y
+CONFIG_DEFAULT_DEVICE_TREE="gazerbeam"
+CONFIG_FIT=y
+CONFIG_FIT_SIGNATURE=y
+CONFIG_FIT_VERBOSE=y
+CONFIG_OF_BOARD_SETUP=y
+CONFIG_OF_STDOUT_VIA_ALIAS=y
+CONFIG_BOOTDELAY=5
+CONFIG_SYS_CONSOLE_INFO_QUIET=y
+# CONFIG_DISPLAY_BOARDINFO is not set
+CONFIG_HUSH_PARSER=y
+CONFIG_AUTOBOOT_KEYED=y
+CONFIG_AUTOBOOT_STOP_STR=" "
+CONFIG_CMD_MEMTEST=y
+CONFIG_CMD_MMC=y
+CONFIG_CMD_I2C=y
+# CONFIG_CMD_FPGA is not set
+CONFIG_CMD_GPIO=y
+CONFIG_CMD_IHS_FPGA=y
+CONFIG_CMD_IHS_AXI=y
+# CONFIG_CMD_SETEXPR is not set
+# CONFIG_CMD_NFS is not set
+CONFIG_CMD_MII=y
+CONFIG_CMD_MII_DRIVER=y
+CONFIG_CMD_PING=y
+CONFIG_CMD_HASH=y
+CONFIG_CMD_TPM=y
+CONFIG_CMD_EXT2=y
+CONFIG_DOS_PARTITION=y
+CONFIG_OF_CONTROL=y
+CONFIG_OF_BOARD_FIXUP=y
+CONFIG_OF_EMBED=y
+CONFIG_DM=y
+CONFIG_CLK=y
+CONFIG_ICS8N3QV01=y
+CONFIG_DM_GPIO=y
+CONFIG_DM_PCA953X=y
+CONFIG_MPC8XXX_GPIO=y
+CONFIG_DM_I2C=y
+CONFIG_SYS_I2C_FSL=y
+CONFIG_SYS_I2C_IHS=y
+CONFIG_MISC=y
+CONFIG_IHS_FPGA=y
+CONFIG_IHS_AXI=y
+CONFIG_IHS_VIDEO_OUT=y
+CONFIG_GDSYS_RXAUI_CTRL=y
+CONFIG_GDSYS_IOEP=y
+CONFIG_MTD=y
+CONFIG_MTD_NOR_FLASH=y
+CONFIG_CFI_FLASH=y
+CONFIG_PHYLIB=y
+CONFIG_PHYLIB_10G=y
+CONFIG_PHY_MARVELL=y
+CONFIG_BOARD_M88E1510_CONFIG=y
+CONFIG_PHY_MV88X2=y
+CONFIG_BOARD_MV88X2_CONFIG=y
+CONFIG_MV88X2_DEBUG_REGS=y
+CONFIG_MV88X2_LINE_10GBASE_R=y
+CONFIG_MV88X2_HOST_10GBASE_X2=y
+CONFIG_MV88X2_X2_DISPARITY=y
+CONFIG_MV88X2_LED0_SOLID=6
+CONFIG_MV88X2_LED1_SOLID=6
+CONFIG_MV88X2_HOST_LANE_MUX_2_PORT=0x0800
+CONFIG_DM_SERIAL=y
+CONFIG_SYS_NS16550=y
+CONFIG_TPM_ATMEL_TWI=y
+CONFIG_TPM_AUTH_SESSIONS=y
+CONFIG_TRANSMITTER=y
+CONFIG_LOGICORE_DP_TX=y
+CONFIG_TPM=y
diff --git a/include/configs/gazerbeam.h b/include/configs/gazerbeam.h
new file mode 100644
index 0000000000..a8d0474771
--- /dev/null
+++ b/include/configs/gazerbeam.h
@@ -0,0 +1,484 @@
+/*
+ * (C) Copyright 2015
+ * Dirk Eibach,  Guntermann & Drunck GmbH, eibach at gdsys.de
+ *
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#ifndef __CONFIG_H
+#define __CONFIG_H
+
+/*
+ * High Level Configuration Options
+ */
+#define CONFIG_E300		1 /* E300 family */
+#define CONFIG_MPC83xx		1 /* MPC83xx family */
+#define CONFIG_MPC830x		1 /* MPC830x family */
+#define CONFIG_MPC8308		1 /* MPC8308 CPU specific */
+
+#define	CONFIG_SYS_TEXT_BASE	0xFE000000
+
+#define CONFIG_LAST_STAGE_INIT
+#define CONFIG_DISPLAY_BOARDINFO_LATE
+
+#define CONFIG_FSL_ESDHC
+#define CONFIG_SYS_FSL_ESDHC_ADDR	CONFIG_SYS_MPC83xx_ESDHC_ADDR
+#define CONFIG_SYS_FSL_ERRATUM_ESDHC111
+
+#define CONFIG_SYS_ALT_MEMTEST
+
+/*
+ * System Clock Setup
+ */
+#define CONFIG_83XX_CLKIN      33333333 /* in Hz */
+#define CONFIG_SYS_CLK_FREQ    CONFIG_83XX_CLKIN
+
+/*
+ * Hardware Reset Configuration Word
+ * if CLKIN is 66.66MHz, then
+ * CSB = 133MHz, DDRC = 266MHz, LBC = 133MHz
+ * We choose the A type silicon as default, so the core is 400Mhz.
+ */
+#define CONFIG_SYS_HRCW_LOW (\
+	HRCWL_LCL_BUS_TO_SCB_CLK_1X1 |\
+	HRCWL_DDR_TO_SCB_CLK_2X1 |\
+	HRCWL_SVCOD_DIV_2 |\
+	HRCWL_CSB_TO_CLKIN_4X1 |\
+	HRCWL_CORE_TO_CSB_3X1)
+/*
+ * There are neither HRCWH_PCI_HOST nor HRCWH_PCI1_ARBITER_ENABLE bits
+ * in 8308's HRCWH according to the manual, but original Freescale's
+ * code has them and I've expirienced some problems using the board
+ * with BDI3000 attached when I've tried to set these bits to zero
+ * (UART doesn't work after the 'reset run' command).
+ */
+#define CONFIG_SYS_HRCW_HIGH (\
+	HRCWH_PCI_HOST |\
+	HRCWH_PCI1_ARBITER_ENABLE |\
+	HRCWH_CORE_ENABLE |\
+	HRCWH_FROM_0XFFF00100 |\
+	HRCWH_BOOTSEQ_DISABLE |\
+	HRCWH_SW_WATCHDOG_DISABLE |\
+	HRCWH_ROM_LOC_LOCAL_16BIT |\
+	HRCWH_RL_EXT_LEGACY |\
+	HRCWH_TSEC1M_IN_RGMII |\
+	HRCWH_TSEC2M_IN_RGMII |\
+	HRCWH_BIG_ENDIAN)
+
+/*
+ * System IO Config
+ */
+ #define CONFIG_SYS_SICRH (\
+ 	SICRH_ESDHC_A_SD |\
+ 	SICRH_ESDHC_B_SD |\
+ 	SICRH_ESDHC_C_SD |\
+ 	SICRH_GPIO_A_TSEC2 |\
+ 	SICRH_GPIO_B_TSEC2_GTX_CLK125 |\
+ 	SICRH_IEEE1588_A_GPIO |\
+ 	SICRH_USB |\
+ 	SICRH_GTM_GPIO |\
+ 	SICRH_IEEE1588_B_GPIO |\
+ 	SICRH_ETSEC2_GPIO |\
+ 	SICRH_GPIOSEL_1 |\
+ 	SICRH_TMROBI_V3P3 |\
+ 	SICRH_TSOBI1_V2P5 |\
+ 	SICRH_TSOBI2_V2P5)	/* 0x01b7f103 */
+ #define CONFIG_SYS_SICRL (\
+ 	SICRL_SPI_PF0 |\
+ 	SICRL_UART_PF0 |\
+ 	SICRL_IRQ_PF0 |\
+ 	SICRL_I2C2_PF0 |\
+ 	SICRL_ETSEC1_GTX_CLK125)	/* 0x00000000 */
+
+/*
+ * IMMR new address
+ */
+#define CONFIG_SYS_IMMR		0xE0000000
+
+/*
+ * SERDES
+ */
+#define CONFIG_FSL_SERDES
+#define CONFIG_FSL_SERDES1	0xe3000
+
+/*
+ * Arbiter Setup
+ */
+#define CONFIG_SYS_ACR_PIPE_DEP	3 /* Arbiter pipeline depth is 4 */
+#define CONFIG_SYS_ACR_RPTCNT	3 /* Arbiter repeat count is 4 */
+#define CONFIG_SYS_SPCR_TSECEP	3 /* eTSEC emergency priority is highest */
+
+/*
+ * DDR Setup
+ */
+#define CONFIG_SYS_DDR_BASE		0x00000000 /* DDR is system memory */
+#define CONFIG_SYS_SDRAM_BASE		CONFIG_SYS_DDR_BASE
+#define CONFIG_SYS_DDR_SDRAM_BASE	CONFIG_SYS_DDR_BASE
+#define CONFIG_SYS_DDR_SDRAM_CLK_CNTL	DDR_SDRAM_CLK_CNTL_CLK_ADJUST_05
+#define CONFIG_SYS_DDRCDR_VALUE	(DDRCDR_EN \
+				| DDRCDR_PZ_LOZ \
+				| DDRCDR_NZ_LOZ \
+				| DDRCDR_ODT \
+				| DDRCDR_Q_DRN)
+				/* 0x7b880001 */
+/*
+ * Manually set up DDR parameters
+ * consist of one chip NT5TU64M16HG from NANYA
+ */
+
+#define CONFIG_SYS_DDR_SIZE		128 /* MB */
+
+#define CONFIG_SYS_DDR_CS0_BNDS	0x00000007
+#define CONFIG_SYS_DDR_CS0_CONFIG	(CSCONFIG_EN \
+				| CSCONFIG_ODT_RD_NEVER \
+				| CSCONFIG_ODT_WR_ONLY_CURRENT \
+				| CSCONFIG_BANK_BIT_3 \
+				| CSCONFIG_ROW_BIT_13 | CSCONFIG_COL_BIT_10)
+				/* 0x80010102 */
+#define CONFIG_SYS_DDR_TIMING_3	0
+#define CONFIG_SYS_DDR_TIMING_0	((0 << TIMING_CFG0_RWT_SHIFT) \
+				| (0 << TIMING_CFG0_WRT_SHIFT) \
+				| (0 << TIMING_CFG0_RRT_SHIFT) \
+				| (0 << TIMING_CFG0_WWT_SHIFT) \
+				| (2 << TIMING_CFG0_ACT_PD_EXIT_SHIFT) \
+				| (6 << TIMING_CFG0_PRE_PD_EXIT_SHIFT) \
+				| (8 << TIMING_CFG0_ODT_PD_EXIT_SHIFT) \
+				| (2 << TIMING_CFG0_MRS_CYC_SHIFT))
+				/* 0x00260802 */
+#define CONFIG_SYS_DDR_TIMING_1	((2 << TIMING_CFG1_PRETOACT_SHIFT) \
+				| (6 << TIMING_CFG1_ACTTOPRE_SHIFT) \
+				| (2 << TIMING_CFG1_ACTTORW_SHIFT) \
+				| (7 << TIMING_CFG1_CASLAT_SHIFT) \
+				| (9 << TIMING_CFG1_REFREC_SHIFT) \
+				| (2 << TIMING_CFG1_WRREC_SHIFT) \
+				| (2 << TIMING_CFG1_ACTTOACT_SHIFT) \
+				| (2 << TIMING_CFG1_WRTORD_SHIFT))
+				/* 0x26279222 */
+#define CONFIG_SYS_DDR_TIMING_2	((0 << TIMING_CFG2_ADD_LAT_SHIFT) \
+				| (4 << TIMING_CFG2_CPO_SHIFT) \
+				| (3 << TIMING_CFG2_WR_LAT_DELAY_SHIFT) \
+				| (2 << TIMING_CFG2_RD_TO_PRE_SHIFT) \
+				| (2 << TIMING_CFG2_WR_DATA_DELAY_SHIFT) \
+				| (3 << TIMING_CFG2_CKE_PLS_SHIFT) \
+				| (5 << TIMING_CFG2_FOUR_ACT_SHIFT))
+				/* 0x021848c5 */
+#define CONFIG_SYS_DDR_INTERVAL	((0x0824 << SDRAM_INTERVAL_REFINT_SHIFT) \
+				| (0x0100 << SDRAM_INTERVAL_BSTOPRE_SHIFT))
+				/* 0x08240100 */
+#define CONFIG_SYS_DDR_SDRAM_CFG	(SDRAM_CFG_SREN \
+				| SDRAM_CFG_SDRAM_TYPE_DDR2 \
+				| SDRAM_CFG_DBW_16)
+				/* 0x43100000 */
+
+#define CONFIG_SYS_DDR_SDRAM_CFG2	0x00401000 /* 1 posted refresh */
+#define CONFIG_SYS_DDR_MODE		((0x0440 << SDRAM_MODE_ESD_SHIFT) \
+				| (0x0242 << SDRAM_MODE_SD_SHIFT))
+				/* ODT 150ohm CL=4, AL=0 on SDRAM */
+#define CONFIG_SYS_DDR_MODE2		0x00000000
+
+/*
+ * Memory test
+ */
+#define CONFIG_SYS_MEMTEST_START	0x00001000 /* memtest region */
+#define CONFIG_SYS_MEMTEST_END		0x07f00000
+
+/*
+ * The reserved memory
+ */
+#define CONFIG_SYS_MONITOR_BASE	CONFIG_SYS_TEXT_BASE /* start of monitor */
+
+#define CONFIG_SYS_MONITOR_LEN	(512 * 1024) /* Reserve 512 kB for Mon */
+#define CONFIG_SYS_MALLOC_LEN	(512 * 1024) /* Reserved for malloc */
+
+/*
+ * Initial RAM Base Address Setup
+ */
+#define CONFIG_SYS_INIT_RAM_LOCK	1
+#define CONFIG_SYS_INIT_RAM_ADDR	0xE6000000 /* Initial RAM address */
+#define CONFIG_SYS_INIT_RAM_SIZE	0x1000 /* Size of used area in RAM */
+#define CONFIG_SYS_GBL_DATA_OFFSET	\
+	(CONFIG_SYS_INIT_RAM_SIZE - GENERATED_GBL_DATA_SIZE)
+
+/*
+ * Local Bus Configuration & Clock Setup
+ */
+#define CONFIG_SYS_LCRR_DBYP		LCRR_DBYP
+#define CONFIG_SYS_LCRR_CLKDIV		LCRR_CLKDIV_2
+#define CONFIG_SYS_LBC_LBCR		0x00040000
+
+/*
+ * FLASH on the Local Bus
+ */
+#define CONFIG_SYS_FLASH_CFI		/* use the Common Flash Interface */
+#define CONFIG_FLASH_CFI_DRIVER		/* use the CFI driver */
+#define CONFIG_SYS_FLASH_CFI_WIDTH	FLASH_CFI_16BIT
+#define CONFIG_FLASH_CFI_LEGACY
+#define CONFIG_SYS_FLASH_LEGACY_512Kx16
+
+#define CONFIG_SYS_FLASH_BASE		0xFE000000 /* FLASH base address */
+#define CONFIG_SYS_FLASH_SIZE		8 /* FLASH size is up to 8M */
+#define CONFIG_SYS_FLASH_PROTECTION	1 /* Use h/w Flash protection. */
+
+/* Window base at flash base */
+#define CONFIG_SYS_LBLAWBAR0_PRELIM	CONFIG_SYS_FLASH_BASE
+#define CONFIG_SYS_LBLAWAR0_PRELIM	(LBLAWAR_EN | LBLAWAR_8MB)
+
+#define CONFIG_SYS_BR0_PRELIM	(CONFIG_SYS_FLASH_BASE \
+				| BR_PS_16	/* 16 bit port */ \
+				| BR_MS_GPCM	/* MSEL = GPCM */ \
+				| BR_V)		/* valid */
+#define CONFIG_SYS_OR0_PRELIM	(MEG_TO_AM(CONFIG_SYS_FLASH_SIZE) \
+				| OR_UPM_XAM \
+				| OR_GPCM_CSNT \
+				| OR_GPCM_ACS_DIV2 \
+				| OR_GPCM_XACS \
+				| OR_GPCM_SCY_15 \
+				| OR_GPCM_TRLX_SET \
+				| OR_GPCM_EHTR_SET)
+
+#define CONFIG_SYS_MAX_FLASH_BANKS	1 /* number of banks */
+#define CONFIG_SYS_MAX_FLASH_SECT	135
+
+#define CONFIG_SYS_FLASH_ERASE_TOUT	60000 /* Flash Erase Timeout (ms) */
+#define CONFIG_SYS_FLASH_WRITE_TOUT	500 /* Flash Write Timeout (ms) */
+
+/* Window base@FPGA base */
+#define CONFIG_SYS_LBLAWBAR1_PRELIM	CONFIG_SYS_FPGA0_BASE
+#define CONFIG_SYS_LBLAWAR1_PRELIM	(LBLAWAR_EN | LBLAWAR_1MB)
+#define CONFIG_SYS_LBLAWBAR2_PRELIM	CONFIG_SYS_FPGA1_BASE
+#define CONFIG_SYS_LBLAWAR2_PRELIM	(LBLAWAR_EN | LBLAWAR_1MB)
+
+#define CONFIG_SYS_BR1_PRELIM	(CONFIG_SYS_FPGA0_BASE \
+				| BR_PS_16	/* 16 bit port */ \
+				| BR_MS_GPCM	/* MSEL = GPCM */ \
+				| BR_V)		/* valid */
+#define CONFIG_SYS_OR1_PRELIM   (MEG_TO_AM(CONFIG_SYS_FPGA0_SIZE) \
+				| OR_UPM_XAM \
+				| OR_GPCM_CSNT \
+				| OR_GPCM_SCY_5 \
+				| OR_GPCM_TRLX_CLEAR \
+				| OR_GPCM_EHTR_CLEAR)
+
+#define CONFIG_SYS_BR2_PRELIM	(CONFIG_SYS_FPGA1_BASE \
+				| BR_PS_16	/* 16 bit port */ \
+				| BR_MS_GPCM	/* MSEL = GPCM */ \
+				| BR_V)		/* valid */
+#define CONFIG_SYS_OR2_PRELIM	(MEG_TO_AM(CONFIG_SYS_FPGA1_SIZE) \
+				| OR_UPM_XAM \
+				| OR_GPCM_CSNT \
+				| OR_GPCM_SCY_5 \
+				| OR_GPCM_TRLX_CLEAR \
+				| OR_GPCM_EHTR_CLEAR)
+
+#define CONFIG_SYS_FPGA_COUNT		2
+
+#define CONFIG_SYS_FPGA_PTR { \
+	(struct ihs_fpga *)CONFIG_SYS_FPGA0_BASE, \
+	(struct ihs_fpga *)CONFIG_SYS_FPGA1_BASE }
+
+#define CONFIG_SYS_FPGA_NO_RFL_HI
+
+#define CONFIG_SYS_BAUDRATE_TABLE  \
+	{300, 600, 1200, 2400, 4800, 9600, 19200, 38400, 57600, 115200}
+
+#define CONFIG_SYS_ICS8N3QV01_I2C		{ 3, 6, 4, 7 }
+
+/*
+ * General PCI
+ * Addresses are mapped 1-1.
+ */
+#define CONFIG_SYS_PCIE1_BASE		0xA0000000
+#define CONFIG_SYS_PCIE1_MEM_BASE	0xA0000000
+#define CONFIG_SYS_PCIE1_MEM_PHYS	0xA0000000
+#define CONFIG_SYS_PCIE1_MEM_SIZE	0x10000000
+#define CONFIG_SYS_PCIE1_CFG_BASE	0xB0000000
+#define CONFIG_SYS_PCIE1_CFG_SIZE	0x01000000
+#define CONFIG_SYS_PCIE1_IO_BASE	0x00000000
+#define CONFIG_SYS_PCIE1_IO_PHYS	0xB1000000
+#define CONFIG_SYS_PCIE1_IO_SIZE	0x00800000
+
+/* enable PCIE clock */
+#define CONFIG_SYS_SCCR_PCIEXP1CM	1
+
+#define CONFIG_PCI_INDIRECT_BRIDGE
+#define CONFIG_PCIE
+
+#define CONFIG_SYS_PCI_SUBSYS_VENDORID 0x1957	/* Freescale */
+#define CONFIG_83XX_GENERIC_PCIE_REGISTER_HOSES 1
+
+/*
+ * TSEC
+ */
+#define CONFIG_TSEC_ENET	/* TSEC ethernet support */
+#define CONFIG_SYS_TSEC1_OFFSET	0x24000
+#define CONFIG_SYS_TSEC1	(CONFIG_SYS_IMMR+CONFIG_SYS_TSEC1_OFFSET)
+#define CONFIG_SYS_TSEC2_OFFSET	0x25000
+#define CONFIG_SYS_TSEC2	(CONFIG_SYS_IMMR+CONFIG_SYS_TSEC2_OFFSET)
+
+/*
+ * TSEC ethernet configuration
+ */
+#define CONFIG_MII		1 /* MII PHY management */
+
+#define CONFIG_TSEC1
+#define CONFIG_TSEC1_NAME	"eTSEC0"
+#define TSEC1_PHY_ADDR		1
+#define TSEC1_PHYIDX		0
+#define TSEC1_FLAGS		TSEC_GIGABIT
+
+#define CONFIG_TSEC2
+#define CONFIG_TSEC2_NAME	"eTSEC1"
+#define TSEC2_PHY_ADDR		0
+#define TSEC2_PHYIDX		0
+#define TSEC2_FLAGS		TSEC_GIGABIT
+
+/* Options are: eTSEC[0-1] */
+#define CONFIG_ETHPRIME		"eTSEC0"
+
+/*
+ * Environment
+ */
+#if 1
+#define CONFIG_ENV_IS_IN_FLASH	1
+#define CONFIG_ENV_ADDR		(CONFIG_SYS_MONITOR_BASE + \
+				 CONFIG_SYS_MONITOR_LEN)
+#define CONFIG_ENV_SECT_SIZE	0x10000 /* 64K(one sector) for env */
+#define CONFIG_ENV_SIZE		0x2000
+#define CONFIG_ENV_ADDR_REDUND	(CONFIG_ENV_ADDR + CONFIG_ENV_SECT_SIZE)
+#define CONFIG_ENV_SIZE_REDUND	CONFIG_ENV_SIZE
+#else
+#define CONFIG_ENV_IS_NOWHERE
+#define CONFIG_ENV_SIZE		0x2000		/* 8KB */
+#endif
+
+#define CONFIG_LOADS_ECHO	1	/* echo on for serial download */
+#define CONFIG_SYS_LOADS_BAUD_CHANGE	1	/* allow baudrate change */
+
+/*
+ * Command line configuration.
+ */
+#define CONFIG_CMD_PCI
+
+#define CONFIG_CMDLINE_EDITING	1	/* add command line history */
+#define CONFIG_AUTO_COMPLETE		/* add autocompletion support */
+
+/*
+ * Miscellaneous configurable options
+ */
+#define CONFIG_SYS_LONGHELP		/* undef to save memory */
+#define CONFIG_SYS_LOAD_ADDR		0x2000000 /* default load address */
+#define CONFIG_SYS_HZ		1000	/* decrementer freq: 1ms ticks */
+
+#define CONFIG_SYS_CBSIZE	1024 /* Console I/O Buffer Size */
+
+/* Print Buffer Size */
+#define CONFIG_SYS_PBSIZE (CONFIG_SYS_CBSIZE + sizeof(CONFIG_SYS_PROMPT) + 16)
+#define CONFIG_SYS_MAXARGS	16	/* max number of command args */
+#define CONFIG_SYS_BARGSIZE	CONFIG_SYS_CBSIZE
+
+/*
+ * For booting Linux, the board info and command line data
+ * have to be in the first 256 MB of memory, since this is
+ * the maximum mapped by the Linux kernel during initialization.
+ */
+#define CONFIG_SYS_BOOTMAPSZ	(256 << 20) /* Initial Memory map for Linux */
+
+/*
+ * Core HID Setup
+ */
+#define CONFIG_SYS_HID0_INIT	0x000000000
+#define CONFIG_SYS_HID0_FINAL	(HID0_ENABLE_MACHINE_CHECK | \
+				 HID0_ENABLE_INSTRUCTION_CACHE | \
+				 HID0_ENABLE_DYNAMIC_POWER_MANAGMENT)
+#define CONFIG_SYS_HID2		HID2_HBE
+
+/*
+ * MMU Setup
+ */
+
+/* DDR: cache cacheable */
+#define CONFIG_SYS_IBAT0L	(CONFIG_SYS_SDRAM_BASE | BATL_PP_RW | \
+					BATL_MEMCOHERENCE)
+#define CONFIG_SYS_IBAT0U	(CONFIG_SYS_SDRAM_BASE | BATU_BL_128M | \
+					BATU_VS | BATU_VP)
+#define CONFIG_SYS_DBAT0L	CONFIG_SYS_IBAT0L
+#define CONFIG_SYS_DBAT0U	CONFIG_SYS_IBAT0U
+
+/* IMMRBAR, PCI IO and FPGA: cache-inhibit and guarded */
+#define CONFIG_SYS_IBAT1L	(CONFIG_SYS_IMMR | BATL_PP_RW | \
+			BATL_CACHEINHIBIT | BATL_GUARDEDSTORAGE)
+#define CONFIG_SYS_IBAT1U	(CONFIG_SYS_IMMR | BATU_BL_8M | BATU_VS | \
+					BATU_VP)
+#define CONFIG_SYS_DBAT1L	CONFIG_SYS_IBAT1L
+#define CONFIG_SYS_DBAT1U	CONFIG_SYS_IBAT1U
+
+/* FLASH: icache cacheable, but dcache-inhibit and guarded */
+#define CONFIG_SYS_IBAT2L	(CONFIG_SYS_FLASH_BASE | BATL_PP_RW | \
+					BATL_CACHEINHIBIT | \
+					BATL_GUARDEDSTORAGE)
+#define CONFIG_SYS_IBAT2U	(CONFIG_SYS_FLASH_BASE | BATU_BL_8M | \
+					BATU_VS | BATU_VP)
+#define CONFIG_SYS_DBAT2L	(CONFIG_SYS_FLASH_BASE | BATL_PP_RW | \
+					BATL_CACHEINHIBIT | \
+					BATL_GUARDEDSTORAGE)
+#define CONFIG_SYS_DBAT2U	CONFIG_SYS_IBAT2U
+
+/* Stack in dcache: cacheable, no memory coherence */
+#define CONFIG_SYS_IBAT3L	(CONFIG_SYS_INIT_RAM_ADDR | BATL_PP_RW)
+#define CONFIG_SYS_IBAT3U	(CONFIG_SYS_INIT_RAM_ADDR | BATU_BL_128K | \
+					BATU_VS | BATU_VP)
+#define CONFIG_SYS_DBAT3L	CONFIG_SYS_IBAT3L
+#define CONFIG_SYS_DBAT3U	CONFIG_SYS_IBAT3U
+
+/*
+ * Environment Configuration
+ */
+
+#define CONFIG_ENV_OVERWRITE
+
+#if defined(CONFIG_TSEC_ENET)
+#define CONFIG_HAS_ETH0
+#endif
+
+#define CONFIG_LOADADDR	800000	/* default location for tftp and bootm */
+
+#define CONFIG_HOSTNAME		hrcon
+#define CONFIG_ROOTPATH		"/opt/nfsroot"
+#define CONFIG_BOOTFILE		"uImage"
+
+#define CONFIG_PREBOOT		/* enable preboot variable */
+
+#define	CONFIG_EXTRA_ENV_SETTINGS					\
+	"netdev=eth0\0"							\
+	"consoledev=ttyS1\0"						\
+	"u-boot=u-boot.bin\0"						\
+	"kernel_addr=1000000\0"					\
+	"fdt_addr=C00000\0"						\
+	"fdtfile=hrcon.dtb\0"				\
+	"load=tftp ${loadaddr} ${u-boot}\0"				\
+	"update=protect off " __stringify(CONFIG_SYS_MONITOR_BASE)	\
+		" +${filesize};era " __stringify(CONFIG_SYS_MONITOR_BASE)\
+		" +${filesize};cp.b ${fileaddr} "			\
+		__stringify(CONFIG_SYS_MONITOR_BASE) " ${filesize}\0"	\
+	"upd=run load update\0"						\
+
+#define CONFIG_NFSBOOTCOMMAND						\
+	"setenv bootargs root=/dev/nfs rw "				\
+	"nfsroot=$serverip:$rootpath "					\
+	"ip=$ipaddr:$serverip:$gatewayip:$netmask:$hostname:$netdev:off " \
+	"console=$consoledev,$baudrate $othbootargs;"			\
+	"tftp ${kernel_addr} $bootfile;"				\
+	"tftp ${fdt_addr} $fdtfile;"					\
+	"bootm ${kernel_addr} - ${fdt_addr}"
+
+#define CONFIG_MMCBOOTCOMMAND						\
+	"setenv bootargs root=/dev/mmcblk0p3 rw rootwait "		\
+	"console=$consoledev,$baudrate $othbootargs;"			\
+	"ext2load mmc 0:2 ${kernel_addr} $bootfile;"			\
+	"ext2load mmc 0:2 ${fdt_addr} $fdtfile;"			\
+	"bootm ${kernel_addr} - ${fdt_addr}"
+
+#define CONFIG_BOOTCOMMAND		CONFIG_MMCBOOTCOMMAND
+
+#endif	/* __CONFIG_H */
diff --git a/include/fdt_fixup.h b/include/fdt_fixup.h
index 9390f0a633..f67685a789 100644
--- a/include/fdt_fixup.h
+++ b/include/fdt_fixup.h
@@ -1,4 +1,9 @@
 struct of_board_fixup_data {
+#ifdef CONFIG_TARGET_GAZERBEAM
+	bool var_con;
+	bool mc4;
+	bool mc2;
+#endif
 #ifdef CONFIG_TARGET_CONTROLCENTERDC
 	bool chip_exists[6];
 #endif
-- 
2.11.0

^ permalink raw reply related	[flat|nested] 138+ messages in thread

* [U-Boot] [PATCH 01/51] i2c: fsl_i2c: Fix style violations
  2017-07-14 12:54 ` [U-Boot] [PATCH 01/51] i2c: fsl_i2c: Fix style violations Mario Six
@ 2017-07-18 14:01   ` Simon Glass
  0 siblings, 0 replies; 138+ messages in thread
From: Simon Glass @ 2017-07-18 14:01 UTC (permalink / raw)
  To: u-boot

On 14 July 2017 at 05:54, Mario Six <mario.six@gdsys.cc> wrote:
> Fix some style violations in the fsl_i2c I2C driver.
>
> Signed-off-by: Mario Six <mario.six@gdsys.cc>
> ---
>
>  drivers/i2c/fsl_i2c.c | 109 +++++++++++++++++++++++++-------------------------
>  1 file changed, 55 insertions(+), 54 deletions(-)

Reviewed-by: Simon Glass <sjg@chromium.org>

Note for strings (e.g. debug()) we allow them to run past 80 chars if
there is no alternative but to break the string.

^ permalink raw reply	[flat|nested] 138+ messages in thread

* [U-Boot] [PATCH 02/51] i2c: fsl_i2c: Remove inline declarations
  2017-07-14 12:54 ` [U-Boot] [PATCH 02/51] i2c: fsl_i2c: Remove inline declarations Mario Six
@ 2017-07-18 14:01   ` Simon Glass
  0 siblings, 0 replies; 138+ messages in thread
From: Simon Glass @ 2017-07-18 14:01 UTC (permalink / raw)
  To: u-boot

On 14 July 2017 at 05:54, Mario Six <mario.six@gdsys.cc> wrote:
> Some functions in the fsl_i2c driver are declared as inline, even though
> they are quite large, which needlessly increases the size of the
> resulting binary.
>
> This patch removes the inline declarations.
>
> Signed-off-by: Mario Six <mario.six@gdsys.cc>
> ---
>
>  drivers/i2c/fsl_i2c.c | 14 +++++++-------
>  1 file changed, 7 insertions(+), 7 deletions(-)

Reviewed-by: Simon Glass <sjg@chromium.org>

^ permalink raw reply	[flat|nested] 138+ messages in thread

* [U-Boot] [PATCH 03/51] gdsys: Post ppc4xx removal cleanup
  2017-07-14 12:54 ` [U-Boot] [PATCH 03/51] gdsys: Post ppc4xx removal cleanup Mario Six
@ 2017-07-18 14:01   ` Simon Glass
  0 siblings, 0 replies; 138+ messages in thread
From: Simon Glass @ 2017-07-18 14:01 UTC (permalink / raw)
  To: u-boot

On 14 July 2017 at 05:54, Mario Six <mario.six@gdsys.cc> wrote:
> The ppc4xx architecture was recently removed, and with it several old
> gdsys 44x boards, but some "debris" from these purged boards was left
> over.
>
> This patch removes these remnants (mostly entries in Makefiles, some now
> superfluous data structures and some now obsolete config variables from
> the whitelist).
>
> Signed-off-by: Mario Six <mario.six@gdsys.cc>
> ---
>
>  board/gdsys/common/Makefile   |   4 --
>  board/gdsys/common/miiphybb.c | 128 ------------------------------------------
>  include/gdsys_fpga.h          |  96 -------------------------------
>  scripts/config_whitelist.txt  |  10 ----
>  4 files changed, 238 deletions(-)
>  delete mode 100644 board/gdsys/common/miiphybb.c

Reviewed-by: Simon Glass <sjg@chromium.org>

^ permalink raw reply	[flat|nested] 138+ messages in thread

* [U-Boot] [PATCH 04/51] net: phy: marvell: Fix style violations
  2017-07-14 12:54 ` [U-Boot] [PATCH 04/51] net: phy: marvell: Fix style violations Mario Six
@ 2017-07-18 14:01   ` Simon Glass
  2017-07-27 22:15   ` Joe Hershberger
  1 sibling, 0 replies; 138+ messages in thread
From: Simon Glass @ 2017-07-18 14:01 UTC (permalink / raw)
  To: u-boot

On 14 July 2017 at 05:54, Mario Six <mario.six@gdsys.cc> wrote:
> Fix some style violations in the Marvell PHY driver.
>
> Signed-off-by: Mario Six <mario.six@gdsys.cc>
> ---
>
>  drivers/net/phy/marvell.c | 44 ++++++++++++++++++++++----------------------
>  1 file changed, 22 insertions(+), 22 deletions(-)

Reviewed-by: Simon Glass <sjg@chromium.org>

^ permalink raw reply	[flat|nested] 138+ messages in thread

* [U-Boot] [PATCH 05/51] net: phy: marvell 88e151x: Fix handling of bare RGMII interface type
  2017-07-14 12:54 ` [U-Boot] [PATCH 05/51] net: phy: marvell 88e151x: Fix handling of bare RGMII interface type Mario Six
@ 2017-07-18 14:01   ` Simon Glass
  2017-07-27 16:55   ` Joe Hershberger
  1 sibling, 0 replies; 138+ messages in thread
From: Simon Glass @ 2017-07-18 14:01 UTC (permalink / raw)
  To: u-boot

On 14 July 2017 at 05:54, Mario Six <mario.six@gdsys.cc> wrote:
> Commit 68e6eca ("net: phy: marvell 88e151x: Fix handling of RGMII
> interface types") fixed the initialization of 88e151x phys, but made it
> so that interfaces of type PHY_INTERFACE_MODE_RGMII had both RX and TX
> delay bits cleared. The default (like in m88e1111s_config) is to have
> both bits set.
>
> Hence, this patch changes the behavior in the PHY_INTERFACE_MODE_RGMII
> case so that both bits are set.
>
> Signed-off-by: Mario Six <mario.six@gdsys.cc>
> ---
>
>  drivers/net/phy/marvell.c | 3 ++-
>  1 file changed, 2 insertions(+), 1 deletion(-)

Reviewed-by: Simon Glass <sjg@chromium.org>

^ permalink raw reply	[flat|nested] 138+ messages in thread

* [U-Boot] [PATCH 06/51] cmd: Add command for calculating binary operations
  2017-07-14 12:54 ` [U-Boot] [PATCH 06/51] cmd: Add command for calculating binary operations Mario Six
@ 2017-07-18 14:01   ` Simon Glass
  2017-07-19  8:53     ` Mario Six
  0 siblings, 1 reply; 138+ messages in thread
From: Simon Glass @ 2017-07-18 14:01 UTC (permalink / raw)
  To: u-boot

Hi Mario,

On 14 July 2017 at 05:54, Mario Six <mario.six@gdsys.cc> wrote:
> This patch adds a command that enables the calculation of bit operations
> (AND, OR, XOR) on binary data from the command line. Memory locations as
> well as the contents of environment variables are eligible as sources
> and destination of the binary data used in the operations.
>
> The possible applications are manifold: Setting specific bits in
> registers using the regular read-OR-write pattern, masking out bits in
> bit values, implementation of simple OTP encryption using the XOR
> operation, etc.
>
> Signed-off-by: Mario Six <mario.six@gdsys.cc>

Is this very different from setexpr? It looks like it supports and / or.

Regards,
Simon

^ permalink raw reply	[flat|nested] 138+ messages in thread

* [U-Boot] [PATCH 07/51] phy: Allow forcing clause 45 access
  2017-07-14 12:54 ` [U-Boot] [PATCH 07/51] phy: Allow forcing clause 45 access Mario Six
@ 2017-07-18 14:01   ` Simon Glass
  2017-07-25  7:30     ` Mario Six
  0 siblings, 1 reply; 138+ messages in thread
From: Simon Glass @ 2017-07-18 14:01 UTC (permalink / raw)
  To: u-boot

On 14 July 2017 at 05:54, Mario Six <mario.six@gdsys.cc> wrote:
> From: Dirk Eibach <dirk.eibach@gdsys.cc>
>
> get_phy_device_by_mask() assumes that a clause 45 phy does not respond
> to clause 22 requests. That is not true at least for Marvell 88X2242.
> So allow forcing clause 45 access to prevent reading bogus device ids.
>
> Signed-off-by: Dirk Eibach <dirk.eibach@gdsys.cc>
> Signed-off-by: Mario Six <mario.six@gdsys.cc>
> ---
>
>  drivers/net/phy/phy.c | 12 +++++++-----
>  include/phy.h         | 12 ++++++++++--
>  2 files changed, 17 insertions(+), 7 deletions(-)

Reviewed-by: Simon Glass <sjg@chromium.org>

Please see below.

>
> diff --git a/drivers/net/phy/phy.c b/drivers/net/phy/phy.c
> index 97e0bc022b..08ec2f2ad6 100644
> --- a/drivers/net/phy/phy.c
> +++ b/drivers/net/phy/phy.c
> @@ -707,7 +707,7 @@ static struct phy_device *search_for_existing_phy(struct mii_dev *bus,
>  }
>
>  static struct phy_device *get_phy_device_by_mask(struct mii_dev *bus,
> -               unsigned phy_mask, phy_interface_t interface)
> +               unsigned phy_mask, phy_interface_t interface, bool force_c45)
>  {
>         int i;
>         struct phy_device *phydev;
> @@ -718,6 +718,8 @@ static struct phy_device *get_phy_device_by_mask(struct mii_dev *bus,
>         /* Try Standard (ie Clause 22) access */
>         /* Otherwise we have to try Clause 45 */
>         for (i = 0; i < 5; i++) {
> +               if (!i && force_c45)
> +                       continue;
>                 phydev = create_phy_by_mask(bus, phy_mask,
>                                 i ? i : MDIO_DEVAD_NONE, interface);
>                 if (IS_ERR(phydev))
> @@ -748,7 +750,7 @@ static struct phy_device *get_phy_device_by_mask(struct mii_dev *bus,
>  static struct phy_device *get_phy_device(struct mii_dev *bus, int addr,
>                                          phy_interface_t interface)
>  {
> -       return get_phy_device_by_mask(bus, 1 << addr, interface);
> +       return get_phy_device_by_mask(bus, 1 << addr, interface, false);
>  }
>
>  int phy_reset(struct phy_device *phydev)
> @@ -817,8 +819,8 @@ int miiphy_reset(const char *devname, unsigned char addr)
>         return phy_reset(phydev);
>  }
>
> -struct phy_device *phy_find_by_mask(struct mii_dev *bus, unsigned phy_mask,
> -               phy_interface_t interface)
> +struct phy_device *__phy_find_by_mask(struct mii_dev *bus, unsigned phy_mask,
> +               phy_interface_t interface, bool force_c45)
>  {
>         /* Reset the bus */
>         if (bus->reset) {
> @@ -828,7 +830,7 @@ struct phy_device *phy_find_by_mask(struct mii_dev *bus, unsigned phy_mask,
>                 udelay(15000);
>         }
>
> -       return get_phy_device_by_mask(bus, phy_mask, interface);
> +       return get_phy_device_by_mask(bus, phy_mask, interface, force_c45);
>  }
>
>  #ifdef CONFIG_DM_ETH
> diff --git a/include/phy.h b/include/phy.h
> index 4f2094bdf0..75a9ae3314 100644
> --- a/include/phy.h
> +++ b/include/phy.h
> @@ -227,8 +227,16 @@ static inline int is_10g_interface(phy_interface_t interface)
>
>  int phy_init(void);
>  int phy_reset(struct phy_device *phydev);
> -struct phy_device *phy_find_by_mask(struct mii_dev *bus, unsigned phy_mask,
> -               phy_interface_t interface);
> +struct phy_device *__phy_find_by_mask(struct mii_dev *bus, unsigned phy_mask,
> +               phy_interface_t interface, bool force_c45);

Can you please add a function comment?

> +static inline struct phy_device *phy_find_by_mask(struct mii_dev *bus,
> +               unsigned phy_mask, phy_interface_t interface) {
> +       return __phy_find_by_mask(bus, phy_mask, interface, 0);
> +}
> +static inline struct phy_device *phy_find_by_mask_c45(struct mii_dev *bus,
> +               unsigned phy_mask, phy_interface_t interface) {
> +       return __phy_find_by_mask(bus, phy_mask, interface, 1);
> +}
>  #ifdef CONFIG_DM_ETH
>  void phy_connect_dev(struct phy_device *phydev, struct udevice *dev);
>  struct phy_device *phy_connect(struct mii_dev *bus, int addr,
> --
> 2.11.0
>

^ permalink raw reply	[flat|nested] 138+ messages in thread

* [U-Boot] [PATCH 08/51] phy: Fix style violations
  2017-07-14 12:54 ` [U-Boot] [PATCH 08/51] phy: Fix style violations Mario Six
@ 2017-07-18 14:01   ` Simon Glass
  0 siblings, 0 replies; 138+ messages in thread
From: Simon Glass @ 2017-07-18 14:01 UTC (permalink / raw)
  To: u-boot

On 14 July 2017 at 05:54, Mario Six <mario.six@gdsys.cc> wrote:
> Fix some style violations in the generic PHY management code.
>
> Signed-off-by: Mario Six <mario.six@gdsys.cc>
> ---
>
>  drivers/net/phy/phy.c | 83 +++++++++++++++++++++++++++++++--------------------
>  1 file changed, 50 insertions(+), 33 deletions(-)

Reviewed-by: Simon Glass <sjg@chromium.org>

^ permalink raw reply	[flat|nested] 138+ messages in thread

* [U-Boot] [PATCH 09/51] phy: Support Marvell 88X2242
  2017-07-14 12:54 ` [U-Boot] [PATCH 09/51] phy: Support Marvell 88X2242 Mario Six
@ 2017-07-18 14:01   ` Simon Glass
  2017-07-25  8:22     ` Mario Six
  0 siblings, 1 reply; 138+ messages in thread
From: Simon Glass @ 2017-07-18 14:01 UTC (permalink / raw)
  To: u-boot

Hi Mario,

On 14 July 2017 at 05:54, Mario Six <mario.six@gdsys.cc> wrote:
> From: Dirk Eibach <dirk.eibach@gdsys.cc>
>
> Implement support for the Marvell Alaska X 88X2242P Integrated Dual-port
> and Quad-port Multi-speed Ethernet Transceivers.
>
> Signed-off-by: Dirk Eibach <dirk.eibach@gdsys.cc>
> Signed-off-by: Mario Six <mario.six@gdsys.cc>
> ---
>
>  drivers/net/phy/Kconfig   |  67 ++++
>  drivers/net/phy/Makefile  |   1 +
>  drivers/net/phy/marvell.c |   1 -
>  drivers/net/phy/mv88x2.c  | 846 ++++++++++++++++++++++++++++++++++++++++++++++
>  drivers/net/phy/mv88x2.h  |  12 +
>  drivers/net/phy/phy.c     |   3 +
>  include/phy.h             |   1 +
>  7 files changed, 930 insertions(+), 1 deletion(-)
>  create mode 100644 drivers/net/phy/mv88x2.c
>  create mode 100644 drivers/net/phy/mv88x2.h
>

We should really be using driver model here. Is the generic phy uclass
good enough (generic-phy.h), or do we need a new uclass for Ethernet
PHY?

Regards,
Simon

^ permalink raw reply	[flat|nested] 138+ messages in thread

* [U-Boot] [PATCH 10/51] net:phy:marvell Add hook for m88e1510 board config
  2017-07-14 12:54 ` [U-Boot] [PATCH 10/51] net:phy:marvell Add hook for m88e1510 board config Mario Six
@ 2017-07-18 14:01   ` Simon Glass
  2017-07-25 13:43     ` Mario Six
  0 siblings, 1 reply; 138+ messages in thread
From: Simon Glass @ 2017-07-18 14:01 UTC (permalink / raw)
  To: u-boot

Hi Mario,

On 14 July 2017 at 05:54, Mario Six <mario.six@gdsys.cc> wrote:
> From: Dirk Eibach <dirk.eibach@gdsys.cc>
>
> m88e1510_config() is highly board-specific. So add an optional
> callback board_m88e1510_config() configurable by
> CONFIG_BOARD_M88E1510_CONFIG to support different hardware.
>
> Signed-off-by: Dirk Eibach <dirk.eibach@gdsys.cc>
> Signed-off-by: Mario Six <mario.six@gdsys.cc>
> ---
>
>  drivers/net/phy/marvell.c |  5 +++++
>  include/marvell-phy.h     | 10 ++++++++++
>  2 files changed, 15 insertions(+)
>  create mode 100644 include/marvell-phy.h
>
> diff --git a/drivers/net/phy/marvell.c b/drivers/net/phy/marvell.c
> index 66107a8af3..b3d05d5af4 100644
> --- a/drivers/net/phy/marvell.c
> +++ b/drivers/net/phy/marvell.c
> @@ -9,6 +9,7 @@
>  #include <config.h>
>  #include <common.h>
>  #include <errno.h>
> +#include <marvell-phy.h>
>  #include <phy.h>
>
>  #define PHY_AUTONEGOTIATE_TIMEOUT 5000
> @@ -381,6 +382,9 @@ static int m88e1518_config(struct phy_device *phydev)
>  /* Marvell 88E1510 */
>  static int m88e1510_config(struct phy_device *phydev)
>  {
> +#ifdef CONFIG_BOARD_M88E1510_CONFIG
> +       board_m88e1510_config(phydev);
> +#else

We should not be calling into board code from drivers. How could we do
this with driver model / DT?

>         /* Select page 3 */
>         phy_write(phydev, MDIO_DEVAD_NONE, MIIM_88E1118_PHY_PAGE,
>                   MIIM_88E1118_PHY_LED_PAGE);
> @@ -401,6 +405,7 @@ static int m88e1510_config(struct phy_device *phydev)
>
>         /* Reset page selection */
>         phy_write(phydev, MDIO_DEVAD_NONE, MIIM_88E1118_PHY_PAGE, 0);
> +#endif
>
>         return m88e1518_config(phydev);
>  }
> diff --git a/include/marvell-phy.h b/include/marvell-phy.h
> new file mode 100644
> index 0000000000..1cfa5ed557
> --- /dev/null
> +++ b/include/marvell-phy.h
> @@ -0,0 +1,10 @@
> +#ifndef _MARVELL_PHY_H
> +#define _MARVELL_PHY_H
> +
> +#include <phy.h>
> +
> +void m88e1518_phy_writebits(struct phy_device *phydev,
> +                  u8 reg_num, u16 offset, u16 len, u16 data);
> +int board_m88e1510_config(struct phy_device *phydev);
> +
> +#endif
> --
> 2.11.0
>

Regards,
Simon

^ permalink raw reply	[flat|nested] 138+ messages in thread

* [U-Boot] [PATCH 11/51] powerpc: mpc83xx: Implement get_serial_clock()
  2017-07-14 12:54 ` [U-Boot] [PATCH 11/51] powerpc: mpc83xx: Implement get_serial_clock() Mario Six
@ 2017-07-18 14:01   ` Simon Glass
  2017-07-25  7:34     ` Mario Six
  0 siblings, 1 reply; 138+ messages in thread
From: Simon Glass @ 2017-07-18 14:01 UTC (permalink / raw)
  To: u-boot

On 14 July 2017 at 05:54, Mario Six <mario.six@gdsys.cc> wrote:
> DM serial drivers on PowerPC determine their clock frequency via the
> get_serial_clock function. This function is not Implemented yet for
> MPC83xx.
>
> This patch Implements the function so that DM serial drivers work on
> MPC83xx.
>
> Signed-off-by: Mario Six <mario.six@gdsys.cc>
> ---
>
>  arch/powerpc/cpu/mpc83xx/speed.c | 7 +++++++
>  1 file changed, 7 insertions(+)

Reviewed-by: Simon Glass <sjg@chromium.org>

Really a clock driver would be better.

^ permalink raw reply	[flat|nested] 138+ messages in thread

* [U-Boot] [PATCH 12/51] cfi_flash: Fix style violations
  2017-07-14 12:54 ` [U-Boot] [PATCH 12/51] cfi_flash: Fix style violations Mario Six
@ 2017-07-18 14:01   ` Simon Glass
  0 siblings, 0 replies; 138+ messages in thread
From: Simon Glass @ 2017-07-18 14:01 UTC (permalink / raw)
  To: u-boot

On 14 July 2017 at 05:54, Mario Six <mario.six@gdsys.cc> wrote:
> Fix style violations in the CFI flash driver.
>
> Signed-off-by: Mario Six <mario.six@gdsys.cc>
> ---
>
>  drivers/mtd/cfi_flash.c | 889 ++++++++++++++++++++++++------------------------
>  1 file changed, 443 insertions(+), 446 deletions(-)
>

Reviewed-by: Simon Glass <sjg@chromium.org>

^ permalink raw reply	[flat|nested] 138+ messages in thread

* [U-Boot] [PATCH 13/51] cfi_flash: Clean up code some more
  2017-07-14 12:54 ` [U-Boot] [PATCH 13/51] cfi_flash: Clean up code some more Mario Six
@ 2017-07-18 14:02   ` Simon Glass
  2017-07-19  8:30     ` Mario Six
  0 siblings, 1 reply; 138+ messages in thread
From: Simon Glass @ 2017-07-18 14:02 UTC (permalink / raw)
  To: u-boot

On 14 July 2017 at 05:54, Mario Six <mario.six@gdsys.cc> wrote:
> Fix some more style violations (mostly mis-indented case statements),
> and reduce the scope of some variables.
>
> Signed-off-by: Mario Six <mario.six@gdsys.cc>
> ---
>
>  drivers/mtd/cfi_flash.c | 610 ++++++++++++++++++++++++------------------------
>  1 file changed, 305 insertions(+), 305 deletions(-)

Big change, but it looks right to me if I haven't missed something.

Reviewed-by: Simon Glass <sjg@chromium.org>

^ permalink raw reply	[flat|nested] 138+ messages in thread

* [U-Boot] [PATCH 14/51] cfi_flash: Always define cfi_flash_num_flash_banks
  2017-07-14 12:55 ` [U-Boot] [PATCH 14/51] cfi_flash: Always define cfi_flash_num_flash_banks Mario Six
@ 2017-07-18 14:02   ` Simon Glass
  0 siblings, 0 replies; 138+ messages in thread
From: Simon Glass @ 2017-07-18 14:02 UTC (permalink / raw)
  To: u-boot

On 14 July 2017 at 05:55, Mario Six <mario.six@gdsys.cc> wrote:
> The variable cfi_flash_num_flash_banks is defined iff
> CONFIG_SYS_MAX_FLASH_BANKS_DETECT is defined, but it is used
> unconditionally in the function cfi_flash_init_dm. This leads to a
> undefined variable compile error when CONFIG_SYS_MAX_FLASH_BANKS_DETECT
> is not defined, but DM is enabled.
>
> Fix this by always defining the cfi_flash_num_flash_banks variable.
>
> Signed-off-by: Mario Six <mario.six@gdsys.cc>
> ---
>
>  drivers/mtd/cfi_flash.c | 2 ++
>  1 file changed, 2 insertions(+)

Reviewed-by: Simon Glass <sjg@chromium.org>

^ permalink raw reply	[flat|nested] 138+ messages in thread

* [U-Boot] [PATCH 15/51] gpio: mpc85xx_gpio: Fix style violations
  2017-07-14 12:55 ` [U-Boot] [PATCH 15/51] gpio: mpc85xx_gpio: Fix style violations Mario Six
@ 2017-07-18 14:02   ` Simon Glass
  0 siblings, 0 replies; 138+ messages in thread
From: Simon Glass @ 2017-07-18 14:02 UTC (permalink / raw)
  To: u-boot

On 14 July 2017 at 05:55, Mario Six <mario.six@gdsys.cc> wrote:
> Fix some style violations in the MPC85XX GPIO driver.
>
> Signed-off-by: Mario Six <mario.six@gdsys.cc>
> ---
>
>  drivers/gpio/mpc85xx_gpio.c | 42 ++++++++++++++++++++++--------------------
>  1 file changed, 22 insertions(+), 20 deletions(-)

Reviewed-by: Simon Glass <sjg@chromium.org>

^ permalink raw reply	[flat|nested] 138+ messages in thread

* [U-Boot] [PATCH 16/51] gpio: mpc85xx_gpio: Make compatible with MPC8XXX
  2017-07-14 12:55 ` [U-Boot] [PATCH 16/51] gpio: mpc85xx_gpio: Make compatible with MPC8XXX Mario Six
@ 2017-07-18 14:02   ` Simon Glass
  2017-07-19  8:24     ` Mario Six
  0 siblings, 1 reply; 138+ messages in thread
From: Simon Glass @ 2017-07-18 14:02 UTC (permalink / raw)
  To: u-boot

Hi Mario,

On 14 July 2017 at 05:55, Mario Six <mario.six@gdsys.cc> wrote:
> Since the GPIO controllers on MPC8XXX just vary in the number of pins
> offered, the DM driver for the MPC85XX SoC can be used for the whole
> family.
>
> To reflect this, we rename the mpc85xx_gpio driver to the more generic
> mpc8xxx_gpio, and add the needed mpc8xxx_gpio_plat structure to the
> mpc83xx gpio.h.
>
> Hence, this driver now also serves as a GPIO DM-driver for the MPC83XX
> platform.
>
> Signed-off-by: Mario Six <mario.six@gdsys.cc>
> ---
>
>  arch/powerpc/include/asm/arch-mpc83xx/gpio.h |   8 +
>  arch/powerpc/include/asm/arch-mpc85xx/gpio.h |   2 +-
>  drivers/gpio/Kconfig                         |   9 +-
>  drivers/gpio/Makefile                        |   2 +-
>  drivers/gpio/mpc85xx_gpio.c                  | 253 -------------------------
>  drivers/gpio/mpc8xxx_gpio.c                  | 274 +++++++++++++++++++++++++++
>  6 files changed, 287 insertions(+), 261 deletions(-)
>  delete mode 100644 drivers/gpio/mpc85xx_gpio.c
>  create mode 100644 drivers/gpio/mpc8xxx_gpio.c

This is hard to review as it seems you have made changes as well as
renamed the fine. Can you do the rename first and then the changes in
a subsequent patch?

^ permalink raw reply	[flat|nested] 138+ messages in thread

* [U-Boot] [PATCH 17/51] cmd: mdio: Fix style violations
  2017-07-14 12:55 ` [U-Boot] [PATCH 17/51] cmd: mdio: Fix style violations Mario Six
@ 2017-07-18 14:02   ` Simon Glass
  0 siblings, 0 replies; 138+ messages in thread
From: Simon Glass @ 2017-07-18 14:02 UTC (permalink / raw)
  To: u-boot

On 14 July 2017 at 05:55, Mario Six <mario.six@gdsys.cc> wrote:
> Fix some style violations in the MDIO command.
>
> Signed-off-by: Mario Six <mario.six@gdsys.cc>
> ---
>
>  cmd/mdio.c | 7 +++----
>  1 file changed, 3 insertions(+), 4 deletions(-)

Reviewed-by: Simon Glass <sjg@chromium.org>

^ permalink raw reply	[flat|nested] 138+ messages in thread

* [U-Boot] [PATCH 18/51] cmd: mdio: Add 'driver' subcommand
  2017-07-14 12:55 ` [U-Boot] [PATCH 18/51] cmd: mdio: Add 'driver' subcommand Mario Six
@ 2017-07-18 14:02   ` Simon Glass
  2017-07-25  8:25     ` Mario Six
  0 siblings, 1 reply; 138+ messages in thread
From: Simon Glass @ 2017-07-18 14:02 UTC (permalink / raw)
  To: u-boot

Hi Mario,

On 14 July 2017 at 05:55, Mario Six <mario.six@gdsys.cc> wrote:
> For debug purposes it is sometimes useful to have the ability to
> interact with the driver functionality of a phy from the command line
> (e.g. to manually issue startup, configuration, or shutdown commands to
> the phy device).
>
> This patch adds such a command, which allows issuing the following
> commands to a phy:
>  * getting the driver's name
>  * running the phy's configuration procedure (via calling phy_config)
>  * running the phy's startup procedure (via calling phy_startup)
>  * running the phy's shutdown procedure (via calling phy_shutdown)
>
> Signed-off-by: Mario Six <mario.six@gdsys.cc>
> ---
>
>  cmd/Kconfig |  6 ++++++
>  cmd/mdio.c  | 65 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
>  2 files changed, 71 insertions(+)

This seems reasonable, but we need to figure out how to use driver model.

Regards,
Simon

^ permalink raw reply	[flat|nested] 138+ messages in thread

* [U-Boot] [PATCH 19/51] common: board_f: Fix style violations
  2017-07-14 12:55 ` [U-Boot] [PATCH 19/51] common: board_f: Fix style violations Mario Six
@ 2017-07-18 14:02   ` Simon Glass
  0 siblings, 0 replies; 138+ messages in thread
From: Simon Glass @ 2017-07-18 14:02 UTC (permalink / raw)
  To: u-boot

On 14 July 2017 at 05:55, Mario Six <mario.six@gdsys.cc> wrote:
> Fix some style violations in the board_f file.
>
> Signed-off-by: Mario Six <mario.six@gdsys.cc>
> ---
>
>  common/board_f.c | 10 +++++-----
>  1 file changed, 5 insertions(+), 5 deletions(-)

Reviewed-by: Simon Glass <sjg@chromium.org>

^ permalink raw reply	[flat|nested] 138+ messages in thread

* [U-Boot] [PATCH 20/51] common: board_r: Fix style violations
  2017-07-14 12:55 ` [U-Boot] [PATCH 20/51] common: board_r: " Mario Six
@ 2017-07-18 14:02   ` Simon Glass
  0 siblings, 0 replies; 138+ messages in thread
From: Simon Glass @ 2017-07-18 14:02 UTC (permalink / raw)
  To: u-boot

On 14 July 2017 at 05:55, Mario Six <mario.six@gdsys.cc> wrote:
> Fix some style violations in the board_r file.
>
> Signed-off-by: Mario Six <mario.six@gdsys.cc>
> ---
>
>  common/board_r.c | 27 ++++++++++++++-------------
>  1 file changed, 14 insertions(+), 13 deletions(-)

Reviewed-by: Simon Glass <sjg@chromium.org>

^ permalink raw reply	[flat|nested] 138+ messages in thread

* [U-Boot] [PATCH 16/51] gpio: mpc85xx_gpio: Make compatible with MPC8XXX
  2017-07-18 14:02   ` Simon Glass
@ 2017-07-19  8:24     ` Mario Six
  0 siblings, 0 replies; 138+ messages in thread
From: Mario Six @ 2017-07-19  8:24 UTC (permalink / raw)
  To: u-boot

Hi Simon,

On Tue, Jul 18, 2017 at 4:02 PM, Simon Glass <sjg@chromium.org> wrote:
> Hi Mario,
>
> On 14 July 2017 at 05:55, Mario Six <mario.six@gdsys.cc> wrote:
>> Since the GPIO controllers on MPC8XXX just vary in the number of pins
>> offered, the DM driver for the MPC85XX SoC can be used for the whole
>> family.
>>
>> To reflect this, we rename the mpc85xx_gpio driver to the more generic
>> mpc8xxx_gpio, and add the needed mpc8xxx_gpio_plat structure to the
>> mpc83xx gpio.h.
>>
>> Hence, this driver now also serves as a GPIO DM-driver for the MPC83XX
>> platform.
>>
>> Signed-off-by: Mario Six <mario.six@gdsys.cc>
>> ---
>>
>>  arch/powerpc/include/asm/arch-mpc83xx/gpio.h |   8 +
>>  arch/powerpc/include/asm/arch-mpc85xx/gpio.h |   2 +-
>>  drivers/gpio/Kconfig                         |   9 +-
>>  drivers/gpio/Makefile                        |   2 +-
>>  drivers/gpio/mpc85xx_gpio.c                  | 253 -------------------------
>>  drivers/gpio/mpc8xxx_gpio.c                  | 274 +++++++++++++++++++++++++++
>>  6 files changed, 287 insertions(+), 261 deletions(-)
>>  delete mode 100644 drivers/gpio/mpc85xx_gpio.c
>>  create mode 100644 drivers/gpio/mpc8xxx_gpio.c
>
> This is hard to review as it seems you have made changes as well as
> renamed the fine. Can you do the rename first and then the changes in
> a subsequent patch?

OK, I'll split this one into two patches. If you want to take a look
in the mean time, a bit of git magic helps:

git diff -C30% COMMITID~1..COMMITID

Where COMMITID is the id of the commit. This should ignore the rename and only
display the actual changes.

Best regards,
Mario

^ permalink raw reply	[flat|nested] 138+ messages in thread

* [U-Boot] [PATCH 13/51] cfi_flash: Clean up code some more
  2017-07-18 14:02   ` Simon Glass
@ 2017-07-19  8:30     ` Mario Six
  0 siblings, 0 replies; 138+ messages in thread
From: Mario Six @ 2017-07-19  8:30 UTC (permalink / raw)
  To: u-boot

Hi Simon,

On Tue, Jul 18, 2017 at 4:02 PM, Simon Glass <sjg@chromium.org> wrote:
> On 14 July 2017 at 05:54, Mario Six <mario.six@gdsys.cc> wrote:
>> Fix some more style violations (mostly mis-indented case statements),
>> and reduce the scope of some variables.
>>
>> Signed-off-by: Mario Six <mario.six@gdsys.cc>
>> ---
>>
>>  drivers/mtd/cfi_flash.c | 610 ++++++++++++++++++++++++------------------------
>>  1 file changed, 305 insertions(+), 305 deletions(-)
>
> Big change, but it looks right to me if I haven't missed something.
>
> Reviewed-by: Simon Glass <sjg@chromium.org>

Yeah, it looks big, but the vast majority are white space changes.

git show -w COMMITID

helps a lot here.

I also neglected to mention the changes to early-return style in the commit
message. Will fix in v2.

Best regards,

Mario

^ permalink raw reply	[flat|nested] 138+ messages in thread

* [U-Boot] [PATCH 06/51] cmd: Add command for calculating binary operations
  2017-07-18 14:01   ` Simon Glass
@ 2017-07-19  8:53     ` Mario Six
  2017-07-19  9:07       ` Simon Glass
  0 siblings, 1 reply; 138+ messages in thread
From: Mario Six @ 2017-07-19  8:53 UTC (permalink / raw)
  To: u-boot

Hi Simon,

On Tue, Jul 18, 2017 at 4:01 PM, Simon Glass <sjg@chromium.org> wrote:
> Hi Mario,
>
> On 14 July 2017 at 05:54, Mario Six <mario.six@gdsys.cc> wrote:
>> This patch adds a command that enables the calculation of bit operations
>> (AND, OR, XOR) on binary data from the command line. Memory locations as
>> well as the contents of environment variables are eligible as sources
>> and destination of the binary data used in the operations.
>>
>> The possible applications are manifold: Setting specific bits in
>> registers using the regular read-OR-write pattern, masking out bits in
>> bit values, implementation of simple OTP encryption using the XOR
>> operation, etc.
>>
>> Signed-off-by: Mario Six <mario.six@gdsys.cc>
>
> Is this very different from setexpr? It looks like it supports and / or.
>
> Regards,
> Simon

It is quite similar, but it lacks the support to write the result directly back
to memory, and, the more important point, it also only operates on bytes, words
and longs, whereas binop operates on arbitrarily long byte arrays.

I thought about somehow fixing up setexpr to add support for these two
features, but couldn't think of a good way to do so. Do you have an idea how to
do that? I'd also rather not add an additional command if somehow possible.

Best regards,

Mario

^ permalink raw reply	[flat|nested] 138+ messages in thread

* [U-Boot] [PATCH 21/51] common: Extend board-specific DT fixup
  2017-07-14 12:55 ` [U-Boot] [PATCH 21/51] common: Extend board-specific DT fixup Mario Six
@ 2017-07-19  9:05   ` Simon Glass
  2017-07-25  8:40     ` Mario Six
  0 siblings, 1 reply; 138+ messages in thread
From: Simon Glass @ 2017-07-19  9:05 UTC (permalink / raw)
  To: u-boot

Hi Mario,

On 14 July 2017 at 05:55, Mario Six <mario.six@gdsys.cc> wrote:
> Commit 2a79275 ("dm: Add callback to modify the device tree")
> implemented a board-specific callback that can modify U-Boot's device
> tree before relocation to accomodate a range of hardware variations of
> certain boards.
>
> However, this approach only turns out to be useful when the copy of the
> device tree before relocation is actually writeable. If e.g. a device
> boots out of a NOR flash, this scheme does not work, since the
> modification of the flash's contents is not possible, and the unmodified
> device tree is relocated and used by U-Boot.
>
> To circumvent this problem, we split the modification process into two
> phases.
>
> In phase one we only collect information about the board by querying the
> hardware (reading GPIO values, probing I2C chips, etc.), and store the
> obtained information in a special, board-specific structure that is part
> of the global data structure. This phase runs prior to relocation, and
> utilizes the pre-relocation DM to query hardware information.
>
> In phase two, we read the information back from the structure, and do
> the actual manipulation of the device tree. This phase occurs *after*
> the relocation of the U-Boot image, but before the driver model is
> initialized from the device tree. Since the device tree lives in RAM
> alongside the U-Boot image after relocation, the tree is definitely
> writeable at this point.
>
> Each phase is implemented by a board-specific callback function: phase
> one by board_fix_fdt_get_info, which takes no arguments, and phase two
> by board_fix_fdt_change, which takes the writeable device tree blob as
> its sole argument. Since the structure where the gathered hardware
> information is stored is necessarily board-dependent, we create a
> include file where the boards utilizing the functionality can define
> their individually needed structures.
>
> This commit also adapts the controlcenterdc board's fixup function to
> the new schem

Thanks for the clear explanation.

I have two ideas:

- Can we move the call to the existing function to after reloc_fdt(),
when the DT is in RAM?

- Or can we move this board to use a livetree and adjust the DT using
livetree functions instead? That might be more efficient.

Regards,
Simon

^ permalink raw reply	[flat|nested] 138+ messages in thread

* [U-Boot] [PATCH 22/51] gdsys: mpc8308: Fix style violations
  2017-07-14 12:55 ` [U-Boot] [PATCH 22/51] gdsys: mpc8308: Fix style violations Mario Six
@ 2017-07-19  9:05   ` Simon Glass
  0 siblings, 0 replies; 138+ messages in thread
From: Simon Glass @ 2017-07-19  9:05 UTC (permalink / raw)
  To: u-boot

On 14 July 2017 at 05:55, Mario Six <mario.six@gdsys.cc> wrote:
> Fix some style violations in the gdsys MPC8308 board files, and make the
> code more readable.
>
> Signed-off-by: Mario Six <mario.six@gdsys.cc>
> ---
>
>  board/gdsys/mpc8308/hrcon.c   | 55 ++++++++++++++++++++++---------------------
>  board/gdsys/mpc8308/mpc8308.c | 12 +++++-----
>  board/gdsys/mpc8308/strider.c | 49 +++++++++++++++++++-------------------
>  3 files changed, 59 insertions(+), 57 deletions(-)

Reviewed-by: Simon Glass <sjg@chromium.org>

^ permalink raw reply	[flat|nested] 138+ messages in thread

* [U-Boot] [PATCH 23/51] gdsys: mpc8308: Use shadow register for output GPIO values
  2017-07-14 12:55 ` [U-Boot] [PATCH 23/51] gdsys: mpc8308: Use shadow register for output GPIO values Mario Six
@ 2017-07-19  9:05   ` Simon Glass
  0 siblings, 0 replies; 138+ messages in thread
From: Simon Glass @ 2017-07-19  9:05 UTC (permalink / raw)
  To: u-boot

On 14 July 2017 at 05:55, Mario Six <mario.six@gdsys.cc> wrote:
> Since gpio output status on MPC8xxx cannot be read back, it has to be
> buffered locally.
>
> Signed-off-by: Dirk Eibach <dirk.eibach@gdsys.cc>
> Signed-off-by: Mario Six <mario.six@gdsys.cc>
> ---
>
>  board/gdsys/mpc8308/hrcon.c   |  4 ++--
>  board/gdsys/mpc8308/mpc8308.c | 19 +++++++++++++++++++
>  board/gdsys/mpc8308/mpc8308.h |  3 +++
>  board/gdsys/mpc8308/strider.c |  2 +-
>  4 files changed, 25 insertions(+), 3 deletions(-)

Reviewed-by: Simon Glass <sjg@chromium.org>

^ permalink raw reply	[flat|nested] 138+ messages in thread

* [U-Boot] [PATCH 24/51] gdsys: mpc8308: Move SYS_FPGA{0, 1}_{BASE, SIZE} to Kconfig
  2017-07-14 12:55 ` [U-Boot] [PATCH 24/51] gdsys: mpc8308: Move SYS_FPGA{0, 1}_{BASE, SIZE} to Kconfig Mario Six
@ 2017-07-19  9:05   ` Simon Glass
  2017-07-25  7:39     ` Mario Six
  0 siblings, 1 reply; 138+ messages in thread
From: Simon Glass @ 2017-07-19  9:05 UTC (permalink / raw)
  To: u-boot

Hi Mario,

On 14 July 2017 at 05:55, Mario Six <mario.six@gdsys.cc> wrote:
> Move CONFIG_SYS_FPGA0_BASE, CONFIG_SYS_FPGA0_SIZE, CONFIG_SYS_FPGA1_BASE, and
> CONFIG_SYS_FPGA1_SIZE to Kconfig.

It looks like the FPGA1 options are actually new?

Reviewed-by: Simon Glass <sjg@chromium.org>

We perhaps need an FPGA uclass and a DM driver?

>
> Signed-off-by: Mario Six <mario.six@gdsys.cc>
> ---
>
>  board/gdsys/mpc8308/Kconfig  | 23 +++++++++++++++++++++++
>  include/configs/hrcon.h      |  7 -------
>  include/configs/strider.h    |  7 -------
>  scripts/config_whitelist.txt |  2 --
>  4 files changed, 23 insertions(+), 16 deletions(-)

^ permalink raw reply	[flat|nested] 138+ messages in thread

* [U-Boot] [PATCH 25/51] gdsys: Introduce GDSYS_LEGACY_DRIVERS
  2017-07-14 12:55 ` [U-Boot] [PATCH 25/51] gdsys: Introduce GDSYS_LEGACY_DRIVERS Mario Six
@ 2017-07-19  9:05   ` Simon Glass
  2017-07-25  7:40     ` Mario Six
  0 siblings, 1 reply; 138+ messages in thread
From: Simon Glass @ 2017-07-19  9:05 UTC (permalink / raw)
  To: u-boot

On 14 July 2017 at 05:55, Mario Six <mario.six@gdsys.cc> wrote:
> Future gdsys boards will switch from the legacy drivers in board/gdsys/common
> to DM-based drivers.
>
> Define a Kconfig option that disables the legacy drivers.
>
> Signed-off-by: Mario Six <mario.six@gdsys.cc>
> ---
>
>  board/gdsys/common/adv7611.c   | 4 ++++
>  board/gdsys/common/ch7301.c    | 4 ++++
>  board/gdsys/common/dp501.c     | 4 ++++
>  board/gdsys/common/fanctrl.c   | 4 ++++
>  board/gdsys/common/fpga.c      | 4 ++++
>  board/gdsys/common/ihs_mdio.c  | 4 ++++
>  board/gdsys/common/ioep-fpga.c | 4 ++++
>  board/gdsys/common/mclink.c    | 4 ++++
>  board/gdsys/common/osd.c       | 4 ++++
>  board/gdsys/mpc8308/Kconfig    | 8 ++++++++
>  board/gdsys/mpc8308/mpc8308.c  | 2 ++
>  board/gdsys/p1022/Kconfig      | 6 ++++++
>  include/gdsys_fpga.h           | 2 ++
>  13 files changed, 54 insertions(+)

Reviewed-by: Simon Glass <sjg@chromium.org>

But can you add a help message to your Kconfig?

^ permalink raw reply	[flat|nested] 138+ messages in thread

* [U-Boot] [PATCH 26/51] strider, hrcon: Reset CAT phy on CON2 module
  2017-07-14 12:55 ` [U-Boot] [PATCH 26/51] strider, hrcon: Reset CAT phy on CON2 module Mario Six
@ 2017-07-19  9:05   ` Simon Glass
  0 siblings, 0 replies; 138+ messages in thread
From: Simon Glass @ 2017-07-19  9:05 UTC (permalink / raw)
  To: u-boot

On 14 July 2017 at 05:55, Mario Six <mario.six@gdsys.cc> wrote:
> From: Dirk Eibach <dirk.eibach@gdsys.cc>
>
> The phy on the CON2 module needs a defined reset pulse of at least 10 ms
> to work reliably.
>
> Signed-off-by: Dirk Eibach <dirk.eibach@gdsys.cc>
> Signed-off-by: Mario Six <mario.six@gdsys.cc>
> ---
>
>  board/gdsys/mpc8308/hrcon.c   | 30 ++++++++++++++++++++++++++++++
>  board/gdsys/mpc8308/strider.c | 24 ++++++++++++++++++++++++
>  2 files changed, 54 insertions(+)

That's a long time!

Reviewed-by: Simon Glass <sjg@chromium.org>

^ permalink raw reply	[flat|nested] 138+ messages in thread

* [U-Boot] [PATCH 27/51] gdsys:phy: Adapt fixup_88e1518() to latest Release Notes
  2017-07-14 12:55 ` [U-Boot] [PATCH 27/51] gdsys:phy: Adapt fixup_88e1518() to latest Release Notes Mario Six
@ 2017-07-19  9:05   ` Simon Glass
  0 siblings, 0 replies; 138+ messages in thread
From: Simon Glass @ 2017-07-19  9:05 UTC (permalink / raw)
  To: u-boot

On 14 July 2017 at 05:55, Mario Six <mario.six@gdsys.cc> wrote:
> From: Dirk Eibach <dirk.eibach@gdsys.cc>
>
> The initialization sequence described in the latest Release Notes
> MV-S302033-00 for the Marvell 88E1518 phy omits two register writes.
>
> Use this new sequence for the setup of this phy.
>
> Signed-off-by: Dirk Eibach <dirk.eibach@gdsys.cc>
> Signed-off-by: Mario Six <mario.six@gdsys.cc>
> ---
>
>  board/gdsys/common/phy.c | 2 --
>  1 file changed, 2 deletions(-)

Reviewed-by: Simon Glass <sjg@chromium.org>

^ permalink raw reply	[flat|nested] 138+ messages in thread

* [U-Boot] [PATCH 28/51] i2c: ihs_i2c: Prepare DM conversion
  2017-07-14 12:55 ` [U-Boot] [PATCH 28/51] i2c: ihs_i2c: Prepare DM conversion Mario Six
@ 2017-07-19  9:05   ` Simon Glass
  2017-07-25  7:48     ` Mario Six
  0 siblings, 1 reply; 138+ messages in thread
From: Simon Glass @ 2017-07-19  9:05 UTC (permalink / raw)
  To: u-boot

On 14 July 2017 at 05:55, Mario Six <mario.six@gdsys.cc> wrote:
> Prepare the function interface of the ihs_i2c driver for DM conversion
> in a future patch.
>
> While we're at it, fix some style violations, and make the code more readable.
>
> Signed-off-by: Mario Six <mario.six@gdsys.cc>
> ---
>
>  drivers/i2c/ihs_i2c.c | 74 +++++++++++++++++++++++++++++++--------------------
>  1 file changed, 45 insertions(+), 29 deletions(-)

Reviewed-by: Simon Glass <sjg@chromium.org>

Please see below

>
> diff --git a/drivers/i2c/ihs_i2c.c b/drivers/i2c/ihs_i2c.c
> index 29612e69fe..e066ad53db 100644
> --- a/drivers/i2c/ihs_i2c.c
> +++ b/drivers/i2c/ihs_i2c.c

> @@ -182,13 +182,29 @@ static int ihs_i2c_probe(struct i2c_adapter *adap, uchar chip)
>  static int ihs_i2c_read(struct i2c_adapter *adap, uchar chip, uint addr,
>                         int alen, uchar *buffer, int len)
>  {
> -       return ihs_i2c_access(adap, chip, addr, alen, buffer, len, true);
> +       u8 addr_bytes[4];
> +
> +       addr_bytes[0] = (addr >> 0) & 0xFF;
> +       addr_bytes[1] = (addr >> 8) & 0xFF;
> +       addr_bytes[2] = (addr >> 16) & 0xFF;
> +       addr_bytes[3] = (addr >> 24) & 0xFF;

Can you use put_unaligned_le32() or similar?

> +
> +       return ihs_i2c_access(adap, chip, addr_bytes, alen, buffer, len,
> +                             I2COP_READ);
>  }
>
>  static int ihs_i2c_write(struct i2c_adapter *adap, uchar chip, uint addr,
>                          int alen, uchar *buffer, int len)
>  {
> -       return ihs_i2c_access(adap, chip, addr, alen, buffer, len, false);
> +       u8 addr_bytes[4];
> +
> +       addr_bytes[0] = (addr >> 0) & 0xFF;
> +       addr_bytes[1] = (addr >> 8) & 0xFF;
> +       addr_bytes[2] = (addr >> 16) & 0xFF;
> +       addr_bytes[3] = (addr >> 24) & 0xFF;
> +
> +       return ihs_i2c_access(adap, chip, addr_bytes, alen, buffer, len,
> +                             I2COP_WRITE);
>  }
>
>  static unsigned int ihs_i2c_set_bus_speed(struct i2c_adapter *adap,
> --
> 2.11.0
>

Regards,
Simon

^ permalink raw reply	[flat|nested] 138+ messages in thread

* [U-Boot] [PATCH 29/51] i2c: ihs_i2c: Make DM compatible
  2017-07-14 12:55 ` [U-Boot] [PATCH 29/51] i2c: ihs_i2c: Make DM compatible Mario Six
@ 2017-07-19  9:05   ` Simon Glass
  2017-07-25  7:50     ` Mario Six
  0 siblings, 1 reply; 138+ messages in thread
From: Simon Glass @ 2017-07-19  9:05 UTC (permalink / raw)
  To: u-boot

On 14 July 2017 at 05:55, Mario Six <mario.six@gdsys.cc> wrote:
> Make the ihs_i2c driver DM-compatible; for legacy boards, the old functions are
> retained within #ifdefs.
>
> No board uses the new DM driver yet; this patch only lays the foundation for
> future support.
>
> Signed-off-by: Mario Six <mario.six@gdsys.cc>
> ---
>
>  drivers/i2c/Kconfig          |   6 ++
>  drivers/i2c/ihs_i2c.c        | 197 ++++++++++++++++++++++++++++++++++++++++++-
>  scripts/config_whitelist.txt |   1 -
>  3 files changed, 200 insertions(+), 4 deletions(-)

Reviewed-by: Simon Glass <sjg@chromium.org>

This is a step forward. But I wonder whether this should have an FPGA
driver with an I2C driver as its child?

^ permalink raw reply	[flat|nested] 138+ messages in thread

* [U-Boot] [PATCH 30/51] i2c: ihs_i2c: Factor out send_buffer method
  2017-07-14 12:55 ` [U-Boot] [PATCH 30/51] i2c: ihs_i2c: Factor out send_buffer method Mario Six
@ 2017-07-19  9:05   ` Simon Glass
  0 siblings, 0 replies; 138+ messages in thread
From: Simon Glass @ 2017-07-19  9:05 UTC (permalink / raw)
  To: u-boot

On 14 July 2017 at 05:55, Mario Six <mario.six@gdsys.cc> wrote:
> Simplify the driver logic by extracting a common send_buffer method.
>
> Signed-off-by: Mario Six <mario.six@gdsys.cc>
> ---
>
>  drivers/i2c/ihs_i2c.c | 50 ++++++++++++++++++++++++++------------------------
>  1 file changed, 26 insertions(+), 24 deletions(-)

Reviewed-by: Simon Glass <sjg@chromium.org>

^ permalink raw reply	[flat|nested] 138+ messages in thread

* [U-Boot] [PATCH 31/51] gdsys: mpc8308: Add FPGA flavor option
  2017-07-14 12:55 ` [U-Boot] [PATCH 31/51] gdsys: mpc8308: Add FPGA flavor option Mario Six
@ 2017-07-19  9:05   ` Simon Glass
  2017-07-25  7:52     ` Mario Six
  0 siblings, 1 reply; 138+ messages in thread
From: Simon Glass @ 2017-07-19  9:05 UTC (permalink / raw)
  To: u-boot

On 14 July 2017 at 05:55, Mario Six <mario.six@gdsys.cc> wrote:
> More recent versions of IHS FPGAs feature a different memory layout.
>
> Add a Kconfig option to differentiate between the legacy layout, and the
> new layout (which is used on the upcoming "Gazerbeam" and later boards).
>
> Signed-off-by: Mario Six <mario.six@gdsys.cc>
> ---
>
>  board/gdsys/mpc8308/Kconfig | 11 +++++++++++
>  1 file changed, 11 insertions(+)
>

Reviewed-by: Simon Glass <sjg@chromium.org>

Kconfig help?

> diff --git a/board/gdsys/mpc8308/Kconfig b/board/gdsys/mpc8308/Kconfig
> index e913e94b3a..80ac1a0f8a 100644
> --- a/board/gdsys/mpc8308/Kconfig
> +++ b/board/gdsys/mpc8308/Kconfig
> @@ -55,6 +55,17 @@ config GDSYS_LEGACY_DRIVERS
>
>  endif
>
> +choice
> +       prompt "FPGA flavor selection"
> +
> +config SYS_FPGA_FLAVOR_LEGACY
> +       bool "Legacy flavor"
> +
> +config SYS_FPGA_FLAVOR_GAZERBEAM
> +       bool "Gazerbeam flavor"
> +
> +endchoice
> +
>  config CMD_IOLOOP
>         bool "Enable 'ioloop' and 'ioreflect' commands"
>         help
> --
> 2.11.0
>

^ permalink raw reply	[flat|nested] 138+ messages in thread

* [U-Boot] [PATCH 35/51] drivers: Add ICS8N3QV01 driver
  2017-07-14 12:55 ` [U-Boot] [PATCH 35/51] drivers: Add ICS8N3QV01 driver Mario Six
@ 2017-07-19  9:05   ` Simon Glass
  2017-07-25  8:08     ` Mario Six
  0 siblings, 1 reply; 138+ messages in thread
From: Simon Glass @ 2017-07-19  9:05 UTC (permalink / raw)
  To: u-boot

On 14 July 2017 at 05:55, Mario Six <mario.six@gdsys.cc> wrote:
> Add a driver for the ICS8N3QV01 Quad-Frequency Programmable VCXO.
>
> Signed-off-by: Mario Six <mario.six@gdsys.cc>
> ---
>
>  drivers/clk/Kconfig      |   6 ++
>  drivers/clk/Makefile     |   1 +
>  drivers/clk/ics8n3qv01.c | 184 +++++++++++++++++++++++++++++++++++++++++++++++
>  3 files changed, 191 insertions(+)
>  create mode 100644 drivers/clk/ics8n3qv01.c
>
> diff --git a/drivers/clk/Kconfig b/drivers/clk/Kconfig
> index 44da716b26..f6f3810b64 100644
> --- a/drivers/clk/Kconfig
> +++ b/drivers/clk/Kconfig
> @@ -56,4 +56,10 @@ source "drivers/clk/uniphier/Kconfig"
>  source "drivers/clk/exynos/Kconfig"
>  source "drivers/clk/at91/Kconfig"
>
> +config ICS8N3QV01
> +       bool "Enable ICS8N3QV01 VCXO driver"
> +       depends on CLK
> +       help
> +         Support for the ICS8N3QV01 VCXO.

What is this? Can you describe it a bit more here?

> +
>  endmenu
> diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile
> index 2746a8016a..d7cc486d23 100644
> --- a/drivers/clk/Makefile
> +++ b/drivers/clk/Makefile
> @@ -21,3 +21,4 @@ obj-$(CONFIG_CLK_BCM6345) += clk_bcm6345.o
>  obj-$(CONFIG_CLK_BOSTON) += clk_boston.o
>  obj-$(CONFIG_ARCH_ASPEED) += aspeed/
>  obj-$(CONFIG_STM32F7) += clk_stm32f7.o
> +obj-$(CONFIG_ICS8N3QV01) += ics8n3qv01.o

Would be good if we could have these in alpha order. If you have time
can you do a patch to tidy that up before or after?

> diff --git a/drivers/clk/ics8n3qv01.c b/drivers/clk/ics8n3qv01.c
> new file mode 100644
> index 0000000000..f5f4b74982
> --- /dev/null
> +++ b/drivers/clk/ics8n3qv01.c
> @@ -0,0 +1,184 @@
> +/*
> + * (C) Copyright 2017
> + * Mario Six,  Guntermann & Drunck GmbH, mario.six at gdsys.cc
> + *
> + * based on the gdsys osd driver, which is
> + *
> + * (C) Copyright 2010
> + * Dirk Eibach,  Guntermann & Drunck GmbH, eibach at gdsys.de
> + *
> + * SPDX-License-Identifier:    GPL-2.0+
> + */
> +
> +#include <common.h>
> +#include <dm.h>
> +#include <clk-uclass.h>
> +#include <i2c.h>
> +
> +const long long ICS8N3QV01_FREF = 114285000;
> +const long long ICS8N3QV01_FREF_LL = 114285000LL;
> +const long long ICS8N3QV01_F_DEFAULT_0 = 156250000LL;
> +const long long ICS8N3QV01_F_DEFAULT_1 = 125000000LL;
> +const long long ICS8N3QV01_F_DEFAULT_2 = 100000000LL;
> +const long long ICS8N3QV01_F_DEFAULT_3 = 25175000LL;
> +
> +struct ics8n3qv01_priv {
> +       ulong rate;
> +};
> +
> +static uint ics8n3qv01_get_fout_calc(struct udevice *dev, uint index)
> +{
> +       u64 n, mint, mfrac;
> +       u8 reg_a, reg_b, reg_c, reg_d, reg_f;
> +       u64 fout_calc;
> +
> +       if (index > 3)

What is 3? Should this be an enum/#define?

> +               return 0;
> +
> +       reg_a = dm_i2c_reg_read(dev, 0 + index);

Error checking?

> +       reg_b = dm_i2c_reg_read(dev, 4 + index);
> +       reg_c = dm_i2c_reg_read(dev, 8 + index);
> +       reg_d = dm_i2c_reg_read(dev, 12 + index);
> +       reg_f = dm_i2c_reg_read(dev, 20 + index);
> +
> +       mint = ((reg_a >> 1) & 0x1f) | (reg_f & 0x20);
> +       mfrac = ((reg_a & 0x01) << 17) | (reg_b << 9) | (reg_c << 1)
> +               | (reg_d >> 7);
> +       n = reg_d & 0x7f;
> +
> +       fout_calc = (mint * ICS8N3QV01_FREF_LL
> +                    + mfrac * ICS8N3QV01_FREF_LL / 262144LL
> +                    + ICS8N3QV01_FREF_LL / 524288LL
> +                    + n / 2)
> +                   / n
> +                   * 1000000
> +                   / (1000000 - 100);
> +
> +       return fout_calc;
> +}
> +
> +static void ics8n3qv01_calc_parameters(uint fout, uint *_mint, uint *_mfrac,
> +                                      uint *_n)
> +{
> +       uint n, foutiic, fvcoiic, mint;
> +       u64 mfrac;
> +
> +       n = (2215000000U + fout / 2) / fout;
> +       if ((n & 1) && (n > 5))
> +               n -= 1;
> +
> +       foutiic = fout - (fout / 10000);
> +       fvcoiic = foutiic * n;
> +
> +       mint = fvcoiic / 114285000;
> +       if ((mint < 17) || (mint > 63))
> +               printf("ics8n3qv01_calc_parameters: cannot determine mint\n");

return error?

> +
> +       mfrac = ((u64)fvcoiic % 114285000LL) * 262144LL
> +               / 114285000LL;
> +
> +       *_mint = mint;
> +       *_mfrac = mfrac;
> +       *_n = n;
> +}
> +
> +static ulong ics8n3qv01_set_rate(struct clk *clk, ulong fout)
> +{
> +       struct ics8n3qv01_priv *priv = dev_get_priv(clk->dev);
> +       uint n, mint, mfrac, fout_calc;
> +       u64 fout_prog;
> +       long long off_ppm;
> +       u8 reg0, reg4, reg8, reg12, reg18, reg20;
> +
> +       priv->rate = fout;
> +
> +       fout_calc = ics8n3qv01_get_fout_calc(clk->dev, 1);
> +       off_ppm = (fout_calc - ICS8N3QV01_F_DEFAULT_1) * 1000000
> +                 / ICS8N3QV01_F_DEFAULT_1;
> +       printf("%s: PLL is off by %lld ppm\n", clk->dev->name, off_ppm);

debug()?

> +       fout_prog = (u64)fout * (u64)fout_calc
> +                   / ICS8N3QV01_F_DEFAULT_1;
> +       ics8n3qv01_calc_parameters(fout_prog, &mint, &mfrac, &n);
> +
> +       reg0 = dm_i2c_reg_read(clk->dev, 0) & 0xc0;
> +       reg0 |= (mint & 0x1f) << 1;
> +       reg0 |= (mfrac >> 17) & 0x01;
> +       dm_i2c_reg_write(clk->dev, 0, reg0);

Check error?

> +
> +       reg4 = mfrac >> 9;
> +       dm_i2c_reg_write(clk->dev, 4, reg4);
> +
> +       reg8 = mfrac >> 1;
> +       dm_i2c_reg_write(clk->dev, 8, reg8);
> +
> +       reg12 = mfrac << 7;
> +       reg12 |= n & 0x7f;
> +       dm_i2c_reg_write(clk->dev, 12, reg12);
> +
> +       reg18 = dm_i2c_reg_read(clk->dev, 18) & 0x03;
> +       reg18 |= 0x20;
> +       dm_i2c_reg_write(clk->dev, 18, reg18);
> +
> +       reg20 = dm_i2c_reg_read(clk->dev, 20) & 0x1f;
> +       reg20 |= mint & (1 << 5);
> +       dm_i2c_reg_write(clk->dev, 20, reg20);
> +
> +       return 0;
> +}
> +
> +static int ics8n3qv01_request(struct clk *clock)
> +{
> +       return 0;
> +}
> +
> +static ulong ics8n3qv01_get_rate(struct clk *clk)
> +{
> +       struct ics8n3qv01_priv *priv = dev_get_priv(clk->dev);
> +
> +       return priv->rate;
> +}
> +
> +static int ics8n3qv01_enable(struct clk *clk)
> +{
> +       return 0;
> +}
> +
> +static int ics8n3qv01_disable(struct clk *clk)
> +{
> +       return 0;
> +}
> +
> +static const struct clk_ops ics8n3qv01_ops = {
> +       .request = ics8n3qv01_request,
> +       .get_rate = ics8n3qv01_get_rate,
> +       .set_rate = ics8n3qv01_set_rate,
> +       .enable = ics8n3qv01_enable,
> +       .disable = ics8n3qv01_disable,
> +};
> +
> +static const struct udevice_id ics8n3qv01_ids[] = {
> +       { .compatible = "idt,ics8n3qv01" },
> +       { /* sentinel */ }
> +};
> +
> +int ics8n3qv01_probe(struct udevice *dev)
> +{
> +       struct dm_i2c_chip *chip = dev_get_parent_platdata(dev);
> +       struct udevice *dummy;
> +
> +       if (dm_i2c_probe(dev->parent, chip->chip_addr, chip->flags, &dummy)) {

You should not need to probe here - DM should do this for you.

> +               printf("ics8n3qv01: I2C probe did not succeed.\n");
> +               return -1;
> +       }
> +
> +       return 0;
> +}
> +
> +U_BOOT_DRIVER(ics8n3qv01) = {
> +       .name           = "ics8n3qv01",
> +       .id             = UCLASS_CLK,
> +       .ops            = &ics8n3qv01_ops,
> +       .of_match       = ics8n3qv01_ids,
> +       .probe          = ics8n3qv01_probe,
> +       .priv_auto_alloc_size   = sizeof(struct ics8n3qv01_priv),
> +};
> --
> 2.11.0
>

Regards,
Simon

^ permalink raw reply	[flat|nested] 138+ messages in thread

* [U-Boot] [PATCH 33/51] drivers: Add transmitter uclass
  2017-07-14 12:55 ` [U-Boot] [PATCH 33/51] drivers: Add transmitter uclass Mario Six
@ 2017-07-19  9:05   ` Simon Glass
  2017-07-25  9:29     ` Mario Six
  0 siblings, 1 reply; 138+ messages in thread
From: Simon Glass @ 2017-07-19  9:05 UTC (permalink / raw)
  To: u-boot

Hi Mario,

On 14 July 2017 at 05:55, Mario Six <mario.six@gdsys.cc> wrote:
> This patch adds a simple transmitter uclass meant for DVI or DisplayPort
> transmitters. The only driver functionality implemented are power_on and
> power_off methods for powering the transmitter device on and off,
> respectively.

Could we use UCLASS_DISPLAY for this? We are using that for things
like DisplayPort and HDMI.

If so you could add any missing operation and move your tests to that?

>
> Signed-off-by: Mario Six <mario.six@gdsys.cc>
> ---
>
>  arch/sandbox/dts/sandbox.dts              |  4 ++
>  arch/sandbox/dts/test.dts                 |  4 ++
>  configs/sandbox_defconfig                 |  2 +
>  drivers/Kconfig                           |  2 +
>  drivers/Makefile                          |  1 +
>  drivers/transmitter/Kconfig               | 16 +++++++
>  drivers/transmitter/Makefile              |  9 ++++
>  drivers/transmitter/sandbox_transmitter.c | 74 +++++++++++++++++++++++++++++++
>  drivers/transmitter/transmitter-uclass.c  | 36 +++++++++++++++
>  include/dm/uclass-id.h                    |  1 +
>  include/transmitter.h                     | 49 ++++++++++++++++++++
>  test/dm/Makefile                          |  1 +
>  test/dm/transmitter.c                     | 31 +++++++++++++
>  13 files changed, 230 insertions(+)
>  create mode 100644 drivers/transmitter/Kconfig
>  create mode 100644 drivers/transmitter/Makefile
>  create mode 100644 drivers/transmitter/sandbox_transmitter.c
>  create mode 100644 drivers/transmitter/transmitter-uclass.c
>  create mode 100644 include/transmitter.h
>  create mode 100644 test/dm/transmitter.c
>

Regards,
Simon

^ permalink raw reply	[flat|nested] 138+ messages in thread

* [U-Boot] [PATCH 34/51] transmitter: Add Xilinx LogiCore DP TX
  2017-07-14 12:55 ` [U-Boot] [PATCH 34/51] transmitter: Add Xilinx LogiCore DP TX Mario Six
@ 2017-07-19  9:06   ` Simon Glass
  2017-07-25  9:48     ` Mario Six
  0 siblings, 1 reply; 138+ messages in thread
From: Simon Glass @ 2017-07-19  9:06 UTC (permalink / raw)
  To: u-boot

On 14 July 2017 at 05:55, Mario Six <mario.six@gdsys.cc> wrote:
> Add a driver for the TX side of the Xilinx LogiCore DisplayPort IP core.
>
> Signed-off-by: Mario Six <mario.six@gdsys.cc>
> ---
>
>  drivers/transmitter/Kconfig                |    6 +
>  drivers/transmitter/Makefile               |    1 +
>  drivers/transmitter/logicore_dp_dpcd.h     |  342 +++++
>  drivers/transmitter/logicore_dp_tx.c       | 1984 ++++++++++++++++++++++++++++
>  drivers/transmitter/logicore_dp_tx.h       |   40 +
>  drivers/transmitter/logicore_dp_tx_regif.h |  365 +++++
>  6 files changed, 2738 insertions(+)
>  create mode 100644 drivers/transmitter/logicore_dp_dpcd.h
>  create mode 100644 drivers/transmitter/logicore_dp_tx.c
>  create mode 100644 drivers/transmitter/logicore_dp_tx.h
>  create mode 100644 drivers/transmitter/logicore_dp_tx_regif.h

Can we use UCLASS_DISPLAY?

>
> diff --git a/drivers/transmitter/Kconfig b/drivers/transmitter/Kconfig
> index 64ca08f8b8..e5613586a3 100644
> --- a/drivers/transmitter/Kconfig
> +++ b/drivers/transmitter/Kconfig
> @@ -13,4 +13,10 @@ config SANDBOX_TRANSMITTER
>         help
>           Enable the dummy transmitter for the sandbox.
>
> +config LOGICORE_DP_TX
> +       bool "Enable Logicore DP TX driver"
> +       depends on DM

DM_VIDEO?

> +       help
> +         Enabled the driver for the Logicore DP TX display port transmitter.

Enable. Also can you expand this help to explain what it is?

> +
>  endif
> diff --git a/drivers/transmitter/Makefile b/drivers/transmitter/Makefile
> index b873e63e28..088922d992 100644
> --- a/drivers/transmitter/Makefile
> +++ b/drivers/transmitter/Makefile
> @@ -7,3 +7,4 @@
>
>  obj-y += transmitter-uclass.o
>  obj-$(CONFIG_SANDBOX_TRANSMITTER) += sandbox_transmitter.o
> +obj-$(CONFIG_LOGICORE_DP_TX) += logicore_dp_tx.o
> diff --git a/drivers/transmitter/logicore_dp_dpcd.h b/drivers/transmitter/logicore_dp_dpcd.h
> new file mode 100644
> index 0000000000..6858294551
> --- /dev/null
> +++ b/drivers/transmitter/logicore_dp_dpcd.h
> @@ -0,0 +1,342 @@
> +/*
> + * logicore_dp_dpcd.h
> + *
> + * DPCD interface definition for XILINX LogiCore DisplayPort v6.1
> + * based on Xilinx dp_v3_1 driver sources
> + *
> + * (C) Copyright 2016
> + * Dirk Eibach,  Guntermann & Drunck GmbH, dirk.eibach at gdsys.cc
> + *
> + * SPDX-License-Identifier:    GPL-2.0+
> + */
> +
> +#ifndef __GDSYS_LOGICORE_DP_DPCD_H__
> +#define __GDSYS_LOGICORE_DP_DPCD_H__
> +
> +/* receiver capability field */
> +#define DPCD_REV                                               0x00000
> +#define DPCD_MAX_LINK_RATE                                     0x00001
> +#define DPCD_MAX_LANE_COUNT                                    0x00002
> +#define DPCD_MAX_DOWNSPREAD                                    0x00003
> +#define DPCD_NORP_PWR_V_CAP                                    0x00004
> +#define DPCD_DOWNSP_PRESENT                                    0x00005
> +#define DPCD_ML_CH_CODING_CAP                                  0x00006
> +#define DPCD_DOWNSP_COUNT_MSA_OUI                              0x00007
> +#define        DPCD_RX_PORT0_CAP_0                                     0x00008
> +#define        DPCD_RX_PORT0_CAP_1                                     0x00009
> +#define        DPCD_RX_PORT1_CAP_0                                     0x0000A
> +#define        DPCD_RX_PORT1_CAP_1                                     0x0000B
> +#define DPCD_I2C_SPEED_CTL_CAP                                 0x0000C
> +#define DPCD_EDP_CFG_CAP                                       0x0000D
> +#define DPCD_TRAIN_AUX_RD_INTERVAL                             0x0000E
> +#define DPCD_ADAPTER_CAP                                       0x0000F
> +#define DPCD_FAUX_CAP                                          0x00020
> +#define DPCD_MSTM_CAP                                          0x00021
> +#define DPCD_NUM_AUDIO_EPS                                     0x00022
> +#define        DPCD_AV_GRANULARITY                                     0x00023
> +#define DPCD_AUD_DEC_LAT_7_0                                   0x00024
> +#define DPCD_AUD_DEC_LAT_15_8                                  0x00025
> +#define DPCD_AUD_PP_LAT_7_0                                    0x00026
> +#define DPCD_AUD_PP_LAT_15_8                                   0x00027
> +#define DPCD_VID_INTER_LAT                                     0x00028
> +#define DPCD_VID_PROG_LAT                                      0x00029
> +#define DPCD_REP_LAT                                           0x0002A
> +#define DPCD_AUD_DEL_INS_7_0                                   0x0002B
> +#define DPCD_AUD_DEL_INS_15_8                                  0x0002C
> +#define DPCD_AUD_DEL_INS_23_16                                 0x0002D
> +#define DPCD_GUID                                              0x00030
> +#define DPCD_RX_GTC_VALUE_7_0                                  0x00054
> +#define DPCD_RX_GTC_VALUE_15_8                                 0x00055
> +#define DPCD_RX_GTC_VALUE_23_16                                        0x00056
> +#define DPCD_RX_GTC_VALUE_31_24                                        0x00057
> +#define DPCD_RX_GTC_MSTR_REQ                                   0x00058
> +#define DPCD_RX_GTC_FREQ_LOCK_DONE                             0x00059
> +#define DPCD_DOWNSP_0_CAP                                      0x00080
> +#define DPCD_DOWNSP_1_CAP                                      0x00081
> +#define DPCD_DOWNSP_2_CAP                                      0x00082
> +#define DPCD_DOWNSP_3_CAP                                      0x00083
> +#define DPCD_DOWNSP_0_DET_CAP                                  0x00080
> +#define DPCD_DOWNSP_1_DET_CAP                                  0x00084
> +#define DPCD_DOWNSP_2_DET_CAP                                  0x00088
> +#define DPCD_DOWNSP_3_DET_CAP                                  0x0008C
> +
> +/* link configuration field */
> +#define DPCD_LINK_BW_SET                                       0x00100
> +#define DPCD_LANE_COUNT_SET                                    0x00101
> +#define DPCD_TP_SET                                            0x00102
> +#define DPCD_TRAINING_LANE0_SET                                        0x00103
> +#define DPCD_TRAINING_LANE1_SET                                        0x00104
> +#define DPCD_TRAINING_LANE2_SET                                        0x00105
> +#define DPCD_TRAINING_LANE3_SET                                        0x00106
> +#define DPCD_DOWNSPREAD_CTRL                                   0x00107
> +#define DPCD_ML_CH_CODING_SET                                  0x00108
> +#define DPCD_I2C_SPEED_CTL_SET                                 0x00109
> +#define DPCD_EDP_CFG_SET                                       0x0010A
> +#define DPCD_LINK_QUAL_LANE0_SET                               0x0010B
> +#define DPCD_LINK_QUAL_LANE1_SET                               0x0010C
> +#define DPCD_LINK_QUAL_LANE2_SET                               0x0010D
> +#define DPCD_LINK_QUAL_LANE3_SET                               0x0010E
> +#define DPCD_TRAINING_LANE0_1_SET2                             0x0010F
> +#define DPCD_TRAINING_LANE2_3_SET2                             0x00110
> +#define DPCD_MSTM_CTRL                                         0x00111
> +#define DPCD_AUDIO_DELAY_7_0                                   0x00112
> +#define DPCD_AUDIO_DELAY_15_8                                  0x00113
> +#define DPCD_AUDIO_DELAY_23_6                                  0x00114
> +#define DPCD_UPSTREAM_DEVICE_DP_PWR_NEED                       0x00118
> +#define DPCD_FAUX_MODE_CTRL                                    0x00120
> +#define DPCD_FAUX_FORWARD_CH_DRIVE_SET                         0x00121
> +#define DPCD_BACK_CH_STATUS                                    0x00122
> +#define DPCD_FAUX_BACK_CH_SYMBOL_ERROR_COUNT                   0x00123
> +#define DPCD_FAUX_BACK_CH_TRAINING_PATTERN_TIME                        0x00125
> +#define DPCD_TX_GTC_VALUE_7_0                                  0x00154
> +#define DPCD_TX_GTC_VALUE_15_8                                 0x00155
> +#define DPCD_TX_GTC_VALUE_23_16                                        0x00156
> +#define DPCD_TX_GTC_VALUE_31_24                                        0x00157
> +#define DPCD_RX_GTC_VALUE_PHASE_SKEW_EN                                0x00158
> +#define DPCD_TX_GTC_FREQ_LOCK_DONE                             0x00159
> +#define DPCD_ADAPTER_CTRL                                      0x001A0
> +#define DPCD_BRANCH_DEVICE_CTRL                                        0x001A1
> +#define DPCD_PAYLOAD_ALLOCATE_SET                              0x001C0
> +#define DPCD_PAYLOAD_ALLOCATE_START_TIME_SLOT                  0x001C1
> +#define DPCD_PAYLOAD_ALLOCATE_TIME_SLOT_COUNT                  0x001C2
> +
> +/* link/sink status field */
> +#define DPCD_SINK_COUNT                                                0x00200
> +#define DPCD_DEVICE_SERVICE_IRQ                                        0x00201
> +#define DPCD_STATUS_LANE_0_1                                   0x00202
> +#define DPCD_STATUS_LANE_2_3                                   0x00203
> +#define DPCD_LANE_ALIGN_STATUS_UPDATED                         0x00204
> +#define DPCD_SINK_STATUS                                       0x00205
> +#define DPCD_ADJ_REQ_LANE_0_1                                  0x00206
> +#define DPCD_ADJ_REQ_LANE_2_3                                  0x00207
> +#define DPCD_TRAINING_SCORE_LANE_0                             0x00208
> +#define DPCD_TRAINING_SCORE_LANE_1                             0x00209
> +#define DPCD_TRAINING_SCORE_LANE_2                             0x0020A
> +#define DPCD_TRAINING_SCORE_LANE_3                             0x0020B
> +#define DPCD_ADJ_REQ_PC2                                       0x0020C
> +#define DPCD_FAUX_FORWARD_CH_SYMBOL_ERROR_COUNT                        0x0020D
> +#define DPCD_SYMBOL_ERROR_COUNT_LANE_0                         0x00210
> +#define DPCD_SYMBOL_ERROR_COUNT_LANE_1                         0x00212
> +#define DPCD_SYMBOL_ERROR_COUNT_LANE_2                         0x00214
> +#define DPCD_SYMBOL_ERROR_COUNT_LANE_3                         0x00216
> +
> +/* automated testing sub-field */
> +#define DPCD_FAUX_FORWARD_CH_STATUS                            0x00280
> +#define DPCD_FAUX_BACK_CH_DRIVE_SET                            0x00281
> +#define DPCD_FAUX_BACK_CH_SYM_ERR_COUNT_CTRL                   0x00282
> +#define DPCD_PAYLOAD_TABLE_UPDATE_STATUS                       0x002C0
> +#define DPCD_VC_PAYLOAD_ID_SLOT(SlotNum) \
> +                       (DPCD_PAYLOAD_TABLE_UPDATE_STATUS + SlotNum)
> +
> +/* sink control field */
> +#define DPCD_SET_POWER_DP_PWR_VOLTAGE                          0x00600
> +
> +/* sideband message buffers */
> +#define DPCD_DOWN_REQ                                          0x01000
> +#define DPCD_UP_REP                                            0x01200
> +#define DPCD_DOWN_REP                                          0x01400
> +#define DPCD_UP_REQ                                            0x01600
> +
> +/* event status indicator field */
> +#define DPCD_SINK_COUNT_ESI                                    0x02002
> +#define DPCD_SINK_DEVICE_SERVICE_IRQ_VECTOR_ESI0               0x02003
> +#define DPCD_SINK_DEVICE_SERVICE_IRQ_VECTOR_ESI1               0x02004
> +#define DPCD_SINK_LINK_SERVICE_IRQ_VECTOR_ESI0                 0x02005
> +#define DPCD_SINK_LANE0_1_STATUS                               0x0200C
> +#define DPCD_SINK_LANE2_3_STATUS                               0x0200D
> +#define DPCD_SINK_ALIGN_STATUS_UPDATED_ESI                     0x0200E
> +#define DPCD_SINK_STATUS_ESI                                   0x0200F
> +
> +/*
> + * field addresses and sizes.
> + */
> +#define DPCD_RECEIVER_CAP_FIELD_START          DPCD_REV
> +#define DPCD_RECEIVER_CAP_FIELD_SIZE                   0x100
> +#define DPCD_LINK_CFG_FIELD_START              DPCD_LINK_BW_SET
> +#define DPCD_LINK_CFG_FIELD_SIZE                               0x100
> +#define DPCD_LINK_SINK_STATUS_FIELD_START      DPCD_SINK_COUNT
> +#define DPCD_LINK_SINK_STATUS_FIELD_SIZE                       0x17
> +/* 0x00000: DPCD_REV */
> +#define DPCD_REV_MNR_MASK                                      0x0F
> +#define DPCD_REV_MJR_MASK                                      0xF0
> +#define DPCD_REV_MJR_SHIFT                                     4
> +/* 0x00001: MAX_LINK_RATE */
> +#define DPCD_MAX_LINK_RATE_162GBPS                             0x06
> +#define DPCD_MAX_LINK_RATE_270GBPS                             0x0A
> +#define DPCD_MAX_LINK_RATE_540GBPS                             0x14
> +/* 0x00002: MAX_LANE_COUNT */
> +#define DPCD_MAX_LANE_COUNT_MASK                               0x1F
> +#define DPCD_MAX_LANE_COUNT_1                                  0x01
> +#define DPCD_MAX_LANE_COUNT_2                                  0x02
> +#define DPCD_MAX_LANE_COUNT_4                                  0x04
> +#define DPCD_TPS3_SUPPORT_MASK                                 0x40
> +#define DPCD_ENHANCED_FRAME_SUPPORT_MASK                       0x80
> +/* 0x00003: MAX_DOWNSPREAD */
> +#define DPCD_MAX_DOWNSPREAD_MASK                               0x01
> +#define DPCD_NO_AUX_HANDSHAKE_LINK_TRAIN_MASK                  0x40
> +/* 0x00005: DOWNSP_PRESENT */
> +#define DPCD_DOWNSP_PRESENT_MASK                               0x01
> +#define DPCD_DOWNSP_TYPE_MASK                                  0x06
> +#define DPCD_DOWNSP_TYPE_SHIFT                                 1
> +#define DPCD_DOWNSP_TYPE_DP                                    0x0
> +#define DPCD_DOWNSP_TYPE_AVGA_ADVII                            0x1
> +#define DPCD_DOWNSP_TYPE_DVI_HDMI_DPPP                         0x2
> +#define DPCD_DOWNSP_TYPE_OTHERS                                        0x3
> +#define DPCD_DOWNSP_FORMAT_CONV_MASK                           0x08
> +#define DPCD_DOWNSP_DCAP_INFO_AVAIL_MASK                       0x10
> +/* 0x00006, 0x00108: ML_CH_CODING_SUPPORT, ML_CH_CODING_SET */
> +#define DPCD_ML_CH_CODING_MASK                                 0x01
> +/* 0x00007: DOWNSP_COUNT_MSA_OUI */
> +#define DPCD_DOWNSP_COUNT_MASK                                 0x0F
> +#define DPCD_MSA_TIMING_PAR_IGNORED_MASK                       0x40
> +#define DPCD_OUI_SUPPORT_MASK                                  0x80
> +/* 0x00008, 0x0000A: RX_PORT[0-1]_CAP_0 */
> +#define DPCD_RX_PORTX_CAP_0_LOCAL_EDID_PRESENT_MASK            0x02
> +#define DPCD_RX_PORTX_CAP_0_ASSOC_TO_PRECEDING_PORT_MASK       0x04
> +/* 0x0000C, 0x00109: I2C_SPEED_CTL_CAP, I2C_SPEED_CTL_SET */
> +#define DPCD_I2C_SPEED_CTL_NONE                                        0x00
> +#define DPCD_I2C_SPEED_CTL_1KBIPS                              0x01
> +#define DPCD_I2C_SPEED_CTL_5KBIPS                              0x02
> +#define DPCD_I2C_SPEED_CTL_10KBIPS                             0x04
> +#define DPCD_I2C_SPEED_CTL_100KBIPS                            0x08
> +#define DPCD_I2C_SPEED_CTL_400KBIPS                            0x10
> +#define DPCD_I2C_SPEED_CTL_1MBIPS                              0x20
> +/* 0x0000E: TRAIN_AUX_RD_INTERVAL */
> +#define DPCD_TRAIN_AUX_RD_INT_100_400US                                0x00
> +#define DPCD_TRAIN_AUX_RD_INT_4MS                              0x01
> +#define DPCD_TRAIN_AUX_RD_INT_8MS                              0x02
> +#define DPCD_TRAIN_AUX_RD_INT_12MS                             0x03
> +#define DPCD_TRAIN_AUX_RD_INT_16MS                             0x04
> +/* 0x00020: DPCD_FAUX_CAP */
> +#define DPCD_FAUX_CAP_MASK                                     0x01
> +/* 0x00021: MSTM_CAP */
> +#define DPCD_MST_CAP_MASK                                      0x01
> +/* 0x00080, 0x00081|4, 0x00082|8, 0x00083|C: DOWNSP_X_(DET_)CAP */
> +#define DPCD_DOWNSP_X_CAP_TYPE_MASK                            0x07
> +#define DPCD_DOWNSP_X_CAP_TYPE_DP                              0x0
> +#define DPCD_DOWNSP_X_CAP_TYPE_AVGA                            0x1
> +#define DPCD_DOWNSP_X_CAP_TYPE_DVI                             0x2
> +#define DPCD_DOWNSP_X_CAP_TYPE_HDMI                            0x3
> +#define DPCD_DOWNSP_X_CAP_TYPE_OTHERS                          0x4
> +#define DPCD_DOWNSP_X_CAP_TYPE_DPPP                            0x5
> +#define DPCD_DOWNSP_X_CAP_HPD_MASK                             0x80
> +#define DPCD_DOWNSP_X_CAP_NON_EDID_ATTR_MASK                   0xF0
> +#define DPCD_DOWNSP_X_CAP_NON_EDID_ATTR_SHIFT                  4
> +#define DPCD_DOWNSP_X_CAP_NON_EDID_ATTR_720_480_I_60           0x1
> +#define DPCD_DOWNSP_X_CAP_NON_EDID_ATTR_720_480_I_50           0x2
> +#define DPCD_DOWNSP_X_CAP_NON_EDID_ATTR_1920_1080_I_60         0x3
> +#define DPCD_DOWNSP_X_CAP_NON_EDID_ATTR_1920_1080_I_50         0x4
> +#define DPCD_DOWNSP_X_CAP_NON_EDID_ATTR_1280_720_P_60          0x5
> +#define DPCD_DOWNSP_X_CAP_NON_EDID_ATTR_1280_720_P_50          0x7
> +/* 0x00082, 0x00086, 0x0008A, 0x0008E: DOWNSP_X_(DET_)CAP2 */
> +#define DPCD_DOWNSP_X_DCAP_MAX_BPC_MASK                                0x03
> +#define DPCD_DOWNSP_X_DCAP_MAX_BPC_8                           0x0
> +#define DPCD_DOWNSP_X_DCAP_MAX_BPC_10                          0x1
> +#define DPCD_DOWNSP_X_DCAP_MAX_BPC_12                          0x2
> +#define DPCD_DOWNSP_X_DCAP_MAX_BPC_16                          0x3
> +/* 0x00082, 0x00086, 0x0008A, 0x0008E: DOWNSP_X_(DET_)CAP2 */
> +#define DPCD_DOWNSP_X_DCAP_HDMI_DPPP_FS2FP_MASK                        0x01
> +#define DPCD_DOWNSP_X_DCAP_DVI_DL_MASK                         0x02
> +#define DPCD_DOWNSP_X_DCAP_DVI_HCD_MASK                                0x04
> +
> +/* link configuration field masks, shifts, and register values */
> +/* 0x00100: DPCD_LINK_BW_SET */
> +#define DPCD_LINK_BW_SET_162GBPS                               0x06
> +#define DPCD_LINK_BW_SET_270GBPS                               0x0A
> +#define DPCD_LINK_BW_SET_540GBPS                               0x14
> +/* 0x00101: LANE_COUNT_SET */
> +#define DPCD_LANE_COUNT_SET_MASK                               0x1F
> +#define DPCD_LANE_COUNT_SET_1                                  0x01
> +#define DPCD_LANE_COUNT_SET_2                                  0x02
> +#define DPCD_LANE_COUNT_SET_4                                  0x04
> +#define DPCD_ENHANCED_FRAME_EN_MASK                            0x80
> +/* 0x00102: TP_SET */
> +#define DPCD_TP_SEL_MASK                                       0x03
> +#define DPCD_TP_SEL_OFF                                                0x0
> +#define DPCD_TP_SEL_TP1                                                0x1
> +#define DPCD_TP_SEL_TP2                                                0x2
> +#define DPCD_TP_SEL_TP3                                                0x3
> +#define DPCD_TP_SET_LQP_MASK                                   0x06
> +#define DPCD_TP_SET_LQP_SHIFT                                  2
> +#define DPCD_TP_SET_LQP_OFF                                    0x0
> +#define DPCD_TP_SET_LQP_D102_TEST                              0x1
> +#define DPCD_TP_SET_LQP_SER_MES                                        0x2
> +#define DPCD_TP_SET_LQP_PRBS7                                  0x3
> +#define DPCD_TP_SET_REC_CLK_OUT_EN_MASK                                0x10
> +#define DPCD_TP_SET_SCRAMB_DIS_MASK                            0x20
> +#define DPCD_TP_SET_SE_COUNT_SEL_MASK                          0xC0
> +#define DPCD_TP_SET_SE_COUNT_SEL_SHIFT                         6
> +#define DPCD_TP_SET_SE_COUNT_SEL_DE_ISE                                0x0
> +#define DPCD_TP_SET_SE_COUNT_SEL_DE                            0x1
> +#define DPCD_TP_SET_SE_COUNT_SEL_ISE                           0x2
> +/* 0x00103-0x00106: TRAINING_LANE[0-3]_SET */
> +#define DPCD_TRAINING_LANEX_SET_VS_MASK                                0x03
> +#define DPCD_TRAINING_LANEX_SET_MAX_VS_MASK                    0x04
> +#define DPCD_TRAINING_LANEX_SET_PE_MASK                                0x18
> +#define DPCD_TRAINING_LANEX_SET_PE_SHIFT                       3
> +#define DPCD_TRAINING_LANEX_SET_MAX_PE_MASK                    0x20
> +/* 0x00107: DOWNSPREAD_CTRL */
> +#define DPCD_SPREAD_AMP_MASK                                   0x10
> +#define DPCD_MSA_TIMING_PAR_IGNORED_EN_MASK                    0x80
> +/* 0x00108: ML_CH_CODING_SET - Same as 0x00006: ML_CH_CODING_SUPPORT */
> +/* 0x00109: I2C_SPEED_CTL_SET - Same as 0x0000C: I2C_SPEED_CTL_CAP */
> +/* 0x0010F-0x00110: TRAINING_LANE[0_1-2_3]_SET2 */
> +#define DPCD_TRAINING_LANE_0_2_SET_PC2_MASK                    0x03
> +#define DPCD_TRAINING_LANE_0_2_SET_MAX_PC2_MASK                        0x04
> +#define DPCD_TRAINING_LANE_1_3_SET_PC2_MASK                    0x30
> +#define DPCD_TRAINING_LANE_1_3_SET_PC2_SHIFT                   4
> +#define DPCD_TRAINING_LANE_1_3_SET_MAX_PC2_MASK                        0x40
> +/* 0x00111: MSTM_CTRL */
> +#define DPCD_MST_EN_MASK                                       0x01
> +#define DPCD_UP_REQ_EN_MASK                                    0x02
> +#define DPCD_UP_IS_SRC_MASK                                    0x03
> +
> +/* link/sink status field masks, shifts, and register values */
> +/* 0x00200: SINK_COUNT */
> +#define DPCD_SINK_COUNT_LOW_MASK                               0x3F
> +#define DPCD_SINK_CP_READY_MASK                                        0x40
> +#define DPCD_SINK_COUNT_HIGH_MASK                              0x80
> +#define DPCD_SINK_COUNT_HIGH_LOW_SHIFT                         1
> +/* 0x00202: STATUS_LANE_0_1 */
> +#define DPCD_STATUS_LANE_0_CR_DONE_MASK                                0x01
> +#define DPCD_STATUS_LANE_0_CE_DONE_MASK                                0x02
> +#define DPCD_STATUS_LANE_0_SL_DONE_MASK                                0x04
> +#define DPCD_STATUS_LANE_1_CR_DONE_MASK                                0x10
> +#define DPCD_STATUS_LANE_1_CE_DONE_MASK                                0x20
> +#define DPCD_STATUS_LANE_1_SL_DONE_MASK                                0x40
> +/* 0x00202: STATUS_LANE_2_3 */
> +#define DPCD_STATUS_LANE_2_CR_DONE_MASK                                0x01
> +#define DPCD_STATUS_LANE_2_CE_DONE_MASK                                0x02
> +#define DPCD_STATUS_LANE_2_SL_DONE_MASK                                0x04
> +#define DPCD_STATUS_LANE_3_CR_DONE_MASK                                0x10
> +#define DPCD_STATUS_LANE_3_CE_DONE_MASK                                0x20
> +#define DPCD_STATUS_LANE_3_SL_DONE_MASK                                0x40
> +/* 0x00204: LANE_ALIGN_STATUS_UPDATED */
> +#define DPCD_LANE_ALIGN_STATUS_UPDATED_IA_DONE_MASK \
> +                                                               0x01
> +#define DPCD_LANE_ALIGN_STATUS_UPDATED_DOWNSP_STATUS_CHANGED_MASK \
> +                                                               0x40
> +#define DPCD_LANE_ALIGN_STATUS_UPDATED_LINK_STATUS_UPDATED_MASK \
> +                                                               0x80
> +/* 0x00205: SINK_STATUS */
> +#define DPCD_SINK_STATUS_RX_PORT0_SYNC_STATUS_MASK             0x01
> +#define DPCD_SINK_STATUS_RX_PORT1_SYNC_STATUS_MASK             0x02
> +
> +/* 0x00206, 0x00207: ADJ_REQ_LANE_[0,2]_[1,3] */
> +#define DPCD_ADJ_REQ_LANE_0_2_VS_MASK                          0x03
> +#define DPCD_ADJ_REQ_LANE_0_2_PE_MASK                          0x0C
> +#define DPCD_ADJ_REQ_LANE_0_2_PE_SHIFT                         2
> +#define DPCD_ADJ_REQ_LANE_1_3_VS_MASK                          0x30
> +#define DPCD_ADJ_REQ_LANE_1_3_VS_SHIFT                         4
> +#define DPCD_ADJ_REQ_LANE_1_3_PE_MASK                          0xC0
> +#define DPCD_ADJ_REQ_LANE_1_3_PE_SHIFT                         6
> +/* 0x0020C: ADJ_REQ_PC2 */
> +#define DPCD_ADJ_REQ_PC2_LANE_0_MASK                           0x03
> +#define DPCD_ADJ_REQ_PC2_LANE_1_MASK                           0x0C
> +#define DPCD_ADJ_REQ_PC2_LANE_1_SHIFT                          2
> +#define DPCD_ADJ_REQ_PC2_LANE_2_MASK                           0x30
> +#define DPCD_ADJ_REQ_PC2_LANE_2_SHIFT                          4
> +#define DPCD_ADJ_REQ_PC2_LANE_3_MASK                           0xC0
> +#define DPCD_ADJ_REQ_PC2_LANE_3_SHIFT                          6
> +
> +#endif /* __GDSYS_LOGICORE_DP_DPCD_H__ */
> diff --git a/drivers/transmitter/logicore_dp_tx.c b/drivers/transmitter/logicore_dp_tx.c
> new file mode 100644
> index 0000000000..b61159cd89
> --- /dev/null
> +++ b/drivers/transmitter/logicore_dp_tx.c
> @@ -0,0 +1,1984 @@
> +/*
> + * logicore_dp_tx.c
> + *
> + * Driver for XILINX LogiCore DisplayPort v6.1 TX (Source)
> + * based on Xilinx dp_v3_1 driver sources, updated to dp_v4_0
> + *
> + * (C) Copyright 2016
> + * Dirk Eibach,  Guntermann & Drunck GmbH, dirk.eibach at gdsys.cc
> + *
> + * SPDX-License-Identifier:    GPL-2.0+
> + */
> +
> +#include <common.h>
> +#include <clk.h>
> +#include <dm.h>
> +#include <errno.h>
> +#include <transmitter.h>
> +
> +#include "ihs_axi.h"
> +
> +#include "logicore_dp_dpcd.h"
> +#include "logicore_dp_tx_regif.h"
> +#include "logicore_dp_tx.h"
> +
> +DECLARE_GLOBAL_DATA_PTR;
> +
> +#define S_AXI_CLK_DEFAULT 100000000
> +
> +#define PHY_CLOCK_SELECT_DEFAULT PHY_CLOCK_SELECT_540GBPS
> +
> +/* The maximum voltage swing level is 3. */
> +#define MAXIMUM_VS_LEVEL 3
> +/* The maximum pre-emphasis level is 3. */
> +#define MAXIMUM_PE_LEVEL 3
> +
> +/* Error out if an AUX request yields a defer reply more than 50 times. */
> +#define AUX_MAX_DEFER_COUNT 50
> +/* Error out if an AUX request times out more than 50 times awaiting a reply. */
> +#define AUX_MAX_TIMEOUT_COUNT 50
> +/* Error out if checking for a connected device times out more than 50 times. */
> +#define IS_CONNECTED_MAX_TIMEOUT_COUNT 50
> +
> +enum {
> +       TS_CLOCK_RECOVERY,
> +       TS_CHANNEL_EQUALIZATION,
> +       TS_ADJUST_LINK_RATE,
> +       TS_ADJUST_LANE_COUNT,
> +       TS_FAILURE,
> +       TS_SUCCESS
> +};
> +
> +struct aux_transaction {
> +       u16 cmd_code;
> +       u8 num_bytes;
> +       u32 address;
> +       u8 *data;

Comment these members.

> +};
> +
> +/*
> + * all porch parameters have been removed because our videodata is hstart/vstart
> + * based and there is no benefit in keeping the porches
> + */
> +
> +struct main_stream_attributes {
> +       /* Pixel clock of the stream (in Hz). */
> +       u32 pixel_clock_hz;
> +       /* Miscellaneous stream attributes 0 as specified by the DisplayPort
> +        * 1.2 specification.
> +        */
> +       u32 misc_0;
> +       /* Miscellaneous stream attributes 1 as specified by the DisplayPort
> +        * 1.2 specification.
> +        */
> +       u32 misc_1;
> +       /* N value for the video stream. */
> +       u32 n_vid;
> +       /* M value used to recover the video clock from the link clock. */
> +       u32 m_vid;
> +       /* Width of the user data input port. */
> +       u32 user_pixel_width;
> +       /* Used to translate the number of pixels per line to the native
> +        * internal 16-bit datapath.
> +        */
> +       u32 data_per_lane;
> +       /* Average number of bytes per transfer unit, scaled up by a factor of
> +        * 1000.
> +        */
> +       u32 avg_bytes_per_tu;
> +       /* Size of the transfer unit in the framing logic. In MST mode, this is
> +        * also the number of time slots that are alloted in the payload ID
> +        * table.
> +        */
> +       u32 transfer_unit_size;
> +       /* Number of initial wait cycles at the start of a new line by the
> +        * framing logic.
> +        */
> +       u32 init_wait;
> +       /* Bits per color component. */
> +       u32 bits_per_color;
> +       /* The component format currently in use by the video stream. */
> +       u8 component_format;
> +       /* The dynamic range currently in use by the video stream. */
> +       u8 dynamic_range;
> +       /* The YCbCr colorimetry currently in use by the video stream. */
> +       u8 y_cb_cr_colorimetry;
> +       /* Synchronous clock mode is currently in use by the video stream. */
> +       u8 synchronous_clock_mode;
> +       /* If set to 1, the value stored for user_pixel_width will be used as
> +        * the pixel width.
> +        */
> +       u8 override_user_pixel_width;
> +       /* Horiz. blank start (pixels). */
> +       u32 h_start;
> +       /* Horiz. active resolution (pixels) */
> +       u16 h_active;
> +       /* Horiz. sync width (pixels) */
> +       u16 h_sync_width;
> +       /* Horiz. total (pixels) */
> +       u16 h_total;
> +       /* Horiz. sync polarity (0=neg|1=pos) */
> +       bool h_sync_polarity;
> +       /* Vert. blank start (in lines). */
> +       u32 v_start;
> +       /* Vert. active resolution (lines) */
> +       u16 v_active;
> +       /* Vert. sync width (lines) */
> +       u16 v_sync_width;
> +       /* Vert. total (lines) */
> +       u16 v_total;
> +       /* Vert. sync polarity (0=neg|1=pos) */
> +       bool v_sync_polarity;
> +};
> +
> +struct link_config {
> +       u8 lane_count;
> +       u8 link_rate;
> +       bool scrambler_en;
> +       bool enhanced_framing_mode;
> +       bool downspread_control;
> +       u8 max_lane_count;
> +       u8 max_link_rate;
> +       bool support_enhanced_framing_mode;
> +       bool support_downspread_control;
> +       u8 vs_level; /* voltage swing for each lane */
> +       u8 pe_level; /* pre-emphasis/cursor level for each lane */
> +       u8 pattern;
> +};
> +
> +struct dp_tx {
> +       u32 base;
> +
> +       u32 s_axi_clk;
> +
> +       bool train_adaptive;
> +
> +       u8 max_link_rate;
> +       u8 max_lane_count;
> +
> +       u8 dpcd_rx_caps[16];
> +
> +       /* This is a raw read of the RX device's status registers. The first 4
> +        * bytes correspond to the lane status associated with clock recovery,
> +        * channel equalization, symbol lock, and interlane alignment. The
> +        * remaining 2 bytes represent the pre-emphasis and voltage swing level
> +        * adjustments requested by the RX device.
> +        */
> +       u8 lane_status_ajd_reqs[6];
> +
> +       struct link_config link_config;
> +       struct main_stream_attributes main_stream_attributes;
> +};
> +
> +/*
> + * internal API
> + */
> +
> +static u32 get_reg(struct udevice *dev, u32 reg)
> +{
> +       struct dp_tx *dp_tx = dev_get_priv(dev);
> +       u32 value = 0;
> +       int res;
> +
> +       // TODO error handling

/* TODO(email): Error handling

(or do you intend to do in v2?)

> +       res = axi_read(dev->parent, dp_tx->base + reg, &value);
> +       if (res < 0)
> +               printf("%s() failed; res = %d\n", __func__, res);

How about debug() and return an error?

> +
> +       return value;
> +}
> +
> +static void set_reg(struct udevice *dev, u32 reg, u32 value)
> +{
> +       struct dp_tx *dp_tx = dev_get_priv(dev);
> +
> +       axi_write(dev->parent, dp_tx->base + reg, value);

Can this fail? Error checking?

> +}
> +
> +/*
> + * Check if there is a connected RX device.
> + * The Xilinx original calls msleep_interruptible at least once,
> + * ignoring status.
> + */
> +bool is_connected(struct udevice *dev)
> +{
> +       u8 retries = 0;
> +
> +       do {
> +               int status = get_reg(dev, REG_INTERRUPT_SIG_STATE) &
> +                            INTERRUPT_SIG_STATE_HPD_STATE_MASK;
> +               if (status)
> +                       return true;
> +
> +               udelay(1000);
> +       } while (retries++ < IS_CONNECTED_MAX_TIMEOUT_COUNT);
> +
> +       return false;
> +}
> +
> +/*
> + * Wait for the DisplayPort PHY to come out of reset.
> + */
> +static int wait_phy_ready(struct udevice *dev, u32 mask)
> +{
> +       u16 timeout = 20000;
> +       u32 phy_status;
> +
> +       /* Wait until the PHY is ready. */
> +       do {
> +               phy_status = get_reg(dev, REG_PHY_STATUS) & mask;
> +
> +               /* Protect against an infinite loop. */
> +               if (!timeout--)
> +                       return -ETIMEDOUT;
> +
> +               udelay(20);
> +       } while (phy_status != mask);
> +
> +       return 0;
> +}
> +
> +/* AUX channel access */
> +
> +/*
> + * Wait until another request is no longer in progress.
> + */
> +static int aux_wait_ready(struct udevice *dev)
> +{
> +       int status;
> +       u32 timeout = 100;
> +
> +       /* Wait until the DisplayPort TX core is ready. */
> +       do {
> +               status = get_reg(dev, REG_INTERRUPT_SIG_STATE);
> +
> +               /* Protect against an infinite loop. */
> +               if (!timeout--)
> +                       return -ETIMEDOUT;
> +               udelay(20);
> +       } while (status & REPLY_STATUS_REPLY_IN_PROGRESS_MASK);
> +
> +       return 0;
> +}
> +
> +/*
> + * Wait for a reply indicating that the most recent AUX request
> + * has been received by the RX device.
> + */
> +static int aux_wait_reply(struct udevice *dev)
> +{
> +       u32 timeout = 100;
> +
> +       while (timeout > 0) {
> +               int status = get_reg(dev, REG_REPLY_STATUS);
> +
> +               /* Check for error. */
> +               if (status & REPLY_STATUS_REPLY_ERROR_MASK)
> +                       return -ETIMEDOUT;
> +
> +               /* Check for a reply. */
> +               if ((status & REPLY_STATUS_REPLY_RECEIVED_MASK) &&
> +                   !(status &
> +                     REPLY_STATUS_REQUEST_IN_PROGRESS_MASK) &&
> +                   !(status &
> +                     REPLY_STATUS_REPLY_IN_PROGRESS_MASK)) {
> +                       return 0;
> +               }
> +
> +               timeout--;
> +               udelay(20);

This makes me think we should have a way to do us timeouts.

We have get_timer(), so:

start = get_timer(0);
...
while () {
    ...
   if (get_timer(start) > 20) {
      debug(...)
      return -ETIMEDOUT;
   }

Perhaps we should have a timer_get_us_base(ulong base) which works in
a similar way?

> +       }
> +
> +       return -ETIMEDOUT;
> +}
> +
> +/*
> + * Submit the supplied AUX request to the RX device over the AUX
> + * channel by writing the command, the destination address, (the write buffer
> + * for write commands), and the data size to the DisplayPort TX core.
> + */
> +static int aux_request_send(struct udevice *dev,
> +                           struct aux_transaction *request)
> +{
> +       u32 timeout_count;
> +       int status;
> +       u8 index;
> +
> +       /* Ensure that any pending AUX transactions have completed. */
> +       timeout_count = 0;
> +       do {
> +               status = get_reg(dev, REG_REPLY_STATUS);
> +
> +               udelay(20);
> +               timeout_count++;
> +               if (timeout_count >= AUX_MAX_TIMEOUT_COUNT)
> +                       return -ETIMEDOUT;
> +       } while ((status & REPLY_STATUS_REQUEST_IN_PROGRESS_MASK) ||
> +                (status & REPLY_STATUS_REPLY_IN_PROGRESS_MASK));
> +
> +       set_reg(dev, REG_AUX_ADDRESS, request->address);
> +
> +       if ((request->cmd_code == AUX_CMD_WRITE) ||
> +           (request->cmd_code == AUX_CMD_I2C_WRITE) ||
> +           (request->cmd_code == AUX_CMD_I2C_WRITE_MOT)) {
> +               /* Feed write data into the DisplayPort TX core's write FIFO. */
> +               for (index = 0; index < request->num_bytes; index++) {
> +                       set_reg(dev,
> +                               REG_AUX_WRITE_FIFO, request->data[index]);
> +               }
> +       }
> +
> +       /* Submit the command and the data size. */
> +       set_reg(dev, REG_AUX_CMD,
> +               ((request->cmd_code << AUX_CMD_SHIFT) |
> +                ((request->num_bytes - 1) &
> +                 AUX_CMD_NBYTES_TRANSFER_MASK)));
> +
> +       /* Check for a reply from the RX device to the submitted request. */
> +       status = aux_wait_reply(dev);
> +       if (status)
> +               /* Waiting for a reply timed out. */
> +               return -ETIMEDOUT;
> +
> +       /* Analyze the reply. */
> +       status = get_reg(dev, REG_AUX_REPLY_CODE);
> +       if ((status == AUX_REPLY_CODE_DEFER) ||
> +           (status == AUX_REPLY_CODE_I2C_DEFER)) {
> +               /* The request was deferred. */
> +               return -EAGAIN;
> +       } else if ((status == AUX_REPLY_CODE_NACK) ||
> +                  (status == AUX_REPLY_CODE_I2C_NACK)) {
> +               /* The request was not acknowledged. */
> +               return -EIO;
> +       }
> +
> +       /* The request was acknowledged. */
> +
> +       if ((request->cmd_code == AUX_CMD_READ) ||
> +           (request->cmd_code == AUX_CMD_I2C_READ) ||
> +           (request->cmd_code == AUX_CMD_I2C_READ_MOT)) {
> +               /* Wait until all data has been received. */
> +               timeout_count = 0;
> +               do {
> +                       status = get_reg(dev, REG_REPLY_DATA_COUNT);
> +
> +                       udelay(100);
> +                       timeout_count++;
> +                       if (timeout_count >= AUX_MAX_TIMEOUT_COUNT)
> +                               return -ETIMEDOUT;
> +               } while (status != request->num_bytes);
> +
> +               /* Obtain the read data from the reply FIFO. */
> +               for (index = 0; index < request->num_bytes; index++)
> +                       request->data[index] = get_reg(dev, REG_AUX_REPLY_DATA);
> +       }
> +
> +       return 0;
> +}
> +
> +/*
> + * Submit the supplied AUX request to the RX device over the AUX
> + * channel. If waiting for a reply times out, or if the DisplayPort TX core
> + * indicates that the request was deferred, the request is sent again (up to a
> + * maximum specified by AUX_MAX_DEFER_COUNT|AUX_MAX_TIMEOUT_COUNT).
> + */
> +static int aux_request(struct udevice *dev, struct aux_transaction *request)
> +{
> +       u32 defer_count = 0;
> +       u32 timeout_count = 0;
> +
> +       while ((defer_count < AUX_MAX_DEFER_COUNT) &&
> +              (timeout_count < AUX_MAX_TIMEOUT_COUNT)) {
> +               int status = aux_wait_ready(dev);
> +
> +               if (status) {
> +                       /* The RX device isn't ready yet. */
> +                       timeout_count++;
> +                       continue;
> +               }
> +
> +               status = aux_request_send(dev, request);
> +               if (status == -EAGAIN) {
> +                       /* The request was deferred. */
> +                       defer_count++;
> +               } else if (status == -ETIMEDOUT) {
> +                       /* Waiting for a reply timed out. */
> +                       timeout_count++;
> +               } else {
> +                       /* -EIO indicates that the request was NACK'ed,
> +                        * 0 indicates that the request was ACK'ed.
> +                        */
> +                       return status;
> +               }
> +
> +               udelay(100);
> +       }
> +
> +       /* The request was not successfully received by the RX device. */
> +       return -ETIMEDOUT;
> +}
> +
> +/*
> + * Common sequence of submitting an AUX command for
> + * AUX read, AUX write, I2C-over-AUX read, and I2C-over-AUX write transactions.
> + * If required, the reads and writes are split into multiple requests, each
> + * acting on a maximum of 16 bytes.
> + */
> +static int aux_common(struct udevice *dev, u32 cmd_type, u32 address,
> +                     u32 num_bytes, u8 *data)
> +{
> +       struct aux_transaction request;
> +       u32 bytes_left;
> +
> +       /*
> +        * set the start address for AUX transactions. For I2C transactions,
> +        * this is the address of the I2C bus.
> +        */
> +       request.address = address;
> +
> +       bytes_left = num_bytes;
> +       while (bytes_left) {
> +               int status;
> +
> +               request.cmd_code = cmd_type;
> +
> +               if ((cmd_type == AUX_CMD_READ) ||
> +                   (cmd_type == AUX_CMD_WRITE)) {
> +                       /* Increment address for normal AUX transactions. */
> +                       request.address = address + (num_bytes - bytes_left);
> +               }
> +
> +               /* Increment the pointer to the supplied data buffer. */
> +               request.data = &data[num_bytes - bytes_left];
> +
> +               request.num_bytes = (bytes_left > 16) ? 16 : bytes_left;
> +               bytes_left -= request.num_bytes;
> +
> +               if ((cmd_type == AUX_CMD_I2C_READ) && bytes_left) {
> +                       /* Middle of a transaction I2C read request. Override
> +                        * the command code that was set to cmd_type.
> +                        */
> +                       request.cmd_code = AUX_CMD_I2C_READ_MOT;
> +               } else if ((cmd_type == AUX_CMD_I2C_WRITE) && bytes_left) {
> +                       /* Middle of a transaction I2C write request. Override
> +                        * the command code that was set to cmd_type.
> +                        */
> +                       request.cmd_code = AUX_CMD_I2C_WRITE_MOT;
> +               }
> +
> +               status = aux_request(dev, &request);
> +               if (status)
> +                       return status;
> +       }
> +
> +       return 0;
> +}
> +
> +/*
> + * Issue a read request over the AUX channel that will read from
> + * the RX device's DisplayPort Configuration data (DPCD) address space. The read
> + * message will be divided into multiple transactions which read a maximum of 16
> + * bytes each.
> + */
> +static int aux_read(struct udevice *dev, u32 dpcd_address, u32 bytes_to_read,
> +                   void *read_data)
> +{
> +       int status;
> +
> +       if (!is_connected(dev))
> +               return -ENODEV;

Can we use -ENXIO for this? That error means there is no device. There
is a device, it just isn't connected / working.

> +
> +       /* Send AUX read transaction. */
> +       status = aux_common(dev, AUX_CMD_READ, dpcd_address,
> +                           bytes_to_read, (u8 *)read_data);
> +
> +       return status;
> +}
> +
> +/*
> + * Issue a write request over the AUX channel that will write to
> + * the RX device's DisplayPort Configuration data (DPCD) address space. The
> + * write message will be divided into multiple transactions which write a
> + * maximum of 16 bytes each.
> + */
> +static int aux_write(struct udevice *dev, u32 dpcd_address, u32 bytes_to_write,
> +                    void *write_data)
> +{
> +       int status;
> +
> +       if (!is_connected(dev))
> +               return -ENODEV;

Here too

> +
> +       /* Send AUX write transaction. */
> +       status = aux_common(dev, AUX_CMD_WRITE, dpcd_address,
> +                           bytes_to_write, (u8 *)write_data);
> +
> +       return status;
> +}
> +
> +/* core initialization */
> +
> +static int initialize(struct udevice *dev)
> +{
> +       struct dp_tx *dp_tx = dev_get_priv(dev);
> +       u32 val;
> +       u32 phy_config;
> +       unsigned int k;
> +
> +       /* place the PHY (and GTTXRESET) into reset. */
> +       phy_config = get_reg(dev, REG_PHY_CONFIG);
> +       set_reg(dev, REG_PHY_CONFIG, phy_config | PHY_CONFIG_GT_ALL_RESET_MASK);
> +
> +       /* reset the video streams and AUX logic. */
> +       set_reg(dev, REG_SOFT_RESET,
> +               SOFT_RESET_VIDEO_STREAM_ALL_MASK |
> +               SOFT_RESET_AUX_MASK);
> +
> +       /* disable the DisplayPort TX core. */
> +       set_reg(dev, REG_ENABLE, 0);
> +
> +       /* set the clock divider. */
> +       val = get_reg(dev, REG_AUX_CLK_DIVIDER);
> +       val &= ~AUX_CLK_DIVIDER_VAL_MASK;
> +       val |= dp_tx->s_axi_clk / 1000000;
> +       set_reg(dev, REG_AUX_CLK_DIVIDER, val);
> +
> +       /* set the DisplayPort TX core's clock speed. */
> +       set_reg(dev, REG_PHY_CLOCK_SELECT, PHY_CLOCK_SELECT_DEFAULT);
> +
> +       /* bring the PHY (and GTTXRESET) out of reset. */
> +       set_reg(dev, REG_PHY_CONFIG,
> +               phy_config & ~PHY_CONFIG_GT_ALL_RESET_MASK);
> +
> +       /* enable the DisplayPort TX core. */
> +       set_reg(dev, REG_ENABLE, 1);
> +
> +       /* Unmask Hot-Plug-Detect (HPD) interrupts. */
> +       set_reg(dev, REG_INTERRUPT_MASK,
> +               ~INTERRUPT_MASK_HPD_PULSE_DETECTED_MASK &
> +               ~INTERRUPT_MASK_HPD_EVENT_MASK &
> +               ~INTERRUPT_MASK_HPD_IRQ_MASK);
> +
> +       for (k = 0; k < 4; k++) {
> +               /* Disable pre-cursor levels. */
> +               set_reg(dev, REG_PHY_PRECURSOR_LANE_0 + 4 * k, 0);
> +
> +               /* Write default voltage swing levels to the TX registers. */
> +               set_reg(dev, REG_PHY_VOLTAGE_DIFF_LANE_0 + 4 * k, 0);
> +
> +               /* Write default pre-emphasis levels to the TX registers. */
> +               set_reg(dev, REG_PHY_POSTCURSOR_LANE_0 + 4 * k, 0);
> +       }
> +
> +       return 0;
> +}
> +
> +bool is_link_rate_valid(struct udevice *dev, u8 link_rate)
> +{
> +       struct dp_tx *dp_tx = dev_get_priv(dev);
> +       bool valid = true;
> +
> +       if ((link_rate != LINK_BW_SET_162GBPS) &&
> +           (link_rate != LINK_BW_SET_270GBPS) &&
> +           (link_rate != LINK_BW_SET_540GBPS))
> +               valid = false;
> +       else if (link_rate > dp_tx->link_config.max_link_rate)
> +               valid = false;
> +
> +       return valid;
> +}
> +
> +bool is_lane_count_valid(struct udevice *dev, u8 lane_count)
> +{
> +       struct dp_tx *dp_tx = dev_get_priv(dev);
> +       bool valid = true;
> +
> +       if ((lane_count != LANE_COUNT_SET_1) &&
> +           (lane_count != LANE_COUNT_SET_2) &&
> +           (lane_count != LANE_COUNT_SET_4))
> +               valid = false;
> +       else if (lane_count > dp_tx->link_config.max_lane_count)
> +               valid = false;
> +
> +       return valid;
> +}
> +
> +static int get_rx_capabilities(struct udevice *dev)
> +{
> +       struct dp_tx *dp_tx = dev_get_priv(dev);
> +       int status;
> +       u8 rx_max_link_rate;
> +       u8 rx_max_lane_count;
> +
> +       if (!is_connected(dev))
> +               return -ENODEV;
> +
> +       status = aux_read(dev, DPCD_RECEIVER_CAP_FIELD_START, 16,
> +                         dp_tx->dpcd_rx_caps);
> +       if (status)
> +               return -EIO;
> +
> +       rx_max_link_rate = dp_tx->dpcd_rx_caps[DPCD_MAX_LINK_RATE];
> +       rx_max_lane_count = dp_tx->dpcd_rx_caps[DPCD_MAX_LANE_COUNT] &
> +                           DPCD_MAX_LANE_COUNT_MASK;
> +
> +       dp_tx->link_config.max_link_rate =
> +               (rx_max_link_rate > dp_tx->max_link_rate) ?
> +               dp_tx->max_link_rate : rx_max_link_rate;
> +       if (!is_link_rate_valid(dev, rx_max_link_rate))
> +               return -EINVAL;
> +
> +       dp_tx->link_config.max_lane_count =
> +               (rx_max_lane_count > dp_tx->max_lane_count) ?
> +               dp_tx->max_lane_count : rx_max_lane_count;
> +       if (!is_lane_count_valid(dev, rx_max_lane_count))
> +               return -EINVAL;
> +
> +       dp_tx->link_config.support_enhanced_framing_mode =
> +               dp_tx->dpcd_rx_caps[DPCD_MAX_LANE_COUNT] &
> +               DPCD_ENHANCED_FRAME_SUPPORT_MASK;
> +       dp_tx->link_config.support_downspread_control =
> +               dp_tx->dpcd_rx_caps[DPCD_MAX_DOWNSPREAD] &
> +               DPCD_MAX_DOWNSPREAD_MASK;
> +
> +       return 0;
> +}
> +
> +static void enable_main_link(struct udevice *dev)
> +{
> +       /* reset the scrambler. */
> +       set_reg(dev, REG_FORCE_SCRAMBLER_RESET, 0x1);
> +
> +       /* enable the main stream. */
> +       set_reg(dev, REG_ENABLE_MAIN_STREAM, 0x1);
> +}
> +
> +static void disable_main_link(struct udevice *dev)
> +{
> +       /* reset the scrambler. */
> +       set_reg(dev, REG_FORCE_SCRAMBLER_RESET, 0x1);
> +
> +       /* Disable the main stream. */
> +       set_reg(dev, REG_ENABLE_MAIN_STREAM, 0x0);
> +}
> +
> +static void reset_dp_phy(struct udevice *dev, u32 reset)
> +{
> +       struct dp_tx *dp_tx = dev_get_priv(dev);
> +       u32 val;
> +
> +       set_reg(dev, REG_ENABLE, 0x0);
> +
> +       val = get_reg(dev, REG_PHY_CONFIG);
> +
> +       /* Apply reset. */
> +       set_reg(dev, REG_PHY_CONFIG, val | reset);
> +
> +       /* Remove reset. */
> +       set_reg(dev, REG_PHY_CONFIG, val);
> +
> +       /* Wait for the PHY to be ready. */
> +       wait_phy_ready(dev, PHY_STATUS_LANES_READY_MASK(dp_tx->max_lane_count));
> +
> +       set_reg(dev, REG_ENABLE, 0x1);
> +}
> +
> +/*
> + * enable or disable the enhanced framing symbol sequence for
> + * both the DisplayPort TX core and the RX device.
> + */
> +static int set_enhanced_frame_mode(struct udevice *dev, u8 enable)
> +{
> +       struct dp_tx *dp_tx = dev_get_priv(dev);
> +       int status;
> +       u8 val;
> +
> +       if (!is_connected(dev))
> +               return -ENODEV;
> +
> +       if (dp_tx->link_config.support_enhanced_framing_mode)
> +               dp_tx->link_config.enhanced_framing_mode = enable;
> +       else
> +               dp_tx->link_config.enhanced_framing_mode = false;
> +
> +       /* Write enhanced frame mode enable to the DisplayPort TX core. */
> +       set_reg(dev, REG_ENHANCED_FRAME_EN,
> +               dp_tx->link_config.enhanced_framing_mode);
> +
> +       /* Write enhanced frame mode enable to the RX device. */
> +       status = aux_read(dev, DPCD_LANE_COUNT_SET, 0x1, &val);
> +       if (status)
> +               return -EIO;
> +
> +       if (dp_tx->link_config.enhanced_framing_mode)
> +               val |= DPCD_ENHANCED_FRAME_EN_MASK;
> +       else
> +               val &= ~DPCD_ENHANCED_FRAME_EN_MASK;
> +
> +       status = aux_write(dev, DPCD_LANE_COUNT_SET, 0x1, &val);
> +       if (status)
> +               return -EIO;
> +
> +       return 0;
> +}
> +
> +/*
> + * Set the number of lanes to be used by the main link for both
> + * the DisplayPort TX core and the RX device.
> + */
> +static int set_lane_count(struct udevice *dev, u8 lane_count)
> +{
> +       struct dp_tx *dp_tx = dev_get_priv(dev);
> +       int status;
> +       u8 val;
> +
> +       if (!is_connected(dev))
> +               return -ENODEV;
> +
> +       printf("       set lane count to %u\n", lane_count);
> +
> +       dp_tx->link_config.lane_count = lane_count;
> +
> +       /* Write the new lane count to the DisplayPort TX core. */
> +       set_reg(dev, REG_LANE_COUNT_SET, dp_tx->link_config.lane_count);
> +
> +       /* Write the new lane count to the RX device. */
> +       status = aux_read(dev, DPCD_LANE_COUNT_SET, 0x1, &val);
> +       if (status)
> +               return -EIO;
> +       val &= ~DPCD_LANE_COUNT_SET_MASK;
> +       val |= dp_tx->link_config.lane_count;
> +
> +       status = aux_write(dev, DPCD_LANE_COUNT_SET, 0x1, &val);
> +       if (status)
> +               return -EIO;
> +
> +       return 0;
> +}
> +
> +/*
> + * Set the clock frequency for the DisplayPort PHY corresponding
> + * to a desired data rate.
> + */
> +static int set_clk_speed(struct udevice *dev, u32 speed)
> +{
> +       struct dp_tx *dp_tx = dev_get_priv(dev);
> +       int status;
> +       u32 val;
> +
> +       /* Disable the DisplayPort TX core first. */
> +       val = get_reg(dev, REG_ENABLE);
> +       set_reg(dev, REG_ENABLE, 0x0);
> +
> +       /* Change speed of the feedback clock. */
> +       set_reg(dev, REG_PHY_CLOCK_SELECT, speed);
> +
> +       /* Re-enable the DisplayPort TX core if it was previously enabled. */
> +       if (val)
> +               set_reg(dev, REG_ENABLE, 0x1);
> +
> +       /* Wait until the PHY is ready. */
> +       status = wait_phy_ready(dev, PHY_STATUS_LANES_READY_MASK(dp_tx->max_lane_count));
> +       if (status)
> +               return -EIO;
> +
> +       return 0;
> +}
> +
> +/*
> + * Set the data rate to be used by the main link for both the
> + * DisplayPort TX core and the RX device.
> + */
> +static int set_link_rate(struct udevice *dev, u8 link_rate)
> +{
> +       struct dp_tx *dp_tx = dev_get_priv(dev);
> +       int status;
> +
> +       /* Write a corresponding clock frequency to the DisplayPort TX core. */
> +       switch (link_rate) {
> +       case LINK_BW_SET_162GBPS:
> +               printf("       set link rate to 1.62 Gb/s\n");
> +               status = set_clk_speed(dev, PHY_CLOCK_SELECT_162GBPS);
> +               break;
> +       case LINK_BW_SET_270GBPS:
> +               printf("       set link rate to 2.70 Gb/s\n");
> +               status = set_clk_speed(dev, PHY_CLOCK_SELECT_270GBPS);
> +               break;
> +       case LINK_BW_SET_540GBPS:
> +               printf("       set link rate to 5.40 Gb/s\n");
> +               status = set_clk_speed(dev, PHY_CLOCK_SELECT_540GBPS);
> +               break;
> +       default:
> +               return -EINVAL;
> +       }
> +       if (status)
> +               return -EIO;
> +
> +       dp_tx->link_config.link_rate = link_rate;
> +
> +       /* Write new link rate to the DisplayPort TX core. */
> +       set_reg(dev, REG_LINK_BW_SET, dp_tx->link_config.link_rate);
> +
> +       /* Write new link rate to the RX device. */
> +       status = aux_write(dev, DPCD_LINK_BW_SET, 1,
> +                          &dp_tx->link_config.link_rate);
> +       if (status)
> +               return -EIO;

Can you not return the error you got from aux_write()?

[..]

Regards,
Simon

^ permalink raw reply	[flat|nested] 138+ messages in thread

* [U-Boot] [PATCH 32/51] drivers: Add ihs_fpga and gdsys_soc drivers
  2017-07-14 12:55 ` [U-Boot] [PATCH 32/51] drivers: Add ihs_fpga and gdsys_soc drivers Mario Six
@ 2017-07-19  9:06   ` Simon Glass
  2017-07-25  9:22     ` Mario Six
  0 siblings, 1 reply; 138+ messages in thread
From: Simon Glass @ 2017-07-19  9:06 UTC (permalink / raw)
  To: u-boot

Hi Mario,

On 14 July 2017 at 05:55, Mario Six <mario.six@gdsys.cc> wrote:
> This patch adds DM drivers for IHS FPGAs and their associated busses, as
> well as uclasses for both.
>
> Signed-off-by: Mario Six <mario.six@gdsys.cc>
> ---
>
>  drivers/misc/Kconfig     |   6 +
>  drivers/misc/Makefile    |   1 +
>  drivers/misc/gdsys_soc.c |  51 +++
>  drivers/misc/ihs_fpga.c  | 871 +++++++++++++++++++++++++++++++++++++++++++++++
>  include/dm/uclass-id.h   |   2 +
>  include/gdsys_soc.h      |  29 ++
>  include/ihs_fpga.h       | 111 ++++++
>  7 files changed, 1071 insertions(+)
>  create mode 100644 drivers/misc/gdsys_soc.c
>  create mode 100644 drivers/misc/ihs_fpga.c
>  create mode 100644 include/gdsys_soc.h
>  create mode 100644 include/ihs_fpga.h

There are definitely cases where you we might have a unique peripheral
and want to add a uclass for it.

But for what you have here, could we use UCLASS_SYSCON for the soc bus?

For the FPGA could we add a new FPGA uclass? It could have read and
write methods a bit like struct pci_ops where you specify the size of
the read/write. I think that would be useful generally.

[..]

> +static int ihs_fpga_set_reg(struct udevice *dev, const char *compat,
> +                           uint value)
> +{
> +       struct ihs_fpga_priv *priv = dev_get_priv(dev);
> +       struct reg_spec spec;
> +
> +       if (get_reg_spec(dev, compat, &spec)) {
> +               printf("%s: Could not get %s regspec for '%s'.\n", __func__,
> +                      dev->name, compat);
> +               return -ENODEV;

Can you return the error from get_reg_spec()? Also -ENODEV means no
device which cannot be true if you have  a dev pointer. Perhaps
-ENXIO?

> +       }
> +
> +       out_le16((void *)(priv->regs + spec.addr), value << spec.shift);
> +
> +       return 0;
> +}
> +
> +static int ihs_fpga_get_reg(struct udevice *dev, const char *compat,
> +                           uint *value)
> +{
> +       struct ihs_fpga_priv *priv = dev_get_priv(dev);
> +       struct reg_spec spec;
> +       uint tmp;
> +
> +       if (get_reg_spec(dev, compat, &spec)) {
> +               printf("%s: Could not get %s regspec for '%s'.\n", __func__,
> +                      dev->name, compat);

Can we use debug() in drivers?

> +               return -ENODEV;
> +       }
> +
> +       tmp = in_le16((void *)(priv->regs + spec.addr));
> +       *value = (tmp & spec.mask) >> spec.shift;
> +
> +       return 0;
> +}
> +
> +static u16 ihs_fpga_in_le16(struct udevice *dev, phys_addr_t addr)
> +{
> +       struct ihs_fpga_priv *priv = dev_get_priv(dev);
> +
> +       /* TODO: MCLink transfer */
> +
> +       return in_le16((void *)(priv->regs + addr));
> +}
> +
> +static void ihs_fpga_out_le16(struct udevice *dev, phys_addr_t addr, u16 value)
> +{
> +       struct ihs_fpga_priv *priv = dev_get_priv(dev);
> +
> +       /* TODO: MCLink transfer */
> +
> +       out_le16((void *)(priv->regs + addr), value);
> +}
> +
> +static const struct ihs_fpga_ops ihs_fpga_ops = {
> +       .set_reg = ihs_fpga_set_reg,
> +       .get_reg = ihs_fpga_get_reg,
> +       .in_le16 = ihs_fpga_in_le16,
> +       .out_le16 = ihs_fpga_out_le16,
> +};
> +
> +static int ihs_fpga_probe(struct udevice *dev)
> +{
> +       struct ihs_fpga_priv *priv = dev_get_priv(dev);
> +       fdt_addr_t addr;
> +       struct fdtdec_phandle_args phandle_args;

Since this is new code I think using the dev_read_...() functions is better

> +       struct fdtdec_phandle_args args;
> +       struct udevice *busdev = NULL;
> +       struct udevice *child = NULL;
> +       uint mem_width;
> +
> +       if (fdtdec_parse_phandle_with_args(gd->fdt_blob, dev_of_offset(dev),
> +                                          "regmap", NULL, 0, 0, &args)) {
> +               printf("%s: Could not get regmap.\n", dev->name);
> +               return 1;
> +       }
> +
> +       priv->regmap_node = args.node;
> +
> +       addr = devfdt_get_addr(dev);
> +
> +       priv->addr = addr;
> +       priv->regs = map_sysmem(addr, mem_width);
> +
> +       gpio_request_by_name(dev, "reset-gpios", 0, &priv->reset_gpio,
> +                            GPIOD_IS_OUT);
> +       if (!priv->reset_gpio.dev)

You should check the return value of the function. How come you don't
return the error code here? If it is OK to not have a GPIO then use
dm_gpio_is_valid() - and hopefully debug() instead of printf().

> +               printf("%s: Could not get reset-GPIO.\n", dev->name);
> +
> +       gpio_request_by_name(dev, "done-gpios", 0, &priv->done_gpio,
> +                            GPIOD_IS_IN);
> +       if (!priv->done_gpio.dev)
> +               printf("%s: Could not get done-GPIO.\n", dev->name);
> +
> +       dm_gpio_set_value(&priv->reset_gpio, 1);

Error check? This returns -ENOENT if the GPIO is not valid (as above)
so you could filter that out, or use dm_gpo_is_valid() to avoid
calling it.

> +
> +       signal_startup_finished(dev);
> +
> +       if (!do_reflection_test(dev)) {
> +               int ctr = 0;
> +
> +               dm_gpio_set_value(&priv->reset_gpio, 0);
> +
> +               while (!dm_gpio_get_value(&priv->done_gpio)) {
> +                       mdelay(100);
> +                       if (ctr++ > 5) {
> +                               printf("Initializing FPGA failed\n");
> +                               break;
> +                       }
> +               }
> +
> +               udelay(10);
> +
> +               dm_gpio_set_value(&priv->reset_gpio, 1);
> +
> +               if (!do_reflection_test(dev)) {
> +                       printf("%s: Reflection test FAILED.\n", dev->name);
> +                       return -1;

This is -EPERM. Perhaps use -EIO? Better to return vaue from the
do_reflection_tests() call.

> +               }
> +       }
> +
> +       printf("%s: Reflection test passed.\n", dev->name);

debug()?

> +
> +       if (fdtdec_parse_phandle_with_args(gd->fdt_blob, dev_of_offset(dev), "bus",
> +                                          NULL, 0, 0, &phandle_args))
> +               return -1;
> +
> +       lists_bind_fdt(dev, offset_to_ofnode(phandle_args.node), &busdev);

Should this be dm_scan_fdt_dev,()?

Also should go in bind() method

> +
> +       fpga_print_info(dev);
> +
> +       /* TODO: Check if this should be gazerbeam-specific */
> +       if (priv->has_osd) {
> +               /* Disable softcore, select external pixclock */
> +               fpga_set_reg(dev, "control", 0x8000);
> +       }
> +
> +       device_probe(busdev);
> +
> +       for (device_find_first_child(busdev, &child);
> +            child;
> +            device_find_next_child(&child))
> +               device_probe(child);

The children should be probed when used by things like uclass_get_device()...

We should not be probing them here.

> +
> +       return 0;
> +}
> +
> +static const struct udevice_id ihs_fpga_ids[] = {
> +       { .compatible = "gdsys,iocon_fpga" },
> +       { .compatible = "gdsys,iocpu_fpga" },
> +       { }
> +};
> +
> +U_BOOT_DRIVER(ihs_fpga_bus) = {
> +       .name           = "ihs_fpga_bus",
> +       .id             = UCLASS_IHS_FPGA,
> +       .ops            = &ihs_fpga_ops,
> +       .of_match       = ihs_fpga_ids,
> +       .probe          = ihs_fpga_probe,
> +       .priv_auto_alloc_size = sizeof(struct ihs_fpga_priv),
> +};
> diff --git a/include/dm/uclass-id.h b/include/dm/uclass-id.h
> index 2e6498b7dc..56fbedaa9d 100644
> --- a/include/dm/uclass-id.h
> +++ b/include/dm/uclass-id.h
> @@ -35,12 +35,14 @@ enum uclass_id {
>         UCLASS_DISPLAY,         /* Display (e.g. DisplayPort, HDMI) */
>         UCLASS_DMA,             /* Direct Memory Access */
>         UCLASS_ETH,             /* Ethernet device */
> +       UCLASS_GDSYS_SOC,       /* gdsys soc buses */
>         UCLASS_GPIO,            /* Bank of general-purpose I/O pins */
>         UCLASS_FIRMWARE,        /* Firmware */
>         UCLASS_I2C,             /* I2C bus */
>         UCLASS_I2C_EEPROM,      /* I2C EEPROM device */
>         UCLASS_I2C_GENERIC,     /* Generic I2C device */
>         UCLASS_I2C_MUX,         /* I2C multiplexer */
> +       UCLASS_IHS_FPGA,        /* gdsys IHS FPGAs */
>         UCLASS_IRQ,             /* Interrupt controller */
>         UCLASS_KEYBOARD,        /* Keyboard input device */
>         UCLASS_LED,             /* Light-emitting diode (LED) */
> diff --git a/include/gdsys_soc.h b/include/gdsys_soc.h
> new file mode 100644
> index 0000000000..2164651f62
> --- /dev/null
> +++ b/include/gdsys_soc.h
> @@ -0,0 +1,29 @@
> +/*
> + * (C) Copyright 2017
> + * Mario Six,  Guntermann & Drunck GmbH, mario.six at gdsys.cc
> + *
> + * SPDX-License-Identifier:    GPL-2.0+
> + */
> +
> +#ifndef _GDSYS_SOC_H_
> +#define _GDSYS_SOC_H_
> +
> +/**
> + * struct gdsys_soc_child_platdata - platform data for devices on gdsys soc
> + *                                  buses
> + *
> + * To access their register maps, devices on gdsys soc buses usually have
> + * facilitate the accessor function of the IHS FPGA their parent bus is
> + * attached to. To pass the FPGA device down to the bus' children, a pointer to
> + * it is contained in this structure.
> + *
> + * To obtain this structure, use dev_get_parent_platdata(dev) where dev is a
> + * device on the gdsys soc bus.
> + *
> + * @fpga:      The IHS FPGA that controls the bus the device is attached to.
> + */
> +struct gdsys_soc_child_platdata {
> +       struct udevice *fpga;
> +};
> +
> +#endif /* _GDSYS_SOC_H_ */
> diff --git a/include/ihs_fpga.h b/include/ihs_fpga.h
> new file mode 100644
> index 0000000000..552583cbe1
> --- /dev/null
> +++ b/include/ihs_fpga.h
> @@ -0,0 +1,111 @@
> +/*
> + * (C) Copyright 2017
> + * Mario Six,  Guntermann & Drunck GmbH, mario.six at gdsys.cc
> + *
> + * SPDX-License-Identifier:    GPL-2.0+
> + */
> +
> +#ifndef _IHS_FPGA_H_
> +#define _IHS_FPGA_H_
> +
> +/**
> + * struct ihs_fpga_ops - driver operations for IHS FPGA 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 ihs_fpga_ops {
> +       /**
> +        * get_reg() - Get value of a named FPGA register
> +        *
> +        * To accommodate possible future memory layout changes, the registers
> +        * of a IHS FPGA are described in the device tree, and each is given a
> +        * distinct compatible string to address them with.
> +        *
> +        * @dev:        FPGA device to read from.
> +        * @compat:     The compatible string of the register to write to.
> +        * @value:      Pointer to a variable that takes the value read from the
> +        *              register.
> +        * @return 0 if OK, -ENODEV if no named register with the given
> +        *  compatibility string exists.
> +        */
> +       int (*get_reg)(struct udevice *dev, const char *compat, uint *value);
> +
> +       /**
> +        * set_reg() - Set value of a named FPGA register
> +        *
> +        * To accommodate possible future memory layout changes, the registers
> +        * of a IHS FPGA are described in the device tree, and each is given a
> +        * distinct compatible string to address them with.
> +        *
> +        * @dev:        FPGA device to write to.
> +        * @compat:     The compatible string of the register to write to.
> +        * @value:      Value to write to the register.
> +        * @return 0 if OK, -ENODEV if no named register with the given
> +        *      compatibility string exists.
> +        */
> +       int (*set_reg)(struct udevice *dev, const char *compat, uint value);
> +
> +       /**
> +        * in_le16() - Read 16 bit value from address in FPGA register space
> +        *
> +        * @dev:        FPGA device to read from.
> +        * @addr:       Address in the FPGA register space to read from.
> +        * @return 0 if OK, -ve on error.
> +        */
> +       u16 (*in_le16)(struct udevice *dev, phys_addr_t addr);
> +
> +       /**
> +        * out_le16() - Write 16 bit value to address in FPGA register space
> +        *
> +        * @dev:        FPGA device to write to.
> +        * @addr:       Address in the FPGA register space to write to.
> +        * @return 0 if OK, -ve on error.
> +        */
> +       void (*out_le16)(struct udevice *dev, phys_addr_t addr, u16 value);
> +};
> +
> +#define ihs_fpga_get_ops(dev)  ((struct ihs_fpga_ops *)(dev)->driver->ops)
> +
> +/**
> + * fpga_get_reg() - Get value of a named FPGA register
> + *
> + * @dev:       FPGA device to read from.
> + * @compat:    The compatible string of the register to write to.
> + * @value:     Pointer to a variable that takes the value read from the register.
> + * @return 0 if OK, -ENODEV if no named register with the given compatibility
> + *  string exists.
> + */
> +int fpga_get_reg(struct udevice *dev, const char *compat, uint *value);
> +
> +/**
> + * fpga_set_reg() - Set value of a named FPGA register
> + *
> + * @dev:       FPGA device to write to.
> + * @compat:    The compatible string of the register to write to.
> + * @value:     Value to write to the register.
> + * @return 0 if OK, -ENODEV if no named register with the given compatibility
> + *  string exists.
> + */
> +int fpga_set_reg(struct udevice *dev, const char *compat, uint value);
> +
> +/**
> + * fpga_in_le16() - Read 16 bit value from address in FPGA register space
> + *
> + * @dev:       FPGA device to read from.
> + * @addr:      Address in the FPGA register space to read from.
> + * @return 0 if OK, -ve on error.
> + */
> +u16 fpga_in_le16(struct udevice *dev, phys_addr_t addr);
> +
> +/**
> + * fpga_out_le16() - Write 16 bit value to address in FPGA register space
> + *
> + * @dev:       FPGA device to write to.
> + * @addr:      Address in the FPGA register space to write to.
> + * @return 0 if OK, -ve on error.
> + */
> +void fpga_out_le16(struct udevice *dev, phys_addr_t addr, u16 value);
> +
> +#endif /* !_IHS_FPGA_H_ */
> --
> 2.11.0
>

Regards,
Simon

^ permalink raw reply	[flat|nested] 138+ messages in thread

* [U-Boot] [PATCH 36/51] drivers: Add ihs_axi driver
  2017-07-14 12:55 ` [U-Boot] [PATCH 36/51] drivers: Add ihs_axi driver Mario Six
@ 2017-07-19  9:06   ` Simon Glass
  2017-07-25 12:27     ` Mario Six
  0 siblings, 1 reply; 138+ messages in thread
From: Simon Glass @ 2017-07-19  9:06 UTC (permalink / raw)
  To: u-boot

Hi Mario,

On 14 July 2017 at 05:55, Mario Six <mario.six@gdsys.cc> wrote:
> Add a driver for the IHS AXI bus on IHS FPGAs.

Can we make this uclass more generic by using AXI instead of IHS_AXI?

>
> Signed-off-by: Mario Six <mario.six@gdsys.cc>
> ---
>
>  drivers/misc/Kconfig   |   7 ++
>  drivers/misc/Makefile  |   1 +
>  drivers/misc/ihs_axi.c | 208 +++++++++++++++++++++++++++++++++++++++++++++++++
>  include/dm/uclass-id.h |   1 +
>  include/ihs_axi.h      |  69 ++++++++++++++++
>  5 files changed, 286 insertions(+)
>  create mode 100644 drivers/misc/ihs_axi.c
>  create mode 100644 include/ihs_axi.h
>
> diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig
> index 8b59a444ce..c53f9f195e 100644
> --- a/drivers/misc/Kconfig
> +++ b/drivers/misc/Kconfig
> @@ -202,4 +202,11 @@ config IHS_FPGA
>         depends on MISC
>         help
>           Support for IHS FPGA.
> +
> +config IHS_AXI
> +       bool "Enable IHS AXI driver"
> +       depends on MISC
> +       help
> +         Support for IHS AXI bus.

More help? Spell out the abbreviations and point to more info.

> +
>  endmenu
> diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile
> index d2e46fc7d6..a6c71acedd 100644
> --- a/drivers/misc/Makefile
> +++ b/drivers/misc/Makefile
> @@ -53,3 +53,4 @@ obj-$(CONFIG_WINBOND_W83627) += winbond_w83627.o
>  obj-$(CONFIG_QFW) += qfw.o
>  obj-$(CONFIG_ROCKCHIP_EFUSE) += rockchip-efuse.o
>  obj-$(CONFIG_IHS_FPGA) += ihs_fpga.o gdsys_soc.o
> +obj-$(CONFIG_IHS_AXI) += ihs_axi.o
> diff --git a/drivers/misc/ihs_axi.c b/drivers/misc/ihs_axi.c
> new file mode 100644
> index 0000000000..07150e2262
> --- /dev/null
> +++ b/drivers/misc/ihs_axi.c
> @@ -0,0 +1,208 @@
> +/*
> + * (C) Copyright 2016
> + * Dirk Eibach,  Guntermann & Drunck GmbH, dirk.eibach at gdsys.cc
> + *
> + * (C) Copyright 2017
> + * Mario Six,  Guntermann & Drunck GmbH, mario.six at gdsys.cc
> + *
> + * SPDX-License-Identifier:    GPL-2.0+
> + */
> +
> +#include <common.h>
> +#include <dm.h>
> +#include <dm/device-internal.h>
> +#include <ihs_axi.h>
> +#include <ihs_fpga.h>
> +#include <gdsys_soc.h>
> +
> +DECLARE_GLOBAL_DATA_PTR;
> +
> +enum {
> +       REG_INTERRUPT_STATUS = 0x00,
> +       REG_INTERRUPT_ENABLE_CONTROL = 0x02,
> +       REG_ADDRESS_LSB = 0x04,
> +       REG_ADDRESS_MSB = 0x06,
> +       REG_WRITE_DATA_LSB = 0x08,
> +       REG_WRITE_DATA_MSB = 0x0A,
> +       REG_READ_DATA_LSB = 0x0C,
> +       REG_READ_DATA_MSB = 0x0E,
> +};
> +
> +struct ihs_axi_priv {
> +       fdt_addr_t addr;
> +};
> +
> +enum {
> +       STATUS_EVENT_MASK = GENMASK(15, 12),
> +
> +       STATUS_READ_COMPLETE_EVENT = BIT(15),
> +       STATUS_WRITE_COMPLETE_EVENT = BIT(14),
> +       STATUS_TIMEOUT_EVENT = BIT(13),
> +       STATUS_ERROR_EVENT = BIT(12),
> +       STATUS_AXI_INT = BIT(11),
> +       STATUS_READ_DATA_AVAILABLE = BIT(7),
> +       STATUS_BUSY = BIT(6),
> +       STATUS_INIT_DONE = BIT(5),
> +};
> +
> +enum {
> +       CONTROL_EVENT_ENABLE_MASK = GENMASK(15, 11),
> +       CONTROL_CMD_MASK = GENMASK(3, 0),
> +
> +       CONTROL_READ_COMPLETE_EVENT_ENABLE = BIT(15),
> +       CONTROL_WRITE_COMPLETE_EVENT_ENABLE = BIT(14),
> +       CONTROL_TIMEOUT_EVENT_ENABLE = BIT(13),
> +       CONTROL_ERROR_EVENT_ENABLE = BIT(12),
> +       CONTROL_AXI_INT_ENABLE = BIT(11),
> +
> +       CONTROL_CMD_NOP = 0x0,
> +       CONTROL_CMD_WRITE = 0x8,
> +       CONTROL_CMD_WRITE_POST_INC = 0x9,
> +       CONTROL_CMD_READ = 0xa,
> +       CONTROL_CMD_READ_POST_INC = 0xb,
> +
> +};
> +
> +static int axi_transfer(struct udevice *bus, u32 address, u16 cmd,
> +                       u16 complete_flag)
> +{
> +       struct ihs_axi_priv *priv = dev_get_priv(bus);
> +       struct gdsys_soc_child_platdata *pplat = dev_get_parent_platdata(bus);
> +       u16 wait_mask = complete_flag | STATUS_TIMEOUT_EVENT |
> +                       STATUS_ERROR_EVENT;
> +       u16 status;
> +       uint k;
> +
> +       cmd &= CONTROL_CMD_MASK;
> +
> +       fpga_out_le16(pplat->fpga, priv->addr + REG_ADDRESS_LSB,
> +                     address & 0xffff);
> +       fpga_out_le16(pplat->fpga, priv->addr + REG_ADDRESS_MSB,
> +                     (address >> 16) & 0xffff);
> +
> +       fpga_out_le16(pplat->fpga, priv->addr + REG_INTERRUPT_STATUS,
> +                     wait_mask);
> +       fpga_out_le16(pplat->fpga, priv->addr + REG_INTERRUPT_ENABLE_CONTROL,
> +                     cmd);
> +
> +       for (k = 10; k > 0; --k) {
> +               status = fpga_in_le16(pplat->fpga,
> +                                     priv->addr + REG_INTERRUPT_STATUS);
> +               if (status & wait_mask)
> +                       break;
> +               udelay(1);
> +       }
> +
> +       if (!k)
> +               status = fpga_in_le16(pplat->fpga,
> +                                     priv->addr + REG_INTERRUPT_STATUS);
> +
> +       if (status & complete_flag)
> +               return 0;
> +
> +       if (status & STATUS_ERROR_EVENT)
> +               return -EIO;
> +
> +       return -ETIMEDOUT;
> +}
> +
> +int axi_read(struct udevice *dev, u32 address, u32 *data)
> +{
> +       struct ihs_axi_ops *ops = ihs_axi_get_ops(dev);
> +
> +       return ops->read(dev, address, data);
> +}
> +
> +int axi_write(struct udevice *dev, u32 address, u32 data)
> +{
> +       struct ihs_axi_ops *ops = ihs_axi_get_ops(dev);
> +
> +       return ops->write(dev, address, data);
> +}
> +
> +/*
> + * API
> + */
> +
> +int ihs_axi_read(struct udevice *dev, u32 address, u32 *data)
> +{
> +       struct ihs_axi_priv *priv = dev_get_priv(dev);
> +       struct gdsys_soc_child_platdata *pplat = dev_get_parent_platdata(dev);
> +       int res = 0;
> +       u16 data_lsb, data_msb;
> +
> +       res = axi_transfer(dev, address, CONTROL_CMD_READ,
> +                          STATUS_READ_COMPLETE_EVENT);
> +       if (res < 0)
> +               return res;
> +
> +       data_lsb = fpga_in_le16(pplat->fpga,
> +                               priv->addr + REG_READ_DATA_LSB);
> +       data_msb = fpga_in_le16(pplat->fpga,
> +                               priv->addr + REG_READ_DATA_MSB);
> +
> +       *data = (data_msb << 16) | data_lsb;
> +
> +       return res;
> +}
> +
> +int ihs_axi_write(struct udevice *dev, u32 address, u32 data)
> +{
> +       struct ihs_axi_priv *priv = dev_get_priv(dev);
> +       struct gdsys_soc_child_platdata *pplat = dev_get_parent_platdata(dev);
> +       int res = 0;
> +
> +       fpga_out_le16(pplat->fpga, priv->addr + REG_READ_DATA_LSB,
> +                     data & 0xffff);
> +       fpga_out_le16(pplat->fpga, priv->addr + REG_READ_DATA_MSB,
> +                     (data >> 16) & 0xffff);
> +
> +       res = axi_transfer(dev, address, CONTROL_CMD_WRITE,
> +                          STATUS_WRITE_COMPLETE_EVENT);
> +
> +       return res;
> +}
> +
> +UCLASS_DRIVER(ihs_axi) = {
> +       .id             = UCLASS_IHS_AXI,
> +       .name           = "ihs_axi",
> +       .post_bind      = dm_scan_fdt_dev,
> +       .flags          = DM_UC_FLAG_SEQ_ALIAS,
> +};
> +
> +static const struct udevice_id ihs_axi_ids[] = {
> +       { .compatible = "gdsys,ihs_axi" },
> +       { /* sentinel */ }
> +};
> +
> +static const struct ihs_axi_ops ihs_axi_ops = {
> +       .read = ihs_axi_read,
> +       .write = ihs_axi_write,
> +};
> +
> +int ihs_axi_probe(struct udevice *dev)
> +{
> +       struct ihs_axi_priv *priv = dev_get_priv(dev);
> +       struct udevice *child = NULL;
> +       int addr;
> +
> +       addr = fdtdec_get_int(gd->fdt_blob, dev_of_offset(dev), "reg", -1);

dev_read_...

> +
> +       priv->addr = addr;
> +
> +       for (device_find_first_child(dev, &child);
> +            child;
> +            device_find_next_child(&child))
> +               device_probe(child);

Should not probe children. Instead when you probe a child this bus
should be auto-probed by DM.

> +
> +       return 0;
> +}
> +
> +U_BOOT_DRIVER(ihs_axi_bus) = {
> +       .name           = "ihs_axi_bus",
> +       .id             = UCLASS_IHS_AXI,
> +       .of_match       = ihs_axi_ids,
> +       .ops            = &ihs_axi_ops,
> +       .priv_auto_alloc_size = sizeof(struct ihs_axi_priv),
> +       .probe          = ihs_axi_probe,
> +};
> diff --git a/include/dm/uclass-id.h b/include/dm/uclass-id.h
> index 8eee8534ab..1a24de10b4 100644
> --- a/include/dm/uclass-id.h
> +++ b/include/dm/uclass-id.h
> @@ -42,6 +42,7 @@ enum uclass_id {
>         UCLASS_I2C_EEPROM,      /* I2C EEPROM device */
>         UCLASS_I2C_GENERIC,     /* Generic I2C device */
>         UCLASS_I2C_MUX,         /* I2C multiplexer */
> +       UCLASS_IHS_AXI,         /* gdsys IHS AXI bus */
>         UCLASS_IHS_FPGA,        /* gdsys IHS FPGAs */
>         UCLASS_IRQ,             /* Interrupt controller */
>         UCLASS_KEYBOARD,        /* Keyboard input device */
> diff --git a/include/ihs_axi.h b/include/ihs_axi.h
> new file mode 100644
> index 0000000000..8640d45a0a
> --- /dev/null
> +++ b/include/ihs_axi.h
> @@ -0,0 +1,69 @@
> +/*
> + * (C) Copyright 2017
> + * Mario Six,  Guntermann & Drunck GmbH, mario.six at gdsys.cc
> + *
> + * SPDX-License-Identifier:    GPL-2.0+
> + */
> +
> +#ifndef _AXI_H_
> +#define _AXI_H_
> +
> +/**
> + * struct ihs_axi_ops - driver operations for IHS AXI 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 ihs_axi_ops {
> +       /**
> +        * read() - Read a single 32 bit value from a specified address on a
> +        *          IHS AXI bus
> +        *
> +        * @dev:        IHS AXI bus to read from.
> +        * @address:    The address to read from.
> +        * @data:       Pointer to a variable that takes the data value read
> +        *              from the address on the IHS AXI bus.
> +        * @return 0 if OK, -ve on error.
> +        */
> +       int (*read)(struct udevice *dev, u32 address, u32* data);

How about using ulong for address so can support 64-bit machines.

Also should we have a data length parameter? Or rename this to read32()?

When adding a new uclass we should have a simple sandbox driver and test.

> +
> +       /**
> +        * write() - Write a single 32 bit value to a specified address on a
> +        *           IHS AXI bus
> +        *
> +        * @dev:        IHS AXI bus to write to.
> +        * @address:    The address to write to.
> +        * @data:       Data value to be written to the address on the IHS AXI
> +        *              bus.
> +        * @return 0 if OK, -ve on error.
> +        */
> +       int (*write)(struct udevice *dev, u32 address, u32 data);
> +};
> +
> +#define ihs_axi_get_ops(dev)   ((struct ihs_axi_ops *)(dev)->driver->ops)
> +
> +/**
> + * axi_read() - Read a single 32 bit value from a specified address on a
> + *              IHS AXI bus
> + *
> + * @dev:       IHS AXI bus to read from.
> + * @address:   The address to read from.
> + * @data:      Pointer to a variable that takes the data value read from the
> + *              address on the IHS AXI bus.
> + * @return 0 if OK, -ve on error.
> + */
> +int axi_read(struct udevice *dev, u32 address, u32* data);
> +
> +/**
> + * axi_write() - Write a single 32 bit value to a specified address on a
> + *              IHS AXI bus
> + *
> + * @dev:       IHS AXI bus to write to.
> + * @address:   The address to write to.
> + * @data:      Data value to be written to the address on the IHS AXI bus.
> + * @return 0 if OK, -ve on error.
> + */
> +int axi_write(struct udevice *dev, u32 address, u32 data);
> +
> +#endif
> --
> 2.11.0
>

Regards,
Simon

^ permalink raw reply	[flat|nested] 138+ messages in thread

* [U-Boot] [PATCH 37/51] drivers: Add ihs_video_out driver
  2017-07-14 12:55 ` [U-Boot] [PATCH 37/51] drivers: Add ihs_video_out driver Mario Six
@ 2017-07-19  9:06   ` Simon Glass
  2017-07-25 11:36     ` Mario Six
  0 siblings, 1 reply; 138+ messages in thread
From: Simon Glass @ 2017-07-19  9:06 UTC (permalink / raw)
  To: u-boot

Hi Mario,

On 14 July 2017 at 05:55, Mario Six <mario.six@gdsys.cc> wrote:
> Add a driver for IHS OSDs on IHS FPGAs.
>
> Signed-off-by: Mario Six <mario.six@gdsys.cc>
> ---
>
>  drivers/misc/Kconfig         |   6 ++
>  drivers/misc/Makefile        |   1 +
>  drivers/misc/ihs_video_out.c | 243 +++++++++++++++++++++++++++++++++++++++++++
>  include/dm/uclass-id.h       |   1 +
>  include/ihs_video_out.h      | 146 ++++++++++++++++++++++++++
>  5 files changed, 397 insertions(+)
>  create mode 100644 drivers/misc/ihs_video_out.c
>  create mode 100644 include/ihs_video_out.h
>
> diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig
> index c53f9f195e..c0e4b921b4 100644
> --- a/drivers/misc/Kconfig
> +++ b/drivers/misc/Kconfig
> @@ -209,4 +209,10 @@ config IHS_AXI
>         help
>           Support for IHS AXI bus.
>
> +config IHS_VIDEO_OUT
> +       bool "Enable IHS video out driver"
> +       depends on MISC
> +       help
> +         Support for IHS video out.
> +
>  endmenu
> diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile
> index a6c71acedd..eab539b739 100644
> --- a/drivers/misc/Makefile
> +++ b/drivers/misc/Makefile
> @@ -54,3 +54,4 @@ obj-$(CONFIG_QFW) += qfw.o
>  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
> diff --git a/drivers/misc/ihs_video_out.c b/drivers/misc/ihs_video_out.c
> new file mode 100644
> index 0000000000..a7e855f054
> --- /dev/null
> +++ b/drivers/misc/ihs_video_out.c
> @@ -0,0 +1,243 @@
> +/*
> + * (C) Copyright 2017
> + * Mario Six,  Guntermann & Drunck GmbH, mario.six at gdsys.cc
> + *
> + * based on the gdsys osd driver, which is
> + *
> + * (C) Copyright 2010
> + * Dirk Eibach,  Guntermann & Drunck GmbH, eibach at gdsys.de
> + *
> + * SPDX-License-Identifier:    GPL-2.0+
> + */
> +
> +#include <common.h>
> +#include <dm.h>
> +#include <dm/device-internal.h>
> +#include <dm/uclass-internal.h>
> +#include <gdsys_soc.h>
> +#include <ihs_fpga.h>
> +#include <ihs_video_out.h>
> +#include <transmitter.h>
> +#include <asm/gpio.h>
> +
> +#include "../transmitter/logicore_dp_tx.h"
> +
> +DECLARE_GLOBAL_DATA_PTR;
> +
> +enum {
> +       REG_VERSION = 0x00,
> +       REG_FEATURES = 0x02,
> +       REG_CONTROL = 0x04,
> +       REG_XY_SIZE = 0x06,
> +       REG_XY_SCALE = 0x08,
> +       REG_X_POS = 0x0A,
> +       REG_Y_POS = 0x0C,
> +};
> +
> +struct ihs_video_out_priv {
> +       int addr;
> +       int osd_base;
> +       int osd_buffer_base;
> +       uint base_width;
> +       uint base_height;
> +       int sync_src;
> +       struct udevice *dp_tx;
> +       struct udevice *clk_gen;
> +};
> +
> +UCLASS_DRIVER(ihs_video_out) = {
> +       .id             = UCLASS_IHS_VIDEO_OUT,
> +       .name           = "ihs_video_out",
> +       .flags          = DM_UC_FLAG_SEQ_ALIAS,
> +};
> +
> +static const struct udevice_id ihs_video_out_ids[] = {
> +       { .compatible = "gdsys,ihs_video_out" },
> +       { }
> +};
> +
> +int video_out_get_data(struct udevice *dev, struct ihs_video_out_data *data)
> +{
> +       struct ihs_video_out_ops *ops = ihs_video_out_get_ops(dev);
> +
> +       return ops->get_data(dev, data);
> +}
> +
> +int video_out_set_mem(struct udevice *dev, uint x, uint y, u16 *buf,
> +                     size_t buflen)
> +{
> +       struct ihs_video_out_ops *ops = ihs_video_out_get_ops(dev);
> +
> +       return ops->set_mem(dev, x, y, buf, buflen);
> +}
> +
> +int video_out_set_control(struct udevice *dev, u16 value)
> +{
> +       struct ihs_video_out_ops *ops = ihs_video_out_get_ops(dev);
> +
> +       return ops->set_control(dev, value);
> +}
> +
> +int video_out_set_size(struct udevice *dev, u16 xy_size, u16 x_pos, u16 y_pos)
> +{
> +       struct ihs_video_out_ops *ops = ihs_video_out_get_ops(dev);
> +
> +       return ops->set_size(dev, xy_size, x_pos, y_pos);
> +}
> +
> +void print_info(struct udevice *dev)
> +{
> +       struct ihs_video_out_priv *priv = dev_get_priv(dev);
> +       struct gdsys_soc_child_platdata *pplat = dev_get_parent_platdata(dev);
> +       u16 version;
> +       u16 features;
> +       u16 control = 0x49;
> +
> +       version = fpga_in_le16(pplat->fpga, priv->osd_base + REG_VERSION);
> +       features = fpga_in_le16(pplat->fpga, priv->osd_base + REG_FEATURES);
> +
> +       if (priv->sync_src)
> +               control |= ((priv->sync_src & 0x7) << 8);
> +
> +       fpga_out_le16(pplat->fpga, priv->osd_base + REG_CONTROL, control);
> +
> +       priv->base_width = ((features & 0x3f00) >> 8) + 1;
> +       priv->base_height = (features & 0x001f) + 1;
> +
> +       printf("OSD-%s: Digital-OSD version %01d.%02d, %d x %d characters\n",
> +              dev->name, version / 100, version % 100,
> +              priv->base_width, priv->base_height);
> +}
> +
> +int ihs_video_out_get_data(struct udevice *dev, struct ihs_video_out_data *data)
> +{
> +       struct ihs_video_out_priv *priv = dev_get_priv(dev);
> +
> +       data->width = priv->base_width;
> +       data->height = priv->base_height;
> +
> +       return 0;
> +}
> +
> +int ihs_video_out_set_mem(struct udevice *dev, uint x, uint y, u16 *buf,
> +                         size_t buflen)
> +{
> +       struct ihs_video_out_priv *priv = dev_get_priv(dev);
> +       struct gdsys_soc_child_platdata *pplat = dev_get_parent_platdata(dev);
> +       uint offset = y * priv->base_width + x;
> +       uint k;
> +
> +       for (k = 0; k < buflen; ++k) {
> +               if (offset + k >= priv->base_width * priv->base_height)
> +                       return -ENXIO;
> +
> +               fpga_out_le16(pplat->fpga,
> +                             priv->osd_buffer_base + offset + k, buf[k]);
> +       }
> +
> +       return buflen;
> +}
> +
> +int ihs_video_out_set_control(struct udevice *dev, u16 value)
> +{
> +       struct ihs_video_out_priv *priv = dev_get_priv(dev);
> +       struct gdsys_soc_child_platdata *pplat = dev_get_parent_platdata(dev);
> +
> +       fpga_out_le16(pplat->fpga, priv->addr + REG_CONTROL, value);
> +
> +       return 0;
> +}
> +
> +int ihs_video_out_set_size(struct udevice *dev, u16 xy_size,
> +                          u16 x_pos, u16 y_pos)
> +{
> +       struct ihs_video_out_priv *priv = dev_get_priv(dev);
> +       struct gdsys_soc_child_platdata *pplat = dev_get_parent_platdata(dev);
> +
> +       fpga_out_le16(pplat->fpga, priv->addr + REG_XY_SIZE, xy_size);
> +       fpga_out_le16(pplat->fpga, priv->addr + REG_X_POS, x_pos);
> +       fpga_out_le16(pplat->fpga, priv->addr + REG_Y_POS, y_pos);
> +
> +       return 0;
> +}
> +
> +static const struct ihs_video_out_ops ihs_video_out_ops = {
> +       .get_data = ihs_video_out_get_data,
> +       .set_mem = ihs_video_out_set_mem,
> +       .set_control = ihs_video_out_set_control,
> +       .set_size = ihs_video_out_set_size,
> +};
> +
> +int ihs_video_out_probe(struct udevice *dev)
> +{
> +       struct ihs_video_out_priv *priv = dev_get_priv(dev);
> +       int len = 0;
> +       struct fdtdec_phandle_args phandle_args;
> +       char *mode;
> +
> +       priv->addr = fdtdec_get_int(gd->fdt_blob, dev_of_offset(dev),
> +                                   "reg", -1);

Can we use dev_read_...() API?

> +
> +       priv->osd_base = fdtdec_get_int(gd->fdt_blob, dev_of_offset(dev),
> +                                       "osd_base", -1);
> +
> +       priv->osd_buffer_base = fdtdec_get_int(gd->fdt_blob, dev_of_offset(dev),
> +                                              "osd_buffer_base", -1);
> +
> +       priv->sync_src = fdtdec_get_bool(gd->fdt_blob, dev_of_offset(dev),
> +                       "sync-source");
> +
> +       print_info(dev);
> +
> +       if (fdtdec_parse_phandle_with_args(gd->fdt_blob, dev_of_offset(dev),
> +                                          "clk_gen", NULL, 0, 0,
> +                                          &phandle_args)) {
> +               printf("%s: Could not get clk_gen node.\n", dev->name);
> +               return -1;

These should return -EINVAL I think.

> +       }
> +
> +       if (device_get_global_by_of_offset(phandle_args.node, &priv->clk_gen)) {
> +               printf("%s: Could not get clk_gen dev.\n", dev->name);
> +               return -1;
> +       }
> +
> +       if (fdtdec_parse_phandle_with_args(gd->fdt_blob, dev_of_offset(dev),
> +                                          "dp_tx", NULL, 0, 0,
> +                                          &phandle_args)) {
> +               printf("%s: Could not get dp_tx.\n", dev->name);
> +               return -1;
> +       }
> +
> +       if (device_get_global_by_of_offset(phandle_args.node, &priv->dp_tx)) {
> +               printf("%s: Could not get dp_tx dev.\n", dev->name);
> +               return -1;
> +       }
> +
> +       mode = (char *)fdt_getprop(gd->fdt_blob, dev_of_offset(dev),
> +                                  "mode", &len);
> +
> +       if (!mode) {
> +               printf("%s: Could not read mode property.\n", dev->name);
> +               return -1;
> +       }
> +
> +       if (!strcmp(mode, "1024_768_60"))
> +               priv->sync_src = 2;
> +       else if (!strcmp(mode, "720_400_70"))
> +               priv->sync_src = 1;
> +       else
> +               priv->sync_src = 0;
> +
> +       transmitter_power_on(priv->dp_tx, mode);
> +
> +       return 0;
> +}
> +
> +U_BOOT_DRIVER(ihs_video_out_drv) = {
> +       .name           = "ihs_video_out_drv",
> +       .id             = UCLASS_IHS_VIDEO_OUT,
> +       .ops            = &ihs_video_out_ops,
> +       .of_match       = ihs_video_out_ids,
> +       .probe          = ihs_video_out_probe,
> +       .priv_auto_alloc_size = sizeof(struct ihs_video_out_priv),
> +};
> diff --git a/include/dm/uclass-id.h b/include/dm/uclass-id.h
> index 1a24de10b4..a40185d2bb 100644
> --- a/include/dm/uclass-id.h
> +++ b/include/dm/uclass-id.h
> @@ -44,6 +44,7 @@ enum uclass_id {
>         UCLASS_I2C_MUX,         /* I2C multiplexer */
>         UCLASS_IHS_AXI,         /* gdsys IHS AXI bus */
>         UCLASS_IHS_FPGA,        /* gdsys IHS FPGAs */
> +       UCLASS_IHS_VIDEO_OUT,   /* gdsys IHS video output */

Is this video out? It seems to me it is more about an on-screen
display/ So how about a new uclass like VIDEO_OSD?

Then you can make it generic so that other drivers might use it. Your
operations don't seem too specific to this driver...?

>         UCLASS_IRQ,             /* Interrupt controller */
>         UCLASS_KEYBOARD,        /* Keyboard input device */
>         UCLASS_LED,             /* Light-emitting diode (LED) */
> diff --git a/include/ihs_video_out.h b/include/ihs_video_out.h
> new file mode 100644
> index 0000000000..e3dcdad8c5
> --- /dev/null
> +++ b/include/ihs_video_out.h
> @@ -0,0 +1,146 @@
> +/*
> + * (C) Copyright 2017
> + * Mario Six,  Guntermann & Drunck GmbH, mario.six at gdsys.cc
> + *
> + * SPDX-License-Identifier:    GPL-2.0+
> + */
> +
> +#ifndef _IHS_VIDEO_OUT_H_
> +#define _IHS_VIDEO_OUT_H_
> +
> +/*
> + * The IHS OSD is a character-oriented on-screen display of gdsys devices built
> + * into a IHS FPGA. It is controlled via a set of registers in the FPGA's
> + * register space, as well as a memory buffer that holds character data
> + * (line-wise, left-to-right, 16 bit per character) that constitute the data to
> + * be displayed by the OSD.
> + */
> +
> +/**
> + * struct ihs_video_out_data - information about a IHS OSD instance
> + *
> + * @width      Maximum width of the OSD screen in characters.
> + * @heigth     Maximum height of the OSD screen in characters.
> + */
> +struct ihs_video_out_data {
> +       uint width;
> +       uint height;
> +};
> +
> +/**
> + * struct ihs_video_out_ops - driver operations for IHS OSD 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 ihs_video_out_ops {
> +       /**
> +        * get_data() - Get information about a IHS OSD instance
> +        *
> +        * A IHS OSD instance keeps some internal data about itself. This
> +        * function can be used to access this data.
> +        *
> +        * @dev:        IHS OSD instance to query.
> +        * @data:       Pointer to a struct ihs_video_out_data structure that
> +        *              takes the information read from the OSD instance.
> +        * @return 0 if OK, -ve on error.
> +        */
> +       int (*get_data)(struct udevice *dev, struct ihs_video_out_data *data);
> +
> +       /**
> +        * set_mem() - Write pixel data to OSD memory
> +        *
> +        * Each 16 bit word of data encodes the display information for a
> +        * single character. The data are written to a given character position
> +        * (x/y coordinates), which are written left-to-right, line-wise,
> +        * continuing to the next line if the data are longer than the current
> +        * line.
> +        *
> +        * @dev:        IHS OSD instance to query.

query?

> +        * @x:          Horizontal character coordinate to write to.
> +        * @y:          Vertical character coordinate to write to.
> +        * @buf:        Array containing 16 bit words to write to the specified
> +        *              address in the IHS OSD memory.

Here I wonder if we can use a u8 * ?

> +        * @buflen:     Length of the data in the passed buffer (in 16 bit
> +        *              words).
> +        * @return 0 if OK, -ve on error.
> +        */
> +       int (*set_mem)(struct udevice *dev, uint x, uint y, u16 *buf, size_t buflen);
> +
> +       /**
> +        * set_control() - Set the value of the IHS OSD's control register
> +        *
> +        * @dev:        IHS OSD instance to write to.
> +        * @value:      Value to write to the IHS OSD's control register.
> +        * @return 0 if OK, -ve on error.
> +        */
> +       int (*set_control)(struct udevice *dev, u16 value);
> +
> +       /**
> +        * set_size() - Set the position and dimension of the IHS OSD's
> +        *              writeable window
> +        *
> +        * @dev:        IHS OSD instance to write to.
> +        * @xy_size:    The number of characters in a row and a column,
> +        *              combined into a 16 bit value.

Can you separate out the values?

> +        * @x_pos:      The horizontal position of the upper left corner of the
> +        *              OSD's writeable window in pixels.
> +        * @y_pos:      The vertical position of the upper left corner of the
> +        *              OSD's writeable window in pixels.
> +        * @return 0 if OK, -ve on error.
> +        */
> +       int (*set_size)(struct udevice *dev, u16 xy_size, u16 x_pos, u16 y_pos);
> +};
> +
> +#define ihs_video_out_get_ops(dev)     ((struct ihs_video_out_ops *)(dev)->driver->ops)
> +
> +/**
> + * video_out_get_data() - Get information about a IHS OSD instance
> + *
> + * @dev:       IHS OSD instance to query.
> + * @data:      Pointer to a struct ihs_video_out_data structure that takes the
> + *             information read from the OSD instance.
> + * @return 0 if OK, -ve on error.
> + */
> +int video_out_get_data(struct udevice *dev, struct ihs_video_out_data *data);
> +
> +/**
> + * video_out_set_mem() - Write pixel data to OSD memory
> + *
> + * @dev:       IHS OSD instance to query.
> + * @x:         Horizontal character coordinate to write to.
> + * @y:         Vertical character coordinate to write to.
> + * @buf:       Array containing 16 bit words to write to the specified address
> + *             in the IHS OSD memory.

u8 * ?

> + * @buflen:    Length of the data in the passed buffer (in 16 bit words).
> + * @return 0 if OK, -ve on error.
> + */
> +int video_out_set_mem(struct udevice *dev, uint x, uint y, u16 *buf,
> +                     size_t buflen);
> +
> +/**
> + * video_out_set_control() - Set the value of the IHS OSD's control register
> + *
> + * @dev:       IHS OSD instance to write to.
> + * @value:     Value to write to the IHS OSD's control register.
> + * @return 0 if OK, -ve on error.
> + */
> +int video_out_set_control(struct udevice *dev, u16 value);
> +
> +/**
> + * video_out_set_size() - Set the position and dimension of the IHS OSD's
> + *                       writeable window
> + *
> + * @dev:       IHS OSD instance to write to.
> + * @xy_size:   The number of characters in a row and a column, combined into a
> + *             16 bit value.
> + * @x_pos:     The horizontal position of the upper left corner of the OSD's
> + *             writeable window in pixels.
> + * @y_pos:     The vertical position of the upper left corner of the OSD's
> + *             writeable window in pixels.
> + * @return 0 if OK, -ve on error.
> + */
> +int video_out_set_size(struct udevice *dev, u16 xy_size, u16 x_pos, u16 y_pos);
> +
> +#endif /* !_IHS_VIDEO_OUT_H_ */
> --
> 2.11.0
>

Regards,
Simon

^ permalink raw reply	[flat|nested] 138+ messages in thread

* [U-Boot] [PATCH 38/51] gdsys: drivers: Add gdsys_rxaui_ctrl driver
  2017-07-14 12:55 ` [U-Boot] [PATCH 38/51] gdsys: drivers: Add gdsys_rxaui_ctrl driver Mario Six
@ 2017-07-19  9:06   ` Simon Glass
  2017-07-25 11:41     ` Mario Six
  0 siblings, 1 reply; 138+ messages in thread
From: Simon Glass @ 2017-07-19  9:06 UTC (permalink / raw)
  To: u-boot

Hi Mario,

On 14 July 2017 at 05:55, Mario Six <mario.six@gdsys.cc> wrote:
> 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

Can we use generic PHY for this and add a few operations? Or should we
create a new phy type?

In general with DM we should not add driver-specific uclasses. There
are cases where is makes sense and it's hard to predict the future,
but you can imagine ending up with a huge number of APIs if we don't
manager to share.

Regards.
Simon

^ permalink raw reply	[flat|nested] 138+ messages in thread

* [U-Boot] [PATCH 39/51] drivers: Add gdsys_ioep driver
  2017-07-14 12:55 ` [U-Boot] [PATCH 39/51] drivers: Add gdsys_ioep driver Mario Six
@ 2017-07-19  9:06   ` Simon Glass
  2017-07-25 11:49     ` Mario Six
  0 siblings, 1 reply; 138+ messages in thread
From: Simon Glass @ 2017-07-19  9:06 UTC (permalink / raw)
  To: u-boot

Hi Mario,

On 14 July 2017 at 05:55, Mario Six <mario.six@gdsys.cc> wrote:
> Add driver for the IHS IO endpoint on IHS FPGAs.

Would UCLASS_MAILBOX work for this?

Or MISC?

>
> Signed-off-by: Mario Six <mario.six@gdsys.cc>
> ---
>
>  drivers/misc/Kconfig      |   6 +
>  drivers/misc/Makefile     |   1 +
>  drivers/misc/gdsys_ioep.c | 301 ++++++++++++++++++++++++++++++++++++++++++++++
>  include/dm/uclass-id.h    |   1 +
>  include/gdsys_ioep.h      | 196 ++++++++++++++++++++++++++++++
>  5 files changed, 505 insertions(+)
>  create mode 100644 drivers/misc/gdsys_ioep.c
>  create mode 100644 include/gdsys_ioep.h

^ permalink raw reply	[flat|nested] 138+ messages in thread

* [U-Boot] [PATCH 40/51] cmd: Add ihs osd commands
  2017-07-14 12:55 ` [U-Boot] [PATCH 40/51] cmd: Add ihs osd commands Mario Six
@ 2017-07-19  9:06   ` Simon Glass
  2017-07-25 12:01     ` Mario Six
  0 siblings, 1 reply; 138+ messages in thread
From: Simon Glass @ 2017-07-19  9:06 UTC (permalink / raw)
  To: u-boot

Hi Mario,

On 14 July 2017 at 05:55, Mario Six <mario.six@gdsys.cc> wrote:
> Add command to query information from and write text to IHS OSDs.
>
> Signed-off-by: Mario Six <mario.six@gdsys.cc>
> ---
>
>  cmd/Kconfig   |   6 +++
>  cmd/Makefile  |   1 +
>  cmd/ihs_osd.c | 167 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
>  3 files changed, 174 insertions(+)
>  create mode 100644 cmd/ihs_osd.c
>
> diff --git a/cmd/Kconfig b/cmd/Kconfig
> index 6425c425d6..b632049022 100644
> --- a/cmd/Kconfig
> +++ b/cmd/Kconfig
> @@ -933,6 +933,12 @@ config CMD_DISPLAY
>           displayed on a simple board-specific display. Implement
>           display_putc() to use it.
>
> +config CMD_IHS_OSD
> +       bool "ihs osd"
> +       help
> +         Enable the 'osd' command which allows to query information from and
> +         write text data to a gdsys OSD.
> +
>  config CMD_LED
>         bool "led"
>         default y if LED
> diff --git a/cmd/Makefile b/cmd/Makefile
> index 243f9f45d4..c30511982b 100644
> --- a/cmd/Makefile
> +++ b/cmd/Makefile
> @@ -62,6 +62,7 @@ obj-$(CONFIG_CMD_FS_GENERIC) += fs.o
>  obj-$(CONFIG_CMD_FUSE) += fuse.o
>  obj-$(CONFIG_CMD_GETTIME) += gettime.o
>  obj-$(CONFIG_CMD_GPIO) += gpio.o
> +obj-$(CONFIG_CMD_IHS_OSD) += ihs_osd.o
>  obj-$(CONFIG_CMD_I2C) += i2c.o
>  obj-$(CONFIG_CMD_IOTRACE) += iotrace.o
>  obj-$(CONFIG_CMD_HASH) += hash.o
> diff --git a/cmd/ihs_osd.c b/cmd/ihs_osd.c
> new file mode 100644
> index 0000000000..01ef3eee83
> --- /dev/null
> +++ b/cmd/ihs_osd.c
> @@ -0,0 +1,167 @@
> +/*
> + * (C) Copyright 2017
> + * Mario Six,  Guntermann & Drunck GmbH, mario.six at gdsys.cc
> + *
> + * based on the gdsys osd driver, which is
> + *
> + * (C) Copyright 2010
> + * Dirk Eibach,  Guntermann & Drunck GmbH, eibach at gdsys.de
> + *
> + * SPDX-License-Identifier:    GPL-2.0+
> + */
> +
> +#include <common.h>
> +#include <dm.h>
> +#include <dm/uclass-internal.h>
> +#include <i2c.h>
> +#include <ihs_video_out.h>
> +#include <malloc.h>
> +
> +#define MAX_VIDEOMEM_WIDTH 64
> +#define MAX_VIDEOMEM_HEIGHT 32
> +#define MAX_X_CHARS 53
> +#define MAX_Y_CHARS 26


> +
> +size_t hexstr_to_u16_array(char *hexstr, u16 *array, size_t arrsize)
> +{
> +       size_t pos;
> +
> +       for (pos = 0; pos < arrsize; ++pos) {
> +               char substr[5];
> +
> +               memcpy(substr, hexstr, 4);
> +               substr[4] = 0;
> +               *array = simple_strtoul(substr, NULL, 16);
> +
> +               hexstr += 4;
> +               array++;
> +               if (*hexstr == 0)
> +                       break;
> +       }
> +
> +       return pos;
> +}
> +
> +int do_osd_write(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
> +{
> +       struct udevice *dev;
> +       uint x, y;
> +       uint count;
> +       char *hexstr;
> +       u16 buffer[MAX_VIDEOMEM_WIDTH];
> +       size_t buflen;
> +
> +       if ((argc < 4) || (strlen(argv[3]) % 4)) {
> +               cmd_usage(cmdtp);
> +               return 1;
> +       }
> +
> +       x = simple_strtoul(argv[1], NULL, 16);
> +       y = simple_strtoul(argv[2], NULL, 16);
> +       hexstr = argv[3];
> +       count = (argc > 4) ? simple_strtoul(argv[4], NULL, 16) : 1;
> +
> +       buflen = hexstr_to_u16_array(hexstr, buffer, MAX_VIDEOMEM_WIDTH);
> +
> +       for (uclass_find_first_device(UCLASS_IHS_VIDEO_OUT, &dev);
> +            dev;
> +            uclass_find_next_device(&dev)) {

Why write to all devices? Perhaps you should have the concept of a
current device in this file?

> +               uint k;
> +
> +               for (k = 0; k < count; ++k)
> +                       video_out_set_mem(dev, x + k * buflen, y, buffer,
> +                                         buflen);
> +
> +               video_out_set_control(dev, 0x0049);
> +       }
> +
> +       return 0;
> +}
> +
> +static int do_osd_print(cmd_tbl_t *cmdtp, int flag, int argc,
> +                       char * const argv[])
> +{
> +       struct udevice *dev;
> +       u16 buffer[MAX_VIDEOMEM_WIDTH];
> +       uint x, y, charcount, len;
> +       u8 color;
> +       uint k;
> +       char *text;
> +
> +       if (argc < 5) {
> +               cmd_usage(cmdtp);
> +               return 1;
> +       }
> +
> +       x = simple_strtoul(argv[1], NULL, 16);
> +       y = simple_strtoul(argv[2], NULL, 16);
> +       color = simple_strtoul(argv[3], NULL, 16);
> +       text = argv[4];
> +       charcount = strlen(text);
> +       len = min(charcount, (uint)MAX_VIDEOMEM_WIDTH);
> +
> +       for (uclass_find_first_device(UCLASS_IHS_VIDEO_OUT, &dev);
> +            dev;
> +            uclass_find_next_device(&dev)) {
> +               int res;
> +
> +               for (k = 0; k < len; ++k)
> +                       buffer[k] = (text[k] << 8) | color;

This is specific to your device. If you are making a generic device
you should have something like video_osd_set_char(...k, color).

Then other drivers can implement it.

> +
> +               res = video_out_set_mem(dev, x, y, buffer, len);
> +
> +               if (res < 0)
> +                       return res;
> +
> +               video_out_set_control(dev, 0x0049);
> +       }
> +
> +       return 0;
> +}
> +
> +int do_osd_size(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
> +{
> +       struct udevice *dev;
> +       uint x, y;
> +
> +       if (argc < 3) {
> +               cmd_usage(cmdtp);
> +               return 1;
> +       }
> +
> +       x = simple_strtoul(argv[1], NULL, 16);
> +       y = simple_strtoul(argv[2], NULL, 16);
> +
> +       if (!x || (x > 64) || (x > MAX_X_CHARS) ||
> +           !y || (y > 32) || (y > MAX_Y_CHARS)) {
> +               cmd_usage(cmdtp);
> +               return 1;
> +       }
> +
> +       for (uclass_find_first_device(UCLASS_IHS_VIDEO_OUT, &dev);
> +            dev;
> +            uclass_find_next_device(&dev))
> +               video_out_set_size(dev, ((x - 1) << 8) | (y - 1),
> +                                  32767 * (640 - 12 * x) / 65535,
> +                                  32767 * (480 - 18 * x) / 65535);

Again this logic should be in the driver, not the command.

> +
> +       return 0;
> +}
> +
> +U_BOOT_CMD(
> +       osdw, 5, 0, do_osd_write,
> +       "write 16-bit hex encoded buffer to osd memory",
> +       "osd write [pos_x] [pos_y] [buffer] [count] - write 16-bit hex encoded buffer to osd memory\n"
> +);
> +
> +U_BOOT_CMD(
> +       osdp, 5, 0, do_osd_print,
> +       "write ASCII buffer to osd memory",
> +       "osd print [pos_x] [pos_y] [color] [text] - write ASCII buffer to osd memory\n"
> +);
> +
> +U_BOOT_CMD(
> +       osdsize, 3, 0, do_osd_size,
> +       "set OSD XY size in characters",
> +       "osd size [size_x] [size_y] - set OSD XY size in characters\n"
> +);
> --
> 2.11.0
>

I think this should be an 'osd' command with sub-commands.

Regards,
Simon

^ permalink raw reply	[flat|nested] 138+ messages in thread

* [U-Boot] [PATCH 41/51] cmd: Add ihs axi command
  2017-07-14 12:55 ` [U-Boot] [PATCH 41/51] cmd: Add ihs axi command Mario Six
@ 2017-07-19  9:06   ` Simon Glass
  2017-07-25  8:14     ` Mario Six
  0 siblings, 1 reply; 138+ messages in thread
From: Simon Glass @ 2017-07-19  9:06 UTC (permalink / raw)
  To: u-boot

On 14 July 2017 at 05:55, Mario Six <mario.six@gdsys.cc> wrote:
> Add a command to debug the IHS AXI bus.
>
> Signed-off-by: Mario Six <mario.six@gdsys.cc>
> ---
>
>  cmd/Kconfig   |   5 ++
>  cmd/Makefile  |   2 +
>  cmd/ihs_axi.c | 257 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
>  3 files changed, 264 insertions(+)
>  create mode 100644 cmd/ihs_axi.c

Reviewed-by: Simon Glass <sjg@chromium.org>

nits below

>
> diff --git a/cmd/Kconfig b/cmd/Kconfig
> index b632049022..4bbe9d435c 100644
> --- a/cmd/Kconfig
> +++ b/cmd/Kconfig
> @@ -753,6 +753,11 @@ config CMD_SATA
>           Attachment, where AT refers to an IBM AT (Advanced Technology)
>           computer released in 1984.
>
> +config CMD_IHS_AXI
> +       bool "axi"
> +       help
> +         Enable the GDSYS IHS AXI command for accessing the AXI bus.

Can we make this help generic?

depends on AXI


> +
>  endmenu
>
>
> diff --git a/cmd/Makefile b/cmd/Makefile
> index c30511982b..0baaf76b47 100644
> --- a/cmd/Makefile
> +++ b/cmd/Makefile
> @@ -144,6 +144,8 @@ obj-$(CONFIG_CMD_DFU) += dfu.o
>  obj-$(CONFIG_CMD_GPT) += gpt.o
>  obj-$(CONFIG_CMD_ETHSW) += ethsw.o
>
> +obj-$(CONFIG_CMD_IHS_AXI) += ihs_axi.o
> +
>  # Power
>  obj-$(CONFIG_CMD_PMIC) += pmic.o
>  obj-$(CONFIG_CMD_REGULATOR) += regulator.o
> diff --git a/cmd/ihs_axi.c b/cmd/ihs_axi.c
> new file mode 100644
> index 0000000000..336c239fae
> --- /dev/null
> +++ b/cmd/ihs_axi.c
> @@ -0,0 +1,257 @@
> +/*
> + * (C) Copyright 2016
> + * Dirk Eibach,  Guntermann & Drunck GmbH, dirk.eibach at gdsys.cc
> + *
> + * (C) Copyright 2017
> + * Mario Six,  Guntermann & Drunck GmbH, mario.six at gdsys.cc
> + *
> + * SPDX-License-Identifier:    GPL-2.0+
> + */
> +
> +#include <common.h>
> +#include <dm.h>
> +#include <command.h>
> +#include <console.h>
> +#include <ihs_axi.h>
> +
> +static struct udevice *axi_cur_bus;
> +static uint dp_last_addr;
> +static uint dp_last_length = 0x40;
> +
> +static void show_bus(struct udevice *bus)
> +{
> +       struct udevice *dev;
> +
> +       printf("Bus %d:\t%s", bus->req_seq, bus->name);
> +       if (device_active(bus))
> +               printf("  (active %d)", bus->seq);
> +       printf("\n");
> +       for (device_find_first_child(bus, &dev);
> +            dev;
> +            device_find_next_child(&dev)) {
> +               //struct dm_i2c_chip *chip = dev_get_parent_platdata(dev);
> +
> +               //printf("   %02x: %s, offset len %x, flags %x\n",
> +                      //chip->chip_addr, dev->name, chip->offset_len,
> +                      //chip->flags);

debug() ?

> +               printf("  %s\n", dev->name);
> +       }
> +}
> +
> +static int do_axi_show_bus(cmd_tbl_t *cmdtp, int flag, int argc,
> +                          char * const argv[])
> +{
> +       if (argc == 1) {
> +               /* show all busses */
> +               struct udevice *bus;
> +               struct uclass *uc;
> +               int ret;
> +
> +               ret = uclass_get(UCLASS_IHS_AXI, &uc);
> +               if (ret)
> +                       return CMD_RET_FAILURE;
> +               uclass_foreach_dev(bus, uc)
> +                       show_bus(bus);
> +       } else {
> +               int i;
> +
> +               /* show specific bus */
> +               i = simple_strtoul(argv[1], NULL, 10);
> +
> +               struct udevice *bus;
> +               int ret;
> +
> +               ret = uclass_get_device_by_seq(UCLASS_IHS_AXI, i, &bus);

This is fine, but note that above you may be looking at buses that are
not probed (since you use the find API). Here the device will be
probed.

> +               if (ret) {
> +                       printf("Invalid bus %d: err=%d\n", i, ret);
> +                       return CMD_RET_FAILURE;
> +               }
> +               show_bus(bus);
> +       }
> +
> +       return 0;
> +}
> +
> +static int cmd_axi_set_bus_num(unsigned int busnum)
> +{
> +       struct udevice *bus;
> +       int ret;
> +
> +       ret = uclass_get_device_by_seq(UCLASS_IHS_AXI, busnum, &bus);
> +       if (ret) {
> +               debug("%s: No bus %d\n", __func__, busnum);
> +               return ret;
> +       }
> +       axi_cur_bus = bus;
> +
> +       return 0;
> +}
> +
> +static int axi_get_cur_bus(struct udevice **busp)
> +{
> +       if (!axi_cur_bus) {
> +               puts("No AXI bus selected\n");
> +               return ENODEV;
> +       }
> +       *busp = axi_cur_bus;
> +
> +       return 0;
> +}
> +
> +static int do_axi_bus_num(cmd_tbl_t *cmdtp, int flag, int argc,
> +                         char * const argv[])
> +{
> +       int             ret = 0;
> +       int     bus_no;
> +
> +       if (argc == 1) {
> +               /* querying current setting */
> +               struct udevice *bus;
> +
> +               if (!axi_get_cur_bus(&bus))
> +                       bus_no = bus->seq;
> +               else
> +                       bus_no = -1;
> +               printf("Current bus is %d\n", bus_no);
> +       } else {
> +               bus_no = simple_strtoul(argv[1], NULL, 10);
> +               printf("Setting bus to %d\n", bus_no);
> +
> +               ret = cmd_axi_set_bus_num(bus_no);
> +
> +               if (ret)
> +                       printf("Failure changing bus number (%d)\n", ret);
> +       }
> +
> +       return ret ? CMD_RET_FAILURE : 0;
> +}
> +
> +#define DISP_LINE_LEN  16
> +
> +int do_axi_md(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
> +{
> +       unsigned int k;
> +       ulong   addr, length;
> +       int rc = 0;
> +       u32 linebuf[DISP_LINE_LEN / sizeof(u32)];
> +       ulong nbytes;
> +
> +       /*
> +        * We use the last specified parameters, unless new ones are
> +        * entered.
> +        */
> +       addr = dp_last_addr;
> +       length = dp_last_length;
> +
> +       if (argc < 2)
> +               return CMD_RET_USAGE;
> +
> +       if (!axi_cur_bus) {
> +               puts("No AXI bus selected\n");
> +               return ENODEV;
> +       }
> +
> +       if ((flag & CMD_FLAG_REPEAT) == 0) {
> +               /*
> +                * Address is specified since argc > 3
> +                */
> +               addr = simple_strtoul(argv[1], NULL, 16);
> +
> +               /*
> +                * If another parameter, it is the length to display.
> +                * Length is the number of objects, not number of bytes.
> +                */
> +               if (argc > 2)
> +                       length = simple_strtoul(argv[2], NULL, 16);
> +       }
> +
> +       nbytes = length * sizeof(u32);
> +       do {
> +               ulong linebytes = (nbytes > DISP_LINE_LEN) ?
> +                                 DISP_LINE_LEN : nbytes;
> +
> +               for (k = 0; k < linebytes / sizeof(u32); ++k)
> +                       axi_read(axi_cur_bus, addr + k * sizeof(u32),
> +                                &linebuf[k]);
> +               print_buffer(addr, (void *)linebuf, sizeof(u32),
> +                            linebytes / sizeof(u32),
> +                            DISP_LINE_LEN / sizeof(u32));
> +
> +               nbytes -= linebytes;
> +               addr += linebytes;
> +               if (ctrlc()) {
> +                       rc = 1;
> +                       break;
> +               }
> +       } while (nbytes > 0);
> +
> +       dp_last_addr = addr;
> +       dp_last_length = length;
> +
> +       return rc;
> +}
> +
> +static int do_axi_mw(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
> +{
> +       u32 writeval;
> +       ulong addr, count;
> +
> +       if ((argc < 3) || (argc > 4))
> +               return CMD_RET_USAGE;
> +
> +       /* Address is specified since argc > 3 */
> +       addr = simple_strtoul(argv[1], NULL, 16);
> +
> +       /* Get the value to write.  */
> +       writeval = simple_strtoul(argv[2], NULL, 16);
> +
> +       /* Count ? */
> +       if (argc == 4)
> +               count = simple_strtoul(argv[3], NULL, 16);
> +       else
> +               count = 1;
> +
> +       while (count-- > 0)
> +               axi_write(axi_cur_bus, addr + count * sizeof(u32), writeval);

Error check

> +
> +       return 0;
> +}
> +
> +static cmd_tbl_t cmd_axi_sub[] = {
> +       U_BOOT_CMD_MKENT(bus, 1, 1, do_axi_show_bus, "", ""),
> +       U_BOOT_CMD_MKENT(dev, 1, 1, do_axi_bus_num, "", ""),
> +       U_BOOT_CMD_MKENT(md, 3, 1, do_axi_md, "", ""),
> +       U_BOOT_CMD_MKENT(mw, 4, 1, do_axi_mw, "", ""),
> +};
> +
> +static int do_ihs_axi(cmd_tbl_t *cmdtp, int flag, int argc,
> +                     char * const argv[])
> +{
> +       cmd_tbl_t *c;
> +
> +       if (argc < 2)
> +               return CMD_RET_USAGE;
> +
> +       /* Strip off leading 'axi' command argument */
> +       argc--;
> +       argv++;
> +
> +       c = find_cmd_tbl(argv[0], &cmd_axi_sub[0], ARRAY_SIZE(cmd_axi_sub));
> +
> +       if (c)
> +               return c->cmd(cmdtp, flag, argc, argv);
> +       else
> +               return CMD_RET_USAGE;
> +}
> +
> +static char axi_help_text[] =
> +       "bus  - show AXI bus info\n"
> +       "axi dev [dev] - show or set current AXI bus\n"
> +       "axi md address [# of objects] - read from AXI device\n"
> +       "axi mw address value [count] - write to AXI device (fill)\n";
> +
> +U_BOOT_CMD(
> +       axi, 7, 1, do_ihs_axi,
> +       "AXI sub-system",
> +       axi_help_text
> +);
> --
> 2.11.0
>

Regards,
Simon

^ permalink raw reply	[flat|nested] 138+ messages in thread

* [U-Boot] [PATCH 42/51] cmd: Add ihs fpga command
  2017-07-14 12:55 ` [U-Boot] [PATCH 42/51] cmd: Add ihs fpga command Mario Six
@ 2017-07-19  9:06   ` Simon Glass
  2017-07-25 12:33     ` Mario Six
  0 siblings, 1 reply; 138+ messages in thread
From: Simon Glass @ 2017-07-19  9:06 UTC (permalink / raw)
  To: u-boot

Hi Mario,

On 14 July 2017 at 05:55, Mario Six <mario.six@gdsys.cc> wrote:
> Add a comman to debug the IHS FPGA's bus.
>
> Signed-off-by: Mario Six <mario.six@gdsys.cc>
> ---
>
>  cmd/Kconfig    |   5 ++
>  cmd/Makefile   |   1 +
>  cmd/ihs_fpga.c | 269 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
>  3 files changed, 275 insertions(+)
>  create mode 100644 cmd/ihs_fpga.c

This should be more generic as per the driver - e.g. a read/write()
method that supports an access size parameter.

Is there any way we can make some of the code common with things like 'md'?

>
> diff --git a/cmd/Kconfig b/cmd/Kconfig
> index 4bbe9d435c..6d13c681cb 100644
> --- a/cmd/Kconfig
> +++ b/cmd/Kconfig
> @@ -753,6 +753,11 @@ config CMD_SATA
>           Attachment, where AT refers to an IBM AT (Advanced Technology)
>           computer released in 1984.
>
> +config CMD_IHS_FPGA
> +       bool "fpga"
> +       help
> +         Enable the GDSYS IHS FPGA command for accessing the FPGA's regisers.
> +

Regards,
Simon

^ permalink raw reply	[flat|nested] 138+ messages in thread

* [U-Boot] [PATCH 43/51] gdsys: cmd_ioloop: Fix style violations
  2017-07-14 12:55 ` [U-Boot] [PATCH 43/51] gdsys: cmd_ioloop: Fix style violations Mario Six
@ 2017-07-19  9:06   ` Simon Glass
  0 siblings, 0 replies; 138+ messages in thread
From: Simon Glass @ 2017-07-19  9:06 UTC (permalink / raw)
  To: u-boot

On 14 July 2017 at 05:55, Mario Six <mario.six@gdsys.cc> wrote:
> Fix some style violations in the ioloop command, and make the code more
> readable where possible.
>
> Signed-off-by: Mario Six <mario.six@gdsys.cc>
> ---
>
>  board/gdsys/common/cmd_ioloop.c | 78 ++++++++++++++++++++---------------------
>  1 file changed, 38 insertions(+), 40 deletions(-)

Reviewed-by: Simon Glass <sjg@chromium.org>

^ permalink raw reply	[flat|nested] 138+ messages in thread

* [U-Boot] [PATCH 44/51] gdsys: cmd_ioloop: Introduce commenting enum
  2017-07-14 12:55 ` [U-Boot] [PATCH 44/51] gdsys: cmd_ioloop: Introduce commenting enum Mario Six
@ 2017-07-19  9:06   ` Simon Glass
  0 siblings, 0 replies; 138+ messages in thread
From: Simon Glass @ 2017-07-19  9:06 UTC (permalink / raw)
  To: u-boot

On 14 July 2017 at 05:55, Mario Six <mario.six@gdsys.cc> wrote:
> Replace the boolean parameter of io_check_status that controls whether
> the status is printed or not with a documenting enum.
>
> Signed-off-by: Mario Six <mario.six@gdsys.cc>
> ---
>
>  board/gdsys/common/cmd_ioloop.c | 13 +++++++++----
>  1 file changed, 9 insertions(+), 4 deletions(-)

Reviewed-by: Simon Glass <sjg@chromium.org>

^ permalink raw reply	[flat|nested] 138+ messages in thread

* [U-Boot] [PATCH 45/51] gdsys: cmd_ioloop: Make DM compatible
  2017-07-14 12:55 ` [U-Boot] [PATCH 45/51] gdsys: cmd_ioloop: Make DM compatible Mario Six
@ 2017-07-19  9:06   ` Simon Glass
  0 siblings, 0 replies; 138+ messages in thread
From: Simon Glass @ 2017-07-19  9:06 UTC (permalink / raw)
  To: u-boot

On 14 July 2017 at 05:55, Mario Six <mario.six@gdsys.cc> wrote:
> Make the ioloop command DM compatible, while keeping the old
> functionality for not-yet-converted boards.
>
> Signed-off-by: Mario Six <mario.six@gdsys.cc>
> ---
>
>  board/gdsys/common/cmd_ioloop.c | 241 ++++++++++++++++++++++++++++++++++++++--
>  1 file changed, 234 insertions(+), 7 deletions(-)

Reviewed-by: Simon Glass <sjg@chromium.org>

^ permalink raw reply	[flat|nested] 138+ messages in thread

* [U-Boot] [PATCH 46/51] ihs_mdio: Add support to force clause45 access
  2017-07-14 12:55 ` [U-Boot] [PATCH 46/51] ihs_mdio: Add support to force clause45 access Mario Six
@ 2017-07-19  9:06   ` Simon Glass
  0 siblings, 0 replies; 138+ messages in thread
From: Simon Glass @ 2017-07-19  9:06 UTC (permalink / raw)
  To: u-boot

On 14 July 2017 at 05:55, Mario Six <mario.six@gdsys.cc> wrote:
> Add support to ihs_mdio to force clause 45 access (in addition to
> clause 22 access).
>
> Signed-off-by: Mario Six <mario.six@gdsys.cc>
> ---
>
>  board/gdsys/common/ihs_mdio.c | 26 +++++++++++++++++++++++---
>  board/gdsys/common/ihs_mdio.h |  1 +
>  2 files changed, 24 insertions(+), 3 deletions(-)

Reviewed-by: Simon Glass <sjg@chromium.org>

^ permalink raw reply	[flat|nested] 138+ messages in thread

* [U-Boot] [PATCH 47/51] ihs_mdio: Fix style violations
  2017-07-14 12:55 ` [U-Boot] [PATCH 47/51] ihs_mdio: Fix style violations Mario Six
@ 2017-07-19  9:06   ` Simon Glass
  0 siblings, 0 replies; 138+ messages in thread
From: Simon Glass @ 2017-07-19  9:06 UTC (permalink / raw)
  To: u-boot

On 14 July 2017 at 05:55, Mario Six <mario.six@gdsys.cc> wrote:
> Fix some style violations in the ihs_mdio driver, and make the code more
> readable where possible.
>
> Signed-off-by: Mario Six <mario.six@gdsys.cc>
> ---
>
>  board/gdsys/common/ihs_mdio.c | 10 +++++++---
>  1 file changed, 7 insertions(+), 3 deletions(-)

Reviewed-by: Simon Glass <sjg@chromium.org>

^ permalink raw reply	[flat|nested] 138+ messages in thread

* [U-Boot] [PATCH 48/51] ihs_mdio: Make DM-compatible
  2017-07-14 12:55 ` [U-Boot] [PATCH 48/51] ihs_mdio: Make DM-compatible Mario Six
@ 2017-07-19  9:06   ` Simon Glass
  0 siblings, 0 replies; 138+ messages in thread
From: Simon Glass @ 2017-07-19  9:06 UTC (permalink / raw)
  To: u-boot

On 14 July 2017 at 05:55, Mario Six <mario.six@gdsys.cc> wrote:
> Make the ihs_mdio driver DM-compatible, while retaining the old
> functionality for not-yet-converted boards.
>
> Signed-off-by: Mario Six <mario.six@gdsys.cc>
> ---
>
>  board/gdsys/common/ihs_mdio.c | 49 ++++++++++++++++++++++++++++++++++++++-----
>  board/gdsys/common/ihs_mdio.h |  5 +++++
>  2 files changed, 49 insertions(+), 5 deletions(-)
>

As before I think the FPGA API should change a little but otherwise:

Reviewed-by: Simon Glass <sjg@chromium.org>

^ permalink raw reply	[flat|nested] 138+ messages in thread

* [U-Boot] [PATCH 49/51] gazerbeam: Import Linux DT
  2017-07-14 12:55 ` [U-Boot] [PATCH 49/51] gazerbeam: Import Linux DT Mario Six
@ 2017-07-19  9:07   ` Simon Glass
  0 siblings, 0 replies; 138+ messages in thread
From: Simon Glass @ 2017-07-19  9:07 UTC (permalink / raw)
  To: u-boot

On 14 July 2017 at 05:55, Mario Six <mario.six@gdsys.cc> wrote:
> Import the Linux device tree for the Gazerbeam board.
>
> Signed-off-by: Mario Six <mario.six@gdsys.cc>
> ---
>
>  arch/powerpc/dts/gazerbeam.dts             | 539 +++++++++++++++++++++++++++++
>  arch/powerpc/dts/gdsys/gazerbeam-base.dtsi | 205 +++++++++++
>  arch/powerpc/dts/gdsys/mpc8308.dtsi        | 243 +++++++++++++
>  3 files changed, 987 insertions(+)
>  create mode 100644 arch/powerpc/dts/gazerbeam.dts
>  create mode 100644 arch/powerpc/dts/gdsys/gazerbeam-base.dtsi
>  create mode 100644 arch/powerpc/dts/gdsys/mpc8308.dtsi

Reviewed-by: Simon Glass <sjg@chromium.org>

^ permalink raw reply	[flat|nested] 138+ messages in thread

* [U-Boot] [PATCH 50/51] gazerbeam: Add u-boot specific dts include file
  2017-07-14 12:55 ` [U-Boot] [PATCH 50/51] gazerbeam: Add u-boot specific dts include file Mario Six
@ 2017-07-19  9:07   ` Simon Glass
  0 siblings, 0 replies; 138+ messages in thread
From: Simon Glass @ 2017-07-19  9:07 UTC (permalink / raw)
  To: u-boot

On 14 July 2017 at 05:55, Mario Six <mario.six@gdsys.cc> wrote:
> Add a U-Boot specific dts file, which encapsulates the needed
> modifications to the Gazerbeam Linux device tree.
>
> Signed-off-by: Mario Six <mario.six@gdsys.cc>
> ---
>
>  arch/powerpc/dts/gazerbeam.dts              |   2 +
>  arch/powerpc/dts/gdsys/gazerbeam-uboot.dtsi | 192 ++++++++++++++++++++++++++++
>  2 files changed, 194 insertions(+)
>  create mode 100644 arch/powerpc/dts/gdsys/gazerbeam-uboot.dtsi

Reviewed-by: Simon Glass <sjg@chromium.org>

^ permalink raw reply	[flat|nested] 138+ messages in thread

* [U-Boot] [PATCH 51/51] mpc83xx: Add gazerbeam board
  2017-07-14 12:55 ` [U-Boot] [PATCH 51/51] mpc83xx: Add gazerbeam board Mario Six
@ 2017-07-19  9:07   ` Simon Glass
  2017-07-26  8:24     ` Mario Six
  0 siblings, 1 reply; 138+ messages in thread
From: Simon Glass @ 2017-07-19  9:07 UTC (permalink / raw)
  To: u-boot

Hi Mario,

On 14 July 2017 at 05:55, Mario Six <mario.six@gdsys.cc> wrote:
> From: Dirk Eibach <dirk.eibach@gdsys.cc>
>
> The gdsys gazerbeam board is based on a Freescale MPC8308 SOC.
> It boots from NOR-Flash, kernel and rootfs are stored on
> SD-Card.
>
> On board peripherals include:
> - 2x 10/100 Mbit/s Ethernet (optional)
>
> Signed-off-by: Dirk Eibach <dirk.eibach@gdsys.cc>
> Signed-off-by: Mario Six <mario.six@gdsys.cc>
> ---
>
>  arch/powerpc/cpu/mpc83xx/Kconfig |   3 +
>  arch/powerpc/dts/.gitignore      |   1 +
>  arch/powerpc/dts/Makefile        |  15 +
>  board/gdsys/common/Makefile      |   1 +
>  board/gdsys/common/ioep-fpga.c   | 617 ++++++++++++++++++++++++++++++---------
>  board/gdsys/mpc8308/Kconfig      |  19 ++
>  board/gdsys/mpc8308/MAINTAINERS  |   2 +
>  board/gdsys/mpc8308/Makefile     |   1 +
>  board/gdsys/mpc8308/gazerbeam.c  | 332 +++++++++++++++++++++
>  configs/gazerbeam_defconfig      |  76 +++++
>  include/configs/gazerbeam.h      | 484 ++++++++++++++++++++++++++++++
>  include/fdt_fixup.h              |   5 +
>  12 files changed, 1416 insertions(+), 140 deletions(-)
>  create mode 100644 arch/powerpc/dts/.gitignore
>  create mode 100644 arch/powerpc/dts/Makefile
>  create mode 100644 board/gdsys/mpc8308/gazerbeam.c
>  create mode 100644 configs/gazerbeam_defconfig
>  create mode 100644 include/configs/gazerbeam.h
>
> diff --git a/arch/powerpc/cpu/mpc83xx/Kconfig b/arch/powerpc/cpu/mpc83xx/Kconfig
> index cdd21a253a..0790b47aa4 100644
> --- a/arch/powerpc/cpu/mpc83xx/Kconfig
> +++ b/arch/powerpc/cpu/mpc83xx/Kconfig
> @@ -91,6 +91,9 @@ config TARGET_STRIDER
>         bool "Support strider"
>         select SYS_FSL_ERRATUM_ESDHC111
>
> +config TARGET_GAZERBEAM
> +       bool "Support gazerbeam"

Need description of the board, URL, etc.

> +
>  endchoice
>
>  source "board/esd/vme8349/Kconfig"
> diff --git a/arch/powerpc/dts/.gitignore b/arch/powerpc/dts/.gitignore
> new file mode 100644
> index 0000000000..b60ed208c7
> --- /dev/null
> +++ b/arch/powerpc/dts/.gitignore
> @@ -0,0 +1 @@
> +*.dtb
> diff --git a/arch/powerpc/dts/Makefile b/arch/powerpc/dts/Makefile
> new file mode 100644
> index 0000000000..7a0c61ffaa
> --- /dev/null
> +++ b/arch/powerpc/dts/Makefile
> @@ -0,0 +1,15 @@
> +#
> +# SPDX-License-Identifier:      GPL-2.0+
> +#
> +
> +dtb-$(CONFIG_TARGET_GAZERBEAM) += gazerbeam.dtb
> +
> +targets += $(dtb-y)
> +
> +DTC_FLAGS += -R 4 -p 0x1000
> +
> +PHONY += dtbs
> +dtbs: $(addprefix $(obj)/, $(dtb-y))
> +        @:
> +
> +clean-files := *.dtb

These two files should be added along with your DT I think, not in
this patch. Your board patch should just add the dtb-$(CONFIG... line
above.

> diff --git a/board/gdsys/common/Makefile b/board/gdsys/common/Makefile
> index 6f2fea207f..52561db2e1 100644
> --- a/board/gdsys/common/Makefile
> +++ b/board/gdsys/common/Makefile
> @@ -13,3 +13,4 @@ obj-$(CONFIG_STRIDER) += mclink.o dp501.o phy.o ioep-fpga.o adv7611.o ch7301.o
>  obj-$(CONFIG_STRIDER) += fanctrl.o
>  obj-$(CONFIG_STRIDER_CON) += osd.o
>  obj-$(CONFIG_STRIDER_CON_DP) += osd.o
> +obj-$(CONFIG_TARGET_GAZERBEAM) += osd.o ihs_mdio.o ioep-fpga.o
> diff --git a/board/gdsys/common/ioep-fpga.c b/board/gdsys/common/ioep-fpga.c
> index a666b93445..24585672f6 100644
> --- a/board/gdsys/common/ioep-fpga.c
> +++ b/board/gdsys/common/ioep-fpga.c
> @@ -11,231 +11,568 @@
>
>  #include <gdsys_fpga.h>
>
> -enum {
> -       UNITTYPE_MAIN_SERVER = 0,
> -       UNITTYPE_MAIN_USER = 1,
> -       UNITTYPE_VIDEO_SERVER = 2,
> -       UNITTYPE_VIDEO_USER = 3,
> +enum pcb_video_type {
> +       PCB_DVI_SL,
> +       PCB_DP_165MPIX,
> +       PCB_DP_300MPIX,
> +       PCB_HDMI,
> +       PCB_DP_1_2,
> +       PCB_HDMI_2_0,
>  };
>
> -enum {
> -       UNITTYPEPCB_DVI = 0,
> -       UNITTYPEPCB_DP_165 = 1,
> -       UNITTYPEPCB_DP_300 = 2,
> -       UNITTYPEPCB_HDMI = 3,
> +enum pcb_transmission_type {
> +       PCB_CAT_1G,
> +       PCB_FIBER_3G,
> +       PCB_CAT_10G,
> +       PCB_FIBER_10G,
>  };
>
> -enum {
> -       COMPRESSION_NONE = 0,
> -       COMPRESSION_TYPE_1 = 1,
> -       COMPRESSION_TYPE_1_2 = 3,
> -       COMPRESSION_TYPE_1_2_3 = 7,
> +enum carrier_speed {
> +       CARRIER_SPEED_1G,
> +       CARRIER_SPEED_3G,
> +       CARRIER_SPEED_2_5G = CARRIER_SPEED_3G,
> +       CARRIER_SPEED_10G,
>  };
>
> -enum {
> -       AUDIO_NONE = 0,
> -       AUDIO_TX = 1,
> -       AUDIO_RX = 2,
> -       AUDIO_RXTX = 3,
> +enum ram_config {
> +       RAM_DDR2_32BIT_295MBPS,
> +       RAM_DDR3_32BIT_590MBPS,
> +       RAM_DDR3_48BIT_590MBPS,
> +       RAM_DDR3_64BIT_1800MBPS,
> +       RAM_DDR3_48BIT_1800MBPS,
>  };
>
> -enum {
> -       SYSCLK_147456 = 0,
> +enum sysclock {
> +       SYSCLK_147456,
>  };
>
> -enum {
> -       RAM_DDR2_32 = 0,
> -       RAM_DDR3_32 = 1,
> -       RAM_DDR3_48 = 2,
> +struct fpga_versions {
> +       bool video_channel;
> +       bool con_side;
> +       enum pcb_video_type pcb_video_type;
> +       enum pcb_transmission_type pcb_transmission_type;
> +       unsigned int hw_version;
>  };
>
> -enum {
> -       CARRIER_SPEED_1G = 0,
> -       CARRIER_SPEED_2_5G = 1,
> +struct fpga_features {
> +       u8 video_channels;
> +       u8 carriers;
> +       enum carrier_speed carrier_speed;
> +       enum ram_config ram_config;
> +       enum sysclock sysclock;
> +
> +       bool pcm_tx;
> +       bool pcm_rx;
> +       bool spdif_tx;
> +       bool spdif_rx;
> +       bool usb2;
> +       bool rs232;
> +       bool compression_type1;
> +       bool compression_type2;
> +       bool compression_type3;
> +       bool interlace;
> +       bool osd;
> +       bool compression_pipes;
>  };
>
> -bool ioep_fpga_has_osd(unsigned int fpga)
> +#ifdef CONFIG_SYS_FPGA_FLAVOR_GAZERBEAM
> +
> +static int get_versions(unsigned int fpga, struct fpga_versions *versions)
>  {
> -       u16 fpga_features;
> -       unsigned feature_osd;
> +       enum {
> +               VERSIONS_FPGA_VIDEO_CHANNEL = BIT(12),
> +               VERSIONS_FPGA_CON_SIDE = BIT(13),
> +               VERSIONS_FPGA_SC = BIT(14),
> +               VERSIONS_PCB_CON = BIT(9),
> +               VERSIONS_PCB_SC = BIT(8),
> +               VERSIONS_PCB_VIDEO_MASK = 0x3 << 6,
> +               VERSIONS_PCB_VIDEO_DP_1_2 = 0x0 << 6,
> +               VERSIONS_PCB_VIDEO_HDMI_2_0 = 0x1 << 6,
> +               VERSIONS_PCB_TRANSMISSION_MASK = 0x3 << 4,
> +               VERSIONS_PCB_TRANSMISSION_FIBER_10G = 0x0 << 4,
> +               VERSIONS_PCB_TRANSMISSION_CAT_10G = 0x1 << 4,
> +               VERSIONS_PCB_TRANSMISSION_FIBER_3G = 0x2 << 4,
> +               VERSIONS_PCB_TRANSMISSION_CAT_1G = 0x3 << 4,
> +               VERSIONS_HW_VER_MASK = 0xf << 0,
> +       };
> +       u16 raw_versions;
> +
> +       memset(versions, 0, sizeof(struct fpga_versions));
> +
> +       FPGA_GET_REG(fpga, versions, &raw_versions);
> +
> +       versions->video_channel = raw_versions & VERSIONS_FPGA_VIDEO_CHANNEL;
> +       versions->con_side = raw_versions & VERSIONS_FPGA_CON_SIDE;
> +
> +       switch (raw_versions & VERSIONS_PCB_VIDEO_MASK) {
> +       case VERSIONS_PCB_VIDEO_DP_1_2:
> +               versions->pcb_video_type = PCB_DP_1_2;
> +               break;
> +
> +       case VERSIONS_PCB_VIDEO_HDMI_2_0:
> +               versions->pcb_video_type = PCB_HDMI_2_0;
> +               break;
> +       }
> +
> +       switch (raw_versions & VERSIONS_PCB_TRANSMISSION_MASK) {
> +       case VERSIONS_PCB_TRANSMISSION_FIBER_10G:
> +               versions->pcb_transmission_type = PCB_FIBER_10G;
> +               break;
> +
> +       case VERSIONS_PCB_TRANSMISSION_CAT_10G:
> +               versions->pcb_transmission_type = PCB_CAT_10G;
> +               break;
> +
> +       case VERSIONS_PCB_TRANSMISSION_FIBER_3G:
> +               versions->pcb_transmission_type = PCB_FIBER_3G;
> +               break;
> +
> +       case VERSIONS_PCB_TRANSMISSION_CAT_1G:
> +               versions->pcb_transmission_type = PCB_CAT_1G;
> +               break;
> +
> +       }
>
> -       FPGA_GET_REG(0, fpga_features, &fpga_features);
> -       feature_osd = fpga_features & (1<<11);
> +       versions->hw_version = raw_versions & VERSIONS_HW_VER_MASK;
>
> -       return feature_osd;
> +       return 0;
>  }
>
> -void ioep_fpga_print_info(unsigned int fpga)
> +static int get_features(unsigned int fpga, struct fpga_features *features)
>  {
> -       u16 versions;
> -       u16 fpga_version;
> -       u16 fpga_features;
> -       unsigned unit_type;
> -       unsigned unit_type_pcb_video;
> -       unsigned feature_compression;
> -       unsigned feature_osd;
> -       unsigned feature_audio;
> -       unsigned feature_sysclock;
> -       unsigned feature_ramconfig;
> -       unsigned feature_carrier_speed;
> -       unsigned feature_carriers;
> -       unsigned feature_video_channels;
> -
> -       FPGA_GET_REG(fpga, versions, &versions);
> -       FPGA_GET_REG(fpga, fpga_version, &fpga_version);
> -       FPGA_GET_REG(fpga, fpga_features, &fpga_features);
> -
> -       unit_type = (versions & 0xf000) >> 12;
> -       unit_type_pcb_video = (versions & 0x01c0) >> 6;
> -       feature_compression = (fpga_features & 0xe000) >> 13;
> -       feature_osd = fpga_features & (1<<11);
> -       feature_audio = (fpga_features & 0x0600) >> 9;
> -       feature_sysclock = (fpga_features & 0x0180) >> 7;
> -       feature_ramconfig = (fpga_features & 0x0060) >> 5;
> -       feature_carrier_speed = fpga_features & (1<<4);
> -       feature_carriers = (fpga_features & 0x000c) >> 2;
> -       feature_video_channels = fpga_features & 0x0003;
> -
> -       switch (unit_type) {
> -       case UNITTYPE_MAIN_SERVER:
> -       case UNITTYPE_MAIN_USER:
> -               printf("Mainchannel");
> +       enum {
> +               FEATURE_SPDIF_RX = BIT(15),
> +               FEATURE_SPDIF_TX = BIT(14),
> +               FEATURE_PCM_RX = BIT(13),
> +               FEATURE_PCM_TX = BIT(12),
> +               FEATURE_RAM_MASK = GENMASK(11, 8),
> +               FEATURE_RAM_DDR2_32BIT_295MBPS = 0x0 << 8,
> +               FEATURE_RAM_DDR3_32BIT_590MBPS = 0x1 << 8,
> +               FEATURE_RAM_DDR3_48BIT_590MBPS = 0x2 << 8,
> +               FEATURE_RAM_DDR3_64BIT_1800MBPS = 0x3 << 8,
> +               FEATURE_RAM_DDR3_48BIT_1800MBPS = 0x4 << 8,
> +               FEATURE_CARRIER_SPEED_MASK = GENMASK(7, 6),
> +               FEATURE_CARRIER_SPEED_1G = 0x0 << 6,
> +               FEATURE_CARRIER_SPEED_2_5G = 0x1 << 6,
> +               FEATURE_CARRIER_SPEED_10G = 0x2 << 6,
> +               FEATURE_CARRIERS_MASK = GENMASK(5, 4),
> +               FEATURE_CARRIERS_0 = 0x0 << 4,
> +               FEATURE_CARRIERS_1 = 0x1 << 4,
> +               FEATURE_CARRIERS_2 = 0x2 << 4,
> +               FEATURE_CARRIERS_4 = 0x3 << 4,
> +               FEATURE_USB2 = BIT(3),
> +               FEATURE_VIDEOCHANNELS_MASK = GENMASK(2, 0),
> +               FEATURE_VIDEOCHANNELS_0 = 0x0 << 0,
> +               FEATURE_VIDEOCHANNELS_1 = 0x1 << 0,
> +               FEATURE_VIDEOCHANNELS_1_1 = 0x2 << 0,
> +               FEATURE_VIDEOCHANNELS_2 = 0x3 << 0,
> +       };
> +
> +       enum {
> +               EXT_FEATURE_OSD = BIT(15),
> +               EXT_FEATURE_ETHERNET = BIT(9),
> +               EXT_FEATURE_INTERLACE = BIT(8),
> +               EXT_FEATURE_RS232 = BIT(7),
> +               EXT_FEATURE_COMPRESSION_PERF_MASK = GENMASK(6, 4),
> +               EXT_FEATURE_COMPRESSION_PERF_1X = 0x0 << 4,
> +               EXT_FEATURE_COMPRESSION_PERF_2X = 0x1 << 4,
> +               EXT_FEATURE_COMPRESSION_PERF_4X = 0x2 << 4,
> +               EXT_FEATURE_COMPRESSION_TYPE1 = BIT(0),
> +               EXT_FEATURE_COMPRESSION_TYPE2 = BIT(1),
> +               EXT_FEATURE_COMPRESSION_TYPE3 = BIT(2),
> +       };
> +
> +       u16 raw_features;
> +       u16 raw_extended_features;
> +
> +       memset(features, 0, sizeof(struct fpga_features));
> +
> +       FPGA_GET_REG(fpga, fpga_features, &raw_features);
> +       FPGA_GET_REG(fpga, fpga_ext_features, &raw_extended_features);
> +
> +       switch (raw_features & FEATURE_VIDEOCHANNELS_MASK) {
> +       case FEATURE_VIDEOCHANNELS_0:
> +               features->video_channels = 0;
>                 break;
>
> -       case UNITTYPE_VIDEO_SERVER:
> -       case UNITTYPE_VIDEO_USER:
> -               printf("Videochannel");
> +       case FEATURE_VIDEOCHANNELS_1:
> +               features->video_channels = 1;
>                 break;
>
> -       default:
> -               printf("UnitType %d(not supported)", unit_type);
> +       case FEATURE_VIDEOCHANNELS_1_1:
> +       case FEATURE_VIDEOCHANNELS_2:
> +               features->video_channels = 2;
>                 break;
> -       }
> +       };
>
> -       switch (unit_type) {
> -       case UNITTYPE_MAIN_SERVER:
> -       case UNITTYPE_VIDEO_SERVER:
> -               printf(" Server");
> -               if (versions & (1<<4))
> -                       printf(" UC");
> +       switch (raw_features & FEATURE_CARRIERS_MASK) {
> +       case FEATURE_CARRIERS_0:
> +               features->carriers = 0;
>                 break;
>
> -       case UNITTYPE_MAIN_USER:
> -       case UNITTYPE_VIDEO_USER:
> -               printf(" User");
> +       case FEATURE_CARRIERS_1:
> +               features->carriers = 1;
>                 break;
>
> -       default:
> +       case FEATURE_CARRIERS_2:
> +               features->carriers = 2;
> +               break;
> +
> +       case FEATURE_CARRIERS_4:
> +               features->carriers = 4;
>                 break;
>         }
>
> -       if (versions & (1<<5))
> -               printf(" Fiber");
> -       else
> -               printf(" CAT");
> +       switch (raw_features & FEATURE_CARRIER_SPEED_MASK) {
> +       case FEATURE_CARRIER_SPEED_1G:
> +               features->carrier_speed = CARRIER_SPEED_1G;
> +               break;
> +       case FEATURE_CARRIER_SPEED_2_5G:
> +               features->carrier_speed = CARRIER_SPEED_2_5G;
> +               break;
> +       case FEATURE_CARRIER_SPEED_10G:
> +               features->carrier_speed = CARRIER_SPEED_10G;
> +               break;
> +       }
>
> -       switch (unit_type_pcb_video) {
> -       case UNITTYPEPCB_DVI:
> -               printf(" DVI,");
> +       switch (raw_features & FEATURE_RAM_MASK) {
> +       case FEATURE_RAM_DDR2_32BIT_295MBPS:
> +               features->ram_config = RAM_DDR2_32BIT_295MBPS;
>                 break;
>
> -       case UNITTYPEPCB_DP_165:
> -               printf(" DP 165MPix/s,");
> +       case FEATURE_RAM_DDR3_32BIT_590MBPS:
> +               features->ram_config = RAM_DDR3_32BIT_590MBPS;
>                 break;
>
> -       case UNITTYPEPCB_DP_300:
> -               printf(" DP 300MPix/s,");
> +       case FEATURE_RAM_DDR3_48BIT_590MBPS:
> +               features->ram_config = RAM_DDR3_48BIT_590MBPS;
>                 break;
>
> -       case UNITTYPEPCB_HDMI:
> -               printf(" HDMI,");
> +       case FEATURE_RAM_DDR3_64BIT_1800MBPS:
> +               features->ram_config = RAM_DDR3_64BIT_1800MBPS;
> +               break;
> +
> +       case FEATURE_RAM_DDR3_48BIT_1800MBPS:
> +               features->ram_config = RAM_DDR3_48BIT_1800MBPS;
>                 break;
>         }
>
> -       printf(" FPGA V %d.%02d\n       features:",
> -              fpga_version / 100, fpga_version % 100);
> +       features->pcm_tx = raw_features & FEATURE_PCM_TX;
> +       features->pcm_rx = raw_features & FEATURE_PCM_RX;
> +       features->spdif_tx = raw_features & FEATURE_SPDIF_TX;
> +       features->spdif_rx = raw_features & FEATURE_SPDIF_RX;
> +       features->usb2 = raw_features & FEATURE_USB2;
> +       features->rs232 = raw_extended_features & EXT_FEATURE_RS232;
> +       features->compression_type1 = raw_extended_features & EXT_FEATURE_COMPRESSION_TYPE1;
> +       features->compression_type2 = raw_extended_features & EXT_FEATURE_COMPRESSION_TYPE2;
> +       features->compression_type3 = raw_extended_features & EXT_FEATURE_COMPRESSION_TYPE3;
> +       features->interlace = raw_extended_features & EXT_FEATURE_INTERLACE;
> +       features->osd = raw_extended_features & EXT_FEATURE_OSD;
> +       features->compression_pipes = raw_extended_features & EXT_FEATURE_COMPRESSION_PERF_MASK;
> +
> +       return 0;
> +}
> +
> +#else
> +
> +static int get_versions(unsigned int fpga, struct fpga_versions *versions)
> +{
> +       enum {
> +               /* HW version encoding is a mess, leave it for the moment */
> +               VERSIONS_HW_VER_MASK = 0xf << 0,
> +               VERSIONS_PIX_CLOCK_GEN_IDT8N3QV01 = BIT(4),
> +               VERSIONS_SFP = BIT(5),
> +               VERSIONS_VIDEO_MASK = 0x7 << 6,
> +               VERSIONS_VIDEO_DVI = 0x0 << 6,
> +               VERSIONS_VIDEO_DP_165 = 0x1 << 6,
> +               VERSIONS_VIDEO_DP_300 = 0x2 << 6,
> +               VERSIONS_VIDEO_HDMI = 0x3 << 6,
> +               VERSIONS_UT_MASK = 0xf << 12,
> +               VERSIONS_UT_MAIN_SERVER = 0x0 << 12,
> +               VERSIONS_UT_MAIN_USER = 0x1 << 12,
> +               VERSIONS_UT_VIDEO_SERVER = 0x2 << 12,
> +               VERSIONS_UT_VIDEO_USER = 0x3 << 12,
> +       };
> +       u16 raw_versions;
> +
> +       memset(versions, 0, sizeof(struct fpga_versions));
> +
> +       FPGA_GET_REG(fpga, versions, &raw_versions);
> +
> +       switch (raw_versions & VERSIONS_UT_MASK) {
> +       case VERSIONS_UT_MAIN_SERVER:
> +               versions->video_channel = false;
> +               versions->con_side = false;
> +               break;
> +
> +       case VERSIONS_UT_MAIN_USER:
> +               versions->video_channel = false;
> +               versions->con_side = true;
> +               break;
>
> +       case VERSIONS_UT_VIDEO_SERVER:
> +               versions->video_channel = true;
> +               versions->con_side = false;
> +               break;
>
> -       switch (feature_compression) {
> -       case COMPRESSION_NONE:
> -               printf(" no compression");
> +       case VERSIONS_UT_VIDEO_USER:
> +               versions->video_channel = true;
> +               versions->con_side = true;
>                 break;
>
> -       case COMPRESSION_TYPE_1:
> -               printf(" compression type1(delta)");
> +       }
> +
> +       switch (raw_versions & VERSIONS_VIDEO_MASK) {
> +       case VERSIONS_VIDEO_DVI:
> +               versions->pcb_video_type = PCB_DVI_SL;
>                 break;
>
> -       case COMPRESSION_TYPE_1_2:
> -               printf(" compression type1(delta), type2(inline)");
> +       case VERSIONS_VIDEO_DP_165:
> +               versions->pcb_video_type = PCB_DP_165MPIX;
>                 break;
>
> -       case COMPRESSION_TYPE_1_2_3:
> -               printf(" compression type1(delta), type2(inline), type3(intempo)");
> +       case VERSIONS_VIDEO_DP_300:
> +               versions->pcb_video_type = PCB_DP_300MPIX;
>                 break;
>
> -       default:
> -               printf(" compression %d(not supported)", feature_compression);
> +       case VERSIONS_VIDEO_HDMI:
> +               versions->pcb_video_type = PCB_HDMI;
>                 break;
>         }
>
> -       printf(", %sosd", feature_osd ? "" : "no ");
> +       versions->hw_version = raw_versions & VERSIONS_HW_VER_MASK;
>
> -       switch (feature_audio) {
> -       case AUDIO_NONE:
> -               printf(", no audio");
> +       if (raw_versions & VERSIONS_SFP)
> +               versions->pcb_transmission_type = PCB_FIBER_3G;
> +       else
> +               versions->pcb_transmission_type = PCB_CAT_1G;
> +
> +       return 0;
> +}
> +
> +static int get_features(unsigned int fpga, struct fpga_features *features)
> +{
> +       enum {
> +               FEATURE_CARRIER_SPEED_2_5 = BIT(4),
> +               FEATURE_RAM_MASK = 0x7 << 5,
> +               FEATURE_RAM_DDR2_32BIT = 0x0 << 5,
> +               FEATURE_RAM_DDR3_32BIT = 0x1 << 5,
> +               FEATURE_RAM_DDR3_48BIT = 0x2 << 5,
> +               FEATURE_PCM_AUDIO_TX = BIT(9),
> +               FEATURE_PCM_AUDIO_RX = BIT(10),
> +               FEATURE_OSD = BIT(11),
> +               FEATURE_USB20 = BIT(12),
> +               FEATURE_COMPRESSION_MASK = 7 << 13,
> +               FEATURE_COMPRESSION_TYPE1 = 0x1 << 13,
> +               FEATURE_COMPRESSION_TYPE1_TYPE2 = 0x3 << 13,
> +               FEATURE_COMPRESSION_TYPE1_TYPE2_TYPE3 = 0x7 << 13,
> +       };
> +
> +       enum {
> +               EXTENDED_FEATURE_SPDIF_AUDIO_TX = BIT(0),
> +               EXTENDED_FEATURE_SPDIF_AUDIO_RX = BIT(1),
> +               EXTENDED_FEATURE_RS232 = BIT(2),
> +               EXTENDED_FEATURE_COMPRESSION_PIPES = BIT(3),
> +               EXTENDED_FEATURE_INTERLACE = BIT(4),
> +       };
> +
> +       u16 raw_features;
> +       u16 raw_extended_features;
> +
> +       memset(features, 0, sizeof(struct fpga_features));
> +
> +       FPGA_GET_REG(fpga, fpga_features, &raw_features);
> +       FPGA_GET_REG(fpga, fpga_ext_features, &raw_extended_features);
> +
> +       features->video_channels = raw_features & 0x3;
> +       features->carriers = (raw_features >> 2) & 0x3;
> +
> +       features->carrier_speed = (raw_features & FEATURE_CARRIER_SPEED_2_5)
> +               ? CARRIER_SPEED_2_5G : CARRIER_SPEED_1G;
> +
> +       switch (raw_features & FEATURE_RAM_MASK) {
> +       case FEATURE_RAM_DDR2_32BIT:
> +               features->ram_config = RAM_DDR2_32BIT_295MBPS;
>                 break;
>
> -       case AUDIO_TX:
> -               printf(", audio tx");
> +       case FEATURE_RAM_DDR3_32BIT:
> +               features->ram_config = RAM_DDR3_32BIT_590MBPS;
>                 break;
>
> -       case AUDIO_RX:
> -               printf(", audio rx");
> +       case FEATURE_RAM_DDR3_48BIT:
> +               features->ram_config = RAM_DDR3_48BIT_590MBPS;
>                 break;
> +       }
>
> -       case AUDIO_RXTX:
> -               printf(", audio rx+tx");
> +       features->pcm_tx = raw_features & FEATURE_PCM_AUDIO_TX;
> +       features->pcm_rx = raw_features & FEATURE_PCM_AUDIO_RX;
> +       features->spdif_tx = raw_extended_features & EXTENDED_FEATURE_SPDIF_AUDIO_TX;
> +       features->spdif_rx = raw_extended_features & EXTENDED_FEATURE_SPDIF_AUDIO_RX;
> +
> +       features->usb2 = raw_features & FEATURE_USB20;
> +       features->rs232 = raw_extended_features & EXTENDED_FEATURE_RS232;
> +
> +       features->compression_type1 = false;
> +       features->compression_type2 = false;
> +       features->compression_type3 = false;
> +       switch (raw_features & FEATURE_COMPRESSION_MASK) {
> +       case FEATURE_COMPRESSION_TYPE1_TYPE2_TYPE3:
> +               features->compression_type3 = true;
> +       case FEATURE_COMPRESSION_TYPE1_TYPE2:
> +               features->compression_type2 = true;
> +       case FEATURE_COMPRESSION_TYPE1:
> +               features->compression_type1 = true;
>                 break;
> +       }
> +
> +       features->interlace = raw_extended_features & EXTENDED_FEATURE_INTERLACE;
> +       features->osd = raw_features & FEATURE_OSD;
> +       features->compression_pipes = raw_extended_features & EXTENDED_FEATURE_COMPRESSION_PIPES;
>
> -       default:
> -               printf(", audio %d(not supported)", feature_audio);
> +       return 0;
> +}
> +
> +#endif
> +
> +bool ioep_fpga_has_osd(unsigned int fpga)
> +{
> +       struct fpga_features features;
> +
> +       get_features(fpga, &features);
> +
> +       return features.osd;
> +}
> +
> +void ioep_fpga_print_info(unsigned int fpga)
> +{
> +       u16 fpga_version;
> +       struct fpga_versions versions;
> +       struct fpga_features features;
> +
> +       FPGA_GET_REG(fpga, fpga_version, &fpga_version);
> +       get_versions(fpga, &versions);
> +       get_features(fpga, &features);
> +
> +       if (versions.video_channel)
> +               printf("Videochannel");
> +       else
> +               printf("Mainchannel");
> +
> +       if (versions.con_side)
> +               printf(" User");
> +       else
> +               printf(" Server");
> +
> +// FIXME
> +#if 0
> +               if (versions & (1<<4))
> +                       printf(" UC");
> +#endif
> +
> +       switch(versions.pcb_transmission_type) {
> +       case PCB_CAT_1G:
> +       case PCB_CAT_10G:
> +               printf(" CAT");
> +               break;
> +       case PCB_FIBER_3G:
> +       case PCB_FIBER_10G:
> +               printf(" Fiber");
> +               break;
> +       };
> +
> +       switch (versions.pcb_video_type) {
> +       case PCB_DVI_SL:
> +               printf(" DVI,");
> +               break;
> +       case PCB_DP_165MPIX:
> +               printf(" DP 165MPix/s,");
> +               break;
> +       case PCB_DP_300MPIX:
> +               printf(" DP 300MPix/s,");
> +               break;
> +       case PCB_HDMI:
> +               printf(" HDMI,");
> +               break;
> +       case PCB_DP_1_2:
> +               printf(" DP 1.2,");
> +               break;
> +       case PCB_HDMI_2_0:
> +               printf(" HDMI 2.0,");
>                 break;
>         }
>
> +       printf(" FPGA V %d.%02d\n       features: ",
> +              fpga_version / 100, fpga_version % 100);
> +
> +       if (!features.compression_type1 &&
> +           !features.compression_type2 &&
> +           !features.compression_type3)
> +               printf("no compression, ");
> +
> +       if (features.compression_type1)
> +               printf("type1-deltacompression, ");
> +
> +       if (features.compression_type2)
> +               printf("type2-inlinecompression, ");
> +
> +       if (features.compression_type3)
> +               printf("type3-intempocompression, ");
> +
> +       printf("%sosd", features.osd ? "" : "no ");
> +
> +       if (features.pcm_rx && features.pcm_tx)
> +               printf(", pcm rx+tx");
> +       else if(features.pcm_rx)
> +               printf(", pcm rx");
> +       else if(features.pcm_tx)
> +               printf(", pcm tx");
> +
> +       if (features.spdif_rx && features.spdif_tx)
> +               printf(", spdif rx+tx");
> +       else if(features.spdif_rx)
> +               printf(", spdif rx");
> +       else if(features.spdif_tx)
> +               printf(", spdif tx");
> +
>         puts(",\n       ");
>
> -       switch (feature_sysclock) {
> +       switch (features.sysclock) {
>         case SYSCLK_147456:
>                 printf("clock 147.456 MHz");
>                 break;
> -
> -       default:
> -               printf("clock %d(not supported)", feature_sysclock);
> -               break;
>         }
>
> -       switch (feature_ramconfig) {
> -       case RAM_DDR2_32:
> +       switch (features.ram_config) {
> +       case RAM_DDR2_32BIT_295MBPS:
>                 printf(", RAM 32 bit DDR2");
>                 break;
> -
> -       case RAM_DDR3_32:
> +       case RAM_DDR3_32BIT_590MBPS:
>                 printf(", RAM 32 bit DDR3");
>                 break;
> -
> -       case RAM_DDR3_48:
> +       case RAM_DDR3_48BIT_590MBPS:
> +       case RAM_DDR3_48BIT_1800MBPS:
>                 printf(", RAM 48 bit DDR3");
>                 break;
> -
> -       default:
> -               printf(", RAM %d(not supported)", feature_ramconfig);
> +       case RAM_DDR3_64BIT_1800MBPS:
> +               printf(", RAM 64 bit DDR3");
>                 break;
>         }
>
> -       printf(", %d carrier(s) %s", feature_carriers,
> -              feature_carrier_speed ? "2.5Gbit/s" : "1Gbit/s");
> +       printf(", %d carrier(s)", features.carriers);
> +
> +       switch(features.carrier_speed) {
> +       case CARRIER_SPEED_1G:
> +               printf(", 1Gbit/s");
> +               break;
> +       case CARRIER_SPEED_3G:
> +               printf(", 3Gbit/s");
> +               break;
> +       case CARRIER_SPEED_10G:
> +               printf(", 10Gbit/s");
> +               break;
> +       }
>
> -       printf(", %d video channel(s)\n", feature_video_channels);
> +       printf(", %d video channel(s)\n", features.video_channels);
>  }
>
>  #endif /* CONFIG_GDSYS_LEGACY_DRIVERS */
> diff --git a/board/gdsys/mpc8308/Kconfig b/board/gdsys/mpc8308/Kconfig
> index 80ac1a0f8a..79d0dc9829 100644
> --- a/board/gdsys/mpc8308/Kconfig
> +++ b/board/gdsys/mpc8308/Kconfig
> @@ -55,6 +55,25 @@ config GDSYS_LEGACY_DRIVERS
>
>  endif
>
> +if TARGET_GAZERBEAM
> +
> +config SYS_BOARD
> +       default "mpc8308"
> +
> +config SYS_VENDOR
> +       default "gdsys"
> +
> +config SYS_CONFIG_NAME
> +       default "gazerbeam"
> +
> +config SYS_FPGA1_BASE
> +       default E0700000
> +
> +config SYS_FPGA1_SIZE
> +       default 1
> +
> +endif
> +
>  choice
>         prompt "FPGA flavor selection"
>
> diff --git a/board/gdsys/mpc8308/MAINTAINERS b/board/gdsys/mpc8308/MAINTAINERS
> index 3895b01732..a986ae3664 100644
> --- a/board/gdsys/mpc8308/MAINTAINERS
> +++ b/board/gdsys/mpc8308/MAINTAINERS
> @@ -6,5 +6,7 @@ F:      include/configs/hrcon.h
>  F:     configs/hrcon_defconfig
>  F:     configs/hrcon_dh_defconfig
>  F:     include/configs/strider.h
> +F:     configs/strider_defconfig
>  F:     configs/strider_cpu_defconfig
>  F:     configs/strider_con_defconfig
> +F:     configs/gazerbeam_defconfig
> diff --git a/board/gdsys/mpc8308/Makefile b/board/gdsys/mpc8308/Makefile
> index 42702fb967..bafb9beaaf 100644
> --- a/board/gdsys/mpc8308/Makefile
> +++ b/board/gdsys/mpc8308/Makefile
> @@ -8,3 +8,4 @@
>  obj-y := mpc8308.o sdram.o
>  obj-$(CONFIG_HRCON) += hrcon.o
>  obj-$(CONFIG_STRIDER) += strider.o
> +obj-$(CONFIG_TARGET_GAZERBEAM) += gazerbeam.o
> diff --git a/board/gdsys/mpc8308/gazerbeam.c b/board/gdsys/mpc8308/gazerbeam.c
> new file mode 100644
> index 0000000000..a86333d92c
> --- /dev/null
> +++ b/board/gdsys/mpc8308/gazerbeam.c
> @@ -0,0 +1,332 @@
> +/*
> + * (C) Copyright 2015
> + * Dirk Eibach,  Guntermann & Drunck GmbH, eibach at gdsys.de
> + *
> + * SPDX-License-Identifier:    GPL-2.0+
> + */
> +
> +#include <common.h>
> +#include <dm.h>
> +#include <dm/device-internal.h>
> +#include <dm/uclass-internal.h>
> +#include <fsl_esdhc.h>
> +#include <gdsys_rxaui_ctrl.h>
> +#include <marvell-phy.h>
> +#include <miiphy.h>
> +#include <tpm.h>
> +#include <i2c.h>
> +#include <asm/fsl_mpc83xx_serdes.h>
> +#include <asm/gpio.h>
> +
> +#include "../../../drivers/net/phy/mv88x2.h"
> +#include "../common/ihs_mdio.h"
> +
> +DECLARE_GLOBAL_DATA_PTR;
> +
> +struct ihs_mdio_info ihs_mdio_info[] = {
> +       { .fpga = NULL, .name = "ihs0", .clause45 = true, .base = 0x58 },
> +       { .fpga = NULL, .name = "ihs1", .clause45 = true, .base = 0x58 },
> +};
> +
> +int child_find_by_name(struct udevice *parent, const char *dev_name,
> +                      struct udevice **child)

Can we add (in separate patch with test) dev_find_child_by_name() in
the dm core code?

> +{
> +       struct udevice *dev = NULL;
> +
> +       for (device_find_first_child(parent, &dev);
> +            dev;
> +            device_find_next_child(&dev)) {
> +               if (!strncmp(dev->name, dev_name, strlen(dev_name))) {
> +                       *child = dev;
> +                       return 0;
> +               }
> +       }
> +
> +       return -1;
> +}
> +
> +int request_gpio_by_dev(struct gpio_desc *gpio, struct udevice *gpio_dev,
> +                       uint offset, char *gpio_name)
> +{
> +       gpio->dev = gpio_dev;
> +       gpio->offset = offset;
> +       gpio->flags = 0;
> +
> +       return dm_gpio_request(gpio, gpio_name);
> +}
> +
> +void determine_board_type(struct of_board_fixup_data *data)
> +{
> +       struct udevice *i2c_bus;
> +       struct udevice *dummy;
> +       struct udevice *gpio_dev = NULL;
> +       struct gpio_desc gpio;
> +       char name[16];
> +
> +       uclass_get_device_by_name(UCLASS_I2C, "i2c at 3100", &i2c_bus);

Can you use an alias to find this and get by seq? Or have a property
somewhere which points to this as a phandle?

> +
> +       if (!i2c_bus) {
> +               puts("Could not get I2C bus\n");
> +               return;
> +       }
> +
> +       data->mc2 = !dm_i2c_probe(i2c_bus, 0x20, 0, &dummy);
> +       data->mc4 = !dm_i2c_probe(i2c_bus, 0x22, 0, &dummy);
> +
> +       if (data->mc2 && data->mc4) {
> +               puts("Board hardware configuration inconsistent.");
> +               return;
> +       }
> +
> +       snprintf(name, sizeof(name), "pca9698@%x", data->mc4 ? 0x22 : 0x20);
> +
> +       if (child_find_by_name(i2c_bus, name, &gpio_dev)) {
> +               printf("Could not find child %s of device %s\n", name,
> +                      i2c_bus->name);
> +               return;
> +       }
> +
> +       device_probe(gpio_dev);

Let's have device_get_child_by_name() also. We should not explicitly
probe outside DM code if possible.

> +
> +       if (!data->mc4) {
> +               if (!request_gpio_by_dev(&gpio, gpio_dev, 0, "var-mc_sc"))

Can you have this GPIO in the device tree so you can use
gpio_request_by_name() from a driver? What is this GPIO for?

> +                       data->mc2 = !dm_gpio_get_value(&gpio);
> +               else
> +                       puts("Could not query var-mc_sc GPIO.\n");
> +
> +               dm_gpio_free(gpio_dev, &gpio);
> +       }
> +
> +       if (!request_gpio_by_dev(&gpio, gpio_dev, 11, "var-con"))
> +               data->var_con = dm_gpio_get_value(&gpio);
> +       else
> +               puts("Could not query var-con GPIO.\n");
> +
> +       dm_gpio_free(gpio_dev, &gpio);
> +}
> +
> +int board_fix_fdt_get_info(void)
> +{
> +       struct of_board_fixup_data data;
> +
> +       determine_board_type(&data);
> +
> +       gd->board_fixup_data.var_con = data.var_con;
> +       gd->board_fixup_data.mc2 = data.mc2;
> +       gd->board_fixup_data.mc4 = data.mc4;
> +
> +       return 0;
> +}
> +
> +int fdt_disable_by_ofname(void *rw_fdt_blob, char *ofname)
> +{
> +       int offset = fdt_path_offset(rw_fdt_blob, ofname);
> +
> +       return fdt_status_disabled(rw_fdt_blob, offset);
> +}
> +
> +int board_fix_fdt_change(void *rw_fdt_blob)
> +{
> +       struct of_board_fixup_data data = gd->board_fixup_data;
> +
> +       if (!data.mc4) {
> +               fdt_disable_by_ofname(rw_fdt_blob,
> +                                     "/localbus at e0005000/iocon_uart at 2,0");
> +               fdt_disable_by_ofname(rw_fdt_blob, "/fpga1bus");
> +       }
> +
> +       if (!data.mc2 || !data.var_con) {
> +               fdt_disable_by_ofname(rw_fdt_blob, "/fpga0bus/fpga0_video1");
> +               fdt_disable_by_ofname(rw_fdt_blob, "/fpga0bus/fpga0_iic_video1");
> +               fdt_disable_by_ofname(rw_fdt_blob, "/fpga0bus/fpga0_axi_video1");
> +       }
> +
> +       if (!data.var_con) {
> +               fdt_disable_by_ofname(rw_fdt_blob, "/fpga0bus/fpga0_video0");
> +               fdt_disable_by_ofname(rw_fdt_blob, "/fpga0bus/fpga0_iic_video0");
> +               fdt_disable_by_ofname(rw_fdt_blob, "/fpga0bus/fpga0_axi_video0");
> +       }
> +
> +       return 0;
> +}
> +
> +int checkboard(void)
> +{
> +       struct of_board_fixup_data data = gd->board_fixup_data;
> +       char *s = getenv("serial#");
> +
> +       puts("Board: Gazerbeam ");
> +       printf("%s ", data.mc4 ? "MC4" : data.mc2 ? "MC2" : "SC");
> +       printf("%s", data.var_con ? "CON" : "CPU");
> +
> +       if (s) {
> +               puts(", serial# ");
> +               puts(s);
> +       }
> +
> +       puts("\n");
> +
> +       return 0;
> +}
> +
> +int last_stage_init(void)
> +{
> +       uint fpga_hw_rev = 0;
> +       uint k = 0;
> +       struct udevice *fpga;
> +       struct udevice *rxaui;
> +       struct udevice *i2c_bus;
> +       struct udevice *gpio_dev;
> +       char name[16];
> +
> +       uclass_get_device_by_name(UCLASS_I2C, "i2c at 3000", &i2c_bus);
> +
> +       if (child_find_by_name(i2c_bus, "pca9698 at 20", &gpio_dev)) {
> +               printf("Could not find child %s of device %s\n", name,
> +                      i2c_bus->name);
> +               return -1;
> +       }
> +
> +       device_probe(gpio_dev);
> +
> +       for (k = 0; k < 4; ++k) {
> +               struct gpio_desc gpio;
> +
> +               snprintf(name, sizeof(name), "fpga_hw_rev%d", k);
> +
> +               if (!request_gpio_by_dev(&gpio, gpio_dev, 12 + k, name))
> +                       fpga_hw_rev |= dm_gpio_get_value(&gpio) ? BIT(k) : 0;
> +       }
> +
> +       setenv_ulong("fpga_hw_rev", fpga_hw_rev);

Can we use gpio_request_list_by_name() and dm_gpio_get_values_as_int() ?

> +
> +       if (tpm_init() || tpm_startup(TPM_ST_CLEAR) ||
> +           tpm_continue_self_test()) {
> +               printf("TPM init failed\n");
> +       }
> +
> +       if (fpga_hw_rev >= 4) {
> +               for (uclass_find_first_device(UCLASS_RXAUI_CTRL, &rxaui);
> +                    rxaui;
> +                    uclass_find_next_device(&rxaui)) {
> +                       rxaui_disable_polarity_inversion(rxaui);
> +               }
> +       }
> +
> +       for (uclass_find_first_device(UCLASS_IHS_FPGA, &fpga);
> +            fpga;
> +            uclass_find_next_device(&fpga)) {

Can you use uclass_first_next_device() since it does the probing for you.

> +               struct mii_dev *bus;
> +
> +               device_probe(fpga);
> +
> +               if (fpga->seq < 0)
> +                       continue;

What is this checking for?

> +
> +               ihs_mdio_info[fpga->seq].fpga = fpga;
> +
> +               ihs_mdio_init(&ihs_mdio_info[fpga->seq]);
> +               bus = miiphy_get_dev_by_name(fpga->seq ? "ihs1" : "ihs0");
> +               if (bus) {
> +                       struct phy_device *phydev;
> +
> +                       phydev = phy_find_by_mask_c45(bus, 1,
> +                                                     PHY_INTERFACE_MODE_XGMII);
> +                       if (phydev)
> +                               phy_config(phydev);
> +               }
> +       }
> +
> +       return 0;
> +}
> +
> +#ifdef CONFIG_FSL_ESDHC
> +int board_mmc_init(bd_t *bd)
> +{
> +       immap_t *immr = (immap_t *)CONFIG_SYS_IMMR;
> +       sysconf83xx_t *sysconf = &immr->sysconf;
> +
> +       /* Enable cache snooping in eSDHC system configuration register */
> +       out_be32(&sysconf->sdhccr, 0x02000000);
> +
> +       return fsl_esdhc_mmc_init(bd);
> +}
> +#endif
> +
> +static struct pci_region pcie_regions_0[] = {
> +       {
> +               .bus_start = CONFIG_SYS_PCIE1_MEM_BASE,
> +               .phys_start = CONFIG_SYS_PCIE1_MEM_PHYS,
> +               .size = CONFIG_SYS_PCIE1_MEM_SIZE,
> +               .flags = PCI_REGION_MEM,
> +       },
> +       {
> +               .bus_start = CONFIG_SYS_PCIE1_IO_BASE,
> +               .phys_start = CONFIG_SYS_PCIE1_IO_PHYS,
> +               .size = CONFIG_SYS_PCIE1_IO_SIZE,
> +               .flags = PCI_REGION_IO,
> +       },
> +};
> +
> +void pci_init_board(void)
> +{
> +       immap_t *immr = (immap_t *)CONFIG_SYS_IMMR;
> +       sysconf83xx_t *sysconf = &immr->sysconf;
> +       law83xx_t *pcie_law = sysconf->pcielaw;
> +       struct pci_region *pcie_reg[] = { pcie_regions_0 };
> +
> +       fsl_setup_serdes(CONFIG_FSL_SERDES1, FSL_SERDES_PROTO_PEX,
> +                        FSL_SERDES_CLK_100, FSL_SERDES_VDD_1V);
> +
> +       /* Deassert the resets in the control register */
> +       out_be32(&sysconf->pecr1, 0xE0008000);
> +       udelay(2000);
> +
> +       /* Configure PCI Express Local Access Windows */
> +       out_be32(&pcie_law[0].bar, CONFIG_SYS_PCIE1_BASE & LAWBAR_BAR);
> +       out_be32(&pcie_law[0].ar, LBLAWAR_EN | LBLAWAR_512MB);
> +
> +       mpc83xx_pcie_init(1, pcie_reg);
> +}
> +
> +ulong board_flash_get_legacy(ulong base, int banknum, flash_info_t *info)
> +{
> +       info->portwidth = FLASH_CFI_16BIT;
> +       info->chipwidth = FLASH_CFI_BY16;
> +       info->interface = FLASH_CFI_X16;
> +       return 1;
> +}
> +
> +#if defined(CONFIG_OF_BOARD_SETUP)
> +int ft_board_setup(void *blob, bd_t *bd)
> +{
> +       ft_cpu_setup(blob, bd);
> +       fsl_fdt_fixup_dr_usb(blob, bd);
> +       fdt_fixup_esdhc(blob, bd);
> +
> +       return 0;
> +}
> +#endif
> +
> +int board_m88e1510_config(struct phy_device *phydev)
> +{
> +       /* Select page 3 */
> +       phy_write(phydev, MDIO_DEVAD_NONE, 22, 3);
> +
> +       /* Configure LEDs */
> +       m88e1518_phy_writebits(phydev, 16, 0, 4, 4);
> +       m88e1518_phy_writebits(phydev, 16, 4, 4, 8);
> +       m88e1518_phy_writebits(phydev, 16, 8, 4, 0);
> +
> +       /* Reset page selection */
> +       phy_write(phydev, MDIO_DEVAD_NONE, 22, 0);
> +
> +       return 0;
> +}
> +
> +int board_mv88x2_config(struct mv88x2_config_data *data)
> +{
> +       data->sfi_pol = (getenv_ulong("fpga_hw_rev", 10, 0) < 4) ? 0x0f03 : 0;
> +
> +       return 0;
> +}
> diff --git a/configs/gazerbeam_defconfig b/configs/gazerbeam_defconfig
> new file mode 100644
> index 0000000000..4fc92ea19b
> --- /dev/null
> +++ b/configs/gazerbeam_defconfig
> @@ -0,0 +1,76 @@
> +CONFIG_PPC=y
> +CONFIG_SYS_MALLOC_F_LEN=0x600
> +CONFIG_IDENT_STRING=" gazerbeam 0.01"
> +CONFIG_MPC83xx=y
> +CONFIG_TARGET_GAZERBEAM=y
> +CONFIG_SYS_FPGA_FLAVOR_GAZERBEAM=y
> +CONFIG_CMD_IOLOOP=y
> +CONFIG_DEFAULT_DEVICE_TREE="gazerbeam"
> +CONFIG_FIT=y
> +CONFIG_FIT_SIGNATURE=y
> +CONFIG_FIT_VERBOSE=y
> +CONFIG_OF_BOARD_SETUP=y
> +CONFIG_OF_STDOUT_VIA_ALIAS=y
> +CONFIG_BOOTDELAY=5
> +CONFIG_SYS_CONSOLE_INFO_QUIET=y
> +# CONFIG_DISPLAY_BOARDINFO is not set
> +CONFIG_HUSH_PARSER=y
> +CONFIG_AUTOBOOT_KEYED=y
> +CONFIG_AUTOBOOT_STOP_STR=" "
> +CONFIG_CMD_MEMTEST=y
> +CONFIG_CMD_MMC=y
> +CONFIG_CMD_I2C=y
> +# CONFIG_CMD_FPGA is not set
> +CONFIG_CMD_GPIO=y
> +CONFIG_CMD_IHS_FPGA=y
> +CONFIG_CMD_IHS_AXI=y
> +# CONFIG_CMD_SETEXPR is not set
> +# CONFIG_CMD_NFS is not set
> +CONFIG_CMD_MII=y
> +CONFIG_CMD_MII_DRIVER=y
> +CONFIG_CMD_PING=y
> +CONFIG_CMD_HASH=y
> +CONFIG_CMD_TPM=y
> +CONFIG_CMD_EXT2=y
> +CONFIG_DOS_PARTITION=y
> +CONFIG_OF_CONTROL=y
> +CONFIG_OF_BOARD_FIXUP=y
> +CONFIG_OF_EMBED=y
> +CONFIG_DM=y
> +CONFIG_CLK=y
> +CONFIG_ICS8N3QV01=y
> +CONFIG_DM_GPIO=y
> +CONFIG_DM_PCA953X=y
> +CONFIG_MPC8XXX_GPIO=y
> +CONFIG_DM_I2C=y
> +CONFIG_SYS_I2C_FSL=y
> +CONFIG_SYS_I2C_IHS=y
> +CONFIG_MISC=y
> +CONFIG_IHS_FPGA=y
> +CONFIG_IHS_AXI=y
> +CONFIG_IHS_VIDEO_OUT=y
> +CONFIG_GDSYS_RXAUI_CTRL=y
> +CONFIG_GDSYS_IOEP=y
> +CONFIG_MTD=y
> +CONFIG_MTD_NOR_FLASH=y
> +CONFIG_CFI_FLASH=y
> +CONFIG_PHYLIB=y
> +CONFIG_PHYLIB_10G=y
> +CONFIG_PHY_MARVELL=y
> +CONFIG_BOARD_M88E1510_CONFIG=y
> +CONFIG_PHY_MV88X2=y
> +CONFIG_BOARD_MV88X2_CONFIG=y
> +CONFIG_MV88X2_DEBUG_REGS=y
> +CONFIG_MV88X2_LINE_10GBASE_R=y
> +CONFIG_MV88X2_HOST_10GBASE_X2=y
> +CONFIG_MV88X2_X2_DISPARITY=y
> +CONFIG_MV88X2_LED0_SOLID=6
> +CONFIG_MV88X2_LED1_SOLID=6
> +CONFIG_MV88X2_HOST_LANE_MUX_2_PORT=0x0800
> +CONFIG_DM_SERIAL=y
> +CONFIG_SYS_NS16550=y
> +CONFIG_TPM_ATMEL_TWI=y
> +CONFIG_TPM_AUTH_SESSIONS=y
> +CONFIG_TRANSMITTER=y
> +CONFIG_LOGICORE_DP_TX=y
> +CONFIG_TPM=y
> diff --git a/include/configs/gazerbeam.h b/include/configs/gazerbeam.h
> new file mode 100644
> index 0000000000..a8d0474771
> --- /dev/null
> +++ b/include/configs/gazerbeam.h
> @@ -0,0 +1,484 @@
> +/*
> + * (C) Copyright 2015
> + * Dirk Eibach,  Guntermann & Drunck GmbH, eibach at gdsys.de
> + *
> + *
> + * SPDX-License-Identifier:    GPL-2.0+
> + */
> +
> +#ifndef __CONFIG_H
> +#define __CONFIG_H
> +
> +/*
> + * High Level Configuration Options
> + */
> +#define CONFIG_E300            1 /* E300 family */
> +#define CONFIG_MPC83xx         1 /* MPC83xx family */
> +#define CONFIG_MPC830x         1 /* MPC830x family */
> +#define CONFIG_MPC8308         1 /* MPC8308 CPU specific */

Can you drop the '1' in these?

> +
> +#define        CONFIG_SYS_TEXT_BASE    0xFE000000
> +
> +#define CONFIG_LAST_STAGE_INIT
> +#define CONFIG_DISPLAY_BOARDINFO_LATE
> +
> +#define CONFIG_FSL_ESDHC
> +#define CONFIG_SYS_FSL_ESDHC_ADDR      CONFIG_SYS_MPC83xx_ESDHC_ADDR
> +#define CONFIG_SYS_FSL_ERRATUM_ESDHC111
> +
> +#define CONFIG_SYS_ALT_MEMTEST
> +
> +/*
> + * System Clock Setup
> + */
> +#define CONFIG_83XX_CLKIN      33333333 /* in Hz */
> +#define CONFIG_SYS_CLK_FREQ    CONFIG_83XX_CLKIN
> +
> +/*
> + * Hardware Reset Configuration Word
> + * if CLKIN is 66.66MHz, then
> + * CSB = 133MHz, DDRC = 266MHz, LBC = 133MHz
> + * We choose the A type silicon as default, so the core is 400Mhz.
> + */
> +#define CONFIG_SYS_HRCW_LOW (\
> +       HRCWL_LCL_BUS_TO_SCB_CLK_1X1 |\
> +       HRCWL_DDR_TO_SCB_CLK_2X1 |\
> +       HRCWL_SVCOD_DIV_2 |\
> +       HRCWL_CSB_TO_CLKIN_4X1 |\
> +       HRCWL_CORE_TO_CSB_3X1)

Seems like this should be in the DT instead of a CONFIG. TBD for later?

> +/*
> + * There are neither HRCWH_PCI_HOST nor HRCWH_PCI1_ARBITER_ENABLE bits
> + * in 8308's HRCWH according to the manual, but original Freescale's
> + * code has them and I've expirienced some problems using the board
> + * with BDI3000 attached when I've tried to set these bits to zero
> + * (UART doesn't work after the 'reset run' command).
> + */
> +#define CONFIG_SYS_HRCW_HIGH (\
> +       HRCWH_PCI_HOST |\
> +       HRCWH_PCI1_ARBITER_ENABLE |\
> +       HRCWH_CORE_ENABLE |\
> +       HRCWH_FROM_0XFFF00100 |\
> +       HRCWH_BOOTSEQ_DISABLE |\
> +       HRCWH_SW_WATCHDOG_DISABLE |\
> +       HRCWH_ROM_LOC_LOCAL_16BIT |\
> +       HRCWH_RL_EXT_LEGACY |\
> +       HRCWH_TSEC1M_IN_RGMII |\
> +       HRCWH_TSEC2M_IN_RGMII |\
> +       HRCWH_BIG_ENDIAN)
> +
> +/*
> + * System IO Config
> + */
> + #define CONFIG_SYS_SICRH (\
> +       SICRH_ESDHC_A_SD |\
> +       SICRH_ESDHC_B_SD |\
> +       SICRH_ESDHC_C_SD |\
> +       SICRH_GPIO_A_TSEC2 |\
> +       SICRH_GPIO_B_TSEC2_GTX_CLK125 |\
> +       SICRH_IEEE1588_A_GPIO |\
> +       SICRH_USB |\
> +       SICRH_GTM_GPIO |\
> +       SICRH_IEEE1588_B_GPIO |\
> +       SICRH_ETSEC2_GPIO |\
> +       SICRH_GPIOSEL_1 |\
> +       SICRH_TMROBI_V3P3 |\
> +       SICRH_TSOBI1_V2P5 |\
> +       SICRH_TSOBI2_V2P5)      /* 0x01b7f103 */
> + #define CONFIG_SYS_SICRL (\
> +       SICRL_SPI_PF0 |\
> +       SICRL_UART_PF0 |\
> +       SICRL_IRQ_PF0 |\
> +       SICRL_I2C2_PF0 |\
> +       SICRL_ETSEC1_GTX_CLK125)        /* 0x00000000 */
> +
> +/*
> + * IMMR new address
> + */
> +#define CONFIG_SYS_IMMR                0xE0000000
> +
> +/*
> + * SERDES
> + */
> +#define CONFIG_FSL_SERDES
> +#define CONFIG_FSL_SERDES1     0xe3000
> +
> +/*
> + * Arbiter Setup
> + */
> +#define CONFIG_SYS_ACR_PIPE_DEP        3 /* Arbiter pipeline depth is 4 */
> +#define CONFIG_SYS_ACR_RPTCNT  3 /* Arbiter repeat count is 4 */
> +#define CONFIG_SYS_SPCR_TSECEP 3 /* eTSEC emergency priority is highest */
> +
> +/*
> + * DDR Setup
> + */
> +#define CONFIG_SYS_DDR_BASE            0x00000000 /* DDR is system memory */
> +#define CONFIG_SYS_SDRAM_BASE          CONFIG_SYS_DDR_BASE
> +#define CONFIG_SYS_DDR_SDRAM_BASE      CONFIG_SYS_DDR_BASE
> +#define CONFIG_SYS_DDR_SDRAM_CLK_CNTL  DDR_SDRAM_CLK_CNTL_CLK_ADJUST_05
> +#define CONFIG_SYS_DDRCDR_VALUE        (DDRCDR_EN \
> +                               | DDRCDR_PZ_LOZ \
> +                               | DDRCDR_NZ_LOZ \
> +                               | DDRCDR_ODT \
> +                               | DDRCDR_Q_DRN)
> +                               /* 0x7b880001 */
> +/*
> + * Manually set up DDR parameters
> + * consist of one chip NT5TU64M16HG from NANYA
> + */
> +
> +#define CONFIG_SYS_DDR_SIZE            128 /* MB */
> +
> +#define CONFIG_SYS_DDR_CS0_BNDS        0x00000007
> +#define CONFIG_SYS_DDR_CS0_CONFIG      (CSCONFIG_EN \
> +                               | CSCONFIG_ODT_RD_NEVER \
> +                               | CSCONFIG_ODT_WR_ONLY_CURRENT \
> +                               | CSCONFIG_BANK_BIT_3 \
> +                               | CSCONFIG_ROW_BIT_13 | CSCONFIG_COL_BIT_10)
> +                               /* 0x80010102 */
> +#define CONFIG_SYS_DDR_TIMING_3        0
> +#define CONFIG_SYS_DDR_TIMING_0        ((0 << TIMING_CFG0_RWT_SHIFT) \
> +                               | (0 << TIMING_CFG0_WRT_SHIFT) \
> +                               | (0 << TIMING_CFG0_RRT_SHIFT) \
> +                               | (0 << TIMING_CFG0_WWT_SHIFT) \
> +                               | (2 << TIMING_CFG0_ACT_PD_EXIT_SHIFT) \
> +                               | (6 << TIMING_CFG0_PRE_PD_EXIT_SHIFT) \
> +                               | (8 << TIMING_CFG0_ODT_PD_EXIT_SHIFT) \
> +                               | (2 << TIMING_CFG0_MRS_CYC_SHIFT))
> +                               /* 0x00260802 */
> +#define CONFIG_SYS_DDR_TIMING_1        ((2 << TIMING_CFG1_PRETOACT_SHIFT) \
> +                               | (6 << TIMING_CFG1_ACTTOPRE_SHIFT) \
> +                               | (2 << TIMING_CFG1_ACTTORW_SHIFT) \
> +                               | (7 << TIMING_CFG1_CASLAT_SHIFT) \
> +                               | (9 << TIMING_CFG1_REFREC_SHIFT) \
> +                               | (2 << TIMING_CFG1_WRREC_SHIFT) \
> +                               | (2 << TIMING_CFG1_ACTTOACT_SHIFT) \
> +                               | (2 << TIMING_CFG1_WRTORD_SHIFT))
> +                               /* 0x26279222 */
> +#define CONFIG_SYS_DDR_TIMING_2        ((0 << TIMING_CFG2_ADD_LAT_SHIFT) \
> +                               | (4 << TIMING_CFG2_CPO_SHIFT) \
> +                               | (3 << TIMING_CFG2_WR_LAT_DELAY_SHIFT) \
> +                               | (2 << TIMING_CFG2_RD_TO_PRE_SHIFT) \
> +                               | (2 << TIMING_CFG2_WR_DATA_DELAY_SHIFT) \
> +                               | (3 << TIMING_CFG2_CKE_PLS_SHIFT) \
> +                               | (5 << TIMING_CFG2_FOUR_ACT_SHIFT))
> +                               /* 0x021848c5 */
> +#define CONFIG_SYS_DDR_INTERVAL        ((0x0824 << SDRAM_INTERVAL_REFINT_SHIFT) \
> +                               | (0x0100 << SDRAM_INTERVAL_BSTOPRE_SHIFT))
> +                               /* 0x08240100 */
> +#define CONFIG_SYS_DDR_SDRAM_CFG       (SDRAM_CFG_SREN \
> +                               | SDRAM_CFG_SDRAM_TYPE_DDR2 \
> +                               | SDRAM_CFG_DBW_16)
> +                               /* 0x43100000 */
> +
> +#define CONFIG_SYS_DDR_SDRAM_CFG2      0x00401000 /* 1 posted refresh */
> +#define CONFIG_SYS_DDR_MODE            ((0x0440 << SDRAM_MODE_ESD_SHIFT) \
> +                               | (0x0242 << SDRAM_MODE_SD_SHIFT))
> +                               /* ODT 150ohm CL=4, AL=0 on SDRAM */
> +#define CONFIG_SYS_DDR_MODE2           0x00000000

I think this should all be a UCLASS_RAM driver with DT configuration.
Too many CONFIGs :-)

> +
> +/*
> + * Memory test
> + */
> +#define CONFIG_SYS_MEMTEST_START       0x00001000 /* memtest region */
> +#define CONFIG_SYS_MEMTEST_END         0x07f00000
> +
> +/*
> + * The reserved memory
> + */
> +#define CONFIG_SYS_MONITOR_BASE        CONFIG_SYS_TEXT_BASE /* start of monitor */
> +
> +#define CONFIG_SYS_MONITOR_LEN (512 * 1024) /* Reserve 512 kB for Mon */
> +#define CONFIG_SYS_MALLOC_LEN  (512 * 1024) /* Reserved for malloc */
> +
> +/*
> + * Initial RAM Base Address Setup
> + */
> +#define CONFIG_SYS_INIT_RAM_LOCK       1
> +#define CONFIG_SYS_INIT_RAM_ADDR       0xE6000000 /* Initial RAM address */
> +#define CONFIG_SYS_INIT_RAM_SIZE       0x1000 /* Size of used area in RAM */
> +#define CONFIG_SYS_GBL_DATA_OFFSET     \
> +       (CONFIG_SYS_INIT_RAM_SIZE - GENERATED_GBL_DATA_SIZE)
> +
> +/*
> + * Local Bus Configuration & Clock Setup
> + */
> +#define CONFIG_SYS_LCRR_DBYP           LCRR_DBYP
> +#define CONFIG_SYS_LCRR_CLKDIV         LCRR_CLKDIV_2
> +#define CONFIG_SYS_LBC_LBCR            0x00040000
> +
> +/*
> + * FLASH on the Local Bus
> + */
> +#define CONFIG_SYS_FLASH_CFI           /* use the Common Flash Interface */
> +#define CONFIG_FLASH_CFI_DRIVER                /* use the CFI driver */
> +#define CONFIG_SYS_FLASH_CFI_WIDTH     FLASH_CFI_16BIT
> +#define CONFIG_FLASH_CFI_LEGACY
> +#define CONFIG_SYS_FLASH_LEGACY_512Kx16
> +
> +#define CONFIG_SYS_FLASH_BASE          0xFE000000 /* FLASH base address */
> +#define CONFIG_SYS_FLASH_SIZE          8 /* FLASH size is up to 8M */
> +#define CONFIG_SYS_FLASH_PROTECTION    1 /* Use h/w Flash protection. */
> +
> +/* Window base at flash base */
> +#define CONFIG_SYS_LBLAWBAR0_PRELIM    CONFIG_SYS_FLASH_BASE
> +#define CONFIG_SYS_LBLAWAR0_PRELIM     (LBLAWAR_EN | LBLAWAR_8MB)
> +
> +#define CONFIG_SYS_BR0_PRELIM  (CONFIG_SYS_FLASH_BASE \
> +                               | BR_PS_16      /* 16 bit port */ \
> +                               | BR_MS_GPCM    /* MSEL = GPCM */ \
> +                               | BR_V)         /* valid */
> +#define CONFIG_SYS_OR0_PRELIM  (MEG_TO_AM(CONFIG_SYS_FLASH_SIZE) \
> +                               | OR_UPM_XAM \
> +                               | OR_GPCM_CSNT \
> +                               | OR_GPCM_ACS_DIV2 \
> +                               | OR_GPCM_XACS \
> +                               | OR_GPCM_SCY_15 \
> +                               | OR_GPCM_TRLX_SET \
> +                               | OR_GPCM_EHTR_SET)
> +
> +#define CONFIG_SYS_MAX_FLASH_BANKS     1 /* number of banks */
> +#define CONFIG_SYS_MAX_FLASH_SECT      135
> +
> +#define CONFIG_SYS_FLASH_ERASE_TOUT    60000 /* Flash Erase Timeout (ms) */
> +#define CONFIG_SYS_FLASH_WRITE_TOUT    500 /* Flash Write Timeout (ms) */
> +
> +/* Window base at FPGA base */
> +#define CONFIG_SYS_LBLAWBAR1_PRELIM    CONFIG_SYS_FPGA0_BASE
> +#define CONFIG_SYS_LBLAWAR1_PRELIM     (LBLAWAR_EN | LBLAWAR_1MB)
> +#define CONFIG_SYS_LBLAWBAR2_PRELIM    CONFIG_SYS_FPGA1_BASE
> +#define CONFIG_SYS_LBLAWAR2_PRELIM     (LBLAWAR_EN | LBLAWAR_1MB)
> +
> +#define CONFIG_SYS_BR1_PRELIM  (CONFIG_SYS_FPGA0_BASE \
> +                               | BR_PS_16      /* 16 bit port */ \
> +                               | BR_MS_GPCM    /* MSEL = GPCM */ \
> +                               | BR_V)         /* valid */
> +#define CONFIG_SYS_OR1_PRELIM   (MEG_TO_AM(CONFIG_SYS_FPGA0_SIZE) \
> +                               | OR_UPM_XAM \
> +                               | OR_GPCM_CSNT \
> +                               | OR_GPCM_SCY_5 \
> +                               | OR_GPCM_TRLX_CLEAR \
> +                               | OR_GPCM_EHTR_CLEAR)
> +
> +#define CONFIG_SYS_BR2_PRELIM  (CONFIG_SYS_FPGA1_BASE \
> +                               | BR_PS_16      /* 16 bit port */ \
> +                               | BR_MS_GPCM    /* MSEL = GPCM */ \
> +                               | BR_V)         /* valid */
> +#define CONFIG_SYS_OR2_PRELIM  (MEG_TO_AM(CONFIG_SYS_FPGA1_SIZE) \
> +                               | OR_UPM_XAM \
> +                               | OR_GPCM_CSNT \
> +                               | OR_GPCM_SCY_5 \
> +                               | OR_GPCM_TRLX_CLEAR \
> +                               | OR_GPCM_EHTR_CLEAR)

Put this config in the DT.

> +
> +#define CONFIG_SYS_FPGA_COUNT          2

Should not be needed with DT.

> +
> +#define CONFIG_SYS_FPGA_PTR { \
> +       (struct ihs_fpga *)CONFIG_SYS_FPGA0_BASE, \
> +       (struct ihs_fpga *)CONFIG_SYS_FPGA1_BASE }

Get base address from DT.

> +
> +#define CONFIG_SYS_FPGA_NO_RFL_HI
> +
> +#define CONFIG_SYS_BAUDRATE_TABLE  \
> +       {300, 600, 1200, 2400, 4800, 9600, 19200, 38400, 57600, 115200}
> +
> +#define CONFIG_SYS_ICS8N3QV01_I2C              { 3, 6, 4, 7 }
> +
> +/*
> + * General PCI
> + * Addresses are mapped 1-1.
> + */
> +#define CONFIG_SYS_PCIE1_BASE          0xA0000000
> +#define CONFIG_SYS_PCIE1_MEM_BASE      0xA0000000
> +#define CONFIG_SYS_PCIE1_MEM_PHYS      0xA0000000
> +#define CONFIG_SYS_PCIE1_MEM_SIZE      0x10000000
> +#define CONFIG_SYS_PCIE1_CFG_BASE      0xB0000000
> +#define CONFIG_SYS_PCIE1_CFG_SIZE      0x01000000
> +#define CONFIG_SYS_PCIE1_IO_BASE       0x00000000
> +#define CONFIG_SYS_PCIE1_IO_PHYS       0xB1000000
> +#define CONFIG_SYS_PCIE1_IO_SIZE       0x00800000

PCI driver for DM?

> +
> +/* enable PCIE clock */
> +#define CONFIG_SYS_SCCR_PCIEXP1CM      1
> +
> +#define CONFIG_PCI_INDIRECT_BRIDGE
> +#define CONFIG_PCIE
> +
> +#define CONFIG_SYS_PCI_SUBSYS_VENDORID 0x1957  /* Freescale */
> +#define CONFIG_83XX_GENERIC_PCIE_REGISTER_HOSES 1
> +
> +/*
> + * TSEC
> + */
> +#define CONFIG_TSEC_ENET       /* TSEC ethernet support */
> +#define CONFIG_SYS_TSEC1_OFFSET        0x24000
> +#define CONFIG_SYS_TSEC1       (CONFIG_SYS_IMMR+CONFIG_SYS_TSEC1_OFFSET)
> +#define CONFIG_SYS_TSEC2_OFFSET        0x25000
> +#define CONFIG_SYS_TSEC2       (CONFIG_SYS_IMMR+CONFIG_SYS_TSEC2_OFFSET)
> +
> +/*
> + * TSEC ethernet configuration
> + */
> +#define CONFIG_MII             1 /* MII PHY management */
> +
> +#define CONFIG_TSEC1
> +#define CONFIG_TSEC1_NAME      "eTSEC0"
> +#define TSEC1_PHY_ADDR         1
> +#define TSEC1_PHYIDX           0
> +#define TSEC1_FLAGS            TSEC_GIGABIT
> +
> +#define CONFIG_TSEC2
> +#define CONFIG_TSEC2_NAME      "eTSEC1"
> +#define TSEC2_PHY_ADDR         0
> +#define TSEC2_PHYIDX           0
> +#define TSEC2_FLAGS            TSEC_GIGABIT
> +
> +/* Options are: eTSEC[0-1] */
> +#define CONFIG_ETHPRIME                "eTSEC0"

In general we should try to have CONFIGs which enable features, and
use the device tree for config values used by drivers.

> +
> +/*
> + * Environment
> + */
> +#if 1
> +#define CONFIG_ENV_IS_IN_FLASH 1
> +#define CONFIG_ENV_ADDR                (CONFIG_SYS_MONITOR_BASE + \
> +                                CONFIG_SYS_MONITOR_LEN)
> +#define CONFIG_ENV_SECT_SIZE   0x10000 /* 64K(one sector) for env */
> +#define CONFIG_ENV_SIZE                0x2000
> +#define CONFIG_ENV_ADDR_REDUND (CONFIG_ENV_ADDR + CONFIG_ENV_SECT_SIZE)
> +#define CONFIG_ENV_SIZE_REDUND CONFIG_ENV_SIZE
> +#else
> +#define CONFIG_ENV_IS_NOWHERE
> +#define CONFIG_ENV_SIZE                0x2000          /* 8KB */
> +#endif
> +
> +#define CONFIG_LOADS_ECHO      1       /* echo on for serial download */
> +#define CONFIG_SYS_LOADS_BAUD_CHANGE   1       /* allow baudrate change */
> +
> +/*
> + * Command line configuration.
> + */
> +#define CONFIG_CMD_PCI
> +
> +#define CONFIG_CMDLINE_EDITING 1       /* add command line history */

Drop '1' on the end of these.

> +#define CONFIG_AUTO_COMPLETE           /* add autocompletion support */
> +
> +/*
> + * Miscellaneous configurable options
> + */
> +#define CONFIG_SYS_LONGHELP            /* undef to save memory */
> +#define CONFIG_SYS_LOAD_ADDR           0x2000000 /* default load address */
> +#define CONFIG_SYS_HZ          1000    /* decrementer freq: 1ms ticks */
> +
> +#define CONFIG_SYS_CBSIZE      1024 /* Console I/O Buffer Size */
> +
> +/* Print Buffer Size */
> +#define CONFIG_SYS_PBSIZE (CONFIG_SYS_CBSIZE + sizeof(CONFIG_SYS_PROMPT) + 16)
> +#define CONFIG_SYS_MAXARGS     16      /* max number of command args */
> +#define CONFIG_SYS_BARGSIZE    CONFIG_SYS_CBSIZE
> +
> +/*
> + * For booting Linux, the board info and command line data
> + * have to be in the first 256 MB of memory, since this is
> + * the maximum mapped by the Linux kernel during initialization.
> + */
> +#define CONFIG_SYS_BOOTMAPSZ   (256 << 20) /* Initial Memory map for Linux */
> +
> +/*
> + * Core HID Setup
> + */
> +#define CONFIG_SYS_HID0_INIT   0x000000000
> +#define CONFIG_SYS_HID0_FINAL  (HID0_ENABLE_MACHINE_CHECK | \
> +                                HID0_ENABLE_INSTRUCTION_CACHE | \
> +                                HID0_ENABLE_DYNAMIC_POWER_MANAGMENT)
> +#define CONFIG_SYS_HID2                HID2_HBE
> +
> +/*
> + * MMU Setup
> + */
> +
> +/* DDR: cache cacheable */
> +#define CONFIG_SYS_IBAT0L      (CONFIG_SYS_SDRAM_BASE | BATL_PP_RW | \
> +                                       BATL_MEMCOHERENCE)
> +#define CONFIG_SYS_IBAT0U      (CONFIG_SYS_SDRAM_BASE | BATU_BL_128M | \
> +                                       BATU_VS | BATU_VP)
> +#define CONFIG_SYS_DBAT0L      CONFIG_SYS_IBAT0L
> +#define CONFIG_SYS_DBAT0U      CONFIG_SYS_IBAT0U
> +
> +/* IMMRBAR, PCI IO and FPGA: cache-inhibit and guarded */
> +#define CONFIG_SYS_IBAT1L      (CONFIG_SYS_IMMR | BATL_PP_RW | \
> +                       BATL_CACHEINHIBIT | BATL_GUARDEDSTORAGE)
> +#define CONFIG_SYS_IBAT1U      (CONFIG_SYS_IMMR | BATU_BL_8M | BATU_VS | \
> +                                       BATU_VP)
> +#define CONFIG_SYS_DBAT1L      CONFIG_SYS_IBAT1L
> +#define CONFIG_SYS_DBAT1U      CONFIG_SYS_IBAT1U
> +
> +/* FLASH: icache cacheable, but dcache-inhibit and guarded */
> +#define CONFIG_SYS_IBAT2L      (CONFIG_SYS_FLASH_BASE | BATL_PP_RW | \
> +                                       BATL_CACHEINHIBIT | \
> +                                       BATL_GUARDEDSTORAGE)
> +#define CONFIG_SYS_IBAT2U      (CONFIG_SYS_FLASH_BASE | BATU_BL_8M | \
> +                                       BATU_VS | BATU_VP)
> +#define CONFIG_SYS_DBAT2L      (CONFIG_SYS_FLASH_BASE | BATL_PP_RW | \
> +                                       BATL_CACHEINHIBIT | \
> +                                       BATL_GUARDEDSTORAGE)
> +#define CONFIG_SYS_DBAT2U      CONFIG_SYS_IBAT2U
> +
> +/* Stack in dcache: cacheable, no memory coherence */
> +#define CONFIG_SYS_IBAT3L      (CONFIG_SYS_INIT_RAM_ADDR | BATL_PP_RW)
> +#define CONFIG_SYS_IBAT3U      (CONFIG_SYS_INIT_RAM_ADDR | BATU_BL_128K | \
> +                                       BATU_VS | BATU_VP)
> +#define CONFIG_SYS_DBAT3L      CONFIG_SYS_IBAT3L
> +#define CONFIG_SYS_DBAT3U      CONFIG_SYS_IBAT3U
> +
> +/*
> + * Environment Configuration
> + */
> +
> +#define CONFIG_ENV_OVERWRITE
> +
> +#if defined(CONFIG_TSEC_ENET)
> +#define CONFIG_HAS_ETH0
> +#endif
> +
> +#define CONFIG_LOADADDR        800000  /* default location for tftp and bootm */
> +
> +#define CONFIG_HOSTNAME                hrcon
> +#define CONFIG_ROOTPATH                "/opt/nfsroot"
> +#define CONFIG_BOOTFILE                "uImage"
> +
> +#define CONFIG_PREBOOT         /* enable preboot variable */
> +
> +#define        CONFIG_EXTRA_ENV_SETTINGS                                       \
> +       "netdev=eth0\0"                                                 \
> +       "consoledev=ttyS1\0"                                            \
> +       "u-boot=u-boot.bin\0"                                           \
> +       "kernel_addr=1000000\0"                                 \
> +       "fdt_addr=C00000\0"                                             \
> +       "fdtfile=hrcon.dtb\0"                           \
> +       "load=tftp ${loadaddr} ${u-boot}\0"                             \
> +       "update=protect off " __stringify(CONFIG_SYS_MONITOR_BASE)      \
> +               " +${filesize};era " __stringify(CONFIG_SYS_MONITOR_BASE)\
> +               " +${filesize};cp.b ${fileaddr} "                       \
> +               __stringify(CONFIG_SYS_MONITOR_BASE) " ${filesize}\0"   \
> +       "upd=run load update\0"                                         \
> +
> +#define CONFIG_NFSBOOTCOMMAND                                          \
> +       "setenv bootargs root=/dev/nfs rw "                             \
> +       "nfsroot=$serverip:$rootpath "                                  \
> +       "ip=$ipaddr:$serverip:$gatewayip:$netmask:$hostname:$netdev:off " \
> +       "console=$consoledev,$baudrate $othbootargs;"                   \
> +       "tftp ${kernel_addr} $bootfile;"                                \
> +       "tftp ${fdt_addr} $fdtfile;"                                    \
> +       "bootm ${kernel_addr} - ${fdt_addr}"
> +
> +#define CONFIG_MMCBOOTCOMMAND                                          \
> +       "setenv bootargs root=/dev/mmcblk0p3 rw rootwait "              \
> +       "console=$consoledev,$baudrate $othbootargs;"                   \
> +       "ext2load mmc 0:2 ${kernel_addr} $bootfile;"                    \
> +       "ext2load mmc 0:2 ${fdt_addr} $fdtfile;"                        \
> +       "bootm ${kernel_addr} - ${fdt_addr}"
> +
> +#define CONFIG_BOOTCOMMAND             CONFIG_MMCBOOTCOMMAND
> +
> +#endif /* __CONFIG_H */
> diff --git a/include/fdt_fixup.h b/include/fdt_fixup.h
> index 9390f0a633..f67685a789 100644
> --- a/include/fdt_fixup.h
> +++ b/include/fdt_fixup.h

Hoping to drop this file.

> @@ -1,4 +1,9 @@
>  struct of_board_fixup_data {
> +#ifdef CONFIG_TARGET_GAZERBEAM
> +       bool var_con;
> +       bool mc4;
> +       bool mc2;
> +#endif
>  #ifdef CONFIG_TARGET_CONTROLCENTERDC
>         bool chip_exists[6];
>  #endif
> --
> 2.11.0
>

Regards,
Simon

^ permalink raw reply	[flat|nested] 138+ messages in thread

* [U-Boot] [PATCH 06/51] cmd: Add command for calculating binary operations
  2017-07-19  8:53     ` Mario Six
@ 2017-07-19  9:07       ` Simon Glass
  2017-07-25  7:28         ` Mario Six
  0 siblings, 1 reply; 138+ messages in thread
From: Simon Glass @ 2017-07-19  9:07 UTC (permalink / raw)
  To: u-boot

Hi Mario,

On 19 July 2017 at 01:53, Mario Six <mario.six@gdsys.cc> wrote:
> Hi Simon,
>
> On Tue, Jul 18, 2017 at 4:01 PM, Simon Glass <sjg@chromium.org> wrote:
>> Hi Mario,
>>
>> On 14 July 2017 at 05:54, Mario Six <mario.six@gdsys.cc> wrote:
>>> This patch adds a command that enables the calculation of bit operations
>>> (AND, OR, XOR) on binary data from the command line. Memory locations as
>>> well as the contents of environment variables are eligible as sources
>>> and destination of the binary data used in the operations.
>>>
>>> The possible applications are manifold: Setting specific bits in
>>> registers using the regular read-OR-write pattern, masking out bits in
>>> bit values, implementation of simple OTP encryption using the XOR
>>> operation, etc.
>>>
>>> Signed-off-by: Mario Six <mario.six@gdsys.cc>
>>
>> Is this very different from setexpr? It looks like it supports and / or.
>>
>> Regards,
>> Simon
>
> It is quite similar, but it lacks the support to write the result directly back
> to memory, and, the more important point, it also only operates on bytes, words
> and longs, whereas binop operates on arbitrarily long byte arrays.
>
> I thought about somehow fixing up setexpr to add support for these two
> features, but couldn't think of a good way to do so. Do you have an idea how to
> do that? I'd also rather not add an additional command if somehow possible.

Not really. It makes sense to me now. Perhaps add in the help that you
can use byte arrays.

Also can you add a test for this? See for example ut_cmd.

Regards,
Simon

^ permalink raw reply	[flat|nested] 138+ messages in thread

* [U-Boot] [PATCH 06/51] cmd: Add command for calculating binary operations
  2017-07-19  9:07       ` Simon Glass
@ 2017-07-25  7:28         ` Mario Six
  0 siblings, 0 replies; 138+ messages in thread
From: Mario Six @ 2017-07-25  7:28 UTC (permalink / raw)
  To: u-boot

Hi Simon,

On Wed, Jul 19, 2017 at 11:07 AM, Simon Glass <sjg@chromium.org> wrote:
> Hi Mario,
>
> On 19 July 2017 at 01:53, Mario Six <mario.six@gdsys.cc> wrote:
>> Hi Simon,
>>
>> On Tue, Jul 18, 2017 at 4:01 PM, Simon Glass <sjg@chromium.org> wrote:
>>> Hi Mario,
>>>
>>> On 14 July 2017 at 05:54, Mario Six <mario.six@gdsys.cc> wrote:
>>>> This patch adds a command that enables the calculation of bit operations
>>>> (AND, OR, XOR) on binary data from the command line. Memory locations as
>>>> well as the contents of environment variables are eligible as sources
>>>> and destination of the binary data used in the operations.
>>>>
>>>> The possible applications are manifold: Setting specific bits in
>>>> registers using the regular read-OR-write pattern, masking out bits in
>>>> bit values, implementation of simple OTP encryption using the XOR
>>>> operation, etc.
>>>>
>>>> Signed-off-by: Mario Six <mario.six@gdsys.cc>
>>>
>>> Is this very different from setexpr? It looks like it supports and / or.
>>>
>>> Regards,
>>> Simon
>>
>> It is quite similar, but it lacks the support to write the result directly back
>> to memory, and, the more important point, it also only operates on bytes, words
>> and longs, whereas binop operates on arbitrarily long byte arrays.
>>
>> I thought about somehow fixing up setexpr to add support for these two
>> features, but couldn't think of a good way to do so. Do you have an idea how to
>> do that? I'd also rather not add an additional command if somehow possible.
>
> Not really. It makes sense to me now. Perhaps add in the help that you
> can use byte arrays.
>
> Also can you add a test for this? See for example ut_cmd.
>
> Regards,
> Simon

OK, I'll improve the help text and add a test in v2.

Best regards,

Mario

^ permalink raw reply	[flat|nested] 138+ messages in thread

* [U-Boot] [PATCH 07/51] phy: Allow forcing clause 45 access
  2017-07-18 14:01   ` Simon Glass
@ 2017-07-25  7:30     ` Mario Six
  0 siblings, 0 replies; 138+ messages in thread
From: Mario Six @ 2017-07-25  7:30 UTC (permalink / raw)
  To: u-boot

Hi Simon,

On Tue, Jul 18, 2017 at 4:01 PM, Simon Glass <sjg@chromium.org> wrote:
> On 14 July 2017 at 05:54, Mario Six <mario.six@gdsys.cc> wrote:
>> From: Dirk Eibach <dirk.eibach@gdsys.cc>
>>
>> get_phy_device_by_mask() assumes that a clause 45 phy does not respond
>> to clause 22 requests. That is not true at least for Marvell 88X2242.
>> So allow forcing clause 45 access to prevent reading bogus device ids.
>>
>> Signed-off-by: Dirk Eibach <dirk.eibach@gdsys.cc>
>> Signed-off-by: Mario Six <mario.six@gdsys.cc>
>> ---
>>
>>  drivers/net/phy/phy.c | 12 +++++++-----
>>  include/phy.h         | 12 ++++++++++--
>>  2 files changed, 17 insertions(+), 7 deletions(-)
>
> Reviewed-by: Simon Glass <sjg@chromium.org>
>
> Please see below.
>
>>
>> diff --git a/drivers/net/phy/phy.c b/drivers/net/phy/phy.c
>> index 97e0bc022b..08ec2f2ad6 100644
>> --- a/drivers/net/phy/phy.c
>> +++ b/drivers/net/phy/phy.c
>> @@ -707,7 +707,7 @@ static struct phy_device *search_for_existing_phy(struct mii_dev *bus,
>>  }
>>
>>  static struct phy_device *get_phy_device_by_mask(struct mii_dev *bus,
>> -               unsigned phy_mask, phy_interface_t interface)
>> +               unsigned phy_mask, phy_interface_t interface, bool force_c45)
>>  {
>>         int i;
>>         struct phy_device *phydev;
>> @@ -718,6 +718,8 @@ static struct phy_device *get_phy_device_by_mask(struct mii_dev *bus,
>>         /* Try Standard (ie Clause 22) access */
>>         /* Otherwise we have to try Clause 45 */
>>         for (i = 0; i < 5; i++) {
>> +               if (!i && force_c45)
>> +                       continue;
>>                 phydev = create_phy_by_mask(bus, phy_mask,
>>                                 i ? i : MDIO_DEVAD_NONE, interface);
>>                 if (IS_ERR(phydev))
>> @@ -748,7 +750,7 @@ static struct phy_device *get_phy_device_by_mask(struct mii_dev *bus,
>>  static struct phy_device *get_phy_device(struct mii_dev *bus, int addr,
>>                                          phy_interface_t interface)
>>  {
>> -       return get_phy_device_by_mask(bus, 1 << addr, interface);
>> +       return get_phy_device_by_mask(bus, 1 << addr, interface, false);
>>  }
>>
>>  int phy_reset(struct phy_device *phydev)
>> @@ -817,8 +819,8 @@ int miiphy_reset(const char *devname, unsigned char addr)
>>         return phy_reset(phydev);
>>  }
>>
>> -struct phy_device *phy_find_by_mask(struct mii_dev *bus, unsigned phy_mask,
>> -               phy_interface_t interface)
>> +struct phy_device *__phy_find_by_mask(struct mii_dev *bus, unsigned phy_mask,
>> +               phy_interface_t interface, bool force_c45)
>>  {
>>         /* Reset the bus */
>>         if (bus->reset) {
>> @@ -828,7 +830,7 @@ struct phy_device *phy_find_by_mask(struct mii_dev *bus, unsigned phy_mask,
>>                 udelay(15000);
>>         }
>>
>> -       return get_phy_device_by_mask(bus, phy_mask, interface);
>> +       return get_phy_device_by_mask(bus, phy_mask, interface, force_c45);
>>  }
>>
>>  #ifdef CONFIG_DM_ETH
>> diff --git a/include/phy.h b/include/phy.h
>> index 4f2094bdf0..75a9ae3314 100644
>> --- a/include/phy.h
>> +++ b/include/phy.h
>> @@ -227,8 +227,16 @@ static inline int is_10g_interface(phy_interface_t interface)
>>
>>  int phy_init(void);
>>  int phy_reset(struct phy_device *phydev);
>> -struct phy_device *phy_find_by_mask(struct mii_dev *bus, unsigned phy_mask,
>> -               phy_interface_t interface);
>> +struct phy_device *__phy_find_by_mask(struct mii_dev *bus, unsigned phy_mask,
>> +               phy_interface_t interface, bool force_c45);
>
> Can you please add a function comment?
>

I'll add a comment in v2.

>> +static inline struct phy_device *phy_find_by_mask(struct mii_dev *bus,
>> +               unsigned phy_mask, phy_interface_t interface) {
>> +       return __phy_find_by_mask(bus, phy_mask, interface, 0);
>> +}
>> +static inline struct phy_device *phy_find_by_mask_c45(struct mii_dev *bus,
>> +               unsigned phy_mask, phy_interface_t interface) {
>> +       return __phy_find_by_mask(bus, phy_mask, interface, 1);
>> +}
>>  #ifdef CONFIG_DM_ETH
>>  void phy_connect_dev(struct phy_device *phydev, struct udevice *dev);
>>  struct phy_device *phy_connect(struct mii_dev *bus, int addr,
>> --
>> 2.11.0
>>

Best regards,

Mario

^ permalink raw reply	[flat|nested] 138+ messages in thread

* [U-Boot] [PATCH 11/51] powerpc: mpc83xx: Implement get_serial_clock()
  2017-07-18 14:01   ` Simon Glass
@ 2017-07-25  7:34     ` Mario Six
  0 siblings, 0 replies; 138+ messages in thread
From: Mario Six @ 2017-07-25  7:34 UTC (permalink / raw)
  To: u-boot

Hi Simon,

On Tue, Jul 18, 2017 at 4:01 PM, Simon Glass <sjg@chromium.org> wrote:
> On 14 July 2017 at 05:54, Mario Six <mario.six@gdsys.cc> wrote:
>> DM serial drivers on PowerPC determine their clock frequency via the
>> get_serial_clock function. This function is not Implemented yet for
>> MPC83xx.
>>
>> This patch Implements the function so that DM serial drivers work on
>> MPC83xx.
>>
>> Signed-off-by: Mario Six <mario.six@gdsys.cc>
>> ---
>>
>>  arch/powerpc/cpu/mpc83xx/speed.c | 7 +++++++
>>  1 file changed, 7 insertions(+)
>
> Reviewed-by: Simon Glass <sjg@chromium.org>
>
> Really a clock driver would be better.

Since you suggested that I should convert the MPC83xx PCI driver to DM, I'll
probably also just convert the clock functionality into a proper clock driver
(I'll need a way to get the clock in the PCI driver anyway).

So, this will probably be fixed in v2. :-)

Best regards,

Mario

^ permalink raw reply	[flat|nested] 138+ messages in thread

* [U-Boot] [PATCH 24/51] gdsys: mpc8308: Move SYS_FPGA{0, 1}_{BASE, SIZE} to Kconfig
  2017-07-19  9:05   ` Simon Glass
@ 2017-07-25  7:39     ` Mario Six
  0 siblings, 0 replies; 138+ messages in thread
From: Mario Six @ 2017-07-25  7:39 UTC (permalink / raw)
  To: u-boot

Hi Simon,

On Wed, Jul 19, 2017 at 11:05 AM, Simon Glass <sjg@chromium.org> wrote:
> Hi Mario,
>
> On 14 July 2017 at 05:55, Mario Six <mario.six@gdsys.cc> wrote:
>> Move CONFIG_SYS_FPGA0_BASE, CONFIG_SYS_FPGA0_SIZE, CONFIG_SYS_FPGA1_BASE, and
>> CONFIG_SYS_FPGA1_SIZE to Kconfig.
>
> It looks like the FPGA1 options are actually new?
>
> Reviewed-by: Simon Glass <sjg@chromium.org>
>
> We perhaps need an FPGA uclass and a DM driver?
>

Yes, you're right, the FPGA1 options are new. And the FPGA uclass is introduced
in a later patch.

Best regards,

Mario

^ permalink raw reply	[flat|nested] 138+ messages in thread

* [U-Boot] [PATCH 25/51] gdsys: Introduce GDSYS_LEGACY_DRIVERS
  2017-07-19  9:05   ` Simon Glass
@ 2017-07-25  7:40     ` Mario Six
  0 siblings, 0 replies; 138+ messages in thread
From: Mario Six @ 2017-07-25  7:40 UTC (permalink / raw)
  To: u-boot

Hi Simon,

On Wed, Jul 19, 2017 at 11:05 AM, Simon Glass <sjg@chromium.org> wrote:
> On 14 July 2017 at 05:55, Mario Six <mario.six@gdsys.cc> wrote:
>> Future gdsys boards will switch from the legacy drivers in board/gdsys/common
>> to DM-based drivers.
>>
>> Define a Kconfig option that disables the legacy drivers.
>>
>> Signed-off-by: Mario Six <mario.six@gdsys.cc>
>> ---
>>
>>  board/gdsys/common/adv7611.c   | 4 ++++
>>  board/gdsys/common/ch7301.c    | 4 ++++
>>  board/gdsys/common/dp501.c     | 4 ++++
>>  board/gdsys/common/fanctrl.c   | 4 ++++
>>  board/gdsys/common/fpga.c      | 4 ++++
>>  board/gdsys/common/ihs_mdio.c  | 4 ++++
>>  board/gdsys/common/ioep-fpga.c | 4 ++++
>>  board/gdsys/common/mclink.c    | 4 ++++
>>  board/gdsys/common/osd.c       | 4 ++++
>>  board/gdsys/mpc8308/Kconfig    | 8 ++++++++
>>  board/gdsys/mpc8308/mpc8308.c  | 2 ++
>>  board/gdsys/p1022/Kconfig      | 6 ++++++
>>  include/gdsys_fpga.h           | 2 ++
>>  13 files changed, 54 insertions(+)
>
> Reviewed-by: Simon Glass <sjg@chromium.org>
>
> But can you add a help message to your Kconfig?

OK, help message will be added in v2.

Best regards,

Mario

^ permalink raw reply	[flat|nested] 138+ messages in thread

* [U-Boot] [PATCH 28/51] i2c: ihs_i2c: Prepare DM conversion
  2017-07-19  9:05   ` Simon Glass
@ 2017-07-25  7:48     ` Mario Six
  0 siblings, 0 replies; 138+ messages in thread
From: Mario Six @ 2017-07-25  7:48 UTC (permalink / raw)
  To: u-boot

Hi Simon,

On Wed, Jul 19, 2017 at 11:05 AM, Simon Glass <sjg@chromium.org> wrote:
> On 14 July 2017 at 05:55, Mario Six <mario.six@gdsys.cc> wrote:
>> Prepare the function interface of the ihs_i2c driver for DM conversion
>> in a future patch.
>>
>> While we're at it, fix some style violations, and make the code more readable.
>>
>> Signed-off-by: Mario Six <mario.six@gdsys.cc>
>> ---
>>
>>  drivers/i2c/ihs_i2c.c | 74 +++++++++++++++++++++++++++++++--------------------
>>  1 file changed, 45 insertions(+), 29 deletions(-)
>
> Reviewed-by: Simon Glass <sjg@chromium.org>
>
> Please see below
>
>>
>> diff --git a/drivers/i2c/ihs_i2c.c b/drivers/i2c/ihs_i2c.c
>> index 29612e69fe..e066ad53db 100644
>> --- a/drivers/i2c/ihs_i2c.c
>> +++ b/drivers/i2c/ihs_i2c.c
>
>> @@ -182,13 +182,29 @@ static int ihs_i2c_probe(struct i2c_adapter *adap, uchar chip)
>>  static int ihs_i2c_read(struct i2c_adapter *adap, uchar chip, uint addr,
>>                         int alen, uchar *buffer, int len)
>>  {
>> -       return ihs_i2c_access(adap, chip, addr, alen, buffer, len, true);
>> +       u8 addr_bytes[4];
>> +
>> +       addr_bytes[0] = (addr >> 0) & 0xFF;
>> +       addr_bytes[1] = (addr >> 8) & 0xFF;
>> +       addr_bytes[2] = (addr >> 16) & 0xFF;
>> +       addr_bytes[3] = (addr >> 24) & 0xFF;
>
> Can you use put_unaligned_le32() or similar?
>

I wasn't aware that put_unaligned_le32 has been imported from the kernel; I've
used identical code in several I2C drivers, so I'll convert them in a separate
series as well.

>> +
>> +       return ihs_i2c_access(adap, chip, addr_bytes, alen, buffer, len,
>> +                             I2COP_READ);
>>  }
>>
>>  static int ihs_i2c_write(struct i2c_adapter *adap, uchar chip, uint addr,
>>                          int alen, uchar *buffer, int len)
>>  {
>> -       return ihs_i2c_access(adap, chip, addr, alen, buffer, len, false);
>> +       u8 addr_bytes[4];
>> +
>> +       addr_bytes[0] = (addr >> 0) & 0xFF;
>> +       addr_bytes[1] = (addr >> 8) & 0xFF;
>> +       addr_bytes[2] = (addr >> 16) & 0xFF;
>> +       addr_bytes[3] = (addr >> 24) & 0xFF;
>> +
>> +       return ihs_i2c_access(adap, chip, addr_bytes, alen, buffer, len,
>> +                             I2COP_WRITE);
>>  }
>>
>>  static unsigned int ihs_i2c_set_bus_speed(struct i2c_adapter *adap,
>> --
>> 2.11.0
>>
>
> Regards,
> Simon

Best regards,

Mario

^ permalink raw reply	[flat|nested] 138+ messages in thread

* [U-Boot] [PATCH 29/51] i2c: ihs_i2c: Make DM compatible
  2017-07-19  9:05   ` Simon Glass
@ 2017-07-25  7:50     ` Mario Six
  0 siblings, 0 replies; 138+ messages in thread
From: Mario Six @ 2017-07-25  7:50 UTC (permalink / raw)
  To: u-boot

Hi Simon,

On Wed, Jul 19, 2017 at 11:05 AM, Simon Glass <sjg@chromium.org> wrote:
> On 14 July 2017 at 05:55, Mario Six <mario.six@gdsys.cc> wrote:
>> Make the ihs_i2c driver DM-compatible; for legacy boards, the old functions are
>> retained within #ifdefs.
>>
>> No board uses the new DM driver yet; this patch only lays the foundation for
>> future support.
>>
>> Signed-off-by: Mario Six <mario.six@gdsys.cc>
>> ---
>>
>>  drivers/i2c/Kconfig          |   6 ++
>>  drivers/i2c/ihs_i2c.c        | 197 ++++++++++++++++++++++++++++++++++++++++++-
>>  scripts/config_whitelist.txt |   1 -
>>  3 files changed, 200 insertions(+), 4 deletions(-)
>
> Reviewed-by: Simon Glass <sjg@chromium.org>
>
> This is a step forward. But I wonder whether this should have an FPGA
> driver with an I2C driver as its child?
>

That's the idea; the fpga uclass is added in a later patch.

Best regards,

Mario

^ permalink raw reply	[flat|nested] 138+ messages in thread

* [U-Boot] [PATCH 31/51] gdsys: mpc8308: Add FPGA flavor option
  2017-07-19  9:05   ` Simon Glass
@ 2017-07-25  7:52     ` Mario Six
  0 siblings, 0 replies; 138+ messages in thread
From: Mario Six @ 2017-07-25  7:52 UTC (permalink / raw)
  To: u-boot

Hi Simon,

On Wed, Jul 19, 2017 at 11:05 AM, Simon Glass <sjg@chromium.org> wrote:
> On 14 July 2017 at 05:55, Mario Six <mario.six@gdsys.cc> wrote:
>> More recent versions of IHS FPGAs feature a different memory layout.
>>
>> Add a Kconfig option to differentiate between the legacy layout, and the
>> new layout (which is used on the upcoming "Gazerbeam" and later boards).
>>
>> Signed-off-by: Mario Six <mario.six@gdsys.cc>
>> ---
>>
>>  board/gdsys/mpc8308/Kconfig | 11 +++++++++++
>>  1 file changed, 11 insertions(+)
>>
>
> Reviewed-by: Simon Glass <sjg@chromium.org>
>
> Kconfig help?
>

I'll add a Kconfig help in v2.

>> diff --git a/board/gdsys/mpc8308/Kconfig b/board/gdsys/mpc8308/Kconfig
>> index e913e94b3a..80ac1a0f8a 100644
>> --- a/board/gdsys/mpc8308/Kconfig
>> +++ b/board/gdsys/mpc8308/Kconfig
>> @@ -55,6 +55,17 @@ config GDSYS_LEGACY_DRIVERS
>>
>>  endif
>>
>> +choice
>> +       prompt "FPGA flavor selection"
>> +
>> +config SYS_FPGA_FLAVOR_LEGACY
>> +       bool "Legacy flavor"
>> +
>> +config SYS_FPGA_FLAVOR_GAZERBEAM
>> +       bool "Gazerbeam flavor"
>> +
>> +endchoice
>> +
>>  config CMD_IOLOOP
>>         bool "Enable 'ioloop' and 'ioreflect' commands"
>>         help
>> --
>> 2.11.0
>>

Best regards,

Mario

^ permalink raw reply	[flat|nested] 138+ messages in thread

* [U-Boot] [PATCH 35/51] drivers: Add ICS8N3QV01 driver
  2017-07-19  9:05   ` Simon Glass
@ 2017-07-25  8:08     ` Mario Six
  0 siblings, 0 replies; 138+ messages in thread
From: Mario Six @ 2017-07-25  8:08 UTC (permalink / raw)
  To: u-boot

Hi Simon,

On Wed, Jul 19, 2017 at 11:05 AM, Simon Glass <sjg@chromium.org> wrote:
> On 14 July 2017 at 05:55, Mario Six <mario.six@gdsys.cc> wrote:
>> Add a driver for the ICS8N3QV01 Quad-Frequency Programmable VCXO.
>>
>> Signed-off-by: Mario Six <mario.six@gdsys.cc>
>> ---
>>
>>  drivers/clk/Kconfig      |   6 ++
>>  drivers/clk/Makefile     |   1 +
>>  drivers/clk/ics8n3qv01.c | 184 +++++++++++++++++++++++++++++++++++++++++++++++
>>  3 files changed, 191 insertions(+)
>>  create mode 100644 drivers/clk/ics8n3qv01.c
>>
>> diff --git a/drivers/clk/Kconfig b/drivers/clk/Kconfig
>> index 44da716b26..f6f3810b64 100644
>> --- a/drivers/clk/Kconfig
>> +++ b/drivers/clk/Kconfig
>> @@ -56,4 +56,10 @@ source "drivers/clk/uniphier/Kconfig"
>>  source "drivers/clk/exynos/Kconfig"
>>  source "drivers/clk/at91/Kconfig"
>>
>> +config ICS8N3QV01
>> +       bool "Enable ICS8N3QV01 VCXO driver"
>> +       depends on CLK
>> +       help
>> +         Support for the ICS8N3QV01 VCXO.
>
> What is this? Can you describe it a bit more here?
>

I'll add some details in v2.

>> +
>>  endmenu
>> diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile
>> index 2746a8016a..d7cc486d23 100644
>> --- a/drivers/clk/Makefile
>> +++ b/drivers/clk/Makefile
>> @@ -21,3 +21,4 @@ obj-$(CONFIG_CLK_BCM6345) += clk_bcm6345.o
>>  obj-$(CONFIG_CLK_BOSTON) += clk_boston.o
>>  obj-$(CONFIG_ARCH_ASPEED) += aspeed/
>>  obj-$(CONFIG_STM32F7) += clk_stm32f7.o
>> +obj-$(CONFIG_ICS8N3QV01) += ics8n3qv01.o
>
> Would be good if we could have these in alpha order. If you have time
> can you do a patch to tidy that up before or after?
>

Sure, I'll order them.

>> diff --git a/drivers/clk/ics8n3qv01.c b/drivers/clk/ics8n3qv01.c
>> new file mode 100644
>> index 0000000000..f5f4b74982
>> --- /dev/null
>> +++ b/drivers/clk/ics8n3qv01.c
>> @@ -0,0 +1,184 @@
>> +/*
>> + * (C) Copyright 2017
>> + * Mario Six,  Guntermann & Drunck GmbH, mario.six at gdsys.cc
>> + *
>> + * based on the gdsys osd driver, which is
>> + *
>> + * (C) Copyright 2010
>> + * Dirk Eibach,  Guntermann & Drunck GmbH, eibach at gdsys.de
>> + *
>> + * SPDX-License-Identifier:    GPL-2.0+
>> + */
>> +
>> +#include <common.h>
>> +#include <dm.h>
>> +#include <clk-uclass.h>
>> +#include <i2c.h>
>> +
>> +const long long ICS8N3QV01_FREF = 114285000;
>> +const long long ICS8N3QV01_FREF_LL = 114285000LL;
>> +const long long ICS8N3QV01_F_DEFAULT_0 = 156250000LL;
>> +const long long ICS8N3QV01_F_DEFAULT_1 = 125000000LL;
>> +const long long ICS8N3QV01_F_DEFAULT_2 = 100000000LL;
>> +const long long ICS8N3QV01_F_DEFAULT_3 = 25175000LL;
>> +
>> +struct ics8n3qv01_priv {
>> +       ulong rate;
>> +};
>> +
>> +static uint ics8n3qv01_get_fout_calc(struct udevice *dev, uint index)
>> +{
>> +       u64 n, mint, mfrac;
>> +       u8 reg_a, reg_b, reg_c, reg_d, reg_f;
>> +       u64 fout_calc;
>> +
>> +       if (index > 3)
>
> What is 3? Should this be an enum/#define?
>

The device is a VCXO (Voltage-Controlled Crystal Oscillator) that supplies four
frequencies (indexed 0 to 3), so accessing frequency indexes higher than 3
makes no sense. Maybe a MAX_FREQ_INDEX define would help to clarify the intent
here.

>> +               return 0;
>> +
>> +       reg_a = dm_i2c_reg_read(dev, 0 + index);
>
> Error checking?
>

I'll refactor the method to return an error code and use a output parameter for
the frequency (and add error checking, of course).

>> +       reg_b = dm_i2c_reg_read(dev, 4 + index);
>> +       reg_c = dm_i2c_reg_read(dev, 8 + index);
>> +       reg_d = dm_i2c_reg_read(dev, 12 + index);
>> +       reg_f = dm_i2c_reg_read(dev, 20 + index);
>> +
>> +       mint = ((reg_a >> 1) & 0x1f) | (reg_f & 0x20);
>> +       mfrac = ((reg_a & 0x01) << 17) | (reg_b << 9) | (reg_c << 1)
>> +               | (reg_d >> 7);
>> +       n = reg_d & 0x7f;
>> +
>> +       fout_calc = (mint * ICS8N3QV01_FREF_LL
>> +                    + mfrac * ICS8N3QV01_FREF_LL / 262144LL
>> +                    + ICS8N3QV01_FREF_LL / 524288LL
>> +                    + n / 2)
>> +                   / n
>> +                   * 1000000
>> +                   / (1000000 - 100);
>> +
>> +       return fout_calc;
>> +}
>> +
>> +static void ics8n3qv01_calc_parameters(uint fout, uint *_mint, uint *_mfrac,
>> +                                      uint *_n)
>> +{
>> +       uint n, foutiic, fvcoiic, mint;
>> +       u64 mfrac;
>> +
>> +       n = (2215000000U + fout / 2) / fout;
>> +       if ((n & 1) && (n > 5))
>> +               n -= 1;
>> +
>> +       foutiic = fout - (fout / 10000);
>> +       fvcoiic = foutiic * n;
>> +
>> +       mint = fvcoiic / 114285000;
>> +       if ((mint < 17) || (mint > 63))
>> +               printf("ics8n3qv01_calc_parameters: cannot determine mint\n");
>
> return error?
>

dito.

>> +
>> +       mfrac = ((u64)fvcoiic % 114285000LL) * 262144LL
>> +               / 114285000LL;
>> +
>> +       *_mint = mint;
>> +       *_mfrac = mfrac;
>> +       *_n = n;
>> +}
>> +
>> +static ulong ics8n3qv01_set_rate(struct clk *clk, ulong fout)
>> +{
>> +       struct ics8n3qv01_priv *priv = dev_get_priv(clk->dev);
>> +       uint n, mint, mfrac, fout_calc;
>> +       u64 fout_prog;
>> +       long long off_ppm;
>> +       u8 reg0, reg4, reg8, reg12, reg18, reg20;
>> +
>> +       priv->rate = fout;
>> +
>> +       fout_calc = ics8n3qv01_get_fout_calc(clk->dev, 1);
>> +       off_ppm = (fout_calc - ICS8N3QV01_F_DEFAULT_1) * 1000000
>> +                 / ICS8N3QV01_F_DEFAULT_1;
>> +       printf("%s: PLL is off by %lld ppm\n", clk->dev->name, off_ppm);
>
> debug()?
>

That's actually the "status message" we want to see from the clock during
startup; if we know that the value is reasonable during problem diagnosis, we
can be pretty sure that at least the pixel clock works reliably.

>> +       fout_prog = (u64)fout * (u64)fout_calc
>> +                   / ICS8N3QV01_F_DEFAULT_1;
>> +       ics8n3qv01_calc_parameters(fout_prog, &mint, &mfrac, &n);
>> +
>> +       reg0 = dm_i2c_reg_read(clk->dev, 0) & 0xc0;
>> +       reg0 |= (mint & 0x1f) << 1;
>> +       reg0 |= (mfrac >> 17) & 0x01;
>> +       dm_i2c_reg_write(clk->dev, 0, reg0);
>
> Check error?
>

See above, will refactor in v2.

>> +
>> +       reg4 = mfrac >> 9;
>> +       dm_i2c_reg_write(clk->dev, 4, reg4);
>> +
>> +       reg8 = mfrac >> 1;
>> +       dm_i2c_reg_write(clk->dev, 8, reg8);
>> +
>> +       reg12 = mfrac << 7;
>> +       reg12 |= n & 0x7f;
>> +       dm_i2c_reg_write(clk->dev, 12, reg12);
>> +
>> +       reg18 = dm_i2c_reg_read(clk->dev, 18) & 0x03;
>> +       reg18 |= 0x20;
>> +       dm_i2c_reg_write(clk->dev, 18, reg18);
>> +
>> +       reg20 = dm_i2c_reg_read(clk->dev, 20) & 0x1f;
>> +       reg20 |= mint & (1 << 5);
>> +       dm_i2c_reg_write(clk->dev, 20, reg20);
>> +
>> +       return 0;
>> +}
>> +
>> +static int ics8n3qv01_request(struct clk *clock)
>> +{
>> +       return 0;
>> +}
>> +
>> +static ulong ics8n3qv01_get_rate(struct clk *clk)
>> +{
>> +       struct ics8n3qv01_priv *priv = dev_get_priv(clk->dev);
>> +
>> +       return priv->rate;
>> +}
>> +
>> +static int ics8n3qv01_enable(struct clk *clk)
>> +{
>> +       return 0;
>> +}
>> +
>> +static int ics8n3qv01_disable(struct clk *clk)
>> +{
>> +       return 0;
>> +}
>> +
>> +static const struct clk_ops ics8n3qv01_ops = {
>> +       .request = ics8n3qv01_request,
>> +       .get_rate = ics8n3qv01_get_rate,
>> +       .set_rate = ics8n3qv01_set_rate,
>> +       .enable = ics8n3qv01_enable,
>> +       .disable = ics8n3qv01_disable,
>> +};
>> +
>> +static const struct udevice_id ics8n3qv01_ids[] = {
>> +       { .compatible = "idt,ics8n3qv01" },
>> +       { /* sentinel */ }
>> +};
>> +
>> +int ics8n3qv01_probe(struct udevice *dev)
>> +{
>> +       struct dm_i2c_chip *chip = dev_get_parent_platdata(dev);
>> +       struct udevice *dummy;
>> +
>> +       if (dm_i2c_probe(dev->parent, chip->chip_addr, chip->flags, &dummy)) {
>
> You should not need to probe here - DM should do this for you.
>

Ah, OK, the check was in the old ics8n3qv01 driver, so I just adapted it
verbatim to DM. I'll remove it in v2.

>> +               printf("ics8n3qv01: I2C probe did not succeed.\n");
>> +               return -1;
>> +       }
>> +
>> +       return 0;
>> +}
>> +
>> +U_BOOT_DRIVER(ics8n3qv01) = {
>> +       .name           = "ics8n3qv01",
>> +       .id             = UCLASS_CLK,
>> +       .ops            = &ics8n3qv01_ops,
>> +       .of_match       = ics8n3qv01_ids,
>> +       .probe          = ics8n3qv01_probe,
>> +       .priv_auto_alloc_size   = sizeof(struct ics8n3qv01_priv),
>> +};
>> --
>> 2.11.0
>>
>
> Regards,
> Simon

Best regards,

Mario

^ permalink raw reply	[flat|nested] 138+ messages in thread

* [U-Boot] [PATCH 41/51] cmd: Add ihs axi command
  2017-07-19  9:06   ` Simon Glass
@ 2017-07-25  8:14     ` Mario Six
  0 siblings, 0 replies; 138+ messages in thread
From: Mario Six @ 2017-07-25  8:14 UTC (permalink / raw)
  To: u-boot

Hi Simon,

On Wed, Jul 19, 2017 at 11:06 AM, Simon Glass <sjg@chromium.org> wrote:
> On 14 July 2017 at 05:55, Mario Six <mario.six@gdsys.cc> wrote:
>> Add a command to debug the IHS AXI bus.
>>
>> Signed-off-by: Mario Six <mario.six@gdsys.cc>
>> ---
>>
>>  cmd/Kconfig   |   5 ++
>>  cmd/Makefile  |   2 +
>>  cmd/ihs_axi.c | 257 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
>>  3 files changed, 264 insertions(+)
>>  create mode 100644 cmd/ihs_axi.c
>
> Reviewed-by: Simon Glass <sjg@chromium.org>
>
> nits below
>
>>
>> diff --git a/cmd/Kconfig b/cmd/Kconfig
>> index b632049022..4bbe9d435c 100644
>> --- a/cmd/Kconfig
>> +++ b/cmd/Kconfig
>> @@ -753,6 +753,11 @@ config CMD_SATA
>>           Attachment, where AT refers to an IBM AT (Advanced Technology)
>>           computer released in 1984.
>>
>> +config CMD_IHS_AXI
>> +       bool "axi"
>> +       help
>> +         Enable the GDSYS IHS AXI command for accessing the AXI bus.
>
> Can we make this help generic?
>
> depends on AXI
>
>

Will fix in v2. The AXI driver will have to become more general anyway, so
adjusting the matching command is prudent as well.

>> +
>>  endmenu
>>
>>
>> diff --git a/cmd/Makefile b/cmd/Makefile
>> index c30511982b..0baaf76b47 100644
>> --- a/cmd/Makefile
>> +++ b/cmd/Makefile
>> @@ -144,6 +144,8 @@ obj-$(CONFIG_CMD_DFU) += dfu.o
>>  obj-$(CONFIG_CMD_GPT) += gpt.o
>>  obj-$(CONFIG_CMD_ETHSW) += ethsw.o
>>
>> +obj-$(CONFIG_CMD_IHS_AXI) += ihs_axi.o
>> +
>>  # Power
>>  obj-$(CONFIG_CMD_PMIC) += pmic.o
>>  obj-$(CONFIG_CMD_REGULATOR) += regulator.o
>> diff --git a/cmd/ihs_axi.c b/cmd/ihs_axi.c
>> new file mode 100644
>> index 0000000000..336c239fae
>> --- /dev/null
>> +++ b/cmd/ihs_axi.c
>> @@ -0,0 +1,257 @@
>> +/*
>> + * (C) Copyright 2016
>> + * Dirk Eibach,  Guntermann & Drunck GmbH, dirk.eibach at gdsys.cc
>> + *
>> + * (C) Copyright 2017
>> + * Mario Six,  Guntermann & Drunck GmbH, mario.six at gdsys.cc
>> + *
>> + * SPDX-License-Identifier:    GPL-2.0+
>> + */
>> +
>> +#include <common.h>
>> +#include <dm.h>
>> +#include <command.h>
>> +#include <console.h>
>> +#include <ihs_axi.h>
>> +
>> +static struct udevice *axi_cur_bus;
>> +static uint dp_last_addr;
>> +static uint dp_last_length = 0x40;
>> +
>> +static void show_bus(struct udevice *bus)
>> +{
>> +       struct udevice *dev;
>> +
>> +       printf("Bus %d:\t%s", bus->req_seq, bus->name);
>> +       if (device_active(bus))
>> +               printf("  (active %d)", bus->seq);
>> +       printf("\n");
>> +       for (device_find_first_child(bus, &dev);
>> +            dev;
>> +            device_find_next_child(&dev)) {
>> +               //struct dm_i2c_chip *chip = dev_get_parent_platdata(dev);
>> +
>> +               //printf("   %02x: %s, offset len %x, flags %x\n",
>> +                      //chip->chip_addr, dev->name, chip->offset_len,
>> +                      //chip->flags);
>
> debug() ?
>

That's leftover development code, sorry. I'll move it to debug in v2.

>> +               printf("  %s\n", dev->name);
>> +       }
>> +}
>> +
>> +static int do_axi_show_bus(cmd_tbl_t *cmdtp, int flag, int argc,
>> +                          char * const argv[])
>> +{
>> +       if (argc == 1) {
>> +               /* show all busses */
>> +               struct udevice *bus;
>> +               struct uclass *uc;
>> +               int ret;
>> +
>> +               ret = uclass_get(UCLASS_IHS_AXI, &uc);
>> +               if (ret)
>> +                       return CMD_RET_FAILURE;
>> +               uclass_foreach_dev(bus, uc)
>> +                       show_bus(bus);
>> +       } else {
>> +               int i;
>> +
>> +               /* show specific bus */
>> +               i = simple_strtoul(argv[1], NULL, 10);
>> +
>> +               struct udevice *bus;
>> +               int ret;
>> +
>> +               ret = uclass_get_device_by_seq(UCLASS_IHS_AXI, i, &bus);
>
> This is fine, but note that above you may be looking at buses that are
> not probed (since you use the find API). Here the device will be
> probed.
>

Ah, I see. I'll equalize the behavior in v2.

>> +               if (ret) {
>> +                       printf("Invalid bus %d: err=%d\n", i, ret);
>> +                       return CMD_RET_FAILURE;
>> +               }
>> +               show_bus(bus);
>> +       }
>> +
>> +       return 0;
>> +}
>> +
>> +static int cmd_axi_set_bus_num(unsigned int busnum)
>> +{
>> +       struct udevice *bus;
>> +       int ret;
>> +
>> +       ret = uclass_get_device_by_seq(UCLASS_IHS_AXI, busnum, &bus);
>> +       if (ret) {
>> +               debug("%s: No bus %d\n", __func__, busnum);
>> +               return ret;
>> +       }
>> +       axi_cur_bus = bus;
>> +
>> +       return 0;
>> +}
>> +
>> +static int axi_get_cur_bus(struct udevice **busp)
>> +{
>> +       if (!axi_cur_bus) {
>> +               puts("No AXI bus selected\n");
>> +               return ENODEV;
>> +       }
>> +       *busp = axi_cur_bus;
>> +
>> +       return 0;
>> +}
>> +
>> +static int do_axi_bus_num(cmd_tbl_t *cmdtp, int flag, int argc,
>> +                         char * const argv[])
>> +{
>> +       int             ret = 0;
>> +       int     bus_no;
>> +
>> +       if (argc == 1) {
>> +               /* querying current setting */
>> +               struct udevice *bus;
>> +
>> +               if (!axi_get_cur_bus(&bus))
>> +                       bus_no = bus->seq;
>> +               else
>> +                       bus_no = -1;
>> +               printf("Current bus is %d\n", bus_no);
>> +       } else {
>> +               bus_no = simple_strtoul(argv[1], NULL, 10);
>> +               printf("Setting bus to %d\n", bus_no);
>> +
>> +               ret = cmd_axi_set_bus_num(bus_no);
>> +
>> +               if (ret)
>> +                       printf("Failure changing bus number (%d)\n", ret);
>> +       }
>> +
>> +       return ret ? CMD_RET_FAILURE : 0;
>> +}
>> +
>> +#define DISP_LINE_LEN  16
>> +
>> +int do_axi_md(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
>> +{
>> +       unsigned int k;
>> +       ulong   addr, length;
>> +       int rc = 0;
>> +       u32 linebuf[DISP_LINE_LEN / sizeof(u32)];
>> +       ulong nbytes;
>> +
>> +       /*
>> +        * We use the last specified parameters, unless new ones are
>> +        * entered.
>> +        */
>> +       addr = dp_last_addr;
>> +       length = dp_last_length;
>> +
>> +       if (argc < 2)
>> +               return CMD_RET_USAGE;
>> +
>> +       if (!axi_cur_bus) {
>> +               puts("No AXI bus selected\n");
>> +               return ENODEV;
>> +       }
>> +
>> +       if ((flag & CMD_FLAG_REPEAT) == 0) {
>> +               /*
>> +                * Address is specified since argc > 3
>> +                */
>> +               addr = simple_strtoul(argv[1], NULL, 16);
>> +
>> +               /*
>> +                * If another parameter, it is the length to display.
>> +                * Length is the number of objects, not number of bytes.
>> +                */
>> +               if (argc > 2)
>> +                       length = simple_strtoul(argv[2], NULL, 16);
>> +       }
>> +
>> +       nbytes = length * sizeof(u32);
>> +       do {
>> +               ulong linebytes = (nbytes > DISP_LINE_LEN) ?
>> +                                 DISP_LINE_LEN : nbytes;
>> +
>> +               for (k = 0; k < linebytes / sizeof(u32); ++k)
>> +                       axi_read(axi_cur_bus, addr + k * sizeof(u32),
>> +                                &linebuf[k]);
>> +               print_buffer(addr, (void *)linebuf, sizeof(u32),
>> +                            linebytes / sizeof(u32),
>> +                            DISP_LINE_LEN / sizeof(u32));
>> +
>> +               nbytes -= linebytes;
>> +               addr += linebytes;
>> +               if (ctrlc()) {
>> +                       rc = 1;
>> +                       break;
>> +               }
>> +       } while (nbytes > 0);
>> +
>> +       dp_last_addr = addr;
>> +       dp_last_length = length;
>> +
>> +       return rc;
>> +}
>> +
>> +static int do_axi_mw(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
>> +{
>> +       u32 writeval;
>> +       ulong addr, count;
>> +
>> +       if ((argc < 3) || (argc > 4))
>> +               return CMD_RET_USAGE;
>> +
>> +       /* Address is specified since argc > 3 */
>> +       addr = simple_strtoul(argv[1], NULL, 16);
>> +
>> +       /* Get the value to write.  */
>> +       writeval = simple_strtoul(argv[2], NULL, 16);
>> +
>> +       /* Count ? */
>> +       if (argc == 4)
>> +               count = simple_strtoul(argv[3], NULL, 16);
>> +       else
>> +               count = 1;
>> +
>> +       while (count-- > 0)
>> +               axi_write(axi_cur_bus, addr + count * sizeof(u32), writeval);
>
> Error check
>

Will add in v2.

>> +
>> +       return 0;
>> +}
>> +
>> +static cmd_tbl_t cmd_axi_sub[] = {
>> +       U_BOOT_CMD_MKENT(bus, 1, 1, do_axi_show_bus, "", ""),
>> +       U_BOOT_CMD_MKENT(dev, 1, 1, do_axi_bus_num, "", ""),
>> +       U_BOOT_CMD_MKENT(md, 3, 1, do_axi_md, "", ""),
>> +       U_BOOT_CMD_MKENT(mw, 4, 1, do_axi_mw, "", ""),
>> +};
>> +
>> +static int do_ihs_axi(cmd_tbl_t *cmdtp, int flag, int argc,
>> +                     char * const argv[])
>> +{
>> +       cmd_tbl_t *c;
>> +
>> +       if (argc < 2)
>> +               return CMD_RET_USAGE;
>> +
>> +       /* Strip off leading 'axi' command argument */
>> +       argc--;
>> +       argv++;
>> +
>> +       c = find_cmd_tbl(argv[0], &cmd_axi_sub[0], ARRAY_SIZE(cmd_axi_sub));
>> +
>> +       if (c)
>> +               return c->cmd(cmdtp, flag, argc, argv);
>> +       else
>> +               return CMD_RET_USAGE;
>> +}
>> +
>> +static char axi_help_text[] =
>> +       "bus  - show AXI bus info\n"
>> +       "axi dev [dev] - show or set current AXI bus\n"
>> +       "axi md address [# of objects] - read from AXI device\n"
>> +       "axi mw address value [count] - write to AXI device (fill)\n";
>> +
>> +U_BOOT_CMD(
>> +       axi, 7, 1, do_ihs_axi,
>> +       "AXI sub-system",
>> +       axi_help_text
>> +);
>> --
>> 2.11.0
>>
>
> Regards,
> Simon

Best regards,

Mario

^ permalink raw reply	[flat|nested] 138+ messages in thread

* [U-Boot] [PATCH 09/51] phy: Support Marvell 88X2242
  2017-07-18 14:01   ` Simon Glass
@ 2017-07-25  8:22     ` Mario Six
  2017-07-27 21:23       ` Joe Hershberger
  0 siblings, 1 reply; 138+ messages in thread
From: Mario Six @ 2017-07-25  8:22 UTC (permalink / raw)
  To: u-boot

Hi Simon,

On Tue, Jul 18, 2017 at 4:01 PM, Simon Glass <sjg@chromium.org> wrote:
> Hi Mario,
>
> On 14 July 2017 at 05:54, Mario Six <mario.six@gdsys.cc> wrote:
>> From: Dirk Eibach <dirk.eibach@gdsys.cc>
>>
>> Implement support for the Marvell Alaska X 88X2242P Integrated Dual-port
>> and Quad-port Multi-speed Ethernet Transceivers.
>>
>> Signed-off-by: Dirk Eibach <dirk.eibach@gdsys.cc>
>> Signed-off-by: Mario Six <mario.six@gdsys.cc>
>> ---
>>
>>  drivers/net/phy/Kconfig   |  67 ++++
>>  drivers/net/phy/Makefile  |   1 +
>>  drivers/net/phy/marvell.c |   1 -
>>  drivers/net/phy/mv88x2.c  | 846 ++++++++++++++++++++++++++++++++++++++++++++++
>>  drivers/net/phy/mv88x2.h  |  12 +
>>  drivers/net/phy/phy.c     |   3 +
>>  include/phy.h             |   1 +
>>  7 files changed, 930 insertions(+), 1 deletion(-)
>>  create mode 100644 drivers/net/phy/mv88x2.c
>>  create mode 100644 drivers/net/phy/mv88x2.h
>>
>
> We should really be using driver model here. Is the generic phy uclass
> good enough (generic-phy.h), or do we need a new uclass for Ethernet
> PHY?
>

Wouldn't we also need a uclass for MDIO/MII interfaces then? I don't know the
network subsystem too well, so I can't really tell where a ethernet phy uclass
(or a MDIO uclass for that matter) would interface with the rest of it.

> Regards,
> Simon

Best regards,

Mario

^ permalink raw reply	[flat|nested] 138+ messages in thread

* [U-Boot] [PATCH 18/51] cmd: mdio: Add 'driver' subcommand
  2017-07-18 14:02   ` Simon Glass
@ 2017-07-25  8:25     ` Mario Six
  0 siblings, 0 replies; 138+ messages in thread
From: Mario Six @ 2017-07-25  8:25 UTC (permalink / raw)
  To: u-boot

Hi Simon,

On Tue, Jul 18, 2017 at 4:02 PM, Simon Glass <sjg@chromium.org> wrote:
> Hi Mario,
>
> On 14 July 2017 at 05:55, Mario Six <mario.six@gdsys.cc> wrote:
>> For debug purposes it is sometimes useful to have the ability to
>> interact with the driver functionality of a phy from the command line
>> (e.g. to manually issue startup, configuration, or shutdown commands to
>> the phy device).
>>
>> This patch adds such a command, which allows issuing the following
>> commands to a phy:
>>  * getting the driver's name
>>  * running the phy's configuration procedure (via calling phy_config)
>>  * running the phy's startup procedure (via calling phy_startup)
>>  * running the phy's shutdown procedure (via calling phy_shutdown)
>>
>> Signed-off-by: Mario Six <mario.six@gdsys.cc>
>> ---
>>
>>  cmd/Kconfig |  6 ++++++
>>  cmd/mdio.c  | 65 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
>>  2 files changed, 71 insertions(+)
>
> This seems reasonable, but we need to figure out how to use driver model.
>
> Regards,
> Simon

Probably with a MDIO/MII uclass, see my comment on patch 9 ("phy: Support
Marvell 88X2242").

Best regards,

Mario

^ permalink raw reply	[flat|nested] 138+ messages in thread

* [U-Boot] [PATCH 21/51] common: Extend board-specific DT fixup
  2017-07-19  9:05   ` Simon Glass
@ 2017-07-25  8:40     ` Mario Six
  0 siblings, 0 replies; 138+ messages in thread
From: Mario Six @ 2017-07-25  8:40 UTC (permalink / raw)
  To: u-boot

Hi Simon,

On Wed, Jul 19, 2017 at 11:05 AM, Simon Glass <sjg@chromium.org> wrote:
> Hi Mario,
>
> On 14 July 2017 at 05:55, Mario Six <mario.six@gdsys.cc> wrote:
>> Commit 2a79275 ("dm: Add callback to modify the device tree")
>> implemented a board-specific callback that can modify U-Boot's device
>> tree before relocation to accomodate a range of hardware variations of
>> certain boards.
>>
>> However, this approach only turns out to be useful when the copy of the
>> device tree before relocation is actually writeable. If e.g. a device
>> boots out of a NOR flash, this scheme does not work, since the
>> modification of the flash's contents is not possible, and the unmodified
>> device tree is relocated and used by U-Boot.
>>
>> To circumvent this problem, we split the modification process into two
>> phases.
>>
>> In phase one we only collect information about the board by querying the
>> hardware (reading GPIO values, probing I2C chips, etc.), and store the
>> obtained information in a special, board-specific structure that is part
>> of the global data structure. This phase runs prior to relocation, and
>> utilizes the pre-relocation DM to query hardware information.
>>
>> In phase two, we read the information back from the structure, and do
>> the actual manipulation of the device tree. This phase occurs *after*
>> the relocation of the U-Boot image, but before the driver model is
>> initialized from the device tree. Since the device tree lives in RAM
>> alongside the U-Boot image after relocation, the tree is definitely
>> writeable at this point.
>>
>> Each phase is implemented by a board-specific callback function: phase
>> one by board_fix_fdt_get_info, which takes no arguments, and phase two
>> by board_fix_fdt_change, which takes the writeable device tree blob as
>> its sole argument. Since the structure where the gathered hardware
>> information is stored is necessarily board-dependent, we create a
>> include file where the boards utilizing the functionality can define
>> their individually needed structures.
>>
>> This commit also adapts the controlcenterdc board's fixup function to
>> the new schem
>
> Thanks for the clear explanation.
>
> I have two ideas:
>
> - Can we move the call to the existing function to after reloc_fdt(),
> when the DT is in RAM?
>

That might work, but I'm not sure if it was one of the scenarios which didn't
work for some reason that I tried out before. I'll have to test it.

> - Or can we move this board to use a livetree and adjust the DT using
> livetree functions instead? That might be more efficient.
>

That was actually plan A, but even after applying some of your recent livetree
patches (for ns16550 and such), the boot got stuck very early on, so I didn't
follow this option more than that. It would, of course, be the cleanest
solution, but considering the amount of drivers that would need conversion, and
the absence of actual DT manipulation functions (include/dm/write.h doesn't
exist yet), it's a pretty daunting task.

But I'll look into it.

> Regards,
> Simon
>

Best regards,

Mario

^ permalink raw reply	[flat|nested] 138+ messages in thread

* [U-Boot] [PATCH 32/51] drivers: Add ihs_fpga and gdsys_soc drivers
  2017-07-19  9:06   ` Simon Glass
@ 2017-07-25  9:22     ` Mario Six
  0 siblings, 0 replies; 138+ messages in thread
From: Mario Six @ 2017-07-25  9:22 UTC (permalink / raw)
  To: u-boot

Hi Simon,

On Wed, Jul 19, 2017 at 11:06 AM, Simon Glass <sjg@chromium.org> wrote:
> Hi Mario,
>
> On 14 July 2017 at 05:55, Mario Six <mario.six@gdsys.cc> wrote:
>> This patch adds DM drivers for IHS FPGAs and their associated busses, as
>> well as uclasses for both.
>>
>> Signed-off-by: Mario Six <mario.six@gdsys.cc>
>> ---
>>
>>  drivers/misc/Kconfig     |   6 +
>>  drivers/misc/Makefile    |   1 +
>>  drivers/misc/gdsys_soc.c |  51 +++
>>  drivers/misc/ihs_fpga.c  | 871 +++++++++++++++++++++++++++++++++++++++++++++++
>>  include/dm/uclass-id.h   |   2 +
>>  include/gdsys_soc.h      |  29 ++
>>  include/ihs_fpga.h       | 111 ++++++
>>  7 files changed, 1071 insertions(+)
>>  create mode 100644 drivers/misc/gdsys_soc.c
>>  create mode 100644 drivers/misc/ihs_fpga.c
>>  create mode 100644 include/gdsys_soc.h
>>  create mode 100644 include/ihs_fpga.h
>
> There are definitely cases where you we might have a unique peripheral
> and want to add a uclass for it.
>
> But for what you have here, could we use UCLASS_SYSCON for the soc bus?
>

OK, I wasn't aware that the syscon uclass could be used in such a case.

> For the FPGA could we add a new FPGA uclass? It could have read and
> write methods a bit like struct pci_ops where you specify the size of
> the read/write. I think that would be useful generally.
>
> [..]
>

OK, I guess I can make a general FPGA class. But wouldn't that collide with the
type of functionality we have in drivers/fpga now? That code is more concerned
with getting a FPGA to run (load a bit file from somewhere and similar
functions) than accessing the register interface of a running FPGA from what I
can see. Would that be eventually absorbed into the new uclass? Or should those
be different uclasses? Should I put the "new" fpga-uclass.c file in
drivers/fpga, or make a new directory?

>> +static int ihs_fpga_set_reg(struct udevice *dev, const char *compat,
>> +                           uint value)
>> +{
>> +       struct ihs_fpga_priv *priv = dev_get_priv(dev);
>> +       struct reg_spec spec;
>> +
>> +       if (get_reg_spec(dev, compat, &spec)) {
>> +               printf("%s: Could not get %s regspec for '%s'.\n", __func__,
>> +                      dev->name, compat);
>> +               return -ENODEV;
>
> Can you return the error from get_reg_spec()? Also -ENODEV means no
> device which cannot be true if you have  a dev pointer. Perhaps
> -ENXIO?
>

Yes, that's a copy-paste-error; I'll fix it in v2.

>> +       }
>> +
>> +       out_le16((void *)(priv->regs + spec.addr), value << spec.shift);
>> +
>> +       return 0;
>> +}
>> +
>> +static int ihs_fpga_get_reg(struct udevice *dev, const char *compat,
>> +                           uint *value)
>> +{
>> +       struct ihs_fpga_priv *priv = dev_get_priv(dev);
>> +       struct reg_spec spec;
>> +       uint tmp;
>> +
>> +       if (get_reg_spec(dev, compat, &spec)) {
>> +               printf("%s: Could not get %s regspec for '%s'.\n", __func__,
>> +                      dev->name, compat);
>
> Can we use debug() in drivers?
>

Will fix in v2.

>> +               return -ENODEV;
>> +       }
>> +
>> +       tmp = in_le16((void *)(priv->regs + spec.addr));
>> +       *value = (tmp & spec.mask) >> spec.shift;
>> +
>> +       return 0;
>> +}
>> +
>> +static u16 ihs_fpga_in_le16(struct udevice *dev, phys_addr_t addr)
>> +{
>> +       struct ihs_fpga_priv *priv = dev_get_priv(dev);
>> +
>> +       /* TODO: MCLink transfer */
>> +
>> +       return in_le16((void *)(priv->regs + addr));
>> +}
>> +
>> +static void ihs_fpga_out_le16(struct udevice *dev, phys_addr_t addr, u16 value)
>> +{
>> +       struct ihs_fpga_priv *priv = dev_get_priv(dev);
>> +
>> +       /* TODO: MCLink transfer */
>> +
>> +       out_le16((void *)(priv->regs + addr), value);
>> +}
>> +
>> +static const struct ihs_fpga_ops ihs_fpga_ops = {
>> +       .set_reg = ihs_fpga_set_reg,
>> +       .get_reg = ihs_fpga_get_reg,
>> +       .in_le16 = ihs_fpga_in_le16,
>> +       .out_le16 = ihs_fpga_out_le16,
>> +};
>> +
>> +static int ihs_fpga_probe(struct udevice *dev)
>> +{
>> +       struct ihs_fpga_priv *priv = dev_get_priv(dev);
>> +       fdt_addr_t addr;
>> +       struct fdtdec_phandle_args phandle_args;
>
> Since this is new code I think using the dev_read_...() functions is better
>

OK, I'll switch it to the new API in v2. I had this code lying around for a
bit, so it still uses the old interface.

>> +       struct fdtdec_phandle_args args;
>> +       struct udevice *busdev = NULL;
>> +       struct udevice *child = NULL;
>> +       uint mem_width;
>> +
>> +       if (fdtdec_parse_phandle_with_args(gd->fdt_blob, dev_of_offset(dev),
>> +                                          "regmap", NULL, 0, 0, &args)) {
>> +               printf("%s: Could not get regmap.\n", dev->name);
>> +               return 1;
>> +       }
>> +
>> +       priv->regmap_node = args.node;
>> +
>> +       addr = devfdt_get_addr(dev);
>> +
>> +       priv->addr = addr;
>> +       priv->regs = map_sysmem(addr, mem_width);
>> +
>> +       gpio_request_by_name(dev, "reset-gpios", 0, &priv->reset_gpio,
>> +                            GPIOD_IS_OUT);
>> +       if (!priv->reset_gpio.dev)
>
> You should check the return value of the function. How come you don't
> return the error code here? If it is OK to not have a GPIO then use
> dm_gpio_is_valid() - and hopefully debug() instead of printf().
>

I since found this error myself; the probe should really fail if we can't get
the GPIOs (since we can't start the FPGA in this case). Will be fixed in v2.

>> +               printf("%s: Could not get reset-GPIO.\n", dev->name);
>> +
>> +       gpio_request_by_name(dev, "done-gpios", 0, &priv->done_gpio,
>> +                            GPIOD_IS_IN);
>> +       if (!priv->done_gpio.dev)
>> +               printf("%s: Could not get done-GPIO.\n", dev->name);
>> +
>> +       dm_gpio_set_value(&priv->reset_gpio, 1);
>
> Error check? This returns -ENOENT if the GPIO is not valid (as above)
> so you could filter that out, or use dm_gpo_is_valid() to avoid
> calling it.
>

Dito, should make the probe fail. Will fix in v2.

>> +
>> +       signal_startup_finished(dev);
>> +
>> +       if (!do_reflection_test(dev)) {
>> +               int ctr = 0;
>> +
>> +               dm_gpio_set_value(&priv->reset_gpio, 0);
>> +
>> +               while (!dm_gpio_get_value(&priv->done_gpio)) {
>> +                       mdelay(100);
>> +                       if (ctr++ > 5) {
>> +                               printf("Initializing FPGA failed\n");
>> +                               break;
>> +                       }
>> +               }
>> +
>> +               udelay(10);
>> +
>> +               dm_gpio_set_value(&priv->reset_gpio, 1);
>> +
>> +               if (!do_reflection_test(dev)) {
>> +                       printf("%s: Reflection test FAILED.\n", dev->name);
>> +                       return -1;
>
> This is -EPERM. Perhaps use -EIO? Better to return vaue from the
> do_reflection_tests() call.
>

Will fix in v2.

>> +               }
>> +       }
>> +
>> +       printf("%s: Reflection test passed.\n", dev->name);
>
> debug()?
>

That's actually another status message: If it's printed, we know that at least
the FPGA is alive.

>> +
>> +       if (fdtdec_parse_phandle_with_args(gd->fdt_blob, dev_of_offset(dev), "bus",
>> +                                          NULL, 0, 0, &phandle_args))
>> +               return -1;
>> +
>> +       lists_bind_fdt(dev, offset_to_ofnode(phandle_args.node), &busdev);
>
> Should this be dm_scan_fdt_dev,()?
>
> Also should go in bind() method
>

I could use dm_scan_fdt_dev here, but if you take a look in the device tree,
you'll see that the FPGA's bus is not actually a child of the FPGA itself, but
of the root node (that's a quirk from the Linux driver; you will probably see
more of this in the course of the series, I'm afraid). So to make it less
confusing in U-Boot, I use lists_bind_fdt to explicitly bind the bus as a child
of the FPGA. It's pretty much a cosmetic thing, though.

I'll move it to bind() in v2.

>> +
>> +       fpga_print_info(dev);
>> +
>> +       /* TODO: Check if this should be gazerbeam-specific */
>> +       if (priv->has_osd) {
>> +               /* Disable softcore, select external pixclock */
>> +               fpga_set_reg(dev, "control", 0x8000);
>> +       }
>> +
>> +       device_probe(busdev);
>> +
>> +       for (device_find_first_child(busdev, &child);
>> +            child;
>> +            device_find_next_child(&child))
>> +               device_probe(child);
>
> The children should be probed when used by things like uclass_get_device()...
>
> We should not be probing them here.
>

The way the old drivers (board/gdsys/common) worked was that everything was
explicitly initialized/probed/turned on during startup unconditionally, and I
tried to replicate this behavior here.

For the Gazerbeam CON device, DM's lazy probing would probably work as well,
since we display a startup screen on the OSD via some OSD commands in a U-Boot
script (which would in turn probe all devices we need). The Gazerbeam CPU in
contrast doesn't have a OSD, but we need to program the FPGA regardless.

So, how do I make sure that the FPGA is activated in this case (without
explicit probing, that is)?

>> +
>> +       return 0;
>> +}
>> +
>> +static const struct udevice_id ihs_fpga_ids[] = {
>> +       { .compatible = "gdsys,iocon_fpga" },
>> +       { .compatible = "gdsys,iocpu_fpga" },
>> +       { }
>> +};
>> +
>> +U_BOOT_DRIVER(ihs_fpga_bus) = {
>> +       .name           = "ihs_fpga_bus",
>> +       .id             = UCLASS_IHS_FPGA,
>> +       .ops            = &ihs_fpga_ops,
>> +       .of_match       = ihs_fpga_ids,
>> +       .probe          = ihs_fpga_probe,
>> +       .priv_auto_alloc_size = sizeof(struct ihs_fpga_priv),
>> +};
>> diff --git a/include/dm/uclass-id.h b/include/dm/uclass-id.h
>> index 2e6498b7dc..56fbedaa9d 100644
>> --- a/include/dm/uclass-id.h
>> +++ b/include/dm/uclass-id.h
>> @@ -35,12 +35,14 @@ enum uclass_id {
>>         UCLASS_DISPLAY,         /* Display (e.g. DisplayPort, HDMI) */
>>         UCLASS_DMA,             /* Direct Memory Access */
>>         UCLASS_ETH,             /* Ethernet device */
>> +       UCLASS_GDSYS_SOC,       /* gdsys soc buses */
>>         UCLASS_GPIO,            /* Bank of general-purpose I/O pins */
>>         UCLASS_FIRMWARE,        /* Firmware */
>>         UCLASS_I2C,             /* I2C bus */
>>         UCLASS_I2C_EEPROM,      /* I2C EEPROM device */
>>         UCLASS_I2C_GENERIC,     /* Generic I2C device */
>>         UCLASS_I2C_MUX,         /* I2C multiplexer */
>> +       UCLASS_IHS_FPGA,        /* gdsys IHS FPGAs */
>>         UCLASS_IRQ,             /* Interrupt controller */
>>         UCLASS_KEYBOARD,        /* Keyboard input device */
>>         UCLASS_LED,             /* Light-emitting diode (LED) */
>> diff --git a/include/gdsys_soc.h b/include/gdsys_soc.h
>> new file mode 100644
>> index 0000000000..2164651f62
>> --- /dev/null
>> +++ b/include/gdsys_soc.h
>> @@ -0,0 +1,29 @@
>> +/*
>> + * (C) Copyright 2017
>> + * Mario Six,  Guntermann & Drunck GmbH, mario.six at gdsys.cc
>> + *
>> + * SPDX-License-Identifier:    GPL-2.0+
>> + */
>> +
>> +#ifndef _GDSYS_SOC_H_
>> +#define _GDSYS_SOC_H_
>> +
>> +/**
>> + * struct gdsys_soc_child_platdata - platform data for devices on gdsys soc
>> + *                                  buses
>> + *
>> + * To access their register maps, devices on gdsys soc buses usually have
>> + * facilitate the accessor function of the IHS FPGA their parent bus is
>> + * attached to. To pass the FPGA device down to the bus' children, a pointer to
>> + * it is contained in this structure.
>> + *
>> + * To obtain this structure, use dev_get_parent_platdata(dev) where dev is a
>> + * device on the gdsys soc bus.
>> + *
>> + * @fpga:      The IHS FPGA that controls the bus the device is attached to.
>> + */
>> +struct gdsys_soc_child_platdata {
>> +       struct udevice *fpga;
>> +};
>> +
>> +#endif /* _GDSYS_SOC_H_ */
>> diff --git a/include/ihs_fpga.h b/include/ihs_fpga.h
>> new file mode 100644
>> index 0000000000..552583cbe1
>> --- /dev/null
>> +++ b/include/ihs_fpga.h
>> @@ -0,0 +1,111 @@
>> +/*
>> + * (C) Copyright 2017
>> + * Mario Six,  Guntermann & Drunck GmbH, mario.six at gdsys.cc
>> + *
>> + * SPDX-License-Identifier:    GPL-2.0+
>> + */
>> +
>> +#ifndef _IHS_FPGA_H_
>> +#define _IHS_FPGA_H_
>> +
>> +/**
>> + * struct ihs_fpga_ops - driver operations for IHS FPGA 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 ihs_fpga_ops {
>> +       /**
>> +        * get_reg() - Get value of a named FPGA register
>> +        *
>> +        * To accommodate possible future memory layout changes, the registers
>> +        * of a IHS FPGA are described in the device tree, and each is given a
>> +        * distinct compatible string to address them with.
>> +        *
>> +        * @dev:        FPGA device to read from.
>> +        * @compat:     The compatible string of the register to write to.
>> +        * @value:      Pointer to a variable that takes the value read from the
>> +        *              register.
>> +        * @return 0 if OK, -ENODEV if no named register with the given
>> +        *  compatibility string exists.
>> +        */
>> +       int (*get_reg)(struct udevice *dev, const char *compat, uint *value);
>> +
>> +       /**
>> +        * set_reg() - Set value of a named FPGA register
>> +        *
>> +        * To accommodate possible future memory layout changes, the registers
>> +        * of a IHS FPGA are described in the device tree, and each is given a
>> +        * distinct compatible string to address them with.
>> +        *
>> +        * @dev:        FPGA device to write to.
>> +        * @compat:     The compatible string of the register to write to.
>> +        * @value:      Value to write to the register.
>> +        * @return 0 if OK, -ENODEV if no named register with the given
>> +        *      compatibility string exists.
>> +        */
>> +       int (*set_reg)(struct udevice *dev, const char *compat, uint value);
>> +
>> +       /**
>> +        * in_le16() - Read 16 bit value from address in FPGA register space
>> +        *
>> +        * @dev:        FPGA device to read from.
>> +        * @addr:       Address in the FPGA register space to read from.
>> +        * @return 0 if OK, -ve on error.
>> +        */
>> +       u16 (*in_le16)(struct udevice *dev, phys_addr_t addr);
>> +
>> +       /**
>> +        * out_le16() - Write 16 bit value to address in FPGA register space
>> +        *
>> +        * @dev:        FPGA device to write to.
>> +        * @addr:       Address in the FPGA register space to write to.
>> +        * @return 0 if OK, -ve on error.
>> +        */
>> +       void (*out_le16)(struct udevice *dev, phys_addr_t addr, u16 value);
>> +};
>> +
>> +#define ihs_fpga_get_ops(dev)  ((struct ihs_fpga_ops *)(dev)->driver->ops)
>> +
>> +/**
>> + * fpga_get_reg() - Get value of a named FPGA register
>> + *
>> + * @dev:       FPGA device to read from.
>> + * @compat:    The compatible string of the register to write to.
>> + * @value:     Pointer to a variable that takes the value read from the register.
>> + * @return 0 if OK, -ENODEV if no named register with the given compatibility
>> + *  string exists.
>> + */
>> +int fpga_get_reg(struct udevice *dev, const char *compat, uint *value);
>> +
>> +/**
>> + * fpga_set_reg() - Set value of a named FPGA register
>> + *
>> + * @dev:       FPGA device to write to.
>> + * @compat:    The compatible string of the register to write to.
>> + * @value:     Value to write to the register.
>> + * @return 0 if OK, -ENODEV if no named register with the given compatibility
>> + *  string exists.
>> + */
>> +int fpga_set_reg(struct udevice *dev, const char *compat, uint value);
>> +
>> +/**
>> + * fpga_in_le16() - Read 16 bit value from address in FPGA register space
>> + *
>> + * @dev:       FPGA device to read from.
>> + * @addr:      Address in the FPGA register space to read from.
>> + * @return 0 if OK, -ve on error.
>> + */
>> +u16 fpga_in_le16(struct udevice *dev, phys_addr_t addr);
>> +
>> +/**
>> + * fpga_out_le16() - Write 16 bit value to address in FPGA register space
>> + *
>> + * @dev:       FPGA device to write to.
>> + * @addr:      Address in the FPGA register space to write to.
>> + * @return 0 if OK, -ve on error.
>> + */
>> +void fpga_out_le16(struct udevice *dev, phys_addr_t addr, u16 value);
>> +
>> +#endif /* !_IHS_FPGA_H_ */
>> --
>> 2.11.0
>>
>
> Regards,
> Simon

Best regards,

Mario

^ permalink raw reply	[flat|nested] 138+ messages in thread

* [U-Boot] [PATCH 33/51] drivers: Add transmitter uclass
  2017-07-19  9:05   ` Simon Glass
@ 2017-07-25  9:29     ` Mario Six
  0 siblings, 0 replies; 138+ messages in thread
From: Mario Six @ 2017-07-25  9:29 UTC (permalink / raw)
  To: u-boot

Hi Simon,

On Wed, Jul 19, 2017 at 11:05 AM, Simon Glass <sjg@chromium.org> wrote:
> Hi Mario,
>
> On 14 July 2017 at 05:55, Mario Six <mario.six@gdsys.cc> wrote:
>> This patch adds a simple transmitter uclass meant for DVI or DisplayPort
>> transmitters. The only driver functionality implemented are power_on and
>> power_off methods for powering the transmitter device on and off,
>> respectively.
>
> Could we use UCLASS_DISPLAY for this? We are using that for things
> like DisplayPort and HDMI.
>
> If so you could add any missing operation and move your tests to that?
>

OK, I thought the display uclass consisted of literal displays (as in LCD
screens and such).

I'll use that uclass in v2 then.

>>
>> Signed-off-by: Mario Six <mario.six@gdsys.cc>
>> ---
>>
>>  arch/sandbox/dts/sandbox.dts              |  4 ++
>>  arch/sandbox/dts/test.dts                 |  4 ++
>>  configs/sandbox_defconfig                 |  2 +
>>  drivers/Kconfig                           |  2 +
>>  drivers/Makefile                          |  1 +
>>  drivers/transmitter/Kconfig               | 16 +++++++
>>  drivers/transmitter/Makefile              |  9 ++++
>>  drivers/transmitter/sandbox_transmitter.c | 74 +++++++++++++++++++++++++++++++
>>  drivers/transmitter/transmitter-uclass.c  | 36 +++++++++++++++
>>  include/dm/uclass-id.h                    |  1 +
>>  include/transmitter.h                     | 49 ++++++++++++++++++++
>>  test/dm/Makefile                          |  1 +
>>  test/dm/transmitter.c                     | 31 +++++++++++++
>>  13 files changed, 230 insertions(+)
>>  create mode 100644 drivers/transmitter/Kconfig
>>  create mode 100644 drivers/transmitter/Makefile
>>  create mode 100644 drivers/transmitter/sandbox_transmitter.c
>>  create mode 100644 drivers/transmitter/transmitter-uclass.c
>>  create mode 100644 include/transmitter.h
>>  create mode 100644 test/dm/transmitter.c
>>
>
> Regards,
> Simon

Best regards,

Mario

^ permalink raw reply	[flat|nested] 138+ messages in thread

* [U-Boot] [PATCH 34/51] transmitter: Add Xilinx LogiCore DP TX
  2017-07-19  9:06   ` Simon Glass
@ 2017-07-25  9:48     ` Mario Six
  0 siblings, 0 replies; 138+ messages in thread
From: Mario Six @ 2017-07-25  9:48 UTC (permalink / raw)
  To: u-boot

Hi Simon,

On Wed, Jul 19, 2017 at 11:06 AM, Simon Glass <sjg@chromium.org> wrote:
> On 14 July 2017 at 05:55, Mario Six <mario.six@gdsys.cc> wrote:
>> Add a driver for the TX side of the Xilinx LogiCore DisplayPort IP core.
>>
>> Signed-off-by: Mario Six <mario.six@gdsys.cc>
>> ---
>>
>>  drivers/transmitter/Kconfig                |    6 +
>>  drivers/transmitter/Makefile               |    1 +
>>  drivers/transmitter/logicore_dp_dpcd.h     |  342 +++++
>>  drivers/transmitter/logicore_dp_tx.c       | 1984 ++++++++++++++++++++++++++++
>>  drivers/transmitter/logicore_dp_tx.h       |   40 +
>>  drivers/transmitter/logicore_dp_tx_regif.h |  365 +++++
>>  6 files changed, 2738 insertions(+)
>>  create mode 100644 drivers/transmitter/logicore_dp_dpcd.h
>>  create mode 100644 drivers/transmitter/logicore_dp_tx.c
>>  create mode 100644 drivers/transmitter/logicore_dp_tx.h
>>  create mode 100644 drivers/transmitter/logicore_dp_tx_regif.h
>
> Can we use UCLASS_DISPLAY?
>

Yes, the display uclass should work; I'll move it there in v2.

>>
>> diff --git a/drivers/transmitter/Kconfig b/drivers/transmitter/Kconfig
>> index 64ca08f8b8..e5613586a3 100644
>> --- a/drivers/transmitter/Kconfig
>> +++ b/drivers/transmitter/Kconfig
>> @@ -13,4 +13,10 @@ config SANDBOX_TRANSMITTER
>>         help
>>           Enable the dummy transmitter for the sandbox.
>>
>> +config LOGICORE_DP_TX
>> +       bool "Enable Logicore DP TX driver"
>> +       depends on DM
>
> DM_VIDEO?
>

As soon as it's move to the display uclass, naturally. :-)

>> +       help
>> +         Enabled the driver for the Logicore DP TX display port transmitter.
>
> Enable. Also can you expand this help to explain what it is?
>

I'll expand the help text a bit in v2.

>> +
>>  endif
>> diff --git a/drivers/transmitter/Makefile b/drivers/transmitter/Makefile
>> index b873e63e28..088922d992 100644
>> --- a/drivers/transmitter/Makefile
>> +++ b/drivers/transmitter/Makefile
>> @@ -7,3 +7,4 @@
>>
>>  obj-y += transmitter-uclass.o
>>  obj-$(CONFIG_SANDBOX_TRANSMITTER) += sandbox_transmitter.o
>> +obj-$(CONFIG_LOGICORE_DP_TX) += logicore_dp_tx.o
>> diff --git a/drivers/transmitter/logicore_dp_dpcd.h b/drivers/transmitter/logicore_dp_dpcd.h
>> new file mode 100644
>> index 0000000000..6858294551
>> --- /dev/null
>> +++ b/drivers/transmitter/logicore_dp_dpcd.h
>> @@ -0,0 +1,342 @@
>> +/*
>> + * logicore_dp_dpcd.h
>> + *
>> + * DPCD interface definition for XILINX LogiCore DisplayPort v6.1
>> + * based on Xilinx dp_v3_1 driver sources
>> + *
>> + * (C) Copyright 2016
>> + * Dirk Eibach,  Guntermann & Drunck GmbH, dirk.eibach at gdsys.cc
>> + *
>> + * SPDX-License-Identifier:    GPL-2.0+
>> + */
>> +
>> +#ifndef __GDSYS_LOGICORE_DP_DPCD_H__
>> +#define __GDSYS_LOGICORE_DP_DPCD_H__
>> +
>> +/* receiver capability field */
>> +#define DPCD_REV                                               0x00000
>> +#define DPCD_MAX_LINK_RATE                                     0x00001
>> +#define DPCD_MAX_LANE_COUNT                                    0x00002
>> +#define DPCD_MAX_DOWNSPREAD                                    0x00003
>> +#define DPCD_NORP_PWR_V_CAP                                    0x00004
>> +#define DPCD_DOWNSP_PRESENT                                    0x00005
>> +#define DPCD_ML_CH_CODING_CAP                                  0x00006
>> +#define DPCD_DOWNSP_COUNT_MSA_OUI                              0x00007
>> +#define        DPCD_RX_PORT0_CAP_0                                     0x00008
>> +#define        DPCD_RX_PORT0_CAP_1                                     0x00009
>> +#define        DPCD_RX_PORT1_CAP_0                                     0x0000A
>> +#define        DPCD_RX_PORT1_CAP_1                                     0x0000B
>> +#define DPCD_I2C_SPEED_CTL_CAP                                 0x0000C
>> +#define DPCD_EDP_CFG_CAP                                       0x0000D
>> +#define DPCD_TRAIN_AUX_RD_INTERVAL                             0x0000E
>> +#define DPCD_ADAPTER_CAP                                       0x0000F
>> +#define DPCD_FAUX_CAP                                          0x00020
>> +#define DPCD_MSTM_CAP                                          0x00021
>> +#define DPCD_NUM_AUDIO_EPS                                     0x00022
>> +#define        DPCD_AV_GRANULARITY                                     0x00023
>> +#define DPCD_AUD_DEC_LAT_7_0                                   0x00024
>> +#define DPCD_AUD_DEC_LAT_15_8                                  0x00025
>> +#define DPCD_AUD_PP_LAT_7_0                                    0x00026
>> +#define DPCD_AUD_PP_LAT_15_8                                   0x00027
>> +#define DPCD_VID_INTER_LAT                                     0x00028
>> +#define DPCD_VID_PROG_LAT                                      0x00029
>> +#define DPCD_REP_LAT                                           0x0002A
>> +#define DPCD_AUD_DEL_INS_7_0                                   0x0002B
>> +#define DPCD_AUD_DEL_INS_15_8                                  0x0002C
>> +#define DPCD_AUD_DEL_INS_23_16                                 0x0002D
>> +#define DPCD_GUID                                              0x00030
>> +#define DPCD_RX_GTC_VALUE_7_0                                  0x00054
>> +#define DPCD_RX_GTC_VALUE_15_8                                 0x00055
>> +#define DPCD_RX_GTC_VALUE_23_16                                        0x00056
>> +#define DPCD_RX_GTC_VALUE_31_24                                        0x00057
>> +#define DPCD_RX_GTC_MSTR_REQ                                   0x00058
>> +#define DPCD_RX_GTC_FREQ_LOCK_DONE                             0x00059
>> +#define DPCD_DOWNSP_0_CAP                                      0x00080
>> +#define DPCD_DOWNSP_1_CAP                                      0x00081
>> +#define DPCD_DOWNSP_2_CAP                                      0x00082
>> +#define DPCD_DOWNSP_3_CAP                                      0x00083
>> +#define DPCD_DOWNSP_0_DET_CAP                                  0x00080
>> +#define DPCD_DOWNSP_1_DET_CAP                                  0x00084
>> +#define DPCD_DOWNSP_2_DET_CAP                                  0x00088
>> +#define DPCD_DOWNSP_3_DET_CAP                                  0x0008C
>> +
>> +/* link configuration field */
>> +#define DPCD_LINK_BW_SET                                       0x00100
>> +#define DPCD_LANE_COUNT_SET                                    0x00101
>> +#define DPCD_TP_SET                                            0x00102
>> +#define DPCD_TRAINING_LANE0_SET                                        0x00103
>> +#define DPCD_TRAINING_LANE1_SET                                        0x00104
>> +#define DPCD_TRAINING_LANE2_SET                                        0x00105
>> +#define DPCD_TRAINING_LANE3_SET                                        0x00106
>> +#define DPCD_DOWNSPREAD_CTRL                                   0x00107
>> +#define DPCD_ML_CH_CODING_SET                                  0x00108
>> +#define DPCD_I2C_SPEED_CTL_SET                                 0x00109
>> +#define DPCD_EDP_CFG_SET                                       0x0010A
>> +#define DPCD_LINK_QUAL_LANE0_SET                               0x0010B
>> +#define DPCD_LINK_QUAL_LANE1_SET                               0x0010C
>> +#define DPCD_LINK_QUAL_LANE2_SET                               0x0010D
>> +#define DPCD_LINK_QUAL_LANE3_SET                               0x0010E
>> +#define DPCD_TRAINING_LANE0_1_SET2                             0x0010F
>> +#define DPCD_TRAINING_LANE2_3_SET2                             0x00110
>> +#define DPCD_MSTM_CTRL                                         0x00111
>> +#define DPCD_AUDIO_DELAY_7_0                                   0x00112
>> +#define DPCD_AUDIO_DELAY_15_8                                  0x00113
>> +#define DPCD_AUDIO_DELAY_23_6                                  0x00114
>> +#define DPCD_UPSTREAM_DEVICE_DP_PWR_NEED                       0x00118
>> +#define DPCD_FAUX_MODE_CTRL                                    0x00120
>> +#define DPCD_FAUX_FORWARD_CH_DRIVE_SET                         0x00121
>> +#define DPCD_BACK_CH_STATUS                                    0x00122
>> +#define DPCD_FAUX_BACK_CH_SYMBOL_ERROR_COUNT                   0x00123
>> +#define DPCD_FAUX_BACK_CH_TRAINING_PATTERN_TIME                        0x00125
>> +#define DPCD_TX_GTC_VALUE_7_0                                  0x00154
>> +#define DPCD_TX_GTC_VALUE_15_8                                 0x00155
>> +#define DPCD_TX_GTC_VALUE_23_16                                        0x00156
>> +#define DPCD_TX_GTC_VALUE_31_24                                        0x00157
>> +#define DPCD_RX_GTC_VALUE_PHASE_SKEW_EN                                0x00158
>> +#define DPCD_TX_GTC_FREQ_LOCK_DONE                             0x00159
>> +#define DPCD_ADAPTER_CTRL                                      0x001A0
>> +#define DPCD_BRANCH_DEVICE_CTRL                                        0x001A1
>> +#define DPCD_PAYLOAD_ALLOCATE_SET                              0x001C0
>> +#define DPCD_PAYLOAD_ALLOCATE_START_TIME_SLOT                  0x001C1
>> +#define DPCD_PAYLOAD_ALLOCATE_TIME_SLOT_COUNT                  0x001C2
>> +
>> +/* link/sink status field */
>> +#define DPCD_SINK_COUNT                                                0x00200
>> +#define DPCD_DEVICE_SERVICE_IRQ                                        0x00201
>> +#define DPCD_STATUS_LANE_0_1                                   0x00202
>> +#define DPCD_STATUS_LANE_2_3                                   0x00203
>> +#define DPCD_LANE_ALIGN_STATUS_UPDATED                         0x00204
>> +#define DPCD_SINK_STATUS                                       0x00205
>> +#define DPCD_ADJ_REQ_LANE_0_1                                  0x00206
>> +#define DPCD_ADJ_REQ_LANE_2_3                                  0x00207
>> +#define DPCD_TRAINING_SCORE_LANE_0                             0x00208
>> +#define DPCD_TRAINING_SCORE_LANE_1                             0x00209
>> +#define DPCD_TRAINING_SCORE_LANE_2                             0x0020A
>> +#define DPCD_TRAINING_SCORE_LANE_3                             0x0020B
>> +#define DPCD_ADJ_REQ_PC2                                       0x0020C
>> +#define DPCD_FAUX_FORWARD_CH_SYMBOL_ERROR_COUNT                        0x0020D
>> +#define DPCD_SYMBOL_ERROR_COUNT_LANE_0                         0x00210
>> +#define DPCD_SYMBOL_ERROR_COUNT_LANE_1                         0x00212
>> +#define DPCD_SYMBOL_ERROR_COUNT_LANE_2                         0x00214
>> +#define DPCD_SYMBOL_ERROR_COUNT_LANE_3                         0x00216
>> +
>> +/* automated testing sub-field */
>> +#define DPCD_FAUX_FORWARD_CH_STATUS                            0x00280
>> +#define DPCD_FAUX_BACK_CH_DRIVE_SET                            0x00281
>> +#define DPCD_FAUX_BACK_CH_SYM_ERR_COUNT_CTRL                   0x00282
>> +#define DPCD_PAYLOAD_TABLE_UPDATE_STATUS                       0x002C0
>> +#define DPCD_VC_PAYLOAD_ID_SLOT(SlotNum) \
>> +                       (DPCD_PAYLOAD_TABLE_UPDATE_STATUS + SlotNum)
>> +
>> +/* sink control field */
>> +#define DPCD_SET_POWER_DP_PWR_VOLTAGE                          0x00600
>> +
>> +/* sideband message buffers */
>> +#define DPCD_DOWN_REQ                                          0x01000
>> +#define DPCD_UP_REP                                            0x01200
>> +#define DPCD_DOWN_REP                                          0x01400
>> +#define DPCD_UP_REQ                                            0x01600
>> +
>> +/* event status indicator field */
>> +#define DPCD_SINK_COUNT_ESI                                    0x02002
>> +#define DPCD_SINK_DEVICE_SERVICE_IRQ_VECTOR_ESI0               0x02003
>> +#define DPCD_SINK_DEVICE_SERVICE_IRQ_VECTOR_ESI1               0x02004
>> +#define DPCD_SINK_LINK_SERVICE_IRQ_VECTOR_ESI0                 0x02005
>> +#define DPCD_SINK_LANE0_1_STATUS                               0x0200C
>> +#define DPCD_SINK_LANE2_3_STATUS                               0x0200D
>> +#define DPCD_SINK_ALIGN_STATUS_UPDATED_ESI                     0x0200E
>> +#define DPCD_SINK_STATUS_ESI                                   0x0200F
>> +
>> +/*
>> + * field addresses and sizes.
>> + */
>> +#define DPCD_RECEIVER_CAP_FIELD_START          DPCD_REV
>> +#define DPCD_RECEIVER_CAP_FIELD_SIZE                   0x100
>> +#define DPCD_LINK_CFG_FIELD_START              DPCD_LINK_BW_SET
>> +#define DPCD_LINK_CFG_FIELD_SIZE                               0x100
>> +#define DPCD_LINK_SINK_STATUS_FIELD_START      DPCD_SINK_COUNT
>> +#define DPCD_LINK_SINK_STATUS_FIELD_SIZE                       0x17
>> +/* 0x00000: DPCD_REV */
>> +#define DPCD_REV_MNR_MASK                                      0x0F
>> +#define DPCD_REV_MJR_MASK                                      0xF0
>> +#define DPCD_REV_MJR_SHIFT                                     4
>> +/* 0x00001: MAX_LINK_RATE */
>> +#define DPCD_MAX_LINK_RATE_162GBPS                             0x06
>> +#define DPCD_MAX_LINK_RATE_270GBPS                             0x0A
>> +#define DPCD_MAX_LINK_RATE_540GBPS                             0x14
>> +/* 0x00002: MAX_LANE_COUNT */
>> +#define DPCD_MAX_LANE_COUNT_MASK                               0x1F
>> +#define DPCD_MAX_LANE_COUNT_1                                  0x01
>> +#define DPCD_MAX_LANE_COUNT_2                                  0x02
>> +#define DPCD_MAX_LANE_COUNT_4                                  0x04
>> +#define DPCD_TPS3_SUPPORT_MASK                                 0x40
>> +#define DPCD_ENHANCED_FRAME_SUPPORT_MASK                       0x80
>> +/* 0x00003: MAX_DOWNSPREAD */
>> +#define DPCD_MAX_DOWNSPREAD_MASK                               0x01
>> +#define DPCD_NO_AUX_HANDSHAKE_LINK_TRAIN_MASK                  0x40
>> +/* 0x00005: DOWNSP_PRESENT */
>> +#define DPCD_DOWNSP_PRESENT_MASK                               0x01
>> +#define DPCD_DOWNSP_TYPE_MASK                                  0x06
>> +#define DPCD_DOWNSP_TYPE_SHIFT                                 1
>> +#define DPCD_DOWNSP_TYPE_DP                                    0x0
>> +#define DPCD_DOWNSP_TYPE_AVGA_ADVII                            0x1
>> +#define DPCD_DOWNSP_TYPE_DVI_HDMI_DPPP                         0x2
>> +#define DPCD_DOWNSP_TYPE_OTHERS                                        0x3
>> +#define DPCD_DOWNSP_FORMAT_CONV_MASK                           0x08
>> +#define DPCD_DOWNSP_DCAP_INFO_AVAIL_MASK                       0x10
>> +/* 0x00006, 0x00108: ML_CH_CODING_SUPPORT, ML_CH_CODING_SET */
>> +#define DPCD_ML_CH_CODING_MASK                                 0x01
>> +/* 0x00007: DOWNSP_COUNT_MSA_OUI */
>> +#define DPCD_DOWNSP_COUNT_MASK                                 0x0F
>> +#define DPCD_MSA_TIMING_PAR_IGNORED_MASK                       0x40
>> +#define DPCD_OUI_SUPPORT_MASK                                  0x80
>> +/* 0x00008, 0x0000A: RX_PORT[0-1]_CAP_0 */
>> +#define DPCD_RX_PORTX_CAP_0_LOCAL_EDID_PRESENT_MASK            0x02
>> +#define DPCD_RX_PORTX_CAP_0_ASSOC_TO_PRECEDING_PORT_MASK       0x04
>> +/* 0x0000C, 0x00109: I2C_SPEED_CTL_CAP, I2C_SPEED_CTL_SET */
>> +#define DPCD_I2C_SPEED_CTL_NONE                                        0x00
>> +#define DPCD_I2C_SPEED_CTL_1KBIPS                              0x01
>> +#define DPCD_I2C_SPEED_CTL_5KBIPS                              0x02
>> +#define DPCD_I2C_SPEED_CTL_10KBIPS                             0x04
>> +#define DPCD_I2C_SPEED_CTL_100KBIPS                            0x08
>> +#define DPCD_I2C_SPEED_CTL_400KBIPS                            0x10
>> +#define DPCD_I2C_SPEED_CTL_1MBIPS                              0x20
>> +/* 0x0000E: TRAIN_AUX_RD_INTERVAL */
>> +#define DPCD_TRAIN_AUX_RD_INT_100_400US                                0x00
>> +#define DPCD_TRAIN_AUX_RD_INT_4MS                              0x01
>> +#define DPCD_TRAIN_AUX_RD_INT_8MS                              0x02
>> +#define DPCD_TRAIN_AUX_RD_INT_12MS                             0x03
>> +#define DPCD_TRAIN_AUX_RD_INT_16MS                             0x04
>> +/* 0x00020: DPCD_FAUX_CAP */
>> +#define DPCD_FAUX_CAP_MASK                                     0x01
>> +/* 0x00021: MSTM_CAP */
>> +#define DPCD_MST_CAP_MASK                                      0x01
>> +/* 0x00080, 0x00081|4, 0x00082|8, 0x00083|C: DOWNSP_X_(DET_)CAP */
>> +#define DPCD_DOWNSP_X_CAP_TYPE_MASK                            0x07
>> +#define DPCD_DOWNSP_X_CAP_TYPE_DP                              0x0
>> +#define DPCD_DOWNSP_X_CAP_TYPE_AVGA                            0x1
>> +#define DPCD_DOWNSP_X_CAP_TYPE_DVI                             0x2
>> +#define DPCD_DOWNSP_X_CAP_TYPE_HDMI                            0x3
>> +#define DPCD_DOWNSP_X_CAP_TYPE_OTHERS                          0x4
>> +#define DPCD_DOWNSP_X_CAP_TYPE_DPPP                            0x5
>> +#define DPCD_DOWNSP_X_CAP_HPD_MASK                             0x80
>> +#define DPCD_DOWNSP_X_CAP_NON_EDID_ATTR_MASK                   0xF0
>> +#define DPCD_DOWNSP_X_CAP_NON_EDID_ATTR_SHIFT                  4
>> +#define DPCD_DOWNSP_X_CAP_NON_EDID_ATTR_720_480_I_60           0x1
>> +#define DPCD_DOWNSP_X_CAP_NON_EDID_ATTR_720_480_I_50           0x2
>> +#define DPCD_DOWNSP_X_CAP_NON_EDID_ATTR_1920_1080_I_60         0x3
>> +#define DPCD_DOWNSP_X_CAP_NON_EDID_ATTR_1920_1080_I_50         0x4
>> +#define DPCD_DOWNSP_X_CAP_NON_EDID_ATTR_1280_720_P_60          0x5
>> +#define DPCD_DOWNSP_X_CAP_NON_EDID_ATTR_1280_720_P_50          0x7
>> +/* 0x00082, 0x00086, 0x0008A, 0x0008E: DOWNSP_X_(DET_)CAP2 */
>> +#define DPCD_DOWNSP_X_DCAP_MAX_BPC_MASK                                0x03
>> +#define DPCD_DOWNSP_X_DCAP_MAX_BPC_8                           0x0
>> +#define DPCD_DOWNSP_X_DCAP_MAX_BPC_10                          0x1
>> +#define DPCD_DOWNSP_X_DCAP_MAX_BPC_12                          0x2
>> +#define DPCD_DOWNSP_X_DCAP_MAX_BPC_16                          0x3
>> +/* 0x00082, 0x00086, 0x0008A, 0x0008E: DOWNSP_X_(DET_)CAP2 */
>> +#define DPCD_DOWNSP_X_DCAP_HDMI_DPPP_FS2FP_MASK                        0x01
>> +#define DPCD_DOWNSP_X_DCAP_DVI_DL_MASK                         0x02
>> +#define DPCD_DOWNSP_X_DCAP_DVI_HCD_MASK                                0x04
>> +
>> +/* link configuration field masks, shifts, and register values */
>> +/* 0x00100: DPCD_LINK_BW_SET */
>> +#define DPCD_LINK_BW_SET_162GBPS                               0x06
>> +#define DPCD_LINK_BW_SET_270GBPS                               0x0A
>> +#define DPCD_LINK_BW_SET_540GBPS                               0x14
>> +/* 0x00101: LANE_COUNT_SET */
>> +#define DPCD_LANE_COUNT_SET_MASK                               0x1F
>> +#define DPCD_LANE_COUNT_SET_1                                  0x01
>> +#define DPCD_LANE_COUNT_SET_2                                  0x02
>> +#define DPCD_LANE_COUNT_SET_4                                  0x04
>> +#define DPCD_ENHANCED_FRAME_EN_MASK                            0x80
>> +/* 0x00102: TP_SET */
>> +#define DPCD_TP_SEL_MASK                                       0x03
>> +#define DPCD_TP_SEL_OFF                                                0x0
>> +#define DPCD_TP_SEL_TP1                                                0x1
>> +#define DPCD_TP_SEL_TP2                                                0x2
>> +#define DPCD_TP_SEL_TP3                                                0x3
>> +#define DPCD_TP_SET_LQP_MASK                                   0x06
>> +#define DPCD_TP_SET_LQP_SHIFT                                  2
>> +#define DPCD_TP_SET_LQP_OFF                                    0x0
>> +#define DPCD_TP_SET_LQP_D102_TEST                              0x1
>> +#define DPCD_TP_SET_LQP_SER_MES                                        0x2
>> +#define DPCD_TP_SET_LQP_PRBS7                                  0x3
>> +#define DPCD_TP_SET_REC_CLK_OUT_EN_MASK                                0x10
>> +#define DPCD_TP_SET_SCRAMB_DIS_MASK                            0x20
>> +#define DPCD_TP_SET_SE_COUNT_SEL_MASK                          0xC0
>> +#define DPCD_TP_SET_SE_COUNT_SEL_SHIFT                         6
>> +#define DPCD_TP_SET_SE_COUNT_SEL_DE_ISE                                0x0
>> +#define DPCD_TP_SET_SE_COUNT_SEL_DE                            0x1
>> +#define DPCD_TP_SET_SE_COUNT_SEL_ISE                           0x2
>> +/* 0x00103-0x00106: TRAINING_LANE[0-3]_SET */
>> +#define DPCD_TRAINING_LANEX_SET_VS_MASK                                0x03
>> +#define DPCD_TRAINING_LANEX_SET_MAX_VS_MASK                    0x04
>> +#define DPCD_TRAINING_LANEX_SET_PE_MASK                                0x18
>> +#define DPCD_TRAINING_LANEX_SET_PE_SHIFT                       3
>> +#define DPCD_TRAINING_LANEX_SET_MAX_PE_MASK                    0x20
>> +/* 0x00107: DOWNSPREAD_CTRL */
>> +#define DPCD_SPREAD_AMP_MASK                                   0x10
>> +#define DPCD_MSA_TIMING_PAR_IGNORED_EN_MASK                    0x80
>> +/* 0x00108: ML_CH_CODING_SET - Same as 0x00006: ML_CH_CODING_SUPPORT */
>> +/* 0x00109: I2C_SPEED_CTL_SET - Same as 0x0000C: I2C_SPEED_CTL_CAP */
>> +/* 0x0010F-0x00110: TRAINING_LANE[0_1-2_3]_SET2 */
>> +#define DPCD_TRAINING_LANE_0_2_SET_PC2_MASK                    0x03
>> +#define DPCD_TRAINING_LANE_0_2_SET_MAX_PC2_MASK                        0x04
>> +#define DPCD_TRAINING_LANE_1_3_SET_PC2_MASK                    0x30
>> +#define DPCD_TRAINING_LANE_1_3_SET_PC2_SHIFT                   4
>> +#define DPCD_TRAINING_LANE_1_3_SET_MAX_PC2_MASK                        0x40
>> +/* 0x00111: MSTM_CTRL */
>> +#define DPCD_MST_EN_MASK                                       0x01
>> +#define DPCD_UP_REQ_EN_MASK                                    0x02
>> +#define DPCD_UP_IS_SRC_MASK                                    0x03
>> +
>> +/* link/sink status field masks, shifts, and register values */
>> +/* 0x00200: SINK_COUNT */
>> +#define DPCD_SINK_COUNT_LOW_MASK                               0x3F
>> +#define DPCD_SINK_CP_READY_MASK                                        0x40
>> +#define DPCD_SINK_COUNT_HIGH_MASK                              0x80
>> +#define DPCD_SINK_COUNT_HIGH_LOW_SHIFT                         1
>> +/* 0x00202: STATUS_LANE_0_1 */
>> +#define DPCD_STATUS_LANE_0_CR_DONE_MASK                                0x01
>> +#define DPCD_STATUS_LANE_0_CE_DONE_MASK                                0x02
>> +#define DPCD_STATUS_LANE_0_SL_DONE_MASK                                0x04
>> +#define DPCD_STATUS_LANE_1_CR_DONE_MASK                                0x10
>> +#define DPCD_STATUS_LANE_1_CE_DONE_MASK                                0x20
>> +#define DPCD_STATUS_LANE_1_SL_DONE_MASK                                0x40
>> +/* 0x00202: STATUS_LANE_2_3 */
>> +#define DPCD_STATUS_LANE_2_CR_DONE_MASK                                0x01
>> +#define DPCD_STATUS_LANE_2_CE_DONE_MASK                                0x02
>> +#define DPCD_STATUS_LANE_2_SL_DONE_MASK                                0x04
>> +#define DPCD_STATUS_LANE_3_CR_DONE_MASK                                0x10
>> +#define DPCD_STATUS_LANE_3_CE_DONE_MASK                                0x20
>> +#define DPCD_STATUS_LANE_3_SL_DONE_MASK                                0x40
>> +/* 0x00204: LANE_ALIGN_STATUS_UPDATED */
>> +#define DPCD_LANE_ALIGN_STATUS_UPDATED_IA_DONE_MASK \
>> +                                                               0x01
>> +#define DPCD_LANE_ALIGN_STATUS_UPDATED_DOWNSP_STATUS_CHANGED_MASK \
>> +                                                               0x40
>> +#define DPCD_LANE_ALIGN_STATUS_UPDATED_LINK_STATUS_UPDATED_MASK \
>> +                                                               0x80
>> +/* 0x00205: SINK_STATUS */
>> +#define DPCD_SINK_STATUS_RX_PORT0_SYNC_STATUS_MASK             0x01
>> +#define DPCD_SINK_STATUS_RX_PORT1_SYNC_STATUS_MASK             0x02
>> +
>> +/* 0x00206, 0x00207: ADJ_REQ_LANE_[0,2]_[1,3] */
>> +#define DPCD_ADJ_REQ_LANE_0_2_VS_MASK                          0x03
>> +#define DPCD_ADJ_REQ_LANE_0_2_PE_MASK                          0x0C
>> +#define DPCD_ADJ_REQ_LANE_0_2_PE_SHIFT                         2
>> +#define DPCD_ADJ_REQ_LANE_1_3_VS_MASK                          0x30
>> +#define DPCD_ADJ_REQ_LANE_1_3_VS_SHIFT                         4
>> +#define DPCD_ADJ_REQ_LANE_1_3_PE_MASK                          0xC0
>> +#define DPCD_ADJ_REQ_LANE_1_3_PE_SHIFT                         6
>> +/* 0x0020C: ADJ_REQ_PC2 */
>> +#define DPCD_ADJ_REQ_PC2_LANE_0_MASK                           0x03
>> +#define DPCD_ADJ_REQ_PC2_LANE_1_MASK                           0x0C
>> +#define DPCD_ADJ_REQ_PC2_LANE_1_SHIFT                          2
>> +#define DPCD_ADJ_REQ_PC2_LANE_2_MASK                           0x30
>> +#define DPCD_ADJ_REQ_PC2_LANE_2_SHIFT                          4
>> +#define DPCD_ADJ_REQ_PC2_LANE_3_MASK                           0xC0
>> +#define DPCD_ADJ_REQ_PC2_LANE_3_SHIFT                          6
>> +
>> +#endif /* __GDSYS_LOGICORE_DP_DPCD_H__ */
>> diff --git a/drivers/transmitter/logicore_dp_tx.c b/drivers/transmitter/logicore_dp_tx.c
>> new file mode 100644
>> index 0000000000..b61159cd89
>> --- /dev/null
>> +++ b/drivers/transmitter/logicore_dp_tx.c
>> @@ -0,0 +1,1984 @@
>> +/*
>> + * logicore_dp_tx.c
>> + *
>> + * Driver for XILINX LogiCore DisplayPort v6.1 TX (Source)
>> + * based on Xilinx dp_v3_1 driver sources, updated to dp_v4_0
>> + *
>> + * (C) Copyright 2016
>> + * Dirk Eibach,  Guntermann & Drunck GmbH, dirk.eibach at gdsys.cc
>> + *
>> + * SPDX-License-Identifier:    GPL-2.0+
>> + */
>> +
>> +#include <common.h>
>> +#include <clk.h>
>> +#include <dm.h>
>> +#include <errno.h>
>> +#include <transmitter.h>
>> +
>> +#include "ihs_axi.h"
>> +
>> +#include "logicore_dp_dpcd.h"
>> +#include "logicore_dp_tx_regif.h"
>> +#include "logicore_dp_tx.h"
>> +
>> +DECLARE_GLOBAL_DATA_PTR;
>> +
>> +#define S_AXI_CLK_DEFAULT 100000000
>> +
>> +#define PHY_CLOCK_SELECT_DEFAULT PHY_CLOCK_SELECT_540GBPS
>> +
>> +/* The maximum voltage swing level is 3. */
>> +#define MAXIMUM_VS_LEVEL 3
>> +/* The maximum pre-emphasis level is 3. */
>> +#define MAXIMUM_PE_LEVEL 3
>> +
>> +/* Error out if an AUX request yields a defer reply more than 50 times. */
>> +#define AUX_MAX_DEFER_COUNT 50
>> +/* Error out if an AUX request times out more than 50 times awaiting a reply. */
>> +#define AUX_MAX_TIMEOUT_COUNT 50
>> +/* Error out if checking for a connected device times out more than 50 times. */
>> +#define IS_CONNECTED_MAX_TIMEOUT_COUNT 50
>> +
>> +enum {
>> +       TS_CLOCK_RECOVERY,
>> +       TS_CHANNEL_EQUALIZATION,
>> +       TS_ADJUST_LINK_RATE,
>> +       TS_ADJUST_LANE_COUNT,
>> +       TS_FAILURE,
>> +       TS_SUCCESS
>> +};
>> +
>> +struct aux_transaction {
>> +       u16 cmd_code;
>> +       u8 num_bytes;
>> +       u32 address;
>> +       u8 *data;
>
> Comment these members.
>

OK, will add comments in v2.

>> +};
>> +
>> +/*
>> + * all porch parameters have been removed because our videodata is hstart/vstart
>> + * based and there is no benefit in keeping the porches
>> + */
>> +
>> +struct main_stream_attributes {
>> +       /* Pixel clock of the stream (in Hz). */
>> +       u32 pixel_clock_hz;
>> +       /* Miscellaneous stream attributes 0 as specified by the DisplayPort
>> +        * 1.2 specification.
>> +        */
>> +       u32 misc_0;
>> +       /* Miscellaneous stream attributes 1 as specified by the DisplayPort
>> +        * 1.2 specification.
>> +        */
>> +       u32 misc_1;
>> +       /* N value for the video stream. */
>> +       u32 n_vid;
>> +       /* M value used to recover the video clock from the link clock. */
>> +       u32 m_vid;
>> +       /* Width of the user data input port. */
>> +       u32 user_pixel_width;
>> +       /* Used to translate the number of pixels per line to the native
>> +        * internal 16-bit datapath.
>> +        */
>> +       u32 data_per_lane;
>> +       /* Average number of bytes per transfer unit, scaled up by a factor of
>> +        * 1000.
>> +        */
>> +       u32 avg_bytes_per_tu;
>> +       /* Size of the transfer unit in the framing logic. In MST mode, this is
>> +        * also the number of time slots that are alloted in the payload ID
>> +        * table.
>> +        */
>> +       u32 transfer_unit_size;
>> +       /* Number of initial wait cycles at the start of a new line by the
>> +        * framing logic.
>> +        */
>> +       u32 init_wait;
>> +       /* Bits per color component. */
>> +       u32 bits_per_color;
>> +       /* The component format currently in use by the video stream. */
>> +       u8 component_format;
>> +       /* The dynamic range currently in use by the video stream. */
>> +       u8 dynamic_range;
>> +       /* The YCbCr colorimetry currently in use by the video stream. */
>> +       u8 y_cb_cr_colorimetry;
>> +       /* Synchronous clock mode is currently in use by the video stream. */
>> +       u8 synchronous_clock_mode;
>> +       /* If set to 1, the value stored for user_pixel_width will be used as
>> +        * the pixel width.
>> +        */
>> +       u8 override_user_pixel_width;
>> +       /* Horiz. blank start (pixels). */
>> +       u32 h_start;
>> +       /* Horiz. active resolution (pixels) */
>> +       u16 h_active;
>> +       /* Horiz. sync width (pixels) */
>> +       u16 h_sync_width;
>> +       /* Horiz. total (pixels) */
>> +       u16 h_total;
>> +       /* Horiz. sync polarity (0=neg|1=pos) */
>> +       bool h_sync_polarity;
>> +       /* Vert. blank start (in lines). */
>> +       u32 v_start;
>> +       /* Vert. active resolution (lines) */
>> +       u16 v_active;
>> +       /* Vert. sync width (lines) */
>> +       u16 v_sync_width;
>> +       /* Vert. total (lines) */
>> +       u16 v_total;
>> +       /* Vert. sync polarity (0=neg|1=pos) */
>> +       bool v_sync_polarity;
>> +};
>> +
>> +struct link_config {
>> +       u8 lane_count;
>> +       u8 link_rate;
>> +       bool scrambler_en;
>> +       bool enhanced_framing_mode;
>> +       bool downspread_control;
>> +       u8 max_lane_count;
>> +       u8 max_link_rate;
>> +       bool support_enhanced_framing_mode;
>> +       bool support_downspread_control;
>> +       u8 vs_level; /* voltage swing for each lane */
>> +       u8 pe_level; /* pre-emphasis/cursor level for each lane */
>> +       u8 pattern;
>> +};
>> +
>> +struct dp_tx {
>> +       u32 base;
>> +
>> +       u32 s_axi_clk;
>> +
>> +       bool train_adaptive;
>> +
>> +       u8 max_link_rate;
>> +       u8 max_lane_count;
>> +
>> +       u8 dpcd_rx_caps[16];
>> +
>> +       /* This is a raw read of the RX device's status registers. The first 4
>> +        * bytes correspond to the lane status associated with clock recovery,
>> +        * channel equalization, symbol lock, and interlane alignment. The
>> +        * remaining 2 bytes represent the pre-emphasis and voltage swing level
>> +        * adjustments requested by the RX device.
>> +        */
>> +       u8 lane_status_ajd_reqs[6];
>> +
>> +       struct link_config link_config;
>> +       struct main_stream_attributes main_stream_attributes;
>> +};
>> +
>> +/*
>> + * internal API
>> + */
>> +
>> +static u32 get_reg(struct udevice *dev, u32 reg)
>> +{
>> +       struct dp_tx *dp_tx = dev_get_priv(dev);
>> +       u32 value = 0;
>> +       int res;
>> +
>> +       // TODO error handling
>
> /* TODO(email): Error handling
>
> (or do you intend to do in v2?)
>

I might as well fix it, since I'll have to tweak the methods again for the
uclass move anyway. Will be fixed in v2.

>> +       res = axi_read(dev->parent, dp_tx->base + reg, &value);
>> +       if (res < 0)
>> +               printf("%s() failed; res = %d\n", __func__, res);
>
> How about debug() and return an error?
>

OK, I'll return the error from the axi_read in v2.

>> +
>> +       return value;
>> +}
>> +
>> +static void set_reg(struct udevice *dev, u32 reg, u32 value)
>> +{
>> +       struct dp_tx *dp_tx = dev_get_priv(dev);
>> +
>> +       axi_write(dev->parent, dp_tx->base + reg, value);
>
> Can this fail? Error checking?
>

The function itself returns a error code, but I think it can't really fail in
practice. Will check, and add error handling in v2 if necessary.

>> +}
>> +
>> +/*
>> + * Check if there is a connected RX device.
>> + * The Xilinx original calls msleep_interruptible at least once,
>> + * ignoring status.
>> + */
>> +bool is_connected(struct udevice *dev)
>> +{
>> +       u8 retries = 0;
>> +
>> +       do {
>> +               int status = get_reg(dev, REG_INTERRUPT_SIG_STATE) &
>> +                            INTERRUPT_SIG_STATE_HPD_STATE_MASK;
>> +               if (status)
>> +                       return true;
>> +
>> +               udelay(1000);
>> +       } while (retries++ < IS_CONNECTED_MAX_TIMEOUT_COUNT);
>> +
>> +       return false;
>> +}
>> +
>> +/*
>> + * Wait for the DisplayPort PHY to come out of reset.
>> + */
>> +static int wait_phy_ready(struct udevice *dev, u32 mask)
>> +{
>> +       u16 timeout = 20000;
>> +       u32 phy_status;
>> +
>> +       /* Wait until the PHY is ready. */
>> +       do {
>> +               phy_status = get_reg(dev, REG_PHY_STATUS) & mask;
>> +
>> +               /* Protect against an infinite loop. */
>> +               if (!timeout--)
>> +                       return -ETIMEDOUT;
>> +
>> +               udelay(20);
>> +       } while (phy_status != mask);
>> +
>> +       return 0;
>> +}
>> +
>> +/* AUX channel access */
>> +
>> +/*
>> + * Wait until another request is no longer in progress.
>> + */
>> +static int aux_wait_ready(struct udevice *dev)
>> +{
>> +       int status;
>> +       u32 timeout = 100;
>> +
>> +       /* Wait until the DisplayPort TX core is ready. */
>> +       do {
>> +               status = get_reg(dev, REG_INTERRUPT_SIG_STATE);
>> +
>> +               /* Protect against an infinite loop. */
>> +               if (!timeout--)
>> +                       return -ETIMEDOUT;
>> +               udelay(20);
>> +       } while (status & REPLY_STATUS_REPLY_IN_PROGRESS_MASK);
>> +
>> +       return 0;
>> +}
>> +
>> +/*
>> + * Wait for a reply indicating that the most recent AUX request
>> + * has been received by the RX device.
>> + */
>> +static int aux_wait_reply(struct udevice *dev)
>> +{
>> +       u32 timeout = 100;
>> +
>> +       while (timeout > 0) {
>> +               int status = get_reg(dev, REG_REPLY_STATUS);
>> +
>> +               /* Check for error. */
>> +               if (status & REPLY_STATUS_REPLY_ERROR_MASK)
>> +                       return -ETIMEDOUT;
>> +
>> +               /* Check for a reply. */
>> +               if ((status & REPLY_STATUS_REPLY_RECEIVED_MASK) &&
>> +                   !(status &
>> +                     REPLY_STATUS_REQUEST_IN_PROGRESS_MASK) &&
>> +                   !(status &
>> +                     REPLY_STATUS_REPLY_IN_PROGRESS_MASK)) {
>> +                       return 0;
>> +               }
>> +
>> +               timeout--;
>> +               udelay(20);
>
> This makes me think we should have a way to do us timeouts.
>
> We have get_timer(), so:
>
> start = get_timer(0);
> ...
> while () {
>     ...
>    if (get_timer(start) > 20) {
>       debug(...)
>       return -ETIMEDOUT;
>    }
>
> Perhaps we should have a timer_get_us_base(ulong base) which works in
> a similar way?
>

That would indeed be helpful; I know that we use loops like this all over the
place in our board code, so optimizing that would help a lot.

>> +       }
>> +
>> +       return -ETIMEDOUT;
>> +}
>> +
>> +/*
>> + * Submit the supplied AUX request to the RX device over the AUX
>> + * channel by writing the command, the destination address, (the write buffer
>> + * for write commands), and the data size to the DisplayPort TX core.
>> + */
>> +static int aux_request_send(struct udevice *dev,
>> +                           struct aux_transaction *request)
>> +{
>> +       u32 timeout_count;
>> +       int status;
>> +       u8 index;
>> +
>> +       /* Ensure that any pending AUX transactions have completed. */
>> +       timeout_count = 0;
>> +       do {
>> +               status = get_reg(dev, REG_REPLY_STATUS);
>> +
>> +               udelay(20);
>> +               timeout_count++;
>> +               if (timeout_count >= AUX_MAX_TIMEOUT_COUNT)
>> +                       return -ETIMEDOUT;
>> +       } while ((status & REPLY_STATUS_REQUEST_IN_PROGRESS_MASK) ||
>> +                (status & REPLY_STATUS_REPLY_IN_PROGRESS_MASK));
>> +
>> +       set_reg(dev, REG_AUX_ADDRESS, request->address);
>> +
>> +       if ((request->cmd_code == AUX_CMD_WRITE) ||
>> +           (request->cmd_code == AUX_CMD_I2C_WRITE) ||
>> +           (request->cmd_code == AUX_CMD_I2C_WRITE_MOT)) {
>> +               /* Feed write data into the DisplayPort TX core's write FIFO. */
>> +               for (index = 0; index < request->num_bytes; index++) {
>> +                       set_reg(dev,
>> +                               REG_AUX_WRITE_FIFO, request->data[index]);
>> +               }
>> +       }
>> +
>> +       /* Submit the command and the data size. */
>> +       set_reg(dev, REG_AUX_CMD,
>> +               ((request->cmd_code << AUX_CMD_SHIFT) |
>> +                ((request->num_bytes - 1) &
>> +                 AUX_CMD_NBYTES_TRANSFER_MASK)));
>> +
>> +       /* Check for a reply from the RX device to the submitted request. */
>> +       status = aux_wait_reply(dev);
>> +       if (status)
>> +               /* Waiting for a reply timed out. */
>> +               return -ETIMEDOUT;
>> +
>> +       /* Analyze the reply. */
>> +       status = get_reg(dev, REG_AUX_REPLY_CODE);
>> +       if ((status == AUX_REPLY_CODE_DEFER) ||
>> +           (status == AUX_REPLY_CODE_I2C_DEFER)) {
>> +               /* The request was deferred. */
>> +               return -EAGAIN;
>> +       } else if ((status == AUX_REPLY_CODE_NACK) ||
>> +                  (status == AUX_REPLY_CODE_I2C_NACK)) {
>> +               /* The request was not acknowledged. */
>> +               return -EIO;
>> +       }
>> +
>> +       /* The request was acknowledged. */
>> +
>> +       if ((request->cmd_code == AUX_CMD_READ) ||
>> +           (request->cmd_code == AUX_CMD_I2C_READ) ||
>> +           (request->cmd_code == AUX_CMD_I2C_READ_MOT)) {
>> +               /* Wait until all data has been received. */
>> +               timeout_count = 0;
>> +               do {
>> +                       status = get_reg(dev, REG_REPLY_DATA_COUNT);
>> +
>> +                       udelay(100);
>> +                       timeout_count++;
>> +                       if (timeout_count >= AUX_MAX_TIMEOUT_COUNT)
>> +                               return -ETIMEDOUT;
>> +               } while (status != request->num_bytes);
>> +
>> +               /* Obtain the read data from the reply FIFO. */
>> +               for (index = 0; index < request->num_bytes; index++)
>> +                       request->data[index] = get_reg(dev, REG_AUX_REPLY_DATA);
>> +       }
>> +
>> +       return 0;
>> +}
>> +
>> +/*
>> + * Submit the supplied AUX request to the RX device over the AUX
>> + * channel. If waiting for a reply times out, or if the DisplayPort TX core
>> + * indicates that the request was deferred, the request is sent again (up to a
>> + * maximum specified by AUX_MAX_DEFER_COUNT|AUX_MAX_TIMEOUT_COUNT).
>> + */
>> +static int aux_request(struct udevice *dev, struct aux_transaction *request)
>> +{
>> +       u32 defer_count = 0;
>> +       u32 timeout_count = 0;
>> +
>> +       while ((defer_count < AUX_MAX_DEFER_COUNT) &&
>> +              (timeout_count < AUX_MAX_TIMEOUT_COUNT)) {
>> +               int status = aux_wait_ready(dev);
>> +
>> +               if (status) {
>> +                       /* The RX device isn't ready yet. */
>> +                       timeout_count++;
>> +                       continue;
>> +               }
>> +
>> +               status = aux_request_send(dev, request);
>> +               if (status == -EAGAIN) {
>> +                       /* The request was deferred. */
>> +                       defer_count++;
>> +               } else if (status == -ETIMEDOUT) {
>> +                       /* Waiting for a reply timed out. */
>> +                       timeout_count++;
>> +               } else {
>> +                       /* -EIO indicates that the request was NACK'ed,
>> +                        * 0 indicates that the request was ACK'ed.
>> +                        */
>> +                       return status;
>> +               }
>> +
>> +               udelay(100);
>> +       }
>> +
>> +       /* The request was not successfully received by the RX device. */
>> +       return -ETIMEDOUT;
>> +}
>> +
>> +/*
>> + * Common sequence of submitting an AUX command for
>> + * AUX read, AUX write, I2C-over-AUX read, and I2C-over-AUX write transactions.
>> + * If required, the reads and writes are split into multiple requests, each
>> + * acting on a maximum of 16 bytes.
>> + */
>> +static int aux_common(struct udevice *dev, u32 cmd_type, u32 address,
>> +                     u32 num_bytes, u8 *data)
>> +{
>> +       struct aux_transaction request;
>> +       u32 bytes_left;
>> +
>> +       /*
>> +        * set the start address for AUX transactions. For I2C transactions,
>> +        * this is the address of the I2C bus.
>> +        */
>> +       request.address = address;
>> +
>> +       bytes_left = num_bytes;
>> +       while (bytes_left) {
>> +               int status;
>> +
>> +               request.cmd_code = cmd_type;
>> +
>> +               if ((cmd_type == AUX_CMD_READ) ||
>> +                   (cmd_type == AUX_CMD_WRITE)) {
>> +                       /* Increment address for normal AUX transactions. */
>> +                       request.address = address + (num_bytes - bytes_left);
>> +               }
>> +
>> +               /* Increment the pointer to the supplied data buffer. */
>> +               request.data = &data[num_bytes - bytes_left];
>> +
>> +               request.num_bytes = (bytes_left > 16) ? 16 : bytes_left;
>> +               bytes_left -= request.num_bytes;
>> +
>> +               if ((cmd_type == AUX_CMD_I2C_READ) && bytes_left) {
>> +                       /* Middle of a transaction I2C read request. Override
>> +                        * the command code that was set to cmd_type.
>> +                        */
>> +                       request.cmd_code = AUX_CMD_I2C_READ_MOT;
>> +               } else if ((cmd_type == AUX_CMD_I2C_WRITE) && bytes_left) {
>> +                       /* Middle of a transaction I2C write request. Override
>> +                        * the command code that was set to cmd_type.
>> +                        */
>> +                       request.cmd_code = AUX_CMD_I2C_WRITE_MOT;
>> +               }
>> +
>> +               status = aux_request(dev, &request);
>> +               if (status)
>> +                       return status;
>> +       }
>> +
>> +       return 0;
>> +}
>> +
>> +/*
>> + * Issue a read request over the AUX channel that will read from
>> + * the RX device's DisplayPort Configuration data (DPCD) address space. The read
>> + * message will be divided into multiple transactions which read a maximum of 16
>> + * bytes each.
>> + */
>> +static int aux_read(struct udevice *dev, u32 dpcd_address, u32 bytes_to_read,
>> +                   void *read_data)
>> +{
>> +       int status;
>> +
>> +       if (!is_connected(dev))
>> +               return -ENODEV;
>
> Can we use -ENXIO for this? That error means there is no device. There
> is a device, it just isn't connected / working.
>

OK, will change in v2.

>> +
>> +       /* Send AUX read transaction. */
>> +       status = aux_common(dev, AUX_CMD_READ, dpcd_address,
>> +                           bytes_to_read, (u8 *)read_data);
>> +
>> +       return status;
>> +}
>> +
>> +/*
>> + * Issue a write request over the AUX channel that will write to
>> + * the RX device's DisplayPort Configuration data (DPCD) address space. The
>> + * write message will be divided into multiple transactions which write a
>> + * maximum of 16 bytes each.
>> + */
>> +static int aux_write(struct udevice *dev, u32 dpcd_address, u32 bytes_to_write,
>> +                    void *write_data)
>> +{
>> +       int status;
>> +
>> +       if (!is_connected(dev))
>> +               return -ENODEV;
>
> Here too
>

Dito, will change in v2.

>> +
>> +       /* Send AUX write transaction. */
>> +       status = aux_common(dev, AUX_CMD_WRITE, dpcd_address,
>> +                           bytes_to_write, (u8 *)write_data);
>> +
>> +       return status;
>> +}
>> +
>> +/* core initialization */
>> +
>> +static int initialize(struct udevice *dev)
>> +{
>> +       struct dp_tx *dp_tx = dev_get_priv(dev);
>> +       u32 val;
>> +       u32 phy_config;
>> +       unsigned int k;
>> +
>> +       /* place the PHY (and GTTXRESET) into reset. */
>> +       phy_config = get_reg(dev, REG_PHY_CONFIG);
>> +       set_reg(dev, REG_PHY_CONFIG, phy_config | PHY_CONFIG_GT_ALL_RESET_MASK);
>> +
>> +       /* reset the video streams and AUX logic. */
>> +       set_reg(dev, REG_SOFT_RESET,
>> +               SOFT_RESET_VIDEO_STREAM_ALL_MASK |
>> +               SOFT_RESET_AUX_MASK);
>> +
>> +       /* disable the DisplayPort TX core. */
>> +       set_reg(dev, REG_ENABLE, 0);
>> +
>> +       /* set the clock divider. */
>> +       val = get_reg(dev, REG_AUX_CLK_DIVIDER);
>> +       val &= ~AUX_CLK_DIVIDER_VAL_MASK;
>> +       val |= dp_tx->s_axi_clk / 1000000;
>> +       set_reg(dev, REG_AUX_CLK_DIVIDER, val);
>> +
>> +       /* set the DisplayPort TX core's clock speed. */
>> +       set_reg(dev, REG_PHY_CLOCK_SELECT, PHY_CLOCK_SELECT_DEFAULT);
>> +
>> +       /* bring the PHY (and GTTXRESET) out of reset. */
>> +       set_reg(dev, REG_PHY_CONFIG,
>> +               phy_config & ~PHY_CONFIG_GT_ALL_RESET_MASK);
>> +
>> +       /* enable the DisplayPort TX core. */
>> +       set_reg(dev, REG_ENABLE, 1);
>> +
>> +       /* Unmask Hot-Plug-Detect (HPD) interrupts. */
>> +       set_reg(dev, REG_INTERRUPT_MASK,
>> +               ~INTERRUPT_MASK_HPD_PULSE_DETECTED_MASK &
>> +               ~INTERRUPT_MASK_HPD_EVENT_MASK &
>> +               ~INTERRUPT_MASK_HPD_IRQ_MASK);
>> +
>> +       for (k = 0; k < 4; k++) {
>> +               /* Disable pre-cursor levels. */
>> +               set_reg(dev, REG_PHY_PRECURSOR_LANE_0 + 4 * k, 0);
>> +
>> +               /* Write default voltage swing levels to the TX registers. */
>> +               set_reg(dev, REG_PHY_VOLTAGE_DIFF_LANE_0 + 4 * k, 0);
>> +
>> +               /* Write default pre-emphasis levels to the TX registers. */
>> +               set_reg(dev, REG_PHY_POSTCURSOR_LANE_0 + 4 * k, 0);
>> +       }
>> +
>> +       return 0;
>> +}
>> +
>> +bool is_link_rate_valid(struct udevice *dev, u8 link_rate)
>> +{
>> +       struct dp_tx *dp_tx = dev_get_priv(dev);
>> +       bool valid = true;
>> +
>> +       if ((link_rate != LINK_BW_SET_162GBPS) &&
>> +           (link_rate != LINK_BW_SET_270GBPS) &&
>> +           (link_rate != LINK_BW_SET_540GBPS))
>> +               valid = false;
>> +       else if (link_rate > dp_tx->link_config.max_link_rate)
>> +               valid = false;
>> +
>> +       return valid;
>> +}
>> +
>> +bool is_lane_count_valid(struct udevice *dev, u8 lane_count)
>> +{
>> +       struct dp_tx *dp_tx = dev_get_priv(dev);
>> +       bool valid = true;
>> +
>> +       if ((lane_count != LANE_COUNT_SET_1) &&
>> +           (lane_count != LANE_COUNT_SET_2) &&
>> +           (lane_count != LANE_COUNT_SET_4))
>> +               valid = false;
>> +       else if (lane_count > dp_tx->link_config.max_lane_count)
>> +               valid = false;
>> +
>> +       return valid;
>> +}
>> +
>> +static int get_rx_capabilities(struct udevice *dev)
>> +{
>> +       struct dp_tx *dp_tx = dev_get_priv(dev);
>> +       int status;
>> +       u8 rx_max_link_rate;
>> +       u8 rx_max_lane_count;
>> +
>> +       if (!is_connected(dev))
>> +               return -ENODEV;
>> +
>> +       status = aux_read(dev, DPCD_RECEIVER_CAP_FIELD_START, 16,
>> +                         dp_tx->dpcd_rx_caps);
>> +       if (status)
>> +               return -EIO;
>> +
>> +       rx_max_link_rate = dp_tx->dpcd_rx_caps[DPCD_MAX_LINK_RATE];
>> +       rx_max_lane_count = dp_tx->dpcd_rx_caps[DPCD_MAX_LANE_COUNT] &
>> +                           DPCD_MAX_LANE_COUNT_MASK;
>> +
>> +       dp_tx->link_config.max_link_rate =
>> +               (rx_max_link_rate > dp_tx->max_link_rate) ?
>> +               dp_tx->max_link_rate : rx_max_link_rate;
>> +       if (!is_link_rate_valid(dev, rx_max_link_rate))
>> +               return -EINVAL;
>> +
>> +       dp_tx->link_config.max_lane_count =
>> +               (rx_max_lane_count > dp_tx->max_lane_count) ?
>> +               dp_tx->max_lane_count : rx_max_lane_count;
>> +       if (!is_lane_count_valid(dev, rx_max_lane_count))
>> +               return -EINVAL;
>> +
>> +       dp_tx->link_config.support_enhanced_framing_mode =
>> +               dp_tx->dpcd_rx_caps[DPCD_MAX_LANE_COUNT] &
>> +               DPCD_ENHANCED_FRAME_SUPPORT_MASK;
>> +       dp_tx->link_config.support_downspread_control =
>> +               dp_tx->dpcd_rx_caps[DPCD_MAX_DOWNSPREAD] &
>> +               DPCD_MAX_DOWNSPREAD_MASK;
>> +
>> +       return 0;
>> +}
>> +
>> +static void enable_main_link(struct udevice *dev)
>> +{
>> +       /* reset the scrambler. */
>> +       set_reg(dev, REG_FORCE_SCRAMBLER_RESET, 0x1);
>> +
>> +       /* enable the main stream. */
>> +       set_reg(dev, REG_ENABLE_MAIN_STREAM, 0x1);
>> +}
>> +
>> +static void disable_main_link(struct udevice *dev)
>> +{
>> +       /* reset the scrambler. */
>> +       set_reg(dev, REG_FORCE_SCRAMBLER_RESET, 0x1);
>> +
>> +       /* Disable the main stream. */
>> +       set_reg(dev, REG_ENABLE_MAIN_STREAM, 0x0);
>> +}
>> +
>> +static void reset_dp_phy(struct udevice *dev, u32 reset)
>> +{
>> +       struct dp_tx *dp_tx = dev_get_priv(dev);
>> +       u32 val;
>> +
>> +       set_reg(dev, REG_ENABLE, 0x0);
>> +
>> +       val = get_reg(dev, REG_PHY_CONFIG);
>> +
>> +       /* Apply reset. */
>> +       set_reg(dev, REG_PHY_CONFIG, val | reset);
>> +
>> +       /* Remove reset. */
>> +       set_reg(dev, REG_PHY_CONFIG, val);
>> +
>> +       /* Wait for the PHY to be ready. */
>> +       wait_phy_ready(dev, PHY_STATUS_LANES_READY_MASK(dp_tx->max_lane_count));
>> +
>> +       set_reg(dev, REG_ENABLE, 0x1);
>> +}
>> +
>> +/*
>> + * enable or disable the enhanced framing symbol sequence for
>> + * both the DisplayPort TX core and the RX device.
>> + */
>> +static int set_enhanced_frame_mode(struct udevice *dev, u8 enable)
>> +{
>> +       struct dp_tx *dp_tx = dev_get_priv(dev);
>> +       int status;
>> +       u8 val;
>> +
>> +       if (!is_connected(dev))
>> +               return -ENODEV;
>> +
>> +       if (dp_tx->link_config.support_enhanced_framing_mode)
>> +               dp_tx->link_config.enhanced_framing_mode = enable;
>> +       else
>> +               dp_tx->link_config.enhanced_framing_mode = false;
>> +
>> +       /* Write enhanced frame mode enable to the DisplayPort TX core. */
>> +       set_reg(dev, REG_ENHANCED_FRAME_EN,
>> +               dp_tx->link_config.enhanced_framing_mode);
>> +
>> +       /* Write enhanced frame mode enable to the RX device. */
>> +       status = aux_read(dev, DPCD_LANE_COUNT_SET, 0x1, &val);
>> +       if (status)
>> +               return -EIO;
>> +
>> +       if (dp_tx->link_config.enhanced_framing_mode)
>> +               val |= DPCD_ENHANCED_FRAME_EN_MASK;
>> +       else
>> +               val &= ~DPCD_ENHANCED_FRAME_EN_MASK;
>> +
>> +       status = aux_write(dev, DPCD_LANE_COUNT_SET, 0x1, &val);
>> +       if (status)
>> +               return -EIO;
>> +
>> +       return 0;
>> +}
>> +
>> +/*
>> + * Set the number of lanes to be used by the main link for both
>> + * the DisplayPort TX core and the RX device.
>> + */
>> +static int set_lane_count(struct udevice *dev, u8 lane_count)
>> +{
>> +       struct dp_tx *dp_tx = dev_get_priv(dev);
>> +       int status;
>> +       u8 val;
>> +
>> +       if (!is_connected(dev))
>> +               return -ENODEV;
>> +
>> +       printf("       set lane count to %u\n", lane_count);
>> +
>> +       dp_tx->link_config.lane_count = lane_count;
>> +
>> +       /* Write the new lane count to the DisplayPort TX core. */
>> +       set_reg(dev, REG_LANE_COUNT_SET, dp_tx->link_config.lane_count);
>> +
>> +       /* Write the new lane count to the RX device. */
>> +       status = aux_read(dev, DPCD_LANE_COUNT_SET, 0x1, &val);
>> +       if (status)
>> +               return -EIO;
>> +       val &= ~DPCD_LANE_COUNT_SET_MASK;
>> +       val |= dp_tx->link_config.lane_count;
>> +
>> +       status = aux_write(dev, DPCD_LANE_COUNT_SET, 0x1, &val);
>> +       if (status)
>> +               return -EIO;
>> +
>> +       return 0;
>> +}
>> +
>> +/*
>> + * Set the clock frequency for the DisplayPort PHY corresponding
>> + * to a desired data rate.
>> + */
>> +static int set_clk_speed(struct udevice *dev, u32 speed)
>> +{
>> +       struct dp_tx *dp_tx = dev_get_priv(dev);
>> +       int status;
>> +       u32 val;
>> +
>> +       /* Disable the DisplayPort TX core first. */
>> +       val = get_reg(dev, REG_ENABLE);
>> +       set_reg(dev, REG_ENABLE, 0x0);
>> +
>> +       /* Change speed of the feedback clock. */
>> +       set_reg(dev, REG_PHY_CLOCK_SELECT, speed);
>> +
>> +       /* Re-enable the DisplayPort TX core if it was previously enabled. */
>> +       if (val)
>> +               set_reg(dev, REG_ENABLE, 0x1);
>> +
>> +       /* Wait until the PHY is ready. */
>> +       status = wait_phy_ready(dev, PHY_STATUS_LANES_READY_MASK(dp_tx->max_lane_count));
>> +       if (status)
>> +               return -EIO;
>> +
>> +       return 0;
>> +}
>> +
>> +/*
>> + * Set the data rate to be used by the main link for both the
>> + * DisplayPort TX core and the RX device.
>> + */
>> +static int set_link_rate(struct udevice *dev, u8 link_rate)
>> +{
>> +       struct dp_tx *dp_tx = dev_get_priv(dev);
>> +       int status;
>> +
>> +       /* Write a corresponding clock frequency to the DisplayPort TX core. */
>> +       switch (link_rate) {
>> +       case LINK_BW_SET_162GBPS:
>> +               printf("       set link rate to 1.62 Gb/s\n");
>> +               status = set_clk_speed(dev, PHY_CLOCK_SELECT_162GBPS);
>> +               break;
>> +       case LINK_BW_SET_270GBPS:
>> +               printf("       set link rate to 2.70 Gb/s\n");
>> +               status = set_clk_speed(dev, PHY_CLOCK_SELECT_270GBPS);
>> +               break;
>> +       case LINK_BW_SET_540GBPS:
>> +               printf("       set link rate to 5.40 Gb/s\n");
>> +               status = set_clk_speed(dev, PHY_CLOCK_SELECT_540GBPS);
>> +               break;
>> +       default:
>> +               return -EINVAL;
>> +       }
>> +       if (status)
>> +               return -EIO;
>> +
>> +       dp_tx->link_config.link_rate = link_rate;
>> +
>> +       /* Write new link rate to the DisplayPort TX core. */
>> +       set_reg(dev, REG_LINK_BW_SET, dp_tx->link_config.link_rate);
>> +
>> +       /* Write new link rate to the RX device. */
>> +       status = aux_write(dev, DPCD_LINK_BW_SET, 1,
>> +                          &dp_tx->link_config.link_rate);
>> +       if (status)
>> +               return -EIO;
>
> Can you not return the error you got from aux_write()?
>

I'll return the aux_write error code in v2.

> [..]
>
> Regards,
> Simon

Best regards,

Mario

^ permalink raw reply	[flat|nested] 138+ messages in thread

* [U-Boot] [PATCH 37/51] drivers: Add ihs_video_out driver
  2017-07-19  9:06   ` Simon Glass
@ 2017-07-25 11:36     ` Mario Six
  0 siblings, 0 replies; 138+ messages in thread
From: Mario Six @ 2017-07-25 11:36 UTC (permalink / raw)
  To: u-boot

Hi Simon,

On Wed, Jul 19, 2017 at 11:06 AM, Simon Glass <sjg@chromium.org> wrote:
> Hi Mario,
>
> On 14 July 2017 at 05:55, Mario Six <mario.six@gdsys.cc> wrote:
>> Add a driver for IHS OSDs on IHS FPGAs.
>>
>> Signed-off-by: Mario Six <mario.six@gdsys.cc>
>> ---
>>
>>  drivers/misc/Kconfig         |   6 ++
>>  drivers/misc/Makefile        |   1 +
>>  drivers/misc/ihs_video_out.c | 243 +++++++++++++++++++++++++++++++++++++++++++
>>  include/dm/uclass-id.h       |   1 +
>>  include/ihs_video_out.h      | 146 ++++++++++++++++++++++++++
>>  5 files changed, 397 insertions(+)
>>  create mode 100644 drivers/misc/ihs_video_out.c
>>  create mode 100644 include/ihs_video_out.h
>>
>> diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig
>> index c53f9f195e..c0e4b921b4 100644
>> --- a/drivers/misc/Kconfig
>> +++ b/drivers/misc/Kconfig
>> @@ -209,4 +209,10 @@ config IHS_AXI
>>         help
>>           Support for IHS AXI bus.
>>
>> +config IHS_VIDEO_OUT
>> +       bool "Enable IHS video out driver"
>> +       depends on MISC
>> +       help
>> +         Support for IHS video out.
>> +
>>  endmenu
>> diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile
>> index a6c71acedd..eab539b739 100644
>> --- a/drivers/misc/Makefile
>> +++ b/drivers/misc/Makefile
>> @@ -54,3 +54,4 @@ obj-$(CONFIG_QFW) += qfw.o
>>  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
>> diff --git a/drivers/misc/ihs_video_out.c b/drivers/misc/ihs_video_out.c
>> new file mode 100644
>> index 0000000000..a7e855f054
>> --- /dev/null
>> +++ b/drivers/misc/ihs_video_out.c
>> @@ -0,0 +1,243 @@
>> +/*
>> + * (C) Copyright 2017
>> + * Mario Six,  Guntermann & Drunck GmbH, mario.six at gdsys.cc
>> + *
>> + * based on the gdsys osd driver, which is
>> + *
>> + * (C) Copyright 2010
>> + * Dirk Eibach,  Guntermann & Drunck GmbH, eibach at gdsys.de
>> + *
>> + * SPDX-License-Identifier:    GPL-2.0+
>> + */
>> +
>> +#include <common.h>
>> +#include <dm.h>
>> +#include <dm/device-internal.h>
>> +#include <dm/uclass-internal.h>
>> +#include <gdsys_soc.h>
>> +#include <ihs_fpga.h>
>> +#include <ihs_video_out.h>
>> +#include <transmitter.h>
>> +#include <asm/gpio.h>
>> +
>> +#include "../transmitter/logicore_dp_tx.h"
>> +
>> +DECLARE_GLOBAL_DATA_PTR;
>> +
>> +enum {
>> +       REG_VERSION = 0x00,
>> +       REG_FEATURES = 0x02,
>> +       REG_CONTROL = 0x04,
>> +       REG_XY_SIZE = 0x06,
>> +       REG_XY_SCALE = 0x08,
>> +       REG_X_POS = 0x0A,
>> +       REG_Y_POS = 0x0C,
>> +};
>> +
>> +struct ihs_video_out_priv {
>> +       int addr;
>> +       int osd_base;
>> +       int osd_buffer_base;
>> +       uint base_width;
>> +       uint base_height;
>> +       int sync_src;
>> +       struct udevice *dp_tx;
>> +       struct udevice *clk_gen;
>> +};
>> +
>> +UCLASS_DRIVER(ihs_video_out) = {
>> +       .id             = UCLASS_IHS_VIDEO_OUT,
>> +       .name           = "ihs_video_out",
>> +       .flags          = DM_UC_FLAG_SEQ_ALIAS,
>> +};
>> +
>> +static const struct udevice_id ihs_video_out_ids[] = {
>> +       { .compatible = "gdsys,ihs_video_out" },
>> +       { }
>> +};
>> +
>> +int video_out_get_data(struct udevice *dev, struct ihs_video_out_data *data)
>> +{
>> +       struct ihs_video_out_ops *ops = ihs_video_out_get_ops(dev);
>> +
>> +       return ops->get_data(dev, data);
>> +}
>> +
>> +int video_out_set_mem(struct udevice *dev, uint x, uint y, u16 *buf,
>> +                     size_t buflen)
>> +{
>> +       struct ihs_video_out_ops *ops = ihs_video_out_get_ops(dev);
>> +
>> +       return ops->set_mem(dev, x, y, buf, buflen);
>> +}
>> +
>> +int video_out_set_control(struct udevice *dev, u16 value)
>> +{
>> +       struct ihs_video_out_ops *ops = ihs_video_out_get_ops(dev);
>> +
>> +       return ops->set_control(dev, value);
>> +}
>> +
>> +int video_out_set_size(struct udevice *dev, u16 xy_size, u16 x_pos, u16 y_pos)
>> +{
>> +       struct ihs_video_out_ops *ops = ihs_video_out_get_ops(dev);
>> +
>> +       return ops->set_size(dev, xy_size, x_pos, y_pos);
>> +}
>> +
>> +void print_info(struct udevice *dev)
>> +{
>> +       struct ihs_video_out_priv *priv = dev_get_priv(dev);
>> +       struct gdsys_soc_child_platdata *pplat = dev_get_parent_platdata(dev);
>> +       u16 version;
>> +       u16 features;
>> +       u16 control = 0x49;
>> +
>> +       version = fpga_in_le16(pplat->fpga, priv->osd_base + REG_VERSION);
>> +       features = fpga_in_le16(pplat->fpga, priv->osd_base + REG_FEATURES);
>> +
>> +       if (priv->sync_src)
>> +               control |= ((priv->sync_src & 0x7) << 8);
>> +
>> +       fpga_out_le16(pplat->fpga, priv->osd_base + REG_CONTROL, control);
>> +
>> +       priv->base_width = ((features & 0x3f00) >> 8) + 1;
>> +       priv->base_height = (features & 0x001f) + 1;
>> +
>> +       printf("OSD-%s: Digital-OSD version %01d.%02d, %d x %d characters\n",
>> +              dev->name, version / 100, version % 100,
>> +              priv->base_width, priv->base_height);
>> +}
>> +
>> +int ihs_video_out_get_data(struct udevice *dev, struct ihs_video_out_data *data)
>> +{
>> +       struct ihs_video_out_priv *priv = dev_get_priv(dev);
>> +
>> +       data->width = priv->base_width;
>> +       data->height = priv->base_height;
>> +
>> +       return 0;
>> +}
>> +
>> +int ihs_video_out_set_mem(struct udevice *dev, uint x, uint y, u16 *buf,
>> +                         size_t buflen)
>> +{
>> +       struct ihs_video_out_priv *priv = dev_get_priv(dev);
>> +       struct gdsys_soc_child_platdata *pplat = dev_get_parent_platdata(dev);
>> +       uint offset = y * priv->base_width + x;
>> +       uint k;
>> +
>> +       for (k = 0; k < buflen; ++k) {
>> +               if (offset + k >= priv->base_width * priv->base_height)
>> +                       return -ENXIO;
>> +
>> +               fpga_out_le16(pplat->fpga,
>> +                             priv->osd_buffer_base + offset + k, buf[k]);
>> +       }
>> +
>> +       return buflen;
>> +}
>> +
>> +int ihs_video_out_set_control(struct udevice *dev, u16 value)
>> +{
>> +       struct ihs_video_out_priv *priv = dev_get_priv(dev);
>> +       struct gdsys_soc_child_platdata *pplat = dev_get_parent_platdata(dev);
>> +
>> +       fpga_out_le16(pplat->fpga, priv->addr + REG_CONTROL, value);
>> +
>> +       return 0;
>> +}
>> +
>> +int ihs_video_out_set_size(struct udevice *dev, u16 xy_size,
>> +                          u16 x_pos, u16 y_pos)
>> +{
>> +       struct ihs_video_out_priv *priv = dev_get_priv(dev);
>> +       struct gdsys_soc_child_platdata *pplat = dev_get_parent_platdata(dev);
>> +
>> +       fpga_out_le16(pplat->fpga, priv->addr + REG_XY_SIZE, xy_size);
>> +       fpga_out_le16(pplat->fpga, priv->addr + REG_X_POS, x_pos);
>> +       fpga_out_le16(pplat->fpga, priv->addr + REG_Y_POS, y_pos);
>> +
>> +       return 0;
>> +}
>> +
>> +static const struct ihs_video_out_ops ihs_video_out_ops = {
>> +       .get_data = ihs_video_out_get_data,
>> +       .set_mem = ihs_video_out_set_mem,
>> +       .set_control = ihs_video_out_set_control,
>> +       .set_size = ihs_video_out_set_size,
>> +};
>> +
>> +int ihs_video_out_probe(struct udevice *dev)
>> +{
>> +       struct ihs_video_out_priv *priv = dev_get_priv(dev);
>> +       int len = 0;
>> +       struct fdtdec_phandle_args phandle_args;
>> +       char *mode;
>> +
>> +       priv->addr = fdtdec_get_int(gd->fdt_blob, dev_of_offset(dev),
>> +                                   "reg", -1);
>
> Can we use dev_read_...() API?
>

I'll switch to the new API in v2 (again, older code so it still used the old
API).

>> +
>> +       priv->osd_base = fdtdec_get_int(gd->fdt_blob, dev_of_offset(dev),
>> +                                       "osd_base", -1);
>> +
>> +       priv->osd_buffer_base = fdtdec_get_int(gd->fdt_blob, dev_of_offset(dev),
>> +                                              "osd_buffer_base", -1);
>> +
>> +       priv->sync_src = fdtdec_get_bool(gd->fdt_blob, dev_of_offset(dev),
>> +                       "sync-source");
>> +
>> +       print_info(dev);
>> +
>> +       if (fdtdec_parse_phandle_with_args(gd->fdt_blob, dev_of_offset(dev),
>> +                                          "clk_gen", NULL, 0, 0,
>> +                                          &phandle_args)) {
>> +               printf("%s: Could not get clk_gen node.\n", dev->name);
>> +               return -1;
>
> These should return -EINVAL I think.
>

OK, will change in v2.

>> +       }
>> +
>> +       if (device_get_global_by_of_offset(phandle_args.node, &priv->clk_gen)) {
>> +               printf("%s: Could not get clk_gen dev.\n", dev->name);
>> +               return -1;
>> +       }
>> +
>> +       if (fdtdec_parse_phandle_with_args(gd->fdt_blob, dev_of_offset(dev),
>> +                                          "dp_tx", NULL, 0, 0,
>> +                                          &phandle_args)) {
>> +               printf("%s: Could not get dp_tx.\n", dev->name);
>> +               return -1;
>> +       }
>> +
>> +       if (device_get_global_by_of_offset(phandle_args.node, &priv->dp_tx)) {
>> +               printf("%s: Could not get dp_tx dev.\n", dev->name);
>> +               return -1;
>> +       }
>> +
>> +       mode = (char *)fdt_getprop(gd->fdt_blob, dev_of_offset(dev),
>> +                                  "mode", &len);
>> +
>> +       if (!mode) {
>> +               printf("%s: Could not read mode property.\n", dev->name);
>> +               return -1;
>> +       }
>> +
>> +       if (!strcmp(mode, "1024_768_60"))
>> +               priv->sync_src = 2;
>> +       else if (!strcmp(mode, "720_400_70"))
>> +               priv->sync_src = 1;
>> +       else
>> +               priv->sync_src = 0;
>> +
>> +       transmitter_power_on(priv->dp_tx, mode);
>> +
>> +       return 0;
>> +}
>> +
>> +U_BOOT_DRIVER(ihs_video_out_drv) = {
>> +       .name           = "ihs_video_out_drv",
>> +       .id             = UCLASS_IHS_VIDEO_OUT,
>> +       .ops            = &ihs_video_out_ops,
>> +       .of_match       = ihs_video_out_ids,
>> +       .probe          = ihs_video_out_probe,
>> +       .priv_auto_alloc_size = sizeof(struct ihs_video_out_priv),
>> +};
>> diff --git a/include/dm/uclass-id.h b/include/dm/uclass-id.h
>> index 1a24de10b4..a40185d2bb 100644
>> --- a/include/dm/uclass-id.h
>> +++ b/include/dm/uclass-id.h
>> @@ -44,6 +44,7 @@ enum uclass_id {
>>         UCLASS_I2C_MUX,         /* I2C multiplexer */
>>         UCLASS_IHS_AXI,         /* gdsys IHS AXI bus */
>>         UCLASS_IHS_FPGA,        /* gdsys IHS FPGAs */
>> +       UCLASS_IHS_VIDEO_OUT,   /* gdsys IHS video output */
>
> Is this video out? It seems to me it is more about an on-screen
> display/ So how about a new uclass like VIDEO_OSD?
>
> Then you can make it generic so that other drivers might use it. Your
> operations don't seem too specific to this driver...?
>

Yes, the naming convention is a bit weird here. The video_out device controls
both the actual video registers and the OSD functionalities, but only the OSD
stuff is used in U-Boot.

A new uclass would be fine with me, but is it OK to assume that all OSDs are
text-based (like ours is)? What about those that are pixel-based? Would they
just use a different set of functions in the same uclass?

>>         UCLASS_IRQ,             /* Interrupt controller */
>>         UCLASS_KEYBOARD,        /* Keyboard input device */
>>         UCLASS_LED,             /* Light-emitting diode (LED) */
>> diff --git a/include/ihs_video_out.h b/include/ihs_video_out.h
>> new file mode 100644
>> index 0000000000..e3dcdad8c5
>> --- /dev/null
>> +++ b/include/ihs_video_out.h
>> @@ -0,0 +1,146 @@
>> +/*
>> + * (C) Copyright 2017
>> + * Mario Six,  Guntermann & Drunck GmbH, mario.six at gdsys.cc
>> + *
>> + * SPDX-License-Identifier:    GPL-2.0+
>> + */
>> +
>> +#ifndef _IHS_VIDEO_OUT_H_
>> +#define _IHS_VIDEO_OUT_H_
>> +
>> +/*
>> + * The IHS OSD is a character-oriented on-screen display of gdsys devices built
>> + * into a IHS FPGA. It is controlled via a set of registers in the FPGA's
>> + * register space, as well as a memory buffer that holds character data
>> + * (line-wise, left-to-right, 16 bit per character) that constitute the data to
>> + * be displayed by the OSD.
>> + */
>> +
>> +/**
>> + * struct ihs_video_out_data - information about a IHS OSD instance
>> + *
>> + * @width      Maximum width of the OSD screen in characters.
>> + * @heigth     Maximum height of the OSD screen in characters.
>> + */
>> +struct ihs_video_out_data {
>> +       uint width;
>> +       uint height;
>> +};
>> +
>> +/**
>> + * struct ihs_video_out_ops - driver operations for IHS OSD 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 ihs_video_out_ops {
>> +       /**
>> +        * get_data() - Get information about a IHS OSD instance
>> +        *
>> +        * A IHS OSD instance keeps some internal data about itself. This
>> +        * function can be used to access this data.
>> +        *
>> +        * @dev:        IHS OSD instance to query.
>> +        * @data:       Pointer to a struct ihs_video_out_data structure that
>> +        *              takes the information read from the OSD instance.
>> +        * @return 0 if OK, -ve on error.
>> +        */
>> +       int (*get_data)(struct udevice *dev, struct ihs_video_out_data *data);
>> +
>> +       /**
>> +        * set_mem() - Write pixel data to OSD memory
>> +        *
>> +        * Each 16 bit word of data encodes the display information for a
>> +        * single character. The data are written to a given character position
>> +        * (x/y coordinates), which are written left-to-right, line-wise,
>> +        * continuing to the next line if the data are longer than the current
>> +        * line.
>> +        *
>> +        * @dev:        IHS OSD instance to query.
>
> query?
>

Copy-paste error, will fix in v2.

>> +        * @x:          Horizontal character coordinate to write to.
>> +        * @y:          Vertical character coordinate to write to.
>> +        * @buf:        Array containing 16 bit words to write to the specified
>> +        *              address in the IHS OSD memory.
>
> Here I wonder if we can use a u8 * ?
>

For a generic osd uclass definitely; I used u16 here, since our OSD only
supports 16-bit accesses.

>> +        * @buflen:     Length of the data in the passed buffer (in 16 bit
>> +        *              words).
>> +        * @return 0 if OK, -ve on error.
>> +        */
>> +       int (*set_mem)(struct udevice *dev, uint x, uint y, u16 *buf, size_t buflen);
>> +
>> +       /**
>> +        * set_control() - Set the value of the IHS OSD's control register
>> +        *
>> +        * @dev:        IHS OSD instance to write to.
>> +        * @value:      Value to write to the IHS OSD's control register.
>> +        * @return 0 if OK, -ve on error.
>> +        */
>> +       int (*set_control)(struct udevice *dev, u16 value);
>> +
>> +       /**
>> +        * set_size() - Set the position and dimension of the IHS OSD's
>> +        *              writeable window
>> +        *
>> +        * @dev:        IHS OSD instance to write to.
>> +        * @xy_size:    The number of characters in a row and a column,
>> +        *              combined into a 16 bit value.
>
> Can you separate out the values?
>

OK, will separate them in v2.

>> +        * @x_pos:      The horizontal position of the upper left corner of the
>> +        *              OSD's writeable window in pixels.
>> +        * @y_pos:      The vertical position of the upper left corner of the
>> +        *              OSD's writeable window in pixels.
>> +        * @return 0 if OK, -ve on error.
>> +        */
>> +       int (*set_size)(struct udevice *dev, u16 xy_size, u16 x_pos, u16 y_pos);
>> +};
>> +
>> +#define ihs_video_out_get_ops(dev)     ((struct ihs_video_out_ops *)(dev)->driver->ops)
>> +
>> +/**
>> + * video_out_get_data() - Get information about a IHS OSD instance
>> + *
>> + * @dev:       IHS OSD instance to query.
>> + * @data:      Pointer to a struct ihs_video_out_data structure that takes the
>> + *             information read from the OSD instance.
>> + * @return 0 if OK, -ve on error.
>> + */
>> +int video_out_get_data(struct udevice *dev, struct ihs_video_out_data *data);
>> +
>> +/**
>> + * video_out_set_mem() - Write pixel data to OSD memory
>> + *
>> + * @dev:       IHS OSD instance to query.
>> + * @x:         Horizontal character coordinate to write to.
>> + * @y:         Vertical character coordinate to write to.
>> + * @buf:       Array containing 16 bit words to write to the specified address
>> + *             in the IHS OSD memory.
>
> u8 * ?
>

For a generic osd uclass, yes. Will fix in v2.

>> + * @buflen:    Length of the data in the passed buffer (in 16 bit words).
>> + * @return 0 if OK, -ve on error.
>> + */
>> +int video_out_set_mem(struct udevice *dev, uint x, uint y, u16 *buf,
>> +                     size_t buflen);
>> +
>> +/**
>> + * video_out_set_control() - Set the value of the IHS OSD's control register
>> + *
>> + * @dev:       IHS OSD instance to write to.
>> + * @value:     Value to write to the IHS OSD's control register.
>> + * @return 0 if OK, -ve on error.
>> + */
>> +int video_out_set_control(struct udevice *dev, u16 value);
>> +
>> +/**
>> + * video_out_set_size() - Set the position and dimension of the IHS OSD's
>> + *                       writeable window
>> + *
>> + * @dev:       IHS OSD instance to write to.
>> + * @xy_size:   The number of characters in a row and a column, combined into a
>> + *             16 bit value.
>> + * @x_pos:     The horizontal position of the upper left corner of the OSD's
>> + *             writeable window in pixels.
>> + * @y_pos:     The vertical position of the upper left corner of the OSD's
>> + *             writeable window in pixels.
>> + * @return 0 if OK, -ve on error.
>> + */
>> +int video_out_set_size(struct udevice *dev, u16 xy_size, u16 x_pos, u16 y_pos);
>> +
>> +#endif /* !_IHS_VIDEO_OUT_H_ */
>> --
>> 2.11.0
>>
>
> Regards,
> Simon

Best regards,

Mario

^ permalink raw reply	[flat|nested] 138+ messages in thread

* [U-Boot] [PATCH 38/51] gdsys: drivers: Add gdsys_rxaui_ctrl driver
  2017-07-19  9:06   ` Simon Glass
@ 2017-07-25 11:41     ` Mario Six
  0 siblings, 0 replies; 138+ messages in thread
From: Mario Six @ 2017-07-25 11:41 UTC (permalink / raw)
  To: u-boot

Hi Simon,

On Wed, Jul 19, 2017 at 11:06 AM, Simon Glass <sjg@chromium.org> wrote:
> Hi Mario,
>
> On 14 July 2017 at 05:55, Mario Six <mario.six@gdsys.cc> wrote:
>> 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
>
> Can we use generic PHY for this and add a few operations? Or should we
> create a new phy type?
>

I think a ethernet-specific phy uclass is probably a good idea here, though I'm
not perfectly sure. Someone with more knowledge about the network subsystem can
probably answer that question better than me.

> In general with DM we should not add driver-specific uclasses. There
> are cases where is makes sense and it's hard to predict the future,
> but you can imagine ending up with a huge number of APIs if we don't
> manager to share.
>

OK, I wasn't really sure about that. Thanks for clarifying.

> Regards.
> Simon

Best regards,

Mario

^ permalink raw reply	[flat|nested] 138+ messages in thread

* [U-Boot] [PATCH 39/51] drivers: Add gdsys_ioep driver
  2017-07-19  9:06   ` Simon Glass
@ 2017-07-25 11:49     ` Mario Six
  0 siblings, 0 replies; 138+ messages in thread
From: Mario Six @ 2017-07-25 11:49 UTC (permalink / raw)
  To: u-boot

Hi Simon,

On Wed, Jul 19, 2017 at 11:06 AM, Simon Glass <sjg@chromium.org> wrote:
> Hi Mario,
>
> On 14 July 2017 at 05:55, Mario Six <mario.six@gdsys.cc> wrote:
>> Add driver for the IHS IO endpoint on IHS FPGAs.
>
> Would UCLASS_MAILBOX work for this?
>
> Or MISC?
>

Hmm, we do need the enable_receive, disable_receive, set_address,
data_available, and reset_status functions somehow, so mailbox is probably a
bit restrictive. The misc uclass will always work, of course, but implementing
all functionality with ioctl is a bit ugly as well.

>>
>> Signed-off-by: Mario Six <mario.six@gdsys.cc>
>> ---
>>
>>  drivers/misc/Kconfig      |   6 +
>>  drivers/misc/Makefile     |   1 +
>>  drivers/misc/gdsys_ioep.c | 301 ++++++++++++++++++++++++++++++++++++++++++++++
>>  include/dm/uclass-id.h    |   1 +
>>  include/gdsys_ioep.h      | 196 ++++++++++++++++++++++++++++++
>>  5 files changed, 505 insertions(+)
>>  create mode 100644 drivers/misc/gdsys_ioep.c
>>  create mode 100644 include/gdsys_ioep.h

Best regards,

Mario

^ permalink raw reply	[flat|nested] 138+ messages in thread

* [U-Boot] [PATCH 40/51] cmd: Add ihs osd commands
  2017-07-19  9:06   ` Simon Glass
@ 2017-07-25 12:01     ` Mario Six
  0 siblings, 0 replies; 138+ messages in thread
From: Mario Six @ 2017-07-25 12:01 UTC (permalink / raw)
  To: u-boot

Hi Simon,

On Wed, Jul 19, 2017 at 11:06 AM, Simon Glass <sjg@chromium.org> wrote:
> Hi Mario,
>
> On 14 July 2017 at 05:55, Mario Six <mario.six@gdsys.cc> wrote:
>> Add command to query information from and write text to IHS OSDs.
>>
>> Signed-off-by: Mario Six <mario.six@gdsys.cc>
>> ---
>>
>>  cmd/Kconfig   |   6 +++
>>  cmd/Makefile  |   1 +
>>  cmd/ihs_osd.c | 167 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
>>  3 files changed, 174 insertions(+)
>>  create mode 100644 cmd/ihs_osd.c
>>
>> diff --git a/cmd/Kconfig b/cmd/Kconfig
>> index 6425c425d6..b632049022 100644
>> --- a/cmd/Kconfig
>> +++ b/cmd/Kconfig
>> @@ -933,6 +933,12 @@ config CMD_DISPLAY
>>           displayed on a simple board-specific display. Implement
>>           display_putc() to use it.
>>
>> +config CMD_IHS_OSD
>> +       bool "ihs osd"
>> +       help
>> +         Enable the 'osd' command which allows to query information from and
>> +         write text data to a gdsys OSD.
>> +
>>  config CMD_LED
>>         bool "led"
>>         default y if LED
>> diff --git a/cmd/Makefile b/cmd/Makefile
>> index 243f9f45d4..c30511982b 100644
>> --- a/cmd/Makefile
>> +++ b/cmd/Makefile
>> @@ -62,6 +62,7 @@ obj-$(CONFIG_CMD_FS_GENERIC) += fs.o
>>  obj-$(CONFIG_CMD_FUSE) += fuse.o
>>  obj-$(CONFIG_CMD_GETTIME) += gettime.o
>>  obj-$(CONFIG_CMD_GPIO) += gpio.o
>> +obj-$(CONFIG_CMD_IHS_OSD) += ihs_osd.o
>>  obj-$(CONFIG_CMD_I2C) += i2c.o
>>  obj-$(CONFIG_CMD_IOTRACE) += iotrace.o
>>  obj-$(CONFIG_CMD_HASH) += hash.o
>> diff --git a/cmd/ihs_osd.c b/cmd/ihs_osd.c
>> new file mode 100644
>> index 0000000000..01ef3eee83
>> --- /dev/null
>> +++ b/cmd/ihs_osd.c
>> @@ -0,0 +1,167 @@
>> +/*
>> + * (C) Copyright 2017
>> + * Mario Six,  Guntermann & Drunck GmbH, mario.six at gdsys.cc
>> + *
>> + * based on the gdsys osd driver, which is
>> + *
>> + * (C) Copyright 2010
>> + * Dirk Eibach,  Guntermann & Drunck GmbH, eibach at gdsys.de
>> + *
>> + * SPDX-License-Identifier:    GPL-2.0+
>> + */
>> +
>> +#include <common.h>
>> +#include <dm.h>
>> +#include <dm/uclass-internal.h>
>> +#include <i2c.h>
>> +#include <ihs_video_out.h>
>> +#include <malloc.h>
>> +
>> +#define MAX_VIDEOMEM_WIDTH 64
>> +#define MAX_VIDEOMEM_HEIGHT 32
>> +#define MAX_X_CHARS 53
>> +#define MAX_Y_CHARS 26
>
>
>> +
>> +size_t hexstr_to_u16_array(char *hexstr, u16 *array, size_t arrsize)
>> +{
>> +       size_t pos;
>> +
>> +       for (pos = 0; pos < arrsize; ++pos) {
>> +               char substr[5];
>> +
>> +               memcpy(substr, hexstr, 4);
>> +               substr[4] = 0;
>> +               *array = simple_strtoul(substr, NULL, 16);
>> +
>> +               hexstr += 4;
>> +               array++;
>> +               if (*hexstr == 0)
>> +                       break;
>> +       }
>> +
>> +       return pos;
>> +}
>> +
>> +int do_osd_write(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
>> +{
>> +       struct udevice *dev;
>> +       uint x, y;
>> +       uint count;
>> +       char *hexstr;
>> +       u16 buffer[MAX_VIDEOMEM_WIDTH];
>> +       size_t buflen;
>> +
>> +       if ((argc < 4) || (strlen(argv[3]) % 4)) {
>> +               cmd_usage(cmdtp);
>> +               return 1;
>> +       }
>> +
>> +       x = simple_strtoul(argv[1], NULL, 16);
>> +       y = simple_strtoul(argv[2], NULL, 16);
>> +       hexstr = argv[3];
>> +       count = (argc > 4) ? simple_strtoul(argv[4], NULL, 16) : 1;
>> +
>> +       buflen = hexstr_to_u16_array(hexstr, buffer, MAX_VIDEOMEM_WIDTH);
>> +
>> +       for (uclass_find_first_device(UCLASS_IHS_VIDEO_OUT, &dev);
>> +            dev;
>> +            uclass_find_next_device(&dev)) {
>
> Why write to all devices? Perhaps you should have the concept of a
> current device in this file?
>

We always write to all possible OSDs on our boards. But for a generic OSD
uclass this doesn't really make sense, I realize.

This does create a problem with backwards compatibility, though. See below.

>> +               uint k;
>> +
>> +               for (k = 0; k < count; ++k)
>> +                       video_out_set_mem(dev, x + k * buflen, y, buffer,
>> +                                         buflen);
>> +
>> +               video_out_set_control(dev, 0x0049);
>> +       }
>> +
>> +       return 0;
>> +}
>> +
>> +static int do_osd_print(cmd_tbl_t *cmdtp, int flag, int argc,
>> +                       char * const argv[])
>> +{
>> +       struct udevice *dev;
>> +       u16 buffer[MAX_VIDEOMEM_WIDTH];
>> +       uint x, y, charcount, len;
>> +       u8 color;
>> +       uint k;
>> +       char *text;
>> +
>> +       if (argc < 5) {
>> +               cmd_usage(cmdtp);
>> +               return 1;
>> +       }
>> +
>> +       x = simple_strtoul(argv[1], NULL, 16);
>> +       y = simple_strtoul(argv[2], NULL, 16);
>> +       color = simple_strtoul(argv[3], NULL, 16);
>> +       text = argv[4];
>> +       charcount = strlen(text);
>> +       len = min(charcount, (uint)MAX_VIDEOMEM_WIDTH);
>> +
>> +       for (uclass_find_first_device(UCLASS_IHS_VIDEO_OUT, &dev);
>> +            dev;
>> +            uclass_find_next_device(&dev)) {
>> +               int res;
>> +
>> +               for (k = 0; k < len; ++k)
>> +                       buffer[k] = (text[k] << 8) | color;
>
> This is specific to your device. If you are making a generic device
> you should have something like video_osd_set_char(...k, color).
>
> Then other drivers can implement it.
>

OK, will implement a generic interface in v2 if the backwards compatibility
problem can be solved, see below.

>> +
>> +               res = video_out_set_mem(dev, x, y, buffer, len);
>> +
>> +               if (res < 0)
>> +                       return res;
>> +
>> +               video_out_set_control(dev, 0x0049);
>> +       }
>> +
>> +       return 0;
>> +}
>> +
>> +int do_osd_size(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
>> +{
>> +       struct udevice *dev;
>> +       uint x, y;
>> +
>> +       if (argc < 3) {
>> +               cmd_usage(cmdtp);
>> +               return 1;
>> +       }
>> +
>> +       x = simple_strtoul(argv[1], NULL, 16);
>> +       y = simple_strtoul(argv[2], NULL, 16);
>> +
>> +       if (!x || (x > 64) || (x > MAX_X_CHARS) ||
>> +           !y || (y > 32) || (y > MAX_Y_CHARS)) {
>> +               cmd_usage(cmdtp);
>> +               return 1;
>> +       }
>> +
>> +       for (uclass_find_first_device(UCLASS_IHS_VIDEO_OUT, &dev);
>> +            dev;
>> +            uclass_find_next_device(&dev))
>> +               video_out_set_size(dev, ((x - 1) << 8) | (y - 1),
>> +                                  32767 * (640 - 12 * x) / 65535,
>> +                                  32767 * (480 - 18 * x) / 65535);
>
> Again this logic should be in the driver, not the command.
>

Dito, will change in v2, if the backwards compatibility problem can be solved,
see below.

>> +
>> +       return 0;
>> +}
>> +
>> +U_BOOT_CMD(
>> +       osdw, 5, 0, do_osd_write,
>> +       "write 16-bit hex encoded buffer to osd memory",
>> +       "osd write [pos_x] [pos_y] [buffer] [count] - write 16-bit hex encoded buffer to osd memory\n"
>> +);
>> +
>> +U_BOOT_CMD(
>> +       osdp, 5, 0, do_osd_print,
>> +       "write ASCII buffer to osd memory",
>> +       "osd print [pos_x] [pos_y] [color] [text] - write ASCII buffer to osd memory\n"
>> +);
>> +
>> +U_BOOT_CMD(
>> +       osdsize, 3, 0, do_osd_size,
>> +       "set OSD XY size in characters",
>> +       "osd size [size_x] [size_y] - set OSD XY size in characters\n"
>> +);
>> --
>> 2.11.0
>>
>
> I think this should be an 'osd' command with sub-commands.
>

That's how I first implemented it. Then I realized that these commands have to
be backwards compatible to the ones in boards/gdsys/common/osd.c. These demand
that data is queried from/written to all OSD instances, and they define three
commands instead of one with three subcommands.

How can I keep backwards compatibility intact while still implementing a
generic interface for OSDs?

> Regards,
> Simon

Best regards,

Mario

^ permalink raw reply	[flat|nested] 138+ messages in thread

* [U-Boot] [PATCH 36/51] drivers: Add ihs_axi driver
  2017-07-19  9:06   ` Simon Glass
@ 2017-07-25 12:27     ` Mario Six
  0 siblings, 0 replies; 138+ messages in thread
From: Mario Six @ 2017-07-25 12:27 UTC (permalink / raw)
  To: u-boot

Hi Simon,

On Wed, Jul 19, 2017 at 11:06 AM, Simon Glass <sjg@chromium.org> wrote:
> Hi Mario,
>
> On 14 July 2017 at 05:55, Mario Six <mario.six@gdsys.cc> wrote:
>> Add a driver for the IHS AXI bus on IHS FPGAs.
>
> Can we make this uclass more generic by using AXI instead of IHS_AXI?
>

This should work. I'll have to take a look at how to handle different bus
widths, but it should work in general.

>>
>> Signed-off-by: Mario Six <mario.six@gdsys.cc>
>> ---
>>
>>  drivers/misc/Kconfig   |   7 ++
>>  drivers/misc/Makefile  |   1 +
>>  drivers/misc/ihs_axi.c | 208 +++++++++++++++++++++++++++++++++++++++++++++++++
>>  include/dm/uclass-id.h |   1 +
>>  include/ihs_axi.h      |  69 ++++++++++++++++
>>  5 files changed, 286 insertions(+)
>>  create mode 100644 drivers/misc/ihs_axi.c
>>  create mode 100644 include/ihs_axi.h
>>
>> diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig
>> index 8b59a444ce..c53f9f195e 100644
>> --- a/drivers/misc/Kconfig
>> +++ b/drivers/misc/Kconfig
>> @@ -202,4 +202,11 @@ config IHS_FPGA
>>         depends on MISC
>>         help
>>           Support for IHS FPGA.
>> +
>> +config IHS_AXI
>> +       bool "Enable IHS AXI driver"
>> +       depends on MISC
>> +       help
>> +         Support for IHS AXI bus.
>
> More help? Spell out the abbreviations and point to more info.
>

OK, will add some more information in v2.

>> +
>>  endmenu
>> diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile
>> index d2e46fc7d6..a6c71acedd 100644
>> --- a/drivers/misc/Makefile
>> +++ b/drivers/misc/Makefile
>> @@ -53,3 +53,4 @@ obj-$(CONFIG_WINBOND_W83627) += winbond_w83627.o
>>  obj-$(CONFIG_QFW) += qfw.o
>>  obj-$(CONFIG_ROCKCHIP_EFUSE) += rockchip-efuse.o
>>  obj-$(CONFIG_IHS_FPGA) += ihs_fpga.o gdsys_soc.o
>> +obj-$(CONFIG_IHS_AXI) += ihs_axi.o
>> diff --git a/drivers/misc/ihs_axi.c b/drivers/misc/ihs_axi.c
>> new file mode 100644
>> index 0000000000..07150e2262
>> --- /dev/null
>> +++ b/drivers/misc/ihs_axi.c
>> @@ -0,0 +1,208 @@
>> +/*
>> + * (C) Copyright 2016
>> + * Dirk Eibach,  Guntermann & Drunck GmbH, dirk.eibach at gdsys.cc
>> + *
>> + * (C) Copyright 2017
>> + * Mario Six,  Guntermann & Drunck GmbH, mario.six at gdsys.cc
>> + *
>> + * SPDX-License-Identifier:    GPL-2.0+
>> + */
>> +
>> +#include <common.h>
>> +#include <dm.h>
>> +#include <dm/device-internal.h>
>> +#include <ihs_axi.h>
>> +#include <ihs_fpga.h>
>> +#include <gdsys_soc.h>
>> +
>> +DECLARE_GLOBAL_DATA_PTR;
>> +
>> +enum {
>> +       REG_INTERRUPT_STATUS = 0x00,
>> +       REG_INTERRUPT_ENABLE_CONTROL = 0x02,
>> +       REG_ADDRESS_LSB = 0x04,
>> +       REG_ADDRESS_MSB = 0x06,
>> +       REG_WRITE_DATA_LSB = 0x08,
>> +       REG_WRITE_DATA_MSB = 0x0A,
>> +       REG_READ_DATA_LSB = 0x0C,
>> +       REG_READ_DATA_MSB = 0x0E,
>> +};
>> +
>> +struct ihs_axi_priv {
>> +       fdt_addr_t addr;
>> +};
>> +
>> +enum {
>> +       STATUS_EVENT_MASK = GENMASK(15, 12),
>> +
>> +       STATUS_READ_COMPLETE_EVENT = BIT(15),
>> +       STATUS_WRITE_COMPLETE_EVENT = BIT(14),
>> +       STATUS_TIMEOUT_EVENT = BIT(13),
>> +       STATUS_ERROR_EVENT = BIT(12),
>> +       STATUS_AXI_INT = BIT(11),
>> +       STATUS_READ_DATA_AVAILABLE = BIT(7),
>> +       STATUS_BUSY = BIT(6),
>> +       STATUS_INIT_DONE = BIT(5),
>> +};
>> +
>> +enum {
>> +       CONTROL_EVENT_ENABLE_MASK = GENMASK(15, 11),
>> +       CONTROL_CMD_MASK = GENMASK(3, 0),
>> +
>> +       CONTROL_READ_COMPLETE_EVENT_ENABLE = BIT(15),
>> +       CONTROL_WRITE_COMPLETE_EVENT_ENABLE = BIT(14),
>> +       CONTROL_TIMEOUT_EVENT_ENABLE = BIT(13),
>> +       CONTROL_ERROR_EVENT_ENABLE = BIT(12),
>> +       CONTROL_AXI_INT_ENABLE = BIT(11),
>> +
>> +       CONTROL_CMD_NOP = 0x0,
>> +       CONTROL_CMD_WRITE = 0x8,
>> +       CONTROL_CMD_WRITE_POST_INC = 0x9,
>> +       CONTROL_CMD_READ = 0xa,
>> +       CONTROL_CMD_READ_POST_INC = 0xb,
>> +
>> +};
>> +
>> +static int axi_transfer(struct udevice *bus, u32 address, u16 cmd,
>> +                       u16 complete_flag)
>> +{
>> +       struct ihs_axi_priv *priv = dev_get_priv(bus);
>> +       struct gdsys_soc_child_platdata *pplat = dev_get_parent_platdata(bus);
>> +       u16 wait_mask = complete_flag | STATUS_TIMEOUT_EVENT |
>> +                       STATUS_ERROR_EVENT;
>> +       u16 status;
>> +       uint k;
>> +
>> +       cmd &= CONTROL_CMD_MASK;
>> +
>> +       fpga_out_le16(pplat->fpga, priv->addr + REG_ADDRESS_LSB,
>> +                     address & 0xffff);
>> +       fpga_out_le16(pplat->fpga, priv->addr + REG_ADDRESS_MSB,
>> +                     (address >> 16) & 0xffff);
>> +
>> +       fpga_out_le16(pplat->fpga, priv->addr + REG_INTERRUPT_STATUS,
>> +                     wait_mask);
>> +       fpga_out_le16(pplat->fpga, priv->addr + REG_INTERRUPT_ENABLE_CONTROL,
>> +                     cmd);
>> +
>> +       for (k = 10; k > 0; --k) {
>> +               status = fpga_in_le16(pplat->fpga,
>> +                                     priv->addr + REG_INTERRUPT_STATUS);
>> +               if (status & wait_mask)
>> +                       break;
>> +               udelay(1);
>> +       }
>> +
>> +       if (!k)
>> +               status = fpga_in_le16(pplat->fpga,
>> +                                     priv->addr + REG_INTERRUPT_STATUS);
>> +
>> +       if (status & complete_flag)
>> +               return 0;
>> +
>> +       if (status & STATUS_ERROR_EVENT)
>> +               return -EIO;
>> +
>> +       return -ETIMEDOUT;
>> +}
>> +
>> +int axi_read(struct udevice *dev, u32 address, u32 *data)
>> +{
>> +       struct ihs_axi_ops *ops = ihs_axi_get_ops(dev);
>> +
>> +       return ops->read(dev, address, data);
>> +}
>> +
>> +int axi_write(struct udevice *dev, u32 address, u32 data)
>> +{
>> +       struct ihs_axi_ops *ops = ihs_axi_get_ops(dev);
>> +
>> +       return ops->write(dev, address, data);
>> +}
>> +
>> +/*
>> + * API
>> + */
>> +
>> +int ihs_axi_read(struct udevice *dev, u32 address, u32 *data)
>> +{
>> +       struct ihs_axi_priv *priv = dev_get_priv(dev);
>> +       struct gdsys_soc_child_platdata *pplat = dev_get_parent_platdata(dev);
>> +       int res = 0;
>> +       u16 data_lsb, data_msb;
>> +
>> +       res = axi_transfer(dev, address, CONTROL_CMD_READ,
>> +                          STATUS_READ_COMPLETE_EVENT);
>> +       if (res < 0)
>> +               return res;
>> +
>> +       data_lsb = fpga_in_le16(pplat->fpga,
>> +                               priv->addr + REG_READ_DATA_LSB);
>> +       data_msb = fpga_in_le16(pplat->fpga,
>> +                               priv->addr + REG_READ_DATA_MSB);
>> +
>> +       *data = (data_msb << 16) | data_lsb;
>> +
>> +       return res;
>> +}
>> +
>> +int ihs_axi_write(struct udevice *dev, u32 address, u32 data)
>> +{
>> +       struct ihs_axi_priv *priv = dev_get_priv(dev);
>> +       struct gdsys_soc_child_platdata *pplat = dev_get_parent_platdata(dev);
>> +       int res = 0;
>> +
>> +       fpga_out_le16(pplat->fpga, priv->addr + REG_READ_DATA_LSB,
>> +                     data & 0xffff);
>> +       fpga_out_le16(pplat->fpga, priv->addr + REG_READ_DATA_MSB,
>> +                     (data >> 16) & 0xffff);
>> +
>> +       res = axi_transfer(dev, address, CONTROL_CMD_WRITE,
>> +                          STATUS_WRITE_COMPLETE_EVENT);
>> +
>> +       return res;
>> +}
>> +
>> +UCLASS_DRIVER(ihs_axi) = {
>> +       .id             = UCLASS_IHS_AXI,
>> +       .name           = "ihs_axi",
>> +       .post_bind      = dm_scan_fdt_dev,
>> +       .flags          = DM_UC_FLAG_SEQ_ALIAS,
>> +};
>> +
>> +static const struct udevice_id ihs_axi_ids[] = {
>> +       { .compatible = "gdsys,ihs_axi" },
>> +       { /* sentinel */ }
>> +};
>> +
>> +static const struct ihs_axi_ops ihs_axi_ops = {
>> +       .read = ihs_axi_read,
>> +       .write = ihs_axi_write,
>> +};
>> +
>> +int ihs_axi_probe(struct udevice *dev)
>> +{
>> +       struct ihs_axi_priv *priv = dev_get_priv(dev);
>> +       struct udevice *child = NULL;
>> +       int addr;
>> +
>> +       addr = fdtdec_get_int(gd->fdt_blob, dev_of_offset(dev), "reg", -1);
>
> dev_read_...
>

Older code again :-) Will fix in v2.

>> +
>> +       priv->addr = addr;
>> +
>> +       for (device_find_first_child(dev, &child);
>> +            child;
>> +            device_find_next_child(&child))
>> +               device_probe(child);
>
> Should not probe children. Instead when you probe a child this bus
> should be auto-probed by DM.
>

OK, that's fine for the device, since only the CON really uses the AXI
interface. Will fix in v2.

>> +
>> +       return 0;
>> +}
>> +
>> +U_BOOT_DRIVER(ihs_axi_bus) = {
>> +       .name           = "ihs_axi_bus",
>> +       .id             = UCLASS_IHS_AXI,
>> +       .of_match       = ihs_axi_ids,
>> +       .ops            = &ihs_axi_ops,
>> +       .priv_auto_alloc_size = sizeof(struct ihs_axi_priv),
>> +       .probe          = ihs_axi_probe,
>> +};
>> diff --git a/include/dm/uclass-id.h b/include/dm/uclass-id.h
>> index 8eee8534ab..1a24de10b4 100644
>> --- a/include/dm/uclass-id.h
>> +++ b/include/dm/uclass-id.h
>> @@ -42,6 +42,7 @@ enum uclass_id {
>>         UCLASS_I2C_EEPROM,      /* I2C EEPROM device */
>>         UCLASS_I2C_GENERIC,     /* Generic I2C device */
>>         UCLASS_I2C_MUX,         /* I2C multiplexer */
>> +       UCLASS_IHS_AXI,         /* gdsys IHS AXI bus */
>>         UCLASS_IHS_FPGA,        /* gdsys IHS FPGAs */
>>         UCLASS_IRQ,             /* Interrupt controller */
>>         UCLASS_KEYBOARD,        /* Keyboard input device */
>> diff --git a/include/ihs_axi.h b/include/ihs_axi.h
>> new file mode 100644
>> index 0000000000..8640d45a0a
>> --- /dev/null
>> +++ b/include/ihs_axi.h
>> @@ -0,0 +1,69 @@
>> +/*
>> + * (C) Copyright 2017
>> + * Mario Six,  Guntermann & Drunck GmbH, mario.six at gdsys.cc
>> + *
>> + * SPDX-License-Identifier:    GPL-2.0+
>> + */
>> +
>> +#ifndef _AXI_H_
>> +#define _AXI_H_
>> +
>> +/**
>> + * struct ihs_axi_ops - driver operations for IHS AXI 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 ihs_axi_ops {
>> +       /**
>> +        * read() - Read a single 32 bit value from a specified address on a
>> +        *          IHS AXI bus
>> +        *
>> +        * @dev:        IHS AXI bus to read from.
>> +        * @address:    The address to read from.
>> +        * @data:       Pointer to a variable that takes the data value read
>> +        *              from the address on the IHS AXI bus.
>> +        * @return 0 if OK, -ve on error.
>> +        */
>> +       int (*read)(struct udevice *dev, u32 address, u32* data);
>
> How about using ulong for address so can support 64-bit machines.
>
> Also should we have a data length parameter? Or rename this to read32()?
>
> When adding a new uclass we should have a simple sandbox driver and test.
>

AXI supports data bus widths of 8, 16, 32, 64, 128, 256, 512, and 1024 bits, so
on one hand we have discrete possible values for the data length, but too many
to support separate functions for each width.

Do you have any suggestions? A length parameter and a test in the uclass works,
of course, but then you have to do the check for each transmit.

>> +
>> +       /**
>> +        * write() - Write a single 32 bit value to a specified address on a
>> +        *           IHS AXI bus
>> +        *
>> +        * @dev:        IHS AXI bus to write to.
>> +        * @address:    The address to write to.
>> +        * @data:       Data value to be written to the address on the IHS AXI
>> +        *              bus.
>> +        * @return 0 if OK, -ve on error.
>> +        */
>> +       int (*write)(struct udevice *dev, u32 address, u32 data);
>> +};
>> +
>> +#define ihs_axi_get_ops(dev)   ((struct ihs_axi_ops *)(dev)->driver->ops)
>> +
>> +/**
>> + * axi_read() - Read a single 32 bit value from a specified address on a
>> + *              IHS AXI bus
>> + *
>> + * @dev:       IHS AXI bus to read from.
>> + * @address:   The address to read from.
>> + * @data:      Pointer to a variable that takes the data value read from the
>> + *              address on the IHS AXI bus.
>> + * @return 0 if OK, -ve on error.
>> + */
>> +int axi_read(struct udevice *dev, u32 address, u32* data);
>> +
>> +/**
>> + * axi_write() - Write a single 32 bit value to a specified address on a
>> + *              IHS AXI bus
>> + *
>> + * @dev:       IHS AXI bus to write to.
>> + * @address:   The address to write to.
>> + * @data:      Data value to be written to the address on the IHS AXI bus.
>> + * @return 0 if OK, -ve on error.
>> + */
>> +int axi_write(struct udevice *dev, u32 address, u32 data);
>> +
>> +#endif
>> --
>> 2.11.0
>>
>
> Regards,
> Simon

Best regards,

Mario

^ permalink raw reply	[flat|nested] 138+ messages in thread

* [U-Boot] [PATCH 42/51] cmd: Add ihs fpga command
  2017-07-19  9:06   ` Simon Glass
@ 2017-07-25 12:33     ` Mario Six
  0 siblings, 0 replies; 138+ messages in thread
From: Mario Six @ 2017-07-25 12:33 UTC (permalink / raw)
  To: u-boot

Hi Simon,

On Wed, Jul 19, 2017 at 11:06 AM, Simon Glass <sjg@chromium.org> wrote:
> Hi Mario,
>
> On 14 July 2017 at 05:55, Mario Six <mario.six@gdsys.cc> wrote:
>> Add a comman to debug the IHS FPGA's bus.
>>
>> Signed-off-by: Mario Six <mario.six@gdsys.cc>
>> ---
>>
>>  cmd/Kconfig    |   5 ++
>>  cmd/Makefile   |   1 +
>>  cmd/ihs_fpga.c | 269 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
>>  3 files changed, 275 insertions(+)
>>  create mode 100644 cmd/ihs_fpga.c
>
> This should be more generic as per the driver - e.g. a read/write()
> method that supports an access size parameter.
>

For a generic FPGA uclass, yes, definitely. Will fix in v2.

> Is there any way we can make some of the code common with things like 'md'?
>

You mean share code between all the commands that read/write to memory-like
devices? Probably. I'll take a look. Any preference where the common code
should be kept? In cmd/ ?

>>
>> diff --git a/cmd/Kconfig b/cmd/Kconfig
>> index 4bbe9d435c..6d13c681cb 100644
>> --- a/cmd/Kconfig
>> +++ b/cmd/Kconfig
>> @@ -753,6 +753,11 @@ config CMD_SATA
>>           Attachment, where AT refers to an IBM AT (Advanced Technology)
>>           computer released in 1984.
>>
>> +config CMD_IHS_FPGA
>> +       bool "fpga"
>> +       help
>> +         Enable the GDSYS IHS FPGA command for accessing the FPGA's regisers.
>> +
>
> Regards,
> Simon

Best regards,

Mario

^ permalink raw reply	[flat|nested] 138+ messages in thread

* [U-Boot] [PATCH 10/51] net:phy:marvell Add hook for m88e1510 board config
  2017-07-18 14:01   ` Simon Glass
@ 2017-07-25 13:43     ` Mario Six
  0 siblings, 0 replies; 138+ messages in thread
From: Mario Six @ 2017-07-25 13:43 UTC (permalink / raw)
  To: u-boot

Hi Simon,

On Tue, Jul 18, 2017 at 4:01 PM, Simon Glass <sjg@chromium.org> wrote:
> Hi Mario,
>
> On 14 July 2017 at 05:54, Mario Six <mario.six@gdsys.cc> wrote:
>> From: Dirk Eibach <dirk.eibach@gdsys.cc>
>>
>> m88e1510_config() is highly board-specific. So add an optional
>> callback board_m88e1510_config() configurable by
>> CONFIG_BOARD_M88E1510_CONFIG to support different hardware.
>>
>> Signed-off-by: Dirk Eibach <dirk.eibach@gdsys.cc>
>> Signed-off-by: Mario Six <mario.six@gdsys.cc>
>> ---
>>
>>  drivers/net/phy/marvell.c |  5 +++++
>>  include/marvell-phy.h     | 10 ++++++++++
>>  2 files changed, 15 insertions(+)
>>  create mode 100644 include/marvell-phy.h
>>
>> diff --git a/drivers/net/phy/marvell.c b/drivers/net/phy/marvell.c
>> index 66107a8af3..b3d05d5af4 100644
>> --- a/drivers/net/phy/marvell.c
>> +++ b/drivers/net/phy/marvell.c
>> @@ -9,6 +9,7 @@
>>  #include <config.h>
>>  #include <common.h>
>>  #include <errno.h>
>> +#include <marvell-phy.h>
>>  #include <phy.h>
>>
>>  #define PHY_AUTONEGOTIATE_TIMEOUT 5000
>> @@ -381,6 +382,9 @@ static int m88e1518_config(struct phy_device *phydev)
>>  /* Marvell 88E1510 */
>>  static int m88e1510_config(struct phy_device *phydev)
>>  {
>> +#ifdef CONFIG_BOARD_M88E1510_CONFIG
>> +       board_m88e1510_config(phydev);
>> +#else
>
> We should not be calling into board code from drivers. How could we do
> this with driver model / DT?
>

The simplest way I see would be to convert the phy to DM (i.e. make a ethernet
phy uclass if necessary), get the udevice for the phy in the board code (e.g.
in last_stage_init) to force a probe, and finally run the initialization code.
The problem is, of course, that this final part of the initialization then
happens outside the driver code; that violates the philosophy that probing the
device should initialize it completely.

Well, to collect some facts:

The board-specific initialization code cannot live in the phy driver, since
it's board-specific. Hence, it must either live in the board code or in a
different driver. Since calling into board code is not a good idea, it can only
live in a different driver. The questions is, which driver should this be, and
what other code should it contain?

The other question is that of the caller (i.e. who should call the
initialization code). Since we already saw that calling the code from the board
code is not so good, we must conclude that we have to call it from a driver.
Since we want to keep the initialization intact (i.e. not split it up), we have
to call it from the phy driver.

Hence, the other possible way would be to have a "fixup driver" with a matching
function somewhere in the DT (the code for which will probably reside in the
board directory), the phy driver gets the corresponding udevice, and runs the
initialization code by calling a suitable uclass function on that udevice. That
would make sure that the initialization is always coherent. Maybe calling the
fixup driver could also be part of the phy uclass, but that would have to be
evaluated further.

>>         /* Select page 3 */
>>         phy_write(phydev, MDIO_DEVAD_NONE, MIIM_88E1118_PHY_PAGE,
>>                   MIIM_88E1118_PHY_LED_PAGE);
>> @@ -401,6 +405,7 @@ static int m88e1510_config(struct phy_device *phydev)
>>
>>         /* Reset page selection */
>>         phy_write(phydev, MDIO_DEVAD_NONE, MIIM_88E1118_PHY_PAGE, 0);
>> +#endif
>>
>>         return m88e1518_config(phydev);
>>  }
>> diff --git a/include/marvell-phy.h b/include/marvell-phy.h
>> new file mode 100644
>> index 0000000000..1cfa5ed557
>> --- /dev/null
>> +++ b/include/marvell-phy.h
>> @@ -0,0 +1,10 @@
>> +#ifndef _MARVELL_PHY_H
>> +#define _MARVELL_PHY_H
>> +
>> +#include <phy.h>
>> +
>> +void m88e1518_phy_writebits(struct phy_device *phydev,
>> +                  u8 reg_num, u16 offset, u16 len, u16 data);
>> +int board_m88e1510_config(struct phy_device *phydev);
>> +
>> +#endif
>> --
>> 2.11.0
>>
>
> Regards,
> Simon

Best regards,

Mario

^ permalink raw reply	[flat|nested] 138+ messages in thread

* [U-Boot] [PATCH 51/51] mpc83xx: Add gazerbeam board
  2017-07-19  9:07   ` Simon Glass
@ 2017-07-26  8:24     ` Mario Six
  2017-08-04  9:34       ` Simon Glass
  0 siblings, 1 reply; 138+ messages in thread
From: Mario Six @ 2017-07-26  8:24 UTC (permalink / raw)
  To: u-boot

Hi Simon,

On Wed, Jul 19, 2017 at 11:07 AM, Simon Glass <sjg@chromium.org> wrote:
> Hi Mario,
>
> On 14 July 2017 at 05:55, Mario Six <mario.six@gdsys.cc> wrote:
>> From: Dirk Eibach <dirk.eibach@gdsys.cc>
>>
>> The gdsys gazerbeam board is based on a Freescale MPC8308 SOC.
>> It boots from NOR-Flash, kernel and rootfs are stored on
>> SD-Card.
>>
>> On board peripherals include:
>> - 2x 10/100 Mbit/s Ethernet (optional)
>>
>> Signed-off-by: Dirk Eibach <dirk.eibach@gdsys.cc>
>> Signed-off-by: Mario Six <mario.six@gdsys.cc>
>> ---
>>
>>  arch/powerpc/cpu/mpc83xx/Kconfig |   3 +
>>  arch/powerpc/dts/.gitignore      |   1 +
>>  arch/powerpc/dts/Makefile        |  15 +
>>  board/gdsys/common/Makefile      |   1 +
>>  board/gdsys/common/ioep-fpga.c   | 617 ++++++++++++++++++++++++++++++---------
>>  board/gdsys/mpc8308/Kconfig      |  19 ++
>>  board/gdsys/mpc8308/MAINTAINERS  |   2 +
>>  board/gdsys/mpc8308/Makefile     |   1 +
>>  board/gdsys/mpc8308/gazerbeam.c  | 332 +++++++++++++++++++++
>>  configs/gazerbeam_defconfig      |  76 +++++
>>  include/configs/gazerbeam.h      | 484 ++++++++++++++++++++++++++++++
>>  include/fdt_fixup.h              |   5 +
>>  12 files changed, 1416 insertions(+), 140 deletions(-)
>>  create mode 100644 arch/powerpc/dts/.gitignore
>>  create mode 100644 arch/powerpc/dts/Makefile
>>  create mode 100644 board/gdsys/mpc8308/gazerbeam.c
>>  create mode 100644 configs/gazerbeam_defconfig
>>  create mode 100644 include/configs/gazerbeam.h
>>
>> diff --git a/arch/powerpc/cpu/mpc83xx/Kconfig b/arch/powerpc/cpu/mpc83xx/Kconfig
>> index cdd21a253a..0790b47aa4 100644
>> --- a/arch/powerpc/cpu/mpc83xx/Kconfig
>> +++ b/arch/powerpc/cpu/mpc83xx/Kconfig
>> @@ -91,6 +91,9 @@ config TARGET_STRIDER
>>         bool "Support strider"
>>         select SYS_FSL_ERRATUM_ESDHC111
>>
>> +config TARGET_GAZERBEAM
>> +       bool "Support gazerbeam"
>
> Need description of the board, URL, etc.
>

Ah, OK. None of the other powerpc boards have a description, so I was unaware
that this is even recommended (but I see other architectures have them). I'll
add a description, and I'll probably add one for the gdsys boards that are
already in the tree in a separate series.

>> +
>>  endchoice
>>
>>  source "board/esd/vme8349/Kconfig"
>> diff --git a/arch/powerpc/dts/.gitignore b/arch/powerpc/dts/.gitignore
>> new file mode 100644
>> index 0000000000..b60ed208c7
>> --- /dev/null
>> +++ b/arch/powerpc/dts/.gitignore
>> @@ -0,0 +1 @@
>> +*.dtb
>> diff --git a/arch/powerpc/dts/Makefile b/arch/powerpc/dts/Makefile
>> new file mode 100644
>> index 0000000000..7a0c61ffaa
>> --- /dev/null
>> +++ b/arch/powerpc/dts/Makefile
>> @@ -0,0 +1,15 @@
>> +#
>> +# SPDX-License-Identifier:      GPL-2.0+
>> +#
>> +
>> +dtb-$(CONFIG_TARGET_GAZERBEAM) += gazerbeam.dtb
>> +
>> +targets += $(dtb-y)
>> +
>> +DTC_FLAGS += -R 4 -p 0x1000
>> +
>> +PHONY += dtbs
>> +dtbs: $(addprefix $(obj)/, $(dtb-y))
>> +        @:
>> +
>> +clean-files := *.dtb
>
> These two files should be added along with your DT I think, not in
> this patch. Your board patch should just add the dtb-$(CONFIG... line
> above.
>

Yes, that's probably cleaner. I also pulled in the old Makefile that was
removed in 98f705c ("powerpc: remove 4xx support"), so these lines came from
there. But I guess they are not really needed.

>> diff --git a/board/gdsys/common/Makefile b/board/gdsys/common/Makefile
>> index 6f2fea207f..52561db2e1 100644
>> --- a/board/gdsys/common/Makefile
>> +++ b/board/gdsys/common/Makefile
>> @@ -13,3 +13,4 @@ obj-$(CONFIG_STRIDER) += mclink.o dp501.o phy.o ioep-fpga.o adv7611.o ch7301.o
>>  obj-$(CONFIG_STRIDER) += fanctrl.o
>>  obj-$(CONFIG_STRIDER_CON) += osd.o
>>  obj-$(CONFIG_STRIDER_CON_DP) += osd.o
>> +obj-$(CONFIG_TARGET_GAZERBEAM) += osd.o ihs_mdio.o ioep-fpga.o
>> diff --git a/board/gdsys/common/ioep-fpga.c b/board/gdsys/common/ioep-fpga.c
>> index a666b93445..24585672f6 100644
>> --- a/board/gdsys/common/ioep-fpga.c
>> +++ b/board/gdsys/common/ioep-fpga.c
>> @@ -11,231 +11,568 @@
>>
>>  #include <gdsys_fpga.h>
>>
>> -enum {
>> -       UNITTYPE_MAIN_SERVER = 0,
>> -       UNITTYPE_MAIN_USER = 1,
>> -       UNITTYPE_VIDEO_SERVER = 2,
>> -       UNITTYPE_VIDEO_USER = 3,
>> +enum pcb_video_type {
>> +       PCB_DVI_SL,
>> +       PCB_DP_165MPIX,
>> +       PCB_DP_300MPIX,
>> +       PCB_HDMI,
>> +       PCB_DP_1_2,
>> +       PCB_HDMI_2_0,
>>  };
>>
>> -enum {
>> -       UNITTYPEPCB_DVI = 0,
>> -       UNITTYPEPCB_DP_165 = 1,
>> -       UNITTYPEPCB_DP_300 = 2,
>> -       UNITTYPEPCB_HDMI = 3,
>> +enum pcb_transmission_type {
>> +       PCB_CAT_1G,
>> +       PCB_FIBER_3G,
>> +       PCB_CAT_10G,
>> +       PCB_FIBER_10G,
>>  };
>>
>> -enum {
>> -       COMPRESSION_NONE = 0,
>> -       COMPRESSION_TYPE_1 = 1,
>> -       COMPRESSION_TYPE_1_2 = 3,
>> -       COMPRESSION_TYPE_1_2_3 = 7,
>> +enum carrier_speed {
>> +       CARRIER_SPEED_1G,
>> +       CARRIER_SPEED_3G,
>> +       CARRIER_SPEED_2_5G = CARRIER_SPEED_3G,
>> +       CARRIER_SPEED_10G,
>>  };
>>
>> -enum {
>> -       AUDIO_NONE = 0,
>> -       AUDIO_TX = 1,
>> -       AUDIO_RX = 2,
>> -       AUDIO_RXTX = 3,
>> +enum ram_config {
>> +       RAM_DDR2_32BIT_295MBPS,
>> +       RAM_DDR3_32BIT_590MBPS,
>> +       RAM_DDR3_48BIT_590MBPS,
>> +       RAM_DDR3_64BIT_1800MBPS,
>> +       RAM_DDR3_48BIT_1800MBPS,
>>  };
>>
>> -enum {
>> -       SYSCLK_147456 = 0,
>> +enum sysclock {
>> +       SYSCLK_147456,
>>  };
>>
>> -enum {
>> -       RAM_DDR2_32 = 0,
>> -       RAM_DDR3_32 = 1,
>> -       RAM_DDR3_48 = 2,
>> +struct fpga_versions {
>> +       bool video_channel;
>> +       bool con_side;
>> +       enum pcb_video_type pcb_video_type;
>> +       enum pcb_transmission_type pcb_transmission_type;
>> +       unsigned int hw_version;
>>  };
>>
>> -enum {
>> -       CARRIER_SPEED_1G = 0,
>> -       CARRIER_SPEED_2_5G = 1,
>> +struct fpga_features {
>> +       u8 video_channels;
>> +       u8 carriers;
>> +       enum carrier_speed carrier_speed;
>> +       enum ram_config ram_config;
>> +       enum sysclock sysclock;
>> +
>> +       bool pcm_tx;
>> +       bool pcm_rx;
>> +       bool spdif_tx;
>> +       bool spdif_rx;
>> +       bool usb2;
>> +       bool rs232;
>> +       bool compression_type1;
>> +       bool compression_type2;
>> +       bool compression_type3;
>> +       bool interlace;
>> +       bool osd;
>> +       bool compression_pipes;
>>  };
>>
>> -bool ioep_fpga_has_osd(unsigned int fpga)
>> +#ifdef CONFIG_SYS_FPGA_FLAVOR_GAZERBEAM
>> +
>> +static int get_versions(unsigned int fpga, struct fpga_versions *versions)
>>  {
>> -       u16 fpga_features;
>> -       unsigned feature_osd;
>> +       enum {
>> +               VERSIONS_FPGA_VIDEO_CHANNEL = BIT(12),
>> +               VERSIONS_FPGA_CON_SIDE = BIT(13),
>> +               VERSIONS_FPGA_SC = BIT(14),
>> +               VERSIONS_PCB_CON = BIT(9),
>> +               VERSIONS_PCB_SC = BIT(8),
>> +               VERSIONS_PCB_VIDEO_MASK = 0x3 << 6,
>> +               VERSIONS_PCB_VIDEO_DP_1_2 = 0x0 << 6,
>> +               VERSIONS_PCB_VIDEO_HDMI_2_0 = 0x1 << 6,
>> +               VERSIONS_PCB_TRANSMISSION_MASK = 0x3 << 4,
>> +               VERSIONS_PCB_TRANSMISSION_FIBER_10G = 0x0 << 4,
>> +               VERSIONS_PCB_TRANSMISSION_CAT_10G = 0x1 << 4,
>> +               VERSIONS_PCB_TRANSMISSION_FIBER_3G = 0x2 << 4,
>> +               VERSIONS_PCB_TRANSMISSION_CAT_1G = 0x3 << 4,
>> +               VERSIONS_HW_VER_MASK = 0xf << 0,
>> +       };
>> +       u16 raw_versions;
>> +
>> +       memset(versions, 0, sizeof(struct fpga_versions));
>> +
>> +       FPGA_GET_REG(fpga, versions, &raw_versions);
>> +
>> +       versions->video_channel = raw_versions & VERSIONS_FPGA_VIDEO_CHANNEL;
>> +       versions->con_side = raw_versions & VERSIONS_FPGA_CON_SIDE;
>> +
>> +       switch (raw_versions & VERSIONS_PCB_VIDEO_MASK) {
>> +       case VERSIONS_PCB_VIDEO_DP_1_2:
>> +               versions->pcb_video_type = PCB_DP_1_2;
>> +               break;
>> +
>> +       case VERSIONS_PCB_VIDEO_HDMI_2_0:
>> +               versions->pcb_video_type = PCB_HDMI_2_0;
>> +               break;
>> +       }
>> +
>> +       switch (raw_versions & VERSIONS_PCB_TRANSMISSION_MASK) {
>> +       case VERSIONS_PCB_TRANSMISSION_FIBER_10G:
>> +               versions->pcb_transmission_type = PCB_FIBER_10G;
>> +               break;
>> +
>> +       case VERSIONS_PCB_TRANSMISSION_CAT_10G:
>> +               versions->pcb_transmission_type = PCB_CAT_10G;
>> +               break;
>> +
>> +       case VERSIONS_PCB_TRANSMISSION_FIBER_3G:
>> +               versions->pcb_transmission_type = PCB_FIBER_3G;
>> +               break;
>> +
>> +       case VERSIONS_PCB_TRANSMISSION_CAT_1G:
>> +               versions->pcb_transmission_type = PCB_CAT_1G;
>> +               break;
>> +
>> +       }
>>
>> -       FPGA_GET_REG(0, fpga_features, &fpga_features);
>> -       feature_osd = fpga_features & (1<<11);
>> +       versions->hw_version = raw_versions & VERSIONS_HW_VER_MASK;
>>
>> -       return feature_osd;
>> +       return 0;
>>  }
>>
>> -void ioep_fpga_print_info(unsigned int fpga)
>> +static int get_features(unsigned int fpga, struct fpga_features *features)
>>  {
>> -       u16 versions;
>> -       u16 fpga_version;
>> -       u16 fpga_features;
>> -       unsigned unit_type;
>> -       unsigned unit_type_pcb_video;
>> -       unsigned feature_compression;
>> -       unsigned feature_osd;
>> -       unsigned feature_audio;
>> -       unsigned feature_sysclock;
>> -       unsigned feature_ramconfig;
>> -       unsigned feature_carrier_speed;
>> -       unsigned feature_carriers;
>> -       unsigned feature_video_channels;
>> -
>> -       FPGA_GET_REG(fpga, versions, &versions);
>> -       FPGA_GET_REG(fpga, fpga_version, &fpga_version);
>> -       FPGA_GET_REG(fpga, fpga_features, &fpga_features);
>> -
>> -       unit_type = (versions & 0xf000) >> 12;
>> -       unit_type_pcb_video = (versions & 0x01c0) >> 6;
>> -       feature_compression = (fpga_features & 0xe000) >> 13;
>> -       feature_osd = fpga_features & (1<<11);
>> -       feature_audio = (fpga_features & 0x0600) >> 9;
>> -       feature_sysclock = (fpga_features & 0x0180) >> 7;
>> -       feature_ramconfig = (fpga_features & 0x0060) >> 5;
>> -       feature_carrier_speed = fpga_features & (1<<4);
>> -       feature_carriers = (fpga_features & 0x000c) >> 2;
>> -       feature_video_channels = fpga_features & 0x0003;
>> -
>> -       switch (unit_type) {
>> -       case UNITTYPE_MAIN_SERVER:
>> -       case UNITTYPE_MAIN_USER:
>> -               printf("Mainchannel");
>> +       enum {
>> +               FEATURE_SPDIF_RX = BIT(15),
>> +               FEATURE_SPDIF_TX = BIT(14),
>> +               FEATURE_PCM_RX = BIT(13),
>> +               FEATURE_PCM_TX = BIT(12),
>> +               FEATURE_RAM_MASK = GENMASK(11, 8),
>> +               FEATURE_RAM_DDR2_32BIT_295MBPS = 0x0 << 8,
>> +               FEATURE_RAM_DDR3_32BIT_590MBPS = 0x1 << 8,
>> +               FEATURE_RAM_DDR3_48BIT_590MBPS = 0x2 << 8,
>> +               FEATURE_RAM_DDR3_64BIT_1800MBPS = 0x3 << 8,
>> +               FEATURE_RAM_DDR3_48BIT_1800MBPS = 0x4 << 8,
>> +               FEATURE_CARRIER_SPEED_MASK = GENMASK(7, 6),
>> +               FEATURE_CARRIER_SPEED_1G = 0x0 << 6,
>> +               FEATURE_CARRIER_SPEED_2_5G = 0x1 << 6,
>> +               FEATURE_CARRIER_SPEED_10G = 0x2 << 6,
>> +               FEATURE_CARRIERS_MASK = GENMASK(5, 4),
>> +               FEATURE_CARRIERS_0 = 0x0 << 4,
>> +               FEATURE_CARRIERS_1 = 0x1 << 4,
>> +               FEATURE_CARRIERS_2 = 0x2 << 4,
>> +               FEATURE_CARRIERS_4 = 0x3 << 4,
>> +               FEATURE_USB2 = BIT(3),
>> +               FEATURE_VIDEOCHANNELS_MASK = GENMASK(2, 0),
>> +               FEATURE_VIDEOCHANNELS_0 = 0x0 << 0,
>> +               FEATURE_VIDEOCHANNELS_1 = 0x1 << 0,
>> +               FEATURE_VIDEOCHANNELS_1_1 = 0x2 << 0,
>> +               FEATURE_VIDEOCHANNELS_2 = 0x3 << 0,
>> +       };
>> +
>> +       enum {
>> +               EXT_FEATURE_OSD = BIT(15),
>> +               EXT_FEATURE_ETHERNET = BIT(9),
>> +               EXT_FEATURE_INTERLACE = BIT(8),
>> +               EXT_FEATURE_RS232 = BIT(7),
>> +               EXT_FEATURE_COMPRESSION_PERF_MASK = GENMASK(6, 4),
>> +               EXT_FEATURE_COMPRESSION_PERF_1X = 0x0 << 4,
>> +               EXT_FEATURE_COMPRESSION_PERF_2X = 0x1 << 4,
>> +               EXT_FEATURE_COMPRESSION_PERF_4X = 0x2 << 4,
>> +               EXT_FEATURE_COMPRESSION_TYPE1 = BIT(0),
>> +               EXT_FEATURE_COMPRESSION_TYPE2 = BIT(1),
>> +               EXT_FEATURE_COMPRESSION_TYPE3 = BIT(2),
>> +       };
>> +
>> +       u16 raw_features;
>> +       u16 raw_extended_features;
>> +
>> +       memset(features, 0, sizeof(struct fpga_features));
>> +
>> +       FPGA_GET_REG(fpga, fpga_features, &raw_features);
>> +       FPGA_GET_REG(fpga, fpga_ext_features, &raw_extended_features);
>> +
>> +       switch (raw_features & FEATURE_VIDEOCHANNELS_MASK) {
>> +       case FEATURE_VIDEOCHANNELS_0:
>> +               features->video_channels = 0;
>>                 break;
>>
>> -       case UNITTYPE_VIDEO_SERVER:
>> -       case UNITTYPE_VIDEO_USER:
>> -               printf("Videochannel");
>> +       case FEATURE_VIDEOCHANNELS_1:
>> +               features->video_channels = 1;
>>                 break;
>>
>> -       default:
>> -               printf("UnitType %d(not supported)", unit_type);
>> +       case FEATURE_VIDEOCHANNELS_1_1:
>> +       case FEATURE_VIDEOCHANNELS_2:
>> +               features->video_channels = 2;
>>                 break;
>> -       }
>> +       };
>>
>> -       switch (unit_type) {
>> -       case UNITTYPE_MAIN_SERVER:
>> -       case UNITTYPE_VIDEO_SERVER:
>> -               printf(" Server");
>> -               if (versions & (1<<4))
>> -                       printf(" UC");
>> +       switch (raw_features & FEATURE_CARRIERS_MASK) {
>> +       case FEATURE_CARRIERS_0:
>> +               features->carriers = 0;
>>                 break;
>>
>> -       case UNITTYPE_MAIN_USER:
>> -       case UNITTYPE_VIDEO_USER:
>> -               printf(" User");
>> +       case FEATURE_CARRIERS_1:
>> +               features->carriers = 1;
>>                 break;
>>
>> -       default:
>> +       case FEATURE_CARRIERS_2:
>> +               features->carriers = 2;
>> +               break;
>> +
>> +       case FEATURE_CARRIERS_4:
>> +               features->carriers = 4;
>>                 break;
>>         }
>>
>> -       if (versions & (1<<5))
>> -               printf(" Fiber");
>> -       else
>> -               printf(" CAT");
>> +       switch (raw_features & FEATURE_CARRIER_SPEED_MASK) {
>> +       case FEATURE_CARRIER_SPEED_1G:
>> +               features->carrier_speed = CARRIER_SPEED_1G;
>> +               break;
>> +       case FEATURE_CARRIER_SPEED_2_5G:
>> +               features->carrier_speed = CARRIER_SPEED_2_5G;
>> +               break;
>> +       case FEATURE_CARRIER_SPEED_10G:
>> +               features->carrier_speed = CARRIER_SPEED_10G;
>> +               break;
>> +       }
>>
>> -       switch (unit_type_pcb_video) {
>> -       case UNITTYPEPCB_DVI:
>> -               printf(" DVI,");
>> +       switch (raw_features & FEATURE_RAM_MASK) {
>> +       case FEATURE_RAM_DDR2_32BIT_295MBPS:
>> +               features->ram_config = RAM_DDR2_32BIT_295MBPS;
>>                 break;
>>
>> -       case UNITTYPEPCB_DP_165:
>> -               printf(" DP 165MPix/s,");
>> +       case FEATURE_RAM_DDR3_32BIT_590MBPS:
>> +               features->ram_config = RAM_DDR3_32BIT_590MBPS;
>>                 break;
>>
>> -       case UNITTYPEPCB_DP_300:
>> -               printf(" DP 300MPix/s,");
>> +       case FEATURE_RAM_DDR3_48BIT_590MBPS:
>> +               features->ram_config = RAM_DDR3_48BIT_590MBPS;
>>                 break;
>>
>> -       case UNITTYPEPCB_HDMI:
>> -               printf(" HDMI,");
>> +       case FEATURE_RAM_DDR3_64BIT_1800MBPS:
>> +               features->ram_config = RAM_DDR3_64BIT_1800MBPS;
>> +               break;
>> +
>> +       case FEATURE_RAM_DDR3_48BIT_1800MBPS:
>> +               features->ram_config = RAM_DDR3_48BIT_1800MBPS;
>>                 break;
>>         }
>>
>> -       printf(" FPGA V %d.%02d\n       features:",
>> -              fpga_version / 100, fpga_version % 100);
>> +       features->pcm_tx = raw_features & FEATURE_PCM_TX;
>> +       features->pcm_rx = raw_features & FEATURE_PCM_RX;
>> +       features->spdif_tx = raw_features & FEATURE_SPDIF_TX;
>> +       features->spdif_rx = raw_features & FEATURE_SPDIF_RX;
>> +       features->usb2 = raw_features & FEATURE_USB2;
>> +       features->rs232 = raw_extended_features & EXT_FEATURE_RS232;
>> +       features->compression_type1 = raw_extended_features & EXT_FEATURE_COMPRESSION_TYPE1;
>> +       features->compression_type2 = raw_extended_features & EXT_FEATURE_COMPRESSION_TYPE2;
>> +       features->compression_type3 = raw_extended_features & EXT_FEATURE_COMPRESSION_TYPE3;
>> +       features->interlace = raw_extended_features & EXT_FEATURE_INTERLACE;
>> +       features->osd = raw_extended_features & EXT_FEATURE_OSD;
>> +       features->compression_pipes = raw_extended_features & EXT_FEATURE_COMPRESSION_PERF_MASK;
>> +
>> +       return 0;
>> +}
>> +
>> +#else
>> +
>> +static int get_versions(unsigned int fpga, struct fpga_versions *versions)
>> +{
>> +       enum {
>> +               /* HW version encoding is a mess, leave it for the moment */
>> +               VERSIONS_HW_VER_MASK = 0xf << 0,
>> +               VERSIONS_PIX_CLOCK_GEN_IDT8N3QV01 = BIT(4),
>> +               VERSIONS_SFP = BIT(5),
>> +               VERSIONS_VIDEO_MASK = 0x7 << 6,
>> +               VERSIONS_VIDEO_DVI = 0x0 << 6,
>> +               VERSIONS_VIDEO_DP_165 = 0x1 << 6,
>> +               VERSIONS_VIDEO_DP_300 = 0x2 << 6,
>> +               VERSIONS_VIDEO_HDMI = 0x3 << 6,
>> +               VERSIONS_UT_MASK = 0xf << 12,
>> +               VERSIONS_UT_MAIN_SERVER = 0x0 << 12,
>> +               VERSIONS_UT_MAIN_USER = 0x1 << 12,
>> +               VERSIONS_UT_VIDEO_SERVER = 0x2 << 12,
>> +               VERSIONS_UT_VIDEO_USER = 0x3 << 12,
>> +       };
>> +       u16 raw_versions;
>> +
>> +       memset(versions, 0, sizeof(struct fpga_versions));
>> +
>> +       FPGA_GET_REG(fpga, versions, &raw_versions);
>> +
>> +       switch (raw_versions & VERSIONS_UT_MASK) {
>> +       case VERSIONS_UT_MAIN_SERVER:
>> +               versions->video_channel = false;
>> +               versions->con_side = false;
>> +               break;
>> +
>> +       case VERSIONS_UT_MAIN_USER:
>> +               versions->video_channel = false;
>> +               versions->con_side = true;
>> +               break;
>>
>> +       case VERSIONS_UT_VIDEO_SERVER:
>> +               versions->video_channel = true;
>> +               versions->con_side = false;
>> +               break;
>>
>> -       switch (feature_compression) {
>> -       case COMPRESSION_NONE:
>> -               printf(" no compression");
>> +       case VERSIONS_UT_VIDEO_USER:
>> +               versions->video_channel = true;
>> +               versions->con_side = true;
>>                 break;
>>
>> -       case COMPRESSION_TYPE_1:
>> -               printf(" compression type1(delta)");
>> +       }
>> +
>> +       switch (raw_versions & VERSIONS_VIDEO_MASK) {
>> +       case VERSIONS_VIDEO_DVI:
>> +               versions->pcb_video_type = PCB_DVI_SL;
>>                 break;
>>
>> -       case COMPRESSION_TYPE_1_2:
>> -               printf(" compression type1(delta), type2(inline)");
>> +       case VERSIONS_VIDEO_DP_165:
>> +               versions->pcb_video_type = PCB_DP_165MPIX;
>>                 break;
>>
>> -       case COMPRESSION_TYPE_1_2_3:
>> -               printf(" compression type1(delta), type2(inline), type3(intempo)");
>> +       case VERSIONS_VIDEO_DP_300:
>> +               versions->pcb_video_type = PCB_DP_300MPIX;
>>                 break;
>>
>> -       default:
>> -               printf(" compression %d(not supported)", feature_compression);
>> +       case VERSIONS_VIDEO_HDMI:
>> +               versions->pcb_video_type = PCB_HDMI;
>>                 break;
>>         }
>>
>> -       printf(", %sosd", feature_osd ? "" : "no ");
>> +       versions->hw_version = raw_versions & VERSIONS_HW_VER_MASK;
>>
>> -       switch (feature_audio) {
>> -       case AUDIO_NONE:
>> -               printf(", no audio");
>> +       if (raw_versions & VERSIONS_SFP)
>> +               versions->pcb_transmission_type = PCB_FIBER_3G;
>> +       else
>> +               versions->pcb_transmission_type = PCB_CAT_1G;
>> +
>> +       return 0;
>> +}
>> +
>> +static int get_features(unsigned int fpga, struct fpga_features *features)
>> +{
>> +       enum {
>> +               FEATURE_CARRIER_SPEED_2_5 = BIT(4),
>> +               FEATURE_RAM_MASK = 0x7 << 5,
>> +               FEATURE_RAM_DDR2_32BIT = 0x0 << 5,
>> +               FEATURE_RAM_DDR3_32BIT = 0x1 << 5,
>> +               FEATURE_RAM_DDR3_48BIT = 0x2 << 5,
>> +               FEATURE_PCM_AUDIO_TX = BIT(9),
>> +               FEATURE_PCM_AUDIO_RX = BIT(10),
>> +               FEATURE_OSD = BIT(11),
>> +               FEATURE_USB20 = BIT(12),
>> +               FEATURE_COMPRESSION_MASK = 7 << 13,
>> +               FEATURE_COMPRESSION_TYPE1 = 0x1 << 13,
>> +               FEATURE_COMPRESSION_TYPE1_TYPE2 = 0x3 << 13,
>> +               FEATURE_COMPRESSION_TYPE1_TYPE2_TYPE3 = 0x7 << 13,
>> +       };
>> +
>> +       enum {
>> +               EXTENDED_FEATURE_SPDIF_AUDIO_TX = BIT(0),
>> +               EXTENDED_FEATURE_SPDIF_AUDIO_RX = BIT(1),
>> +               EXTENDED_FEATURE_RS232 = BIT(2),
>> +               EXTENDED_FEATURE_COMPRESSION_PIPES = BIT(3),
>> +               EXTENDED_FEATURE_INTERLACE = BIT(4),
>> +       };
>> +
>> +       u16 raw_features;
>> +       u16 raw_extended_features;
>> +
>> +       memset(features, 0, sizeof(struct fpga_features));
>> +
>> +       FPGA_GET_REG(fpga, fpga_features, &raw_features);
>> +       FPGA_GET_REG(fpga, fpga_ext_features, &raw_extended_features);
>> +
>> +       features->video_channels = raw_features & 0x3;
>> +       features->carriers = (raw_features >> 2) & 0x3;
>> +
>> +       features->carrier_speed = (raw_features & FEATURE_CARRIER_SPEED_2_5)
>> +               ? CARRIER_SPEED_2_5G : CARRIER_SPEED_1G;
>> +
>> +       switch (raw_features & FEATURE_RAM_MASK) {
>> +       case FEATURE_RAM_DDR2_32BIT:
>> +               features->ram_config = RAM_DDR2_32BIT_295MBPS;
>>                 break;
>>
>> -       case AUDIO_TX:
>> -               printf(", audio tx");
>> +       case FEATURE_RAM_DDR3_32BIT:
>> +               features->ram_config = RAM_DDR3_32BIT_590MBPS;
>>                 break;
>>
>> -       case AUDIO_RX:
>> -               printf(", audio rx");
>> +       case FEATURE_RAM_DDR3_48BIT:
>> +               features->ram_config = RAM_DDR3_48BIT_590MBPS;
>>                 break;
>> +       }
>>
>> -       case AUDIO_RXTX:
>> -               printf(", audio rx+tx");
>> +       features->pcm_tx = raw_features & FEATURE_PCM_AUDIO_TX;
>> +       features->pcm_rx = raw_features & FEATURE_PCM_AUDIO_RX;
>> +       features->spdif_tx = raw_extended_features & EXTENDED_FEATURE_SPDIF_AUDIO_TX;
>> +       features->spdif_rx = raw_extended_features & EXTENDED_FEATURE_SPDIF_AUDIO_RX;
>> +
>> +       features->usb2 = raw_features & FEATURE_USB20;
>> +       features->rs232 = raw_extended_features & EXTENDED_FEATURE_RS232;
>> +
>> +       features->compression_type1 = false;
>> +       features->compression_type2 = false;
>> +       features->compression_type3 = false;
>> +       switch (raw_features & FEATURE_COMPRESSION_MASK) {
>> +       case FEATURE_COMPRESSION_TYPE1_TYPE2_TYPE3:
>> +               features->compression_type3 = true;
>> +       case FEATURE_COMPRESSION_TYPE1_TYPE2:
>> +               features->compression_type2 = true;
>> +       case FEATURE_COMPRESSION_TYPE1:
>> +               features->compression_type1 = true;
>>                 break;
>> +       }
>> +
>> +       features->interlace = raw_extended_features & EXTENDED_FEATURE_INTERLACE;
>> +       features->osd = raw_features & FEATURE_OSD;
>> +       features->compression_pipes = raw_extended_features & EXTENDED_FEATURE_COMPRESSION_PIPES;
>>
>> -       default:
>> -               printf(", audio %d(not supported)", feature_audio);
>> +       return 0;
>> +}
>> +
>> +#endif
>> +
>> +bool ioep_fpga_has_osd(unsigned int fpga)
>> +{
>> +       struct fpga_features features;
>> +
>> +       get_features(fpga, &features);
>> +
>> +       return features.osd;
>> +}
>> +
>> +void ioep_fpga_print_info(unsigned int fpga)
>> +{
>> +       u16 fpga_version;
>> +       struct fpga_versions versions;
>> +       struct fpga_features features;
>> +
>> +       FPGA_GET_REG(fpga, fpga_version, &fpga_version);
>> +       get_versions(fpga, &versions);
>> +       get_features(fpga, &features);
>> +
>> +       if (versions.video_channel)
>> +               printf("Videochannel");
>> +       else
>> +               printf("Mainchannel");
>> +
>> +       if (versions.con_side)
>> +               printf(" User");
>> +       else
>> +               printf(" Server");
>> +
>> +// FIXME
>> +#if 0
>> +               if (versions & (1<<4))
>> +                       printf(" UC");
>> +#endif
>> +
>> +       switch(versions.pcb_transmission_type) {
>> +       case PCB_CAT_1G:
>> +       case PCB_CAT_10G:
>> +               printf(" CAT");
>> +               break;
>> +       case PCB_FIBER_3G:
>> +       case PCB_FIBER_10G:
>> +               printf(" Fiber");
>> +               break;
>> +       };
>> +
>> +       switch (versions.pcb_video_type) {
>> +       case PCB_DVI_SL:
>> +               printf(" DVI,");
>> +               break;
>> +       case PCB_DP_165MPIX:
>> +               printf(" DP 165MPix/s,");
>> +               break;
>> +       case PCB_DP_300MPIX:
>> +               printf(" DP 300MPix/s,");
>> +               break;
>> +       case PCB_HDMI:
>> +               printf(" HDMI,");
>> +               break;
>> +       case PCB_DP_1_2:
>> +               printf(" DP 1.2,");
>> +               break;
>> +       case PCB_HDMI_2_0:
>> +               printf(" HDMI 2.0,");
>>                 break;
>>         }
>>
>> +       printf(" FPGA V %d.%02d\n       features: ",
>> +              fpga_version / 100, fpga_version % 100);
>> +
>> +       if (!features.compression_type1 &&
>> +           !features.compression_type2 &&
>> +           !features.compression_type3)
>> +               printf("no compression, ");
>> +
>> +       if (features.compression_type1)
>> +               printf("type1-deltacompression, ");
>> +
>> +       if (features.compression_type2)
>> +               printf("type2-inlinecompression, ");
>> +
>> +       if (features.compression_type3)
>> +               printf("type3-intempocompression, ");
>> +
>> +       printf("%sosd", features.osd ? "" : "no ");
>> +
>> +       if (features.pcm_rx && features.pcm_tx)
>> +               printf(", pcm rx+tx");
>> +       else if(features.pcm_rx)
>> +               printf(", pcm rx");
>> +       else if(features.pcm_tx)
>> +               printf(", pcm tx");
>> +
>> +       if (features.spdif_rx && features.spdif_tx)
>> +               printf(", spdif rx+tx");
>> +       else if(features.spdif_rx)
>> +               printf(", spdif rx");
>> +       else if(features.spdif_tx)
>> +               printf(", spdif tx");
>> +
>>         puts(",\n       ");
>>
>> -       switch (feature_sysclock) {
>> +       switch (features.sysclock) {
>>         case SYSCLK_147456:
>>                 printf("clock 147.456 MHz");
>>                 break;
>> -
>> -       default:
>> -               printf("clock %d(not supported)", feature_sysclock);
>> -               break;
>>         }
>>
>> -       switch (feature_ramconfig) {
>> -       case RAM_DDR2_32:
>> +       switch (features.ram_config) {
>> +       case RAM_DDR2_32BIT_295MBPS:
>>                 printf(", RAM 32 bit DDR2");
>>                 break;
>> -
>> -       case RAM_DDR3_32:
>> +       case RAM_DDR3_32BIT_590MBPS:
>>                 printf(", RAM 32 bit DDR3");
>>                 break;
>> -
>> -       case RAM_DDR3_48:
>> +       case RAM_DDR3_48BIT_590MBPS:
>> +       case RAM_DDR3_48BIT_1800MBPS:
>>                 printf(", RAM 48 bit DDR3");
>>                 break;
>> -
>> -       default:
>> -               printf(", RAM %d(not supported)", feature_ramconfig);
>> +       case RAM_DDR3_64BIT_1800MBPS:
>> +               printf(", RAM 64 bit DDR3");
>>                 break;
>>         }
>>
>> -       printf(", %d carrier(s) %s", feature_carriers,
>> -              feature_carrier_speed ? "2.5Gbit/s" : "1Gbit/s");
>> +       printf(", %d carrier(s)", features.carriers);
>> +
>> +       switch(features.carrier_speed) {
>> +       case CARRIER_SPEED_1G:
>> +               printf(", 1Gbit/s");
>> +               break;
>> +       case CARRIER_SPEED_3G:
>> +               printf(", 3Gbit/s");
>> +               break;
>> +       case CARRIER_SPEED_10G:
>> +               printf(", 10Gbit/s");
>> +               break;
>> +       }
>>
>> -       printf(", %d video channel(s)\n", feature_video_channels);
>> +       printf(", %d video channel(s)\n", features.video_channels);
>>  }
>>
>>  #endif /* CONFIG_GDSYS_LEGACY_DRIVERS */
>> diff --git a/board/gdsys/mpc8308/Kconfig b/board/gdsys/mpc8308/Kconfig
>> index 80ac1a0f8a..79d0dc9829 100644
>> --- a/board/gdsys/mpc8308/Kconfig
>> +++ b/board/gdsys/mpc8308/Kconfig
>> @@ -55,6 +55,25 @@ config GDSYS_LEGACY_DRIVERS
>>
>>  endif
>>
>> +if TARGET_GAZERBEAM
>> +
>> +config SYS_BOARD
>> +       default "mpc8308"
>> +
>> +config SYS_VENDOR
>> +       default "gdsys"
>> +
>> +config SYS_CONFIG_NAME
>> +       default "gazerbeam"
>> +
>> +config SYS_FPGA1_BASE
>> +       default E0700000
>> +
>> +config SYS_FPGA1_SIZE
>> +       default 1
>> +
>> +endif
>> +
>>  choice
>>         prompt "FPGA flavor selection"
>>
>> diff --git a/board/gdsys/mpc8308/MAINTAINERS b/board/gdsys/mpc8308/MAINTAINERS
>> index 3895b01732..a986ae3664 100644
>> --- a/board/gdsys/mpc8308/MAINTAINERS
>> +++ b/board/gdsys/mpc8308/MAINTAINERS
>> @@ -6,5 +6,7 @@ F:      include/configs/hrcon.h
>>  F:     configs/hrcon_defconfig
>>  F:     configs/hrcon_dh_defconfig
>>  F:     include/configs/strider.h
>> +F:     configs/strider_defconfig
>>  F:     configs/strider_cpu_defconfig
>>  F:     configs/strider_con_defconfig
>> +F:     configs/gazerbeam_defconfig
>> diff --git a/board/gdsys/mpc8308/Makefile b/board/gdsys/mpc8308/Makefile
>> index 42702fb967..bafb9beaaf 100644
>> --- a/board/gdsys/mpc8308/Makefile
>> +++ b/board/gdsys/mpc8308/Makefile
>> @@ -8,3 +8,4 @@
>>  obj-y := mpc8308.o sdram.o
>>  obj-$(CONFIG_HRCON) += hrcon.o
>>  obj-$(CONFIG_STRIDER) += strider.o
>> +obj-$(CONFIG_TARGET_GAZERBEAM) += gazerbeam.o
>> diff --git a/board/gdsys/mpc8308/gazerbeam.c b/board/gdsys/mpc8308/gazerbeam.c
>> new file mode 100644
>> index 0000000000..a86333d92c
>> --- /dev/null
>> +++ b/board/gdsys/mpc8308/gazerbeam.c
>> @@ -0,0 +1,332 @@
>> +/*
>> + * (C) Copyright 2015
>> + * Dirk Eibach,  Guntermann & Drunck GmbH, eibach at gdsys.de
>> + *
>> + * SPDX-License-Identifier:    GPL-2.0+
>> + */
>> +
>> +#include <common.h>
>> +#include <dm.h>
>> +#include <dm/device-internal.h>
>> +#include <dm/uclass-internal.h>
>> +#include <fsl_esdhc.h>
>> +#include <gdsys_rxaui_ctrl.h>
>> +#include <marvell-phy.h>
>> +#include <miiphy.h>
>> +#include <tpm.h>
>> +#include <i2c.h>
>> +#include <asm/fsl_mpc83xx_serdes.h>
>> +#include <asm/gpio.h>
>> +
>> +#include "../../../drivers/net/phy/mv88x2.h"
>> +#include "../common/ihs_mdio.h"
>> +
>> +DECLARE_GLOBAL_DATA_PTR;
>> +
>> +struct ihs_mdio_info ihs_mdio_info[] = {
>> +       { .fpga = NULL, .name = "ihs0", .clause45 = true, .base = 0x58 },
>> +       { .fpga = NULL, .name = "ihs1", .clause45 = true, .base = 0x58 },
>> +};
>> +
>> +int child_find_by_name(struct udevice *parent, const char *dev_name,
>> +                      struct udevice **child)
>
> Can we add (in separate patch with test) dev_find_child_by_name() in
> the dm core code?
>

OK, will add the function in v2.

>> +{
>> +       struct udevice *dev = NULL;
>> +
>> +       for (device_find_first_child(parent, &dev);
>> +            dev;
>> +            device_find_next_child(&dev)) {
>> +               if (!strncmp(dev->name, dev_name, strlen(dev_name))) {
>> +                       *child = dev;
>> +                       return 0;
>> +               }
>> +       }
>> +
>> +       return -1;
>> +}
>> +
>> +int request_gpio_by_dev(struct gpio_desc *gpio, struct udevice *gpio_dev,
>> +                       uint offset, char *gpio_name)
>> +{
>> +       gpio->dev = gpio_dev;
>> +       gpio->offset = offset;
>> +       gpio->flags = 0;
>> +
>> +       return dm_gpio_request(gpio, gpio_name);
>> +}
>> +
>> +void determine_board_type(struct of_board_fixup_data *data)
>> +{
>> +       struct udevice *i2c_bus;
>> +       struct udevice *dummy;
>> +       struct udevice *gpio_dev = NULL;
>> +       struct gpio_desc gpio;
>> +       char name[16];
>> +
>> +       uclass_get_device_by_name(UCLASS_I2C, "i2c at 3100", &i2c_bus);
>
> Can you use an alias to find this and get by seq? Or have a property
> somewhere which points to this as a phandle?
>

I'll probably go with the alias-and-seq approach. I don't really know where a
property might fit in.

>> +
>> +       if (!i2c_bus) {
>> +               puts("Could not get I2C bus\n");
>> +               return;
>> +       }
>> +
>> +       data->mc2 = !dm_i2c_probe(i2c_bus, 0x20, 0, &dummy);
>> +       data->mc4 = !dm_i2c_probe(i2c_bus, 0x22, 0, &dummy);
>> +
>> +       if (data->mc2 && data->mc4) {
>> +               puts("Board hardware configuration inconsistent.");
>> +               return;
>> +       }
>> +
>> +       snprintf(name, sizeof(name), "pca9698@%x", data->mc4 ? 0x22 : 0x20);
>> +
>> +       if (child_find_by_name(i2c_bus, name, &gpio_dev)) {
>> +               printf("Could not find child %s of device %s\n", name,
>> +                      i2c_bus->name);
>> +               return;
>> +       }
>> +
>> +       device_probe(gpio_dev);
>
> Let's have device_get_child_by_name() also. We should not explicitly
> probe outside DM code if possible.
>

OK, will add the function in v2.

>> +
>> +       if (!data->mc4) {
>> +               if (!request_gpio_by_dev(&gpio, gpio_dev, 0, "var-mc_sc"))
>
> Can you have this GPIO in the device tree so you can use
> gpio_request_by_name() from a driver? What is this GPIO for?
>

That's a bit of a problem. That GPIO determines whether the board is a
single-channel variant or a multi-channel variant. So it doesn't really
"belong" to any device at all; it's a property of the board itself.

Introducing some kind of "variant driver" with a matching node in the DT would
probably work, but I don't know if the concept is generic enough to warrant
something like that (it would need another new uclass, probably).

The nicest thing would probably be a "board driver" that describes properties
of the board itself (this GPIO could then be a property of the board). This
would also be a possible way to do away with board files completely: Every
board that needs board-specific initialization implements a board driver with
the current callback functions board_early_init_{r,f}, last_stage_init etc. as
driver functions as needed. Those are called from board_{f,r}.c via
board-uclass.c, and we don't need board files anymore. But, that's probably a
bit too far fetched.

>> +                       data->mc2 = !dm_gpio_get_value(&gpio);
>> +               else
>> +                       puts("Could not query var-mc_sc GPIO.\n");
>> +
>> +               dm_gpio_free(gpio_dev, &gpio);
>> +       }
>> +
>> +       if (!request_gpio_by_dev(&gpio, gpio_dev, 11, "var-con"))
>> +               data->var_con = dm_gpio_get_value(&gpio);
>> +       else
>> +               puts("Could not query var-con GPIO.\n");
>> +
>> +       dm_gpio_free(gpio_dev, &gpio);
>> +}
>> +
>> +int board_fix_fdt_get_info(void)
>> +{
>> +       struct of_board_fixup_data data;
>> +
>> +       determine_board_type(&data);
>> +
>> +       gd->board_fixup_data.var_con = data.var_con;
>> +       gd->board_fixup_data.mc2 = data.mc2;
>> +       gd->board_fixup_data.mc4 = data.mc4;
>> +
>> +       return 0;
>> +}
>> +
>> +int fdt_disable_by_ofname(void *rw_fdt_blob, char *ofname)
>> +{
>> +       int offset = fdt_path_offset(rw_fdt_blob, ofname);
>> +
>> +       return fdt_status_disabled(rw_fdt_blob, offset);
>> +}
>> +
>> +int board_fix_fdt_change(void *rw_fdt_blob)
>> +{
>> +       struct of_board_fixup_data data = gd->board_fixup_data;
>> +
>> +       if (!data.mc4) {
>> +               fdt_disable_by_ofname(rw_fdt_blob,
>> +                                     "/localbus at e0005000/iocon_uart at 2,0");
>> +               fdt_disable_by_ofname(rw_fdt_blob, "/fpga1bus");
>> +       }
>> +
>> +       if (!data.mc2 || !data.var_con) {
>> +               fdt_disable_by_ofname(rw_fdt_blob, "/fpga0bus/fpga0_video1");
>> +               fdt_disable_by_ofname(rw_fdt_blob, "/fpga0bus/fpga0_iic_video1");
>> +               fdt_disable_by_ofname(rw_fdt_blob, "/fpga0bus/fpga0_axi_video1");
>> +       }
>> +
>> +       if (!data.var_con) {
>> +               fdt_disable_by_ofname(rw_fdt_blob, "/fpga0bus/fpga0_video0");
>> +               fdt_disable_by_ofname(rw_fdt_blob, "/fpga0bus/fpga0_iic_video0");
>> +               fdt_disable_by_ofname(rw_fdt_blob, "/fpga0bus/fpga0_axi_video0");
>> +       }
>> +
>> +       return 0;
>> +}
>> +
>> +int checkboard(void)
>> +{
>> +       struct of_board_fixup_data data = gd->board_fixup_data;
>> +       char *s = getenv("serial#");
>> +
>> +       puts("Board: Gazerbeam ");
>> +       printf("%s ", data.mc4 ? "MC4" : data.mc2 ? "MC2" : "SC");
>> +       printf("%s", data.var_con ? "CON" : "CPU");
>> +
>> +       if (s) {
>> +               puts(", serial# ");
>> +               puts(s);
>> +       }
>> +
>> +       puts("\n");
>> +
>> +       return 0;
>> +}
>> +
>> +int last_stage_init(void)
>> +{
>> +       uint fpga_hw_rev = 0;
>> +       uint k = 0;
>> +       struct udevice *fpga;
>> +       struct udevice *rxaui;
>> +       struct udevice *i2c_bus;
>> +       struct udevice *gpio_dev;
>> +       char name[16];
>> +
>> +       uclass_get_device_by_name(UCLASS_I2C, "i2c at 3000", &i2c_bus);
>> +
>> +       if (child_find_by_name(i2c_bus, "pca9698 at 20", &gpio_dev)) {
>> +               printf("Could not find child %s of device %s\n", name,
>> +                      i2c_bus->name);
>> +               return -1;
>> +       }
>> +
>> +       device_probe(gpio_dev);
>> +
>> +       for (k = 0; k < 4; ++k) {
>> +               struct gpio_desc gpio;
>> +
>> +               snprintf(name, sizeof(name), "fpga_hw_rev%d", k);
>> +
>> +               if (!request_gpio_by_dev(&gpio, gpio_dev, 12 + k, name))
>> +                       fpga_hw_rev |= dm_gpio_get_value(&gpio) ? BIT(k) : 0;
>> +       }
>> +
>> +       setenv_ulong("fpga_hw_rev", fpga_hw_rev);
>
> Can we use gpio_request_list_by_name() and dm_gpio_get_values_as_int() ?
>

Yeah, that would be nicer. I'll use them in v2.

>> +
>> +       if (tpm_init() || tpm_startup(TPM_ST_CLEAR) ||
>> +           tpm_continue_self_test()) {
>> +               printf("TPM init failed\n");
>> +       }
>> +
>> +       if (fpga_hw_rev >= 4) {
>> +               for (uclass_find_first_device(UCLASS_RXAUI_CTRL, &rxaui);
>> +                    rxaui;
>> +                    uclass_find_next_device(&rxaui)) {
>> +                       rxaui_disable_polarity_inversion(rxaui);
>> +               }
>> +       }
>> +
>> +       for (uclass_find_first_device(UCLASS_IHS_FPGA, &fpga);
>> +            fpga;
>> +            uclass_find_next_device(&fpga)) {
>
> Can you use uclass_first_next_device() since it does the probing for you.
>

OK, will fix in v2.

>> +               struct mii_dev *bus;
>> +
>> +               device_probe(fpga);
>> +
>> +               if (fpga->seq < 0)
>> +                       continue;
>
> What is this checking for?
>

The phy initialization below should only run for the first FPGA, so we skip it
for all others.

>> +
>> +               ihs_mdio_info[fpga->seq].fpga = fpga;
>> +
>> +               ihs_mdio_init(&ihs_mdio_info[fpga->seq]);
>> +               bus = miiphy_get_dev_by_name(fpga->seq ? "ihs1" : "ihs0");
>> +               if (bus) {
>> +                       struct phy_device *phydev;
>> +
>> +                       phydev = phy_find_by_mask_c45(bus, 1,
>> +                                                     PHY_INTERFACE_MODE_XGMII);
>> +                       if (phydev)
>> +                               phy_config(phydev);
>> +               }
>> +       }
>> +
>> +       return 0;
>> +}
>> +
>> +#ifdef CONFIG_FSL_ESDHC
>> +int board_mmc_init(bd_t *bd)
>> +{
>> +       immap_t *immr = (immap_t *)CONFIG_SYS_IMMR;
>> +       sysconf83xx_t *sysconf = &immr->sysconf;
>> +
>> +       /* Enable cache snooping in eSDHC system configuration register */
>> +       out_be32(&sysconf->sdhccr, 0x02000000);
>> +
>> +       return fsl_esdhc_mmc_init(bd);
>> +}
>> +#endif
>> +
>> +static struct pci_region pcie_regions_0[] = {
>> +       {
>> +               .bus_start = CONFIG_SYS_PCIE1_MEM_BASE,
>> +               .phys_start = CONFIG_SYS_PCIE1_MEM_PHYS,
>> +               .size = CONFIG_SYS_PCIE1_MEM_SIZE,
>> +               .flags = PCI_REGION_MEM,
>> +       },
>> +       {
>> +               .bus_start = CONFIG_SYS_PCIE1_IO_BASE,
>> +               .phys_start = CONFIG_SYS_PCIE1_IO_PHYS,
>> +               .size = CONFIG_SYS_PCIE1_IO_SIZE,
>> +               .flags = PCI_REGION_IO,
>> +       },
>> +};
>> +
>> +void pci_init_board(void)
>> +{
>> +       immap_t *immr = (immap_t *)CONFIG_SYS_IMMR;
>> +       sysconf83xx_t *sysconf = &immr->sysconf;
>> +       law83xx_t *pcie_law = sysconf->pcielaw;
>> +       struct pci_region *pcie_reg[] = { pcie_regions_0 };
>> +
>> +       fsl_setup_serdes(CONFIG_FSL_SERDES1, FSL_SERDES_PROTO_PEX,
>> +                        FSL_SERDES_CLK_100, FSL_SERDES_VDD_1V);
>> +
>> +       /* Deassert the resets in the control register */
>> +       out_be32(&sysconf->pecr1, 0xE0008000);
>> +       udelay(2000);
>> +
>> +       /* Configure PCI Express Local Access Windows */
>> +       out_be32(&pcie_law[0].bar, CONFIG_SYS_PCIE1_BASE & LAWBAR_BAR);
>> +       out_be32(&pcie_law[0].ar, LBLAWAR_EN | LBLAWAR_512MB);
>> +
>> +       mpc83xx_pcie_init(1, pcie_reg);
>> +}
>> +
>> +ulong board_flash_get_legacy(ulong base, int banknum, flash_info_t *info)
>> +{
>> +       info->portwidth = FLASH_CFI_16BIT;
>> +       info->chipwidth = FLASH_CFI_BY16;
>> +       info->interface = FLASH_CFI_X16;
>> +       return 1;
>> +}
>> +
>> +#if defined(CONFIG_OF_BOARD_SETUP)
>> +int ft_board_setup(void *blob, bd_t *bd)
>> +{
>> +       ft_cpu_setup(blob, bd);
>> +       fsl_fdt_fixup_dr_usb(blob, bd);
>> +       fdt_fixup_esdhc(blob, bd);
>> +
>> +       return 0;
>> +}
>> +#endif
>> +
>> +int board_m88e1510_config(struct phy_device *phydev)
>> +{
>> +       /* Select page 3 */
>> +       phy_write(phydev, MDIO_DEVAD_NONE, 22, 3);
>> +
>> +       /* Configure LEDs */
>> +       m88e1518_phy_writebits(phydev, 16, 0, 4, 4);
>> +       m88e1518_phy_writebits(phydev, 16, 4, 4, 8);
>> +       m88e1518_phy_writebits(phydev, 16, 8, 4, 0);
>> +
>> +       /* Reset page selection */
>> +       phy_write(phydev, MDIO_DEVAD_NONE, 22, 0);
>> +
>> +       return 0;
>> +}
>> +
>> +int board_mv88x2_config(struct mv88x2_config_data *data)
>> +{
>> +       data->sfi_pol = (getenv_ulong("fpga_hw_rev", 10, 0) < 4) ? 0x0f03 : 0;
>> +
>> +       return 0;
>> +}
>> diff --git a/configs/gazerbeam_defconfig b/configs/gazerbeam_defconfig
>> new file mode 100644
>> index 0000000000..4fc92ea19b
>> --- /dev/null
>> +++ b/configs/gazerbeam_defconfig
>> @@ -0,0 +1,76 @@
>> +CONFIG_PPC=y
>> +CONFIG_SYS_MALLOC_F_LEN=0x600
>> +CONFIG_IDENT_STRING=" gazerbeam 0.01"
>> +CONFIG_MPC83xx=y
>> +CONFIG_TARGET_GAZERBEAM=y
>> +CONFIG_SYS_FPGA_FLAVOR_GAZERBEAM=y
>> +CONFIG_CMD_IOLOOP=y
>> +CONFIG_DEFAULT_DEVICE_TREE="gazerbeam"
>> +CONFIG_FIT=y
>> +CONFIG_FIT_SIGNATURE=y
>> +CONFIG_FIT_VERBOSE=y
>> +CONFIG_OF_BOARD_SETUP=y
>> +CONFIG_OF_STDOUT_VIA_ALIAS=y
>> +CONFIG_BOOTDELAY=5
>> +CONFIG_SYS_CONSOLE_INFO_QUIET=y
>> +# CONFIG_DISPLAY_BOARDINFO is not set
>> +CONFIG_HUSH_PARSER=y
>> +CONFIG_AUTOBOOT_KEYED=y
>> +CONFIG_AUTOBOOT_STOP_STR=" "
>> +CONFIG_CMD_MEMTEST=y
>> +CONFIG_CMD_MMC=y
>> +CONFIG_CMD_I2C=y
>> +# CONFIG_CMD_FPGA is not set
>> +CONFIG_CMD_GPIO=y
>> +CONFIG_CMD_IHS_FPGA=y
>> +CONFIG_CMD_IHS_AXI=y
>> +# CONFIG_CMD_SETEXPR is not set
>> +# CONFIG_CMD_NFS is not set
>> +CONFIG_CMD_MII=y
>> +CONFIG_CMD_MII_DRIVER=y
>> +CONFIG_CMD_PING=y
>> +CONFIG_CMD_HASH=y
>> +CONFIG_CMD_TPM=y
>> +CONFIG_CMD_EXT2=y
>> +CONFIG_DOS_PARTITION=y
>> +CONFIG_OF_CONTROL=y
>> +CONFIG_OF_BOARD_FIXUP=y
>> +CONFIG_OF_EMBED=y
>> +CONFIG_DM=y
>> +CONFIG_CLK=y
>> +CONFIG_ICS8N3QV01=y
>> +CONFIG_DM_GPIO=y
>> +CONFIG_DM_PCA953X=y
>> +CONFIG_MPC8XXX_GPIO=y
>> +CONFIG_DM_I2C=y
>> +CONFIG_SYS_I2C_FSL=y
>> +CONFIG_SYS_I2C_IHS=y
>> +CONFIG_MISC=y
>> +CONFIG_IHS_FPGA=y
>> +CONFIG_IHS_AXI=y
>> +CONFIG_IHS_VIDEO_OUT=y
>> +CONFIG_GDSYS_RXAUI_CTRL=y
>> +CONFIG_GDSYS_IOEP=y
>> +CONFIG_MTD=y
>> +CONFIG_MTD_NOR_FLASH=y
>> +CONFIG_CFI_FLASH=y
>> +CONFIG_PHYLIB=y
>> +CONFIG_PHYLIB_10G=y
>> +CONFIG_PHY_MARVELL=y
>> +CONFIG_BOARD_M88E1510_CONFIG=y
>> +CONFIG_PHY_MV88X2=y
>> +CONFIG_BOARD_MV88X2_CONFIG=y
>> +CONFIG_MV88X2_DEBUG_REGS=y
>> +CONFIG_MV88X2_LINE_10GBASE_R=y
>> +CONFIG_MV88X2_HOST_10GBASE_X2=y
>> +CONFIG_MV88X2_X2_DISPARITY=y
>> +CONFIG_MV88X2_LED0_SOLID=6
>> +CONFIG_MV88X2_LED1_SOLID=6
>> +CONFIG_MV88X2_HOST_LANE_MUX_2_PORT=0x0800
>> +CONFIG_DM_SERIAL=y
>> +CONFIG_SYS_NS16550=y
>> +CONFIG_TPM_ATMEL_TWI=y
>> +CONFIG_TPM_AUTH_SESSIONS=y
>> +CONFIG_TRANSMITTER=y
>> +CONFIG_LOGICORE_DP_TX=y
>> +CONFIG_TPM=y
>> diff --git a/include/configs/gazerbeam.h b/include/configs/gazerbeam.h
>> new file mode 100644
>> index 0000000000..a8d0474771
>> --- /dev/null
>> +++ b/include/configs/gazerbeam.h
>> @@ -0,0 +1,484 @@
>> +/*
>> + * (C) Copyright 2015
>> + * Dirk Eibach,  Guntermann & Drunck GmbH, eibach at gdsys.de
>> + *
>> + *
>> + * SPDX-License-Identifier:    GPL-2.0+
>> + */
>> +
>> +#ifndef __CONFIG_H
>> +#define __CONFIG_H
>> +
>> +/*
>> + * High Level Configuration Options
>> + */
>> +#define CONFIG_E300            1 /* E300 family */
>> +#define CONFIG_MPC83xx         1 /* MPC83xx family */
>> +#define CONFIG_MPC830x         1 /* MPC830x family */
>> +#define CONFIG_MPC8308         1 /* MPC8308 CPU specific */
>
> Can you drop the '1' in these?
>

I'll drop them. They're also in every other MPC83xx config file, pretty much
(probably copied/pasted over time). I'll prune them as well in a separate
series.

>> +
>> +#define        CONFIG_SYS_TEXT_BASE    0xFE000000
>> +
>> +#define CONFIG_LAST_STAGE_INIT
>> +#define CONFIG_DISPLAY_BOARDINFO_LATE
>> +
>> +#define CONFIG_FSL_ESDHC
>> +#define CONFIG_SYS_FSL_ESDHC_ADDR      CONFIG_SYS_MPC83xx_ESDHC_ADDR
>> +#define CONFIG_SYS_FSL_ERRATUM_ESDHC111
>> +
>> +#define CONFIG_SYS_ALT_MEMTEST
>> +
>> +/*
>> + * System Clock Setup
>> + */
>> +#define CONFIG_83XX_CLKIN      33333333 /* in Hz */
>> +#define CONFIG_SYS_CLK_FREQ    CONFIG_83XX_CLKIN
>> +
>> +/*
>> + * Hardware Reset Configuration Word
>> + * if CLKIN is 66.66MHz, then
>> + * CSB = 133MHz, DDRC = 266MHz, LBC = 133MHz
>> + * We choose the A type silicon as default, so the core is 400Mhz.
>> + */
>> +#define CONFIG_SYS_HRCW_LOW (\
>> +       HRCWL_LCL_BUS_TO_SCB_CLK_1X1 |\
>> +       HRCWL_DDR_TO_SCB_CLK_2X1 |\
>> +       HRCWL_SVCOD_DIV_2 |\
>> +       HRCWL_CSB_TO_CLKIN_4X1 |\
>> +       HRCWL_CORE_TO_CSB_3X1)
>
> Seems like this should be in the DT instead of a CONFIG. TBD for later?
>

The HRCW (Hard Reset Configuration Word) has to be hard-coded in the image at a
specific position, since the SoC reads it when it starts up, and configures
itself according to it. So it could be moved to Kconfig, but not to DT, I'm
afraid.

>> +/*
>> + * There are neither HRCWH_PCI_HOST nor HRCWH_PCI1_ARBITER_ENABLE bits
>> + * in 8308's HRCWH according to the manual, but original Freescale's
>> + * code has them and I've expirienced some problems using the board
>> + * with BDI3000 attached when I've tried to set these bits to zero
>> + * (UART doesn't work after the 'reset run' command).
>> + */
>> +#define CONFIG_SYS_HRCW_HIGH (\
>> +       HRCWH_PCI_HOST |\
>> +       HRCWH_PCI1_ARBITER_ENABLE |\
>> +       HRCWH_CORE_ENABLE |\
>> +       HRCWH_FROM_0XFFF00100 |\
>> +       HRCWH_BOOTSEQ_DISABLE |\
>> +       HRCWH_SW_WATCHDOG_DISABLE |\
>> +       HRCWH_ROM_LOC_LOCAL_16BIT |\
>> +       HRCWH_RL_EXT_LEGACY |\
>> +       HRCWH_TSEC1M_IN_RGMII |\
>> +       HRCWH_TSEC2M_IN_RGMII |\
>> +       HRCWH_BIG_ENDIAN)
>> +
>> +/*
>> + * System IO Config
>> + */
>> + #define CONFIG_SYS_SICRH (\
>> +       SICRH_ESDHC_A_SD |\
>> +       SICRH_ESDHC_B_SD |\
>> +       SICRH_ESDHC_C_SD |\
>> +       SICRH_GPIO_A_TSEC2 |\
>> +       SICRH_GPIO_B_TSEC2_GTX_CLK125 |\
>> +       SICRH_IEEE1588_A_GPIO |\
>> +       SICRH_USB |\
>> +       SICRH_GTM_GPIO |\
>> +       SICRH_IEEE1588_B_GPIO |\
>> +       SICRH_ETSEC2_GPIO |\
>> +       SICRH_GPIOSEL_1 |\
>> +       SICRH_TMROBI_V3P3 |\
>> +       SICRH_TSOBI1_V2P5 |\
>> +       SICRH_TSOBI2_V2P5)      /* 0x01b7f103 */
>> + #define CONFIG_SYS_SICRL (\
>> +       SICRL_SPI_PF0 |\
>> +       SICRL_UART_PF0 |\
>> +       SICRL_IRQ_PF0 |\
>> +       SICRL_I2C2_PF0 |\
>> +       SICRL_ETSEC1_GTX_CLK125)        /* 0x00000000 */
>> +
>> +/*
>> + * IMMR new address
>> + */
>> +#define CONFIG_SYS_IMMR                0xE0000000
>> +
>> +/*
>> + * SERDES
>> + */
>> +#define CONFIG_FSL_SERDES
>> +#define CONFIG_FSL_SERDES1     0xe3000
>> +
>> +/*
>> + * Arbiter Setup
>> + */
>> +#define CONFIG_SYS_ACR_PIPE_DEP        3 /* Arbiter pipeline depth is 4 */
>> +#define CONFIG_SYS_ACR_RPTCNT  3 /* Arbiter repeat count is 4 */
>> +#define CONFIG_SYS_SPCR_TSECEP 3 /* eTSEC emergency priority is highest */
>> +
>> +/*
>> + * DDR Setup
>> + */
>> +#define CONFIG_SYS_DDR_BASE            0x00000000 /* DDR is system memory */
>> +#define CONFIG_SYS_SDRAM_BASE          CONFIG_SYS_DDR_BASE
>> +#define CONFIG_SYS_DDR_SDRAM_BASE      CONFIG_SYS_DDR_BASE
>> +#define CONFIG_SYS_DDR_SDRAM_CLK_CNTL  DDR_SDRAM_CLK_CNTL_CLK_ADJUST_05
>> +#define CONFIG_SYS_DDRCDR_VALUE        (DDRCDR_EN \
>> +                               | DDRCDR_PZ_LOZ \
>> +                               | DDRCDR_NZ_LOZ \
>> +                               | DDRCDR_ODT \
>> +                               | DDRCDR_Q_DRN)
>> +                               /* 0x7b880001 */
>> +/*
>> + * Manually set up DDR parameters
>> + * consist of one chip NT5TU64M16HG from NANYA
>> + */
>> +
>> +#define CONFIG_SYS_DDR_SIZE            128 /* MB */
>> +
>> +#define CONFIG_SYS_DDR_CS0_BNDS        0x00000007
>> +#define CONFIG_SYS_DDR_CS0_CONFIG      (CSCONFIG_EN \
>> +                               | CSCONFIG_ODT_RD_NEVER \
>> +                               | CSCONFIG_ODT_WR_ONLY_CURRENT \
>> +                               | CSCONFIG_BANK_BIT_3 \
>> +                               | CSCONFIG_ROW_BIT_13 | CSCONFIG_COL_BIT_10)
>> +                               /* 0x80010102 */
>> +#define CONFIG_SYS_DDR_TIMING_3        0
>> +#define CONFIG_SYS_DDR_TIMING_0        ((0 << TIMING_CFG0_RWT_SHIFT) \
>> +                               | (0 << TIMING_CFG0_WRT_SHIFT) \
>> +                               | (0 << TIMING_CFG0_RRT_SHIFT) \
>> +                               | (0 << TIMING_CFG0_WWT_SHIFT) \
>> +                               | (2 << TIMING_CFG0_ACT_PD_EXIT_SHIFT) \
>> +                               | (6 << TIMING_CFG0_PRE_PD_EXIT_SHIFT) \
>> +                               | (8 << TIMING_CFG0_ODT_PD_EXIT_SHIFT) \
>> +                               | (2 << TIMING_CFG0_MRS_CYC_SHIFT))
>> +                               /* 0x00260802 */
>> +#define CONFIG_SYS_DDR_TIMING_1        ((2 << TIMING_CFG1_PRETOACT_SHIFT) \
>> +                               | (6 << TIMING_CFG1_ACTTOPRE_SHIFT) \
>> +                               | (2 << TIMING_CFG1_ACTTORW_SHIFT) \
>> +                               | (7 << TIMING_CFG1_CASLAT_SHIFT) \
>> +                               | (9 << TIMING_CFG1_REFREC_SHIFT) \
>> +                               | (2 << TIMING_CFG1_WRREC_SHIFT) \
>> +                               | (2 << TIMING_CFG1_ACTTOACT_SHIFT) \
>> +                               | (2 << TIMING_CFG1_WRTORD_SHIFT))
>> +                               /* 0x26279222 */
>> +#define CONFIG_SYS_DDR_TIMING_2        ((0 << TIMING_CFG2_ADD_LAT_SHIFT) \
>> +                               | (4 << TIMING_CFG2_CPO_SHIFT) \
>> +                               | (3 << TIMING_CFG2_WR_LAT_DELAY_SHIFT) \
>> +                               | (2 << TIMING_CFG2_RD_TO_PRE_SHIFT) \
>> +                               | (2 << TIMING_CFG2_WR_DATA_DELAY_SHIFT) \
>> +                               | (3 << TIMING_CFG2_CKE_PLS_SHIFT) \
>> +                               | (5 << TIMING_CFG2_FOUR_ACT_SHIFT))
>> +                               /* 0x021848c5 */
>> +#define CONFIG_SYS_DDR_INTERVAL        ((0x0824 << SDRAM_INTERVAL_REFINT_SHIFT) \
>> +                               | (0x0100 << SDRAM_INTERVAL_BSTOPRE_SHIFT))
>> +                               /* 0x08240100 */
>> +#define CONFIG_SYS_DDR_SDRAM_CFG       (SDRAM_CFG_SREN \
>> +                               | SDRAM_CFG_SDRAM_TYPE_DDR2 \
>> +                               | SDRAM_CFG_DBW_16)
>> +                               /* 0x43100000 */
>> +
>> +#define CONFIG_SYS_DDR_SDRAM_CFG2      0x00401000 /* 1 posted refresh */
>> +#define CONFIG_SYS_DDR_MODE            ((0x0440 << SDRAM_MODE_ESD_SHIFT) \
>> +                               | (0x0242 << SDRAM_MODE_SD_SHIFT))
>> +                               /* ODT 150ohm CL=4, AL=0 on SDRAM */
>> +#define CONFIG_SYS_DDR_MODE2           0x00000000
>
> I think this should all be a UCLASS_RAM driver with DT configuration.
> Too many CONFIGs :-)
>

Yeah, it's not really nice, that's true. I'll look into it. I was planning on
taking on MPC83xx DM conversion anyway, so I might as well combine it with the
Gazerbeam series while I'm at it.

>> +
>> +/*
>> + * Memory test
>> + */
>> +#define CONFIG_SYS_MEMTEST_START       0x00001000 /* memtest region */
>> +#define CONFIG_SYS_MEMTEST_END         0x07f00000
>> +
>> +/*
>> + * The reserved memory
>> + */
>> +#define CONFIG_SYS_MONITOR_BASE        CONFIG_SYS_TEXT_BASE /* start of monitor */
>> +
>> +#define CONFIG_SYS_MONITOR_LEN (512 * 1024) /* Reserve 512 kB for Mon */
>> +#define CONFIG_SYS_MALLOC_LEN  (512 * 1024) /* Reserved for malloc */
>> +
>> +/*
>> + * Initial RAM Base Address Setup
>> + */
>> +#define CONFIG_SYS_INIT_RAM_LOCK       1
>> +#define CONFIG_SYS_INIT_RAM_ADDR       0xE6000000 /* Initial RAM address */
>> +#define CONFIG_SYS_INIT_RAM_SIZE       0x1000 /* Size of used area in RAM */
>> +#define CONFIG_SYS_GBL_DATA_OFFSET     \
>> +       (CONFIG_SYS_INIT_RAM_SIZE - GENERATED_GBL_DATA_SIZE)
>> +
>> +/*
>> + * Local Bus Configuration & Clock Setup
>> + */
>> +#define CONFIG_SYS_LCRR_DBYP           LCRR_DBYP
>> +#define CONFIG_SYS_LCRR_CLKDIV         LCRR_CLKDIV_2
>> +#define CONFIG_SYS_LBC_LBCR            0x00040000
>> +
>> +/*
>> + * FLASH on the Local Bus
>> + */
>> +#define CONFIG_SYS_FLASH_CFI           /* use the Common Flash Interface */
>> +#define CONFIG_FLASH_CFI_DRIVER                /* use the CFI driver */
>> +#define CONFIG_SYS_FLASH_CFI_WIDTH     FLASH_CFI_16BIT
>> +#define CONFIG_FLASH_CFI_LEGACY
>> +#define CONFIG_SYS_FLASH_LEGACY_512Kx16
>> +
>> +#define CONFIG_SYS_FLASH_BASE          0xFE000000 /* FLASH base address */
>> +#define CONFIG_SYS_FLASH_SIZE          8 /* FLASH size is up to 8M */
>> +#define CONFIG_SYS_FLASH_PROTECTION    1 /* Use h/w Flash protection. */
>> +
>> +/* Window base at flash base */
>> +#define CONFIG_SYS_LBLAWBAR0_PRELIM    CONFIG_SYS_FLASH_BASE
>> +#define CONFIG_SYS_LBLAWAR0_PRELIM     (LBLAWAR_EN | LBLAWAR_8MB)
>> +
>> +#define CONFIG_SYS_BR0_PRELIM  (CONFIG_SYS_FLASH_BASE \
>> +                               | BR_PS_16      /* 16 bit port */ \
>> +                               | BR_MS_GPCM    /* MSEL = GPCM */ \
>> +                               | BR_V)         /* valid */
>> +#define CONFIG_SYS_OR0_PRELIM  (MEG_TO_AM(CONFIG_SYS_FLASH_SIZE) \
>> +                               | OR_UPM_XAM \
>> +                               | OR_GPCM_CSNT \
>> +                               | OR_GPCM_ACS_DIV2 \
>> +                               | OR_GPCM_XACS \
>> +                               | OR_GPCM_SCY_15 \
>> +                               | OR_GPCM_TRLX_SET \
>> +                               | OR_GPCM_EHTR_SET)
>> +
>> +#define CONFIG_SYS_MAX_FLASH_BANKS     1 /* number of banks */
>> +#define CONFIG_SYS_MAX_FLASH_SECT      135
>> +
>> +#define CONFIG_SYS_FLASH_ERASE_TOUT    60000 /* Flash Erase Timeout (ms) */
>> +#define CONFIG_SYS_FLASH_WRITE_TOUT    500 /* Flash Write Timeout (ms) */
>> +
>> +/* Window base at FPGA base */
>> +#define CONFIG_SYS_LBLAWBAR1_PRELIM    CONFIG_SYS_FPGA0_BASE
>> +#define CONFIG_SYS_LBLAWAR1_PRELIM     (LBLAWAR_EN | LBLAWAR_1MB)
>> +#define CONFIG_SYS_LBLAWBAR2_PRELIM    CONFIG_SYS_FPGA1_BASE
>> +#define CONFIG_SYS_LBLAWAR2_PRELIM     (LBLAWAR_EN | LBLAWAR_1MB)
>> +
>> +#define CONFIG_SYS_BR1_PRELIM  (CONFIG_SYS_FPGA0_BASE \
>> +                               | BR_PS_16      /* 16 bit port */ \
>> +                               | BR_MS_GPCM    /* MSEL = GPCM */ \
>> +                               | BR_V)         /* valid */
>> +#define CONFIG_SYS_OR1_PRELIM   (MEG_TO_AM(CONFIG_SYS_FPGA0_SIZE) \
>> +                               | OR_UPM_XAM \
>> +                               | OR_GPCM_CSNT \
>> +                               | OR_GPCM_SCY_5 \
>> +                               | OR_GPCM_TRLX_CLEAR \
>> +                               | OR_GPCM_EHTR_CLEAR)
>> +
>> +#define CONFIG_SYS_BR2_PRELIM  (CONFIG_SYS_FPGA1_BASE \
>> +                               | BR_PS_16      /* 16 bit port */ \
>> +                               | BR_MS_GPCM    /* MSEL = GPCM */ \
>> +                               | BR_V)         /* valid */
>> +#define CONFIG_SYS_OR2_PRELIM  (MEG_TO_AM(CONFIG_SYS_FPGA1_SIZE) \
>> +                               | OR_UPM_XAM \
>> +                               | OR_GPCM_CSNT \
>> +                               | OR_GPCM_SCY_5 \
>> +                               | OR_GPCM_TRLX_CLEAR \
>> +                               | OR_GPCM_EHTR_CLEAR)
>
> Put this config in the DT.
>

The recently resurrected MPC8xx has converted this to Kconfig; see 53193a4
("powerpc, 8xx: Add support for MCR3000 board from CSSI"). It's set in
arch/powerpc/cpu/mpc8xxx/fsl_lbc.c, so I'm pretty sure that it could be moved
to the DT as well. So, where should I put it? Rather in the DT, or in Kconfig
option(s)? I would prefer DT myself, since we can retain at least some of the
semantics that are embedded in the macro defines, whereas in Kconfig it's just
the final value of the option, which has to be decoded manually to be
understood.

>> +
>> +#define CONFIG_SYS_FPGA_COUNT          2
>
> Should not be needed with DT.
>

Yeah, that's a leftover value from an older version, sorry. Will be removed in
v2.

>> +
>> +#define CONFIG_SYS_FPGA_PTR { \
>> +       (struct ihs_fpga *)CONFIG_SYS_FPGA0_BASE, \
>> +       (struct ihs_fpga *)CONFIG_SYS_FPGA1_BASE }
>
> Get base address from DT.
>

Dito, from older version.

>> +
>> +#define CONFIG_SYS_FPGA_NO_RFL_HI
>> +
>> +#define CONFIG_SYS_BAUDRATE_TABLE  \
>> +       {300, 600, 1200, 2400, 4800, 9600, 19200, 38400, 57600, 115200}
>> +
>> +#define CONFIG_SYS_ICS8N3QV01_I2C              { 3, 6, 4, 7 }
>> +
>> +/*
>> + * General PCI
>> + * Addresses are mapped 1-1.
>> + */
>> +#define CONFIG_SYS_PCIE1_BASE          0xA0000000
>> +#define CONFIG_SYS_PCIE1_MEM_BASE      0xA0000000
>> +#define CONFIG_SYS_PCIE1_MEM_PHYS      0xA0000000
>> +#define CONFIG_SYS_PCIE1_MEM_SIZE      0x10000000
>> +#define CONFIG_SYS_PCIE1_CFG_BASE      0xB0000000
>> +#define CONFIG_SYS_PCIE1_CFG_SIZE      0x01000000
>> +#define CONFIG_SYS_PCIE1_IO_BASE       0x00000000
>> +#define CONFIG_SYS_PCIE1_IO_PHYS       0xB1000000
>> +#define CONFIG_SYS_PCIE1_IO_SIZE       0x00800000
>
> PCI driver for DM?
>

I'll look into it for v2.

>> +
>> +/* enable PCIE clock */
>> +#define CONFIG_SYS_SCCR_PCIEXP1CM      1
>> +
>> +#define CONFIG_PCI_INDIRECT_BRIDGE
>> +#define CONFIG_PCIE
>> +
>> +#define CONFIG_SYS_PCI_SUBSYS_VENDORID 0x1957  /* Freescale */
>> +#define CONFIG_83XX_GENERIC_PCIE_REGISTER_HOSES 1
>> +
>> +/*
>> + * TSEC
>> + */
>> +#define CONFIG_TSEC_ENET       /* TSEC ethernet support */
>> +#define CONFIG_SYS_TSEC1_OFFSET        0x24000
>> +#define CONFIG_SYS_TSEC1       (CONFIG_SYS_IMMR+CONFIG_SYS_TSEC1_OFFSET)
>> +#define CONFIG_SYS_TSEC2_OFFSET        0x25000
>> +#define CONFIG_SYS_TSEC2       (CONFIG_SYS_IMMR+CONFIG_SYS_TSEC2_OFFSET)
>> +
>> +/*
>> + * TSEC ethernet configuration
>> + */
>> +#define CONFIG_MII             1 /* MII PHY management */
>> +
>> +#define CONFIG_TSEC1
>> +#define CONFIG_TSEC1_NAME      "eTSEC0"
>> +#define TSEC1_PHY_ADDR         1
>> +#define TSEC1_PHYIDX           0
>> +#define TSEC1_FLAGS            TSEC_GIGABIT
>> +
>> +#define CONFIG_TSEC2
>> +#define CONFIG_TSEC2_NAME      "eTSEC1"
>> +#define TSEC2_PHY_ADDR         0
>> +#define TSEC2_PHYIDX           0
>> +#define TSEC2_FLAGS            TSEC_GIGABIT
>> +
>> +/* Options are: eTSEC[0-1] */
>> +#define CONFIG_ETHPRIME                "eTSEC0"
>
> In general we should try to have CONFIGs which enable features, and
> use the device tree for config values used by drivers.
>

Incidentially, I very recently found out that the tsec driver was already
converted to DM, but it didn't work on the board when I tried it out. I'll have
to look into it a bit more for v2.

>> +
>> +/*
>> + * Environment
>> + */
>> +#if 1
>> +#define CONFIG_ENV_IS_IN_FLASH 1
>> +#define CONFIG_ENV_ADDR                (CONFIG_SYS_MONITOR_BASE + \
>> +                                CONFIG_SYS_MONITOR_LEN)
>> +#define CONFIG_ENV_SECT_SIZE   0x10000 /* 64K(one sector) for env */
>> +#define CONFIG_ENV_SIZE                0x2000
>> +#define CONFIG_ENV_ADDR_REDUND (CONFIG_ENV_ADDR + CONFIG_ENV_SECT_SIZE)
>> +#define CONFIG_ENV_SIZE_REDUND CONFIG_ENV_SIZE
>> +#else
>> +#define CONFIG_ENV_IS_NOWHERE
>> +#define CONFIG_ENV_SIZE                0x2000          /* 8KB */
>> +#endif
>> +
>> +#define CONFIG_LOADS_ECHO      1       /* echo on for serial download */
>> +#define CONFIG_SYS_LOADS_BAUD_CHANGE   1       /* allow baudrate change */
>> +
>> +/*
>> + * Command line configuration.
>> + */
>> +#define CONFIG_CMD_PCI
>> +
>> +#define CONFIG_CMDLINE_EDITING 1       /* add command line history */
>
> Drop '1' on the end of these.
>

OK. Another ancient copied/pasted thing, since it's in almost every other
MPC83xx config as well.

>> +#define CONFIG_AUTO_COMPLETE           /* add autocompletion support */
>> +
>> +/*
>> + * Miscellaneous configurable options
>> + */
>> +#define CONFIG_SYS_LONGHELP            /* undef to save memory */
>> +#define CONFIG_SYS_LOAD_ADDR           0x2000000 /* default load address */
>> +#define CONFIG_SYS_HZ          1000    /* decrementer freq: 1ms ticks */
>> +
>> +#define CONFIG_SYS_CBSIZE      1024 /* Console I/O Buffer Size */
>> +
>> +/* Print Buffer Size */
>> +#define CONFIG_SYS_PBSIZE (CONFIG_SYS_CBSIZE + sizeof(CONFIG_SYS_PROMPT) + 16)
>> +#define CONFIG_SYS_MAXARGS     16      /* max number of command args */
>> +#define CONFIG_SYS_BARGSIZE    CONFIG_SYS_CBSIZE
>> +
>> +/*
>> + * For booting Linux, the board info and command line data
>> + * have to be in the first 256 MB of memory, since this is
>> + * the maximum mapped by the Linux kernel during initialization.
>> + */
>> +#define CONFIG_SYS_BOOTMAPSZ   (256 << 20) /* Initial Memory map for Linux */
>> +
>> +/*
>> + * Core HID Setup
>> + */
>> +#define CONFIG_SYS_HID0_INIT   0x000000000
>> +#define CONFIG_SYS_HID0_FINAL  (HID0_ENABLE_MACHINE_CHECK | \
>> +                                HID0_ENABLE_INSTRUCTION_CACHE | \
>> +                                HID0_ENABLE_DYNAMIC_POWER_MANAGMENT)
>> +#define CONFIG_SYS_HID2                HID2_HBE
>> +
>> +/*
>> + * MMU Setup
>> + */
>> +
>> +/* DDR: cache cacheable */
>> +#define CONFIG_SYS_IBAT0L      (CONFIG_SYS_SDRAM_BASE | BATL_PP_RW | \
>> +                                       BATL_MEMCOHERENCE)
>> +#define CONFIG_SYS_IBAT0U      (CONFIG_SYS_SDRAM_BASE | BATU_BL_128M | \
>> +                                       BATU_VS | BATU_VP)
>> +#define CONFIG_SYS_DBAT0L      CONFIG_SYS_IBAT0L
>> +#define CONFIG_SYS_DBAT0U      CONFIG_SYS_IBAT0U
>> +
>> +/* IMMRBAR, PCI IO and FPGA: cache-inhibit and guarded */
>> +#define CONFIG_SYS_IBAT1L      (CONFIG_SYS_IMMR | BATL_PP_RW | \
>> +                       BATL_CACHEINHIBIT | BATL_GUARDEDSTORAGE)
>> +#define CONFIG_SYS_IBAT1U      (CONFIG_SYS_IMMR | BATU_BL_8M | BATU_VS | \
>> +                                       BATU_VP)
>> +#define CONFIG_SYS_DBAT1L      CONFIG_SYS_IBAT1L
>> +#define CONFIG_SYS_DBAT1U      CONFIG_SYS_IBAT1U
>> +
>> +/* FLASH: icache cacheable, but dcache-inhibit and guarded */
>> +#define CONFIG_SYS_IBAT2L      (CONFIG_SYS_FLASH_BASE | BATL_PP_RW | \
>> +                                       BATL_CACHEINHIBIT | \
>> +                                       BATL_GUARDEDSTORAGE)
>> +#define CONFIG_SYS_IBAT2U      (CONFIG_SYS_FLASH_BASE | BATU_BL_8M | \
>> +                                       BATU_VS | BATU_VP)
>> +#define CONFIG_SYS_DBAT2L      (CONFIG_SYS_FLASH_BASE | BATL_PP_RW | \
>> +                                       BATL_CACHEINHIBIT | \
>> +                                       BATL_GUARDEDSTORAGE)
>> +#define CONFIG_SYS_DBAT2U      CONFIG_SYS_IBAT2U
>> +
>> +/* Stack in dcache: cacheable, no memory coherence */
>> +#define CONFIG_SYS_IBAT3L      (CONFIG_SYS_INIT_RAM_ADDR | BATL_PP_RW)
>> +#define CONFIG_SYS_IBAT3U      (CONFIG_SYS_INIT_RAM_ADDR | BATU_BL_128K | \
>> +                                       BATU_VS | BATU_VP)
>> +#define CONFIG_SYS_DBAT3L      CONFIG_SYS_IBAT3L
>> +#define CONFIG_SYS_DBAT3U      CONFIG_SYS_IBAT3U
>> +
>> +/*
>> + * Environment Configuration
>> + */
>> +
>> +#define CONFIG_ENV_OVERWRITE
>> +
>> +#if defined(CONFIG_TSEC_ENET)
>> +#define CONFIG_HAS_ETH0
>> +#endif
>> +
>> +#define CONFIG_LOADADDR        800000  /* default location for tftp and bootm */
>> +
>> +#define CONFIG_HOSTNAME                hrcon
>> +#define CONFIG_ROOTPATH                "/opt/nfsroot"
>> +#define CONFIG_BOOTFILE                "uImage"
>> +
>> +#define CONFIG_PREBOOT         /* enable preboot variable */
>> +
>> +#define        CONFIG_EXTRA_ENV_SETTINGS                                       \
>> +       "netdev=eth0\0"                                                 \
>> +       "consoledev=ttyS1\0"                                            \
>> +       "u-boot=u-boot.bin\0"                                           \
>> +       "kernel_addr=1000000\0"                                 \
>> +       "fdt_addr=C00000\0"                                             \
>> +       "fdtfile=hrcon.dtb\0"                           \
>> +       "load=tftp ${loadaddr} ${u-boot}\0"                             \
>> +       "update=protect off " __stringify(CONFIG_SYS_MONITOR_BASE)      \
>> +               " +${filesize};era " __stringify(CONFIG_SYS_MONITOR_BASE)\
>> +               " +${filesize};cp.b ${fileaddr} "                       \
>> +               __stringify(CONFIG_SYS_MONITOR_BASE) " ${filesize}\0"   \
>> +       "upd=run load update\0"                                         \
>> +
>> +#define CONFIG_NFSBOOTCOMMAND                                          \
>> +       "setenv bootargs root=/dev/nfs rw "                             \
>> +       "nfsroot=$serverip:$rootpath "                                  \
>> +       "ip=$ipaddr:$serverip:$gatewayip:$netmask:$hostname:$netdev:off " \
>> +       "console=$consoledev,$baudrate $othbootargs;"                   \
>> +       "tftp ${kernel_addr} $bootfile;"                                \
>> +       "tftp ${fdt_addr} $fdtfile;"                                    \
>> +       "bootm ${kernel_addr} - ${fdt_addr}"
>> +
>> +#define CONFIG_MMCBOOTCOMMAND                                          \
>> +       "setenv bootargs root=/dev/mmcblk0p3 rw rootwait "              \
>> +       "console=$consoledev,$baudrate $othbootargs;"                   \
>> +       "ext2load mmc 0:2 ${kernel_addr} $bootfile;"                    \
>> +       "ext2load mmc 0:2 ${fdt_addr} $fdtfile;"                        \
>> +       "bootm ${kernel_addr} - ${fdt_addr}"
>> +
>> +#define CONFIG_BOOTCOMMAND             CONFIG_MMCBOOTCOMMAND
>> +
>> +#endif /* __CONFIG_H */
>> diff --git a/include/fdt_fixup.h b/include/fdt_fixup.h
>> index 9390f0a633..f67685a789 100644
>> --- a/include/fdt_fixup.h
>> +++ b/include/fdt_fixup.h
>
> Hoping to drop this file.
>

Probably doable.

>> @@ -1,4 +1,9 @@
>>  struct of_board_fixup_data {
>> +#ifdef CONFIG_TARGET_GAZERBEAM
>> +       bool var_con;
>> +       bool mc4;
>> +       bool mc2;
>> +#endif
>>  #ifdef CONFIG_TARGET_CONTROLCENTERDC
>>         bool chip_exists[6];
>>  #endif
>> --
>> 2.11.0
>>
>
> Regards,
> Simon

Thank you very much for reviewing the series! It'll probably take a bit until
v2 is ready (there's quite a bit to do).

Best regards,

Mario

^ permalink raw reply	[flat|nested] 138+ messages in thread

* [U-Boot] [PATCH 05/51] net: phy: marvell 88e151x: Fix handling of bare RGMII interface type
  2017-07-14 12:54 ` [U-Boot] [PATCH 05/51] net: phy: marvell 88e151x: Fix handling of bare RGMII interface type Mario Six
  2017-07-18 14:01   ` Simon Glass
@ 2017-07-27 16:55   ` Joe Hershberger
  1 sibling, 0 replies; 138+ messages in thread
From: Joe Hershberger @ 2017-07-27 16:55 UTC (permalink / raw)
  To: u-boot

On Fri, Jul 14, 2017 at 7:54 AM, Mario Six <mario.six@gdsys.cc> wrote:
> Commit 68e6eca ("net: phy: marvell 88e151x: Fix handling of RGMII
> interface types") fixed the initialization of 88e151x phys, but made it
> so that interfaces of type PHY_INTERFACE_MODE_RGMII had both RX and TX
> delay bits cleared. The default (like in m88e1111s_config) is to have
> both bits set.
>
> Hence, this patch changes the behavior in the PHY_INTERFACE_MODE_RGMII
> case so that both bits are set.
>
> Signed-off-by: Mario Six <mario.six@gdsys.cc>

Acked-by: Joe Hershberger <joe.hershberger@gmail.com>

^ permalink raw reply	[flat|nested] 138+ messages in thread

* [U-Boot] [PATCH 09/51] phy: Support Marvell 88X2242
  2017-07-25  8:22     ` Mario Six
@ 2017-07-27 21:23       ` Joe Hershberger
  2017-08-06  5:16         ` Simon Glass
  0 siblings, 1 reply; 138+ messages in thread
From: Joe Hershberger @ 2017-07-27 21:23 UTC (permalink / raw)
  To: u-boot

On Tue, Jul 25, 2017 at 3:22 AM, Mario Six <mario.six@gdsys.cc> wrote:
> Hi Simon,
>
> On Tue, Jul 18, 2017 at 4:01 PM, Simon Glass <sjg@chromium.org> wrote:
>> Hi Mario,
>>
>> On 14 July 2017 at 05:54, Mario Six <mario.six@gdsys.cc> wrote:
>>> From: Dirk Eibach <dirk.eibach@gdsys.cc>
>>>
>>> Implement support for the Marvell Alaska X 88X2242P Integrated Dual-port
>>> and Quad-port Multi-speed Ethernet Transceivers.
>>>
>>> Signed-off-by: Dirk Eibach <dirk.eibach@gdsys.cc>
>>> Signed-off-by: Mario Six <mario.six@gdsys.cc>
>>> ---
>>>
>>>  drivers/net/phy/Kconfig   |  67 ++++
>>>  drivers/net/phy/Makefile  |   1 +
>>>  drivers/net/phy/marvell.c |   1 -
>>>  drivers/net/phy/mv88x2.c  | 846 ++++++++++++++++++++++++++++++++++++++++++++++
>>>  drivers/net/phy/mv88x2.h  |  12 +
>>>  drivers/net/phy/phy.c     |   3 +
>>>  include/phy.h             |   1 +
>>>  7 files changed, 930 insertions(+), 1 deletion(-)
>>>  create mode 100644 drivers/net/phy/mv88x2.c
>>>  create mode 100644 drivers/net/phy/mv88x2.h
>>>
>>
>> We should really be using driver model here. Is the generic phy uclass
>> good enough (generic-phy.h), or do we need a new uclass for Ethernet
>> PHY?
>>
>
> Wouldn't we also need a uclass for MDIO/MII interfaces then? I don't know the
> network subsystem too well, so I can't really tell where a ethernet phy uclass
> (or a MDIO uclass for that matter) would interface with the rest of it.

The reason I've avoided implementing the uclass for phys so far is
that the DTs of various boards are quite different in how they relate
MDIO, PHY, and ETH. I suspect we'll end up needing some sort of ETH /
platform / board specific DT parsing code and some way to hook into
that.

I don't think the generic-phy is appropriate. Quite unrelated to Ethernet phys.

>
>> Regards,
>> Simon
>
> Best regards,
>
> Mario
> _______________________________________________
> U-Boot mailing list
> U-Boot at lists.denx.de
> https://lists.denx.de/listinfo/u-boot

^ permalink raw reply	[flat|nested] 138+ messages in thread

* [U-Boot] [PATCH 04/51] net: phy: marvell: Fix style violations
  2017-07-14 12:54 ` [U-Boot] [PATCH 04/51] net: phy: marvell: Fix style violations Mario Six
  2017-07-18 14:01   ` Simon Glass
@ 2017-07-27 22:15   ` Joe Hershberger
  1 sibling, 0 replies; 138+ messages in thread
From: Joe Hershberger @ 2017-07-27 22:15 UTC (permalink / raw)
  To: u-boot

On Fri, Jul 14, 2017 at 7:54 AM, Mario Six <mario.six@gdsys.cc> wrote:
> Fix some style violations in the Marvell PHY driver.
>
> Signed-off-by: Mario Six <mario.six@gdsys.cc>

Acked-by: Joe Hershberger <joe.hershberger@ni.com>

^ permalink raw reply	[flat|nested] 138+ messages in thread

* [U-Boot] [PATCH 51/51] mpc83xx: Add gazerbeam board
  2017-07-26  8:24     ` Mario Six
@ 2017-08-04  9:34       ` Simon Glass
  0 siblings, 0 replies; 138+ messages in thread
From: Simon Glass @ 2017-08-04  9:34 UTC (permalink / raw)
  To: u-boot

Hi Mario,

On 26 July 2017 at 02:24, Mario Six <mario.six@gdsys.cc> wrote:
> Hi Simon,
>
> On Wed, Jul 19, 2017 at 11:07 AM, Simon Glass <sjg@chromium.org> wrote:
>> Hi Mario,
>>
>> On 14 July 2017 at 05:55, Mario Six <mario.six@gdsys.cc> wrote:
>>> From: Dirk Eibach <dirk.eibach@gdsys.cc>
>>>
>>> The gdsys gazerbeam board is based on a Freescale MPC8308 SOC.
>>> It boots from NOR-Flash, kernel and rootfs are stored on
>>> SD-Card.
>>>
>>> On board peripherals include:
>>> - 2x 10/100 Mbit/s Ethernet (optional)
>>>
>>> Signed-off-by: Dirk Eibach <dirk.eibach@gdsys.cc>
>>> Signed-off-by: Mario Six <mario.six@gdsys.cc>
>>> ---
>>>
>>>  arch/powerpc/cpu/mpc83xx/Kconfig |   3 +
>>>  arch/powerpc/dts/.gitignore      |   1 +
>>>  arch/powerpc/dts/Makefile        |  15 +
>>>  board/gdsys/common/Makefile      |   1 +
>>>  board/gdsys/common/ioep-fpga.c   | 617 ++++++++++++++++++++++++++++++---------
>>>  board/gdsys/mpc8308/Kconfig      |  19 ++
>>>  board/gdsys/mpc8308/MAINTAINERS  |   2 +
>>>  board/gdsys/mpc8308/Makefile     |   1 +
>>>  board/gdsys/mpc8308/gazerbeam.c  | 332 +++++++++++++++++++++
>>>  configs/gazerbeam_defconfig      |  76 +++++
>>>  include/configs/gazerbeam.h      | 484 ++++++++++++++++++++++++++++++
>>>  include/fdt_fixup.h              |   5 +
>>>  12 files changed, 1416 insertions(+), 140 deletions(-)
>>>  create mode 100644 arch/powerpc/dts/.gitignore
>>>  create mode 100644 arch/powerpc/dts/Makefile
>>>  create mode 100644 board/gdsys/mpc8308/gazerbeam.c
>>>  create mode 100644 configs/gazerbeam_defconfig
>>>  create mode 100644 include/configs/gazerbeam.h

[..]

>>> +
>>> +       if (!data->mc4) {
>>> +               if (!request_gpio_by_dev(&gpio, gpio_dev, 0, "var-mc_sc"))
>>
>> Can you have this GPIO in the device tree so you can use
>> gpio_request_by_name() from a driver? What is this GPIO for?
>>
>
> That's a bit of a problem. That GPIO determines whether the board is a
> single-channel variant or a multi-channel variant. So it doesn't really
> "belong" to any device at all; it's a property of the board itself.
>
> Introducing some kind of "variant driver" with a matching node in the DT would
> probably work, but I don't know if the concept is generic enough to warrant
> something like that (it would need another new uclass, probably).
>
> The nicest thing would probably be a "board driver" that describes properties
> of the board itself (this GPIO could then be a property of the board). This
> would also be a possible way to do away with board files completely: Every
> board that needs board-specific initialization implements a board driver with
> the current callback functions board_early_init_{r,f}, last_stage_init etc. as
> driver functions as needed. Those are called from board_{f,r}.c via
> board-uclass.c, and we don't need board files anymore. But, that's probably a
> bit too far fetched.

That makes a lot of sense to me.I did actually send a series with
something like this:

https://lists.denx.de/pipermail/u-boot/2017-March/284087.html

But it was more focussed on init, and I may revisit that another time.

For what you want I think a new uclass would be nice. The question is
what operations it should support. I suppose one would be something
like detect(struct udevice *) to figure out the board type. Perhaps
then it could provide a set of properties which can be queried? Each
could have an index and a name and the uclass could provide a way to
obtain the value of each property (perhaps support bool, int, string?)

Then for drivers which need to obtain a property, they can make an
appropriate uclass call.

Another option would be to mangle the device tree just before
relocation, changing compatible strings or adding/changing properties
for drivers, based on the board detectoin stuff. I suppose these two
things are not mutually exclusive.

[..]

>>> +
>>> +       if (tpm_init() || tpm_startup(TPM_ST_CLEAR) ||
>>> +           tpm_continue_self_test()) {
>>> +               printf("TPM init failed\n");
>>> +       }
>>> +
>>> +       if (fpga_hw_rev >= 4) {
>>> +               for (uclass_find_first_device(UCLASS_RXAUI_CTRL, &rxaui);
>>> +                    rxaui;
>>> +                    uclass_find_next_device(&rxaui)) {
>>> +                       rxaui_disable_polarity_inversion(rxaui);
>>> +               }
>>> +       }
>>> +
>>> +       for (uclass_find_first_device(UCLASS_IHS_FPGA, &fpga);
>>> +            fpga;
>>> +            uclass_find_next_device(&fpga)) {
>>
>> Can you use uclass_first_next_device() since it does the probing for you.
>>
>
> OK, will fix in v2.
>
>>> +               struct mii_dev *bus;
>>> +
>>> +               device_probe(fpga);
>>> +
>>> +               if (fpga->seq < 0)
>>> +                       continue;
>>
>> What is this checking for?
>>
>
> The phy initialization below should only run for the first FPGA, so we skip it
> for all others.
>

So perhaps just do uclass_get_device_by_seq(UCLASS_FPGA, 0)?


[..]

>>> +/*
>>> + * Hardware Reset Configuration Word
>>> + * if CLKIN is 66.66MHz, then
>>> + * CSB = 133MHz, DDRC = 266MHz, LBC = 133MHz
>>> + * We choose the A type silicon as default, so the core is 400Mhz.
>>> + */
>>> +#define CONFIG_SYS_HRCW_LOW (\
>>> +       HRCWL_LCL_BUS_TO_SCB_CLK_1X1 |\
>>> +       HRCWL_DDR_TO_SCB_CLK_2X1 |\
>>> +       HRCWL_SVCOD_DIV_2 |\
>>> +       HRCWL_CSB_TO_CLKIN_4X1 |\
>>> +       HRCWL_CORE_TO_CSB_3X1)
>>
>> Seems like this should be in the DT instead of a CONFIG. TBD for later?
>>
>
> The HRCW (Hard Reset Configuration Word) has to be hard-coded in the image at a
> specific position, since the SoC reads it when it starts up, and configures
> itself according to it. So it could be moved to Kconfig, but not to DT, I'm
> afraid.

OK I see.

[..]

>>> +#define CONFIG_SYS_DDR_TIMING_1        ((2 << TIMING_CFG1_PRETOACT_SHIFT) \
>>> +                               | (6 << TIMING_CFG1_ACTTOPRE_SHIFT) \
>>> +                               | (2 << TIMING_CFG1_ACTTORW_SHIFT) \
>>> +                               | (7 << TIMING_CFG1_CASLAT_SHIFT) \
>>> +                               | (9 << TIMING_CFG1_REFREC_SHIFT) \
>>> +                               | (2 << TIMING_CFG1_WRREC_SHIFT) \
>>> +                               | (2 << TIMING_CFG1_ACTTOACT_SHIFT) \
>>> +                               | (2 << TIMING_CFG1_WRTORD_SHIFT))
>>> +                               /* 0x26279222 */
>>> +#define CONFIG_SYS_DDR_TIMING_2        ((0 << TIMING_CFG2_ADD_LAT_SHIFT) \
>>> +                               | (4 << TIMING_CFG2_CPO_SHIFT) \
>>> +                               | (3 << TIMING_CFG2_WR_LAT_DELAY_SHIFT) \
>>> +                               | (2 << TIMING_CFG2_RD_TO_PRE_SHIFT) \
>>> +                               | (2 << TIMING_CFG2_WR_DATA_DELAY_SHIFT) \
>>> +                               | (3 << TIMING_CFG2_CKE_PLS_SHIFT) \
>>> +                               | (5 << TIMING_CFG2_FOUR_ACT_SHIFT))
>>> +                               /* 0x021848c5 */
>>> +#define CONFIG_SYS_DDR_INTERVAL        ((0x0824 << SDRAM_INTERVAL_REFINT_SHIFT) \
>>> +                               | (0x0100 << SDRAM_INTERVAL_BSTOPRE_SHIFT))
>>> +                               /* 0x08240100 */
>>> +#define CONFIG_SYS_DDR_SDRAM_CFG       (SDRAM_CFG_SREN \
>>> +                               | SDRAM_CFG_SDRAM_TYPE_DDR2 \
>>> +                               | SDRAM_CFG_DBW_16)
>>> +                               /* 0x43100000 */
>>> +
>>> +#define CONFIG_SYS_DDR_SDRAM_CFG2      0x00401000 /* 1 posted refresh */
>>> +#define CONFIG_SYS_DDR_MODE            ((0x0440 << SDRAM_MODE_ESD_SHIFT) \
>>> +                               | (0x0242 << SDRAM_MODE_SD_SHIFT))
>>> +                               /* ODT 150ohm CL=4, AL=0 on SDRAM */
>>> +#define CONFIG_SYS_DDR_MODE2           0x00000000
>>
>> I think this should all be a UCLASS_RAM driver with DT configuration.
>> Too many CONFIGs :-)
>>
>
> Yeah, it's not really nice, that's true. I'll look into it. I was planning on
> taking on MPC83xx DM conversion anyway, so I might as well combine it with the
> Gazerbeam series while I'm at it.
>

Sounds good

[..[

>>> +
>>> +#define CONFIG_SYS_FLASH_ERASE_TOUT    60000 /* Flash Erase Timeout (ms) */
>>> +#define CONFIG_SYS_FLASH_WRITE_TOUT    500 /* Flash Write Timeout (ms) */
>>> +
>>> +/* Window base at FPGA base */
>>> +#define CONFIG_SYS_LBLAWBAR1_PRELIM    CONFIG_SYS_FPGA0_BASE
>>> +#define CONFIG_SYS_LBLAWAR1_PRELIM     (LBLAWAR_EN | LBLAWAR_1MB)
>>> +#define CONFIG_SYS_LBLAWBAR2_PRELIM    CONFIG_SYS_FPGA1_BASE
>>> +#define CONFIG_SYS_LBLAWAR2_PRELIM     (LBLAWAR_EN | LBLAWAR_1MB)
>>> +
>>> +#define CONFIG_SYS_BR1_PRELIM  (CONFIG_SYS_FPGA0_BASE \
>>> +                               | BR_PS_16      /* 16 bit port */ \
>>> +                               | BR_MS_GPCM    /* MSEL = GPCM */ \
>>> +                               | BR_V)         /* valid */
>>> +#define CONFIG_SYS_OR1_PRELIM   (MEG_TO_AM(CONFIG_SYS_FPGA0_SIZE) \
>>> +                               | OR_UPM_XAM \
>>> +                               | OR_GPCM_CSNT \
>>> +                               | OR_GPCM_SCY_5 \
>>> +                               | OR_GPCM_TRLX_CLEAR \
>>> +                               | OR_GPCM_EHTR_CLEAR)
>>> +
>>> +#define CONFIG_SYS_BR2_PRELIM  (CONFIG_SYS_FPGA1_BASE \
>>> +                               | BR_PS_16      /* 16 bit port */ \
>>> +                               | BR_MS_GPCM    /* MSEL = GPCM */ \
>>> +                               | BR_V)         /* valid */
>>> +#define CONFIG_SYS_OR2_PRELIM  (MEG_TO_AM(CONFIG_SYS_FPGA1_SIZE) \
>>> +                               | OR_UPM_XAM \
>>> +                               | OR_GPCM_CSNT \
>>> +                               | OR_GPCM_SCY_5 \
>>> +                               | OR_GPCM_TRLX_CLEAR \
>>> +                               | OR_GPCM_EHTR_CLEAR)
>>
>> Put this config in the DT.
>>
>
> The recently resurrected MPC8xx has converted this to Kconfig; see 53193a4
> ("powerpc, 8xx: Add support for MCR3000 board from CSSI"). It's set in
> arch/powerpc/cpu/mpc8xxx/fsl_lbc.c, so I'm pretty sure that it could be moved
> to the DT as well. So, where should I put it? Rather in the DT, or in Kconfig
> option(s)? I would prefer DT myself, since we can retain at least some of the
> semantics that are embedded in the macro defines, whereas in Kconfig it's just
> the final value of the option, which has to be decoded manually to be
> understood.
>

I think CONFIG should be used for enabling features / options (mostly
at compile time) and DT should be used for configuring those features.
We have too many CONFIG options.


>>> +
>>> +#define CONFIG_CMDLINE_EDITING 1       /* add command line history */
>>
>> Drop '1' on the end of these.
>>
>
> OK. Another ancient copied/pasted thing, since it's in almost every other
> MPC83xx config as well.

Yes I see that. The convention changed at some point.


>
>>> @@ -1,4 +1,9 @@
>>>  struct of_board_fixup_data {
>>> +#ifdef CONFIG_TARGET_GAZERBEAM
>>> +       bool var_con;
>>> +       bool mc4;
>>> +       bool mc2;
>>> +#endif
>>>  #ifdef CONFIG_TARGET_CONTROLCENTERDC
>>>         bool chip_exists[6];
>>>  #endif
>>> --
>>> 2.11.0
>>>
>>
>> Regards,
>> Simon
>
> Thank you very much for reviewing the series! It'll probably take a bit until
> v2 is ready (there's quite a bit to do).

Yes, a lot to do, but very important.

Regards,
Simon

^ permalink raw reply	[flat|nested] 138+ messages in thread

* [U-Boot] [PATCH 09/51] phy: Support Marvell 88X2242
  2017-07-27 21:23       ` Joe Hershberger
@ 2017-08-06  5:16         ` Simon Glass
  2017-08-07 16:37           ` Joe Hershberger
  0 siblings, 1 reply; 138+ messages in thread
From: Simon Glass @ 2017-08-06  5:16 UTC (permalink / raw)
  To: u-boot

Hi Joe,

On 27 July 2017 at 15:23, Joe Hershberger <joe.hershberger@ni.com> wrote:
> On Tue, Jul 25, 2017 at 3:22 AM, Mario Six <mario.six@gdsys.cc> wrote:
>> Hi Simon,
>>
>> On Tue, Jul 18, 2017 at 4:01 PM, Simon Glass <sjg@chromium.org> wrote:
>>> Hi Mario,
>>>
>>> On 14 July 2017 at 05:54, Mario Six <mario.six@gdsys.cc> wrote:
>>>> From: Dirk Eibach <dirk.eibach@gdsys.cc>
>>>>
>>>> Implement support for the Marvell Alaska X 88X2242P Integrated Dual-port
>>>> and Quad-port Multi-speed Ethernet Transceivers.
>>>>
>>>> Signed-off-by: Dirk Eibach <dirk.eibach@gdsys.cc>
>>>> Signed-off-by: Mario Six <mario.six@gdsys.cc>
>>>> ---
>>>>
>>>>  drivers/net/phy/Kconfig   |  67 ++++
>>>>  drivers/net/phy/Makefile  |   1 +
>>>>  drivers/net/phy/marvell.c |   1 -
>>>>  drivers/net/phy/mv88x2.c  | 846 ++++++++++++++++++++++++++++++++++++++++++++++
>>>>  drivers/net/phy/mv88x2.h  |  12 +
>>>>  drivers/net/phy/phy.c     |   3 +
>>>>  include/phy.h             |   1 +
>>>>  7 files changed, 930 insertions(+), 1 deletion(-)
>>>>  create mode 100644 drivers/net/phy/mv88x2.c
>>>>  create mode 100644 drivers/net/phy/mv88x2.h
>>>>
>>>
>>> We should really be using driver model here. Is the generic phy uclass
>>> good enough (generic-phy.h), or do we need a new uclass for Ethernet
>>> PHY?
>>>
>>
>> Wouldn't we also need a uclass for MDIO/MII interfaces then? I don't know the
>> network subsystem too well, so I can't really tell where a ethernet phy uclass
>> (or a MDIO uclass for that matter) would interface with the rest of it.
>
> The reason I've avoided implementing the uclass for phys so far is
> that the DTs of various boards are quite different in how they relate
> MDIO, PHY, and ETH. I suspect we'll end up needing some sort of ETH /
> platform / board specific DT parsing code and some way to hook into
> that.
>

Do you mean that we cannot have plain PHY driver (e.g. for MII) that
works with multiple bords? Don't we have something similar already?
What can we do to move this forward.

Regards,
Simon

^ permalink raw reply	[flat|nested] 138+ messages in thread

* [U-Boot] [PATCH 09/51] phy: Support Marvell 88X2242
  2017-08-06  5:16         ` Simon Glass
@ 2017-08-07 16:37           ` Joe Hershberger
  2017-08-13 21:35             ` Simon Glass
  0 siblings, 1 reply; 138+ messages in thread
From: Joe Hershberger @ 2017-08-07 16:37 UTC (permalink / raw)
  To: u-boot

On Sun, Aug 6, 2017 at 12:16 AM, Simon Glass <sjg@chromium.org> wrote:
> Hi Joe,
>
> On 27 July 2017 at 15:23, Joe Hershberger <joe.hershberger@ni.com> wrote:
>> On Tue, Jul 25, 2017 at 3:22 AM, Mario Six <mario.six@gdsys.cc> wrote:
>>> Hi Simon,
>>>
>>> On Tue, Jul 18, 2017 at 4:01 PM, Simon Glass <sjg@chromium.org> wrote:
>>>> Hi Mario,
>>>>
>>>> On 14 July 2017 at 05:54, Mario Six <mario.six@gdsys.cc> wrote:
>>>>> From: Dirk Eibach <dirk.eibach@gdsys.cc>
>>>>>
>>>>> Implement support for the Marvell Alaska X 88X2242P Integrated Dual-port
>>>>> and Quad-port Multi-speed Ethernet Transceivers.
>>>>>
>>>>> Signed-off-by: Dirk Eibach <dirk.eibach@gdsys.cc>
>>>>> Signed-off-by: Mario Six <mario.six@gdsys.cc>
>>>>> ---
>>>>>
>>>>>  drivers/net/phy/Kconfig   |  67 ++++
>>>>>  drivers/net/phy/Makefile  |   1 +
>>>>>  drivers/net/phy/marvell.c |   1 -
>>>>>  drivers/net/phy/mv88x2.c  | 846 ++++++++++++++++++++++++++++++++++++++++++++++
>>>>>  drivers/net/phy/mv88x2.h  |  12 +
>>>>>  drivers/net/phy/phy.c     |   3 +
>>>>>  include/phy.h             |   1 +
>>>>>  7 files changed, 930 insertions(+), 1 deletion(-)
>>>>>  create mode 100644 drivers/net/phy/mv88x2.c
>>>>>  create mode 100644 drivers/net/phy/mv88x2.h
>>>>>
>>>>
>>>> We should really be using driver model here. Is the generic phy uclass
>>>> good enough (generic-phy.h), or do we need a new uclass for Ethernet
>>>> PHY?
>>>>
>>>
>>> Wouldn't we also need a uclass for MDIO/MII interfaces then? I don't know the
>>> network subsystem too well, so I can't really tell where a ethernet phy uclass
>>> (or a MDIO uclass for that matter) would interface with the rest of it.
>>
>> The reason I've avoided implementing the uclass for phys so far is
>> that the DTs of various boards are quite different in how they relate
>> MDIO, PHY, and ETH. I suspect we'll end up needing some sort of ETH /
>> platform / board specific DT parsing code and some way to hook into
>> that.
>>
>
> Do you mean that we cannot have plain PHY driver (e.g. for MII) that
> works with multiple bords? Don't we have something similar already?
> What can we do to move this forward.

I think the driver is not the issue. If we want to be able to leverage
the same DT bindings that Linux does, then it's not going to be
generic. How the MDIO driver is associated to an ETH driver and how
that ETH driver is associated with a PHY driver will all be unique to
each ETH driver. By that I mean the drivers can be shared for the
PHYs, but how they are bound will be unique. We can't have global PHY
binding code in the PHY uclass.

Do we do something like this elsewhere? Maybe in PCI or something? I
haven't gone looking so far.

Cheers,
-Joe

^ permalink raw reply	[flat|nested] 138+ messages in thread

* [U-Boot] [PATCH 09/51] phy: Support Marvell 88X2242
  2017-08-07 16:37           ` Joe Hershberger
@ 2017-08-13 21:35             ` Simon Glass
  0 siblings, 0 replies; 138+ messages in thread
From: Simon Glass @ 2017-08-13 21:35 UTC (permalink / raw)
  To: u-boot

Hi Joe,

On 7 August 2017 at 10:37, Joe Hershberger <joe.hershberger@gmail.com> wrote:
> On Sun, Aug 6, 2017 at 12:16 AM, Simon Glass <sjg@chromium.org> wrote:
>> Hi Joe,
>>
>> On 27 July 2017 at 15:23, Joe Hershberger <joe.hershberger@ni.com> wrote:
>>> On Tue, Jul 25, 2017 at 3:22 AM, Mario Six <mario.six@gdsys.cc> wrote:
>>>> Hi Simon,
>>>>
>>>> On Tue, Jul 18, 2017 at 4:01 PM, Simon Glass <sjg@chromium.org> wrote:
>>>>> Hi Mario,
>>>>>
>>>>> On 14 July 2017 at 05:54, Mario Six <mario.six@gdsys.cc> wrote:
>>>>>> From: Dirk Eibach <dirk.eibach@gdsys.cc>
>>>>>>
>>>>>> Implement support for the Marvell Alaska X 88X2242P Integrated Dual-port
>>>>>> and Quad-port Multi-speed Ethernet Transceivers.
>>>>>>
>>>>>> Signed-off-by: Dirk Eibach <dirk.eibach@gdsys.cc>
>>>>>> Signed-off-by: Mario Six <mario.six@gdsys.cc>
>>>>>> ---
>>>>>>
>>>>>>  drivers/net/phy/Kconfig   |  67 ++++
>>>>>>  drivers/net/phy/Makefile  |   1 +
>>>>>>  drivers/net/phy/marvell.c |   1 -
>>>>>>  drivers/net/phy/mv88x2.c  | 846 ++++++++++++++++++++++++++++++++++++++++++++++
>>>>>>  drivers/net/phy/mv88x2.h  |  12 +
>>>>>>  drivers/net/phy/phy.c     |   3 +
>>>>>>  include/phy.h             |   1 +
>>>>>>  7 files changed, 930 insertions(+), 1 deletion(-)
>>>>>>  create mode 100644 drivers/net/phy/mv88x2.c
>>>>>>  create mode 100644 drivers/net/phy/mv88x2.h
>>>>>>
>>>>>
>>>>> We should really be using driver model here. Is the generic phy uclass
>>>>> good enough (generic-phy.h), or do we need a new uclass for Ethernet
>>>>> PHY?
>>>>>
>>>>
>>>> Wouldn't we also need a uclass for MDIO/MII interfaces then? I don't know the
>>>> network subsystem too well, so I can't really tell where a ethernet phy uclass
>>>> (or a MDIO uclass for that matter) would interface with the rest of it.
>>>
>>> The reason I've avoided implementing the uclass for phys so far is
>>> that the DTs of various boards are quite different in how they relate
>>> MDIO, PHY, and ETH. I suspect we'll end up needing some sort of ETH /
>>> platform / board specific DT parsing code and some way to hook into
>>> that.
>>>
>>
>> Do you mean that we cannot have plain PHY driver (e.g. for MII) that
>> works with multiple bords? Don't we have something similar already?
>> What can we do to move this forward.
>
> I think the driver is not the issue. If we want to be able to leverage
> the same DT bindings that Linux does, then it's not going to be
> generic. How the MDIO driver is associated to an ETH driver and how
> that ETH driver is associated with a PHY driver will all be unique to
> each ETH driver. By that I mean the drivers can be shared for the
> PHYs, but how they are bound will be unique. We can't have global PHY
> binding code in the PHY uclass.
>
> Do we do something like this elsewhere? Maybe in PCI or something? I
> haven't gone looking so far.

Yes. That seems fine to me. We already do that in some other cases
(e.g. USB and PCI devices are detected at run-time and devices bound
accordingly).

How can we get started on this?

>
> Cheers,
> -Joe

Regards,
Simon

^ permalink raw reply	[flat|nested] 138+ messages in thread

end of thread, other threads:[~2017-08-13 21:35 UTC | newest]

Thread overview: 138+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-07-14 12:54 [U-Boot] [PATCH 00/51] gdsys: Add support for Gazerbeam board Mario Six
2017-07-14 12:54 ` [U-Boot] [PATCH 01/51] i2c: fsl_i2c: Fix style violations Mario Six
2017-07-18 14:01   ` Simon Glass
2017-07-14 12:54 ` [U-Boot] [PATCH 02/51] i2c: fsl_i2c: Remove inline declarations Mario Six
2017-07-18 14:01   ` Simon Glass
2017-07-14 12:54 ` [U-Boot] [PATCH 03/51] gdsys: Post ppc4xx removal cleanup Mario Six
2017-07-18 14:01   ` Simon Glass
2017-07-14 12:54 ` [U-Boot] [PATCH 04/51] net: phy: marvell: Fix style violations Mario Six
2017-07-18 14:01   ` Simon Glass
2017-07-27 22:15   ` Joe Hershberger
2017-07-14 12:54 ` [U-Boot] [PATCH 05/51] net: phy: marvell 88e151x: Fix handling of bare RGMII interface type Mario Six
2017-07-18 14:01   ` Simon Glass
2017-07-27 16:55   ` Joe Hershberger
2017-07-14 12:54 ` [U-Boot] [PATCH 06/51] cmd: Add command for calculating binary operations Mario Six
2017-07-18 14:01   ` Simon Glass
2017-07-19  8:53     ` Mario Six
2017-07-19  9:07       ` Simon Glass
2017-07-25  7:28         ` Mario Six
2017-07-14 12:54 ` [U-Boot] [PATCH 07/51] phy: Allow forcing clause 45 access Mario Six
2017-07-18 14:01   ` Simon Glass
2017-07-25  7:30     ` Mario Six
2017-07-14 12:54 ` [U-Boot] [PATCH 08/51] phy: Fix style violations Mario Six
2017-07-18 14:01   ` Simon Glass
2017-07-14 12:54 ` [U-Boot] [PATCH 09/51] phy: Support Marvell 88X2242 Mario Six
2017-07-18 14:01   ` Simon Glass
2017-07-25  8:22     ` Mario Six
2017-07-27 21:23       ` Joe Hershberger
2017-08-06  5:16         ` Simon Glass
2017-08-07 16:37           ` Joe Hershberger
2017-08-13 21:35             ` Simon Glass
2017-07-14 12:54 ` [U-Boot] [PATCH 10/51] net:phy:marvell Add hook for m88e1510 board config Mario Six
2017-07-18 14:01   ` Simon Glass
2017-07-25 13:43     ` Mario Six
2017-07-14 12:54 ` [U-Boot] [PATCH 11/51] powerpc: mpc83xx: Implement get_serial_clock() Mario Six
2017-07-18 14:01   ` Simon Glass
2017-07-25  7:34     ` Mario Six
2017-07-14 12:54 ` [U-Boot] [PATCH 12/51] cfi_flash: Fix style violations Mario Six
2017-07-18 14:01   ` Simon Glass
2017-07-14 12:54 ` [U-Boot] [PATCH 13/51] cfi_flash: Clean up code some more Mario Six
2017-07-18 14:02   ` Simon Glass
2017-07-19  8:30     ` Mario Six
2017-07-14 12:55 ` [U-Boot] [PATCH 14/51] cfi_flash: Always define cfi_flash_num_flash_banks Mario Six
2017-07-18 14:02   ` Simon Glass
2017-07-14 12:55 ` [U-Boot] [PATCH 15/51] gpio: mpc85xx_gpio: Fix style violations Mario Six
2017-07-18 14:02   ` Simon Glass
2017-07-14 12:55 ` [U-Boot] [PATCH 16/51] gpio: mpc85xx_gpio: Make compatible with MPC8XXX Mario Six
2017-07-18 14:02   ` Simon Glass
2017-07-19  8:24     ` Mario Six
2017-07-14 12:55 ` [U-Boot] [PATCH 17/51] cmd: mdio: Fix style violations Mario Six
2017-07-18 14:02   ` Simon Glass
2017-07-14 12:55 ` [U-Boot] [PATCH 18/51] cmd: mdio: Add 'driver' subcommand Mario Six
2017-07-18 14:02   ` Simon Glass
2017-07-25  8:25     ` Mario Six
2017-07-14 12:55 ` [U-Boot] [PATCH 19/51] common: board_f: Fix style violations Mario Six
2017-07-18 14:02   ` Simon Glass
2017-07-14 12:55 ` [U-Boot] [PATCH 20/51] common: board_r: " Mario Six
2017-07-18 14:02   ` Simon Glass
2017-07-14 12:55 ` [U-Boot] [PATCH 21/51] common: Extend board-specific DT fixup Mario Six
2017-07-19  9:05   ` Simon Glass
2017-07-25  8:40     ` Mario Six
2017-07-14 12:55 ` [U-Boot] [PATCH 22/51] gdsys: mpc8308: Fix style violations Mario Six
2017-07-19  9:05   ` Simon Glass
2017-07-14 12:55 ` [U-Boot] [PATCH 23/51] gdsys: mpc8308: Use shadow register for output GPIO values Mario Six
2017-07-19  9:05   ` Simon Glass
2017-07-14 12:55 ` [U-Boot] [PATCH 24/51] gdsys: mpc8308: Move SYS_FPGA{0, 1}_{BASE, SIZE} to Kconfig Mario Six
2017-07-19  9:05   ` Simon Glass
2017-07-25  7:39     ` Mario Six
2017-07-14 12:55 ` [U-Boot] [PATCH 25/51] gdsys: Introduce GDSYS_LEGACY_DRIVERS Mario Six
2017-07-19  9:05   ` Simon Glass
2017-07-25  7:40     ` Mario Six
2017-07-14 12:55 ` [U-Boot] [PATCH 26/51] strider, hrcon: Reset CAT phy on CON2 module Mario Six
2017-07-19  9:05   ` Simon Glass
2017-07-14 12:55 ` [U-Boot] [PATCH 27/51] gdsys:phy: Adapt fixup_88e1518() to latest Release Notes Mario Six
2017-07-19  9:05   ` Simon Glass
2017-07-14 12:55 ` [U-Boot] [PATCH 28/51] i2c: ihs_i2c: Prepare DM conversion Mario Six
2017-07-19  9:05   ` Simon Glass
2017-07-25  7:48     ` Mario Six
2017-07-14 12:55 ` [U-Boot] [PATCH 29/51] i2c: ihs_i2c: Make DM compatible Mario Six
2017-07-19  9:05   ` Simon Glass
2017-07-25  7:50     ` Mario Six
2017-07-14 12:55 ` [U-Boot] [PATCH 30/51] i2c: ihs_i2c: Factor out send_buffer method Mario Six
2017-07-19  9:05   ` Simon Glass
2017-07-14 12:55 ` [U-Boot] [PATCH 31/51] gdsys: mpc8308: Add FPGA flavor option Mario Six
2017-07-19  9:05   ` Simon Glass
2017-07-25  7:52     ` Mario Six
2017-07-14 12:55 ` [U-Boot] [PATCH 32/51] drivers: Add ihs_fpga and gdsys_soc drivers Mario Six
2017-07-19  9:06   ` Simon Glass
2017-07-25  9:22     ` Mario Six
2017-07-14 12:55 ` [U-Boot] [PATCH 33/51] drivers: Add transmitter uclass Mario Six
2017-07-19  9:05   ` Simon Glass
2017-07-25  9:29     ` Mario Six
2017-07-14 12:55 ` [U-Boot] [PATCH 34/51] transmitter: Add Xilinx LogiCore DP TX Mario Six
2017-07-19  9:06   ` Simon Glass
2017-07-25  9:48     ` Mario Six
2017-07-14 12:55 ` [U-Boot] [PATCH 35/51] drivers: Add ICS8N3QV01 driver Mario Six
2017-07-19  9:05   ` Simon Glass
2017-07-25  8:08     ` Mario Six
2017-07-14 12:55 ` [U-Boot] [PATCH 36/51] drivers: Add ihs_axi driver Mario Six
2017-07-19  9:06   ` Simon Glass
2017-07-25 12:27     ` Mario Six
2017-07-14 12:55 ` [U-Boot] [PATCH 37/51] drivers: Add ihs_video_out driver Mario Six
2017-07-19  9:06   ` Simon Glass
2017-07-25 11:36     ` Mario Six
2017-07-14 12:55 ` [U-Boot] [PATCH 38/51] gdsys: drivers: Add gdsys_rxaui_ctrl driver Mario Six
2017-07-19  9:06   ` Simon Glass
2017-07-25 11:41     ` Mario Six
2017-07-14 12:55 ` [U-Boot] [PATCH 39/51] drivers: Add gdsys_ioep driver Mario Six
2017-07-19  9:06   ` Simon Glass
2017-07-25 11:49     ` Mario Six
2017-07-14 12:55 ` [U-Boot] [PATCH 40/51] cmd: Add ihs osd commands Mario Six
2017-07-19  9:06   ` Simon Glass
2017-07-25 12:01     ` Mario Six
2017-07-14 12:55 ` [U-Boot] [PATCH 41/51] cmd: Add ihs axi command Mario Six
2017-07-19  9:06   ` Simon Glass
2017-07-25  8:14     ` Mario Six
2017-07-14 12:55 ` [U-Boot] [PATCH 42/51] cmd: Add ihs fpga command Mario Six
2017-07-19  9:06   ` Simon Glass
2017-07-25 12:33     ` Mario Six
2017-07-14 12:55 ` [U-Boot] [PATCH 43/51] gdsys: cmd_ioloop: Fix style violations Mario Six
2017-07-19  9:06   ` Simon Glass
2017-07-14 12:55 ` [U-Boot] [PATCH 44/51] gdsys: cmd_ioloop: Introduce commenting enum Mario Six
2017-07-19  9:06   ` Simon Glass
2017-07-14 12:55 ` [U-Boot] [PATCH 45/51] gdsys: cmd_ioloop: Make DM compatible Mario Six
2017-07-19  9:06   ` Simon Glass
2017-07-14 12:55 ` [U-Boot] [PATCH 46/51] ihs_mdio: Add support to force clause45 access Mario Six
2017-07-19  9:06   ` Simon Glass
2017-07-14 12:55 ` [U-Boot] [PATCH 47/51] ihs_mdio: Fix style violations Mario Six
2017-07-19  9:06   ` Simon Glass
2017-07-14 12:55 ` [U-Boot] [PATCH 48/51] ihs_mdio: Make DM-compatible Mario Six
2017-07-19  9:06   ` Simon Glass
2017-07-14 12:55 ` [U-Boot] [PATCH 49/51] gazerbeam: Import Linux DT Mario Six
2017-07-19  9:07   ` Simon Glass
2017-07-14 12:55 ` [U-Boot] [PATCH 50/51] gazerbeam: Add u-boot specific dts include file Mario Six
2017-07-19  9:07   ` Simon Glass
2017-07-14 12:55 ` [U-Boot] [PATCH 51/51] mpc83xx: Add gazerbeam board Mario Six
2017-07-19  9:07   ` Simon Glass
2017-07-26  8:24     ` Mario Six
2017-08-04  9:34       ` Simon Glass

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.