summaryrefslogtreecommitdiff
path: root/drivers/phy/ti
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/phy/ti')
-rw-r--r--drivers/phy/ti/phy-am654-serdes.c331
-rw-r--r--drivers/phy/ti/phy-gmii-sel.c159
-rw-r--r--drivers/phy/ti/phy-j721e-wiz.c1
-rw-r--r--drivers/phy/ti/phy-omap-usb2.c36
4 files changed, 328 insertions, 199 deletions
diff --git a/drivers/phy/ti/phy-am654-serdes.c b/drivers/phy/ti/phy-am654-serdes.c
index a174b3c3f010..2ff56ce77b30 100644
--- a/drivers/phy/ti/phy-am654-serdes.c
+++ b/drivers/phy/ti/phy-am654-serdes.c
@@ -19,15 +19,38 @@
#include <linux/pm_runtime.h>
#include <linux/regmap.h>
+#define CMU_R004 0x4
+#define CMU_R060 0x60
#define CMU_R07C 0x7c
-
+#define CMU_R088 0x88
+#define CMU_R0D0 0xd0
+#define CMU_R0E8 0xe8
+
+#define LANE_R048 0x248
+#define LANE_R058 0x258
+#define LANE_R06c 0x26c
+#define LANE_R070 0x270
+#define LANE_R070 0x270
+#define LANE_R19C 0x39c
+
+#define COMLANE_R004 0xa04
#define COMLANE_R138 0xb38
-#define VERSION 0x70
+#define VERSION_VAL 0x70
#define COMLANE_R190 0xb90
-
#define COMLANE_R194 0xb94
+#define COMRXEQ_R004 0x1404
+#define COMRXEQ_R008 0x1408
+#define COMRXEQ_R00C 0x140c
+#define COMRXEQ_R014 0x1414
+#define COMRXEQ_R018 0x1418
+#define COMRXEQ_R01C 0x141c
+#define COMRXEQ_R04C 0x144c
+#define COMRXEQ_R088 0x1488
+#define COMRXEQ_R094 0x1494
+#define COMRXEQ_R098 0x1498
+
#define SERDES_CTRL 0x1fd0
#define WIZ_LANEXCTL_STS 0x1fe0
@@ -80,27 +103,136 @@ static const struct regmap_config serdes_am654_regmap_config = {
.max_register = 0x1ffc,
};
-static const struct reg_field cmu_master_cdn_o = REG_FIELD(CMU_R07C, 24, 24);
-static const struct reg_field config_version = REG_FIELD(COMLANE_R138, 16, 23);
-static const struct reg_field l1_master_cdn_o = REG_FIELD(COMLANE_R190, 9, 9);
-static const struct reg_field cmu_ok_i_0 = REG_FIELD(COMLANE_R194, 19, 19);
-static const struct reg_field por_en = REG_FIELD(SERDES_CTRL, 29, 29);
-static const struct reg_field tx0_enable = REG_FIELD(WIZ_LANEXCTL_STS, 29, 31);
-static const struct reg_field rx0_enable = REG_FIELD(WIZ_LANEXCTL_STS, 13, 15);
-static const struct reg_field pll_enable = REG_FIELD(WIZ_PLL_CTRL, 29, 31);
-static const struct reg_field pll_ok = REG_FIELD(WIZ_PLL_CTRL, 28, 28);
+enum serdes_am654_fields {
+ /* CMU PLL Control */
+ CMU_PLL_CTRL,
+
+ LANE_PLL_CTRL_RXEQ_RXIDLE,
+
+ /* CMU VCO bias current and VREG setting */
+ AHB_PMA_CM_VCO_VBIAS_VREG,
+ AHB_PMA_CM_VCO_BIAS_VREG,
+
+ AHB_PMA_CM_SR,
+ AHB_SSC_GEN_Z_O_20_13,
+
+ /* AHB PMA Lane Configuration */
+ AHB_PMA_LN_AGC_THSEL_VREGH,
+
+ /* AGC and Signal detect threshold for Gen3 */
+ AHB_PMA_LN_GEN3_AGC_SD_THSEL,
+
+ AHB_PMA_LN_RX_SELR_GEN3,
+ AHB_PMA_LN_TX_DRV,
+
+ /* CMU Master Reset */
+ CMU_MASTER_CDN,
+
+ /* P2S ring buffer initial startup pointer difference */
+ P2S_RBUF_PTR_DIFF,
+
+ CONFIG_VERSION,
+
+ /* Lane 1 Master Reset */
+ L1_MASTER_CDN,
+
+ /* CMU OK Status */
+ CMU_OK_I_0,
+
+ /* Mid-speed initial calibration control */
+ COMRXEQ_MS_INIT_CTRL_7_0,
+
+ /* High-speed initial calibration control */
+ COMRXEQ_HS_INIT_CAL_7_0,
+
+ /* Mid-speed recalibration control */
+ COMRXEQ_MS_RECAL_CTRL_7_0,
+
+ /* High-speed recalibration control */
+ COMRXEQ_HS_RECAL_CTRL_7_0,
+
+ /* ATT configuration */
+ COMRXEQ_CSR_ATT_CONFIG,
+
+ /* Edge based boost adaptation window length */
+ COMRXEQ_CSR_EBSTADAPT_WIN_LEN,
+
+ /* COMRXEQ control 3 & 4 */
+ COMRXEQ_CTRL_3_4,
+
+ /* COMRXEQ control 14, 15 and 16*/
+ COMRXEQ_CTRL_14_15_16,
+
+ /* Threshold for errors in pattern data */
+ COMRXEQ_CSR_DLEV_ERR_THRESH,
+
+ /* COMRXEQ control 25 */
+ COMRXEQ_CTRL_25,
+
+ /* Mid-speed rate change calibration control */
+ CSR_RXEQ_RATE_CHANGE_CAL_RUN_RATE2_O,
+
+ /* High-speed rate change calibration control */
+ COMRXEQ_HS_RCHANGE_CTRL_7_0,
+
+ /* Serdes reset */
+ POR_EN,
+
+ /* Tx Enable Value */
+ TX0_ENABLE,
+
+ /* Rx Enable Value */
+ RX0_ENABLE,
+
+ /* PLL Enable Value */
+ PLL_ENABLE,
+
+ /* PLL ready for use */
+ PLL_OK,
+
+ /* sentinel */
+ MAX_FIELDS
+
+};
+
+static const struct reg_field serdes_am654_reg_fields[] = {
+ [CMU_PLL_CTRL] = REG_FIELD(CMU_R004, 8, 15),
+ [AHB_PMA_CM_VCO_VBIAS_VREG] = REG_FIELD(CMU_R060, 8, 15),
+ [CMU_MASTER_CDN] = REG_FIELD(CMU_R07C, 24, 31),
+ [AHB_PMA_CM_VCO_BIAS_VREG] = REG_FIELD(CMU_R088, 24, 31),
+ [AHB_PMA_CM_SR] = REG_FIELD(CMU_R0D0, 24, 31),
+ [AHB_SSC_GEN_Z_O_20_13] = REG_FIELD(CMU_R0E8, 8, 15),
+ [LANE_PLL_CTRL_RXEQ_RXIDLE] = REG_FIELD(LANE_R048, 8, 15),
+ [AHB_PMA_LN_AGC_THSEL_VREGH] = REG_FIELD(LANE_R058, 16, 23),
+ [AHB_PMA_LN_GEN3_AGC_SD_THSEL] = REG_FIELD(LANE_R06c, 0, 7),
+ [AHB_PMA_LN_RX_SELR_GEN3] = REG_FIELD(LANE_R070, 16, 23),
+ [AHB_PMA_LN_TX_DRV] = REG_FIELD(LANE_R19C, 16, 23),
+ [P2S_RBUF_PTR_DIFF] = REG_FIELD(COMLANE_R004, 0, 7),
+ [CONFIG_VERSION] = REG_FIELD(COMLANE_R138, 16, 23),
+ [L1_MASTER_CDN] = REG_FIELD(COMLANE_R190, 8, 15),
+ [CMU_OK_I_0] = REG_FIELD(COMLANE_R194, 19, 19),
+ [COMRXEQ_MS_INIT_CTRL_7_0] = REG_FIELD(COMRXEQ_R004, 24, 31),
+ [COMRXEQ_HS_INIT_CAL_7_0] = REG_FIELD(COMRXEQ_R008, 0, 7),
+ [COMRXEQ_MS_RECAL_CTRL_7_0] = REG_FIELD(COMRXEQ_R00C, 8, 15),
+ [COMRXEQ_HS_RECAL_CTRL_7_0] = REG_FIELD(COMRXEQ_R00C, 16, 23),
+ [COMRXEQ_CSR_ATT_CONFIG] = REG_FIELD(COMRXEQ_R014, 16, 23),
+ [COMRXEQ_CSR_EBSTADAPT_WIN_LEN] = REG_FIELD(COMRXEQ_R018, 16, 23),
+ [COMRXEQ_CTRL_3_4] = REG_FIELD(COMRXEQ_R01C, 8, 15),
+ [COMRXEQ_CTRL_14_15_16] = REG_FIELD(COMRXEQ_R04C, 0, 7),
+ [COMRXEQ_CSR_DLEV_ERR_THRESH] = REG_FIELD(COMRXEQ_R088, 16, 23),
+ [COMRXEQ_CTRL_25] = REG_FIELD(COMRXEQ_R094, 24, 31),
+ [CSR_RXEQ_RATE_CHANGE_CAL_RUN_RATE2_O] = REG_FIELD(COMRXEQ_R098, 8, 15),
+ [COMRXEQ_HS_RCHANGE_CTRL_7_0] = REG_FIELD(COMRXEQ_R098, 16, 23),
+ [POR_EN] = REG_FIELD(SERDES_CTRL, 29, 29),
+ [TX0_ENABLE] = REG_FIELD(WIZ_LANEXCTL_STS, 29, 31),
+ [RX0_ENABLE] = REG_FIELD(WIZ_LANEXCTL_STS, 13, 15),
+ [PLL_ENABLE] = REG_FIELD(WIZ_PLL_CTRL, 29, 31),
+ [PLL_OK] = REG_FIELD(WIZ_PLL_CTRL, 28, 28),
+};
struct serdes_am654 {
struct regmap *regmap;
- struct regmap_field *cmu_master_cdn_o;
- struct regmap_field *config_version;
- struct regmap_field *l1_master_cdn_o;
- struct regmap_field *cmu_ok_i_0;
- struct regmap_field *por_en;
- struct regmap_field *tx0_enable;
- struct regmap_field *rx0_enable;
- struct regmap_field *pll_enable;
- struct regmap_field *pll_ok;
+ struct regmap_field *fields[MAX_FIELDS];
struct device *dev;
struct mux_control *control;
@@ -116,12 +248,12 @@ static int serdes_am654_enable_pll(struct serdes_am654 *phy)
int ret;
u32 val;
- ret = regmap_field_write(phy->pll_enable, PLL_ENABLE_STATE);
+ ret = regmap_field_write(phy->fields[PLL_ENABLE], PLL_ENABLE_STATE);
if (ret)
return ret;
- return regmap_field_read_poll_timeout(phy->pll_ok, val, val, 1000,
- PLL_LOCK_TIME);
+ return regmap_field_read_poll_timeout(phy->fields[PLL_OK], val, val,
+ 1000, PLL_LOCK_TIME);
}
static void serdes_am654_disable_pll(struct serdes_am654 *phy)
@@ -129,41 +261,39 @@ static void serdes_am654_disable_pll(struct serdes_am654 *phy)
struct device *dev = phy->dev;
int ret;
- ret = regmap_field_write(phy->pll_enable, PLL_DISABLE_STATE);
+ ret = regmap_field_write(phy->fields[PLL_ENABLE], PLL_DISABLE_STATE);
if (ret)
dev_err(dev, "Failed to disable PLL\n");
}
static int serdes_am654_enable_txrx(struct serdes_am654 *phy)
{
- int ret;
+ int ret = 0;
/* Enable TX */
- ret = regmap_field_write(phy->tx0_enable, TX0_ENABLE_STATE);
- if (ret)
- return ret;
+ ret |= regmap_field_write(phy->fields[TX0_ENABLE], TX0_ENABLE_STATE);
/* Enable RX */
- ret = regmap_field_write(phy->rx0_enable, RX0_ENABLE_STATE);
+ ret |= regmap_field_write(phy->fields[RX0_ENABLE], RX0_ENABLE_STATE);
+
if (ret)
- return ret;
+ return -EIO;
return 0;
}
static int serdes_am654_disable_txrx(struct serdes_am654 *phy)
{
- int ret;
+ int ret = 0;
/* Disable TX */
- ret = regmap_field_write(phy->tx0_enable, TX0_DISABLE_STATE);
- if (ret)
- return ret;
+ ret |= regmap_field_write(phy->fields[TX0_ENABLE], TX0_DISABLE_STATE);
/* Disable RX */
- ret = regmap_field_write(phy->rx0_enable, RX0_DISABLE_STATE);
+ ret |= regmap_field_write(phy->fields[RX0_ENABLE], RX0_DISABLE_STATE);
+
if (ret)
- return ret;
+ return -EIO;
return 0;
}
@@ -187,8 +317,8 @@ static int serdes_am654_power_on(struct phy *x)
return ret;
}
- return regmap_field_read_poll_timeout(phy->cmu_ok_i_0, val, val,
- SLEEP_TIME, PLL_LOCK_TIME);
+ return regmap_field_read_poll_timeout(phy->fields[CMU_OK_I_0], val,
+ val, SLEEP_TIME, PLL_LOCK_TIME);
}
static int serdes_am654_power_off(struct phy *x)
@@ -286,19 +416,37 @@ static int serdes_am654_usb3_init(struct serdes_am654 *phy)
static int serdes_am654_pcie_init(struct serdes_am654 *phy)
{
- int ret;
+ int ret = 0;
- ret = regmap_field_write(phy->config_version, VERSION);
- if (ret)
- return ret;
+ ret |= regmap_field_write(phy->fields[CMU_PLL_CTRL], 0x2);
+ ret |= regmap_field_write(phy->fields[AHB_PMA_CM_VCO_VBIAS_VREG], 0x98);
+ ret |= regmap_field_write(phy->fields[AHB_PMA_CM_VCO_BIAS_VREG], 0x98);
+ ret |= regmap_field_write(phy->fields[AHB_PMA_CM_SR], 0x45);
+ ret |= regmap_field_write(phy->fields[AHB_SSC_GEN_Z_O_20_13], 0xe);
+ ret |= regmap_field_write(phy->fields[LANE_PLL_CTRL_RXEQ_RXIDLE], 0x5);
+ ret |= regmap_field_write(phy->fields[AHB_PMA_LN_AGC_THSEL_VREGH], 0x83);
+ ret |= regmap_field_write(phy->fields[AHB_PMA_LN_GEN3_AGC_SD_THSEL], 0x83);
+ ret |= regmap_field_write(phy->fields[AHB_PMA_LN_RX_SELR_GEN3], 0x81);
+ ret |= regmap_field_write(phy->fields[AHB_PMA_LN_TX_DRV], 0x3b);
+ ret |= regmap_field_write(phy->fields[P2S_RBUF_PTR_DIFF], 0x3);
+ ret |= regmap_field_write(phy->fields[CONFIG_VERSION], VERSION_VAL);
+ ret |= regmap_field_write(phy->fields[COMRXEQ_MS_INIT_CTRL_7_0], 0xf);
+ ret |= regmap_field_write(phy->fields[COMRXEQ_HS_INIT_CAL_7_0], 0x4f);
+ ret |= regmap_field_write(phy->fields[COMRXEQ_MS_RECAL_CTRL_7_0], 0xf);
+ ret |= regmap_field_write(phy->fields[COMRXEQ_HS_RECAL_CTRL_7_0], 0x4f);
+ ret |= regmap_field_write(phy->fields[COMRXEQ_CSR_ATT_CONFIG], 0x7);
+ ret |= regmap_field_write(phy->fields[COMRXEQ_CSR_EBSTADAPT_WIN_LEN], 0x7f);
+ ret |= regmap_field_write(phy->fields[COMRXEQ_CTRL_3_4], 0xf);
+ ret |= regmap_field_write(phy->fields[COMRXEQ_CTRL_14_15_16], 0x9a);
+ ret |= regmap_field_write(phy->fields[COMRXEQ_CSR_DLEV_ERR_THRESH], 0x32);
+ ret |= regmap_field_write(phy->fields[COMRXEQ_CTRL_25], 0x80);
+ ret |= regmap_field_write(phy->fields[CSR_RXEQ_RATE_CHANGE_CAL_RUN_RATE2_O], 0xf);
+ ret |= regmap_field_write(phy->fields[COMRXEQ_HS_RCHANGE_CTRL_7_0], 0x4f);
+ ret |= regmap_field_write(phy->fields[CMU_MASTER_CDN], 0x1);
+ ret |= regmap_field_write(phy->fields[L1_MASTER_CDN], 0x2);
- ret = regmap_field_write(phy->cmu_master_cdn_o, 0x1);
if (ret)
- return ret;
-
- ret = regmap_field_write(phy->l1_master_cdn_o, 0x1);
- if (ret)
- return ret;
+ return -EIO;
return 0;
}
@@ -320,20 +468,19 @@ static int serdes_am654_init(struct phy *x)
static int serdes_am654_reset(struct phy *x)
{
struct serdes_am654 *phy = phy_get_drvdata(x);
- int ret;
+ int ret = 0;
serdes_am654_disable_pll(phy);
serdes_am654_disable_txrx(phy);
- ret = regmap_field_write(phy->por_en, 0x1);
- if (ret)
- return ret;
+ ret |= regmap_field_write(phy->fields[POR_EN], 0x1);
mdelay(1);
- ret = regmap_field_write(phy->por_en, 0x0);
+ ret |= regmap_field_write(phy->fields[POR_EN], 0x0);
+
if (ret)
- return ret;
+ return -EIO;
return 0;
}
@@ -587,66 +734,16 @@ static int serdes_am654_regfield_init(struct serdes_am654 *am654_phy)
{
struct regmap *regmap = am654_phy->regmap;
struct device *dev = am654_phy->dev;
+ int i;
- am654_phy->cmu_master_cdn_o = devm_regmap_field_alloc(dev, regmap,
- cmu_master_cdn_o);
- if (IS_ERR(am654_phy->cmu_master_cdn_o)) {
- dev_err(dev, "CMU_MASTER_CDN_O reg field init failed\n");
- return PTR_ERR(am654_phy->cmu_master_cdn_o);
- }
-
- am654_phy->config_version = devm_regmap_field_alloc(dev, regmap,
- config_version);
- if (IS_ERR(am654_phy->config_version)) {
- dev_err(dev, "CONFIG_VERSION reg field init failed\n");
- return PTR_ERR(am654_phy->config_version);
- }
-
- am654_phy->l1_master_cdn_o = devm_regmap_field_alloc(dev, regmap,
- l1_master_cdn_o);
- if (IS_ERR(am654_phy->l1_master_cdn_o)) {
- dev_err(dev, "L1_MASTER_CDN_O reg field init failed\n");
- return PTR_ERR(am654_phy->l1_master_cdn_o);
- }
-
- am654_phy->cmu_ok_i_0 = devm_regmap_field_alloc(dev, regmap,
- cmu_ok_i_0);
- if (IS_ERR(am654_phy->cmu_ok_i_0)) {
- dev_err(dev, "CMU_OK_I_0 reg field init failed\n");
- return PTR_ERR(am654_phy->cmu_ok_i_0);
- }
-
- am654_phy->por_en = devm_regmap_field_alloc(dev, regmap, por_en);
- if (IS_ERR(am654_phy->por_en)) {
- dev_err(dev, "POR_EN reg field init failed\n");
- return PTR_ERR(am654_phy->por_en);
- }
-
- am654_phy->tx0_enable = devm_regmap_field_alloc(dev, regmap,
- tx0_enable);
- if (IS_ERR(am654_phy->tx0_enable)) {
- dev_err(dev, "TX0_ENABLE reg field init failed\n");
- return PTR_ERR(am654_phy->tx0_enable);
- }
-
- am654_phy->rx0_enable = devm_regmap_field_alloc(dev, regmap,
- rx0_enable);
- if (IS_ERR(am654_phy->rx0_enable)) {
- dev_err(dev, "RX0_ENABLE reg field init failed\n");
- return PTR_ERR(am654_phy->rx0_enable);
- }
-
- am654_phy->pll_enable = devm_regmap_field_alloc(dev, regmap,
- pll_enable);
- if (IS_ERR(am654_phy->pll_enable)) {
- dev_err(dev, "PLL_ENABLE reg field init failed\n");
- return PTR_ERR(am654_phy->pll_enable);
- }
-
- am654_phy->pll_ok = devm_regmap_field_alloc(dev, regmap, pll_ok);
- if (IS_ERR(am654_phy->pll_ok)) {
- dev_err(dev, "PLL_OK reg field init failed\n");
- return PTR_ERR(am654_phy->pll_ok);
+ for (i = 0; i < MAX_FIELDS; i++) {
+ am654_phy->fields[i] = devm_regmap_field_alloc(dev,
+ regmap,
+ serdes_am654_reg_fields[i]);
+ if (IS_ERR(am654_phy->fields[i])) {
+ dev_err(dev, "Unable to allocate regmap field %d\n", i);
+ return PTR_ERR(am654_phy->fields[i]);
+ }
}
return 0;
@@ -725,8 +822,10 @@ static int serdes_am654_probe(struct platform_device *pdev)
pm_runtime_enable(dev);
phy = devm_phy_create(dev, NULL, &ops);
- if (IS_ERR(phy))
- return PTR_ERR(phy);
+ if (IS_ERR(phy)) {
+ ret = PTR_ERR(phy);
+ goto clk_err;
+ }
phy_set_drvdata(phy, am654_phy);
phy_provider = devm_of_phy_provider_register(dev, serdes_am654_xlate);
diff --git a/drivers/phy/ti/phy-gmii-sel.c b/drivers/phy/ti/phy-gmii-sel.c
index 7edd5c3bc536..5fd2e8a08bfc 100644
--- a/drivers/phy/ti/phy-gmii-sel.c
+++ b/drivers/phy/ti/phy-gmii-sel.c
@@ -11,6 +11,7 @@
#include <linux/module.h>
#include <linux/mfd/syscon.h>
#include <linux/of.h>
+#include <linux/of_address.h>
#include <linux/of_net.h>
#include <linux/phy.h>
#include <linux/phy/phy.h>
@@ -22,7 +23,7 @@
#define AM33XX_GMII_SEL_MODE_RGMII 2
enum {
- PHY_GMII_SEL_PORT_MODE,
+ PHY_GMII_SEL_PORT_MODE = 0,
PHY_GMII_SEL_RGMII_ID_MODE,
PHY_GMII_SEL_RMII_IO_CLK_EN,
PHY_GMII_SEL_LAST,
@@ -41,6 +42,7 @@ struct phy_gmii_sel_soc_data {
u32 num_ports;
u32 features;
const struct reg_field (*regfields)[PHY_GMII_SEL_LAST];
+ bool use_of_data;
};
struct phy_gmii_sel_priv {
@@ -49,6 +51,8 @@ struct phy_gmii_sel_priv {
struct regmap *regmap;
struct phy_provider *phy_provider;
struct phy_gmii_sel_phy_priv *if_phys;
+ u32 num_ports;
+ u32 reg_offset;
};
static int phy_gmii_sel_mode(struct phy *phy, enum phy_mode mode, int submode)
@@ -147,13 +151,9 @@ static const
struct reg_field phy_gmii_sel_fields_dra7[][PHY_GMII_SEL_LAST] = {
{
[PHY_GMII_SEL_PORT_MODE] = REG_FIELD(0x554, 0, 1),
- [PHY_GMII_SEL_RGMII_ID_MODE] = REG_FIELD((~0), 0, 0),
- [PHY_GMII_SEL_RMII_IO_CLK_EN] = REG_FIELD((~0), 0, 0),
},
{
[PHY_GMII_SEL_PORT_MODE] = REG_FIELD(0x554, 4, 5),
- [PHY_GMII_SEL_RGMII_ID_MODE] = REG_FIELD((~0), 0, 0),
- [PHY_GMII_SEL_RMII_IO_CLK_EN] = REG_FIELD((~0), 0, 0),
},
};
@@ -172,16 +172,19 @@ struct phy_gmii_sel_soc_data phy_gmii_sel_soc_dm814 = {
static const
struct reg_field phy_gmii_sel_fields_am654[][PHY_GMII_SEL_LAST] = {
- {
- [PHY_GMII_SEL_PORT_MODE] = REG_FIELD(0x4040, 0, 1),
- [PHY_GMII_SEL_RGMII_ID_MODE] = REG_FIELD((~0), 0, 0),
- [PHY_GMII_SEL_RMII_IO_CLK_EN] = REG_FIELD((~0), 0, 0),
- },
+ { [PHY_GMII_SEL_PORT_MODE] = REG_FIELD(0x0, 0, 2), },
+ { [PHY_GMII_SEL_PORT_MODE] = REG_FIELD(0x4, 0, 2), },
+ { [PHY_GMII_SEL_PORT_MODE] = REG_FIELD(0x8, 0, 2), },
+ { [PHY_GMII_SEL_PORT_MODE] = REG_FIELD(0xC, 0, 2), },
+ { [PHY_GMII_SEL_PORT_MODE] = REG_FIELD(0x10, 0, 2), },
+ { [PHY_GMII_SEL_PORT_MODE] = REG_FIELD(0x14, 0, 2), },
+ { [PHY_GMII_SEL_PORT_MODE] = REG_FIELD(0x18, 0, 2), },
+ { [PHY_GMII_SEL_PORT_MODE] = REG_FIELD(0x1C, 0, 2), },
};
static const
struct phy_gmii_sel_soc_data phy_gmii_sel_soc_am654 = {
- .num_ports = 1,
+ .use_of_data = true,
.regfields = phy_gmii_sel_fields_am654,
};
@@ -228,7 +231,7 @@ static struct phy *phy_gmii_sel_of_xlate(struct device *dev,
if (priv->soc_data->features & BIT(PHY_GMII_SEL_RMII_IO_CLK_EN) &&
args->args_count < 2)
return ERR_PTR(-EINVAL);
- if (phy_id > priv->soc_data->num_ports)
+ if (phy_id > priv->num_ports)
return ERR_PTR(-EINVAL);
if (phy_id != priv->if_phys[phy_id - 1].id)
return ERR_PTR(-EINVAL);
@@ -242,68 +245,97 @@ static struct phy *phy_gmii_sel_of_xlate(struct device *dev,
return priv->if_phys[phy_id].if_phy;
}
-static int phy_gmii_sel_init_ports(struct phy_gmii_sel_priv *priv)
+static int phy_gmii_init_phy(struct phy_gmii_sel_priv *priv, int port,
+ struct phy_gmii_sel_phy_priv *if_phy)
{
const struct phy_gmii_sel_soc_data *soc_data = priv->soc_data;
struct device *dev = priv->dev;
+ const struct reg_field *fields;
+ struct regmap_field *regfield;
+ struct reg_field field;
+ int ret;
+
+ if_phy->id = port;
+ if_phy->priv = priv;
+
+ fields = soc_data->regfields[port - 1];
+ field = *fields++;
+ field.reg += priv->reg_offset;
+ dev_dbg(dev, "%s field %x %d %d\n", __func__,
+ field.reg, field.msb, field.lsb);
+
+ regfield = devm_regmap_field_alloc(dev, priv->regmap, field);
+ if (IS_ERR(regfield))
+ return PTR_ERR(regfield);
+ if_phy->fields[PHY_GMII_SEL_PORT_MODE] = regfield;
+
+ field = *fields++;
+ field.reg += priv->reg_offset;
+ if (soc_data->features & BIT(PHY_GMII_SEL_RGMII_ID_MODE)) {
+ regfield = devm_regmap_field_alloc(dev,
+ priv->regmap,
+ field);
+ if (IS_ERR(regfield))
+ return PTR_ERR(regfield);
+ if_phy->fields[PHY_GMII_SEL_RGMII_ID_MODE] = regfield;
+ dev_dbg(dev, "%s field %x %d %d\n", __func__,
+ field.reg, field.msb, field.lsb);
+ }
+
+ field = *fields;
+ field.reg += priv->reg_offset;
+ if (soc_data->features & BIT(PHY_GMII_SEL_RMII_IO_CLK_EN)) {
+ regfield = devm_regmap_field_alloc(dev,
+ priv->regmap,
+ field);
+ if (IS_ERR(regfield))
+ return PTR_ERR(regfield);
+ if_phy->fields[PHY_GMII_SEL_RMII_IO_CLK_EN] = regfield;
+ dev_dbg(dev, "%s field %x %d %d\n", __func__,
+ field.reg, field.msb, field.lsb);
+ }
+
+ if_phy->if_phy = devm_phy_create(dev,
+ priv->dev->of_node,
+ &phy_gmii_sel_ops);
+ if (IS_ERR(if_phy->if_phy)) {
+ ret = PTR_ERR(if_phy->if_phy);
+ dev_err(dev, "Failed to create phy%d %d\n", port, ret);
+ return ret;
+ }
+ phy_set_drvdata(if_phy->if_phy, if_phy);
+
+ return 0;
+}
+
+static int phy_gmii_sel_init_ports(struct phy_gmii_sel_priv *priv)
+{
+ const struct phy_gmii_sel_soc_data *soc_data = priv->soc_data;
struct phy_gmii_sel_phy_priv *if_phys;
- int i, num_ports, ret;
+ struct device *dev = priv->dev;
+ int i, ret;
- num_ports = priv->soc_data->num_ports;
+ if (soc_data->use_of_data) {
+ const __be32 *offset;
+ u64 size;
- if_phys = devm_kcalloc(priv->dev, num_ports,
+ offset = of_get_address(dev->of_node, 0, &size, NULL);
+ priv->num_ports = size / sizeof(u32);
+ if (!priv->num_ports)
+ return -EINVAL;
+ priv->reg_offset = __be32_to_cpu(*offset);
+ }
+
+ if_phys = devm_kcalloc(dev, priv->num_ports,
sizeof(*if_phys), GFP_KERNEL);
if (!if_phys)
return -ENOMEM;
- dev_dbg(dev, "%s %d\n", __func__, num_ports);
-
- for (i = 0; i < num_ports; i++) {
- const struct reg_field *field;
- struct regmap_field *regfield;
+ dev_dbg(dev, "%s %d\n", __func__, priv->num_ports);
- if_phys[i].id = i + 1;
- if_phys[i].priv = priv;
-
- field = &soc_data->regfields[i][PHY_GMII_SEL_PORT_MODE];
- dev_dbg(dev, "%s field %x %d %d\n", __func__,
- field->reg, field->msb, field->lsb);
-
- regfield = devm_regmap_field_alloc(dev, priv->regmap, *field);
- if (IS_ERR(regfield))
- return PTR_ERR(regfield);
- if_phys[i].fields[PHY_GMII_SEL_PORT_MODE] = regfield;
-
- field = &soc_data->regfields[i][PHY_GMII_SEL_RGMII_ID_MODE];
- if (field->reg != (~0)) {
- regfield = devm_regmap_field_alloc(dev,
- priv->regmap,
- *field);
- if (IS_ERR(regfield))
- return PTR_ERR(regfield);
- if_phys[i].fields[PHY_GMII_SEL_RGMII_ID_MODE] =
- regfield;
- }
-
- field = &soc_data->regfields[i][PHY_GMII_SEL_RMII_IO_CLK_EN];
- if (field->reg != (~0)) {
- regfield = devm_regmap_field_alloc(dev,
- priv->regmap,
- *field);
- if (IS_ERR(regfield))
- return PTR_ERR(regfield);
- if_phys[i].fields[PHY_GMII_SEL_RMII_IO_CLK_EN] =
- regfield;
- }
-
- if_phys[i].if_phy = devm_phy_create(dev,
- priv->dev->of_node,
- &phy_gmii_sel_ops);
- if (IS_ERR(if_phys[i].if_phy)) {
- ret = PTR_ERR(if_phys[i].if_phy);
- dev_err(dev, "Failed to create phy%d %d\n", i, ret);
+ for (i = 0; i < priv->num_ports; i++) {
+ ret = phy_gmii_init_phy(priv, i + 1, &if_phys[i]);
+ if (ret)
return ret;
- }
- phy_set_drvdata(if_phys[i].if_phy, &if_phys[i]);
}
priv->if_phys = if_phys;
@@ -328,6 +360,7 @@ static int phy_gmii_sel_probe(struct platform_device *pdev)
priv->dev = &pdev->dev;
priv->soc_data = of_id->data;
+ priv->num_ports = priv->soc_data->num_ports;
priv->regmap = syscon_node_to_regmap(node->parent);
if (IS_ERR(priv->regmap)) {
diff --git a/drivers/phy/ti/phy-j721e-wiz.c b/drivers/phy/ti/phy-j721e-wiz.c
index 33c4cf0105a4..c9cfafe89cbf 100644
--- a/drivers/phy/ti/phy-j721e-wiz.c
+++ b/drivers/phy/ti/phy-j721e-wiz.c
@@ -20,7 +20,6 @@
#include <linux/pm_runtime.h>
#include <linux/regmap.h>
#include <linux/reset-controller.h>
-#include <dt-bindings/phy/phy.h>
#define WIZ_SERDES_CTRL 0x404
#define WIZ_SERDES_TOP_CTRL 0x408
diff --git a/drivers/phy/ti/phy-omap-usb2.c b/drivers/phy/ti/phy-omap-usb2.c
index 507f79d14adb..4fec90d2624f 100644
--- a/drivers/phy/ti/phy-omap-usb2.c
+++ b/drivers/phy/ti/phy-omap-usb2.c
@@ -6,23 +6,23 @@
* Author: Kishon Vijay Abraham I <kishon@ti.com>
*/
-#include <linux/module.h>
-#include <linux/platform_device.h>
-#include <linux/slab.h>
-#include <linux/of.h>
-#include <linux/io.h>
-#include <linux/phy/omap_usb.h>
-#include <linux/usb/phy_companion.h>
#include <linux/clk.h>
-#include <linux/err.h>
-#include <linux/pm_runtime.h>
#include <linux/delay.h>
+#include <linux/err.h>
+#include <linux/io.h>
+#include <linux/mfd/syscon.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_platform.h>
#include <linux/phy/omap_control_phy.h>
+#include <linux/phy/omap_usb.h>
#include <linux/phy/phy.h>
-#include <linux/mfd/syscon.h>
+#include <linux/platform_device.h>
+#include <linux/pm_runtime.h>
#include <linux/regmap.h>
-#include <linux/of_platform.h>
+#include <linux/slab.h>
#include <linux/sys_soc.h>
+#include <linux/usb/phy_companion.h>
#define USB2PHY_ANA_CONFIG1 0x4c
#define USB2PHY_DISCON_BYP_LATCH BIT(31)
@@ -89,7 +89,7 @@ static inline void omap_usb_writel(void __iomem *addr, unsigned int offset,
}
/**
- * omap_usb2_set_comparator - links the comparator present in the sytem with
+ * omap_usb2_set_comparator - links the comparator present in the system with
* this phy
* @comparator - the companion phy(comparator) for this phy
*
@@ -142,7 +142,7 @@ static int omap_usb_set_host(struct usb_otg *otg, struct usb_bus *host)
}
static int omap_usb_set_peripheral(struct usb_otg *otg,
- struct usb_gadget *gadget)
+ struct usb_gadget *gadget)
{
otg->gadget = gadget;
if (!gadget)
@@ -409,7 +409,7 @@ static int omap_usb2_probe(struct platform_device *pdev)
return PTR_ERR(phy->phy_base);
phy->syscon_phy_power = syscon_regmap_lookup_by_phandle(node,
- "syscon-phy-power");
+ "syscon-phy-power");
if (IS_ERR(phy->syscon_phy_power)) {
dev_dbg(&pdev->dev,
"can't get syscon-phy-power, using control device\n");
@@ -438,7 +438,6 @@ static int omap_usb2_probe(struct platform_device *pdev)
}
}
-
phy->wkupclk = devm_clk_get(phy->dev, "wkupclk");
if (IS_ERR(phy->wkupclk)) {
if (PTR_ERR(phy->wkupclk) == -EPROBE_DEFER)
@@ -452,10 +451,10 @@ static int omap_usb2_probe(struct platform_device *pdev)
if (PTR_ERR(phy->wkupclk) != -EPROBE_DEFER)
dev_err(&pdev->dev, "unable to get usb_phy_cm_clk32k\n");
return PTR_ERR(phy->wkupclk);
- } else {
- dev_warn(&pdev->dev,
- "found usb_phy_cm_clk32k, please fix DTS\n");
}
+
+ dev_warn(&pdev->dev,
+ "found usb_phy_cm_clk32k, please fix DTS\n");
}
phy->optclk = devm_clk_get(phy->dev, "refclk");
@@ -504,7 +503,6 @@ static int omap_usb2_probe(struct platform_device *pdev)
return PTR_ERR(phy_provider);
}
-
usb_add_phy_dev(&phy->phy);
return 0;