diff options
| author | Loc Ho <lho@apm.com> | 2014-03-07 12:28:08 -0500 |
|---|---|---|
| committer | Kishon Vijay Abraham I <kishon@ti.com> | 2014-03-09 03:15:13 -0400 |
| commit | 88e670fe9d240c751fd9735ae3ee2906ed68e63d (patch) | |
| tree | 77b139a2cdb6d1b1a0ca8ba2d0d115b6b1dbe9ff | |
| parent | 1068320b513e658a917e591214d174b7af9d0cf1 (diff) | |
PHY: add APM X-Gene SoC 15Gbps Multi-purpose PHY driver
This patch adds support for the APM X-Gene SoC 15Gbps Multi-purpose PHY.
This is the physical layer interface for the corresponding host
controller. Currently, only external clock and Gen3 SATA mode
are supported.
Signed-off-by: Loc Ho <lho@apm.com>
Signed-off-by: Tuan Phan <tphan@apm.com>
Signed-off-by: Suman Tripathi <stripathi@apm.com>
Signed-off-by: Kishon Vijay Abraham I <kishon@ti.com>
| -rw-r--r-- | drivers/phy/Kconfig | 7 | ||||
| -rw-r--r-- | drivers/phy/Makefile | 1 | ||||
| -rw-r--r-- | drivers/phy/phy-xgene.c | 1750 |
3 files changed, 1758 insertions, 0 deletions
diff --git a/drivers/phy/Kconfig b/drivers/phy/Kconfig index 2aead8b7dc60..8d3c49cc500f 100644 --- a/drivers/phy/Kconfig +++ b/drivers/phy/Kconfig | |||
| @@ -159,4 +159,11 @@ config PHY_EXYNOS5250_USB2 | |||
| 159 | particular SoC is compiled in the driver. In case of Exynos 5250 four | 159 | particular SoC is compiled in the driver. In case of Exynos 5250 four |
| 160 | phys are available - device, host, HSIC0 and HSIC. | 160 | phys are available - device, host, HSIC0 and HSIC. |
| 161 | 161 | ||
| 162 | config PHY_XGENE | ||
| 163 | tristate "APM X-Gene 15Gbps PHY support" | ||
| 164 | depends on HAS_IOMEM && OF && (ARM64 || COMPILE_TEST) | ||
| 165 | select GENERIC_PHY | ||
| 166 | help | ||
| 167 | This option enables support for APM X-Gene SoC multi-purpose PHY. | ||
| 168 | |||
| 162 | endmenu | 169 | endmenu |
diff --git a/drivers/phy/Makefile b/drivers/phy/Makefile index 8da05a841112..2faf78edc864 100644 --- a/drivers/phy/Makefile +++ b/drivers/phy/Makefile | |||
| @@ -17,3 +17,4 @@ obj-$(CONFIG_PHY_SAMSUNG_USB2) += phy-samsung-usb2.o | |||
| 17 | obj-$(CONFIG_PHY_EXYNOS4210_USB2) += phy-exynos4210-usb2.o | 17 | obj-$(CONFIG_PHY_EXYNOS4210_USB2) += phy-exynos4210-usb2.o |
| 18 | obj-$(CONFIG_PHY_EXYNOS4X12_USB2) += phy-exynos4x12-usb2.o | 18 | obj-$(CONFIG_PHY_EXYNOS4X12_USB2) += phy-exynos4x12-usb2.o |
| 19 | obj-$(CONFIG_PHY_EXYNOS5250_USB2) += phy-exynos5250-usb2.o | 19 | obj-$(CONFIG_PHY_EXYNOS5250_USB2) += phy-exynos5250-usb2.o |
| 20 | obj-$(CONFIG_PHY_XGENE) += phy-xgene.o | ||
diff --git a/drivers/phy/phy-xgene.c b/drivers/phy/phy-xgene.c new file mode 100644 index 000000000000..4aa1ccd1511f --- /dev/null +++ b/drivers/phy/phy-xgene.c | |||
| @@ -0,0 +1,1750 @@ | |||
| 1 | /* | ||
| 2 | * AppliedMicro X-Gene Multi-purpose PHY driver | ||
| 3 | * | ||
| 4 | * Copyright (c) 2014, Applied Micro Circuits Corporation | ||
| 5 | * Author: Loc Ho <lho@apm.com> | ||
| 6 | * Tuan Phan <tphan@apm.com> | ||
| 7 | * Suman Tripathi <stripathi@apm.com> | ||
| 8 | * | ||
| 9 | * This program is free software; you can redistribute it and/or modify it | ||
| 10 | * under the terms of the GNU General Public License as published by the | ||
| 11 | * Free Software Foundation; either version 2 of the License, or (at your | ||
| 12 | * option) any later version. | ||
| 13 | * | ||
| 14 | * This program is distributed in the hope that it will be useful, | ||
| 15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 17 | * GNU General Public License for more details. | ||
| 18 | * | ||
| 19 | * You should have received a copy of the GNU General Public License | ||
| 20 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
| 21 | * | ||
| 22 | * The APM X-Gene PHY consists of two PLL clock macro's (CMU) and lanes. | ||
| 23 | * The first PLL clock macro is used for internal reference clock. The second | ||
| 24 | * PLL clock macro is used to generate the clock for the PHY. This driver | ||
| 25 | * configures the first PLL CMU, the second PLL CMU, and programs the PHY to | ||
| 26 | * operate according to the mode of operation. The first PLL CMU is only | ||
| 27 | * required if internal clock is enabled. | ||
| 28 | * | ||
| 29 | * Logical Layer Out Of HW module units: | ||
| 30 | * | ||
| 31 | * ----------------- | ||
| 32 | * | Internal | |------| | ||
| 33 | * | Ref PLL CMU |----| | ------------- --------- | ||
| 34 | * ------------ ---- | MUX |-----|PHY PLL CMU|----| Serdes| | ||
| 35 | * | | | | --------- | ||
| 36 | * External Clock ------| | ------------- | ||
| 37 | * |------| | ||
| 38 | * | ||
| 39 | * The Ref PLL CMU CSR (Configuration System Registers) is accessed | ||
| 40 | * indirectly from the SDS offset at 0x2000. It is only required for | ||
| 41 | * internal reference clock. | ||
| 42 | * The PHY PLL CMU CSR is accessed indirectly from the SDS offset at 0x0000. | ||
| 43 | * The Serdes CSR is accessed indirectly from the SDS offset at 0x0400. | ||
| 44 | * | ||
| 45 | * The Ref PLL CMU can be located within the same PHY IP or outside the PHY IP | ||
| 46 | * due to shared Ref PLL CMU. For PHY with Ref PLL CMU shared with another IP, | ||
| 47 | * it is located outside the PHY IP. This is the case for the PHY located | ||
| 48 | * at 0x1f23a000 (SATA Port 4/5). For such PHY, another resource is required | ||
| 49 | * to located the SDS/Ref PLL CMU module and its clock for that IP enabled. | ||
| 50 | * | ||
| 51 | * Currently, this driver only supports Gen3 SATA mode with external clock. | ||
| 52 | */ | ||
| 53 | #include <linux/module.h> | ||
| 54 | #include <linux/platform_device.h> | ||
| 55 | #include <linux/io.h> | ||
| 56 | #include <linux/delay.h> | ||
| 57 | #include <linux/phy/phy.h> | ||
| 58 | #include <linux/clk.h> | ||
| 59 | |||
| 60 | /* Max 2 lanes per a PHY unit */ | ||
| 61 | #define MAX_LANE 2 | ||
| 62 | |||
| 63 | /* Register offset inside the PHY */ | ||
| 64 | #define SERDES_PLL_INDIRECT_OFFSET 0x0000 | ||
| 65 | #define SERDES_PLL_REF_INDIRECT_OFFSET 0x2000 | ||
| 66 | #define SERDES_INDIRECT_OFFSET 0x0400 | ||
| 67 | #define SERDES_LANE_STRIDE 0x0200 | ||
| 68 | |||
| 69 | /* Some default Serdes parameters */ | ||
| 70 | #define DEFAULT_SATA_TXBOOST_GAIN { 0x1e, 0x1e, 0x1e } | ||
| 71 | #define DEFAULT_SATA_TXEYEDIRECTION { 0x0, 0x0, 0x0 } | ||
| 72 | #define DEFAULT_SATA_TXEYETUNING { 0xa, 0xa, 0xa } | ||
| 73 | #define DEFAULT_SATA_SPD_SEL { 0x1, 0x3, 0x7 } | ||
| 74 | #define DEFAULT_SATA_TXAMP { 0x8, 0x8, 0x8 } | ||
| 75 | #define DEFAULT_SATA_TXCN1 { 0x2, 0x2, 0x2 } | ||
| 76 | #define DEFAULT_SATA_TXCN2 { 0x0, 0x0, 0x0 } | ||
| 77 | #define DEFAULT_SATA_TXCP1 { 0xa, 0xa, 0xa } | ||
| 78 | |||
| 79 | #define SATA_SPD_SEL_GEN3 0x7 | ||
| 80 | #define SATA_SPD_SEL_GEN2 0x3 | ||
| 81 | #define SATA_SPD_SEL_GEN1 0x1 | ||
| 82 | |||
| 83 | #define SSC_DISABLE 0 | ||
| 84 | #define SSC_ENABLE 1 | ||
| 85 | |||
| 86 | #define FBDIV_VAL_50M 0x77 | ||
| 87 | #define REFDIV_VAL_50M 0x1 | ||
| 88 | #define FBDIV_VAL_100M 0x3B | ||
| 89 | #define REFDIV_VAL_100M 0x0 | ||
| 90 | |||
| 91 | /* SATA Clock/Reset CSR */ | ||
| 92 | #define SATACLKENREG 0x00000000 | ||
| 93 | #define SATA0_CORE_CLKEN 0x00000002 | ||
| 94 | #define SATA1_CORE_CLKEN 0x00000004 | ||
| 95 | #define SATASRESETREG 0x00000004 | ||
| 96 | #define SATA_MEM_RESET_MASK 0x00000020 | ||
| 97 | #define SATA_MEM_RESET_RD(src) (((src) & 0x00000020) >> 5) | ||
| 98 | #define SATA_SDS_RESET_MASK 0x00000004 | ||
| 99 | #define SATA_CSR_RESET_MASK 0x00000001 | ||
| 100 | #define SATA_CORE_RESET_MASK 0x00000002 | ||
| 101 | #define SATA_PMCLK_RESET_MASK 0x00000010 | ||
| 102 | #define SATA_PCLK_RESET_MASK 0x00000008 | ||
| 103 | |||
| 104 | /* SDS CSR used for PHY Indirect access */ | ||
| 105 | #define SATA_ENET_SDS_PCS_CTL0 0x00000000 | ||
| 106 | #define REGSPEC_CFG_I_TX_WORDMODE0_SET(dst, src) \ | ||
| 107 | (((dst) & ~0x00070000) | (((u32) (src) << 16) & 0x00070000)) | ||
| 108 | #define REGSPEC_CFG_I_RX_WORDMODE0_SET(dst, src) \ | ||
| 109 | (((dst) & ~0x00e00000) | (((u32) (src) << 21) & 0x00e00000)) | ||
| 110 | #define SATA_ENET_SDS_CTL0 0x0000000c | ||
| 111 | #define REGSPEC_CFG_I_CUSTOMER_PIN_MODE0_SET(dst, src) \ | ||
| 112 | (((dst) & ~0x00007fff) | (((u32) (src)) & 0x00007fff)) | ||
| 113 | #define SATA_ENET_SDS_CTL1 0x00000010 | ||
| 114 | #define CFG_I_SPD_SEL_CDR_OVR1_SET(dst, src) \ | ||
| 115 | (((dst) & ~0x0000000f) | (((u32) (src)) & 0x0000000f)) | ||
| 116 | #define SATA_ENET_SDS_RST_CTL 0x00000024 | ||
| 117 | #define SATA_ENET_SDS_IND_CMD_REG 0x0000003c | ||
| 118 | #define CFG_IND_WR_CMD_MASK 0x00000001 | ||
| 119 | #define CFG_IND_RD_CMD_MASK 0x00000002 | ||
| 120 | #define CFG_IND_CMD_DONE_MASK 0x00000004 | ||
| 121 | #define CFG_IND_ADDR_SET(dst, src) \ | ||
| 122 | (((dst) & ~0x003ffff0) | (((u32) (src) << 4) & 0x003ffff0)) | ||
| 123 | #define SATA_ENET_SDS_IND_RDATA_REG 0x00000040 | ||
| 124 | #define SATA_ENET_SDS_IND_WDATA_REG 0x00000044 | ||
| 125 | #define SATA_ENET_CLK_MACRO_REG 0x0000004c | ||
| 126 | #define I_RESET_B_SET(dst, src) \ | ||
| 127 | (((dst) & ~0x00000001) | (((u32) (src)) & 0x00000001)) | ||
| 128 | #define I_PLL_FBDIV_SET(dst, src) \ | ||
| 129 | (((dst) & ~0x001ff000) | (((u32) (src) << 12) & 0x001ff000)) | ||
| 130 | #define I_CUSTOMEROV_SET(dst, src) \ | ||
| 131 | (((dst) & ~0x00000f80) | (((u32) (src) << 7) & 0x00000f80)) | ||
| 132 | #define O_PLL_LOCK_RD(src) (((src) & 0x40000000) >> 30) | ||
| 133 | #define O_PLL_READY_RD(src) (((src) & 0x80000000) >> 31) | ||
| 134 | |||
| 135 | /* PLL Clock Macro Unit (CMU) CSR accessing from SDS indirectly */ | ||
| 136 | #define CMU_REG0 0x00000 | ||
| 137 | #define CMU_REG0_PLL_REF_SEL_MASK 0x00002000 | ||
| 138 | #define CMU_REG0_PLL_REF_SEL_SET(dst, src) \ | ||
| 139 | (((dst) & ~0x00002000) | (((u32) (src) << 13) & 0x00002000)) | ||
| 140 | #define CMU_REG0_PDOWN_MASK 0x00004000 | ||
| 141 | #define CMU_REG0_CAL_COUNT_RESOL_SET(dst, src) \ | ||
| 142 | (((dst) & ~0x000000e0) | (((u32) (src) << 5) & 0x000000e0)) | ||
| 143 | #define CMU_REG1 0x00002 | ||
| 144 | #define CMU_REG1_PLL_CP_SET(dst, src) \ | ||
| 145 | (((dst) & ~0x00003c00) | (((u32) (src) << 10) & 0x00003c00)) | ||
| 146 | #define CMU_REG1_PLL_MANUALCAL_SET(dst, src) \ | ||
| 147 | (((dst) & ~0x00000008) | (((u32) (src) << 3) & 0x00000008)) | ||
| 148 | #define CMU_REG1_PLL_CP_SEL_SET(dst, src) \ | ||
| 149 | (((dst) & ~0x000003e0) | (((u32) (src) << 5) & 0x000003e0)) | ||
| 150 | #define CMU_REG1_REFCLK_CMOS_SEL_MASK 0x00000001 | ||
| 151 | #define CMU_REG1_REFCLK_CMOS_SEL_SET(dst, src) \ | ||
| 152 | (((dst) & ~0x00000001) | (((u32) (src) << 0) & 0x00000001)) | ||
| 153 | #define CMU_REG2 0x00004 | ||
| 154 | #define CMU_REG2_PLL_REFDIV_SET(dst, src) \ | ||
| 155 | (((dst) & ~0x0000c000) | (((u32) (src) << 14) & 0x0000c000)) | ||
| 156 | #define CMU_REG2_PLL_LFRES_SET(dst, src) \ | ||
| 157 | (((dst) & ~0x0000001e) | (((u32) (src) << 1) & 0x0000001e)) | ||
| 158 | #define CMU_REG2_PLL_FBDIV_SET(dst, src) \ | ||
| 159 | (((dst) & ~0x00003fe0) | (((u32) (src) << 5) & 0x00003fe0)) | ||
| 160 | #define CMU_REG3 0x00006 | ||
| 161 | #define CMU_REG3_VCOVARSEL_SET(dst, src) \ | ||
| 162 | (((dst) & ~0x0000000f) | (((u32) (src) << 0) & 0x0000000f)) | ||
