13335786aSStefan Roese /*
23335786aSStefan Roese * Copyright (C) 2015-2016 Marvell International Ltd.
33335786aSStefan Roese *
43335786aSStefan Roese * SPDX-License-Identifier: GPL-2.0+
53335786aSStefan Roese */
63335786aSStefan Roese
73335786aSStefan Roese #include <common.h>
83335786aSStefan Roese #include <fdtdec.h>
93335786aSStefan Roese #include <asm/io.h>
103335786aSStefan Roese #include <asm/arch/cpu.h>
113335786aSStefan Roese #include <asm/arch/soc.h>
123335786aSStefan Roese
133335786aSStefan Roese #include "comphy_a3700.h"
143335786aSStefan Roese
153335786aSStefan Roese DECLARE_GLOBAL_DATA_PTR;
163335786aSStefan Roese
173335786aSStefan Roese struct sgmii_phy_init_data_fix {
183335786aSStefan Roese u16 addr;
193335786aSStefan Roese u16 value;
203335786aSStefan Roese };
213335786aSStefan Roese
223335786aSStefan Roese /* Changes to 40M1G25 mode data required for running 40M3G125 init mode */
233335786aSStefan Roese static struct sgmii_phy_init_data_fix sgmii_phy_init_fix[] = {
243335786aSStefan Roese {0x005, 0x07CC}, {0x015, 0x0000}, {0x01B, 0x0000}, {0x01D, 0x0000},
253335786aSStefan Roese {0x01E, 0x0000}, {0x01F, 0x0000}, {0x020, 0x0000}, {0x021, 0x0030},
263335786aSStefan Roese {0x026, 0x0888}, {0x04D, 0x0152}, {0x04F, 0xA020}, {0x050, 0x07CC},
273335786aSStefan Roese {0x053, 0xE9CA}, {0x055, 0xBD97}, {0x071, 0x3015}, {0x076, 0x03AA},
283335786aSStefan Roese {0x07C, 0x0FDF}, {0x0C2, 0x3030}, {0x0C3, 0x8000}, {0x0E2, 0x5550},
293335786aSStefan Roese {0x0E3, 0x12A4}, {0x0E4, 0x7D00}, {0x0E6, 0x0C83}, {0x101, 0xFCC0},
303335786aSStefan Roese {0x104, 0x0C10}
313335786aSStefan Roese };
323335786aSStefan Roese
333335786aSStefan Roese /* 40M1G25 mode init data */
343335786aSStefan Roese static u16 sgmii_phy_init[512] = {
353335786aSStefan Roese /* 0 1 2 3 4 5 6 7 */
363335786aSStefan Roese /*-----------------------------------------------------------*/
373335786aSStefan Roese /* 8 9 A B C D E F */
383335786aSStefan Roese 0x3110, 0xFD83, 0x6430, 0x412F, 0x82C0, 0x06FA, 0x4500, 0x6D26, /* 00 */
393335786aSStefan Roese 0xAFC0, 0x8000, 0xC000, 0x0000, 0x2000, 0x49CC, 0x0BC9, 0x2A52, /* 08 */
403335786aSStefan Roese 0x0BD2, 0x0CDE, 0x13D2, 0x0CE8, 0x1149, 0x10E0, 0x0000, 0x0000, /* 10 */
413335786aSStefan Roese 0x0000, 0x0000, 0x0000, 0x0001, 0x0000, 0x4134, 0x0D2D, 0xFFFF, /* 18 */
423335786aSStefan Roese 0xFFE0, 0x4030, 0x1016, 0x0030, 0x0000, 0x0800, 0x0866, 0x0000, /* 20 */
433335786aSStefan Roese 0x0000, 0x0000, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, /* 28 */
443335786aSStefan Roese 0xFFFF, 0xFFFF, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* 30 */
453335786aSStefan Roese 0x0000, 0x0000, 0x000F, 0x6A62, 0x1988, 0x3100, 0x3100, 0x3100, /* 38 */
463335786aSStefan Roese 0x3100, 0xA708, 0x2430, 0x0830, 0x1030, 0x4610, 0xFF00, 0xFF00, /* 40 */
473335786aSStefan Roese 0x0060, 0x1000, 0x0400, 0x0040, 0x00F0, 0x0155, 0x1100, 0xA02A, /* 48 */
483335786aSStefan Roese 0x06FA, 0x0080, 0xB008, 0xE3ED, 0x5002, 0xB592, 0x7A80, 0x0001, /* 50 */
493335786aSStefan Roese 0x020A, 0x8820, 0x6014, 0x8054, 0xACAA, 0xFC88, 0x2A02, 0x45CF, /* 58 */
503335786aSStefan Roese 0x000F, 0x1817, 0x2860, 0x064F, 0x0000, 0x0204, 0x1800, 0x6000, /* 60 */
513335786aSStefan Roese 0x810F, 0x4F23, 0x4000, 0x4498, 0x0850, 0x0000, 0x000E, 0x1002, /* 68 */
523335786aSStefan Roese 0x9D3A, 0x3009, 0xD066, 0x0491, 0x0001, 0x6AB0, 0x0399, 0x3780, /* 70 */
533335786aSStefan Roese 0x0040, 0x5AC0, 0x4A80, 0x0000, 0x01DF, 0x0000, 0x0007, 0x0000, /* 78 */
543335786aSStefan Roese 0x2D54, 0x00A1, 0x4000, 0x0100, 0xA20A, 0x0000, 0x0000, 0x0000, /* 80 */
553335786aSStefan Roese 0x0000, 0x0000, 0x0000, 0x7400, 0x0E81, 0x1000, 0x1242, 0x0210, /* 88 */
563335786aSStefan Roese 0x80DF, 0x0F1F, 0x2F3F, 0x4F5F, 0x6F7F, 0x0F1F, 0x2F3F, 0x4F5F, /* 90 */
573335786aSStefan Roese 0x6F7F, 0x4BAD, 0x0000, 0x0000, 0x0800, 0x0000, 0x2400, 0xB651, /* 98 */
583335786aSStefan Roese 0xC9E0, 0x4247, 0x0A24, 0x0000, 0xAF19, 0x1004, 0x0000, 0x0000, /* A0 */
593335786aSStefan Roese 0x0000, 0x0013, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* A8 */
603335786aSStefan Roese 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /* B0 */
613335786aSStefan Roese 0x0000, 0x0000, 0x0000, 0x0060, 0x0000, 0x0000, 0x0000, 0x0000, /* B8 */
623335786aSStefan Roese 0x0000, 0x0000, 0x3010, 0xFA00, 0x0000, 0x0000, 0x0000, 0x0003, /* C0 */
633335786aSStefan Roese 0x1618, 0x8200, 0x8000, 0x0400, 0x050F, 0x0000, 0x0000, 0x0000, /* C8 */
643335786aSStefan Roese 0x4C93, 0x0000, 0x1000, 0x1120, 0x0010, 0x1242, 0x1242, 0x1E00, /* D0 */
653335786aSStefan Roese 0x0000, 0x0000, 0x0000, 0x00F8, 0x0000, 0x0041, 0x0800, 0x0000, /* D8 */
663335786aSStefan Roese 0x82A0, 0x572E, 0x2490, 0x14A9, 0x4E00, 0x0000, 0x0803, 0x0541, /* E0 */
673335786aSStefan Roese 0x0C15, 0x0000, 0x0000, 0x0400, 0x2626, 0x0000, 0x0000, 0x4200, /* E8 */
683335786aSStefan Roese 0x0000, 0xAA55, 0x1020, 0x0000, 0x0000, 0x5010, 0x0000, 0x0000, /* F0 */
693335786aSStefan Roese 0x0000, 0x0000, 0x5000, 0x0000, 0x0000, 0x0000, 0x02F2, 0x0000, /* F8 */
703335786aSStefan Roese 0x101F, 0xFDC0, 0x4000, 0x8010, 0x0110, 0x0006, 0x0000, 0x0000, /*100 */
713335786aSStefan Roese 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /*108 */
723335786aSStefan Roese 0x04CF, 0x0000, 0x04CF, 0x0000, 0x04CF, 0x0000, 0x04C6, 0x0000, /*110 */
733335786aSStefan Roese 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /*118 */
743335786aSStefan Roese 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /*120 */
753335786aSStefan Roese 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /*128 */
763335786aSStefan Roese 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /*130 */
773335786aSStefan Roese 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /*138 */
783335786aSStefan Roese 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /*140 */
793335786aSStefan Roese 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /*148 */
803335786aSStefan Roese 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /*150 */
813335786aSStefan Roese 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /*158 */
823335786aSStefan Roese 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /*160 */
833335786aSStefan Roese 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /*168 */
843335786aSStefan Roese 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /*170 */
853335786aSStefan Roese 0x0000, 0x0000, 0x0000, 0x00F0, 0x08A2, 0x3112, 0x0A14, 0x0000, /*178 */
863335786aSStefan Roese 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /*180 */
873335786aSStefan Roese 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /*188 */
883335786aSStefan Roese 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /*190 */
893335786aSStefan Roese 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /*198 */
903335786aSStefan Roese 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /*1A0 */
913335786aSStefan Roese 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /*1A8 */
923335786aSStefan Roese 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /*1B0 */
933335786aSStefan Roese 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /*1B8 */
943335786aSStefan Roese 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /*1C0 */
953335786aSStefan Roese 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /*1C8 */
963335786aSStefan Roese 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /*1D0 */
973335786aSStefan Roese 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /*1D8 */
983335786aSStefan Roese 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /*1E0 */
993335786aSStefan Roese 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /*1E8 */
1003335786aSStefan Roese 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /*1F0 */
1013335786aSStefan Roese 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 /*1F8 */
1023335786aSStefan Roese };
1033335786aSStefan Roese
1043335786aSStefan Roese /*
1053335786aSStefan Roese * comphy_poll_reg
1063335786aSStefan Roese *
1073335786aSStefan Roese * return: 1 on success, 0 on timeout
1083335786aSStefan Roese */
comphy_poll_reg(void * addr,u32 val,u32 mask,u32 timeout,u8 op_type)1093335786aSStefan Roese static u32 comphy_poll_reg(void *addr, u32 val, u32 mask, u32 timeout,
1103335786aSStefan Roese u8 op_type)
1113335786aSStefan Roese {
1123335786aSStefan Roese u32 rval = 0xDEAD;
1133335786aSStefan Roese
1143335786aSStefan Roese for (; timeout > 0; timeout--) {
1153335786aSStefan Roese if (op_type == POLL_16B_REG)
1163335786aSStefan Roese rval = readw(addr); /* 16 bit */
1173335786aSStefan Roese else
1183335786aSStefan Roese rval = readl(addr) ; /* 32 bit */
1193335786aSStefan Roese
1203335786aSStefan Roese if ((rval & mask) == val)
1213335786aSStefan Roese return 1;
1223335786aSStefan Roese
1233335786aSStefan Roese udelay(10000);
1243335786aSStefan Roese }
1253335786aSStefan Roese
1263335786aSStefan Roese debug("Time out waiting (%p = %#010x)\n", addr, rval);
1273335786aSStefan Roese return 0;
1283335786aSStefan Roese }
1293335786aSStefan Roese
1303335786aSStefan Roese /*
1313335786aSStefan Roese * comphy_pcie_power_up
1323335786aSStefan Roese *
1333335786aSStefan Roese * return: 1 if PLL locked (OK), 0 otherwise (FAIL)
1343335786aSStefan Roese */
comphy_pcie_power_up(u32 speed,u32 invert)1353335786aSStefan Roese static int comphy_pcie_power_up(u32 speed, u32 invert)
1363335786aSStefan Roese {
1373335786aSStefan Roese int ret;
1383335786aSStefan Roese
1393335786aSStefan Roese debug_enter();
1403335786aSStefan Roese
1413335786aSStefan Roese /*
1423335786aSStefan Roese * 1. Enable max PLL.
1433335786aSStefan Roese */
1443335786aSStefan Roese reg_set16((void __iomem *)LANE_CFG1_ADDR(PCIE),
1453335786aSStefan Roese bf_use_max_pll_rate, 0);
1463335786aSStefan Roese
1473335786aSStefan Roese /*
1483335786aSStefan Roese * 2. Select 20 bit SERDES interface.
1493335786aSStefan Roese */
1503335786aSStefan Roese reg_set16((void __iomem *)GLOB_CLK_SRC_LO_ADDR(PCIE),
1513335786aSStefan Roese bf_cfg_sel_20b, 0);
1523335786aSStefan Roese
1533335786aSStefan Roese /*
1543335786aSStefan Roese * 3. Force to use reg setting for PCIe mode
1553335786aSStefan Roese */
1563335786aSStefan Roese reg_set16((void __iomem *)MISC_REG1_ADDR(PCIE),
1573335786aSStefan Roese bf_sel_bits_pcie_force, 0);
1583335786aSStefan Roese
1593335786aSStefan Roese /*
1603335786aSStefan Roese * 4. Change RX wait
1613335786aSStefan Roese */
1623335786aSStefan Roese reg_set16((void __iomem *)PWR_MGM_TIM1_ADDR(PCIE), 0x10C, 0xFFFF);
1633335786aSStefan Roese
1643335786aSStefan Roese /*
1653335786aSStefan Roese * 5. Enable idle sync
1663335786aSStefan Roese */
1673335786aSStefan Roese reg_set16((void __iomem *)UNIT_CTRL_ADDR(PCIE),
1683335786aSStefan Roese 0x60 | rb_idle_sync_en, 0xFFFF);
1693335786aSStefan Roese
1703335786aSStefan Roese /*
1713335786aSStefan Roese * 6. Enable the output of 100M/125M/500M clock
1723335786aSStefan Roese */
1733335786aSStefan Roese reg_set16((void __iomem *)MISC_REG0_ADDR(PCIE),
1743335786aSStefan Roese 0xA00D | rb_clk500m_en | rb_clk100m_125m_en, 0xFFFF);
1753335786aSStefan Roese
1763335786aSStefan Roese /*
1773335786aSStefan Roese * 7. Enable TX
1783335786aSStefan Roese */
1793335786aSStefan Roese reg_set((void __iomem *)PHY_REF_CLK_ADDR, 0x1342, 0xFFFFFFFF);
1803335786aSStefan Roese
1813335786aSStefan Roese /*
1823335786aSStefan Roese * 8. Check crystal jumper setting and program the Power and PLL
1833335786aSStefan Roese * Control accordingly
1843335786aSStefan Roese */
1853335786aSStefan Roese if (get_ref_clk() == 40) {
1863335786aSStefan Roese reg_set16((void __iomem *)PWR_PLL_CTRL_ADDR(PCIE),
1873335786aSStefan Roese 0xFC63, 0xFFFF); /* 40 MHz */
1883335786aSStefan Roese } else {
1893335786aSStefan Roese reg_set16((void __iomem *)PWR_PLL_CTRL_ADDR(PCIE),
1903335786aSStefan Roese 0xFC62, 0xFFFF); /* 25 MHz */
1913335786aSStefan Roese }
1923335786aSStefan Roese
1933335786aSStefan Roese /*
1943335786aSStefan Roese * 9. Override Speed_PLL value and use MAC PLL
1953335786aSStefan Roese */
1963335786aSStefan Roese reg_set16((void __iomem *)KVCO_CAL_CTRL_ADDR(PCIE),
1973335786aSStefan Roese 0x0040 | rb_use_max_pll_rate, 0xFFFF);
1983335786aSStefan Roese
1993335786aSStefan Roese /*
2003335786aSStefan Roese * 10. Check the Polarity invert bit
2013335786aSStefan Roese */
2023335786aSStefan Roese if (invert & PHY_POLARITY_TXD_INVERT) {
2033335786aSStefan Roese reg_set16((void __iomem *)SYNC_PATTERN_ADDR(PCIE),
2043335786aSStefan Roese phy_txd_inv, 0);
2053335786aSStefan Roese }
2063335786aSStefan Roese
2073335786aSStefan Roese if (invert & PHY_POLARITY_RXD_INVERT) {
2083335786aSStefan Roese reg_set16((void __iomem *)SYNC_PATTERN_ADDR(PCIE),
2093335786aSStefan Roese phy_rxd_inv, 0);
2103335786aSStefan Roese }
2113335786aSStefan Roese
2123335786aSStefan Roese /*
2133335786aSStefan Roese * 11. Release SW reset
2143335786aSStefan Roese */
2153335786aSStefan Roese reg_set16((void __iomem *)GLOB_PHY_CTRL0_ADDR(PCIE),
2163335786aSStefan Roese rb_mode_core_clk_freq_sel | rb_mode_pipe_width_32,
2173335786aSStefan Roese bf_soft_rst | bf_mode_refdiv);
2183335786aSStefan Roese
2193335786aSStefan Roese /* Wait for > 55 us to allow PCLK be enabled */
2203335786aSStefan Roese udelay(PLL_SET_DELAY_US);
2213335786aSStefan Roese
2223335786aSStefan Roese /* Assert PCLK enabled */
2233335786aSStefan Roese ret = comphy_poll_reg((void *)LANE_STAT1_ADDR(PCIE), /* address */
2243335786aSStefan Roese rb_txdclk_pclk_en, /* value */
2253335786aSStefan Roese rb_txdclk_pclk_en, /* mask */
2263335786aSStefan Roese PLL_LOCK_TIMEOUT, /* timeout */
2273335786aSStefan Roese POLL_16B_REG); /* 16bit */
2283335786aSStefan Roese if (ret == 0)
2293335786aSStefan Roese printf("Failed to lock PCIe PLL\n");
2303335786aSStefan Roese
2313335786aSStefan Roese debug_exit();
2323335786aSStefan Roese
2333335786aSStefan Roese /* Return the status of the PLL */
2343335786aSStefan Roese return ret;
2353335786aSStefan Roese }
2363335786aSStefan Roese
2373335786aSStefan Roese /*
2383335786aSStefan Roese * comphy_sata_power_up
2393335786aSStefan Roese *
2403335786aSStefan Roese * return: 1 if PLL locked (OK), 0 otherwise (FAIL)
2413335786aSStefan Roese */
comphy_sata_power_up(void)2423335786aSStefan Roese static int comphy_sata_power_up(void)
2433335786aSStefan Roese {
2443335786aSStefan Roese int ret;
2453335786aSStefan Roese
2463335786aSStefan Roese debug_enter();
2473335786aSStefan Roese
2483335786aSStefan Roese /*
2493335786aSStefan Roese * 0. Swap SATA TX lines
2503335786aSStefan Roese */
2513335786aSStefan Roese reg_set((void __iomem *)rh_vsreg_addr,
2523335786aSStefan Roese vphy_sync_pattern_reg, 0xFFFFFFFF);
2533335786aSStefan Roese reg_set((void __iomem *)rh_vsreg_data, bs_txd_inv, bs_txd_inv);
2543335786aSStefan Roese
2553335786aSStefan Roese /*
2563335786aSStefan Roese * 1. Select 40-bit data width width
2573335786aSStefan Roese */
2583335786aSStefan Roese reg_set((void __iomem *)rh_vsreg_addr, vphy_loopback_reg0, 0xFFFFFFFF);
2593335786aSStefan Roese reg_set((void __iomem *)rh_vsreg_data, 0x800, bs_phyintf_40bit);
2603335786aSStefan Roese
2613335786aSStefan Roese /*
2623335786aSStefan Roese * 2. Select reference clock and PHY mode (SATA)
2633335786aSStefan Roese */
2643335786aSStefan Roese reg_set((void __iomem *)rh_vsreg_addr, vphy_power_reg0, 0xFFFFFFFF);
2653335786aSStefan Roese if (get_ref_clk() == 40) {
2663335786aSStefan Roese reg_set((void __iomem *)rh_vsreg_data,
2673335786aSStefan Roese 0x3, 0x00FF); /* 40 MHz */
2683335786aSStefan Roese } else {
2693335786aSStefan Roese reg_set((void __iomem *)rh_vsreg_data,
2703335786aSStefan Roese 0x1, 0x00FF); /* 25 MHz */
2713335786aSStefan Roese }
2723335786aSStefan Roese
2733335786aSStefan Roese /*
2743335786aSStefan Roese * 3. Use maximum PLL rate (no power save)
2753335786aSStefan Roese */
2763335786aSStefan Roese reg_set((void __iomem *)rh_vsreg_addr, vphy_calctl_reg, 0xFFFFFFFF);
2773335786aSStefan Roese reg_set((void __iomem *)rh_vsreg_data,
2783335786aSStefan Roese bs_max_pll_rate, bs_max_pll_rate);
2793335786aSStefan Roese
2803335786aSStefan Roese /*
2813335786aSStefan Roese * 4. Reset reserved bit (??)
2823335786aSStefan Roese */
2833335786aSStefan Roese reg_set((void __iomem *)rh_vsreg_addr, vphy_reserve_reg, 0xFFFFFFFF);
2843335786aSStefan Roese reg_set((void __iomem *)rh_vsreg_data, 0, bs_phyctrl_frm_pin);
2853335786aSStefan Roese
2863335786aSStefan Roese /*
2873335786aSStefan Roese * 5. Set vendor-specific configuration (??)
2883335786aSStefan Roese */
2893335786aSStefan Roese reg_set((void __iomem *)rh_vs0_a, vsata_ctrl_reg, 0xFFFFFFFF);
2903335786aSStefan Roese reg_set((void __iomem *)rh_vs0_d, bs_phy_pu_pll, bs_phy_pu_pll);
2913335786aSStefan Roese
2923335786aSStefan Roese /* Wait for > 55 us to allow PLL be enabled */
2933335786aSStefan Roese udelay(PLL_SET_DELAY_US);
2943335786aSStefan Roese
2953335786aSStefan Roese /* Assert SATA PLL enabled */
2963335786aSStefan Roese reg_set((void __iomem *)rh_vsreg_addr, vphy_loopback_reg0, 0xFFFFFFFF);
2973335786aSStefan Roese ret = comphy_poll_reg((void *)rh_vsreg_data, /* address */
2983335786aSStefan Roese bs_pll_ready_tx, /* value */
2993335786aSStefan Roese bs_pll_ready_tx, /* mask */
3003335786aSStefan Roese PLL_LOCK_TIMEOUT, /* timeout */
3013335786aSStefan Roese POLL_32B_REG); /* 32bit */
3023335786aSStefan Roese if (ret == 0)
3033335786aSStefan Roese printf("Failed to lock SATA PLL\n");
3043335786aSStefan Roese
3053335786aSStefan Roese debug_exit();
3063335786aSStefan Roese
3073335786aSStefan Roese return ret;
3083335786aSStefan Roese }
3093335786aSStefan Roese
3103335786aSStefan Roese /*
3113335786aSStefan Roese * comphy_usb3_power_up
3123335786aSStefan Roese *
3133335786aSStefan Roese * return: 1 if PLL locked (OK), 0 otherwise (FAIL)
3143335786aSStefan Roese */
comphy_usb3_power_up(u32 type,u32 speed,u32 invert)3153335786aSStefan Roese static int comphy_usb3_power_up(u32 type, u32 speed, u32 invert)
3163335786aSStefan Roese {
3173335786aSStefan Roese int ret;
3183335786aSStefan Roese
3193335786aSStefan Roese debug_enter();
3203335786aSStefan Roese
3213335786aSStefan Roese /*
3223335786aSStefan Roese * 1. Power up OTG module
3233335786aSStefan Roese */
3243335786aSStefan Roese reg_set((void __iomem *)USB2_PHY_OTG_CTRL_ADDR, rb_pu_otg, 0);
3253335786aSStefan Roese
3263335786aSStefan Roese /*
3273335786aSStefan Roese * 2. Set counter for 100us pulse in USB3 Host and Device
3283335786aSStefan Roese * restore default burst size limit (Reference Clock 31:24)
3293335786aSStefan Roese */
3303335786aSStefan Roese reg_set((void __iomem *)USB3_CTRPUL_VAL_REG,
3313335786aSStefan Roese 0x8 << 24, rb_usb3_ctr_100ns);
3323335786aSStefan Roese
3333335786aSStefan Roese
3343335786aSStefan Roese /* 0xd005c300 = 0x1001 */
3353335786aSStefan Roese /* set PRD_TXDEEMPH (3.5db de-emph) */
3363335786aSStefan Roese reg_set16((void __iomem *)LANE_CFG0_ADDR(USB3), 0x1, 0xFF);
3373335786aSStefan Roese
3383335786aSStefan Roese /*
3393335786aSStefan Roese * unset BIT0: set Tx Electrical Idle Mode: Transmitter is in
3403335786aSStefan Roese * low impedance mode during electrical idle
3413335786aSStefan Roese */
3423335786aSStefan Roese /* unset BIT4: set G2 Tx Datapath with no Delayed Latency */
3433335786aSStefan Roese /* unset BIT6: set Tx Detect Rx Mode at LoZ mode */
3443335786aSStefan Roese reg_set16((void __iomem *)LANE_CFG1_ADDR(USB3), 0x0, 0xFFFF);
3453335786aSStefan Roese
3463335786aSStefan Roese
3473335786aSStefan Roese /* 0xd005c310 = 0x93: set Spread Spectrum Clock Enabled */
3483335786aSStefan Roese reg_set16((void __iomem *)LANE_CFG4_ADDR(USB3),
3493335786aSStefan Roese bf_spread_spectrum_clock_en, 0x80);
3503335786aSStefan Roese
3513335786aSStefan Roese /*
3523335786aSStefan Roese * set Override Margining Controls From the MAC: Use margining signals
3533335786aSStefan Roese * from lane configuration
3543335786aSStefan Roese */
3553335786aSStefan Roese reg_set16((void __iomem *)TEST_MODE_CTRL_ADDR(USB3),
3563335786aSStefan Roese rb_mode_margin_override, 0xFFFF);
3573335786aSStefan Roese
3583335786aSStefan Roese /* set Lane-to-Lane Bundle Clock Sampling Period = per PCLK cycles */
3593335786aSStefan Roese /* set Mode Clock Source = PCLK is generated from REFCLK */
3603335786aSStefan Roese reg_set16((void __iomem *)GLOB_CLK_SRC_LO_ADDR(USB3), 0x0, 0xFF);
3613335786aSStefan Roese
3623335786aSStefan Roese /* set G2 Spread Spectrum Clock Amplitude at 4K */
3633335786aSStefan Roese reg_set16((void __iomem *)GEN2_SETTING_2_ADDR(USB3), g2_tx_ssc_amp,
3643335786aSStefan Roese 0xF000);
3653335786aSStefan Roese
3663335786aSStefan Roese /*
3673335786aSStefan Roese * unset G3 Spread Spectrum Clock Amplitude & set G3 TX and RX Register
3683335786aSStefan Roese * Master Current Select
3693335786aSStefan Roese */
3703335786aSStefan Roese reg_set16((void __iomem *)GEN2_SETTING_3_ADDR(USB3), 0x0, 0xFFFF);
3713335786aSStefan Roese
3723335786aSStefan Roese /*
3733335786aSStefan Roese * 3. Check crystal jumper setting and program the Power and PLL
3743335786aSStefan Roese * Control accordingly
3753335786aSStefan Roese */
3763335786aSStefan Roese if (get_ref_clk() == 40) {
3773335786aSStefan Roese reg_set16((void __iomem *)PWR_PLL_CTRL_ADDR(USB3), 0xFCA3,
3783335786aSStefan Roese 0xFFFF); /* 40 MHz */
3793335786aSStefan Roese } else {
3803335786aSStefan Roese reg_set16((void __iomem *)PWR_PLL_CTRL_ADDR(USB3), 0xFCA2,
3813335786aSStefan Roese 0xFFFF); /* 25 MHz */
3823335786aSStefan Roese }
3833335786aSStefan Roese
3843335786aSStefan Roese /*
3853335786aSStefan Roese * 4. Change RX wait
3863335786aSStefan Roese */
3873335786aSStefan Roese reg_set16((void __iomem *)PWR_MGM_TIM1_ADDR(USB3), 0x10C, 0xFFFF);
3883335786aSStefan Roese
3893335786aSStefan Roese /*
3903335786aSStefan Roese * 5. Enable idle sync
3913335786aSStefan Roese */
3923335786aSStefan Roese reg_set16((void __iomem *)UNIT_CTRL_ADDR(USB3), 0x60 | rb_idle_sync_en,
3933335786aSStefan Roese 0xFFFF);
3943335786aSStefan Roese
3953335786aSStefan Roese /*
3963335786aSStefan Roese * 6. Enable the output of 500M clock
3973335786aSStefan Roese */
3983335786aSStefan Roese reg_set16((void __iomem *)MISC_REG0_ADDR(USB3), 0xA00D | rb_clk500m_en,
3993335786aSStefan Roese 0xFFFF);
4003335786aSStefan Roese
4013335786aSStefan Roese /*
4023335786aSStefan Roese * 7. Set 20-bit data width
4033335786aSStefan Roese */
4043335786aSStefan Roese reg_set16((void __iomem *)DIG_LB_EN_ADDR(USB3), 0x0400, 0xFFFF);
4053335786aSStefan Roese
4063335786aSStefan Roese /*
4073335786aSStefan Roese * 8. Override Speed_PLL value and use MAC PLL
4083335786aSStefan Roese */
4093335786aSStefan Roese reg_set16((void __iomem *)KVCO_CAL_CTRL_ADDR(USB3),
4103335786aSStefan Roese 0x0040 | rb_use_max_pll_rate, 0xFFFF);
4113335786aSStefan Roese
4123335786aSStefan Roese /*
4133335786aSStefan Roese * 9. Check the Polarity invert bit
4143335786aSStefan Roese */
4153335786aSStefan Roese if (invert & PHY_POLARITY_TXD_INVERT) {
4163335786aSStefan Roese reg_set16((void __iomem *)SYNC_PATTERN_ADDR(USB3),
4173335786aSStefan Roese phy_txd_inv, 0);
4183335786aSStefan Roese }
4193335786aSStefan Roese
4203335786aSStefan Roese if (invert & PHY_POLARITY_RXD_INVERT) {
4213335786aSStefan Roese reg_set16((void __iomem *)SYNC_PATTERN_ADDR(USB3),
4223335786aSStefan Roese phy_rxd_inv, 0);
4233335786aSStefan Roese }
4243335786aSStefan Roese
4253335786aSStefan Roese /*
4263335786aSStefan Roese * 10. Release SW reset
4273335786aSStefan Roese */
4283335786aSStefan Roese reg_set16((void __iomem *)GLOB_PHY_CTRL0_ADDR(USB3),
4293335786aSStefan Roese rb_mode_core_clk_freq_sel | rb_mode_pipe_width_32 | 0x20,
4303335786aSStefan Roese 0xFFFF);
4313335786aSStefan Roese
4323335786aSStefan Roese /* Wait for > 55 us to allow PCLK be enabled */
4333335786aSStefan Roese udelay(PLL_SET_DELAY_US);
4343335786aSStefan Roese
4353335786aSStefan Roese /* Assert PCLK enabled */
4363335786aSStefan Roese ret = comphy_poll_reg((void *)LANE_STAT1_ADDR(USB3), /* address */
4373335786aSStefan Roese rb_txdclk_pclk_en, /* value */
4383335786aSStefan Roese rb_txdclk_pclk_en, /* mask */
4393335786aSStefan Roese PLL_LOCK_TIMEOUT, /* timeout */
4403335786aSStefan Roese POLL_16B_REG); /* 16bit */
4413335786aSStefan Roese if (ret == 0)
4423335786aSStefan Roese printf("Failed to lock USB3 PLL\n");
4433335786aSStefan Roese
4443335786aSStefan Roese /*
4453335786aSStefan Roese * Set Soft ID for Host mode (Device mode works with Hard ID
4463335786aSStefan Roese * detection)
4473335786aSStefan Roese */
4483335786aSStefan Roese if (type == PHY_TYPE_USB3_HOST0) {
4493335786aSStefan Roese /*
4503335786aSStefan Roese * set BIT0: set ID_MODE of Host/Device = "Soft ID" (BIT1)
4513335786aSStefan Roese * clear BIT1: set SOFT_ID = Host
4523335786aSStefan Roese * set BIT4: set INT_MODE = ID. Interrupt Mode: enable
4533335786aSStefan Roese * interrupt by ID instead of using both interrupts
4543335786aSStefan Roese * of HOST and Device ORed simultaneously
4553335786aSStefan Roese * INT_MODE=ID in order to avoid unexpected
4563335786aSStefan Roese * behaviour or both interrupts together
4573335786aSStefan Roese */
4583335786aSStefan Roese reg_set((void __iomem *)USB32_CTRL_BASE,
4593335786aSStefan Roese usb32_ctrl_id_mode | usb32_ctrl_int_mode,
4603335786aSStefan Roese usb32_ctrl_id_mode | usb32_ctrl_soft_id |
4613335786aSStefan Roese usb32_ctrl_int_mode);
4623335786aSStefan Roese }
4633335786aSStefan Roese
4643335786aSStefan Roese debug_exit();
4653335786aSStefan Roese
4663335786aSStefan Roese return ret;
4673335786aSStefan Roese }
4683335786aSStefan Roese
4693335786aSStefan Roese /*
4703335786aSStefan Roese * comphy_usb2_power_up
4713335786aSStefan Roese *
4723335786aSStefan Roese * return: 1 if PLL locked (OK), 0 otherwise (FAIL)
4733335786aSStefan Roese */
comphy_usb2_power_up(u8 usb32)4743335786aSStefan Roese static int comphy_usb2_power_up(u8 usb32)
4753335786aSStefan Roese {
4763335786aSStefan Roese int ret;
4773335786aSStefan Roese
4783335786aSStefan Roese debug_enter();
4793335786aSStefan Roese
4803335786aSStefan Roese if (usb32 != 0 && usb32 != 1) {
4813335786aSStefan Roese printf("invalid usb32 value: (%d), should be either 0 or 1\n",
4823335786aSStefan Roese usb32);
4833335786aSStefan Roese debug_exit();
4843335786aSStefan Roese return 0;
4853335786aSStefan Roese }
4863335786aSStefan Roese
4873335786aSStefan Roese /*
4883335786aSStefan Roese * 0. Setup PLL. 40MHz clock uses defaults.
4893335786aSStefan Roese * See "PLL Settings for Typical REFCLK" table
4903335786aSStefan Roese */
4913335786aSStefan Roese if (get_ref_clk() == 25) {
4923335786aSStefan Roese reg_set((void __iomem *)USB2_PHY_BASE(usb32),
4933335786aSStefan Roese 5 | (96 << 16), 0x3F | (0xFF << 16) | (0x3 << 28));
4943335786aSStefan Roese }
4953335786aSStefan Roese
4963335786aSStefan Roese /*
4973335786aSStefan Roese * 1. PHY pull up and disable USB2 suspend
4983335786aSStefan Roese */
4993335786aSStefan Roese reg_set((void __iomem *)USB2_PHY_CTRL_ADDR(usb32),
5003335786aSStefan Roese RB_USB2PHY_SUSPM(usb32) | RB_USB2PHY_PU(usb32), 0);
5013335786aSStefan Roese
5023335786aSStefan Roese if (usb32 != 0) {
5033335786aSStefan Roese /*
5043335786aSStefan Roese * 2. Power up OTG module
5053335786aSStefan Roese */
5063335786aSStefan Roese reg_set((void __iomem *)USB2_PHY_OTG_CTRL_ADDR, rb_pu_otg, 0);
5073335786aSStefan Roese
5083335786aSStefan Roese /*
5093335786aSStefan Roese * 3. Configure PHY charger detection
5103335786aSStefan Roese */
5113335786aSStefan Roese reg_set((void __iomem *)USB2_PHY_CHRGR_DET_ADDR, 0,
5123335786aSStefan Roese rb_cdp_en | rb_dcp_en | rb_pd_en | rb_cdp_dm_auto |
5133335786aSStefan Roese rb_enswitch_dp | rb_enswitch_dm | rb_pu_chrg_dtc);
5143335786aSStefan Roese }
5153335786aSStefan Roese
5163335786aSStefan Roese /* Assert PLL calibration done */
5173335786aSStefan Roese ret = comphy_poll_reg((void *)USB2_PHY_CAL_CTRL_ADDR(usb32),
5183335786aSStefan Roese rb_usb2phy_pllcal_done, /* value */
5193335786aSStefan Roese rb_usb2phy_pllcal_done, /* mask */
5203335786aSStefan Roese PLL_LOCK_TIMEOUT, /* timeout */
5213335786aSStefan Roese POLL_32B_REG); /* 32bit */
5223335786aSStefan Roese if (ret == 0)
5233335786aSStefan Roese printf("Failed to end USB2 PLL calibration\n");
5243335786aSStefan Roese
5253335786aSStefan Roese /* Assert impedance calibration done */
5263335786aSStefan Roese ret = comphy_poll_reg((void *)USB2_PHY_CAL_CTRL_ADDR(usb32),
5273335786aSStefan Roese rb_usb2phy_impcal_done, /* value */
5283335786aSStefan Roese rb_usb2phy_impcal_done, /* mask */
5293335786aSStefan Roese PLL_LOCK_TIMEOUT, /* timeout */
5303335786aSStefan Roese POLL_32B_REG); /* 32bit */
5313335786aSStefan Roese if (ret == 0)
5323335786aSStefan Roese printf("Failed to end USB2 impedance calibration\n");
5333335786aSStefan Roese
5343335786aSStefan Roese /* Assert squetch calibration done */
5353335786aSStefan Roese ret = comphy_poll_reg((void *)USB2_PHY_RX_CHAN_CTRL1_ADDR(usb32),
5363335786aSStefan Roese rb_usb2phy_sqcal_done, /* value */
5373335786aSStefan Roese rb_usb2phy_sqcal_done, /* mask */
5383335786aSStefan Roese PLL_LOCK_TIMEOUT, /* timeout */
5393335786aSStefan Roese POLL_32B_REG); /* 32bit */
5403335786aSStefan Roese if (ret == 0)
5413335786aSStefan Roese printf("Failed to end USB2 unknown calibration\n");
5423335786aSStefan Roese
5433335786aSStefan Roese /* Assert PLL is ready */
5443335786aSStefan Roese ret = comphy_poll_reg((void *)USB2_PHY_PLL_CTRL0_ADDR(usb32),
5453335786aSStefan Roese rb_usb2phy_pll_ready, /* value */
5463335786aSStefan Roese rb_usb2phy_pll_ready, /* mask */
5473335786aSStefan Roese PLL_LOCK_TIMEOUT, /* timeout */
5483335786aSStefan Roese POLL_32B_REG); /* 32bit */
5493335786aSStefan Roese
5503335786aSStefan Roese if (ret == 0)
5513335786aSStefan Roese printf("Failed to lock USB2 PLL\n");
5523335786aSStefan Roese
5533335786aSStefan Roese debug_exit();
5543335786aSStefan Roese
5553335786aSStefan Roese return ret;
5563335786aSStefan Roese }
5573335786aSStefan Roese
5583335786aSStefan Roese /*
5593335786aSStefan Roese * comphy_emmc_power_up
5603335786aSStefan Roese *
5613335786aSStefan Roese * return: 1 if PLL locked (OK), 0 otherwise (FAIL)
5623335786aSStefan Roese */
comphy_emmc_power_up(void)5633335786aSStefan Roese static int comphy_emmc_power_up(void)
5643335786aSStefan Roese {
5653335786aSStefan Roese debug_enter();
5663335786aSStefan Roese
5673335786aSStefan Roese /*
5683335786aSStefan Roese * 1. Bus power ON, Bus voltage 1.8V
5693335786aSStefan Roese */
5703335786aSStefan Roese reg_set((void __iomem *)SDIO_HOST_CTRL1_ADDR, 0xB00, 0xF00);
5713335786aSStefan Roese
5723335786aSStefan Roese /*
5733335786aSStefan Roese * 2. Set FIFO parameters
5743335786aSStefan Roese */
5753335786aSStefan Roese reg_set((void __iomem *)SDIO_SDHC_FIFO_ADDR, 0x315, 0xFFFFFFFF);
5763335786aSStefan Roese
5773335786aSStefan Roese /*
5783335786aSStefan Roese * 3. Set Capabilities 1_2
5793335786aSStefan Roese */
5803335786aSStefan Roese reg_set((void __iomem *)SDIO_CAP_12_ADDR, 0x25FAC8B2, 0xFFFFFFFF);
5813335786aSStefan Roese
5823335786aSStefan Roese /*
5833335786aSStefan Roese * 4. Set Endian
5843335786aSStefan Roese */
5853335786aSStefan Roese reg_set((void __iomem *)SDIO_ENDIAN_ADDR, 0x00c00000, 0);
5863335786aSStefan Roese
5873335786aSStefan Roese /*
5883335786aSStefan Roese * 4. Init PHY
5893335786aSStefan Roese */
5903335786aSStefan Roese reg_set((void __iomem *)SDIO_PHY_TIMING_ADDR, 0x80000000, 0x80000000);
5913335786aSStefan Roese reg_set((void __iomem *)SDIO_PHY_PAD_CTRL0_ADDR, 0x50000000,
5923335786aSStefan Roese 0xF0000000);
5933335786aSStefan Roese
5943335786aSStefan Roese /*
5953335786aSStefan Roese * 5. DLL reset
5963335786aSStefan Roese */
5973335786aSStefan Roese reg_set((void __iomem *)SDIO_DLL_RST_ADDR, 0xFFFEFFFF, 0);
5983335786aSStefan Roese reg_set((void __iomem *)SDIO_DLL_RST_ADDR, 0x00010000, 0);
5993335786aSStefan Roese
6003335786aSStefan Roese debug_exit();
6013335786aSStefan Roese
6023335786aSStefan Roese return 1;
6033335786aSStefan Roese }
6043335786aSStefan Roese
6053335786aSStefan Roese /*
6063335786aSStefan Roese * comphy_sgmii_power_up
6073335786aSStefan Roese *
6083335786aSStefan Roese * return:
6093335786aSStefan Roese */
comphy_sgmii_phy_init(u32 lane,u32 speed)6103335786aSStefan Roese static void comphy_sgmii_phy_init(u32 lane, u32 speed)
6113335786aSStefan Roese {
6123335786aSStefan Roese const int fix_arr_sz = ARRAY_SIZE(sgmii_phy_init_fix);
6133335786aSStefan Roese int addr, fix_idx;
6143335786aSStefan Roese u16 val;
6153335786aSStefan Roese
6163335786aSStefan Roese fix_idx = 0;
6173335786aSStefan Roese for (addr = 0; addr < 512; addr++) {
6183335786aSStefan Roese /*
6193335786aSStefan Roese * All PHY register values are defined in full for 3.125Gbps
6203335786aSStefan Roese * SERDES speed. The values required for 1.25 Gbps are almost
6213335786aSStefan Roese * the same and only few registers should be "fixed" in
6223335786aSStefan Roese * comparison to 3.125 Gbps values. These register values are
6233335786aSStefan Roese * stored in "sgmii_phy_init_fix" array.
6243335786aSStefan Roese */
6253335786aSStefan Roese if ((speed != PHY_SPEED_1_25G) &&
6263335786aSStefan Roese (sgmii_phy_init_fix[fix_idx].addr == addr)) {
6273335786aSStefan Roese /* Use new value */
6283335786aSStefan Roese val = sgmii_phy_init_fix[fix_idx].value;
6293335786aSStefan Roese if (fix_idx < fix_arr_sz)
6303335786aSStefan Roese fix_idx++;
6313335786aSStefan Roese } else {
6323335786aSStefan Roese val = sgmii_phy_init[addr];
6333335786aSStefan Roese }
6343335786aSStefan Roese
6353335786aSStefan Roese phy_write16(lane, addr, val, 0xFFFF);
6363335786aSStefan Roese }
6373335786aSStefan Roese }
6383335786aSStefan Roese
6393335786aSStefan Roese /*
6403335786aSStefan Roese * comphy_sgmii_power_up
6413335786aSStefan Roese *
6423335786aSStefan Roese * return: 1 if PLL locked (OK), 0 otherwise (FAIL)
6433335786aSStefan Roese */
comphy_sgmii_power_up(u32 lane,u32 speed,u32 invert)6443335786aSStefan Roese static int comphy_sgmii_power_up(u32 lane, u32 speed, u32 invert)
6453335786aSStefan Roese {
6463335786aSStefan Roese int ret;
6473335786aSStefan Roese
6483335786aSStefan Roese debug_enter();
6493335786aSStefan Roese
6503335786aSStefan Roese /*
6513335786aSStefan Roese * 1. Configure PHY to SATA/SAS mode by setting pin PIN_PIPE_SEL=0
6523335786aSStefan Roese */
6533335786aSStefan Roese reg_set((void __iomem *)COMPHY_SEL_ADDR, 0, rf_compy_select(lane));
6543335786aSStefan Roese
6553335786aSStefan Roese /*
6563335786aSStefan Roese * 2. Reset PHY by setting PHY input port PIN_RESET=1.
6573335786aSStefan Roese * 3. Set PHY input port PIN_TX_IDLE=1, PIN_PU_IVREF=1 to keep
6583335786aSStefan Roese * PHY TXP/TXN output to idle state during PHY initialization
6593335786aSStefan Roese * 4. Set PHY input port PIN_PU_PLL=0, PIN_PU_RX=0, PIN_PU_TX=0.
6603335786aSStefan Roese */
6613335786aSStefan Roese reg_set((void __iomem *)COMPHY_PHY_CFG1_ADDR(lane),
6623335786aSStefan Roese rb_pin_reset_comphy | rb_pin_tx_idle | rb_pin_pu_iveref,
6633335786aSStefan Roese rb_pin_reset_core | rb_pin_pu_pll |
6643335786aSStefan Roese rb_pin_pu_rx | rb_pin_pu_tx);
6653335786aSStefan Roese
6663335786aSStefan Roese /*
6673335786aSStefan Roese * 5. Release reset to the PHY by setting PIN_RESET=0.
6683335786aSStefan Roese */
6693335786aSStefan Roese reg_set((void __iomem *)COMPHY_PHY_CFG1_ADDR(lane),
6703335786aSStefan Roese 0, rb_pin_reset_comphy);
6713335786aSStefan Roese
6723335786aSStefan Roese /*
6733335786aSStefan Roese * 7. Set PIN_PHY_GEN_TX[3:0] and PIN_PHY_GEN_RX[3:0] to decide
6743335786aSStefan Roese * COMPHY bit rate
6753335786aSStefan Roese */
6763335786aSStefan Roese if (speed == PHY_SPEED_3_125G) { /* 3.125 GHz */
6773335786aSStefan Roese reg_set((void __iomem *)COMPHY_PHY_CFG1_ADDR(lane),
6783335786aSStefan Roese (0x8 << rf_gen_rx_sel_shift) |
6793335786aSStefan Roese (0x8 << rf_gen_tx_sel_shift),
6803335786aSStefan Roese rf_gen_rx_select | rf_gen_tx_select);
6813335786aSStefan Roese
6823335786aSStefan Roese } else if (speed == PHY_SPEED_1_25G) { /* 1.25 GHz */
6833335786aSStefan Roese reg_set((void __iomem *)COMPHY_PHY_CFG1_ADDR(lane),
6843335786aSStefan Roese (0x6 << rf_gen_rx_sel_shift) |
6853335786aSStefan Roese (0x6 << rf_gen_tx_sel_shift),
6863335786aSStefan Roese rf_gen_rx_select | rf_gen_tx_select);
6873335786aSStefan Roese } else {
6883335786aSStefan Roese printf("Unsupported COMPHY speed!\n");
6893335786aSStefan Roese return 0;
6903335786aSStefan Roese }
6913335786aSStefan Roese
6923335786aSStefan Roese /*
6933335786aSStefan Roese * 8. Wait 1mS for bandgap and reference clocks to stabilize;
6943335786aSStefan Roese * then start SW programming.
6953335786aSStefan Roese */
6963335786aSStefan Roese mdelay(10);
6973335786aSStefan Roese
6983335786aSStefan Roese /* 9. Program COMPHY register PHY_MODE */
6993335786aSStefan Roese phy_write16(lane, PHY_PWR_PLL_CTRL_ADDR,
7003335786aSStefan Roese PHY_MODE_SGMII << rf_phy_mode_shift, rf_phy_mode_mask);
7013335786aSStefan Roese
7023335786aSStefan Roese /*
7033335786aSStefan Roese * 10. Set COMPHY register REFCLK_SEL to select the correct REFCLK
7043335786aSStefan Roese * source
7053335786aSStefan Roese */
7063335786aSStefan Roese phy_write16(lane, PHY_MISC_REG0_ADDR, 0, rb_ref_clk_sel);
7073335786aSStefan Roese
7083335786aSStefan Roese /*
7093335786aSStefan Roese * 11. Set correct reference clock frequency in COMPHY register
7103335786aSStefan Roese * REF_FREF_SEL.
7113335786aSStefan Roese */
7123335786aSStefan Roese if (get_ref_clk() == 40) {
7133335786aSStefan Roese phy_write16(lane, PHY_PWR_PLL_CTRL_ADDR,
7143335786aSStefan Roese 0x4 << rf_ref_freq_sel_shift, rf_ref_freq_sel_mask);
7153335786aSStefan Roese } else {
7163335786aSStefan Roese /* 25MHz */
7173335786aSStefan Roese phy_write16(lane, PHY_PWR_PLL_CTRL_ADDR,
7183335786aSStefan Roese 0x1 << rf_ref_freq_sel_shift, rf_ref_freq_sel_mask);
7193335786aSStefan Roese }
7203335786aSStefan Roese
7213335786aSStefan Roese /* 12. Program COMPHY register PHY_GEN_MAX[1:0] */
7223335786aSStefan Roese /*
7233335786aSStefan Roese * This step is mentioned in the flow received from verification team.
7243335786aSStefan Roese * However the PHY_GEN_MAX value is only meaningful for other
7253335786aSStefan Roese * interfaces (not SGMII). For instance, it selects SATA speed
7263335786aSStefan Roese * 1.5/3/6 Gbps or PCIe speed 2.5/5 Gbps
7273335786aSStefan Roese */
7283335786aSStefan Roese
7293335786aSStefan Roese /*
7303335786aSStefan Roese * 13. Program COMPHY register SEL_BITS to set correct parallel data
7313335786aSStefan Roese * bus width
7323335786aSStefan Roese */
7333335786aSStefan Roese /* 10bit */
7343335786aSStefan Roese phy_write16(lane, PHY_DIG_LB_EN_ADDR, 0, rf_data_width_mask);
7353335786aSStefan Roese
7363335786aSStefan Roese /*
7373335786aSStefan Roese * 14. As long as DFE function needs to be enabled in any mode,
7383335786aSStefan Roese * COMPHY register DFE_UPDATE_EN[5:0] shall be programmed to 0x3F
7393335786aSStefan Roese * for real chip during COMPHY power on.
7403335786aSStefan Roese */
7413335786aSStefan Roese /*
7423335786aSStefan Roese * The step 14 exists (and empty) in the original initialization flow
7433335786aSStefan Roese * obtained from the verification team. According to the functional
7443335786aSStefan Roese * specification DFE_UPDATE_EN already has the default value 0x3F
7453335786aSStefan Roese */
7463335786aSStefan Roese
7473335786aSStefan Roese /*
7483335786aSStefan Roese * 15. Program COMPHY GEN registers.
7493335786aSStefan Roese * These registers should be programmed based on the lab testing
7503335786aSStefan Roese * result to achieve optimal performance. Please contact the CEA
7513335786aSStefan Roese * group to get the related GEN table during real chip bring-up.
7523335786aSStefan Roese * We only requred to run though the entire registers programming
7533335786aSStefan Roese * flow defined by "comphy_sgmii_phy_init" when the REF clock is
7543335786aSStefan Roese * 40 MHz. For REF clock 25 MHz the default values stored in PHY
7553335786aSStefan Roese * registers are OK.
7563335786aSStefan Roese */
7573335786aSStefan Roese debug("Running C-DPI phy init %s mode\n",
7583335786aSStefan Roese speed == PHY_SPEED_3_125G ? "2G5" : "1G");
7593335786aSStefan Roese if (get_ref_clk() == 40)
7603335786aSStefan Roese comphy_sgmii_phy_init(lane, speed);
7613335786aSStefan Roese
7623335786aSStefan Roese /*
7633335786aSStefan Roese * 16. [Simulation Only] should not be used for real chip.
7643335786aSStefan Roese * By pass power up calibration by programming EXT_FORCE_CAL_DONE
7653335786aSStefan Roese * (R02h[9]) to 1 to shorten COMPHY simulation time.
7663335786aSStefan Roese */
7673335786aSStefan Roese /*
7683335786aSStefan Roese * 17. [Simulation Only: should not be used for real chip]
7693335786aSStefan Roese * Program COMPHY register FAST_DFE_TIMER_EN=1 to shorten RX
7703335786aSStefan Roese * training simulation time.
7713335786aSStefan Roese */
7723335786aSStefan Roese
7733335786aSStefan Roese /*
7743335786aSStefan Roese * 18. Check the PHY Polarity invert bit
7753335786aSStefan Roese */
7763335786aSStefan Roese if (invert & PHY_POLARITY_TXD_INVERT)
7773335786aSStefan Roese phy_write16(lane, PHY_SYNC_PATTERN_ADDR, phy_txd_inv, 0);
7783335786aSStefan Roese
7793335786aSStefan Roese if (invert & PHY_POLARITY_RXD_INVERT)
7803335786aSStefan Roese phy_write16(lane, PHY_SYNC_PATTERN_ADDR, phy_rxd_inv, 0);
7813335786aSStefan Roese
7823335786aSStefan Roese /*
7833335786aSStefan Roese * 19. Set PHY input ports PIN_PU_PLL, PIN_PU_TX and PIN_PU_RX to 1
7843335786aSStefan Roese * to start PHY power up sequence. All the PHY register
7853335786aSStefan Roese * programming should be done before PIN_PU_PLL=1. There should be
7863335786aSStefan Roese * no register programming for normal PHY operation from this point.
7873335786aSStefan Roese */
7883335786aSStefan Roese reg_set((void __iomem *)COMPHY_PHY_CFG1_ADDR(lane),
7893335786aSStefan Roese rb_pin_pu_pll | rb_pin_pu_rx | rb_pin_pu_tx,
7903335786aSStefan Roese rb_pin_pu_pll | rb_pin_pu_rx | rb_pin_pu_tx);
7913335786aSStefan Roese
7923335786aSStefan Roese /*
7933335786aSStefan Roese * 20. Wait for PHY power up sequence to finish by checking output ports
7943335786aSStefan Roese * PIN_PLL_READY_TX=1 and PIN_PLL_READY_RX=1.
7953335786aSStefan Roese */
7963335786aSStefan Roese ret = comphy_poll_reg((void *)COMPHY_PHY_STAT1_ADDR(lane), /* address */
7973335786aSStefan Roese rb_pll_ready_tx | rb_pll_ready_rx, /* value */
7983335786aSStefan Roese rb_pll_ready_tx | rb_pll_ready_rx, /* mask */
7993335786aSStefan Roese PLL_LOCK_TIMEOUT, /* timeout */
8003335786aSStefan Roese POLL_32B_REG); /* 32bit */
8013335786aSStefan Roese if (ret == 0)
8023335786aSStefan Roese printf("Failed to lock PLL for SGMII PHY %d\n", lane);
8033335786aSStefan Roese
8043335786aSStefan Roese /*
8053335786aSStefan Roese * 21. Set COMPHY input port PIN_TX_IDLE=0
8063335786aSStefan Roese */
8073335786aSStefan Roese reg_set((void __iomem *)COMPHY_PHY_CFG1_ADDR(lane),
8083335786aSStefan Roese 0x0, rb_pin_tx_idle);
8093335786aSStefan Roese
8103335786aSStefan Roese /*
8113335786aSStefan Roese * 22. After valid data appear on PIN_RXDATA bus, set PIN_RX_INIT=1.
8123335786aSStefan Roese * to start RX initialization. PIN_RX_INIT_DONE will be cleared to
8133335786aSStefan Roese * 0 by the PHY. After RX initialization is done, PIN_RX_INIT_DONE
8143335786aSStefan Roese * will be set to 1 by COMPHY. Set PIN_RX_INIT=0 after
8153335786aSStefan Roese * PIN_RX_INIT_DONE= 1.
8163335786aSStefan Roese * Please refer to RX initialization part for details.
8173335786aSStefan Roese */
8183335786aSStefan Roese reg_set((void __iomem *)COMPHY_PHY_CFG1_ADDR(lane), rb_phy_rx_init,
8193335786aSStefan Roese 0x0);
8203335786aSStefan Roese
8213335786aSStefan Roese ret = comphy_poll_reg((void *)COMPHY_PHY_STAT1_ADDR(lane), /* address */
8223335786aSStefan Roese rb_rx_init_done, /* value */
8233335786aSStefan Roese rb_rx_init_done, /* mask */
8243335786aSStefan Roese PLL_LOCK_TIMEOUT, /* timeout */
8253335786aSStefan Roese POLL_32B_REG); /* 32bit */
8263335786aSStefan Roese if (ret == 0)
8273335786aSStefan Roese printf("Failed to init RX of SGMII PHY %d\n", lane);
8283335786aSStefan Roese
8293335786aSStefan Roese debug_exit();
8303335786aSStefan Roese
8313335786aSStefan Roese return ret;
8323335786aSStefan Roese }
8333335786aSStefan Roese
comphy_dedicated_phys_init(void)8343335786aSStefan Roese void comphy_dedicated_phys_init(void)
8353335786aSStefan Roese {
8363335786aSStefan Roese int node, usb32, ret = 1;
8373335786aSStefan Roese const void *blob = gd->fdt_blob;
8383335786aSStefan Roese
8393335786aSStefan Roese debug_enter();
8403335786aSStefan Roese
8413335786aSStefan Roese for (usb32 = 0; usb32 <= 1; usb32++) {
8423335786aSStefan Roese /*
8433335786aSStefan Roese * There are 2 UTMI PHYs in this SOC.
8443335786aSStefan Roese * One is independendent and one is paired with USB3 port (OTG)
8453335786aSStefan Roese */
8463335786aSStefan Roese if (usb32 == 0) {
8473335786aSStefan Roese node = fdt_node_offset_by_compatible(
8483335786aSStefan Roese blob, -1, "marvell,armada-3700-ehci");
8493335786aSStefan Roese } else {
8503335786aSStefan Roese node = fdt_node_offset_by_compatible(
8513335786aSStefan Roese blob, -1, "marvell,armada3700-xhci");
8523335786aSStefan Roese }
8533335786aSStefan Roese
8543335786aSStefan Roese if (node > 0) {
8553335786aSStefan Roese if (fdtdec_get_is_enabled(blob, node)) {
8563335786aSStefan Roese ret = comphy_usb2_power_up(usb32);
8573335786aSStefan Roese if (ret == 0)
8583335786aSStefan Roese printf("Failed to initialize UTMI PHY\n");
8593335786aSStefan Roese else
8603335786aSStefan Roese debug("UTMI PHY init succeed\n");
8613335786aSStefan Roese } else {
8623335786aSStefan Roese debug("USB%d node is disabled\n",
8633335786aSStefan Roese usb32 == 0 ? 2 : 3);
8643335786aSStefan Roese }
8653335786aSStefan Roese } else {
8663335786aSStefan Roese debug("No USB%d node in DT\n", usb32 == 0 ? 2 : 3);
8673335786aSStefan Roese }
8683335786aSStefan Roese }
8693335786aSStefan Roese
8703335786aSStefan Roese node = fdt_node_offset_by_compatible(blob, -1,
8713335786aSStefan Roese "marvell,armada-3700-ahci");
8723335786aSStefan Roese if (node > 0) {
8733335786aSStefan Roese if (fdtdec_get_is_enabled(blob, node)) {
8743335786aSStefan Roese ret = comphy_sata_power_up();
8753335786aSStefan Roese if (ret == 0)
8763335786aSStefan Roese printf("Failed to initialize SATA PHY\n");
8773335786aSStefan Roese else
8783335786aSStefan Roese debug("SATA PHY init succeed\n");
8793335786aSStefan Roese } else {
8803335786aSStefan Roese debug("SATA node is disabled\n");
8813335786aSStefan Roese }
8823335786aSStefan Roese } else {
8833335786aSStefan Roese debug("No SATA node in DT\n");
8843335786aSStefan Roese }
8853335786aSStefan Roese
8863335786aSStefan Roese node = fdt_node_offset_by_compatible(blob, -1,
887*14319908SStefan Roese "marvell,armada-8k-sdhci");
8883335786aSStefan Roese if (node <= 0) {
889*14319908SStefan Roese node = fdt_node_offset_by_compatible(
890*14319908SStefan Roese blob, -1, "marvell,armada-3700-sdhci");
8913335786aSStefan Roese }
8923335786aSStefan Roese
8933335786aSStefan Roese if (node > 0) {
8943335786aSStefan Roese if (fdtdec_get_is_enabled(blob, node)) {
8953335786aSStefan Roese ret = comphy_emmc_power_up();
8963335786aSStefan Roese if (ret == 0)
8973335786aSStefan Roese printf("Failed to initialize SDIO/eMMC PHY\n");
8983335786aSStefan Roese else
8993335786aSStefan Roese debug("SDIO/eMMC PHY init succeed\n");
9003335786aSStefan Roese } else {
9013335786aSStefan Roese debug("SDIO/eMMC node is disabled\n");
9023335786aSStefan Roese }
9033335786aSStefan Roese } else {
9043335786aSStefan Roese debug("No SDIO/eMMC node in DT\n");
9053335786aSStefan Roese }
9063335786aSStefan Roese
9073335786aSStefan Roese debug_exit();
9083335786aSStefan Roese }
9093335786aSStefan Roese
comphy_a3700_init(struct chip_serdes_phy_config * chip_cfg,struct comphy_map * serdes_map)9103335786aSStefan Roese int comphy_a3700_init(struct chip_serdes_phy_config *chip_cfg,
9113335786aSStefan Roese struct comphy_map *serdes_map)
9123335786aSStefan Roese {
9133335786aSStefan Roese struct comphy_map *comphy_map;
9143335786aSStefan Roese u32 comphy_max_count = chip_cfg->comphy_lanes_count;
9153335786aSStefan Roese u32 lane, ret = 0;
9163335786aSStefan Roese
9173335786aSStefan Roese debug_enter();
9183335786aSStefan Roese
9193335786aSStefan Roese for (lane = 0, comphy_map = serdes_map; lane < comphy_max_count;
9203335786aSStefan Roese lane++, comphy_map++) {
9213335786aSStefan Roese debug("Initialize serdes number %d\n", lane);
9223335786aSStefan Roese debug("Serdes type = 0x%x invert=%d\n",
9233335786aSStefan Roese comphy_map->type, comphy_map->invert);
9243335786aSStefan Roese
9253335786aSStefan Roese switch (comphy_map->type) {
9263335786aSStefan Roese case PHY_TYPE_UNCONNECTED:
9273335786aSStefan Roese continue;
9283335786aSStefan Roese break;
9293335786aSStefan Roese
9303335786aSStefan Roese case PHY_TYPE_PEX0:
9313335786aSStefan Roese ret = comphy_pcie_power_up(comphy_map->speed,
9323335786aSStefan Roese comphy_map->invert);
9333335786aSStefan Roese break;
9343335786aSStefan Roese
9353335786aSStefan Roese case PHY_TYPE_USB3_HOST0:
9363335786aSStefan Roese case PHY_TYPE_USB3_DEVICE:
9373335786aSStefan Roese ret = comphy_usb3_power_up(comphy_map->type,
9383335786aSStefan Roese comphy_map->speed,
9393335786aSStefan Roese comphy_map->invert);
9403335786aSStefan Roese break;
9413335786aSStefan Roese
9423335786aSStefan Roese case PHY_TYPE_SGMII0:
9433335786aSStefan Roese case PHY_TYPE_SGMII1:
9443335786aSStefan Roese ret = comphy_sgmii_power_up(lane, comphy_map->speed,
9453335786aSStefan Roese comphy_map->invert);
9463335786aSStefan Roese break;
9473335786aSStefan Roese
9483335786aSStefan Roese default:
9493335786aSStefan Roese debug("Unknown SerDes type, skip initialize SerDes %d\n",
9503335786aSStefan Roese lane);
9513335786aSStefan Roese ret = 1;
9523335786aSStefan Roese break;
9533335786aSStefan Roese }
9543335786aSStefan Roese if (ret == 0)
9553335786aSStefan Roese printf("PLL is not locked - Failed to initialize lane %d\n",
9563335786aSStefan Roese lane);
9573335786aSStefan Roese }
9583335786aSStefan Roese
9593335786aSStefan Roese debug_exit();
9603335786aSStefan Roese return ret;
9613335786aSStefan Roese }
962