diff options
Diffstat (limited to 'drivers/phy')
-rw-r--r-- | drivers/phy/marvell/comphy.h | 42 | ||||
-rw-r--r-- | drivers/phy/marvell/comphy_a3700.c | 415 | ||||
-rw-r--r-- | drivers/phy/marvell/comphy_a3700.h | 122 | ||||
-rw-r--r-- | drivers/phy/marvell/comphy_core.c | 68 | ||||
-rw-r--r-- | drivers/phy/marvell/comphy_mux.c | 17 |
5 files changed, 365 insertions, 299 deletions
diff --git a/drivers/phy/marvell/comphy.h b/drivers/phy/marvell/comphy.h index 30ab52877b..b588ae41f0 100644 --- a/drivers/phy/marvell/comphy.h +++ b/drivers/phy/marvell/comphy.h @@ -96,14 +96,48 @@ 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; }; /* 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_a3700.c b/drivers/phy/marvell/comphy_a3700.c index bb8d3b2e34..3b2902f362 100644 --- a/drivers/phy/marvell/comphy_a3700.c +++ b/drivers/phy/marvell/comphy_a3700.c @@ -13,6 +13,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; @@ -105,12 +137,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 @@ -133,85 +164,77 @@ static u32 comphy_poll_reg(void *addr, u32 val, u32 mask, u32 timeout, */ static int comphy_pcie_power_up(u32 speed, u32 invert) { - int ret; + int ret; debug_enter(); /* * 1. Enable max PLL. */ - reg_set16((void __iomem *)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((void __iomem *)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((void __iomem *)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((void __iomem *)PWR_MGM_TIM1_ADDR(PCIE), 0x10C, 0xFFFF); + reg_set16(phy_addr(PCIE, PWR_MGM_TIM1), 0x10C, 0xFFFF); /* * 5. Enable idle sync */ - reg_set16((void __iomem *)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((void __iomem *)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((void __iomem *)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((void __iomem *)PWR_PLL_CTRL_ADDR(PCIE), - 0xFC63, 0xFFFF); /* 40 MHz */ + /* 40 MHz */ + reg_set16(phy_addr(PCIE, PWR_PLL_CTRL), 0xFC63, 0xFFFF); } else { - reg_set16((void __iomem *)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((void __iomem *)KVCO_CAL_CTRL_ADDR(PCIE), - 0x0040 | rb_use_max_pll_rate, 0xFFFF); + 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((void __iomem *)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((void __iomem *)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((void __iomem *)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); @@ -219,12 +242,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 */ + 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) + if (!ret) printf("Failed to lock PCIe PLL\n"); debug_exit(); @@ -234,71 +256,74 @@ static int comphy_pcie_power_up(u32 speed, u32 invert) } /* + * 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 * * return: 1 if PLL locked (OK), 0 otherwise (FAIL) */ static int comphy_sata_power_up(void) { - int ret; + int ret; debug_enter(); /* * 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_indirect(vphy_sync_pattern_reg, 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_indirect(vphy_loopback_reg0, 0x800, bs_phyintf_40bit); /* * 2. Select reference clock and PHY mode (SATA) */ - reg_set((void __iomem *)rh_vsreg_addr, vphy_power_reg0, 0xFFFFFFFF); if (get_ref_clk() == 40) { - reg_set((void __iomem *)rh_vsreg_data, - 0x3, 0x00FF); /* 40 MHz */ + /* 40 MHz */ + reg_set_indirect(vphy_power_reg0, 0x3, 0x00FF); } else { - reg_set((void __iomem *)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((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_indirect(vphy_calctl_reg, 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_indirect(vphy_reserve_reg, 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 */ - if (ret == 0) + 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 */ + POLL_32B_REG); /* 32bit */ + if (!ret) printf("Failed to lock SATA PLL\n"); debug_exit(); @@ -307,137 +332,171 @@ static int comphy_sata_power_up(void) } /* + * 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(); /* * 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); + usb3_reg_set16(LANE_CFG0, 0x1, 0xFF, lane); /* - * unset BIT0: set Tx Electrical Idle Mode: Transmitter is in - * low impedance mode during electrical idle + * 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 */ - /* 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); - + 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 */ - reg_set16((void __iomem *)LANE_CFG4_ADDR(USB3), - 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((void __iomem *)TEST_MODE_CTRL_ADDR(USB3), - 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((void __iomem *)GLOB_CLK_SRC_LO_ADDR(USB3), 0x0, 0xFF); + usb3_reg_set16(GLOB_CLK_SRC_LO, 0x0, 0xFF, lane); /* set G2 Spread Spectrum Clock Amplitude at 4K */ - reg_set16((void __iomem *)GEN2_SETTING_2_ADDR(USB3), 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((void __iomem *)GEN2_SETTING_3_ADDR(USB3), 0x0, 0xFFFF); + usb3_reg_set16(GEN2_SETTINGS_3, 0x0, 0xFFFF, lane); /* * 3. Check crystal jumper setting and program the Power and PLL * Control accordingly + * 4. Change RX wait */ if (get_ref_clk() == 40) { - reg_set16((void __iomem *)PWR_PLL_CTRL_ADDR(USB3), 0xFCA3, - 0xFFFF); /* 40 MHz */ + /* 40 MHz */ + usb3_reg_set16(PWR_PLL_CTRL, 0xFCA3, 0xFFFF, lane); + usb3_reg_set16(PWR_MGM_TIM1, 0x10C, 0xFFFF, lane); } else { - reg_set16((void __iomem *)PWR_PLL_CTRL_ADDR(USB3), 0xFCA2, - 0xFFFF); /* 25 MHz */ + /* 25 MHz */ + usb3_reg_set16(PWR_PLL_CTRL, 0xFCA2, 0xFFFF, lane); + usb3_reg_set16(PWR_MGM_TIM1, 0x107, 0xFFFF, lane); } /* - * 4. Change RX wait - */ - reg_set16((void __iomem *)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); + usb3_reg_set16(UNIT_CTRL, 0x60 | rb_idle_sync_en, 0xFFFF, lane); /* * 6. Enable the output of 500M clock */ - reg_set16((void __iomem *)MISC_REG0_ADDR(USB3), 0xA00D | rb_clk500m_en, - 0xFFFF); + usb3_reg_set16(MISC_REG0, 0xA00D | rb_clk500m_en, 0xFFFF, lane); /* * 7. Set 20-bit data width */ - reg_set16((void __iomem *)DIG_LB_EN_ADDR(USB3), 0x0400, 0xFFFF); + usb3_reg_set16(DIG_LB_EN, 0x0400, 0xFFFF, lane); /* * 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); + 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((void __iomem *)SYNC_PATTERN_ADDR(USB3), - phy_txd_inv, 0); - } + if (invert & PHY_POLARITY_TXD_INVERT) + usb3_reg_set16(SYNC_PATTERN, phy_txd_inv, 0, lane); - if (invert & PHY_POLARITY_RXD_INVERT) { - reg_set16((void __iomem *)SYNC_PATTERN_ADDR(USB3), - phy_rxd_inv, 0); - } + if (invert & PHY_POLARITY_RXD_INVERT) + usb3_reg_set16(SYNC_PATTERN, phy_rxd_inv, 0, lane); /* - * 10. Release SW reset + * 10. Set max speed generation to USB3.0 5Gbps */ - reg_set16((void __iomem *)GLOB_PHY_CTRL0_ADDR(USB3), - rb_mode_core_clk_freq_sel | rb_mode_pipe_width_32 | 0x20, - 0xFFFF); + 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 + | 0x20, 0xFFFF, lane); /* Wait for > 55 us to allow PCLK be enabled */ 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 */ - if (ret == 0) + 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"); /* @@ -454,7 +513,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); @@ -472,7 +531,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(); @@ -488,65 +547,61 @@ 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 */ POLL_32B_REG); /* 32bit */ - if (ret == 0) + if (!ret) 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 */ POLL_32B_REG); /* 32bit */ - if (ret == 0) + if (!ret) 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 */ POLL_32B_REG); /* 32bit */ - if (ret == 0) + if (!ret) 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 */ POLL_32B_REG); /* 32bit */ - if (ret == 0) + if (!ret) printf("Failed to lock USB2 PLL\n"); debug_exit(); @@ -566,35 +621,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(); @@ -631,7 +685,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); } } @@ -642,14 +696,16 @@ 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; + u32 saved_selector; debug_enter(); /* * 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)); + saved_selector = readl(COMPHY_SEL_ADDR); + reg_set(COMPHY_SEL_ADDR, 0, 0xFFFFFFFF); /* * 2. Reset PHY by setting PHY input port PIN_RESET=1. @@ -657,7 +713,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); @@ -665,21 +721,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); @@ -695,26 +750,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, 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 */ - phy_write16(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) { - phy_write16(lane, PHY_PWR_PLL_CTRL_ADDR, - 0x4 << rf_ref_freq_sel_shift, rf_ref_freq_sel_mask); + reg_set16(sgmiiphy_addr(lane, PWR_PLL_CTRL), + 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, PWR_PLL_CTRL), + 0x1 << rf_ref_freq_sel_shift, rf_ref_freq_sel_mask); } /* 12. Program COMPHY register PHY_GEN_MAX[1:0] */ @@ -730,7 +785,7 @@ 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, DIG_LB_EN), 0, rf_data_width_mask); /* * 14. As long as DFE function needs to be enabled in any mode, @@ -773,10 +828,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) - phy_write16(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) - phy_write16(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 @@ -784,7 +839,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); @@ -792,19 +847,17 @@ 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 */ POLL_32B_REG); /* 32bit */ - if (ret == 0) + if (!ret) printf("Failed to lock PLL for SGMII PHY %d\n", lane); /* * 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. @@ -814,17 +867,20 @@ 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 */ POLL_32B_REG); /* 32bit */ - if (ret == 0) + 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; @@ -844,7 +900,7 @@ void comphy_dedicated_phys_init(void) */ if (usb32 == 0) { node = fdt_node_offset_by_compatible( - blob, -1, "marvell,armada-3700-ehci"); + blob, -1, "marvell,armada3700-ehci"); } else { node = fdt_node_offset_by_compatible( blob, -1, "marvell,armada3700-xhci"); @@ -853,7 +909,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"); @@ -871,7 +927,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"); @@ -892,7 +948,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"); @@ -915,6 +971,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); @@ -933,7 +993,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; @@ -950,7 +1011,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); } diff --git a/drivers/phy/marvell/comphy_a3700.h b/drivers/phy/marvell/comphy_a3700.h index 322fc371f1..a14767d809 100644 --- a/drivers/phy/marvell/comphy_a3700.h +++ b/drivers/phy/marvell/comphy_a3700.h @@ -9,7 +9,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 @@ -21,9 +22,8 @@ * 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 + (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) @@ -37,7 +37,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) @@ -58,125 +58,115 @@ #define USB2PHY2_BASE MVEBU_REG(0x05F000) #define USB32_CTRL_BASE MVEBU_REG(0x05D800) #define USB3PHY_SHFT 2 +#define USB3PHY_LANE2_REG_BASE_OFFSET 0x200 -#define SGMIIPHY_BASE(l) (l == 1 ? USB3PHY_BASE : PCIEPHY_BASE) -#define SGMIIPHY_ADDR(l, a) (((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) +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 -#define USB3 2 - -#define PHY_BASE(unit) ((unit == PCIE) ? PCIEPHY_BASE : USB3PHY_BASE) -#define PHY_SHFT(unit) ((unit == PCIE) ? PCIEPHY_SHFT : USB3PHY_SHFT) +enum phy_unit { + PCIE = 1, + USB3 = 2, +}; + +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 -/* 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 GEN3_SETTINGS_3 0x112 + +#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 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) -#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) diff --git a/drivers/phy/marvell/comphy_core.c b/drivers/phy/marvell/comphy_core.c index 17ab39c5d0..c6e2cc8897 100644 --- a/drivers/phy/marvell/comphy_core.c +++ b/drivers/phy/marvell/comphy_core.c @@ -17,11 +17,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"; @@ -29,14 +31,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"; @@ -44,44 +48,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) { @@ -134,6 +100,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 0538702317..1f757d8e04 100644 --- a/drivers/phy/marvell/comphy_mux.c +++ b/drivers/phy/marvell/comphy_mux.c @@ -78,7 +78,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; @@ -89,7 +90,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, @@ -105,6 +114,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; @@ -112,13 +122,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(); } |