All of lore.kernel.org
 help / color / mirror / Atom feed
* [U-Boot] [PATCH v2 00/20] More support for Armada 37xx boards (for Turris Mox)
@ 2018-04-24 15:21 Marek Behún
  2018-04-24 15:21 ` [U-Boot] [PATCH v2 01/20] phy: marvell: a3700: Change return type of macro MVEBU_REG Marek Behún
                   ` (20 more replies)
  0 siblings, 21 replies; 22+ messages in thread
From: Marek Behún @ 2018-04-24 15:21 UTC (permalink / raw)
  To: u-boot

This is the second version of patches for updating the support of Armada 37xx
devices. Here I also send first version of code which adds basic support for the
Turris Mox board, a router currently being developed here at CZ.NIC, which is
being crowdfunded now on Indiegogo.

Changes since v1:
  - these patches were removed, since the update has already been merged into
    U-Boot:
      arm64: mvebu_armada_37xx: Use Armada 37xx pinctrl driver by default
      armada-37xx: Fix SB pinctrl groups according to new revision
  - I have changed the names of the functions SGMIIPHY_ADDR and PHY_ADDR to
    lowercase, as Stefan requested
  - I have used checkpatch on the patches. There still are come warnings, like
    "added, moved or deleted file(s), does MAINTAINERS need updating?" or
    "line over 80 characters" (long string constant in dts). How should I solve
    these?
  - some minor changes based on comments from Stefan
  - added a patch to fix SGMII register addresses
  - added a patch which adds support for the CPU watchdog on Armada 3720
  - added a patch which adds basic support for the Turris Mox board

Please review.

Marek Behun

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

* [U-Boot] [PATCH v2 01/20] phy: marvell: a3700: Change return type of macro MVEBU_REG
  2018-04-24 15:21 [U-Boot] [PATCH v2 00/20] More support for Armada 37xx boards (for Turris Mox) Marek Behún
@ 2018-04-24 15:21 ` Marek Behún
  2018-04-24 15:21 ` [U-Boot] [PATCH v2 02/20] phy: marvell: a3700: Use reg_set16 instead of phy_write16 Marek Behún
                   ` (19 subsequent siblings)
  20 siblings, 0 replies; 22+ messages in thread
From: Marek Behún @ 2018-04-24 15:21 UTC (permalink / raw)
  To: u-boot

All the calls to reg_set and friends have to cast the first argument
to void __iomem *. Lets change the return type of the MVEBU_REG macro
instead.

Signed-off-by: Marek Behun <marek.behun@nic.cz>
---
 drivers/phy/marvell/comphy_a3700.c | 206 ++++++++++++++++---------------------
 drivers/phy/marvell/comphy_a3700.h |   8 +-
 2 files changed, 96 insertions(+), 118 deletions(-)

diff --git a/drivers/phy/marvell/comphy_a3700.c b/drivers/phy/marvell/comphy_a3700.c
index 5afd23c052..bf92672275 100644
--- a/drivers/phy/marvell/comphy_a3700.c
+++ b/drivers/phy/marvell/comphy_a3700.c
@@ -141,78 +141,72 @@ static int comphy_pcie_power_up(u32 speed, u32 invert)
 	/*
 	 * 1. Enable max PLL.
 	 */
-	reg_set16((void __iomem *)LANE_CFG1_ADDR(PCIE),
-		  bf_use_max_pll_rate, 0);
+	reg_set16(LANE_CFG1_ADDR(PCIE), bf_use_max_pll_rate, 0);
 
 	/*
 	 * 2. Select 20 bit SERDES interface.
 	 */
-	reg_set16((void __iomem *)GLOB_CLK_SRC_LO_ADDR(PCIE),
-		  bf_cfg_sel_20b, 0);
+	reg_set16(GLOB_CLK_SRC_LO_ADDR(PCIE), bf_cfg_sel_20b, 0);
 
 	/*
 	 * 3. Force to use reg setting for PCIe mode
 	 */
-	reg_set16((void __iomem *)MISC_REG1_ADDR(PCIE),
-		  bf_sel_bits_pcie_force, 0);
+	reg_set16(MISC_REG1_ADDR(PCIE), bf_sel_bits_pcie_force, 0);
 
 	/*
 	 * 4. Change RX wait
 	 */
-	reg_set16((void __iomem *)PWR_MGM_TIM1_ADDR(PCIE), 0x10C, 0xFFFF);
+	reg_set16(PWR_MGM_TIM1_ADDR(PCIE), 0x10C, 0xFFFF);
 
 	/*
 	 * 5. Enable idle sync
 	 */
-	reg_set16((void __iomem *)UNIT_CTRL_ADDR(PCIE),
-		  0x60 | rb_idle_sync_en, 0xFFFF);
+	reg_set16(UNIT_CTRL_ADDR(PCIE), 0x60 | rb_idle_sync_en, 0xFFFF);
 
 	/*
 	 * 6. Enable the output of 100M/125M/500M clock
 	 */
-	reg_set16((void __iomem *)MISC_REG0_ADDR(PCIE),
+	reg_set16(MISC_REG0_ADDR(PCIE),
 		  0xA00D | rb_clk500m_en | rb_clk100m_125m_en, 0xFFFF);
 
 	/*
 	 * 7. Enable TX
 	 */
-	reg_set((void __iomem *)PHY_REF_CLK_ADDR, 0x1342, 0xFFFFFFFF);
+	reg_set(PHY_REF_CLK_ADDR, 0x1342, 0xFFFFFFFF);
 
 	/*
 	 * 8. Check crystal jumper setting and program the Power and PLL
 	 *    Control accordingly
 	 */
 	if (get_ref_clk() == 40) {
-		reg_set16((void __iomem *)PWR_PLL_CTRL_ADDR(PCIE),
+		reg_set16(PWR_PLL_CTRL_ADDR(PCIE),
 			  0xFC63, 0xFFFF); /* 40 MHz */
 	} else {
-		reg_set16((void __iomem *)PWR_PLL_CTRL_ADDR(PCIE),
+		reg_set16(PWR_PLL_CTRL_ADDR(PCIE),
 			  0xFC62, 0xFFFF); /* 25 MHz */
 	}
 
 	/*
 	 * 9. Override Speed_PLL value and use MAC PLL
 	 */
-	reg_set16((void __iomem *)KVCO_CAL_CTRL_ADDR(PCIE),
-		  0x0040 | rb_use_max_pll_rate, 0xFFFF);
+	reg_set16(KVCO_CAL_CTRL_ADDR(PCIE), 0x0040 | rb_use_max_pll_rate,
+		  0xFFFF);
 
 	/*
 	 * 10. Check the Polarity invert bit
 	 */
 	if (invert & PHY_POLARITY_TXD_INVERT) {
-		reg_set16((void __iomem *)SYNC_PATTERN_ADDR(PCIE),
-			  phy_txd_inv, 0);
+		reg_set16(SYNC_PATTERN_ADDR(PCIE), phy_txd_inv, 0);
 	}
 
 	if (invert & PHY_POLARITY_RXD_INVERT) {
-		reg_set16((void __iomem *)SYNC_PATTERN_ADDR(PCIE),
-			  phy_rxd_inv, 0);
+		reg_set16(SYNC_PATTERN_ADDR(PCIE), phy_rxd_inv, 0);
 	}
 
 	/*
 	 * 11. Release SW reset
 	 */
-	reg_set16((void __iomem *)GLOB_PHY_CTRL0_ADDR(PCIE),
+	reg_set16(GLOB_PHY_CTRL0_ADDR(PCIE),
 		  rb_mode_core_clk_freq_sel | rb_mode_pipe_width_32,
 		  bf_soft_rst | bf_mode_refdiv);
 
@@ -220,11 +214,11 @@ static int comphy_pcie_power_up(u32 speed, u32 invert)
 	udelay(PLL_SET_DELAY_US);
 
 	/* Assert PCLK enabled */
-	ret = comphy_poll_reg((void *)LANE_STAT1_ADDR(PCIE),	/* address */
-			      rb_txdclk_pclk_en,		/* value */
-			      rb_txdclk_pclk_en,		/* mask */
-			      PLL_LOCK_TIMEOUT,			/* timeout */
-			      POLL_16B_REG);			/* 16bit */
+	ret = comphy_poll_reg(LANE_STAT1_ADDR(PCIE),	/* address */
+			      rb_txdclk_pclk_en,	/* value */
+			      rb_txdclk_pclk_en,	/* mask */
+			      PLL_LOCK_TIMEOUT,		/* timeout */
+			      POLL_16B_REG);		/* 16bit */
 	if (ret == 0)
 		printf("Failed to lock PCIe PLL\n");
 
@@ -248,57 +242,53 @@ static int comphy_sata_power_up(void)
 	/*
 	 * 0. Swap SATA TX lines
 	 */
-	reg_set((void __iomem *)rh_vsreg_addr,
-		vphy_sync_pattern_reg, 0xFFFFFFFF);
-	reg_set((void __iomem *)rh_vsreg_data, bs_txd_inv, bs_txd_inv);
+	reg_set(rh_vsreg_addr, vphy_sync_pattern_reg, 0xFFFFFFFF);
+	reg_set(rh_vsreg_data, bs_txd_inv, bs_txd_inv);
 
 	/*
 	 * 1. Select 40-bit data width width
 	 */
-	reg_set((void __iomem *)rh_vsreg_addr, vphy_loopback_reg0, 0xFFFFFFFF);
-	reg_set((void __iomem *)rh_vsreg_data, 0x800, bs_phyintf_40bit);
+	reg_set(rh_vsreg_addr, vphy_loopback_reg0, 0xFFFFFFFF);
+	reg_set(rh_vsreg_data, 0x800, bs_phyintf_40bit);
 
 	/*
 	 * 2. Select reference clock and PHY mode (SATA)
 	 */
-	reg_set((void __iomem *)rh_vsreg_addr, vphy_power_reg0, 0xFFFFFFFF);
+	reg_set(rh_vsreg_addr, vphy_power_reg0, 0xFFFFFFFF);
 	if (get_ref_clk() == 40) {
-		reg_set((void __iomem *)rh_vsreg_data,
-			0x3, 0x00FF); /* 40 MHz */
+		reg_set(rh_vsreg_data, 0x3, 0x00FF); /* 40 MHz */
 	} else {
-		reg_set((void __iomem *)rh_vsreg_data,
-			0x1, 0x00FF); /* 25 MHz */
+		reg_set(rh_vsreg_data, 0x1, 0x00FF); /* 25 MHz */
 	}
 
 	/*
 	 * 3. Use maximum PLL rate (no power save)
 	 */
-	reg_set((void __iomem *)rh_vsreg_addr, vphy_calctl_reg, 0xFFFFFFFF);
-	reg_set((void __iomem *)rh_vsreg_data,
-		bs_max_pll_rate, bs_max_pll_rate);
+	reg_set(rh_vsreg_addr, vphy_calctl_reg, 0xFFFFFFFF);
+	reg_set(rh_vsreg_data, bs_max_pll_rate, bs_max_pll_rate);
 
 	/*
 	 * 4. Reset reserved bit (??)
 	 */
-	reg_set((void __iomem *)rh_vsreg_addr, vphy_reserve_reg, 0xFFFFFFFF);
-	reg_set((void __iomem *)rh_vsreg_data, 0, bs_phyctrl_frm_pin);
+	reg_set(rh_vsreg_addr, vphy_reserve_reg, 0xFFFFFFFF);
+	reg_set(rh_vsreg_data, 0, bs_phyctrl_frm_pin);
 
 	/*
 	 * 5. Set vendor-specific configuration (??)
 	 */
-	reg_set((void __iomem *)rh_vs0_a, vsata_ctrl_reg, 0xFFFFFFFF);
-	reg_set((void __iomem *)rh_vs0_d, bs_phy_pu_pll, bs_phy_pu_pll);
+	reg_set(rh_vs0_a, vsata_ctrl_reg, 0xFFFFFFFF);
+	reg_set(rh_vs0_d, bs_phy_pu_pll, bs_phy_pu_pll);
 
 	/* Wait for > 55 us to allow PLL be enabled */
 	udelay(PLL_SET_DELAY_US);
 
 	/* Assert SATA PLL enabled */
-	reg_set((void __iomem *)rh_vsreg_addr, vphy_loopback_reg0, 0xFFFFFFFF);
-	ret = comphy_poll_reg((void *)rh_vsreg_data,	/* address */
-			      bs_pll_ready_tx,		/* value */
-			      bs_pll_ready_tx,		/* mask */
-			      PLL_LOCK_TIMEOUT,		/* timeout */
-			      POLL_32B_REG);		/* 32bit */
+	reg_set(rh_vsreg_addr, vphy_loopback_reg0, 0xFFFFFFFF);
+	ret = comphy_poll_reg(rh_vsreg_data,	/* address */
+			      bs_pll_ready_tx,	/* value */
+			      bs_pll_ready_tx,	/* mask */
+			      PLL_LOCK_TIMEOUT,	/* timeout */
+			      POLL_32B_REG);	/* 32bit */
 	if (ret == 0)
 		printf("Failed to lock SATA PLL\n");
 
@@ -321,19 +311,18 @@ static int comphy_usb3_power_up(u32 type, u32 speed, u32 invert)
 	/*
 	 * 1. Power up OTG module
 	 */
-	reg_set((void __iomem *)USB2_PHY_OTG_CTRL_ADDR, rb_pu_otg, 0);
+	reg_set(USB2_PHY_OTG_CTRL_ADDR, rb_pu_otg, 0);
 
 	/*
 	 * 2. Set counter for 100us pulse in USB3 Host and Device
 	 * restore default burst size limit (Reference Clock 31:24)
 	 */
-	reg_set((void __iomem *)USB3_CTRPUL_VAL_REG,
-		0x8 << 24, rb_usb3_ctr_100ns);
+	reg_set(USB3_CTRPUL_VAL_REG, 0x8 << 24, rb_usb3_ctr_100ns);
 
 
 	/* 0xd005c300 = 0x1001 */
 	/* set PRD_TXDEEMPH (3.5db de-emph) */
-	reg_set16((void __iomem *)LANE_CFG0_ADDR(USB3), 0x1, 0xFF);
+	reg_set16(LANE_CFG0_ADDR(USB3), 0x1, 0xFF);
 
 	/*
 	 * unset BIT0: set Tx Electrical Idle Mode: Transmitter is in
@@ -341,91 +330,82 @@ static int comphy_usb3_power_up(u32 type, u32 speed, u32 invert)
 	 */
 	/* unset BIT4: set G2 Tx Datapath with no Delayed Latency */
 	/* unset BIT6: set Tx Detect Rx Mode at LoZ mode */
-	reg_set16((void __iomem *)LANE_CFG1_ADDR(USB3), 0x0, 0xFFFF);
+	reg_set16(LANE_CFG1_ADDR(USB3), 0x0, 0xFFFF);
 
 
 	/* 0xd005c310 = 0x93: set Spread Spectrum Clock Enabled  */
-	reg_set16((void __iomem *)LANE_CFG4_ADDR(USB3),
-		  bf_spread_spectrum_clock_en, 0x80);
+	reg_set16(LANE_CFG4_ADDR(USB3), bf_spread_spectrum_clock_en, 0x80);
 
 	/*
 	 * set Override Margining Controls From the MAC: Use margining signals
 	 * from lane configuration
 	 */
-	reg_set16((void __iomem *)TEST_MODE_CTRL_ADDR(USB3),
-		  rb_mode_margin_override, 0xFFFF);
+	reg_set16(TEST_MODE_CTRL_ADDR(USB3), rb_mode_margin_override, 0xFFFF);
 
 	/* set Lane-to-Lane Bundle Clock Sampling Period = per PCLK cycles */
 	/* set Mode Clock Source = PCLK is generated from REFCLK */
-	reg_set16((void __iomem *)GLOB_CLK_SRC_LO_ADDR(USB3), 0x0, 0xFF);
+	reg_set16(GLOB_CLK_SRC_LO_ADDR(USB3), 0x0, 0xFF);
 
 	/* set G2 Spread Spectrum Clock Amplitude@4K */
-	reg_set16((void __iomem *)GEN2_SETTING_2_ADDR(USB3), g2_tx_ssc_amp,
-		  0xF000);
+	reg_set16(GEN2_SETTING_2_ADDR(USB3), g2_tx_ssc_amp, 0xF000);
 
 	/*
 	 * unset G3 Spread Spectrum Clock Amplitude & set G3 TX and RX Register
 	 * Master Current Select
 	 */
-	reg_set16((void __iomem *)GEN2_SETTING_3_ADDR(USB3), 0x0, 0xFFFF);
+	reg_set16(GEN2_SETTING_3_ADDR(USB3), 0x0, 0xFFFF);
 
 	/*
 	 * 3. Check crystal jumper setting and program the Power and PLL
 	 * Control accordingly
 	 */
 	if (get_ref_clk() == 40) {
-		reg_set16((void __iomem *)PWR_PLL_CTRL_ADDR(USB3), 0xFCA3,
-			  0xFFFF); /* 40 MHz */
+		reg_set16(PWR_PLL_CTRL_ADDR(USB3), 0xFCA3, 0xFFFF); /* 40 MHz */
 	} else {
-		reg_set16((void __iomem *)PWR_PLL_CTRL_ADDR(USB3), 0xFCA2,
-			  0xFFFF); /* 25 MHz */
+		reg_set16(PWR_PLL_CTRL_ADDR(USB3), 0xFCA2, 0xFFFF); /* 25 MHz */
 	}
 
 	/*
 	 * 4. Change RX wait
 	 */
-	reg_set16((void __iomem *)PWR_MGM_TIM1_ADDR(USB3), 0x10C, 0xFFFF);
+	reg_set16(PWR_MGM_TIM1_ADDR(USB3), 0x10C, 0xFFFF);
 
 	/*
 	 * 5. Enable idle sync
 	 */
-	reg_set16((void __iomem *)UNIT_CTRL_ADDR(USB3), 0x60 | rb_idle_sync_en,
-		  0xFFFF);
+	reg_set16(UNIT_CTRL_ADDR(USB3), 0x60 | rb_idle_sync_en, 0xFFFF);
 
 	/*
 	 * 6. Enable the output of 500M clock
 	 */
-	reg_set16((void __iomem *)MISC_REG0_ADDR(USB3), 0xA00D | rb_clk500m_en,
-		  0xFFFF);
+	reg_set16(MISC_REG0_ADDR(USB3), 0xA00D | rb_clk500m_en, 0xFFFF);
 
 	/*
 	 * 7. Set 20-bit data width
 	 */
-	reg_set16((void __iomem *)DIG_LB_EN_ADDR(USB3), 0x0400, 0xFFFF);
+	reg_set16(DIG_LB_EN_ADDR(USB3), 0x0400, 0xFFFF);
 
 	/*
 	 * 8. Override Speed_PLL value and use MAC PLL
 	 */
-	reg_set16((void __iomem *)KVCO_CAL_CTRL_ADDR(USB3),
-		  0x0040 | rb_use_max_pll_rate, 0xFFFF);
+	reg_set16(KVCO_CAL_CTRL_ADDR(USB3), 0x0040 | rb_use_max_pll_rate,
+		  0xFFFF);
 
 	/*
 	 * 9. Check the Polarity invert bit
 	 */
 	if (invert & PHY_POLARITY_TXD_INVERT) {
-		reg_set16((void __iomem *)SYNC_PATTERN_ADDR(USB3),
-			  phy_txd_inv, 0);
+		reg_set16(SYNC_PATTERN_ADDR(USB3), phy_txd_inv, 0);
 	}
 
 	if (invert & PHY_POLARITY_RXD_INVERT) {
-		reg_set16((void __iomem *)SYNC_PATTERN_ADDR(USB3),
-			  phy_rxd_inv, 0);
+		reg_set16(SYNC_PATTERN_ADDR(USB3), phy_rxd_inv, 0);
 	}
 
 	/*
 	 * 10. Release SW reset
 	 */
-	reg_set16((void __iomem *)GLOB_PHY_CTRL0_ADDR(USB3),
+	reg_set16(GLOB_PHY_CTRL0_ADDR(USB3),
 		  rb_mode_core_clk_freq_sel | rb_mode_pipe_width_32 | 0x20,
 		  0xFFFF);
 
@@ -433,11 +413,11 @@ static int comphy_usb3_power_up(u32 type, u32 speed, u32 invert)
 	udelay(PLL_SET_DELAY_US);
 
 	/* Assert PCLK enabled */
-	ret = comphy_poll_reg((void *)LANE_STAT1_ADDR(USB3),	/* address */
-			      rb_txdclk_pclk_en,		/* value */
-			      rb_txdclk_pclk_en,		/* mask */
-			      PLL_LOCK_TIMEOUT,			/* timeout */
-			      POLL_16B_REG);			/* 16bit */
+	ret = comphy_poll_reg(LANE_STAT1_ADDR(USB3),	/* address */
+			      rb_txdclk_pclk_en,	/* value */
+			      rb_txdclk_pclk_en,	/* mask */
+			      PLL_LOCK_TIMEOUT,		/* timeout */
+			      POLL_16B_REG);		/* 16bit */
 	if (ret == 0)
 		printf("Failed to lock USB3 PLL\n");
 
@@ -455,7 +435,7 @@ static int comphy_usb3_power_up(u32 type, u32 speed, u32 invert)
 		 *             INT_MODE=ID in order to avoid unexpected
 		 *             behaviour or both interrupts together
 		 */
-		reg_set((void __iomem *)USB32_CTRL_BASE,
+		reg_set(USB32_CTRL_BASE,
 			usb32_ctrl_id_mode | usb32_ctrl_int_mode,
 			usb32_ctrl_id_mode | usb32_ctrl_soft_id |
 			usb32_ctrl_int_mode);
@@ -489,32 +469,32 @@ static int comphy_usb2_power_up(u8 usb32)
 	 *    See "PLL Settings for Typical REFCLK" table
 	 */
 	if (get_ref_clk() == 25) {
-		reg_set((void __iomem *)USB2_PHY_BASE(usb32),
-			5 | (96 << 16), 0x3F | (0xFF << 16) | (0x3 << 28));
+		reg_set(USB2_PHY_BASE(usb32), 5 | (96 << 16),
+			0x3F | (0xFF << 16) | (0x3 << 28));
 	}
 
 	/*
 	 * 1. PHY pull up and disable USB2 suspend
 	 */
-	reg_set((void __iomem *)USB2_PHY_CTRL_ADDR(usb32),
+	reg_set(USB2_PHY_CTRL_ADDR(usb32),
 		RB_USB2PHY_SUSPM(usb32) | RB_USB2PHY_PU(usb32), 0);
 
 	if (usb32 != 0) {
 		/*
 		 * 2. Power up OTG module
 		 */
-		reg_set((void __iomem *)USB2_PHY_OTG_CTRL_ADDR, rb_pu_otg, 0);
+		reg_set(USB2_PHY_OTG_CTRL_ADDR, rb_pu_otg, 0);
 
 		/*
 		 * 3. Configure PHY charger detection
 		 */
-		reg_set((void __iomem *)USB2_PHY_CHRGR_DET_ADDR, 0,
+		reg_set(USB2_PHY_CHRGR_DET_ADDR, 0,
 			rb_cdp_en | rb_dcp_en | rb_pd_en | rb_cdp_dm_auto |
 			rb_enswitch_dp | rb_enswitch_dm | rb_pu_chrg_dtc);
 	}
 
 	/* Assert PLL calibration done */
-	ret = comphy_poll_reg((void *)USB2_PHY_CAL_CTRL_ADDR(usb32),
+	ret = comphy_poll_reg(USB2_PHY_CAL_CTRL_ADDR(usb32),
 			      rb_usb2phy_pllcal_done,	/* value */
 			      rb_usb2phy_pllcal_done,	/* mask */
 			      PLL_LOCK_TIMEOUT,		/* timeout */
@@ -523,7 +503,7 @@ static int comphy_usb2_power_up(u8 usb32)
 		printf("Failed to end USB2 PLL calibration\n");
 
 	/* Assert impedance calibration done */
-	ret = comphy_poll_reg((void *)USB2_PHY_CAL_CTRL_ADDR(usb32),
+	ret = comphy_poll_reg(USB2_PHY_CAL_CTRL_ADDR(usb32),
 			      rb_usb2phy_impcal_done,	/* value */
 			      rb_usb2phy_impcal_done,	/* mask */
 			      PLL_LOCK_TIMEOUT,		/* timeout */
@@ -532,7 +512,7 @@ static int comphy_usb2_power_up(u8 usb32)
 		printf("Failed to end USB2 impedance calibration\n");
 
 	/* Assert squetch calibration done */
-	ret = comphy_poll_reg((void *)USB2_PHY_RX_CHAN_CTRL1_ADDR(usb32),
+	ret = comphy_poll_reg(USB2_PHY_RX_CHAN_CTRL1_ADDR(usb32),
 			      rb_usb2phy_sqcal_done,	/* value */
 			      rb_usb2phy_sqcal_done,	/* mask */
 			      PLL_LOCK_TIMEOUT,		/* timeout */
@@ -541,7 +521,7 @@ static int comphy_usb2_power_up(u8 usb32)
 		printf("Failed to end USB2 unknown calibration\n");
 
 	/* Assert PLL is ready */
-	ret = comphy_poll_reg((void *)USB2_PHY_PLL_CTRL0_ADDR(usb32),
+	ret = comphy_poll_reg(USB2_PHY_PLL_CTRL0_ADDR(usb32),
 			      rb_usb2phy_pll_ready,		/* value */
 			      rb_usb2phy_pll_ready,		/* mask */
 			      PLL_LOCK_TIMEOUT,		/* timeout */
@@ -567,35 +547,34 @@ static int comphy_emmc_power_up(void)
 	/*
 	 * 1. Bus power ON, Bus voltage 1.8V
 	 */
-	reg_set((void __iomem *)SDIO_HOST_CTRL1_ADDR, 0xB00, 0xF00);
+	reg_set(SDIO_HOST_CTRL1_ADDR, 0xB00, 0xF00);
 
 	/*
 	 * 2. Set FIFO parameters
 	 */
-	reg_set((void __iomem *)SDIO_SDHC_FIFO_ADDR, 0x315, 0xFFFFFFFF);
+	reg_set(SDIO_SDHC_FIFO_ADDR, 0x315, 0xFFFFFFFF);
 
 	/*
 	 * 3. Set Capabilities 1_2
 	 */
-	reg_set((void __iomem *)SDIO_CAP_12_ADDR, 0x25FAC8B2, 0xFFFFFFFF);
+	reg_set(SDIO_CAP_12_ADDR, 0x25FAC8B2, 0xFFFFFFFF);
 
 	/*
 	 * 4. Set Endian
 	 */
-	reg_set((void __iomem *)SDIO_ENDIAN_ADDR, 0x00c00000, 0);
+	reg_set(SDIO_ENDIAN_ADDR, 0x00c00000, 0);
 
 	/*
 	 * 4. Init PHY
 	 */
-	reg_set((void __iomem *)SDIO_PHY_TIMING_ADDR, 0x80000000, 0x80000000);
-	reg_set((void __iomem *)SDIO_PHY_PAD_CTRL0_ADDR, 0x50000000,
-		0xF0000000);
+	reg_set(SDIO_PHY_TIMING_ADDR, 0x80000000, 0x80000000);
+	reg_set(SDIO_PHY_PAD_CTRL0_ADDR, 0x50000000, 0xF0000000);
 
 	/*
 	 * 5. DLL reset
 	 */
-	reg_set((void __iomem *)SDIO_DLL_RST_ADDR, 0xFFFEFFFF, 0);
-	reg_set((void __iomem *)SDIO_DLL_RST_ADDR, 0x00010000, 0);
+	reg_set(SDIO_DLL_RST_ADDR, 0xFFFEFFFF, 0);
+	reg_set(SDIO_DLL_RST_ADDR, 0x00010000, 0);
 
 	debug_exit();
 
@@ -650,7 +629,7 @@ static int comphy_sgmii_power_up(u32 lane, u32 speed, u32 invert)
 	/*
 	 * 1. Configure PHY to SATA/SAS mode by setting pin PIN_PIPE_SEL=0
 	 */
-	reg_set((void __iomem *)COMPHY_SEL_ADDR, 0, rf_compy_select(lane));
+	reg_set(COMPHY_SEL_ADDR, 0, rf_compy_select(lane));
 
 	/*
 	 * 2. Reset PHY by setting PHY input port PIN_RESET=1.
@@ -658,7 +637,7 @@ static int comphy_sgmii_power_up(u32 lane, u32 speed, u32 invert)
 	 *    PHY TXP/TXN output to idle state during PHY initialization
 	 * 4. Set PHY input port PIN_PU_PLL=0, PIN_PU_RX=0, PIN_PU_TX=0.
 	 */
-	reg_set((void __iomem *)COMPHY_PHY_CFG1_ADDR(lane),
+	reg_set(COMPHY_PHY_CFG1_ADDR(lane),
 		rb_pin_reset_comphy | rb_pin_tx_idle | rb_pin_pu_iveref,
 		rb_pin_reset_core | rb_pin_pu_pll |
 		rb_pin_pu_rx | rb_pin_pu_tx);
@@ -666,21 +645,20 @@ static int comphy_sgmii_power_up(u32 lane, u32 speed, u32 invert)
 	/*
 	 * 5. Release reset to the PHY by setting PIN_RESET=0.
 	 */
-	reg_set((void __iomem *)COMPHY_PHY_CFG1_ADDR(lane),
-		0, rb_pin_reset_comphy);
+	reg_set(COMPHY_PHY_CFG1_ADDR(lane), 0, rb_pin_reset_comphy);
 
 	/*
 	 * 7. Set PIN_PHY_GEN_TX[3:0] and PIN_PHY_GEN_RX[3:0] to decide
 	 *    COMPHY bit rate
 	 */
 	if (speed == PHY_SPEED_3_125G) { /* 3.125 GHz */
-		reg_set((void __iomem *)COMPHY_PHY_CFG1_ADDR(lane),
+		reg_set(COMPHY_PHY_CFG1_ADDR(lane),
 			(0x8 << rf_gen_rx_sel_shift) |
 			(0x8 << rf_gen_tx_sel_shift),
 			rf_gen_rx_select | rf_gen_tx_select);
 
 	} else if (speed == PHY_SPEED_1_25G) { /* 1.25 GHz */
-		reg_set((void __iomem *)COMPHY_PHY_CFG1_ADDR(lane),
+		reg_set(COMPHY_PHY_CFG1_ADDR(lane),
 			(0x6 << rf_gen_rx_sel_shift) |
 			(0x6 << rf_gen_tx_sel_shift),
 			rf_gen_rx_select | rf_gen_tx_select);
@@ -785,7 +763,7 @@ static int comphy_sgmii_power_up(u32 lane, u32 speed, u32 invert)
 	 *     programming should be done before PIN_PU_PLL=1. There should be
 	 *     no register programming for normal PHY operation from this point.
 	 */
-	reg_set((void __iomem *)COMPHY_PHY_CFG1_ADDR(lane),
+	reg_set(COMPHY_PHY_CFG1_ADDR(lane),
 		rb_pin_pu_pll | rb_pin_pu_rx | rb_pin_pu_tx,
 		rb_pin_pu_pll | rb_pin_pu_rx | rb_pin_pu_tx);
 
@@ -793,7 +771,7 @@ static int comphy_sgmii_power_up(u32 lane, u32 speed, u32 invert)
 	 * 20. Wait for PHY power up sequence to finish by checking output ports
 	 *     PIN_PLL_READY_TX=1 and PIN_PLL_READY_RX=1.
 	 */
-	ret = comphy_poll_reg((void *)COMPHY_PHY_STAT1_ADDR(lane), /* address */
+	ret = comphy_poll_reg(COMPHY_PHY_STAT1_ADDR(lane),	/* address */
 			      rb_pll_ready_tx | rb_pll_ready_rx, /* value */
 			      rb_pll_ready_tx | rb_pll_ready_rx, /* mask */
 			      PLL_LOCK_TIMEOUT,			/* timeout */
@@ -804,8 +782,7 @@ static int comphy_sgmii_power_up(u32 lane, u32 speed, u32 invert)
 	/*
 	 * 21. Set COMPHY input port PIN_TX_IDLE=0
 	 */
-	reg_set((void __iomem *)COMPHY_PHY_CFG1_ADDR(lane),
-		0x0, rb_pin_tx_idle);
+	reg_set(COMPHY_PHY_CFG1_ADDR(lane), 0x0, rb_pin_tx_idle);
 
 	/*
 	 * 22. After valid data appear on PIN_RXDATA bus, set PIN_RX_INIT=1.
@@ -815,10 +792,9 @@ static int comphy_sgmii_power_up(u32 lane, u32 speed, u32 invert)
 	 *     PIN_RX_INIT_DONE= 1.
 	 *     Please refer to RX initialization part for details.
 	 */
-	reg_set((void __iomem *)COMPHY_PHY_CFG1_ADDR(lane), rb_phy_rx_init,
-		0x0);
+	reg_set(COMPHY_PHY_CFG1_ADDR(lane), rb_phy_rx_init, 0x0);
 
-	ret = comphy_poll_reg((void *)COMPHY_PHY_STAT1_ADDR(lane), /* address */
+	ret = comphy_poll_reg(COMPHY_PHY_STAT1_ADDR(lane), /* address */
 			      rb_rx_init_done,			/* value */
 			      rb_rx_init_done,			/* mask */
 			      PLL_LOCK_TIMEOUT,		/* timeout */
diff --git a/drivers/phy/marvell/comphy_a3700.h b/drivers/phy/marvell/comphy_a3700.h
index dd60b882dd..33d1f3f77d 100644
--- a/drivers/phy/marvell/comphy_a3700.h
+++ b/drivers/phy/marvell/comphy_a3700.h
@@ -10,7 +10,8 @@
 #include "comphy.h"
 #include "comphy_hpipe.h"
 
-#define MVEBU_REG(offs)			((uintptr_t)MVEBU_REGISTER(offs))
+#define MVEBU_REG(offs)			\
+	((void __iomem *)(ulong)MVEBU_REGISTER(offs))
 
 #define DEFAULT_REFCLK_MHZ		25
 #define PLL_SET_DELAY_US		600
@@ -61,11 +62,12 @@
 #define USB3PHY_SHFT			2
 
 #define SGMIIPHY_BASE(l)	(l == 1 ? USB3PHY_BASE : PCIEPHY_BASE)
-#define SGMIIPHY_ADDR(l, a)	(((a & 0x00007FF) * 2) | SGMIIPHY_BASE(l))
+#define SGMIIPHY_ADDR(l, a)		\
+	((void __iomem *)(((a & 0x00007FF) * 2) + SGMIIPHY_BASE(l)))
 
 #define phy_read16(l, a)	read16((void __iomem *)SGMIIPHY_ADDR(l, a))
 #define phy_write16(l, a, data, mask)	\
-	reg_set16((void __iomem *)SGMIIPHY_ADDR(l, a), data, mask)
+	reg_set16(SGMIIPHY_ADDR(l, a), data, mask)
 
 /* units */
 #define PCIE				1
-- 
2.16.1

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

* [U-Boot] [PATCH v2 02/20] phy: marvell: a3700: Use reg_set16 instead of phy_write16
  2018-04-24 15:21 [U-Boot] [PATCH v2 00/20] More support for Armada 37xx boards (for Turris Mox) Marek Behún
  2018-04-24 15:21 ` [U-Boot] [PATCH v2 01/20] phy: marvell: a3700: Change return type of macro MVEBU_REG Marek Behún
@ 2018-04-24 15:21 ` Marek Behún
  2018-04-24 15:21 ` [U-Boot] [PATCH v2 03/20] phy: marvell: a3700: Don't create functional macro for each register Marek Behún
                   ` (18 subsequent siblings)
  20 siblings, 0 replies; 22+ messages in thread
From: Marek Behún @ 2018-04-24 15:21 UTC (permalink / raw)
  To: u-boot

The macro phy_write16 is not used by the rest of the code,
phy_read16 is not used at all.
We also change the macro SGMIIPHY_ADDR to a static inline function.

Signed-off-by: Marek Behun <marek.behun@nic.cz>
---
 drivers/phy/marvell/comphy_a3700.c | 25 ++++++++++++++-----------
 drivers/phy/marvell/comphy_a3700.h | 15 ++++++++-------
 2 files changed, 22 insertions(+), 18 deletions(-)

diff --git a/drivers/phy/marvell/comphy_a3700.c b/drivers/phy/marvell/comphy_a3700.c
index bf92672275..90c9d02e2c 100644
--- a/drivers/phy/marvell/comphy_a3700.c
+++ b/drivers/phy/marvell/comphy_a3700.c
@@ -611,7 +611,7 @@ static void comphy_sgmii_phy_init(u32 lane, u32 speed)
 			val = sgmii_phy_init[addr];
 		}
 
-		phy_write16(lane, addr, val, 0xFFFF);
+		reg_set16(sgmiiphy_addr(lane, addr), val, 0xFFFF);
 	}
 }
 
@@ -674,26 +674,26 @@ static int comphy_sgmii_power_up(u32 lane, u32 speed, u32 invert)
 	mdelay(10);
 
 	/* 9. Program COMPHY register PHY_MODE */
-	phy_write16(lane, PHY_PWR_PLL_CTRL_ADDR,
-		    PHY_MODE_SGMII << rf_phy_mode_shift, rf_phy_mode_mask);
+	reg_set16(sgmiiphy_addr(lane, PHY_PWR_PLL_CTRL_ADDR),
+		  PHY_MODE_SGMII << rf_phy_mode_shift, rf_phy_mode_mask);
 
 	/*
 	 * 10. Set COMPHY register REFCLK_SEL to select the correct REFCLK
 	 *     source
 	 */
-	phy_write16(lane, PHY_MISC_REG0_ADDR, 0, rb_ref_clk_sel);
+	reg_set16(sgmiiphy_addr(lane, PHY_MISC_REG0_ADDR), 0, rb_ref_clk_sel);
 
 	/*
 	 * 11. Set correct reference clock frequency in COMPHY register
 	 *     REF_FREF_SEL.
 	 */
 	if (get_ref_clk() == 40) {
-		phy_write16(lane, PHY_PWR_PLL_CTRL_ADDR,
-			    0x4 << rf_ref_freq_sel_shift, rf_ref_freq_sel_mask);
+		reg_set16(sgmiiphy_addr(lane, PHY_PWR_PLL_CTRL_ADDR),
+			  0x4 << rf_ref_freq_sel_shift, rf_ref_freq_sel_mask);
 	} else {
 		/* 25MHz */
-		phy_write16(lane, PHY_PWR_PLL_CTRL_ADDR,
-			    0x1 << rf_ref_freq_sel_shift, rf_ref_freq_sel_mask);
+		reg_set16(sgmiiphy_addr(lane, PHY_PWR_PLL_CTRL_ADDR),
+			  0x1 << rf_ref_freq_sel_shift, rf_ref_freq_sel_mask);
 	}
 
 	/* 12. Program COMPHY register PHY_GEN_MAX[1:0] */
@@ -709,7 +709,8 @@ static int comphy_sgmii_power_up(u32 lane, u32 speed, u32 invert)
 	 *     bus width
 	 */
 	/* 10bit */
-	phy_write16(lane, PHY_DIG_LB_EN_ADDR, 0, rf_data_width_mask);
+	reg_set16(sgmiiphy_addr(lane, PHY_DIG_LB_EN_ADDR), 0,
+		  rf_data_width_mask);
 
 	/*
 	 * 14. As long as DFE function needs to be enabled in any mode,
@@ -752,10 +753,12 @@ static int comphy_sgmii_power_up(u32 lane, u32 speed, u32 invert)
 	 * 18. Check the PHY Polarity invert bit
 	 */
 	if (invert & PHY_POLARITY_TXD_INVERT)
-		phy_write16(lane, PHY_SYNC_PATTERN_ADDR, phy_txd_inv, 0);
+		reg_set16(sgmiiphy_addr(lane, PHY_SYNC_PATTERN_ADDR),
+			  phy_txd_inv, 0);
 
 	if (invert & PHY_POLARITY_RXD_INVERT)
-		phy_write16(lane, PHY_SYNC_PATTERN_ADDR, phy_rxd_inv, 0);
+		reg_set16(sgmiiphy_addr(lane, PHY_SYNC_PATTERN_ADDR),
+			  phy_rxd_inv, 0);
 
 	/*
 	 * 19. Set PHY input ports PIN_PU_PLL, PIN_PU_TX and PIN_PU_RX to 1
diff --git a/drivers/phy/marvell/comphy_a3700.h b/drivers/phy/marvell/comphy_a3700.h
index 33d1f3f77d..40f4638e15 100644
--- a/drivers/phy/marvell/comphy_a3700.h
+++ b/drivers/phy/marvell/comphy_a3700.h
@@ -61,13 +61,14 @@
 #define USB32_CTRL_BASE			MVEBU_REG(0x05D800)
 #define USB3PHY_SHFT			2
 
-#define SGMIIPHY_BASE(l)	(l == 1 ? USB3PHY_BASE : PCIEPHY_BASE)
-#define SGMIIPHY_ADDR(l, a)		\
-	((void __iomem *)(((a & 0x00007FF) * 2) + SGMIIPHY_BASE(l)))
-
-#define phy_read16(l, a)	read16((void __iomem *)SGMIIPHY_ADDR(l, a))
-#define phy_write16(l, a, data, mask)	\
-	reg_set16(SGMIIPHY_ADDR(l, a), data, mask)
+static inline void __iomem *sgmiiphy_addr(u32 lane, u32 addr)
+{
+	addr = (addr & 0x00007FF) * 2;
+	if (lane == 1)
+		return PCIEPHY_BASE + addr;
+	else
+		return USB3PHY_BASE + addr;
+}
 
 /* units */
 #define PCIE				1
-- 
2.16.1

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

* [U-Boot] [PATCH v2 03/20] phy: marvell: a3700: Don't create functional macro for each register
  2018-04-24 15:21 [U-Boot] [PATCH v2 00/20] More support for Armada 37xx boards (for Turris Mox) Marek Behún
  2018-04-24 15:21 ` [U-Boot] [PATCH v2 01/20] phy: marvell: a3700: Change return type of macro MVEBU_REG Marek Behún
  2018-04-24 15:21 ` [U-Boot] [PATCH v2 02/20] phy: marvell: a3700: Use reg_set16 instead of phy_write16 Marek Behún
@ 2018-04-24 15:21 ` Marek Behún
  2018-04-24 15:21 ` [U-Boot] [PATCH v2 04/20] phy: marvell: a3700: Use same timeout for all register polling Marek Behún
                   ` (17 subsequent siblings)
  20 siblings, 0 replies; 22+ messages in thread
From: Marek Behún @ 2018-04-24 15:21 UTC (permalink / raw)
  To: u-boot

Currently there is for each register special functional macro, ie:
  LANE_CFG1_ADDR(u)
  GLOB_CLK_SRC_LO_ADDR(u)
  ...
where can be either PCIE or USB3.

Change this to one function PHY_ADDR(unit, addr). The code becomes:
  phy_addr(PCIE, LANE_CFG1)
  phy_addr(PCIE, GLOB_CLK_SRC_LO)
  ...

Signed-off-by: Marek Behun <marek.behun@nic.cz>
---
 drivers/phy/marvell/comphy_a3700.c | 108 ++++++++++++++++++-------------------
 drivers/phy/marvell/comphy_a3700.h |  92 +++++++++++++------------------
 2 files changed, 89 insertions(+), 111 deletions(-)

diff --git a/drivers/phy/marvell/comphy_a3700.c b/drivers/phy/marvell/comphy_a3700.c
index 90c9d02e2c..702ddd7db2 100644
--- a/drivers/phy/marvell/comphy_a3700.c
+++ b/drivers/phy/marvell/comphy_a3700.c
@@ -141,72 +141,70 @@ static int comphy_pcie_power_up(u32 speed, u32 invert)
 	/*
 	 * 1. Enable max PLL.
 	 */
-	reg_set16(LANE_CFG1_ADDR(PCIE), bf_use_max_pll_rate, 0);
+	reg_set16(phy_addr(PCIE, LANE_CFG1), bf_use_max_pll_rate, 0);
 
 	/*
 	 * 2. Select 20 bit SERDES interface.
 	 */
-	reg_set16(GLOB_CLK_SRC_LO_ADDR(PCIE), bf_cfg_sel_20b, 0);
+	reg_set16(phy_addr(PCIE, GLOB_CLK_SRC_LO), bf_cfg_sel_20b, 0);
 
 	/*
 	 * 3. Force to use reg setting for PCIe mode
 	 */
-	reg_set16(MISC_REG1_ADDR(PCIE), bf_sel_bits_pcie_force, 0);
+	reg_set16(phy_addr(PCIE, MISC_REG1), bf_sel_bits_pcie_force, 0);
 
 	/*
 	 * 4. Change RX wait
 	 */
-	reg_set16(PWR_MGM_TIM1_ADDR(PCIE), 0x10C, 0xFFFF);
+	reg_set16(phy_addr(PCIE, PWR_MGM_TIM1), 0x10C, 0xFFFF);
 
 	/*
 	 * 5. Enable idle sync
 	 */
-	reg_set16(UNIT_CTRL_ADDR(PCIE), 0x60 | rb_idle_sync_en, 0xFFFF);
+	reg_set16(phy_addr(PCIE, UNIT_CTRL), 0x60 | rb_idle_sync_en, 0xFFFF);
 
 	/*
 	 * 6. Enable the output of 100M/125M/500M clock
 	 */
-	reg_set16(MISC_REG0_ADDR(PCIE),
+	reg_set16(phy_addr(PCIE, MISC_REG0),
 		  0xA00D | rb_clk500m_en | rb_clk100m_125m_en, 0xFFFF);
 
 	/*
 	 * 7. Enable TX
 	 */
-	reg_set(PHY_REF_CLK_ADDR, 0x1342, 0xFFFFFFFF);
+	reg_set(PCIE_REF_CLK_ADDR, 0x1342, 0xFFFFFFFF);
 
 	/*
 	 * 8. Check crystal jumper setting and program the Power and PLL
 	 *    Control accordingly
 	 */
 	if (get_ref_clk() == 40) {
-		reg_set16(PWR_PLL_CTRL_ADDR(PCIE),
-			  0xFC63, 0xFFFF); /* 40 MHz */
+		/* 40 MHz */
+		reg_set16(phy_addr(PCIE, PWR_PLL_CTRL), 0xFC63, 0xFFFF);
 	} else {
-		reg_set16(PWR_PLL_CTRL_ADDR(PCIE),
-			  0xFC62, 0xFFFF); /* 25 MHz */
+		/* 25 MHz */
+		reg_set16(phy_addr(PCIE, PWR_PLL_CTRL), 0xFC62, 0xFFFF);
 	}
 
 	/*
 	 * 9. Override Speed_PLL value and use MAC PLL
 	 */
-	reg_set16(KVCO_CAL_CTRL_ADDR(PCIE), 0x0040 | rb_use_max_pll_rate,
+	reg_set16(phy_addr(PCIE, KVCO_CAL_CTRL), 0x0040 | rb_use_max_pll_rate,
 		  0xFFFF);
 
 	/*
 	 * 10. Check the Polarity invert bit
 	 */
-	if (invert & PHY_POLARITY_TXD_INVERT) {
-		reg_set16(SYNC_PATTERN_ADDR(PCIE), phy_txd_inv, 0);
-	}
+	if (invert & PHY_POLARITY_TXD_INVERT)
+		reg_set16(phy_addr(PCIE, SYNC_PATTERN), phy_txd_inv, 0);
 
-	if (invert & PHY_POLARITY_RXD_INVERT) {
-		reg_set16(SYNC_PATTERN_ADDR(PCIE), phy_rxd_inv, 0);
-	}
+	if (invert & PHY_POLARITY_RXD_INVERT)
+		reg_set16(phy_addr(PCIE, SYNC_PATTERN), phy_rxd_inv, 0);
 
 	/*
 	 * 11. Release SW reset
 	 */
-	reg_set16(GLOB_PHY_CTRL0_ADDR(PCIE),
+	reg_set16(phy_addr(PCIE, GLOB_PHY_CTRL0),
 		  rb_mode_core_clk_freq_sel | rb_mode_pipe_width_32,
 		  bf_soft_rst | bf_mode_refdiv);
 
@@ -214,11 +212,11 @@ static int comphy_pcie_power_up(u32 speed, u32 invert)
 	udelay(PLL_SET_DELAY_US);
 
 	/* Assert PCLK enabled */
-	ret = comphy_poll_reg(LANE_STAT1_ADDR(PCIE),	/* address */
-			      rb_txdclk_pclk_en,	/* value */
-			      rb_txdclk_pclk_en,	/* mask */
-			      PLL_LOCK_TIMEOUT,		/* timeout */
-			      POLL_16B_REG);		/* 16bit */
+	ret = comphy_poll_reg(phy_addr(PCIE, LANE_STAT1),	/* address */
+			      rb_txdclk_pclk_en,		/* value */
+			      rb_txdclk_pclk_en,		/* mask */
+			      PLL_LOCK_TIMEOUT,			/* timeout */
+			      POLL_16B_REG);			/* 16bit */
 	if (ret == 0)
 		printf("Failed to lock PCIe PLL\n");
 
@@ -322,7 +320,7 @@ static int comphy_usb3_power_up(u32 type, u32 speed, u32 invert)
 
 	/* 0xd005c300 = 0x1001 */
 	/* set PRD_TXDEEMPH (3.5db de-emph) */
-	reg_set16(LANE_CFG0_ADDR(USB3), 0x1, 0xFF);
+	reg_set16(phy_addr(USB3, LANE_CFG0), 0x1, 0xFF);
 
 	/*
 	 * unset BIT0: set Tx Electrical Idle Mode: Transmitter is in
@@ -330,82 +328,83 @@ static int comphy_usb3_power_up(u32 type, u32 speed, u32 invert)
 	 */
 	/* unset BIT4: set G2 Tx Datapath with no Delayed Latency */
 	/* unset BIT6: set Tx Detect Rx Mode at LoZ mode */
-	reg_set16(LANE_CFG1_ADDR(USB3), 0x0, 0xFFFF);
+	reg_set16(phy_addr(USB3, LANE_CFG1), 0x0, 0xFFFF);
 
 
 	/* 0xd005c310 = 0x93: set Spread Spectrum Clock Enabled  */
-	reg_set16(LANE_CFG4_ADDR(USB3), bf_spread_spectrum_clock_en, 0x80);
+	reg_set16(phy_addr(USB3, LANE_CFG4), bf_spread_spectrum_clock_en, 0x80);
 
 	/*
 	 * set Override Margining Controls From the MAC: Use margining signals
 	 * from lane configuration
 	 */
-	reg_set16(TEST_MODE_CTRL_ADDR(USB3), rb_mode_margin_override, 0xFFFF);
+	reg_set16(phy_addr(USB3, TEST_MODE_CTRL), rb_mode_margin_override,
+		  0xFFFF);
 
 	/* set Lane-to-Lane Bundle Clock Sampling Period = per PCLK cycles */
 	/* set Mode Clock Source = PCLK is generated from REFCLK */
-	reg_set16(GLOB_CLK_SRC_LO_ADDR(USB3), 0x0, 0xFF);
+	reg_set16(phy_addr(USB3, GLOB_CLK_SRC_LO), 0x0, 0xFF);
 
 	/* set G2 Spread Spectrum Clock Amplitude at 4K */
-	reg_set16(GEN2_SETTING_2_ADDR(USB3), g2_tx_ssc_amp, 0xF000);
+	reg_set16(phy_addr(USB3, GEN2_SETTINGS_2), g2_tx_ssc_amp, 0xF000);
 
 	/*
 	 * unset G3 Spread Spectrum Clock Amplitude & set G3 TX and RX Register
 	 * Master Current Select
 	 */
-	reg_set16(GEN2_SETTING_3_ADDR(USB3), 0x0, 0xFFFF);
+	reg_set16(phy_addr(USB3, GEN2_SETTINGS_3), 0x0, 0xFFFF);
 
 	/*
 	 * 3. Check crystal jumper setting and program the Power and PLL
 	 * Control accordingly
 	 */
 	if (get_ref_clk() == 40) {
-		reg_set16(PWR_PLL_CTRL_ADDR(USB3), 0xFCA3, 0xFFFF); /* 40 MHz */
+		/* 40 MHz */
+		reg_set16(phy_addr(USB3, PWR_PLL_CTRL), 0xFCA3, 0xFFFF);
 	} else {
-		reg_set16(PWR_PLL_CTRL_ADDR(USB3), 0xFCA2, 0xFFFF); /* 25 MHz */
+		/* 25 MHz */
+		reg_set16(phy_addr(USB3, PWR_PLL_CTRL), 0xFCA2, 0xFFFF);
 	}
 
 	/*
 	 * 4. Change RX wait
 	 */
-	reg_set16(PWR_MGM_TIM1_ADDR(USB3), 0x10C, 0xFFFF);
+	reg_set16(phy_addr(USB3, PWR_MGM_TIM1), 0x10C, 0xFFFF);
 
 	/*
 	 * 5. Enable idle sync
 	 */
-	reg_set16(UNIT_CTRL_ADDR(USB3), 0x60 | rb_idle_sync_en, 0xFFFF);
+	reg_set16(phy_addr(USB3, UNIT_CTRL), 0x60 | rb_idle_sync_en, 0xFFFF);
 
 	/*
 	 * 6. Enable the output of 500M clock
 	 */
-	reg_set16(MISC_REG0_ADDR(USB3), 0xA00D | rb_clk500m_en, 0xFFFF);
+	reg_set16(phy_addr(USB3, MISC_REG0), 0xA00D | rb_clk500m_en, 0xFFFF);
 
 	/*
 	 * 7. Set 20-bit data width
 	 */
-	reg_set16(DIG_LB_EN_ADDR(USB3), 0x0400, 0xFFFF);
+	reg_set16(phy_addr(USB3, DIG_LB_EN), 0x0400, 0xFFFF);
 
 	/*
 	 * 8. Override Speed_PLL value and use MAC PLL
 	 */
-	reg_set16(KVCO_CAL_CTRL_ADDR(USB3), 0x0040 | rb_use_max_pll_rate,
+	reg_set16(phy_addr(USB3, KVCO_CAL_CTRL), 0x0040 | rb_use_max_pll_rate,
 		  0xFFFF);
 
 	/*
 	 * 9. Check the Polarity invert bit
 	 */
-	if (invert & PHY_POLARITY_TXD_INVERT) {
-		reg_set16(SYNC_PATTERN_ADDR(USB3), phy_txd_inv, 0);
-	}
+	if (invert & PHY_POLARITY_TXD_INVERT)
+		reg_set16(phy_addr(USB3, SYNC_PATTERN), phy_txd_inv, 0);
 
-	if (invert & PHY_POLARITY_RXD_INVERT) {
-		reg_set16(SYNC_PATTERN_ADDR(USB3), phy_rxd_inv, 0);
-	}
+	if (invert & PHY_POLARITY_RXD_INVERT)
+		reg_set16(phy_addr(USB3, SYNC_PATTERN), phy_rxd_inv, 0);
 
 	/*
 	 * 10. Release SW reset
 	 */
-	reg_set16(GLOB_PHY_CTRL0_ADDR(USB3),
+	reg_set16(phy_addr(USB3, GLOB_PHY_CTRL0),
 		  rb_mode_core_clk_freq_sel | rb_mode_pipe_width_32 | 0x20,
 		  0xFFFF);
 
@@ -413,7 +412,7 @@ static int comphy_usb3_power_up(u32 type, u32 speed, u32 invert)
 	udelay(PLL_SET_DELAY_US);
 
 	/* Assert PCLK enabled */
-	ret = comphy_poll_reg(LANE_STAT1_ADDR(USB3),	/* address */
+	ret = comphy_poll_reg(phy_addr(USB3, LANE_STAT1),	/* address */
 			      rb_txdclk_pclk_en,	/* value */
 			      rb_txdclk_pclk_en,	/* mask */
 			      PLL_LOCK_TIMEOUT,		/* timeout */
@@ -674,25 +673,25 @@ static int comphy_sgmii_power_up(u32 lane, u32 speed, u32 invert)
 	mdelay(10);
 
 	/* 9. Program COMPHY register PHY_MODE */
-	reg_set16(sgmiiphy_addr(lane, PHY_PWR_PLL_CTRL_ADDR),
+	reg_set16(sgmiiphy_addr(lane, PWR_PLL_CTRL),
 		  PHY_MODE_SGMII << rf_phy_mode_shift, rf_phy_mode_mask);
 
 	/*
 	 * 10. Set COMPHY register REFCLK_SEL to select the correct REFCLK
 	 *     source
 	 */
-	reg_set16(sgmiiphy_addr(lane, PHY_MISC_REG0_ADDR), 0, rb_ref_clk_sel);
+	reg_set16(sgmiiphy_addr(lane, MISC_REG0), 0, rb_ref_clk_sel);
 
 	/*
 	 * 11. Set correct reference clock frequency in COMPHY register
 	 *     REF_FREF_SEL.
 	 */
 	if (get_ref_clk() == 40) {
-		reg_set16(sgmiiphy_addr(lane, PHY_PWR_PLL_CTRL_ADDR),
+		reg_set16(sgmiiphy_addr(lane, PWR_PLL_CTRL),
 			  0x4 << rf_ref_freq_sel_shift, rf_ref_freq_sel_mask);
 	} else {
 		/* 25MHz */
-		reg_set16(sgmiiphy_addr(lane, PHY_PWR_PLL_CTRL_ADDR),
+		reg_set16(sgmiiphy_addr(lane, PWR_PLL_CTRL),
 			  0x1 << rf_ref_freq_sel_shift, rf_ref_freq_sel_mask);
 	}
 
@@ -709,8 +708,7 @@ static int comphy_sgmii_power_up(u32 lane, u32 speed, u32 invert)
 	 *     bus width
 	 */
 	/* 10bit */
-	reg_set16(sgmiiphy_addr(lane, PHY_DIG_LB_EN_ADDR), 0,
-		  rf_data_width_mask);
+	reg_set16(sgmiiphy_addr(lane, DIG_LB_EN), 0, rf_data_width_mask);
 
 	/*
 	 * 14. As long as DFE function needs to be enabled in any mode,
@@ -753,12 +751,10 @@ static int comphy_sgmii_power_up(u32 lane, u32 speed, u32 invert)
 	 * 18. Check the PHY Polarity invert bit
 	 */
 	if (invert & PHY_POLARITY_TXD_INVERT)
-		reg_set16(sgmiiphy_addr(lane, PHY_SYNC_PATTERN_ADDR),
-			  phy_txd_inv, 0);
+		reg_set16(sgmiiphy_addr(lane, SYNC_PATTERN), phy_txd_inv, 0);
 
 	if (invert & PHY_POLARITY_RXD_INVERT)
-		reg_set16(sgmiiphy_addr(lane, PHY_SYNC_PATTERN_ADDR),
-			  phy_rxd_inv, 0);
+		reg_set16(sgmiiphy_addr(lane, SYNC_PATTERN), phy_rxd_inv, 0);
 
 	/*
 	 * 19. Set PHY input ports PIN_PU_PLL, PIN_PU_TX and PIN_PU_RX to 1
diff --git a/drivers/phy/marvell/comphy_a3700.h b/drivers/phy/marvell/comphy_a3700.h
index 40f4638e15..647548b301 100644
--- a/drivers/phy/marvell/comphy_a3700.h
+++ b/drivers/phy/marvell/comphy_a3700.h
@@ -71,116 +71,98 @@ static inline void __iomem *sgmiiphy_addr(u32 lane, u32 addr)
 }
 
 /* units */
-#define PCIE				1
-#define USB3				2
+enum phy_unit {
+	PCIE = 1,
+	USB3 = 2,
+};
 
-#define PHY_BASE(unit)		((unit == PCIE) ? PCIEPHY_BASE : USB3PHY_BASE)
-#define PHY_SHFT(unit)		((unit == PCIE) ? PCIEPHY_SHFT : USB3PHY_SHFT)
+static inline void __iomem *phy_addr(enum phy_unit unit, u32 addr)
+{
+	if (unit == PCIE)
+		return PCIEPHY_BASE + addr * PCIEPHY_SHFT;
+	else
+		return USB3PHY_BASE + addr * USB3PHY_SHFT;
+}
 
 /* bit definition for USB32_CTRL_BASE (USB32 Control Mode) */
 #define usb32_ctrl_id_mode		BIT(0)
 #define usb32_ctrl_soft_id		BIT(1)
 #define usb32_ctrl_int_mode		BIT(4)
 
-
-#define PHY_PWR_PLL_CTRL_ADDR	0x01	/* for phy_read16 and phy_write16 */
-#define PWR_PLL_CTRL_ADDR(unit)		\
-	(PHY_PWR_PLL_CTRL_ADDR * PHY_SHFT(unit) + PHY_BASE(unit))
+#define PWR_PLL_CTRL			0x01
 #define rf_phy_mode_shift		5
 #define rf_phy_mode_mask		(0x7 << rf_phy_mode_shift)
 #define rf_ref_freq_sel_shift		0
 #define rf_ref_freq_sel_mask		(0x1F << rf_ref_freq_sel_shift)
 #define PHY_MODE_SGMII			0x4
 
-/* for phy_read16 and phy_write16 */
-#define PHY_REG_KVCO_CAL_CTRL_ADDR	0x02
-#define KVCO_CAL_CTRL_ADDR(unit)	\
-	(PHY_REG_KVCO_CAL_CTRL_ADDR * PHY_SHFT(unit) + PHY_BASE(unit))
+#define KVCO_CAL_CTRL			0x02
 #define rb_use_max_pll_rate		BIT(12)
 #define rb_force_calibration_done	BIT(9)
 
-/* for phy_read16 and phy_write16 */
-#define PHY_DIG_LB_EN_ADDR		0x23
-#define DIG_LB_EN_ADDR(unit)		\
-	(PHY_DIG_LB_EN_ADDR * PHY_SHFT(unit) + PHY_BASE(unit))
+#define DIG_LB_EN			0x23
 #define rf_data_width_shift		10
 #define rf_data_width_mask		(0x3 << rf_data_width_shift)
 
-/* for phy_read16 and phy_write16 */
-#define PHY_SYNC_PATTERN_ADDR		0x24
-#define SYNC_PATTERN_ADDR(unit)		\
-	(PHY_SYNC_PATTERN_ADDR * PHY_SHFT(unit) + PHY_BASE(unit))
+#define SYNC_PATTERN			0x24
 #define phy_txd_inv			BIT(10)
 #define phy_rxd_inv			BIT(11)
 
-/* for phy_read16 and phy_write16 */
-#define PHY_REG_UNIT_CTRL_ADDR		0x48
-#define UNIT_CTRL_ADDR(unit)		\
-	(PHY_REG_UNIT_CTRL_ADDR * PHY_SHFT(unit) + PHY_BASE(unit))
+#define SYNC_MASK_GEN			0x25
 #define rb_idle_sync_en			BIT(12)
 
-/* for phy_read16 and phy_write16 */
-#define PHY_REG_GEN2_SETTINGS_2		0x3e
-#define GEN2_SETTING_2_ADDR(unit)	\
-	(PHY_REG_GEN2_SETTINGS_2 * PHY_SHFT(unit) + PHY_BASE(unit))
+#define UNIT_CTRL			0x48
+
+#define GEN2_SETTINGS_2			0x3e
 #define g2_tx_ssc_amp			BIT(14)
 
-/* for phy_read16 and phy_write16 */
-#define PHY_REG_GEN2_SETTINGS_3		0x3f
-#define GEN2_SETTING_3_ADDR(unit)	\
-	(PHY_REG_GEN2_SETTINGS_3 * PHY_SHFT(unit) + PHY_BASE(unit))
+#define GEN2_SETTINGS_3			0x3f
+
+#define GEN3_SETTINGS_3			0x112
 
-/* for phy_read16 and phy_write16 */
-#define PHY_MISC_REG0_ADDR		0x4f
-#define MISC_REG0_ADDR(unit)		\
-	(PHY_MISC_REG0_ADDR * PHY_SHFT(unit) + PHY_BASE(unit))
+#define MISC_REG0			0x4f
 #define rb_clk100m_125m_en		BIT(4)
 #define rb_clk500m_en			BIT(7)
 #define rb_ref_clk_sel			BIT(10)
 
-/* for phy_read16 and phy_write16 */
-#define PHY_REG_IFACE_REF_CLK_CTRL_ADDR		0x51
-#define UNIT_IFACE_REF_CLK_CTRL_ADDR(unit)	\
-	(PHY_REG_IFACE_REF_CLK_CTRL_ADDR * PHY_SHFT(unit) + PHY_BASE(unit))
+#define UNIT_IFACE_REF_CLK_CTRL		0x51
 #define rb_ref1m_gen_div_force		BIT(8)
 #define rf_ref1m_gen_div_value_shift	0
 #define rf_ref1m_gen_div_value_mask	(0xFF << rf_ref1m_gen_div_value_shift)
 
-/* for phy_read16 and phy_write16 */
-#define PHY_REG_ERR_CNT_CONST_CTRL_ADDR	0x6A
-#define UNIT_ERR_CNT_CONST_CTRL_ADDR(unit) \
-	(PHY_REG_ERR_CNT_CONST_CTRL_ADDR * PHY_SHFT(unit) + PHY_BASE(unit))
+#define UNIT_ERR_CNT_CONST_CTRL		0x6a
 #define rb_fast_dfe_enable		BIT(13)
 
-#define MISC_REG1_ADDR(u)		(0x73 * PHY_SHFT(u) + PHY_BASE(u))
+#define MISC_REG1			0x73
 #define bf_sel_bits_pcie_force		BIT(15)
 
-#define LANE_CFG0_ADDR(u)		(0x180 * PHY_SHFT(u) + PHY_BASE(u))
+#define LANE_CFG0			0x180
 #define bf_use_max_pll_rate		BIT(9)
-#define LANE_CFG1_ADDR(u)		(0x181 * PHY_SHFT(u) + PHY_BASE(u))
+
+#define LANE_CFG1			0x181
 #define bf_use_max_pll_rate		BIT(9)
-/* 0x5c310 = 0x93 (set BIT7) */
-#define LANE_CFG4_ADDR(u)		(0x188 * PHY_SHFT(u) + PHY_BASE(u))
+
+#define LANE_CFG4			0x188
 #define bf_spread_spectrum_clock_en	BIT(7)
 
-#define LANE_STAT1_ADDR(u)		(0x183 * PHY_SHFT(u) + PHY_BASE(u))
+#define LANE_STAT1			0x183
 #define rb_txdclk_pclk_en		BIT(0)
 
-#define GLOB_PHY_CTRL0_ADDR(u)		(0x1c1 * PHY_SHFT(u) + PHY_BASE(u))
+#define GLOB_PHY_CTRL0			0x1c1
 #define bf_soft_rst			BIT(0)
 #define bf_mode_refdiv			0x30
 #define rb_mode_core_clk_freq_sel	BIT(9)
 #define rb_mode_pipe_width_32		BIT(3)
 
-#define TEST_MODE_CTRL_ADDR(u)		(0x1c2 * PHY_SHFT(u) + PHY_BASE(u))
+#define TEST_MODE_CTRL			0x1c2
 #define rb_mode_margin_override		BIT(2)
 
-#define GLOB_CLK_SRC_LO_ADDR(u)		(0x1c3 * PHY_SHFT(u) + PHY_BASE(u))
+#define GLOB_CLK_SRC_LO			0x1c3
 #define bf_cfg_sel_20b			BIT(15)
 
-#define PWR_MGM_TIM1_ADDR(u)		(0x1d0 * PHY_SHFT(u) + PHY_BASE(u))
+#define PWR_MGM_TIM1			0x1d0
 
-#define PHY_REF_CLK_ADDR		(0x4814 + PCIE_BASE)
+#define PCIE_REF_CLK_ADDR		(PCIE_BASE + 0x4814)
 
 #define USB3_CTRPUL_VAL_REG		(0x20 + USB32_BASE)
 #define USB3H_CTRPUL_VAL_REG		(0x3454 + USB32H_BASE)
-- 
2.16.1

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

* [U-Boot] [PATCH v2 04/20] phy: marvell: a3700: Use same timeout for all register polling
  2018-04-24 15:21 [U-Boot] [PATCH v2 00/20] More support for Armada 37xx boards (for Turris Mox) Marek Behún
                   ` (2 preceding siblings ...)
  2018-04-24 15:21 ` [U-Boot] [PATCH v2 03/20] phy: marvell: a3700: Don't create functional macro for each register Marek Behún
@ 2018-04-24 15:21 ` Marek Behún
  2018-04-24 15:21 ` [U-Boot] [PATCH v2 05/20] phy: marvell: a3700: Use (!ret) instead of (ret == 0) Marek Behún
                   ` (16 subsequent siblings)
  20 siblings, 0 replies; 22+ messages in thread
From: Marek Behún @ 2018-04-24 15:21 UTC (permalink / raw)
  To: u-boot

The timeout is set to PLL_LOCK_TIMEOUT in every call to
comphy_poll_reg. Remove this parameter from the function.

Signed-off-by: Marek Behun <marek.behun@nic.cz>
Reviewed-by: Stefan Roese <sr@denx.de>
---
 drivers/phy/marvell/comphy_a3700.c | 16 +++-------------
 1 file changed, 3 insertions(+), 13 deletions(-)

diff --git a/drivers/phy/marvell/comphy_a3700.c b/drivers/phy/marvell/comphy_a3700.c
index 702ddd7db2..0c06c00796 100644
--- a/drivers/phy/marvell/comphy_a3700.c
+++ b/drivers/phy/marvell/comphy_a3700.c
@@ -106,12 +106,11 @@ static u16 sgmii_phy_init[512] = {
  *
  * return: 1 on success, 0 on timeout
  */
-static u32 comphy_poll_reg(void *addr, u32 val, u32 mask, u32 timeout,
-			   u8 op_type)
+static u32 comphy_poll_reg(void *addr, u32 val, u32 mask, u8 op_type)
 {
-	u32 rval = 0xDEAD;
+	u32 rval = 0xDEAD, timeout;
 
-	for (; timeout > 0; timeout--) {
+	for (timeout = PLL_LOCK_TIMEOUT; timeout > 0; timeout--) {
 		if (op_type == POLL_16B_REG)
 			rval = readw(addr);	/* 16 bit */
 		else
@@ -215,7 +214,6 @@ static int comphy_pcie_power_up(u32 speed, u32 invert)
 	ret = comphy_poll_reg(phy_addr(PCIE, LANE_STAT1),	/* address */
 			      rb_txdclk_pclk_en,		/* value */
 			      rb_txdclk_pclk_en,		/* mask */
-			      PLL_LOCK_TIMEOUT,			/* timeout */
 			      POLL_16B_REG);			/* 16bit */
 	if (ret == 0)
 		printf("Failed to lock PCIe PLL\n");
@@ -285,7 +283,6 @@ static int comphy_sata_power_up(void)
 	ret = comphy_poll_reg(rh_vsreg_data,	/* address */
 			      bs_pll_ready_tx,	/* value */
 			      bs_pll_ready_tx,	/* mask */
-			      PLL_LOCK_TIMEOUT,	/* timeout */
 			      POLL_32B_REG);	/* 32bit */
 	if (ret == 0)
 		printf("Failed to lock SATA PLL\n");
@@ -415,7 +412,6 @@ static int comphy_usb3_power_up(u32 type, u32 speed, u32 invert)
 	ret = comphy_poll_reg(phy_addr(USB3, LANE_STAT1),	/* address */
 			      rb_txdclk_pclk_en,	/* value */
 			      rb_txdclk_pclk_en,	/* mask */
-			      PLL_LOCK_TIMEOUT,		/* timeout */
 			      POLL_16B_REG);		/* 16bit */
 	if (ret == 0)
 		printf("Failed to lock USB3 PLL\n");
@@ -496,7 +492,6 @@ static int comphy_usb2_power_up(u8 usb32)
 	ret = comphy_poll_reg(USB2_PHY_CAL_CTRL_ADDR(usb32),
 			      rb_usb2phy_pllcal_done,	/* value */
 			      rb_usb2phy_pllcal_done,	/* mask */
-			      PLL_LOCK_TIMEOUT,		/* timeout */
 			      POLL_32B_REG);		/* 32bit */
 	if (ret == 0)
 		printf("Failed to end USB2 PLL calibration\n");
@@ -505,7 +500,6 @@ static int comphy_usb2_power_up(u8 usb32)
 	ret = comphy_poll_reg(USB2_PHY_CAL_CTRL_ADDR(usb32),
 			      rb_usb2phy_impcal_done,	/* value */
 			      rb_usb2phy_impcal_done,	/* mask */
-			      PLL_LOCK_TIMEOUT,		/* timeout */
 			      POLL_32B_REG);		/* 32bit */
 	if (ret == 0)
 		printf("Failed to end USB2 impedance calibration\n");
@@ -514,7 +508,6 @@ static int comphy_usb2_power_up(u8 usb32)
 	ret = comphy_poll_reg(USB2_PHY_RX_CHAN_CTRL1_ADDR(usb32),
 			      rb_usb2phy_sqcal_done,	/* value */
 			      rb_usb2phy_sqcal_done,	/* mask */
-			      PLL_LOCK_TIMEOUT,		/* timeout */
 			      POLL_32B_REG);		/* 32bit */
 	if (ret == 0)
 		printf("Failed to end USB2 unknown calibration\n");
@@ -523,7 +516,6 @@ static int comphy_usb2_power_up(u8 usb32)
 	ret = comphy_poll_reg(USB2_PHY_PLL_CTRL0_ADDR(usb32),
 			      rb_usb2phy_pll_ready,		/* value */
 			      rb_usb2phy_pll_ready,		/* mask */
-			      PLL_LOCK_TIMEOUT,		/* timeout */
 			      POLL_32B_REG);		/* 32bit */
 
 	if (ret == 0)
@@ -773,7 +765,6 @@ static int comphy_sgmii_power_up(u32 lane, u32 speed, u32 invert)
 	ret = comphy_poll_reg(COMPHY_PHY_STAT1_ADDR(lane),	/* address */
 			      rb_pll_ready_tx | rb_pll_ready_rx, /* value */
 			      rb_pll_ready_tx | rb_pll_ready_rx, /* mask */
-			      PLL_LOCK_TIMEOUT,			/* timeout */
 			      POLL_32B_REG);			/* 32bit */
 	if (ret == 0)
 		printf("Failed to lock PLL for SGMII PHY %d\n", lane);
@@ -796,7 +787,6 @@ static int comphy_sgmii_power_up(u32 lane, u32 speed, u32 invert)
 	ret = comphy_poll_reg(COMPHY_PHY_STAT1_ADDR(lane), /* address */
 			      rb_rx_init_done,			/* value */
 			      rb_rx_init_done,			/* mask */
-			      PLL_LOCK_TIMEOUT,		/* timeout */
 			      POLL_32B_REG);			/* 32bit */
 	if (ret == 0)
 		printf("Failed to init RX of SGMII PHY %d\n", lane);
-- 
2.16.1

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

* [U-Boot] [PATCH v2 05/20] phy: marvell: a3700: Use (!ret) instead of (ret == 0)
  2018-04-24 15:21 [U-Boot] [PATCH v2 00/20] More support for Armada 37xx boards (for Turris Mox) Marek Behún
                   ` (3 preceding siblings ...)
  2018-04-24 15:21 ` [U-Boot] [PATCH v2 04/20] phy: marvell: a3700: Use same timeout for all register polling Marek Behún
@ 2018-04-24 15:21 ` Marek Behún
  2018-04-24 15:21 ` [U-Boot] [PATCH v2 06/20] phy: marvell: a3700: Use reg_set_indirect istead of 2 reg_sets Marek Behún
                   ` (15 subsequent siblings)
  20 siblings, 0 replies; 22+ messages in thread
From: Marek Behún @ 2018-04-24 15:21 UTC (permalink / raw)
  To: u-boot

In U-Boot it is usually written this way.

Signed-off-by: Marek Behun <marek.behun@nic.cz>
Reviewed-by: Stefan Roese <sr@denx.de>
---
 drivers/phy/marvell/comphy_a3700.c | 26 +++++++++++++-------------
 1 file changed, 13 insertions(+), 13 deletions(-)

diff --git a/drivers/phy/marvell/comphy_a3700.c b/drivers/phy/marvell/comphy_a3700.c
index 0c06c00796..429ad6b018 100644
--- a/drivers/phy/marvell/comphy_a3700.c
+++ b/drivers/phy/marvell/comphy_a3700.c
@@ -215,7 +215,7 @@ static int comphy_pcie_power_up(u32 speed, u32 invert)
 			      rb_txdclk_pclk_en,		/* value */
 			      rb_txdclk_pclk_en,		/* mask */
 			      POLL_16B_REG);			/* 16bit */
-	if (ret == 0)
+	if (!ret)
 		printf("Failed to lock PCIe PLL\n");
 
 	debug_exit();
@@ -284,7 +284,7 @@ static int comphy_sata_power_up(void)
 			      bs_pll_ready_tx,	/* value */
 			      bs_pll_ready_tx,	/* mask */
 			      POLL_32B_REG);	/* 32bit */
-	if (ret == 0)
+	if (!ret)
 		printf("Failed to lock SATA PLL\n");
 
 	debug_exit();
@@ -413,7 +413,7 @@ static int comphy_usb3_power_up(u32 type, u32 speed, u32 invert)
 			      rb_txdclk_pclk_en,	/* value */
 			      rb_txdclk_pclk_en,	/* mask */
 			      POLL_16B_REG);		/* 16bit */
-	if (ret == 0)
+	if (!ret)
 		printf("Failed to lock USB3 PLL\n");
 
 	/*
@@ -493,7 +493,7 @@ static int comphy_usb2_power_up(u8 usb32)
 			      rb_usb2phy_pllcal_done,	/* value */
 			      rb_usb2phy_pllcal_done,	/* mask */
 			      POLL_32B_REG);		/* 32bit */
-	if (ret == 0)
+	if (!ret)
 		printf("Failed to end USB2 PLL calibration\n");
 
 	/* Assert impedance calibration done */
@@ -501,7 +501,7 @@ static int comphy_usb2_power_up(u8 usb32)
 			      rb_usb2phy_impcal_done,	/* value */
 			      rb_usb2phy_impcal_done,	/* mask */
 			      POLL_32B_REG);		/* 32bit */
-	if (ret == 0)
+	if (!ret)
 		printf("Failed to end USB2 impedance calibration\n");
 
 	/* Assert squetch calibration done */
@@ -509,7 +509,7 @@ static int comphy_usb2_power_up(u8 usb32)
 			      rb_usb2phy_sqcal_done,	/* value */
 			      rb_usb2phy_sqcal_done,	/* mask */
 			      POLL_32B_REG);		/* 32bit */
-	if (ret == 0)
+	if (!ret)
 		printf("Failed to end USB2 unknown calibration\n");
 
 	/* Assert PLL is ready */
@@ -518,7 +518,7 @@ static int comphy_usb2_power_up(u8 usb32)
 			      rb_usb2phy_pll_ready,		/* mask */
 			      POLL_32B_REG);		/* 32bit */
 
-	if (ret == 0)
+	if (!ret)
 		printf("Failed to lock USB2 PLL\n");
 
 	debug_exit();
@@ -766,7 +766,7 @@ static int comphy_sgmii_power_up(u32 lane, u32 speed, u32 invert)
 			      rb_pll_ready_tx | rb_pll_ready_rx, /* value */
 			      rb_pll_ready_tx | rb_pll_ready_rx, /* mask */
 			      POLL_32B_REG);			/* 32bit */
-	if (ret == 0)
+	if (!ret)
 		printf("Failed to lock PLL for SGMII PHY %d\n", lane);
 
 	/*
@@ -788,7 +788,7 @@ static int comphy_sgmii_power_up(u32 lane, u32 speed, u32 invert)
 			      rb_rx_init_done,			/* value */
 			      rb_rx_init_done,			/* mask */
 			      POLL_32B_REG);			/* 32bit */
-	if (ret == 0)
+	if (!ret)
 		printf("Failed to init RX of SGMII PHY %d\n", lane);
 
 	debug_exit();
@@ -819,7 +819,7 @@ void comphy_dedicated_phys_init(void)
 		if (node > 0) {
 			if (fdtdec_get_is_enabled(blob, node)) {
 				ret = comphy_usb2_power_up(usb32);
-				if (ret == 0)
+				if (!ret)
 					printf("Failed to initialize UTMI PHY\n");
 				else
 					debug("UTMI PHY init succeed\n");
@@ -837,7 +837,7 @@ void comphy_dedicated_phys_init(void)
 	if (node > 0) {
 		if (fdtdec_get_is_enabled(blob, node)) {
 			ret = comphy_sata_power_up();
-			if (ret == 0)
+			if (!ret)
 				printf("Failed to initialize SATA PHY\n");
 			else
 				debug("SATA PHY init succeed\n");
@@ -858,7 +858,7 @@ void comphy_dedicated_phys_init(void)
 	if (node > 0) {
 		if (fdtdec_get_is_enabled(blob, node)) {
 			ret = comphy_emmc_power_up();
-			if (ret == 0)
+			if (!ret)
 				printf("Failed to initialize SDIO/eMMC PHY\n");
 			else
 				debug("SDIO/eMMC PHY init succeed\n");
@@ -916,7 +916,7 @@ int comphy_a3700_init(struct chip_serdes_phy_config *chip_cfg,
 			ret = 1;
 			break;
 		}
-		if (ret == 0)
+		if (!ret)
 			printf("PLL is not locked - Failed to initialize lane %d\n",
 			       lane);
 	}
-- 
2.16.1

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

* [U-Boot] [PATCH v2 06/20] phy: marvell: a3700: Use reg_set_indirect istead of 2 reg_sets
  2018-04-24 15:21 [U-Boot] [PATCH v2 00/20] More support for Armada 37xx boards (for Turris Mox) Marek Behún
                   ` (4 preceding siblings ...)
  2018-04-24 15:21 ` [U-Boot] [PATCH v2 05/20] phy: marvell: a3700: Use (!ret) instead of (ret == 0) Marek Behún
@ 2018-04-24 15:21 ` Marek Behún
  2018-04-24 15:21 ` [U-Boot] [PATCH v2 07/20] phy: marvell: a3700: Access USB3 register indirectly on lane 2 Marek Behún
                   ` (14 subsequent siblings)
  20 siblings, 0 replies; 22+ messages in thread
From: Marek Behún @ 2018-04-24 15:21 UTC (permalink / raw)
  To: u-boot

Create a special function for indirect register setting,
reg_set_indirect, and use it instead of the two calls to reg_set.

Signed-off-by: Marek Behun <marek.behun@nic.cz>
Reviewed-by: Stefan Roese <sr@denx.de>
---
 drivers/phy/marvell/comphy_a3700.c | 32 ++++++++++++++++++++------------
 1 file changed, 20 insertions(+), 12 deletions(-)

diff --git a/drivers/phy/marvell/comphy_a3700.c b/drivers/phy/marvell/comphy_a3700.c
index 429ad6b018..d289bdf434 100644
--- a/drivers/phy/marvell/comphy_a3700.c
+++ b/drivers/phy/marvell/comphy_a3700.c
@@ -224,6 +224,17 @@ static int comphy_pcie_power_up(u32 speed, u32 invert)
 	return ret;
 }
 
+/*
+ * reg_set_indirect
+ *
+ * return: void
+ */
+static void reg_set_indirect(u32 reg, u16 data, u16 mask)
+{
+	reg_set(rh_vsreg_addr, reg, 0xFFFFFFFF);
+	reg_set(rh_vsreg_data, data, mask);
+}
+
 /*
  * comphy_sata_power_up
  *
@@ -231,43 +242,40 @@ static int comphy_pcie_power_up(u32 speed, u32 invert)
  */
 static int comphy_sata_power_up(void)
 {
-	int	ret;
+	int ret;
 
 	debug_enter();
 
 	/*
 	 * 0. Swap SATA TX lines
 	 */
-	reg_set(rh_vsreg_addr, vphy_sync_pattern_reg, 0xFFFFFFFF);
-	reg_set(rh_vsreg_data, bs_txd_inv, bs_txd_inv);
+	reg_set_indirect(vphy_sync_pattern_reg, bs_txd_inv, bs_txd_inv);
 
 	/*
 	 * 1. Select 40-bit data width width
 	 */
-	reg_set(rh_vsreg_addr, vphy_loopback_reg0, 0xFFFFFFFF);
-	reg_set(rh_vsreg_data, 0x800, bs_phyintf_40bit);
+	reg_set_indirect(vphy_loopback_reg0, 0x800, bs_phyintf_40bit);
 
 	/*
 	 * 2. Select reference clock and PHY mode (SATA)
 	 */
-	reg_set(rh_vsreg_addr, vphy_power_reg0, 0xFFFFFFFF);
 	if (get_ref_clk() == 40) {
-		reg_set(rh_vsreg_data, 0x3, 0x00FF); /* 40 MHz */
+		/* 40 MHz */
+		reg_set_indirect(vphy_power_reg0, 0x3, 0x00FF);
 	} else {
-		reg_set(rh_vsreg_data, 0x1, 0x00FF); /* 25 MHz */
+		/* 20 MHz */
+		reg_set_indirect(vphy_power_reg0, 0x1, 0x00FF);
 	}
 
 	/*
 	 * 3. Use maximum PLL rate (no power save)
 	 */
-	reg_set(rh_vsreg_addr, vphy_calctl_reg, 0xFFFFFFFF);
-	reg_set(rh_vsreg_data, bs_max_pll_rate, bs_max_pll_rate);
+	reg_set_indirect(vphy_calctl_reg, bs_max_pll_rate, bs_max_pll_rate);
 
 	/*
 	 * 4. Reset reserved bit (??)
 	 */
-	reg_set(rh_vsreg_addr, vphy_reserve_reg, 0xFFFFFFFF);
-	reg_set(rh_vsreg_data, 0, bs_phyctrl_frm_pin);
+	reg_set_indirect(vphy_reserve_reg, 0, bs_phyctrl_frm_pin);
 
 	/*
 	 * 5. Set vendor-specific configuration (??)
-- 
2.16.1

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

* [U-Boot] [PATCH v2 07/20] phy: marvell: a3700: Access USB3 register indirectly on lane 2
  2018-04-24 15:21 [U-Boot] [PATCH v2 00/20] More support for Armada 37xx boards (for Turris Mox) Marek Behún
                   ` (5 preceding siblings ...)
  2018-04-24 15:21 ` [U-Boot] [PATCH v2 06/20] phy: marvell: a3700: Use reg_set_indirect istead of 2 reg_sets Marek Behún
@ 2018-04-24 15:21 ` Marek Behún
  2018-04-24 15:21 ` [U-Boot] [PATCH v2 08/20] phy: marvell: a3700: Set USB3 RX wait depending on ref clock Marek Behún
                   ` (13 subsequent siblings)
  20 siblings, 0 replies; 22+ messages in thread
From: Marek Behún @ 2018-04-24 15:21 UTC (permalink / raw)
  To: u-boot

When USB3 is on comphy lane 2 on the Armada 37xx, the registers
have to be accessed indirectly via SATA indirect access.

This is the case of the Turris Mox board from CZ.NIC.

Signed-off-by: Marek Behun <marek.behun@nic.cz>
---
 drivers/phy/marvell/comphy_a3700.c | 102 ++++++++++++++++++++++++-------------
 drivers/phy/marvell/comphy_a3700.h |   1 +
 2 files changed, 68 insertions(+), 35 deletions(-)

diff --git a/drivers/phy/marvell/comphy_a3700.c b/drivers/phy/marvell/comphy_a3700.c
index d289bdf434..bcfe89e636 100644
--- a/drivers/phy/marvell/comphy_a3700.c
+++ b/drivers/phy/marvell/comphy_a3700.c
@@ -133,7 +133,7 @@ static u32 comphy_poll_reg(void *addr, u32 val, u32 mask, u8 op_type)
  */
 static int comphy_pcie_power_up(u32 speed, u32 invert)
 {
-	int	ret;
+	int ret;
 
 	debug_enter();
 
@@ -300,14 +300,36 @@ static int comphy_sata_power_up(void)
 	return ret;
 }
 
+/*
+ * usb3_reg_set16
+ *
+ * return: void
+ */
+static void usb3_reg_set16(u32 reg, u16 data, u16 mask, u32 lane)
+{
+	/*
+	 * When Lane 2 PHY is for USB3, access the PHY registers
+	 * through indirect Address and Data registers INDIR_ACC_PHY_ADDR
+	 * (RD00E0178h [31:0]) and INDIR_ACC_PHY_DATA (RD00E017Ch [31:0])
+	 * within the SATA Host Controller registers, Lane 2 base register
+	 * offset is 0x200
+	 */
+
+	if (lane == 2)
+		reg_set_indirect(USB3PHY_LANE2_REG_BASE_OFFSET + reg, data,
+				 mask);
+	else
+		reg_set16(phy_addr(USB3, reg), data, mask);
+}
+
 /*
  * comphy_usb3_power_up
  *
  * return: 1 if PLL locked (OK), 0 otherwise (FAIL)
  */
-static int comphy_usb3_power_up(u32 type, u32 speed, u32 invert)
+static int comphy_usb3_power_up(u32 lane, u32 type, u32 speed, u32 invert)
 {
-	int	ret;
+	int ret;
 
 	debug_enter();
 
@@ -325,39 +347,38 @@ static int comphy_usb3_power_up(u32 type, u32 speed, u32 invert)
 
 	/* 0xd005c300 = 0x1001 */
 	/* set PRD_TXDEEMPH (3.5db de-emph) */
-	reg_set16(phy_addr(USB3, LANE_CFG0), 0x1, 0xFF);
+	usb3_reg_set16(LANE_CFG0, 0x1, 0xFF, lane);
 
 	/*
 	 * unset BIT0: set Tx Electrical Idle Mode: Transmitter is in
-	 * low impedance mode during electrical idle
+	 *             low impedance mode during electrical idle
+	 * unset BIT4: set G2 Tx Datapath with no Delayed Latency
+	 * unset BIT6: set Tx Detect Rx Mode at LoZ mode
 	 */
-	/* unset BIT4: set G2 Tx Datapath with no Delayed Latency */
-	/* unset BIT6: set Tx Detect Rx Mode at LoZ mode */
-	reg_set16(phy_addr(USB3, LANE_CFG1), 0x0, 0xFFFF);
+	usb3_reg_set16(LANE_CFG1, 0x0, 0xFFFF, lane);
 
 
-	/* 0xd005c310 = 0x93: set Spread Spectrum Clock Enabled  */
-	reg_set16(phy_addr(USB3, LANE_CFG4), bf_spread_spectrum_clock_en, 0x80);
+	/* 0xd005c310 = 0x93: set Spread Spectrum Clock Enabled */
+	usb3_reg_set16(LANE_CFG4, bf_spread_spectrum_clock_en, 0x80, lane);
 
 	/*
 	 * set Override Margining Controls From the MAC: Use margining signals
 	 * from lane configuration
 	 */
-	reg_set16(phy_addr(USB3, TEST_MODE_CTRL), rb_mode_margin_override,
-		  0xFFFF);
+	usb3_reg_set16(TEST_MODE_CTRL, rb_mode_margin_override, 0xFFFF, lane);
 
 	/* set Lane-to-Lane Bundle Clock Sampling Period = per PCLK cycles */
 	/* set Mode Clock Source = PCLK is generated from REFCLK */
-	reg_set16(phy_addr(USB3, GLOB_CLK_SRC_LO), 0x0, 0xFF);
+	usb3_reg_set16(GLOB_CLK_SRC_LO, 0x0, 0xFF, lane);
 
 	/* set G2 Spread Spectrum Clock Amplitude at 4K */
-	reg_set16(phy_addr(USB3, GEN2_SETTINGS_2), g2_tx_ssc_amp, 0xF000);
+	usb3_reg_set16(GEN2_SETTINGS_2, g2_tx_ssc_amp, 0xF000, lane);
 
 	/*
 	 * unset G3 Spread Spectrum Clock Amplitude & set G3 TX and RX Register
 	 * Master Current Select
 	 */
-	reg_set16(phy_addr(USB3, GEN2_SETTINGS_3), 0x0, 0xFFFF);
+	usb3_reg_set16(GEN2_SETTINGS_3, 0x0, 0xFFFF, lane);
 
 	/*
 	 * 3. Check crystal jumper setting and program the Power and PLL
@@ -365,62 +386,72 @@ static int comphy_usb3_power_up(u32 type, u32 speed, u32 invert)
 	 */
 	if (get_ref_clk() == 40) {
 		/* 40 MHz */
-		reg_set16(phy_addr(USB3, PWR_PLL_CTRL), 0xFCA3, 0xFFFF);
+		usb3_reg_set16(PWR_PLL_CTRL, 0xFCA3, 0xFFFF, lane);
 	} else {
 		/* 25 MHz */
-		reg_set16(phy_addr(USB3, PWR_PLL_CTRL), 0xFCA2, 0xFFFF);
+		usb3_reg_set16(PWR_PLL_CTRL, 0xFCA2, 0xFFFF, lane);
 	}
 
 	/*
 	 * 4. Change RX wait
 	 */
-	reg_set16(phy_addr(USB3, PWR_MGM_TIM1), 0x10C, 0xFFFF);
+	usb3_reg_set16(PWR_MGM_TIM1, 0x10C, 0xFFFF, lane);
 
 	/*
 	 * 5. Enable idle sync
 	 */
-	reg_set16(phy_addr(USB3, UNIT_CTRL), 0x60 | rb_idle_sync_en, 0xFFFF);
+	usb3_reg_set16(UNIT_CTRL, 0x60 | rb_idle_sync_en, 0xFFFF, lane);
 
 	/*
 	 * 6. Enable the output of 500M clock
 	 */
-	reg_set16(phy_addr(USB3, MISC_REG0), 0xA00D | rb_clk500m_en, 0xFFFF);
+	usb3_reg_set16(MISC_REG0, 0xA00D | rb_clk500m_en, 0xFFFF, lane);
 
 	/*
 	 * 7. Set 20-bit data width
 	 */
-	reg_set16(phy_addr(USB3, DIG_LB_EN), 0x0400, 0xFFFF);
+	usb3_reg_set16(DIG_LB_EN, 0x0400, 0xFFFF, lane);
 
 	/*
 	 * 8. Override Speed_PLL value and use MAC PLL
 	 */
-	reg_set16(phy_addr(USB3, KVCO_CAL_CTRL), 0x0040 | rb_use_max_pll_rate,
-		  0xFFFF);
+	usb3_reg_set16(KVCO_CAL_CTRL, 0x0040 | rb_use_max_pll_rate, 0xFFFF,
+		       lane);
 
 	/*
 	 * 9. Check the Polarity invert bit
 	 */
 	if (invert & PHY_POLARITY_TXD_INVERT)
-		reg_set16(phy_addr(USB3, SYNC_PATTERN), phy_txd_inv, 0);
+		usb3_reg_set16(SYNC_PATTERN, phy_txd_inv, 0, lane);
 
 	if (invert & PHY_POLARITY_RXD_INVERT)
-		reg_set16(phy_addr(USB3, SYNC_PATTERN), phy_rxd_inv, 0);
+		usb3_reg_set16(SYNC_PATTERN, phy_rxd_inv, 0, lane);
 
 	/*
 	 * 10. Release SW reset
 	 */
-	reg_set16(phy_addr(USB3, GLOB_PHY_CTRL0),
-		  rb_mode_core_clk_freq_sel | rb_mode_pipe_width_32 | 0x20,
-		  0xFFFF);
+	usb3_reg_set16(GLOB_PHY_CTRL0,
+		       rb_mode_core_clk_freq_sel | rb_mode_pipe_width_32
+		       | 0x20, 0xFFFF, lane);
 
 	/* Wait for > 55 us to allow PCLK be enabled */
 	udelay(PLL_SET_DELAY_US);
 
 	/* Assert PCLK enabled */
-	ret = comphy_poll_reg(phy_addr(USB3, LANE_STAT1),	/* address */
-			      rb_txdclk_pclk_en,	/* value */
-			      rb_txdclk_pclk_en,	/* mask */
-			      POLL_16B_REG);		/* 16bit */
+	if (lane == 2) {
+		reg_set(rh_vsreg_addr,
+			LANE_STAT1 + USB3PHY_LANE2_REG_BASE_OFFSET,
+			0xFFFFFFFF);
+		ret = comphy_poll_reg(rh_vsreg_data,		/* address */
+				      rb_txdclk_pclk_en,	/* value */
+				      rb_txdclk_pclk_en,	/* mask */
+				      POLL_32B_REG);		/* 32bit */
+	} else {
+		ret = comphy_poll_reg(phy_addr(USB3, LANE_STAT1), /* address */
+				      rb_txdclk_pclk_en,	  /* value */
+				      rb_txdclk_pclk_en,	  /* mask */
+				      POLL_16B_REG);		  /* 16bit */
+	}
 	if (!ret)
 		printf("Failed to lock USB3 PLL\n");
 
@@ -456,7 +487,7 @@ static int comphy_usb3_power_up(u32 type, u32 speed, u32 invert)
  */
 static int comphy_usb2_power_up(u8 usb32)
 {
-	int	ret;
+	int ret;
 
 	debug_enter();
 
@@ -621,7 +652,7 @@ static void comphy_sgmii_phy_init(u32 lane, u32 speed)
  */
 static int comphy_sgmii_power_up(u32 lane, u32 speed, u32 invert)
 {
-	int	ret;
+	int ret;
 
 	debug_enter();
 
@@ -907,7 +938,8 @@ int comphy_a3700_init(struct chip_serdes_phy_config *chip_cfg,
 
 		case PHY_TYPE_USB3_HOST0:
 		case PHY_TYPE_USB3_DEVICE:
-			ret = comphy_usb3_power_up(comphy_map->type,
+			ret = comphy_usb3_power_up(lane,
+						   comphy_map->type,
 						   comphy_map->speed,
 						   comphy_map->invert);
 			break;
diff --git a/drivers/phy/marvell/comphy_a3700.h b/drivers/phy/marvell/comphy_a3700.h
index 647548b301..51c95c1618 100644
--- a/drivers/phy/marvell/comphy_a3700.h
+++ b/drivers/phy/marvell/comphy_a3700.h
@@ -60,6 +60,7 @@
 #define USB2PHY2_BASE			MVEBU_REG(0x05F000)
 #define USB32_CTRL_BASE			MVEBU_REG(0x05D800)
 #define USB3PHY_SHFT			2
+#define USB3PHY_LANE2_REG_BASE_OFFSET	0x200
 
 static inline void __iomem *sgmiiphy_addr(u32 lane, u32 addr)
 {
-- 
2.16.1

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

* [U-Boot] [PATCH v2 08/20] phy: marvell: a3700: Set USB3 RX wait depending on ref clock
  2018-04-24 15:21 [U-Boot] [PATCH v2 00/20] More support for Armada 37xx boards (for Turris Mox) Marek Behún
                   ` (6 preceding siblings ...)
  2018-04-24 15:21 ` [U-Boot] [PATCH v2 07/20] phy: marvell: a3700: Access USB3 register indirectly on lane 2 Marek Behún
@ 2018-04-24 15:21 ` Marek Behún
  2018-04-24 15:21 ` [U-Boot] [PATCH v2 09/20] phy: marvell: a3700: revise the USB3 comphy setting during power on Marek Behún
                   ` (12 subsequent siblings)
  20 siblings, 0 replies; 22+ messages in thread
From: Marek Behún @ 2018-04-24 15:21 UTC (permalink / raw)
  To: u-boot

According to specification, CFG_PM_RXDLOZ_WAIT should be set to 0x7
when reference clock is at 25 MHz. The specification (at least the
version I have) does not mentoin the setting for 40 MHz reference
clock, but Marvell's U-Boot sets 0xC in that case.

Signed-off-by: Marek Behun <marek.behun@nic.cz>
Reviewed-by: Stefan Roese <sr@denx.de>
---
 drivers/phy/marvell/comphy_a3700.c | 8 +++-----
 1 file changed, 3 insertions(+), 5 deletions(-)

diff --git a/drivers/phy/marvell/comphy_a3700.c b/drivers/phy/marvell/comphy_a3700.c
index bcfe89e636..82dffc4f83 100644
--- a/drivers/phy/marvell/comphy_a3700.c
+++ b/drivers/phy/marvell/comphy_a3700.c
@@ -383,20 +383,18 @@ static int comphy_usb3_power_up(u32 lane, u32 type, u32 speed, u32 invert)
 	/*
 	 * 3. Check crystal jumper setting and program the Power and PLL
 	 * Control accordingly
+	 * 4. Change RX wait
 	 */
 	if (get_ref_clk() == 40) {
 		/* 40 MHz */
 		usb3_reg_set16(PWR_PLL_CTRL, 0xFCA3, 0xFFFF, lane);
+		usb3_reg_set16(PWR_MGM_TIM1, 0x10C, 0xFFFF, lane);
 	} else {
 		/* 25 MHz */
 		usb3_reg_set16(PWR_PLL_CTRL, 0xFCA2, 0xFFFF, lane);
+		usb3_reg_set16(PWR_MGM_TIM1, 0x107, 0xFFFF, lane);
 	}
 
-	/*
-	 * 4. Change RX wait
-	 */
-	usb3_reg_set16(PWR_MGM_TIM1, 0x10C, 0xFFFF, lane);
-
 	/*
 	 * 5. Enable idle sync
 	 */
-- 
2.16.1

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

* [U-Boot] [PATCH v2 09/20] phy: marvell: a3700: revise the USB3 comphy setting during power on
  2018-04-24 15:21 [U-Boot] [PATCH v2 00/20] More support for Armada 37xx boards (for Turris Mox) Marek Behún
                   ` (7 preceding siblings ...)
  2018-04-24 15:21 ` [U-Boot] [PATCH v2 08/20] phy: marvell: a3700: Set USB3 RX wait depending on ref clock Marek Behún
@ 2018-04-24 15:21 ` Marek Behún
  2018-04-24 15:21 ` [U-Boot] [PATCH v2 10/20] phy: marvell: mux: Support nontrivial node order in selector register Marek Behún
                   ` (11 subsequent siblings)
  20 siblings, 0 replies; 22+ messages in thread
From: Marek Behún @ 2018-04-24 15:21 UTC (permalink / raw)
  To: u-boot

From: zachary <zhangzg@marvell.com>

This commit is based on commit d9899826 by
  zachary <zhangzg@marvell.com>
from u-boot-marvell, see
github.com/MarvellEmbeddedProcessors/u-boot-marvell/commit/d9899826

- According to design specification, the transmitter should be set to high
  impedence mode during electrical idle. Thus transmitter should detect RX
  at high impedence mode also, and delay is needed to accommodate high
  impedence off latency. Otherwise the USB3 will have detection issue that
  most of the time the USB3 device can not be detected at all, or be
  detected as USB2 device sometimes.
  Modified registers: RD005C302h (R181h) (0051h) Lane Configuration 1
  Bit 6: set to 1 to let Tx detect Rx at HiZ mode
  Bit [3:4]: set to 2 to be delayed by 2 clock cycles
  Bit 0: set to 1 to set transmitter to high impedance mode during idle.
- USB3 De-emphasize level of -3.5dB is mandatory, but USB3 MAC selects 0x2
  (emphasize disabled) in the MAC_PHY_TXDEEMPH [1:0], while it is supposed
  to select 0x1(3.5dB emphasize). Thus need to override what comes from
  the MAC(by setting register 0x1c2 bit2 to 0x1) and to configure the
  overridded values of MAC_PHY_TXDEEMPH [1:0] to 0x1(bit15 of register
  0x181 and bit0 of register 0x180).
- According to USB3 application note, need to update below comphy
  registers:
  Set max speed generation to USB3.0 5Gbps(set RD005C04Ah bit[11:10] to 1)
  Set capacitor value to 0xF(set RF005C224 bit[3:0] to 0xF)

Signed-off-by: Marek Behun <marek.behun@nic.cz>
---
 drivers/phy/marvell/comphy_a3700.c | 31 +++++++++++++++++++++++--------
 drivers/phy/marvell/comphy_a3700.h |  5 +++++
 2 files changed, 28 insertions(+), 8 deletions(-)

diff --git a/drivers/phy/marvell/comphy_a3700.c b/drivers/phy/marvell/comphy_a3700.c
index 82dffc4f83..bc9914724a 100644
--- a/drivers/phy/marvell/comphy_a3700.c
+++ b/drivers/phy/marvell/comphy_a3700.c
@@ -350,13 +350,18 @@ static int comphy_usb3_power_up(u32 lane, u32 type, u32 speed, u32 invert)
 	usb3_reg_set16(LANE_CFG0, 0x1, 0xFF, lane);
 
 	/*
-	 * unset BIT0: set Tx Electrical Idle Mode: Transmitter is in
-	 *             low impedance mode during electrical idle
-	 * unset BIT4: set G2 Tx Datapath with no Delayed Latency
-	 * unset BIT6: set Tx Detect Rx Mode at LoZ mode
-	 */
-	usb3_reg_set16(LANE_CFG1, 0x0, 0xFFFF, lane);
-
+	 * Set BIT0: enable transmitter in high impedance mode
+	 * Set BIT[3:4]: delay 2 clock cycles for HiZ off latency
+	 * Set BIT6: Tx detect Rx at HiZ mode
+	 * Unset BIT15: set to 0 to set USB3 De-emphasize level to -3.5db
+	 *              together with bit 0 of COMPHY_REG_LANE_CFG0_ADDR
+	 *              register
+	 */
+	usb3_reg_set16(LANE_CFG1,
+		       tx_det_rx_mode | gen2_tx_data_dly_deft
+		       | tx_elec_idle_mode_en,
+		       prd_txdeemph1_mask | tx_det_rx_mode
+		       | gen2_tx_data_dly_mask | tx_elec_idle_mode_en, lane);
 
 	/* 0xd005c310 = 0x93: set Spread Spectrum Clock Enabled */
 	usb3_reg_set16(LANE_CFG4, bf_spread_spectrum_clock_en, 0x80, lane);
@@ -426,7 +431,17 @@ static int comphy_usb3_power_up(u32 lane, u32 type, u32 speed, u32 invert)
 		usb3_reg_set16(SYNC_PATTERN, phy_rxd_inv, 0, lane);
 
 	/*
-	 * 10. Release SW reset
+	 * 10. Set max speed generation to USB3.0 5Gbps
+	 */
+	usb3_reg_set16(SYNC_MASK_GEN, 0x0400, 0x0C00, lane);
+
+	/*
+	 * 11. Set capacitor value for FFE gain peaking to 0xF
+	 */
+	usb3_reg_set16(GEN3_SETTINGS_3, 0xF, 0xF, lane);
+
+	/*
+	 * 12. Release SW reset
 	 */
 	usb3_reg_set16(GLOB_PHY_CTRL0,
 		       rb_mode_core_clk_freq_sel | rb_mode_pipe_width_32
diff --git a/drivers/phy/marvell/comphy_a3700.h b/drivers/phy/marvell/comphy_a3700.h
index 51c95c1618..952d28e221 100644
--- a/drivers/phy/marvell/comphy_a3700.h
+++ b/drivers/phy/marvell/comphy_a3700.h
@@ -142,6 +142,11 @@ static inline void __iomem *phy_addr(enum phy_unit unit, u32 addr)
 
 #define LANE_CFG1			0x181
 #define bf_use_max_pll_rate		BIT(9)
+#define prd_txdeemph1_mask		BIT(15)
+#define tx_det_rx_mode			BIT(6)
+#define gen2_tx_data_dly_deft		(2 << 3)
+#define gen2_tx_data_dly_mask		(BIT(3) | BIT(4))
+#define tx_elec_idle_mode_en		BIT(0)
 
 #define LANE_CFG4			0x188
 #define bf_spread_spectrum_clock_en	BIT(7)
-- 
2.16.1

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

* [U-Boot] [PATCH v2 10/20] phy: marvell: mux: Support nontrivial node order in selector register
  2018-04-24 15:21 [U-Boot] [PATCH v2 00/20] More support for Armada 37xx boards (for Turris Mox) Marek Behún
                   ` (8 preceding siblings ...)
  2018-04-24 15:21 ` [U-Boot] [PATCH v2 09/20] phy: marvell: a3700: revise the USB3 comphy setting during power on Marek Behún
@ 2018-04-24 15:21 ` Marek Behún
  2018-04-24 15:21 ` [U-Boot] [PATCH v2 11/20] phy: marvell: a3700: Fix SGMII cfg and stat register addresses Marek Behún
                   ` (10 subsequent siblings)
  20 siblings, 0 replies; 22+ messages in thread
From: Marek Behún @ 2018-04-24 15:21 UTC (permalink / raw)
  To: u-boot

Currently comphy_mux supports only trivial order of nodes in pin
selector register, that is lane N on position N*bitcount.

Add support for nontrivial order, with map stored in device tree
property mux-lane-order.

This is needed for Armada 37xx.

As far as I know, there is no driver for Armada 37xx comphy in the
kernel. When such a driver comes, this will need to be rewritten to
support the device tree bindings from the kernel.

Signed-off-by: Marek Behun <marek.behun@nic.cz>
---
 drivers/phy/marvell/comphy.h      |  1 +
 drivers/phy/marvell/comphy_core.c |  4 ++++
 drivers/phy/marvell/comphy_mux.c  | 17 ++++++++++++++---
 3 files changed, 19 insertions(+), 3 deletions(-)

diff --git a/drivers/phy/marvell/comphy.h b/drivers/phy/marvell/comphy.h
index c9b94a4c5e..32e0a1e652 100644
--- a/drivers/phy/marvell/comphy.h
+++ b/drivers/phy/marvell/comphy.h
@@ -97,6 +97,7 @@ struct chip_serdes_phy_config {
 	void __iomem *hpipe3_base_addr;
 	u32 comphy_lanes_count;
 	u32 comphy_mux_bitcount;
+	const fdt32_t *comphy_mux_lane_order;
 	u32 cp_index;
 };
 
diff --git a/drivers/phy/marvell/comphy_core.c b/drivers/phy/marvell/comphy_core.c
index 426db30f73..1e5664c435 100644
--- a/drivers/phy/marvell/comphy_core.c
+++ b/drivers/phy/marvell/comphy_core.c
@@ -135,6 +135,10 @@ static int comphy_probe(struct udevice *dev)
 		return -EINVAL;
 	}
 
+	chip_cfg->comphy_mux_lane_order =
+		fdtdec_locate_array(blob, node, "mux-lane-order",
+				    chip_cfg->comphy_lanes_count);
+
 	if (device_is_compatible(dev, "marvell,comphy-armada-3700"))
 		chip_cfg->ptr_comphy_chip_init = comphy_a3700_init;
 
diff --git a/drivers/phy/marvell/comphy_mux.c b/drivers/phy/marvell/comphy_mux.c
index b036fb13b9..75110b6ba0 100644
--- a/drivers/phy/marvell/comphy_mux.c
+++ b/drivers/phy/marvell/comphy_mux.c
@@ -79,7 +79,8 @@ static u32 comphy_mux_get_mux_value(struct comphy_mux_data *mux_data,
 static void comphy_mux_reg_write(struct comphy_mux_data *mux_data,
 				 struct comphy_map *comphy_map_data,
 				 int comphy_max_lanes,
-				 void __iomem *selector_base, u32 bitcount)
+				 void __iomem *selector_base,
+				 const fdt32_t *mux_lane_order, u32 bitcount)
 {
 	u32 lane, value, offset, mask;
 
@@ -90,7 +91,15 @@ static void comphy_mux_reg_write(struct comphy_mux_data *mux_data,
 		if (comphy_map_data->type == PHY_TYPE_IGNORE)
 			continue;
 
-		offset = lane * bitcount;
+		/*
+		 * if the order of nodes in selector base register is
+		 * nontrivial, use mapping from mux_lane_order
+		 */
+		if (mux_lane_order)
+			offset = fdt32_to_cpu(mux_lane_order[lane]) * bitcount;
+		else
+			offset = lane * bitcount;
+
 		mask = (((1 << bitcount) - 1) << offset);
 		value = (comphy_mux_get_mux_value(mux_data,
 						  comphy_map_data->type,
@@ -106,6 +115,7 @@ void comphy_mux_init(struct chip_serdes_phy_config *chip_cfg,
 		     void __iomem *selector_base)
 {
 	struct comphy_mux_data *mux_data;
+	const fdt32_t *mux_lane_order;
 	u32 mux_bitcount;
 	u32 comphy_max_lanes;
 
@@ -113,13 +123,14 @@ void comphy_mux_init(struct chip_serdes_phy_config *chip_cfg,
 
 	comphy_max_lanes = chip_cfg->comphy_lanes_count;
 	mux_data = chip_cfg->mux_data;
+	mux_lane_order = chip_cfg->comphy_mux_lane_order;
 	mux_bitcount = chip_cfg->comphy_mux_bitcount;
 
 	/* check if the configuration is valid */
 	comphy_mux_check_config(mux_data, comphy_map_data, comphy_max_lanes);
 	/* Init COMPHY selectors */
 	comphy_mux_reg_write(mux_data, comphy_map_data, comphy_max_lanes,
-			     selector_base, mux_bitcount);
+			     selector_base, mux_lane_order, mux_bitcount);
 
 	debug_exit();
 }
-- 
2.16.1

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

* [U-Boot] [PATCH v2 11/20] phy: marvell: a3700: Fix SGMII cfg and stat register addresses
  2018-04-24 15:21 [U-Boot] [PATCH v2 00/20] More support for Armada 37xx boards (for Turris Mox) Marek Behún
                   ` (9 preceding siblings ...)
  2018-04-24 15:21 ` [U-Boot] [PATCH v2 10/20] phy: marvell: mux: Support nontrivial node order in selector register Marek Behún
@ 2018-04-24 15:21 ` Marek Behún
  2018-04-24 15:21 ` [U-Boot] [PATCH v2 12/20] phy: marvell: a3700: Use comphy_mux on Armada 37xx Marek Behún
                   ` (9 subsequent siblings)
  20 siblings, 0 replies; 22+ messages in thread
From: Marek Behún @ 2018-04-24 15:21 UTC (permalink / raw)
  To: u-boot

The register addresses on lanes 0 and 1 are switched, first comes 1 and
then 0.

Signed-off-by: Marek Behun <marek.behun@nic.cz>
---
 drivers/phy/marvell/comphy_a3700.h | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/phy/marvell/comphy_a3700.h b/drivers/phy/marvell/comphy_a3700.h
index 952d28e221..2468468162 100644
--- a/drivers/phy/marvell/comphy_a3700.h
+++ b/drivers/phy/marvell/comphy_a3700.h
@@ -25,7 +25,7 @@
 #define COMPHY_SEL_ADDR			MVEBU_REG(0x0183FC)
 #define rf_compy_select(lane)		(0x1 << (((lane) == 1) ? 4 : 0))
 
-#define COMPHY_PHY_CFG1_ADDR(lane)	MVEBU_REG(0x018300 + (lane) * 0x28)
+#define COMPHY_PHY_CFG1_ADDR(lane)	MVEBU_REG(0x018300 + (1 - lane) * 0x28)
 #define rb_pin_pu_iveref		BIT(1)
 #define rb_pin_reset_core		BIT(11)
 #define rb_pin_reset_comphy		BIT(12)
@@ -39,7 +39,7 @@
 #define rf_gen_tx_select		(0x0F << rf_gen_tx_sel_shift)
 #define rb_phy_rx_init			BIT(30)
 
-#define COMPHY_PHY_STAT1_ADDR(lane)	MVEBU_REG(0x018318 + (lane) * 0x28)
+#define COMPHY_PHY_STAT1_ADDR(lane)	MVEBU_REG(0x018318 + (1 - lane) * 0x28)
 #define rb_rx_init_done			BIT(0)
 #define rb_pll_ready_rx			BIT(2)
 #define rb_pll_ready_tx			BIT(3)
-- 
2.16.1

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

* [U-Boot] [PATCH v2 12/20] phy: marvell: a3700: Use comphy_mux on Armada 37xx.
  2018-04-24 15:21 [U-Boot] [PATCH v2 00/20] More support for Armada 37xx boards (for Turris Mox) Marek Behún
                   ` (10 preceding siblings ...)
  2018-04-24 15:21 ` [U-Boot] [PATCH v2 11/20] phy: marvell: a3700: Fix SGMII cfg and stat register addresses Marek Behún
@ 2018-04-24 15:21 ` Marek Behún
  2018-04-24 15:21 ` [U-Boot] [PATCH v2 13/20] phy: marvell: a3700: Save/restore selector reg in SGMII init Marek Behún
                   ` (8 subsequent siblings)
  20 siblings, 0 replies; 22+ messages in thread
From: Marek Behún @ 2018-04-24 15:21 UTC (permalink / raw)
  To: u-boot

Lane 0 supports SGMII1 and USB3.
Lane 1 supports SGMII0 and PEX0.
Lane 2 supports SATA0 and USB3.

This is needed for Armada 37xx.

This introduces new device tree bindings. AFAIK there is currently no
driver for Armada 37xx comphy in Linux. When such a driver will be
pushed into Linux, this will need to be rewritten accordingly.

Signed-off-by: Marek Behun <marek.behun@nic.cz>
---
 arch/arm/dts/armada-37xx.dtsi      |  5 +++--
 drivers/phy/marvell/comphy_a3700.c | 36 ++++++++++++++++++++++++++++++++++++
 2 files changed, 39 insertions(+), 2 deletions(-)

diff --git a/arch/arm/dts/armada-37xx.dtsi b/arch/arm/dts/armada-37xx.dtsi
index 54007428ed..040e8568e6 100644
--- a/arch/arm/dts/armada-37xx.dtsi
+++ b/arch/arm/dts/armada-37xx.dtsi
@@ -290,8 +290,9 @@
 				compatible = "marvell,mvebu-comphy", "marvell,comphy-armada-3700";
 				reg = <0x18300 0x28>,
 				      <0x1f300 0x3d000>;
-				mux-bitcount = <1>;
-				max-lanes = <2>;
+				mux-bitcount = <4>;
+				mux-lane-order = <1 0 2>;
+				max-lanes = <3>;
 			};
 		};
 
diff --git a/drivers/phy/marvell/comphy_a3700.c b/drivers/phy/marvell/comphy_a3700.c
index bc9914724a..8b44732e52 100644
--- a/drivers/phy/marvell/comphy_a3700.c
+++ b/drivers/phy/marvell/comphy_a3700.c
@@ -14,6 +14,38 @@
 
 DECLARE_GLOBAL_DATA_PTR;
 
+struct comphy_mux_data a3700_comphy_mux_data[] = {
+/* Lane 0 */
+	{
+		4,
+		{
+			{ PHY_TYPE_UNCONNECTED,	0x0 },
+			{ PHY_TYPE_SGMII1,	0x0 },
+			{ PHY_TYPE_USB3_HOST0,	0x1 },
+			{ PHY_TYPE_USB3_DEVICE,	0x1 }
+		}
+	},
+/* Lane 1 */
+	{
+		3,
+		{
+			{ PHY_TYPE_UNCONNECTED,	0x0},
+			{ PHY_TYPE_SGMII0,	0x0},
+			{ PHY_TYPE_PEX0,	0x1}
+		}
+	},
+/* Lane 2 */
+	{
+		4,
+		{
+			{ PHY_TYPE_UNCONNECTED,	0x0},
+			{ PHY_TYPE_SATA0,	0x0},
+			{ PHY_TYPE_USB3_HOST0,	0x1},
+			{ PHY_TYPE_USB3_DEVICE,	0x1}
+		}
+	},
+};
+
 struct sgmii_phy_init_data_fix {
 	u16 addr;
 	u16 value;
@@ -933,6 +965,10 @@ int comphy_a3700_init(struct chip_serdes_phy_config *chip_cfg,
 
 	debug_enter();
 
+	/* Initialize PHY mux */
+	chip_cfg->mux_data = a3700_comphy_mux_data;
+	comphy_mux_init(chip_cfg, serdes_map, COMPHY_SEL_ADDR);
+
 	for (lane = 0, comphy_map = serdes_map; lane < comphy_max_count;
 	     lane++, comphy_map++) {
 		debug("Initialize serdes number %d\n", lane);
-- 
2.16.1

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

* [U-Boot] [PATCH v2 13/20] phy: marvell: a3700: Save/restore selector reg in SGMII init
  2018-04-24 15:21 [U-Boot] [PATCH v2 00/20] More support for Armada 37xx boards (for Turris Mox) Marek Behún
                   ` (11 preceding siblings ...)
  2018-04-24 15:21 ` [U-Boot] [PATCH v2 12/20] phy: marvell: a3700: Use comphy_mux on Armada 37xx Marek Behún
@ 2018-04-24 15:21 ` Marek Behún
  2018-04-24 15:21 ` [U-Boot] [PATCH v2 14/20] driver: clk: Add support for clocks on Armada 37xx Marek Behún
                   ` (7 subsequent siblings)
  20 siblings, 0 replies; 22+ messages in thread
From: Marek Behún @ 2018-04-24 15:21 UTC (permalink / raw)
  To: u-boot

In SGMII initialization PIN_PIPE_SEL has to be zero when resetting
the PHY. Since comphy_mux already set the selector register to
correct values, we have to store it's value before setting it to 0
and restore it after SGMII init.

Signed-off-by: Marek Behun <marek.behun@nic.cz>
Reviewed-by: Stefan Roese <sr@denx.de>
---
 drivers/phy/marvell/comphy_a3700.c | 9 ++++++++-
 drivers/phy/marvell/comphy_a3700.h | 1 -
 2 files changed, 8 insertions(+), 2 deletions(-)

diff --git a/drivers/phy/marvell/comphy_a3700.c b/drivers/phy/marvell/comphy_a3700.c
index 8b44732e52..7f5371afe9 100644
--- a/drivers/phy/marvell/comphy_a3700.c
+++ b/drivers/phy/marvell/comphy_a3700.c
@@ -698,13 +698,15 @@ static void comphy_sgmii_phy_init(u32 lane, u32 speed)
 static int comphy_sgmii_power_up(u32 lane, u32 speed, u32 invert)
 {
 	int ret;
+	u32 saved_selector;
 
 	debug_enter();
 
 	/*
 	 * 1. Configure PHY to SATA/SAS mode by setting pin PIN_PIPE_SEL=0
 	 */
-	reg_set(COMPHY_SEL_ADDR, 0, rf_compy_select(lane));
+	saved_selector = readl(COMPHY_SEL_ADDR);
+	reg_set(COMPHY_SEL_ADDR, 0, 0xFFFFFFFF);
 
 	/*
 	 * 2. Reset PHY by setting PHY input port PIN_RESET=1.
@@ -875,6 +877,11 @@ static int comphy_sgmii_power_up(u32 lane, u32 speed, u32 invert)
 	if (!ret)
 		printf("Failed to init RX of SGMII PHY %d\n", lane);
 
+	/*
+	 * Restore saved selector.
+	 */
+	reg_set(COMPHY_SEL_ADDR, saved_selector, 0xFFFFFFFF);
+
 	debug_exit();
 
 	return ret;
diff --git a/drivers/phy/marvell/comphy_a3700.h b/drivers/phy/marvell/comphy_a3700.h
index 2468468162..6d737967ab 100644
--- a/drivers/phy/marvell/comphy_a3700.h
+++ b/drivers/phy/marvell/comphy_a3700.h
@@ -23,7 +23,6 @@
  * COMPHY SB definitions
  */
 #define COMPHY_SEL_ADDR			MVEBU_REG(0x0183FC)
-#define rf_compy_select(lane)		(0x1 << (((lane) == 1) ? 4 : 0))
 
 #define COMPHY_PHY_CFG1_ADDR(lane)	MVEBU_REG(0x018300 + (1 - lane) * 0x28)
 #define rb_pin_pu_iveref		BIT(1)
-- 
2.16.1

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

* [U-Boot] [PATCH v2 14/20] driver: clk: Add support for clocks on Armada 37xx
  2018-04-24 15:21 [U-Boot] [PATCH v2 00/20] More support for Armada 37xx boards (for Turris Mox) Marek Behún
                   ` (12 preceding siblings ...)
  2018-04-24 15:21 ` [U-Boot] [PATCH v2 13/20] phy: marvell: a3700: Save/restore selector reg in SGMII init Marek Behún
@ 2018-04-24 15:21 ` Marek Behún
  2018-04-24 15:21 ` [U-Boot] [PATCH v2 15/20] spi: mvebu_a3700_spi: Use Armada 37xx clk driver for SPI clock frequency Marek Behún
                   ` (6 subsequent siblings)
  20 siblings, 0 replies; 22+ messages in thread
From: Marek Behún @ 2018-04-24 15:21 UTC (permalink / raw)
  To: u-boot

The drivers are based on Linux driver by Gregory Clement.

The TBG clocks support only the .get_rate method.
  - since setting rate is not supported, the driver computes the rates
    when probing and so subsequent calls to the .get_rate method do not
    read the corresponding registers again

The peripheral clocks support methods .get_rate, .enable and .disable.

  - the .set_parent method theoretically could be supported on some clocks
    (the parent would have to be one of the TBG clocks)

  - the .set_rate method would have to try all the divider values to find
    the best approximation of a given rate, and it doesn't seem like
    this should be needed in U-Boot, therefore not implemented

Signed-off-by: Marek Behun <marek.behun@nic.cz>
Reviewed-by: Stefan Roese <sr@denx.de>
---
 arch/arm/dts/armada-37xx.dtsi          |  20 ++
 drivers/clk/Kconfig                    |   1 +
 drivers/clk/Makefile                   |   1 +
 drivers/clk/mvebu/Kconfig              |  11 +
 drivers/clk/mvebu/Makefile             |   1 +
 drivers/clk/mvebu/armada-37xx-periph.c | 465 +++++++++++++++++++++++++++++++++
 drivers/clk/mvebu/armada-37xx-tbg.c    | 152 +++++++++++
 7 files changed, 651 insertions(+)

diff --git a/arch/arm/dts/armada-37xx.dtsi b/arch/arm/dts/armada-37xx.dtsi
index 040e8568e6..c72fd25abc 100644
--- a/arch/arm/dts/armada-37xx.dtsi
+++ b/arch/arm/dts/armada-37xx.dtsi
@@ -107,6 +107,26 @@
 				status = "disabled";
 			};
 
+			nb_periph_clk: nb-periph-clk at 13000 {
+				compatible = "marvell,armada-3700-periph-clock-nb";
+				reg = <0x13000 0x100>;
+				clocks = <&tbg 0>, <&tbg 1>, <&tbg 2>, <&tbg 3>;
+				#clock-cells = <1>;
+			};
+
+			sb_periph_clk: sb-periph-clk at 18000 {
+				compatible = "marvell,armada-3700-periph-clock-sb";
+				reg = <0x18000 0x100>;
+				clocks = <&tbg 0>, <&tbg 1>, <&tbg 2>, <&tbg 3>;
+				#clock-cells = <1>;
+			};
+
+			tbg: tbg at 13200 {
+				compatible = "marvell,armada-3700-tbg-clock";
+				reg = <0x13200 0x100>;
+				#clock-cells = <1>;
+			};
+
 			pinctrl_nb: pinctrl-nb at 13800 {
 				compatible = "marvell,armada3710-nb-pinctrl",
 				"syscon", "simple-mfd";
diff --git a/drivers/clk/Kconfig b/drivers/clk/Kconfig
index c382e8865f..e182e2ab08 100644
--- a/drivers/clk/Kconfig
+++ b/drivers/clk/Kconfig
@@ -88,5 +88,6 @@ source "drivers/clk/uniphier/Kconfig"
 source "drivers/clk/exynos/Kconfig"
 source "drivers/clk/at91/Kconfig"
 source "drivers/clk/renesas/Kconfig"
+source "drivers/clk/mvebu/Kconfig"
 
 endmenu
diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile
index e05c607223..73f179be20 100644
--- a/drivers/clk/Makefile
+++ b/drivers/clk/Makefile
@@ -11,6 +11,7 @@ obj-y += tegra/
 obj-$(CONFIG_ARCH_ASPEED) += aspeed/
 obj-$(CONFIG_ARCH_ROCKCHIP) += rockchip/
 obj-$(CONFIG_CLK_AT91) += at91/
+obj-$(CONFIG_CLK_MVEBU) += mvebu/
 obj-$(CONFIG_CLK_BCM6345) += clk_bcm6345.o
 obj-$(CONFIG_CLK_BOSTON) += clk_boston.o
 obj-$(CONFIG_CLK_EXYNOS) += exynos/
diff --git a/drivers/clk/mvebu/Kconfig b/drivers/clk/mvebu/Kconfig
new file mode 100644
index 0000000000..e776a15e7b
--- /dev/null
+++ b/drivers/clk/mvebu/Kconfig
@@ -0,0 +1,11 @@
+config CLK_MVEBU
+	bool "MVEBU clock drivers"
+	depends on CLK && ARCH_MVEBU
+	help
+	  Enable support for clock present on Marvell MVEBU SoCs.
+
+config CLK_ARMADA_3720
+	bool "Marvell Armada 3720 clock driver"
+	depends on CLK_MVEBU && ARM64
+	help
+	  Enable this to support the clocks on Marvell Armada 3720 SoC.
diff --git a/drivers/clk/mvebu/Makefile b/drivers/clk/mvebu/Makefile
new file mode 100644
index 0000000000..7f80313203
--- /dev/null
+++ b/drivers/clk/mvebu/Makefile
@@ -0,0 +1 @@
+obj-$(CONFIG_CLK_ARMADA_3720) += armada-37xx-periph.o armada-37xx-tbg.o
diff --git a/drivers/clk/mvebu/armada-37xx-periph.c b/drivers/clk/mvebu/armada-37xx-periph.c
new file mode 100644
index 0000000000..af08e3df08
--- /dev/null
+++ b/drivers/clk/mvebu/armada-37xx-periph.c
@@ -0,0 +1,465 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Marvell Armada 37xx SoC Peripheral clocks
+ *
+ * Marek Behun <marek.behun@nic.cz>
+ *
+ * Based on Linux driver by:
+ *   Gregory CLEMENT <gregory.clement@free-electrons.com>
+ */
+
+#include <common.h>
+#include <malloc.h>
+#include <clk-uclass.h>
+#include <clk.h>
+#include <dm.h>
+#include <asm/io.h>
+#include <asm/arch/cpu.h>
+
+#define TBG_SEL		0x0
+#define DIV_SEL0	0x4
+#define DIV_SEL1	0x8
+#define DIV_SEL2	0xC
+#define CLK_SEL		0x10
+#define CLK_DIS		0x14
+
+enum a37xx_periph_parent {
+	TBG_A_P		= 0,
+	TBG_B_P		= 1,
+	TBG_A_S		= 2,
+	TBG_B_S		= 3,
+	MAX_TBG_PARENTS	= 4,
+	XTAL		= 4,
+	MAX_PARENTS	= 5,
+};
+
+static const struct {
+	const char *name;
+	enum a37xx_periph_parent parent;
+} a37xx_periph_parent_names[] = {
+	{ "TBG-A-P", TBG_A_P },
+	{ "TBG-B-P", TBG_B_P },
+	{ "TBG-A-S", TBG_A_S },
+	{ "TBG-B-S", TBG_B_S },
+	{ "xtal",    XTAL    },
+};
+
+struct clk_periph;
+
+struct a37xx_periphclk {
+	void __iomem *reg;
+
+	ulong parents[MAX_PARENTS];
+
+	const struct clk_periph *clks;
+	bool clk_has_periph_parent[16];
+	int clk_parent[16];
+
+	int count;
+};
+
+struct clk_div_table {
+	u32 div;
+	u32 val;
+};
+
+struct clk_periph {
+	const char *name;
+
+	const char *parent_name;
+
+	u32 disable_bit;
+	int mux_shift;
+
+	const struct clk_div_table *div_table[2];
+	s32 div_reg_off[2];
+	u32 div_mask[2];
+	int div_shift[2];
+
+	unsigned can_gate : 1;
+	unsigned can_mux : 1;
+	unsigned dividers : 2;
+};
+
+static const struct clk_div_table div_table1[] = {
+	{ 1, 1 },
+	{ 2, 2 },
+	{ 0, 0 },
+};
+
+static const struct clk_div_table div_table2[] = {
+	{ 2, 1 },
+	{ 4, 2 },
+	{ 0, 0 },
+};
+
+static const struct clk_div_table div_table6[] = {
+	{ 1, 1 },
+	{ 2, 2 },
+	{ 3, 3 },
+	{ 4, 4 },
+	{ 5, 5 },
+	{ 6, 6 },
+	{ 0, 0 },
+};
+
+#define CLK_FULL_DD(_n, _d, _mux, _r0, _r1, _s0, _s1)	\
+	{						\
+		.name = #_n,				\
+		.disable_bit = BIT(_d),			\
+		.mux_shift = _mux,			\
+		.div_table[0] = div_table6,		\
+		.div_table[1] = div_table6,		\
+		.div_reg_off[0] = _r0,			\
+		.div_reg_off[1] = _r1,			\
+		.div_shift[0] = _s0,			\
+		.div_shift[1] = _s1,			\
+		.div_mask[0] = 7,			\
+		.div_mask[1] = 7,			\
+		.can_gate = 1,				\
+		.can_mux = 1,				\
+		.dividers = 2,				\
+	}
+
+#define CLK_FULL(_n, _d, _mux, _r, _s, _m, _t)	\
+	{					\
+		.name = #_n,			\
+		.disable_bit = BIT(_d),		\
+		.mux_shift = _mux,		\
+		.div_table[0] = _t,		\
+		.div_reg_off[0] = _r,		\
+		.div_shift[0] = _s,		\
+		.div_mask[0] = _m,		\
+		.can_gate = 1,			\
+		.can_mux = 1,			\
+		.dividers = 1,			\
+	}
+
+#define CLK_GATE_DIV(_n, _d, _r, _s, _m, _t, _p)	\
+	{						\
+		.name = #_n,				\
+		.parent_name = _p,			\
+		.disable_bit = BIT(_d),			\
+		.div_table[0] = _t,			\
+		.div_reg_off[0] = _r,			\
+		.div_shift[0] = _s,			\
+		.div_mask[0] = _m,			\
+		.can_gate = 1,				\
+		.dividers = 1,				\
+	}
+
+#define CLK_GATE(_n, _d, _p)		\
+	{				\
+		.name = #_n,		\
+		.parent_name = _p,	\
+		.disable_bit = BIT(_d),	\
+		.can_gate = 1,		\
+	}
+
+#define CLK_MUX_DIV(_n, _mux, _r, _s, _m, _t)	\
+	{					\
+		.name = #_n,			\
+		.mux_shift = _mux,		\
+		.div_table[0] = _t,		\
+		.div_reg_off[0] = _r,		\
+		.div_shift[0] = _s,		\
+		.div_mask[0] = _m,		\
+		.can_mux = 1,			\
+		.dividers = 1,			\
+	}
+
+#define CLK_MUX_DD(_n, _mux, _r0, _r1, _s0, _s1)	\
+	{						\
+		.name = #_n,				\
+		.mux_shift = _mux,			\
+		.div_table[0] = div_table6,		\
+		.div_table[1] = div_table6,		\
+		.div_reg_off[0] = _r0,			\
+		.div_reg_off[1] = _r1,			\
+		.div_shift[0] = _s0,			\
+		.div_shift[1] = _s1,			\
+		.div_mask[0] = 7,			\
+		.div_mask[1] = 7,			\
+		.can_mux = 1,				\
+		.dividers = 2,				\
+	}
+
+/* NB periph clocks */
+static const struct clk_periph clks_nb[] = {
+	CLK_FULL_DD(mmc, 2, 0, DIV_SEL2, DIV_SEL2, 16, 13),
+	CLK_FULL_DD(sata_host, 3, 2, DIV_SEL2, DIV_SEL2, 10, 7),
+	CLK_FULL_DD(sec_at, 6, 4, DIV_SEL1, DIV_SEL1, 3, 0),
+	CLK_FULL_DD(sec_dap, 7, 6, DIV_SEL1, DIV_SEL1, 9, 6),
+	CLK_FULL_DD(tscem, 8, 8, DIV_SEL1, DIV_SEL1, 15, 12),
+	CLK_FULL(tscem_tmx, 10, 10, DIV_SEL1, 18, 7, div_table6),
+	CLK_GATE(avs, 11, "xtal"),
+	CLK_FULL_DD(sqf, 12, 12, DIV_SEL1, DIV_SEL1, 27, 24),
+	CLK_FULL_DD(pwm, 13, 14, DIV_SEL0, DIV_SEL0, 3, 0),
+	CLK_GATE(i2c_2, 16, "xtal"),
+	CLK_GATE(i2c_1, 17, "xtal"),
+	CLK_GATE_DIV(ddr_phy, 19, DIV_SEL0, 18, 1, div_table2, "TBG-A-S"),
+	CLK_FULL_DD(ddr_fclk, 21, 16, DIV_SEL0, DIV_SEL0, 15, 12),
+	CLK_FULL(trace, 22, 18, DIV_SEL0, 20, 7, div_table6),
+	CLK_FULL(counter, 23, 20, DIV_SEL0, 23, 7, div_table6),
+	CLK_FULL_DD(eip97, 24, 24, DIV_SEL2, DIV_SEL2, 22, 19),
+	CLK_MUX_DIV(cpu, 22, DIV_SEL0, 28, 7, div_table6),
+	{ },
+};
+
+/* SB periph clocks */
+static const struct clk_periph clks_sb[] = {
+	CLK_MUX_DD(gbe_50, 6, DIV_SEL2, DIV_SEL2, 6, 9),
+	CLK_MUX_DD(gbe_core, 8, DIV_SEL1, DIV_SEL1, 18, 21),
+	CLK_MUX_DD(gbe_125, 10, DIV_SEL1, DIV_SEL1, 6, 9),
+	CLK_GATE(gbe1_50, 0, "gbe_50"),
+	CLK_GATE(gbe0_50, 1, "gbe_50"),
+	CLK_GATE(gbe1_125, 2, "gbe_125"),
+	CLK_GATE(gbe0_125, 3, "gbe_125"),
+	CLK_GATE_DIV(gbe1_core, 4, DIV_SEL1, 13, 1, div_table1, "gbe_core"),
+	CLK_GATE_DIV(gbe0_core, 5, DIV_SEL1, 14, 1, div_table1, "gbe_core"),
+	CLK_GATE_DIV(gbe_bm, 12, DIV_SEL1, 0, 1, div_table1, "gbe_core"),
+	CLK_FULL_DD(sdio, 11, 14, DIV_SEL0, DIV_SEL0, 3, 6),
+	CLK_FULL_DD(usb32_usb2_sys, 16, 16, DIV_SEL0, DIV_SEL0, 9, 12),
+	CLK_FULL_DD(usb32_ss_sys, 17, 18, DIV_SEL0, DIV_SEL0, 15, 18),
+	{ },
+};
+
+static inline int get_mux(struct a37xx_periphclk *priv, int shift)
+{
+	return (readl(priv->reg + TBG_SEL) >> shift) & 3;
+}
+
+static ulong periph_clk_get_rate(struct a37xx_periphclk *priv, int id);
+
+static ulong get_parent_rate(struct a37xx_periphclk *priv, int id)
+{
+	const struct clk_periph *clk = &priv->clks[id];
+	ulong res;
+
+	if (clk->can_mux) {
+		/* parent is one of TBG clocks */
+		int tbg = get_mux(priv, clk->mux_shift);
+
+		res = priv->parents[tbg];
+	} else if (priv->clk_has_periph_parent[id]) {
+		/* parent is one of other periph clocks */
+
+		if (priv->clk_parent[id] >= priv->count)
+			return -EINVAL;
+
+		res = periph_clk_get_rate(priv, priv->clk_parent[id]);
+	} else {
+		/* otherwise parent is one of TBGs or XTAL */
+
+		if (priv->clk_parent[id] >= MAX_PARENTS)
+			return -EINVAL;
+
+		res = priv->parents[priv->clk_parent[id]];
+	}
+
+	return res;
+}
+
+static ulong get_div(struct a37xx_periphclk *priv,
+		     const struct clk_periph *clk, int idx)
+{
+	const struct clk_div_table *i;
+	u32 reg;
+
+	reg = readl(priv->reg + clk->div_reg_off[idx]);
+	reg = (reg >> clk->div_shift[idx]) & clk->div_mask[idx];
+
+	/* find divisor for register value val */
+	for (i = clk->div_table[idx]; i && i->div != 0; ++i)
+		if (i->val == reg)
+			return i->div;
+
+	return 0;
+}
+
+static ulong periph_clk_get_rate(struct a37xx_periphclk *priv, int id)
+{
+	const struct clk_periph *clk = &priv->clks[id];
+	ulong rate, div;
+	int i;
+
+	rate = get_parent_rate(priv, id);
+	if (rate == -EINVAL)
+		return -EINVAL;
+
+	/* divide the parent rate by dividers */
+	div = 1;
+	for (i = 0; i < clk->dividers; ++i)
+		div *= get_div(priv, clk, i);
+
+	if (!div)
+		return 0;
+
+	return DIV_ROUND_UP(rate, div);
+}
+
+static ulong armada_37xx_periph_clk_get_rate(struct clk *clk)
+{
+	struct a37xx_periphclk *priv = dev_get_priv(clk->dev);
+
+	if (clk->id >= priv->count)
+		return -EINVAL;
+
+	return periph_clk_get_rate(priv, clk->id);
+}
+
+static int periph_clk_enable(struct clk *clk, int enable)
+{
+	struct a37xx_periphclk *priv = dev_get_priv(clk->dev);
+	const struct clk_periph *periph_clk = &priv->clks[clk->id];
+
+	if (clk->id >= priv->count)
+		return -EINVAL;
+
+	if (!periph_clk->can_gate)
+		return -ENOTSUPP;
+
+	if (enable)
+		clrbits_le32(priv->reg + CLK_DIS, periph_clk->disable_bit);
+	else
+		setbits_le32(priv->reg + CLK_DIS, periph_clk->disable_bit);
+
+	return 0;
+}
+
+static int armada_37xx_periph_clk_enable(struct clk *clk)
+{
+	return periph_clk_enable(clk, 1);
+}
+
+static int armada_37xx_periph_clk_disable(struct clk *clk)
+{
+	return periph_clk_enable(clk, 0);
+}
+
+int armada_37xx_periph_clk_dump(struct udevice *dev)
+{
+	struct a37xx_periphclk *priv = dev_get_priv(dev);
+	const struct clk_periph *clks;
+	int i;
+
+	if (!priv)
+		return -ENODEV;
+
+	clks = priv->clks;
+
+	for (i = 0; i < priv->count; ++i)
+		printf("  %s at %lu Hz\n", clks[i].name,
+		       periph_clk_get_rate(priv, i));
+	printf("\n");
+
+	return 0;
+}
+
+static int armada_37xx_periph_clk_probe(struct udevice *dev)
+{
+	struct a37xx_periphclk *priv = dev_get_priv(dev);
+	const struct clk_periph *clks;
+	int ret, i;
+
+	clks = (const struct clk_periph *)dev_get_driver_data(dev);
+	if (!clks)
+		return -ENODEV;
+
+	priv->reg = dev_read_addr_ptr(dev);
+	if (!priv->reg) {
+		dev_err(dev, "no io address\n");
+		return -ENODEV;
+	}
+
+	/* count clk_periph nodes */
+	priv->count = 0;
+	while (clks[priv->count].name)
+		priv->count++;
+
+	priv->clks = clks;
+
+	/* assign parent IDs to nodes which have non-NULL parent_name */
+	for (i = 0; i < priv->count; ++i) {
+		int j;
+
+		if (!clks[i].parent_name)
+			continue;
+
+		/* first try if parent_name is one of TBGs or XTAL */
+		for (j = 0; j < MAX_PARENTS; ++j)
+			if (!strcmp(clks[i].parent_name,
+				    a37xx_periph_parent_names[j].name))
+				break;
+
+		if (j < MAX_PARENTS) {
+			priv->clk_has_periph_parent[i] = false;
+			priv->clk_parent[i] =
+				a37xx_periph_parent_names[j].parent;
+			continue;
+		}
+
+		/* else parent_name should be one of other periph clocks */
+		for (j = 0; j < priv->count; ++j) {
+			if (!strcmp(clks[i].parent_name, clks[j].name))
+				break;
+		}
+
+		if (j < priv->count) {
+			priv->clk_has_periph_parent[i] = true;
+			priv->clk_parent[i] = j;
+			continue;
+		}
+
+		dev_err(dev, "undefined parent %s\n", clks[i].parent_name);
+		return -EINVAL;
+	}
+
+	for (i = 0; i < MAX_PARENTS; ++i) {
+		struct clk clk;
+
+		if (i == XTAL) {
+			priv->parents[i] = get_ref_clk() * 1000000;
+			continue;
+		}
+
+		ret = clk_get_by_index(dev, i, &clk);
+		if (ret) {
+			dev_err(dev, "one of parent clocks (%i) missing: %i\n",
+				i, ret);
+			return -ENODEV;
+		}
+
+		priv->parents[i] = clk_get_rate(&clk);
+		clk_free(&clk);
+	}
+
+	return 0;
+}
+
+static const struct clk_ops armada_37xx_periph_clk_ops = {
+	.get_rate = armada_37xx_periph_clk_get_rate,
+	.enable = armada_37xx_periph_clk_enable,
+	.disable = armada_37xx_periph_clk_disable,
+};
+
+static const struct udevice_id armada_37xx_periph_clk_ids[] = {
+	{
+		.compatible = "marvell,armada-3700-periph-clock-nb",
+		.data = (ulong)clks_nb,
+	},
+	{
+		.compatible = "marvell,armada-3700-periph-clock-sb",
+		.data = (ulong)clks_sb,
+	},
+	{}
+};
+
+U_BOOT_DRIVER(armada_37xx_periph_clk) = {
+	.name		= "armada_37xx_periph_clk",
+	.id		= UCLASS_CLK,
+	.of_match	= armada_37xx_periph_clk_ids,
+	.ops		= &armada_37xx_periph_clk_ops,
+	.priv_auto_alloc_size = sizeof(struct a37xx_periphclk),
+	.probe		= armada_37xx_periph_clk_probe,
+};
diff --git a/drivers/clk/mvebu/armada-37xx-tbg.c b/drivers/clk/mvebu/armada-37xx-tbg.c
new file mode 100644
index 0000000000..c035b8f1fa
--- /dev/null
+++ b/drivers/clk/mvebu/armada-37xx-tbg.c
@@ -0,0 +1,152 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Marvell Armada 37xx SoC Time Base Generator clocks
+ *
+ * Marek Behun <marek.behun@nic.cz>
+ *
+ * Based on Linux driver by:
+ *   Gregory CLEMENT <gregory.clement@free-electrons.com>
+ */
+
+#include <common.h>
+#include <clk-uclass.h>
+#include <clk.h>
+#include <dm.h>
+#include <asm/io.h>
+#include <asm/arch/cpu.h>
+
+#define NUM_TBG	    4
+
+#define TBG_CTRL0		0x4
+#define TBG_CTRL1		0x8
+#define TBG_CTRL7		0x20
+#define TBG_CTRL8		0x30
+
+#define TBG_DIV_MASK		0x1FF
+
+#define TBG_A_REFDIV		0
+#define TBG_B_REFDIV		16
+
+#define TBG_A_FBDIV		2
+#define TBG_B_FBDIV		18
+
+#define TBG_A_VCODIV_SE		0
+#define TBG_B_VCODIV_SE		16
+
+#define TBG_A_VCODIV_DIFF	1
+#define TBG_B_VCODIV_DIFF	17
+
+struct tbg_def {
+	const char *name;
+	u32 refdiv_offset;
+	u32 fbdiv_offset;
+	u32 vcodiv_reg;
+	u32 vcodiv_offset;
+};
+
+static const struct tbg_def tbg[NUM_TBG] = {
+	{"TBG-A-P", TBG_A_REFDIV, TBG_A_FBDIV, TBG_CTRL8, TBG_A_VCODIV_DIFF},
+	{"TBG-B-P", TBG_B_REFDIV, TBG_B_FBDIV, TBG_CTRL8, TBG_B_VCODIV_DIFF},
+	{"TBG-A-S", TBG_A_REFDIV, TBG_A_FBDIV, TBG_CTRL1, TBG_A_VCODIV_SE},
+	{"TBG-B-S", TBG_B_REFDIV, TBG_B_FBDIV, TBG_CTRL1, TBG_B_VCODIV_SE},
+};
+
+struct a37xx_tbgclk {
+	ulong rates[NUM_TBG];
+	unsigned int mult[NUM_TBG];
+	unsigned int div[NUM_TBG];
+};
+
+static unsigned int tbg_get_mult(void __iomem *reg, const struct tbg_def *ptbg)
+{
+	u32 val;
+
+	val = readl(reg + TBG_CTRL0);
+
+	return ((val >> ptbg->fbdiv_offset) & TBG_DIV_MASK) << 2;
+}
+
+static unsigned int tbg_get_div(void __iomem *reg, const struct tbg_def *ptbg)
+{
+	u32 val;
+	unsigned int div;
+
+	val = readl(reg + TBG_CTRL7);
+
+	div = (val >> ptbg->refdiv_offset) & TBG_DIV_MASK;
+	if (div == 0)
+		div = 1;
+	val = readl(reg + ptbg->vcodiv_reg);
+
+	div *= 1 << ((val >>  ptbg->vcodiv_offset) & TBG_DIV_MASK);
+
+	return div;
+}
+
+static ulong armada_37xx_tbg_clk_get_rate(struct clk *clk)
+{
+	struct a37xx_tbgclk *priv = dev_get_priv(clk->dev);
+
+	if (clk->id >= NUM_TBG)
+		return -ENODEV;
+
+	return priv->rates[clk->id];
+}
+
+int armada_37xx_tbg_clk_dump(struct udevice *dev)
+{
+	struct a37xx_tbgclk *priv = dev_get_priv(dev);
+	int i;
+
+	for (i = 0; i < NUM_TBG; ++i)
+		printf("  %s@%lu Hz\n", tbg[i].name,
+		       priv->rates[i]);
+	printf("\n");
+
+	return 0;
+}
+
+static int armada_37xx_tbg_clk_probe(struct udevice *dev)
+{
+	struct a37xx_tbgclk *priv = dev_get_priv(dev);
+	void __iomem *reg;
+	ulong xtal;
+	int i;
+
+	reg = dev_read_addr_ptr(dev);
+	if (!reg) {
+		dev_err(dev, "no io address\n");
+		return -ENODEV;
+	}
+
+	xtal = (ulong)get_ref_clk() * 1000000;
+
+	for (i = 0; i < NUM_TBG; ++i) {
+		unsigned int mult, div;
+
+		mult = tbg_get_mult(reg, &tbg[i]);
+		div = tbg_get_div(reg, &tbg[i]);
+
+		priv->rates[i] = (xtal * mult) / div;
+	}
+
+	return 0;
+}
+
+static const struct clk_ops armada_37xx_tbg_clk_ops = {
+	.get_rate = armada_37xx_tbg_clk_get_rate,
+};
+
+static const struct udevice_id armada_37xx_tbg_clk_ids[] = {
+	{ .compatible = "marvell,armada-3700-tbg-clock" },
+	{}
+};
+
+U_BOOT_DRIVER(armada_37xx_tbg_clk) = {
+	.name		= "armada_37xx_tbg_clk",
+	.id		= UCLASS_CLK,
+	.of_match	= armada_37xx_tbg_clk_ids,
+	.ops		= &armada_37xx_tbg_clk_ops,
+	.priv_auto_alloc_size = sizeof(struct a37xx_tbgclk),
+	.probe		= armada_37xx_tbg_clk_probe,
+};
-- 
2.16.1

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

* [U-Boot] [PATCH v2 15/20] spi: mvebu_a3700_spi: Use Armada 37xx clk driver for SPI clock frequency
  2018-04-24 15:21 [U-Boot] [PATCH v2 00/20] More support for Armada 37xx boards (for Turris Mox) Marek Behún
                   ` (13 preceding siblings ...)
  2018-04-24 15:21 ` [U-Boot] [PATCH v2 14/20] driver: clk: Add support for clocks on Armada 37xx Marek Behún
@ 2018-04-24 15:21 ` Marek Behún
  2018-04-24 15:21 ` [U-Boot] [PATCH v2 16/20] clk: armada-37xx: Support soc_clk_dump Marek Behún
                   ` (5 subsequent siblings)
  20 siblings, 0 replies; 22+ messages in thread
From: Marek Behún @ 2018-04-24 15:21 UTC (permalink / raw)
  To: u-boot

Since now we have driver for clocks on Armada 37xx, use it to determine
SQF clock frequency for the SPI driver.

Also change the default config files for Armada 37xx devices so that
the clock driver is enabled by default, otherwise the SPI driver cannot
be enabled.

Signed-off-by: Marek Behun <marek.behun@nic.cz>
---
 arch/arm/dts/armada-37xx.dtsi               |  4 +--
 configs/mvebu_db-88f3720_defconfig          |  3 ++
 configs/mvebu_espressobin-88f3720_defconfig |  3 ++
 drivers/spi/Kconfig                         |  1 +
 drivers/spi/mvebu_a3700_spi.c               | 52 ++++++++++++++++-------------
 5 files changed, 37 insertions(+), 26 deletions(-)

diff --git a/arch/arm/dts/armada-37xx.dtsi b/arch/arm/dts/armada-37xx.dtsi
index c72fd25abc..5b4a1a49bb 100644
--- a/arch/arm/dts/armada-37xx.dtsi
+++ b/arch/arm/dts/armada-37xx.dtsi
@@ -301,8 +301,8 @@
 				#address-cells = <1>;
 				#size-cells = <0>;
 				#clock-cells = <0>;
-				clock-frequency = <160000>;
-				spi-max-frequency = <40000>;
+				spi-max-frequency = <50000000>;
+				clocks = <&nb_periph_clk 7>;
 				status = "disabled";
 			};
 
diff --git a/configs/mvebu_db-88f3720_defconfig b/configs/mvebu_db-88f3720_defconfig
index 67a8077a58..691d7211dc 100644
--- a/configs/mvebu_db-88f3720_defconfig
+++ b/configs/mvebu_db-88f3720_defconfig
@@ -36,6 +36,9 @@ CONFIG_DM_GPIO=y
 # CONFIG_MVEBU_GPIO is not set
 CONFIG_DM_I2C=y
 CONFIG_MISC=y
+CONFIG_CLK=y
+CONFIG_CLK_MVEBU=y
+CONFIG_CLK_ARMADA_3720=y
 CONFIG_DM_MMC=y
 CONFIG_MMC_SDHCI=y
 CONFIG_MMC_SDHCI_SDMA=y
diff --git a/configs/mvebu_espressobin-88f3720_defconfig b/configs/mvebu_espressobin-88f3720_defconfig
index 48dae2d791..60259bcf2c 100644
--- a/configs/mvebu_espressobin-88f3720_defconfig
+++ b/configs/mvebu_espressobin-88f3720_defconfig
@@ -35,6 +35,9 @@ CONFIG_BLOCK_CACHE=y
 CONFIG_DM_GPIO=y
 CONFIG_DM_I2C=y
 CONFIG_MISC=y
+CONFIG_CLK=y
+CONFIG_CLK_MVEBU=y
+CONFIG_CLK_ARMADA_3720=y
 CONFIG_DM_MMC=y
 CONFIG_MMC_SDHCI=y
 CONFIG_MMC_SDHCI_SDMA=y
diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig
index ec92b84ed2..06fa14ae36 100644
--- a/drivers/spi/Kconfig
+++ b/drivers/spi/Kconfig
@@ -101,6 +101,7 @@ config ICH_SPI
 
 config MVEBU_A3700_SPI
 	bool "Marvell Armada 3700 SPI driver"
+	select CLK_ARMADA_3720
 	help
 	  Enable the Marvell Armada 3700 SPI driver. This driver can be
 	  used to access the SPI NOR flash on platforms embedding this
diff --git a/drivers/spi/mvebu_a3700_spi.c b/drivers/spi/mvebu_a3700_spi.c
index d1708a8d56..9b8b5e4d06 100644
--- a/drivers/spi/mvebu_a3700_spi.c
+++ b/drivers/spi/mvebu_a3700_spi.c
@@ -10,6 +10,7 @@
 #include <dm.h>
 #include <malloc.h>
 #include <spi.h>
+#include <clk.h>
 #include <wait_bit.h>
 #include <asm/io.h>
 
@@ -22,9 +23,8 @@ DECLARE_GLOBAL_DATA_PTR;
 #define MVEBU_SPI_A3700_CLK_POL			BIT(7)
 #define MVEBU_SPI_A3700_FIFO_EN			BIT(17)
 #define MVEBU_SPI_A3700_SPI_EN_0		BIT(16)
-#define MVEBU_SPI_A3700_CLK_PRESCALE_BIT	0
-#define MVEBU_SPI_A3700_CLK_PRESCALE_MASK	\
-	(0x1f << MVEBU_SPI_A3700_CLK_PRESCALE_BIT)
+#define MVEBU_SPI_A3700_CLK_PRESCALE_MASK	0x1f
+
 
 /* SPI registers */
 struct spi_reg {
@@ -36,8 +36,7 @@ struct spi_reg {
 
 struct mvebu_spi_platdata {
 	struct spi_reg *spireg;
-	unsigned int frequency;
-	unsigned int clock;
+	struct clk clk;
 };
 
 static void spi_cs_activate(struct spi_reg *reg, int cs)
@@ -178,17 +177,18 @@ static int mvebu_spi_set_speed(struct udevice *bus, uint hz)
 {
 	struct mvebu_spi_platdata *plat = dev_get_platdata(bus);
 	struct spi_reg *reg = plat->spireg;
-	u32 data;
+	u32 data, prescale;
 
 	data = readl(&reg->cfg);
 
-	/* Set Prescaler */
-	data &= ~MVEBU_SPI_A3700_CLK_PRESCALE_MASK;
+	prescale = DIV_ROUND_UP(clk_get_rate(&plat->clk), hz);
+	if (prescale > 0x1f)
+		prescale = 0x1f;
+	else if (prescale > 0xf)
+		prescale = 0x10 + (prescale + 1) / 2;
 
-	/* Calculate Prescaler = (spi_input_freq / spi_max_freq) */
-	if (hz > plat->frequency)
-		hz = plat->frequency;
-	data |= plat->clock / hz;
+	data &= ~MVEBU_SPI_A3700_CLK_PRESCALE_MASK;
+	data |= prescale & MVEBU_SPI_A3700_CLK_PRESCALE_MASK;
 
 	writel(data, &reg->cfg);
 
@@ -252,21 +252,24 @@ static int mvebu_spi_probe(struct udevice *bus)
 static int mvebu_spi_ofdata_to_platdata(struct udevice *bus)
 {
 	struct mvebu_spi_platdata *plat = dev_get_platdata(bus);
+	int ret;
 
 	plat->spireg = (struct spi_reg *)devfdt_get_addr(bus);
 
-	/*
-	 * FIXME
-	 * Right now, mvebu does not have a clock infrastructure in U-Boot
-	 * which should be used to query the input clock to the SPI
-	 * controller. Once this clock driver is integrated into U-Boot
-	 * it should be used to read the input clock and the DT property
-	 * can be removed.
-	 */
-	plat->clock = fdtdec_get_int(gd->fdt_blob, dev_of_offset(bus),
-				     "clock-frequency", 160000);
-	plat->frequency = fdtdec_get_int(gd->fdt_blob, dev_of_offset(bus),
-					 "spi-max-frequency", 40000);
+	ret = clk_get_by_index(bus, 0, &plat->clk);
+	if (ret) {
+		dev_err(bus, "cannot get clock\n");
+		return ret;
+	}
+
+	return 0;
+}
+
+static int mvebu_spi_remove(struct udevice *bus)
+{
+	struct mvebu_spi_platdata *plat = dev_get_platdata(bus);
+
+	clk_free(&plat->clk);
 
 	return 0;
 }
@@ -294,4 +297,5 @@ U_BOOT_DRIVER(mvebu_spi) = {
 	.ofdata_to_platdata = mvebu_spi_ofdata_to_platdata,
 	.platdata_auto_alloc_size = sizeof(struct mvebu_spi_platdata),
 	.probe = mvebu_spi_probe,
+	.remove = mvebu_spi_remove,
 };
-- 
2.16.1

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

* [U-Boot] [PATCH v2 16/20] clk: armada-37xx: Support soc_clk_dump
  2018-04-24 15:21 [U-Boot] [PATCH v2 00/20] More support for Armada 37xx boards (for Turris Mox) Marek Behún
                   ` (14 preceding siblings ...)
  2018-04-24 15:21 ` [U-Boot] [PATCH v2 15/20] spi: mvebu_a3700_spi: Use Armada 37xx clk driver for SPI clock frequency Marek Behún
@ 2018-04-24 15:21 ` Marek Behún
  2018-04-24 15:21 ` [U-Boot] [PATCH v2 17/20] phy: marvell: core: Cosmetic fixes Marek Behún
                   ` (4 subsequent siblings)
  20 siblings, 0 replies; 22+ messages in thread
From: Marek Behún @ 2018-04-24 15:21 UTC (permalink / raw)
  To: u-boot

Add support for the clk dump command on Armada 37xx.

Signed-off-by: Marek Behun <marek.behun@nic.cz>
Reviewed-by: Stefan Roese <sr@denx.de>
---
 drivers/clk/mvebu/armada-37xx-periph.c | 36 +++++++++++++++++++++++++++++++++-
 drivers/clk/mvebu/armada-37xx-tbg.c    |  2 ++
 2 files changed, 37 insertions(+), 1 deletion(-)

diff --git a/drivers/clk/mvebu/armada-37xx-periph.c b/drivers/clk/mvebu/armada-37xx-periph.c
index af08e3df08..902a6cc9ef 100644
--- a/drivers/clk/mvebu/armada-37xx-periph.c
+++ b/drivers/clk/mvebu/armada-37xx-periph.c
@@ -337,7 +337,8 @@ static int armada_37xx_periph_clk_disable(struct clk *clk)
 	return periph_clk_enable(clk, 0);
 }
 
-int armada_37xx_periph_clk_dump(struct udevice *dev)
+#if defined(CONFIG_CMD_CLK) && defined(CONFIG_CLK_ARMADA_3720)
+static int armada_37xx_periph_clk_dump(struct udevice *dev)
 {
 	struct a37xx_periphclk *priv = dev_get_priv(dev);
 	const struct clk_periph *clks;
@@ -356,6 +357,39 @@ int armada_37xx_periph_clk_dump(struct udevice *dev)
 	return 0;
 }
 
+static int clk_dump(const char *name, int (*func)(struct udevice *))
+{
+	struct udevice *dev;
+
+	if (uclass_get_device_by_name(UCLASS_CLK, name, &dev)) {
+		printf("Cannot find device %s\n", name);
+		return -ENODEV;
+	}
+
+	return func(dev);
+}
+
+int armada_37xx_tbg_clk_dump(struct udevice *);
+
+int soc_clk_dump(void)
+{
+	printf("  xtal at %u000000 Hz\n\n", get_ref_clk());
+
+	if (clk_dump("tbg at 13200", armada_37xx_tbg_clk_dump))
+		return 1;
+
+	if (clk_dump("nb-periph-clk at 13000",
+		     armada_37xx_periph_clk_dump))
+		return 1;
+
+	if (clk_dump("sb-periph-clk at 18000",
+		     armada_37xx_periph_clk_dump))
+		return 1;
+
+	return 0;
+}
+#endif
+
 static int armada_37xx_periph_clk_probe(struct udevice *dev)
 {
 	struct a37xx_periphclk *priv = dev_get_priv(dev);
diff --git a/drivers/clk/mvebu/armada-37xx-tbg.c b/drivers/clk/mvebu/armada-37xx-tbg.c
index c035b8f1fa..aa7ccd690f 100644
--- a/drivers/clk/mvebu/armada-37xx-tbg.c
+++ b/drivers/clk/mvebu/armada-37xx-tbg.c
@@ -93,6 +93,7 @@ static ulong armada_37xx_tbg_clk_get_rate(struct clk *clk)
 	return priv->rates[clk->id];
 }
 
+#if defined(CONFIG_CMD_CLK) && defined(CONFIG_CLK_ARMADA_3720)
 int armada_37xx_tbg_clk_dump(struct udevice *dev)
 {
 	struct a37xx_tbgclk *priv = dev_get_priv(dev);
@@ -105,6 +106,7 @@ int armada_37xx_tbg_clk_dump(struct udevice *dev)
 
 	return 0;
 }
+#endif
 
 static int armada_37xx_tbg_clk_probe(struct udevice *dev)
 {
-- 
2.16.1

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

* [U-Boot] [PATCH v2 17/20] phy: marvell: core: Cosmetic fixes
  2018-04-24 15:21 [U-Boot] [PATCH v2 00/20] More support for Armada 37xx boards (for Turris Mox) Marek Behún
                   ` (15 preceding siblings ...)
  2018-04-24 15:21 ` [U-Boot] [PATCH v2 16/20] clk: armada-37xx: Support soc_clk_dump Marek Behún
@ 2018-04-24 15:21 ` Marek Behún
  2018-04-24 15:21 ` [U-Boot] [PATCH v2 18/20] net: mvneta: Fix fault when wrong device tree Marek Behún
                   ` (3 subsequent siblings)
  20 siblings, 0 replies; 22+ messages in thread
From: Marek Behún @ 2018-04-24 15:21 UTC (permalink / raw)
  To: u-boot

Move the reg_set* functions into comphy.h as static inline functions.
Change return type of get_*_string to const char *.

Signed-off-by: Marek Behun <marek.behun@nic.cz>
Reviewed-by: Stefan Roese <sr@denx.de>
---
 drivers/phy/marvell/comphy.h      | 41 ++++++++++++++++++++++---
 drivers/phy/marvell/comphy_core.c | 64 +++++++++------------------------------
 2 files changed, 52 insertions(+), 53 deletions(-)

diff --git a/drivers/phy/marvell/comphy.h b/drivers/phy/marvell/comphy.h
index 32e0a1e652..176bc89cac 100644
--- a/drivers/phy/marvell/comphy.h
+++ b/drivers/phy/marvell/comphy.h
@@ -102,10 +102,43 @@ struct chip_serdes_phy_config {
 };
 
 /* Register helper functions */
-void reg_set(void __iomem *addr, u32 data, u32 mask);
-void reg_set_silent(void __iomem *addr, u32 data, u32 mask);
-void reg_set16(void __iomem *addr, u16 data, u16 mask);
-void reg_set_silent16(void __iomem *addr, u16 data, u16 mask);
+static inline void reg_set_silent(void __iomem *addr, u32 data, u32 mask)
+{
+	u32 reg_data;
+
+	reg_data = readl(addr);
+	reg_data &= ~mask;
+	reg_data |= data;
+	writel(reg_data, addr);
+}
+
+static inline void reg_set(void __iomem *addr, u32 data, u32 mask)
+{
+	debug("Write to address = %#010lx, data = %#010x (mask = %#010x) - ",
+	      (unsigned long)addr, data, mask);
+	debug("old value = %#010x ==> ", readl(addr));
+	reg_set_silent(addr, data, mask);
+	debug("new value %#010x\n", readl(addr));
+}
+
+static inline void reg_set_silent16(void __iomem *addr, u16 data, u16 mask)
+{
+	u16 reg_data;
+
+	reg_data = readw(addr);
+	reg_data &= ~mask;
+	reg_data |= data;
+	writew(reg_data, addr);
+}
+
+static inline void reg_set16(void __iomem *addr, u16 data, u16 mask)
+{
+	debug("Write to address = %#010lx, data = %#06x (mask = %#06x) - ",
+	      (unsigned long)addr, data, mask);
+	debug("old value = %#06x ==> ", readw(addr));
+	reg_set_silent16(addr, data, mask);
+	debug("new value %#06x\n", readw(addr));
+}
 
 /* SoC specific init functions */
 #ifdef CONFIG_ARMADA_3700
diff --git a/drivers/phy/marvell/comphy_core.c b/drivers/phy/marvell/comphy_core.c
index 1e5664c435..500005f1d5 100644
--- a/drivers/phy/marvell/comphy_core.c
+++ b/drivers/phy/marvell/comphy_core.c
@@ -18,11 +18,13 @@
 
 DECLARE_GLOBAL_DATA_PTR;
 
-static char *get_speed_string(u32 speed)
+static const char *get_speed_string(u32 speed)
 {
-	char *speed_strings[] = {"1.25 Gbps", "1.5 Gbps", "2.5 Gbps",
-				 "3.0 Gbps", "3.125 Gbps", "5 Gbps", "6 Gbps",
-				 "6.25 Gbps", "10.31 Gbps" };
+	static const char * const speed_strings[] = {
+		"1.25 Gbps", "1.5 Gbps", "2.5 Gbps",
+		"3.0 Gbps", "3.125 Gbps", "5 Gbps", "6 Gbps",
+		"6.25 Gbps", "10.31 Gbps"
+	};
 
 	if (speed < 0 || speed > PHY_SPEED_MAX)
 		return "invalid";
@@ -30,14 +32,16 @@ static char *get_speed_string(u32 speed)
 	return speed_strings[speed];
 }
 
-static char *get_type_string(u32 type)
+static const char *get_type_string(u32 type)
 {
-	char *type_strings[] = {"UNCONNECTED", "PEX0", "PEX1", "PEX2", "PEX3",
-				"SATA0", "SATA1", "SATA2", "SATA3", "SGMII0",
-				"SGMII1", "SGMII2", "SGMII3", "QSGMII",
-				"USB3_HOST0", "USB3_HOST1", "USB3_DEVICE",
-				"XAUI0", "XAUI1", "XAUI2", "XAUI3",
-				"RXAUI0", "RXAUI1", "SFI", "IGNORE"};
+	static const char * const type_strings[] = {
+		"UNCONNECTED", "PEX0", "PEX1", "PEX2", "PEX3",
+		"SATA0", "SATA1", "SATA2", "SATA3", "SGMII0",
+		"SGMII1", "SGMII2", "SGMII3", "QSGMII",
+		"USB3_HOST0", "USB3_HOST1", "USB3_DEVICE",
+		"XAUI0", "XAUI1", "XAUI2", "XAUI3",
+		"RXAUI0", "RXAUI1", "SFI", "IGNORE"
+	};
 
 	if (type < 0 || type > PHY_TYPE_MAX)
 		return "invalid";
@@ -45,44 +49,6 @@ static char *get_type_string(u32 type)
 	return type_strings[type];
 }
 
-void reg_set(void __iomem *addr, u32 data, u32 mask)
-{
-	debug("Write to address = %#010lx, data = %#010x (mask = %#010x) - ",
-	      (unsigned long)addr, data, mask);
-	debug("old value = %#010x ==> ", readl(addr));
-	reg_set_silent(addr, data, mask);
-	debug("new value %#010x\n", readl(addr));
-}
-
-void reg_set_silent(void __iomem *addr, u32 data, u32 mask)
-{
-	u32 reg_data;
-
-	reg_data = readl(addr);
-	reg_data &= ~mask;
-	reg_data |= data;
-	writel(reg_data, addr);
-}
-
-void reg_set16(void __iomem *addr, u16 data, u16 mask)
-{
-	debug("Write to address = %#010lx, data = %#06x (mask = %#06x) - ",
-	      (unsigned long)addr, data, mask);
-	debug("old value = %#06x ==> ", readw(addr));
-	reg_set_silent16(addr, data, mask);
-	debug("new value %#06x\n", readw(addr));
-}
-
-void reg_set_silent16(void __iomem *addr, u16 data, u16 mask)
-{
-	u16 reg_data;
-
-	reg_data = readw(addr);
-	reg_data &= ~mask;
-	reg_data |= data;
-	writew(reg_data, addr);
-}
-
 void comphy_print(struct chip_serdes_phy_config *chip_cfg,
 		  struct comphy_map *comphy_map_data)
 {
-- 
2.16.1

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

* [U-Boot] [PATCH v2 18/20] net: mvneta: Fix fault when wrong device tree
  2018-04-24 15:21 [U-Boot] [PATCH v2 00/20] More support for Armada 37xx boards (for Turris Mox) Marek Behún
                   ` (16 preceding siblings ...)
  2018-04-24 15:21 ` [U-Boot] [PATCH v2 17/20] phy: marvell: core: Cosmetic fixes Marek Behún
@ 2018-04-24 15:21 ` Marek Behún
  2018-04-24 15:21 ` [U-Boot] [PATCH v2 19/20] watchdog: Add support for Armada 37xx CPU watchdog Marek Behún
                   ` (2 subsequent siblings)
  20 siblings, 0 replies; 22+ messages in thread
From: Marek Behún @ 2018-04-24 15:21 UTC (permalink / raw)
  To: u-boot

The driver does not check id phy_connect failed (for example on wrong
property name in device tree). In such a case a fault occurs and the
CPU is restarted.

Signed-off-by: Marek Behun <marek.behun@nic.cz>
Reviewed-by: Stefan Roese <sr@denx.de>
---
 drivers/net/mvneta.c | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/drivers/net/mvneta.c b/drivers/net/mvneta.c
index f2e9acfd1f..7ea61ae582 100644
--- a/drivers/net/mvneta.c
+++ b/drivers/net/mvneta.c
@@ -1563,6 +1563,10 @@ static int mvneta_start(struct udevice *dev)
 
 			phydev = phy_connect(pp->bus, pp->phyaddr, dev,
 					     pp->phy_interface);
+			if (!phydev) {
+				printf("phy_connect failed\n");
+				return -ENODEV;
+			}
 
 			pp->phydev = phydev;
 			phy_config(phydev);
-- 
2.16.1

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

* [U-Boot] [PATCH v2 19/20] watchdog: Add support for Armada 37xx CPU watchdog
  2018-04-24 15:21 [U-Boot] [PATCH v2 00/20] More support for Armada 37xx boards (for Turris Mox) Marek Behún
                   ` (17 preceding siblings ...)
  2018-04-24 15:21 ` [U-Boot] [PATCH v2 18/20] net: mvneta: Fix fault when wrong device tree Marek Behún
@ 2018-04-24 15:21 ` Marek Behún
  2018-04-24 15:21 ` [U-Boot] [PATCH v2 20/20] arm64: mvebu: Add basic support for the Turris Mox board Marek Behún
  2018-05-14 11:54 ` [U-Boot] [PATCH v2 00/20] More support for Armada 37xx boards (for Turris Mox) Stefan Roese
  20 siblings, 0 replies; 22+ messages in thread
From: Marek Behún @ 2018-04-24 15:21 UTC (permalink / raw)
  To: u-boot

This adds support for the CPU watchdog found on Marvell Armada 37xx
SoCs.

There are 4 counters which can be set as CPU watchdog counters.
This driver uses the second counter (ID 1, counting from 0)
(Marvell's Linux also uses second counter by default).
In the future it could be adapted to use other counters, with
definition in the device tree.

Signed-off-by: Marek Behun <marek.behun@nic.cz>
---
 arch/arm/dts/armada-37xx.dtsi      |   6 ++
 drivers/watchdog/Kconfig           |   9 ++
 drivers/watchdog/Makefile          |   1 +
 drivers/watchdog/armada-37xx-wdt.c | 175 +++++++++++++++++++++++++++++++++++++
 4 files changed, 191 insertions(+)

diff --git a/arch/arm/dts/armada-37xx.dtsi b/arch/arm/dts/armada-37xx.dtsi
index 5b4a1a49bb..a1052add0c 100644
--- a/arch/arm/dts/armada-37xx.dtsi
+++ b/arch/arm/dts/armada-37xx.dtsi
@@ -107,6 +107,12 @@
 				status = "disabled";
 			};
 
+			wdt: watchdog-timer at 8300 {
+				compatible = "marvell,armada-3700-wdt";
+				reg = <0xd064 0x4>,
+				      <0x8300 0x40>;
+			};
+
 			nb_periph_clk: nb-periph-clk at 13000 {
 				compatible = "marvell,armada-3700-periph-clock-nb";
 				reg = <0x13000 0x100>;
diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig
index dca2c901ac..148c6a0d68 100644
--- a/drivers/watchdog/Kconfig
+++ b/drivers/watchdog/Kconfig
@@ -60,6 +60,15 @@ config WDT_SANDBOX
 	  can be probed and supports all of the methods of WDT, but does not
 	  really do anything.
 
+config WDT_ARMADA_37XX
+	bool "Marvell Armada 37xx watchdog timer support"
+	depends on WDT && ARMADA_3700
+	help
+	   Enable this to support Watchdog Timer on Marvell Armada 37xx SoC.
+	   There are 4 possible clocks which can be used on these SoCs. This
+	   driver uses the second clock (ID 1), assuming that so will also
+	   Linux's driver.
+
 config WDT_ASPEED
 	bool "Aspeed ast2400/ast2500 watchdog timer support"
 	depends on WDT
diff --git a/drivers/watchdog/Makefile b/drivers/watchdog/Makefile
index 4fee6dbd1f..e17aa2b835 100644
--- a/drivers/watchdog/Makefile
+++ b/drivers/watchdog/Makefile
@@ -18,6 +18,7 @@ obj-$(CONFIG_TANGIER_WATCHDOG) += tangier_wdt.o
 obj-$(CONFIG_ULP_WATCHDOG) += ulp_wdog.o
 obj-$(CONFIG_WDT) += wdt-uclass.o
 obj-$(CONFIG_WDT_SANDBOX) += sandbox_wdt.o
+obj-$(CONFIG_WDT_ARMADA_37XX) += armada-37xx-wdt.o
 obj-$(CONFIG_WDT_ASPEED) += ast_wdt.o
 obj-$(CONFIG_WDT_BCM6345) += bcm6345_wdt.o
 obj-$(CONFIG_BCM2835_WDT)       += bcm2835_wdt.o
diff --git a/drivers/watchdog/armada-37xx-wdt.c b/drivers/watchdog/armada-37xx-wdt.c
new file mode 100644
index 0000000000..0fa4fda4fc
--- /dev/null
+++ b/drivers/watchdog/armada-37xx-wdt.c
@@ -0,0 +1,175 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Marvell Armada 37xx SoC Watchdog Driver
+ *
+ * Marek Behun <marek.behun@nic.cz>
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <wdt.h>
+#include <asm/io.h>
+#include <asm/arch/cpu.h>
+#include <asm/arch/soc.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+struct a37xx_wdt {
+	void __iomem *sel_reg;
+	void __iomem *reg;
+	ulong clk_rate;
+	u64 timeout;
+};
+
+/*
+ * We use Counter 1 for watchdog timer, because so does Marvell's Linux by
+ * default.
+ */
+
+#define CNTR_CTRL			0x10
+#define CNTR_CTRL_ENABLE		0x0001
+#define CNTR_CTRL_ACTIVE		0x0002
+#define CNTR_CTRL_MODE_MASK		0x000c
+#define CNTR_CTRL_MODE_ONESHOT		0x0000
+#define CNTR_CTRL_PRESCALE_MASK		0xff00
+#define CNTR_CTRL_PRESCALE_MIN		2
+#define CNTR_CTRL_PRESCALE_SHIFT	8
+
+#define CNTR_COUNT_LOW			0x14
+#define CNTR_COUNT_HIGH			0x18
+
+static void set_counter_value(struct a37xx_wdt *priv)
+{
+	writel(priv->timeout & 0xffffffff, priv->reg + CNTR_COUNT_LOW);
+	writel(priv->timeout >> 32, priv->reg + CNTR_COUNT_HIGH);
+}
+
+static void a37xx_wdt_enable(struct a37xx_wdt *priv)
+{
+	u32 reg = readl(priv->reg + CNTR_CTRL);
+
+	reg |= CNTR_CTRL_ENABLE;
+	writel(reg, priv->reg + CNTR_CTRL);
+}
+
+static void a37xx_wdt_disable(struct a37xx_wdt *priv)
+{
+	u32 reg = readl(priv->reg + CNTR_CTRL);
+
+	reg &= ~CNTR_CTRL_ENABLE;
+	writel(reg, priv->reg + CNTR_CTRL);
+}
+
+static int a37xx_wdt_reset(struct udevice *dev)
+{
+	struct a37xx_wdt *priv = dev_get_priv(dev);
+
+	if (!priv->timeout)
+		return -EINVAL;
+
+	a37xx_wdt_disable(priv);
+	set_counter_value(priv);
+	a37xx_wdt_enable(priv);
+
+	return 0;
+}
+
+static int a37xx_wdt_expire_now(struct udevice *dev, ulong flags)
+{
+	struct a37xx_wdt *priv = dev_get_priv(dev);
+
+	a37xx_wdt_disable(priv);
+	priv->timeout = 0;
+	set_counter_value(priv);
+	a37xx_wdt_enable(priv);
+
+	return 0;
+}
+
+static int a37xx_wdt_start(struct udevice *dev, u64 ms, ulong flags)
+{
+	struct a37xx_wdt *priv = dev_get_priv(dev);
+	u32 reg;
+
+	reg = readl(priv->reg + CNTR_CTRL);
+
+	if (reg & CNTR_CTRL_ACTIVE)
+		return -EBUSY;
+
+	/* set mode */
+	reg = (reg & ~CNTR_CTRL_MODE_MASK) | CNTR_CTRL_MODE_ONESHOT;
+
+	/* set prescaler to the min value */
+	reg &= ~CNTR_CTRL_PRESCALE_MASK;
+	reg |= CNTR_CTRL_PRESCALE_MIN << CNTR_CTRL_PRESCALE_SHIFT;
+
+	priv->timeout = ms * priv->clk_rate / 1000 / CNTR_CTRL_PRESCALE_MIN;
+
+	writel(reg, priv->reg + CNTR_CTRL);
+
+	set_counter_value(priv);
+	a37xx_wdt_enable(priv);
+
+	return 0;
+}
+
+static int a37xx_wdt_stop(struct udevice *dev)
+{
+	struct a37xx_wdt *priv = dev_get_priv(dev);
+
+	a37xx_wdt_disable(priv);
+
+	return 0;
+}
+
+static int a37xx_wdt_probe(struct udevice *dev)
+{
+	struct a37xx_wdt *priv = dev_get_priv(dev);
+	fdt_addr_t addr;
+
+	addr = dev_read_addr_index(dev, 0);
+	if (addr == FDT_ADDR_T_NONE)
+		goto err;
+	priv->sel_reg = (void __iomem *)addr;
+
+	addr = dev_read_addr_index(dev, 1);
+	if (addr == FDT_ADDR_T_NONE)
+		goto err;
+	priv->reg = (void __iomem *)addr;
+
+	priv->clk_rate = (ulong)get_ref_clk() * 1000000;
+
+	a37xx_wdt_disable(priv);
+
+	/*
+	 * We use timer 1 as watchdog timer (because Marvell's Linux uses that
+	 * timer as default), therefore we only set bit TIMER1_IS_WCHDOG_TIMER.
+	 */
+	writel(1 << 1, priv->sel_reg);
+
+	return 0;
+err:
+	dev_err(dev, "no io address\n");
+	return -ENODEV;
+}
+
+static const struct wdt_ops a37xx_wdt_ops = {
+	.start = a37xx_wdt_start,
+	.reset = a37xx_wdt_reset,
+	.stop = a37xx_wdt_stop,
+	.expire_now = a37xx_wdt_expire_now,
+};
+
+static const struct udevice_id a37xx_wdt_ids[] = {
+	{ .compatible = "marvell,armada-3700-wdt" },
+	{}
+};
+
+U_BOOT_DRIVER(a37xx_wdt) = {
+	.name = "armada_37xx_wdt",
+	.id = UCLASS_WDT,
+	.of_match = a37xx_wdt_ids,
+	.probe = a37xx_wdt_probe,
+	.priv_auto_alloc_size = sizeof(struct a37xx_wdt),
+	.ops = &a37xx_wdt_ops,
+};
-- 
2.16.1

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

* [U-Boot] [PATCH v2 20/20] arm64: mvebu: Add basic support for the Turris Mox board
  2018-04-24 15:21 [U-Boot] [PATCH v2 00/20] More support for Armada 37xx boards (for Turris Mox) Marek Behún
                   ` (18 preceding siblings ...)
  2018-04-24 15:21 ` [U-Boot] [PATCH v2 19/20] watchdog: Add support for Armada 37xx CPU watchdog Marek Behún
@ 2018-04-24 15:21 ` Marek Behún
  2018-05-14 11:54 ` [U-Boot] [PATCH v2 00/20] More support for Armada 37xx boards (for Turris Mox) Stefan Roese
  20 siblings, 0 replies; 22+ messages in thread
From: Marek Behún @ 2018-04-24 15:21 UTC (permalink / raw)
  To: u-boot

This adds basic support for the Turris Mox board from CZ.NIC, which is
currently being crowdfunded on Indiegogo.

Turris Mox is as modular router based on the Armada 3720 SOC (same as
EspressoBin).

The basic module can be extended by different modules. The device tree
binary for the kernel can be dependent on which modules are connected,
and in what order. Because of this, the board specific code creates
in U-Boot a variable called module_topology, which carries this
information.

Signed-off-by: Marek Behun <marek.behun@nic.cz>
---
 arch/arm/dts/Makefile                   |   1 +
 arch/arm/dts/armada-3720-turris-mox.dts | 132 ++++++++++++++++++++++++++++++++
 arch/arm/mach-mvebu/Kconfig             |   7 ++
 arch/arm/mach-mvebu/Makefile            |   2 +-
 board/CZ.NIC/turris_mox/MAINTAINERS     |   6 ++
 board/CZ.NIC/turris_mox/Makefile        |   5 ++
 board/CZ.NIC/turris_mox/turris_mox.c    | 127 ++++++++++++++++++++++++++++++
 configs/turris_mox_defconfig            |  76 ++++++++++++++++++
 include/configs/turris_mox.h            | 108 ++++++++++++++++++++++++++
 9 files changed, 463 insertions(+), 1 deletion(-)

diff --git a/arch/arm/dts/Makefile b/arch/arm/dts/Makefile
index ac7667b1e8..07692769d7 100644
--- a/arch/arm/dts/Makefile
+++ b/arch/arm/dts/Makefile
@@ -89,6 +89,7 @@ dtb-$(CONFIG_TEGRA) += tegra20-harmony.dtb \
 dtb-$(CONFIG_ARCH_MVEBU) +=			\
 	armada-3720-db.dtb			\
 	armada-3720-espressobin.dtb		\
+	armada-3720-turris-mox.dtb		\
 	armada-375-db.dtb			\
 	armada-388-clearfog.dtb			\
 	armada-388-gp.dtb			\
diff --git a/arch/arm/dts/armada-3720-turris-mox.dts b/arch/arm/dts/armada-3720-turris-mox.dts
new file mode 100644
index 0000000000..bef100afce
--- /dev/null
+++ b/arch/arm/dts/armada-3720-turris-mox.dts
@@ -0,0 +1,132 @@
+// SPDX-License-Identifier: GPL-2.0+ or X11
+/*
+ * Device Tree file for CZ.NIC Turris Mox Board
+ * 2018 by Marek Behun <marek.behun@nic.cz>
+ *
+ * Based on armada-3720-espressobin.dts by:
+ *   Gregory CLEMENT <gregory.clement@free-electrons.com>
+ *   Konstantin Porotchkin <kostap@marvell.com>
+ */
+
+/dts-v1/;
+
+#include <dt-bindings/gpio/gpio.h>
+#include "armada-372x.dtsi"
+
+/ {
+	model = "CZ.NIC Turris Mox Board";
+	compatible = "cznic,turris-mox", "marvell,armada3720",
+		     "marvell,armada3710";
+
+	chosen {
+		stdout-path = "serial0:115200n8";
+	};
+
+	aliases {
+		ethernet0 = &eth0;
+		i2c0 = &i2c0;
+		spi0 = &spi0;
+	};
+
+	memory {
+		device_type = "memory";
+		reg = <0x00000000 0x00000000 0x00000000 0x20000000>;
+	};
+
+	reg_usb3_vbus: usb3_vbus at 0 {
+		compatible = "regulator-fixed";
+		regulator-name = "usb3-vbus";
+		regulator-min-microvolt = <5000000>;
+		regulator-max-microvolt = <5000000>;
+		shutdown-delay-us = <1000000>;
+		gpio = <&gpiosb 0 GPIO_ACTIVE_HIGH>;
+		regulator-boot-on;
+	};
+
+	mdio {
+		eth_phy1: ethernet-phy at 1 {
+			reg = <1>;
+		};
+	};
+};
+
+&comphy {
+	max-lanes = <3>;
+	phy0 {
+		phy-type = <PHY_TYPE_SGMII1>;
+		phy-speed = <PHY_SPEED_3_125G>;
+	};
+
+	phy1 {
+		phy-type = <PHY_TYPE_PEX0>;
+		phy-speed = <PHY_SPEED_2_5G>;
+	};
+
+	phy2 {
+		phy-type = <PHY_TYPE_USB3_HOST0>;
+		phy-speed = <PHY_SPEED_5G>;
+	};
+};
+
+&eth0 {
+	status = "okay";
+	pinctrl-names = "default";
+	pinctrl-0 = <&rgmii_pins>, <&smi_pins>;
+	phy-mode = "rgmii";
+	phy = <&eth_phy1>;
+};
+
+&i2c0 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&i2c1_pins>;
+	status = "okay";
+};
+
+&sdhci1 {
+	bus-width = <4>;
+	status = "okay";
+};
+
+&pinctrl_nb {
+	spi_cs1_pins: spi-cs1-pins {
+		groups = "spi_cs1";
+		function = "spi";
+	};
+};
+
+&pinctrl_sb {
+	smi_pins: smi-pins {
+		groups = "smi";
+		function = "smi";
+	};
+};
+
+&spi0 {
+	status = "okay";
+	pinctrl-names = "default";
+	pinctrl-0 = <&spi_cs1_pins>;
+
+	spi-flash at 0 {
+		#address-cells = <1>;
+		#size-cells = <1>;
+		compatible = "st,s25fl064l", "spi-flash";
+		reg = <0>;
+		spi-max-frequency = <20000000>;
+		m25p,fast-read;
+	};
+};
+
+&uart0 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&uart1_pins>;
+	status = "okay";
+};
+
+&usb2 {
+	status = "okay";
+};
+
+&usb3 {
+	vbus-supply = <&reg_usb3_vbus>;
+	status = "okay";
+};
diff --git a/arch/arm/mach-mvebu/Kconfig b/arch/arm/mach-mvebu/Kconfig
index 01d700bf2e..5f6ff0b5f3 100644
--- a/arch/arm/mach-mvebu/Kconfig
+++ b/arch/arm/mach-mvebu/Kconfig
@@ -96,6 +96,10 @@ config TARGET_TURRIS_OMNIA
 	bool "Support Turris Omnia"
 	select 88F6820
 
+config TARGET_TURRIS_MOX
+	bool "Support Turris Mox"
+	select ARMADA_3700
+
 config TARGET_MVEBU_ARMADA_8K
 	bool "Support Armada 7k/8k platforms"
 	select ARMADA_8K
@@ -133,6 +137,7 @@ config SYS_BOARD
 	default "db-88f6820-gp" if TARGET_DB_88F6820_GP
 	default "db-88f6820-amc" if TARGET_DB_88F6820_AMC
 	default "turris_omnia" if TARGET_TURRIS_OMNIA
+	default "turris_mox" if TARGET_TURRIS_MOX
 	default "mvebu_armada-8k" if TARGET_MVEBU_ARMADA_8K
 	default "db-mv784mp-gp" if TARGET_DB_MV784MP_GP
 	default "ds414" if TARGET_DS414
@@ -151,6 +156,7 @@ config SYS_CONFIG_NAME
 	default "maxbcm" if TARGET_MAXBCM
 	default "theadorable" if TARGET_THEADORABLE
 	default "turris_omnia" if TARGET_TURRIS_OMNIA
+	default "turris_mox" if TARGET_TURRIS_MOX
 
 config SYS_VENDOR
 	default "Marvell" if TARGET_DB_MV784MP_GP
@@ -162,6 +168,7 @@ config SYS_VENDOR
 	default "solidrun" if TARGET_CLEARFOG
 	default "Synology" if TARGET_DS414
 	default "CZ.NIC" if TARGET_TURRIS_OMNIA
+	default "CZ.NIC" if TARGET_TURRIS_MOX
 
 config SYS_SOC
 	default "mvebu"
diff --git a/arch/arm/mach-mvebu/Makefile b/arch/arm/mach-mvebu/Makefile
index d4210af9d2..b103f34894 100644
--- a/arch/arm/mach-mvebu/Makefile
+++ b/arch/arm/mach-mvebu/Makefile
@@ -9,7 +9,7 @@ ifdef CONFIG_ARM64
 obj-$(CONFIG_ARMADA_3700) += armada3700/
 obj-$(CONFIG_ARMADA_8K) += armada8k/
 obj-y += arm64-common.o
-obj-y += sata.o
+obj-$(CONFIG_AHCI) += sata.o
 
 else # CONFIG_ARM64
 
diff --git a/board/CZ.NIC/turris_mox/MAINTAINERS b/board/CZ.NIC/turris_mox/MAINTAINERS
new file mode 100644
index 0000000000..2b9c1132f5
--- /dev/null
+++ b/board/CZ.NIC/turris_mox/MAINTAINERS
@@ -0,0 +1,6 @@
+TURRIS OMNIA BOARD
+M:	Marek Behún <marek.behun@nic.cz>
+S:	Maintained
+F:	board/CZ.NIC/turris_mox/
+F:	include/configs/turris_mox.h
+F:	configs/turris_mox_defconfig
diff --git a/board/CZ.NIC/turris_mox/Makefile b/board/CZ.NIC/turris_mox/Makefile
new file mode 100644
index 0000000000..619704288b
--- /dev/null
+++ b/board/CZ.NIC/turris_mox/Makefile
@@ -0,0 +1,5 @@
+# SPDX-License-Identifier: GPL-2.0+
+#
+# Copyright (C) 2018 Marek Behun <marek.behun@nic.cz>
+
+obj-y	:= turris_mox.o
diff --git a/board/CZ.NIC/turris_mox/turris_mox.c b/board/CZ.NIC/turris_mox/turris_mox.c
new file mode 100644
index 0000000000..130d4c606d
--- /dev/null
+++ b/board/CZ.NIC/turris_mox/turris_mox.c
@@ -0,0 +1,127 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2018 Marek Behun <marek.behun@nic.cz>
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <clk.h>
+#include <spi.h>
+#include <linux/string.h>
+
+#ifdef CONFIG_WDT_ARMADA_3720
+#include <wdt.h>
+#endif
+
+DECLARE_GLOBAL_DATA_PTR;
+
+#ifdef CONFIG_WDT_ARMADA_3720
+static struct udevice *watchdog_dev;
+
+void watchdog_reset(void)
+{
+	static ulong next_reset;
+	ulong now;
+
+	if (!watchdog_dev)
+		return;
+
+	now = timer_get_us();
+
+	/* Do not reset the watchdog too often */
+	if (now > next_reset) {
+		wdt_reset(watchdog_dev);
+		next_reset = now + 100000;
+	}
+}
+#endif
+
+int board_init(void)
+{
+	/* address of boot parameters */
+	gd->bd->bi_boot_params = CONFIG_SYS_SDRAM_BASE + 0x100;
+
+#ifdef CONFIG_WDT_ARMADA_3720
+	if (uclass_get_device(UCLASS_WDT, 0, &watchdog_dev)) {
+		printf("Cannot find Armada 3720 watchdog!\n");
+	} else {
+		printf("Enabling Armada 3720 watchdog (3 minutes timeout).\n");
+		wdt_start(watchdog_dev, 180000, 0);
+	}
+#endif
+
+	return 0;
+}
+
+int last_stage_init(void)
+{
+	struct spi_slave *slave;
+	struct udevice *dev;
+	u8 din[10], dout[10];
+	int ret, i;
+	size_t len = 0;
+	char module_topology[128];
+
+	ret = spi_get_bus_and_cs(0, 1, 20000000, SPI_CPHA, "spi_generic_drv",
+				 "mox-modules at 1", &dev, &slave);
+	if (ret)
+		goto fail;
+
+	ret = spi_claim_bus(slave);
+	if (ret)
+		goto fail_free;
+
+	memset(din, 0, 10);
+	memset(dout, 0, 10);
+
+	ret = spi_xfer(slave, 80, dout, din, SPI_XFER_ONCE);
+	if (ret)
+		goto fail_release;
+
+	if (din[0] != 0x00 && din[0] != 0xff)
+		goto fail_release;
+
+	printf("Module Topology:\n");
+	for (i = 1; i < 10 && din[i] != 0xff; ++i) {
+		u8 mid = din[i] & 0xf;
+		size_t mlen;
+		const char *mname = "";
+
+		switch (mid) {
+		case 0x1:
+			mname = "sfp-";
+			printf("% 4i: SFP Module\n", i);
+			break;
+		case 0x2:
+			mname = "pci-";
+			printf("% 4i: Mini-PCIe Module\n", i);
+			break;
+		case 0x3:
+			mname = "topaz-";
+			printf("% 4i: Topaz Switch Module\n", i);
+			break;
+		default:
+			printf("% 4i: unknown (ID %i)\n", i, mid);
+		}
+
+		mlen = strlen(mname);
+		if (len + mlen < sizeof(module_topology)) {
+			strcpy(module_topology + len, mname);
+			len += mlen;
+		}
+	}
+	printf("\n");
+
+	module_topology[len > 0 ? len - 1 : 0] = '\0';
+
+	env_set("module_topology", module_topology);
+
+fail_release:
+	spi_release_bus(slave);
+fail_free:
+	spi_free_slave(slave);
+fail:
+	if (ret)
+		printf("Cannot read module topology!\n");
+	return ret;
+}
diff --git a/configs/turris_mox_defconfig b/configs/turris_mox_defconfig
new file mode 100644
index 0000000000..7dea7157dc
--- /dev/null
+++ b/configs/turris_mox_defconfig
@@ -0,0 +1,76 @@
+CONFIG_ARM=y
+CONFIG_ARCH_MVEBU=y
+CONFIG_SYS_TEXT_BASE=0x00000000
+CONFIG_SYS_MALLOC_F_LEN=0x2000
+CONFIG_TARGET_TURRIS_MOX=y
+CONFIG_DEFAULT_DEVICE_TREE="armada-3720-turris-mox"
+CONFIG_DEBUG_UART=y
+CONFIG_DISTRO_DEFAULTS=y
+# CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set
+CONFIG_SYS_CONSOLE_INFO_QUIET=y
+# CONFIG_DISPLAY_CPUINFO is not set
+# CONFIG_DISPLAY_BOARDINFO is not set
+CONFIG_ARCH_EARLY_INIT_R=y
+# CONFIG_CMD_FLASH is not set
+CONFIG_CMD_CLK=y
+CONFIG_CMD_I2C=y
+CONFIG_CMD_MMC=y
+CONFIG_CMD_SF=y
+CONFIG_CMD_SPI=y
+CONFIG_CMD_USB=y
+# CONFIG_CMD_SETEXPR is not set
+CONFIG_CMD_TFTPPUT=y
+CONFIG_CMD_CACHE=y
+CONFIG_CMD_TIME=y
+CONFIG_CMD_MVEBU_BUBT=y
+CONFIG_CMD_BTRFS=y
+CONFIG_CMD_EXT4_WRITE=y
+CONFIG_MAC_PARTITION=y
+CONFIG_ENV_IS_IN_SPI_FLASH=y
+CONFIG_BLOCK_CACHE=y
+CONFIG_DM_I2C=y
+CONFIG_MISC=y
+CONFIG_CLK=y
+CONFIG_CLK_MVEBU=y
+CONFIG_CLK_ARMADA_3720=y
+CONFIG_DM_MMC=y
+CONFIG_MMC_SDHCI=y
+CONFIG_MMC_SDHCI_SDMA=y
+CONFIG_MMC_SDHCI_XENON=y
+CONFIG_WDT=y
+CONFIG_WDT_ARMADA_37XX=y
+CONFIG_DM_GPIO=y
+# CONFIG_MVEBU_GPIO is not set
+CONFIG_PINCTRL=y
+CONFIG_PINCTRL_GENERIC=y
+CONFIG_PINMUX=y
+CONFIG_PINCTRL_ARMADA_37XX=y
+CONFIG_SPI_FLASH=y
+CONFIG_SPI_FLASH_MACRONIX=y
+CONFIG_SPI_FLASH_SPANSION=y
+CONFIG_SPI_FLASH_STMICRO=y
+CONFIG_SPI_FLASH_WINBOND=y
+CONFIG_PHYLIB=y
+CONFIG_PHY_GIGE=y
+CONFIG_MVNETA=y
+CONFIG_MVEBU_COMPHY_SUPPORT=y
+# CONFIG_SPL_SERIAL_PRESENT is not set
+CONFIG_DEBUG_MVEBU_A3700_UART=y
+CONFIG_DEBUG_UART_BASE=0xd0012000
+CONFIG_DEBUG_UART_CLOCK=25804800
+CONFIG_DEBUG_UART_SHIFT=2
+CONFIG_DEBUG_UART_ANNOUNCE=y
+CONFIG_MVEBU_A3700_UART=y
+CONFIG_MVEBU_A3700_SPI=y
+CONFIG_USB=y
+CONFIG_DM_USB=y
+CONFIG_USB_XHCI_HCD=y
+CONFIG_USB_EHCI_HCD=y
+CONFIG_USB_STORAGE=y
+CONFIG_USB_HOST_ETHER=y
+CONFIG_USB_ETHER_ASIX=y
+CONFIG_USB_ETHER_MCS7830=y
+CONFIG_USB_ETHER_RTL8152=y
+CONFIG_USB_ETHER_SMSC95XX=y
+CONFIG_SHA1=y
+CONFIG_SHA256=y
diff --git a/include/configs/turris_mox.h b/include/configs/turris_mox.h
new file mode 100644
index 0000000000..5784851271
--- /dev/null
+++ b/include/configs/turris_mox.h
@@ -0,0 +1,108 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Copyright (C) 2018 Marek Behun <marek.behun@nic.cz>
+ *
+ * Based on mvebu_armada-37xx.h by Stefan Roese <sr@denx.de>
+ */
+
+#ifndef _CONFIG_TURRIS_MOX_H
+#define _CONFIG_TURRIS_MOX_H
+
+#define CONFIG_LAST_STAGE_INIT
+
+/*
+ * High Level Configuration Options (easy to change)
+ */
+#define CONFIG_DISPLAY_BOARDINFO_LATE
+
+/* additions for new ARM relocation support */
+#define CONFIG_SYS_SDRAM_BASE	0x00000000
+
+#define CONFIG_NR_DRAM_BANKS	1
+
+/* auto boot */
+#define CONFIG_PREBOOT
+
+#define CONFIG_SYS_BAUDRATE_TABLE	{ 9600, 19200, 38400, 57600, \
+					  115200, 230400, 460800, 921600 }
+
+/*
+ * For booting Linux, the board info and command line data
+ * have to be in the first 8 MB of memory, since this is
+ * the maximum mapped by the Linux kernel during initialization.
+ */
+#define CONFIG_CMDLINE_TAG		/* enable passing of ATAGs  */
+#define CONFIG_INITRD_TAG		/* enable INITRD tag */
+#define CONFIG_SETUP_MEMORY_TAGS	/* enable memory tag */
+
+#define	CONFIG_SYS_CBSIZE	1024	/* Console I/O Buff Size */
+
+/*
+ * Size of malloc() pool
+ */
+#define CONFIG_SYS_MALLOC_LEN	(4 << 20) /* 4MiB for malloc() */
+
+/*
+ * Other required minimal configurations
+ */
+#define CONFIG_ARCH_CPU_INIT		/* call arch_cpu_init() */
+#define CONFIG_SYS_LOAD_ADDR	0x00800000	/* default load adr- 8M */
+#define CONFIG_SYS_MEMTEST_START 0x00800000	/* 8M */
+#define CONFIG_SYS_MEMTEST_END	0x00ffffff	/*(_16M -1) */
+#define CONFIG_SYS_RESET_ADDRESS 0xffff0000	/* Rst Vector Adr */
+#define CONFIG_SYS_MAXARGS	32	/* max number of command args */
+
+#define CONFIG_SYS_ALT_MEMTEST
+
+/* End of 16M scrubbed by training in bootrom */
+#define CONFIG_SYS_INIT_SP_ADDR         (CONFIG_SYS_TEXT_BASE + 0xFF0000)
+
+/*
+ * I2C
+ */
+#define CONFIG_I2C_MV
+#define CONFIG_SYS_I2C_SLAVE		0x0
+
+/*
+ * SPI Flash configuration
+ */
+#define CONFIG_ENV_SPI_BUS		0
+#define CONFIG_ENV_SPI_CS		0
+
+/* SPI NOR flash default params, used by sf commands */
+#define CONFIG_SF_DEFAULT_SPEED		20000000
+#define CONFIG_SF_DEFAULT_MODE		SPI_MODE_0
+#define CONFIG_ENV_SPI_MODE		CONFIG_SF_DEFAULT_MODE
+
+/* Environment in SPI NOR flash */
+#define CONFIG_ENV_OFFSET		0x180000 /* as Marvell U-Boot version */
+#define CONFIG_ENV_SIZE			(64 << 10) /* 64KiB */
+#define CONFIG_ENV_SECT_SIZE		(64 << 10) /* 64KiB sectors */
+
+/*
+ * Ethernet Driver configuration
+ */
+#define CONFIG_ENV_OVERWRITE	/* ethaddr can be reprogrammed */
+#define CONFIG_ARP_TIMEOUT	200
+#define CONFIG_NET_RETRY_COUNT	50
+#define CONFIG_PHY_MARVELL
+
+#define CONFIG_USB_MAX_CONTROLLER_COUNT (3 + 3)
+
+#define BOOT_TARGET_DEVICES(func) \
+	func(MMC, mmc, 0) \
+	func(USB, usb, 0) \
+	func(PXE, pxe, na) \
+	func(DHCP, dhcp, na)
+
+#include <config_distro_bootcmd.h>
+
+#define CONFIG_EXTRA_ENV_SETTINGS	\
+	"scriptaddr=0x4d00000\0"	\
+	"pxefile_addr_r=0x4e00000\0"	\
+	"fdt_addr_r=0x4f00000\0"	\
+	"kernel_addr_r=0x5000000\0"	\
+	"ramdisk_addr_r=0x8000000\0"	\
+	BOOTENV
+
+#endif /* _CONFIG_TURRIS_MOX_H */
-- 
2.16.1

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

* [U-Boot] [PATCH v2 00/20] More support for Armada 37xx boards (for Turris Mox)
  2018-04-24 15:21 [U-Boot] [PATCH v2 00/20] More support for Armada 37xx boards (for Turris Mox) Marek Behún
                   ` (19 preceding siblings ...)
  2018-04-24 15:21 ` [U-Boot] [PATCH v2 20/20] arm64: mvebu: Add basic support for the Turris Mox board Marek Behún
@ 2018-05-14 11:54 ` Stefan Roese
  20 siblings, 0 replies; 22+ messages in thread
From: Stefan Roese @ 2018-05-14 11:54 UTC (permalink / raw)
  To: u-boot

On 24.04.2018 17:21, Marek Behún wrote:
> This is the second version of patches for updating the support of Armada 37xx
> devices. Here I also send first version of code which adds basic support for the
> Turris Mox board, a router currently being developed here at CZ.NIC, which is
> being crowdfunded now on Indiegogo.
> 
> Changes since v1:
>    - these patches were removed, since the update has already been merged into
>      U-Boot:
>        arm64: mvebu_armada_37xx: Use Armada 37xx pinctrl driver by default
>        armada-37xx: Fix SB pinctrl groups according to new revision
>    - I have changed the names of the functions SGMIIPHY_ADDR and PHY_ADDR to
>      lowercase, as Stefan requested
>    - I have used checkpatch on the patches. There still are come warnings, like
>      "added, moved or deleted file(s), does MAINTAINERS need updating?" or
>      "line over 80 characters" (long string constant in dts). How should I solve
>      these?
>    - some minor changes based on comments from Stefan
>    - added a patch to fix SGMII register addresses
>    - added a patch which adds support for the CPU watchdog on Armada 3720
>    - added a patch which adds basic support for the Turris Mox board
> 
> Please review.

Applied to u-boot-marvell/master

Thanks,
Stefan

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

end of thread, other threads:[~2018-05-14 11:54 UTC | newest]

Thread overview: 22+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-04-24 15:21 [U-Boot] [PATCH v2 00/20] More support for Armada 37xx boards (for Turris Mox) Marek Behún
2018-04-24 15:21 ` [U-Boot] [PATCH v2 01/20] phy: marvell: a3700: Change return type of macro MVEBU_REG Marek Behún
2018-04-24 15:21 ` [U-Boot] [PATCH v2 02/20] phy: marvell: a3700: Use reg_set16 instead of phy_write16 Marek Behún
2018-04-24 15:21 ` [U-Boot] [PATCH v2 03/20] phy: marvell: a3700: Don't create functional macro for each register Marek Behún
2018-04-24 15:21 ` [U-Boot] [PATCH v2 04/20] phy: marvell: a3700: Use same timeout for all register polling Marek Behún
2018-04-24 15:21 ` [U-Boot] [PATCH v2 05/20] phy: marvell: a3700: Use (!ret) instead of (ret == 0) Marek Behún
2018-04-24 15:21 ` [U-Boot] [PATCH v2 06/20] phy: marvell: a3700: Use reg_set_indirect istead of 2 reg_sets Marek Behún
2018-04-24 15:21 ` [U-Boot] [PATCH v2 07/20] phy: marvell: a3700: Access USB3 register indirectly on lane 2 Marek Behún
2018-04-24 15:21 ` [U-Boot] [PATCH v2 08/20] phy: marvell: a3700: Set USB3 RX wait depending on ref clock Marek Behún
2018-04-24 15:21 ` [U-Boot] [PATCH v2 09/20] phy: marvell: a3700: revise the USB3 comphy setting during power on Marek Behún
2018-04-24 15:21 ` [U-Boot] [PATCH v2 10/20] phy: marvell: mux: Support nontrivial node order in selector register Marek Behún
2018-04-24 15:21 ` [U-Boot] [PATCH v2 11/20] phy: marvell: a3700: Fix SGMII cfg and stat register addresses Marek Behún
2018-04-24 15:21 ` [U-Boot] [PATCH v2 12/20] phy: marvell: a3700: Use comphy_mux on Armada 37xx Marek Behún
2018-04-24 15:21 ` [U-Boot] [PATCH v2 13/20] phy: marvell: a3700: Save/restore selector reg in SGMII init Marek Behún
2018-04-24 15:21 ` [U-Boot] [PATCH v2 14/20] driver: clk: Add support for clocks on Armada 37xx Marek Behún
2018-04-24 15:21 ` [U-Boot] [PATCH v2 15/20] spi: mvebu_a3700_spi: Use Armada 37xx clk driver for SPI clock frequency Marek Behún
2018-04-24 15:21 ` [U-Boot] [PATCH v2 16/20] clk: armada-37xx: Support soc_clk_dump Marek Behún
2018-04-24 15:21 ` [U-Boot] [PATCH v2 17/20] phy: marvell: core: Cosmetic fixes Marek Behún
2018-04-24 15:21 ` [U-Boot] [PATCH v2 18/20] net: mvneta: Fix fault when wrong device tree Marek Behún
2018-04-24 15:21 ` [U-Boot] [PATCH v2 19/20] watchdog: Add support for Armada 37xx CPU watchdog Marek Behún
2018-04-24 15:21 ` [U-Boot] [PATCH v2 20/20] arm64: mvebu: Add basic support for the Turris Mox board Marek Behún
2018-05-14 11:54 ` [U-Boot] [PATCH v2 00/20] More support for Armada 37xx boards (for Turris Mox) Stefan Roese

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.