phy: cadence-torrent: Add 19.2 MHz reference clock support
Add configuration functions for 19.2 MHz refclock support. Add register configurations for SSC support. Signed-off-by: Swapnil Jakhade <sjakhade@cadence.com> Signed-off-by: Yuti Amonkar <yamonkar@cadence.com> Signed-off-by: Kishon Vijay Abraham I <kishon@ti.com>
This commit is contained in:
parent
21c79146a1
commit
e4b496a376
|
@ -6,6 +6,7 @@
|
|||
*
|
||||
*/
|
||||
|
||||
#include <linux/clk.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/err.h>
|
||||
#include <linux/io.h>
|
||||
|
@ -18,7 +19,10 @@
|
|||
#include <linux/phy/phy.h>
|
||||
#include <linux/platform_device.h>
|
||||
|
||||
#define DEFAULT_NUM_LANES 2
|
||||
#define REF_CLK_19_2MHz 19200000
|
||||
#define REF_CLK_25MHz 25000000
|
||||
|
||||
#define DEFAULT_NUM_LANES 4
|
||||
#define MAX_NUM_LANES 4
|
||||
#define DEFAULT_MAX_BIT_RATE 8100 /* in Mbps */
|
||||
|
||||
|
@ -58,6 +62,7 @@
|
|||
#define CMN_BGCAL_INIT_TMR 0x00190
|
||||
#define CMN_BGCAL_ITER_TMR 0x00194
|
||||
#define CMN_IBCAL_INIT_TMR 0x001d0
|
||||
#define CMN_PLL0_VCOCAL_TCTRL 0x00208
|
||||
#define CMN_PLL0_VCOCAL_INIT_TMR 0x00210
|
||||
#define CMN_PLL0_VCOCAL_ITER_TMR 0x00214
|
||||
#define CMN_PLL0_VCOCAL_REFTIM_START 0x00218
|
||||
|
@ -67,10 +72,30 @@
|
|||
#define CMN_PLL0_FRACDIVH_M0 0x00248
|
||||
#define CMN_PLL0_HIGH_THR_M0 0x0024c
|
||||
#define CMN_PLL0_DSM_DIAG_M0 0x00250
|
||||
#define CMN_PLL0_SS_CTRL1_M0 0x00260
|
||||
#define CMN_PLL0_SS_CTRL2_M0 0x00264
|
||||
#define CMN_PLL0_SS_CTRL3_M0 0x00268
|
||||
#define CMN_PLL0_SS_CTRL4_M0 0x0026C
|
||||
#define CMN_PLL0_LOCK_REFCNT_START 0x00270
|
||||
#define CMN_PLL0_LOCK_PLLCNT_START 0x00278
|
||||
#define CMN_PLL0_LOCK_PLLCNT_THR 0x0027C
|
||||
#define CMN_PLL1_VCOCAL_TCTRL 0x00308
|
||||
#define CMN_PLL1_VCOCAL_INIT_TMR 0x00310
|
||||
#define CMN_PLL1_VCOCAL_ITER_TMR 0x00314
|
||||
#define CMN_PLL1_VCOCAL_REFTIM_START 0x00318
|
||||
#define CMN_PLL1_VCOCAL_PLLCNT_START 0x00320
|
||||
#define CMN_PLL1_INTDIV_M0 0x00340
|
||||
#define CMN_PLL1_FRACDIVL_M0 0x00344
|
||||
#define CMN_PLL1_FRACDIVH_M0 0x00348
|
||||
#define CMN_PLL1_HIGH_THR_M0 0x0034c
|
||||
#define CMN_PLL1_DSM_DIAG_M0 0x00350
|
||||
#define CMN_PLL1_SS_CTRL1_M0 0x00360
|
||||
#define CMN_PLL1_SS_CTRL2_M0 0x00364
|
||||
#define CMN_PLL1_SS_CTRL3_M0 0x00368
|
||||
#define CMN_PLL1_SS_CTRL4_M0 0x0036C
|
||||
#define CMN_PLL1_LOCK_REFCNT_START 0x00370
|
||||
#define CMN_PLL1_LOCK_PLLCNT_START 0x00378
|
||||
#define CMN_PLL1_LOCK_PLLCNT_THR 0x0037C
|
||||
#define CMN_TXPUCAL_INIT_TMR 0x00410
|
||||
#define CMN_TXPUCAL_ITER_TMR 0x00414
|
||||
#define CMN_TXPDCAL_INIT_TMR 0x00430
|
||||
|
@ -88,18 +113,30 @@
|
|||
#define CMN_PDIAG_PLL0_FILT_PADJ_M0 0x00698
|
||||
#define CMN_PDIAG_PLL0_CP_PADJ_M1 0x006d0
|
||||
#define CMN_PDIAG_PLL0_CP_IADJ_M1 0x006d4
|
||||
#define CMN_PDIAG_PLL1_CTRL_M0 0x00700
|
||||
#define CMN_PDIAG_PLL1_CLK_SEL_M0 0x00704
|
||||
#define CMN_PDIAG_PLL1_CP_PADJ_M0 0x00710
|
||||
#define CMN_PDIAG_PLL1_CP_IADJ_M0 0x00714
|
||||
#define CMN_PDIAG_PLL1_FILT_PADJ_M0 0x00718
|
||||
|
||||
#define XCVR_DIAG_PLLDRC_CTRL 0x10394
|
||||
#define XCVR_DIAG_HSCLK_SEL 0x10398
|
||||
#define XCVR_DIAG_HSCLK_DIV 0x1039c
|
||||
#define XCVR_DIAG_BIDI_CTRL 0x103a8
|
||||
#define TX_PSC_A0 0x10400
|
||||
#define TX_PSC_A1 0x10404
|
||||
#define TX_PSC_A2 0x10408
|
||||
#define TX_PSC_A3 0x1040c
|
||||
#define TX_RCVDET_ST_TMR 0x1048c
|
||||
#define RX_PSC_A0 0x20000
|
||||
#define RX_PSC_A1 0x20004
|
||||
#define RX_PSC_A2 0x20008
|
||||
#define RX_PSC_A3 0x2000c
|
||||
#define RX_PSC_CAL 0x20018
|
||||
#define RX_REE_GCSM1_CTRL 0x20420
|
||||
#define RX_REE_GCSM2_CTRL 0x20440
|
||||
#define RX_REE_PERGCSM_CTRL 0x20460
|
||||
|
||||
#define PHY_PLL_CFG 0x30038
|
||||
|
||||
struct cdns_torrent_phy {
|
||||
|
@ -108,6 +145,8 @@ struct cdns_torrent_phy {
|
|||
u32 num_lanes; /* Number of lanes to use */
|
||||
u32 max_bit_rate; /* Maximum link bit rate to use (in Mbps) */
|
||||
struct device *dev;
|
||||
struct clk *clk;
|
||||
unsigned long ref_clk_rate;
|
||||
};
|
||||
|
||||
enum phy_powerstate {
|
||||
|
@ -118,17 +157,25 @@ enum phy_powerstate {
|
|||
};
|
||||
|
||||
static int cdns_torrent_dp_init(struct phy *phy);
|
||||
static int cdns_torrent_dp_exit(struct phy *phy);
|
||||
static int cdns_torrent_dp_run(struct cdns_torrent_phy *cdns_phy);
|
||||
static
|
||||
int cdns_torrent_dp_wait_pma_cmn_ready(struct cdns_torrent_phy *cdns_phy);
|
||||
static void cdns_torrent_dp_pma_cfg(struct cdns_torrent_phy *cdns_phy);
|
||||
static
|
||||
void cdns_torrent_dp_pma_cmn_cfg_19_2mhz(struct cdns_torrent_phy *cdns_phy);
|
||||
static
|
||||
void cdns_torrent_dp_pma_cmn_vco_cfg_19_2mhz(struct cdns_torrent_phy *cdns_phy,
|
||||
u32 rate, bool ssc);
|
||||
static
|
||||
void cdns_torrent_dp_pma_cmn_cfg_25mhz(struct cdns_torrent_phy *cdns_phy);
|
||||
static
|
||||
void cdns_torrent_dp_pma_cmn_vco_cfg_25mhz(struct cdns_torrent_phy *cdns_phy,
|
||||
u32 rate, bool ssc);
|
||||
static void cdns_torrent_dp_pma_lane_cfg(struct cdns_torrent_phy *cdns_phy,
|
||||
unsigned int lane);
|
||||
static
|
||||
void cdns_torrent_dp_pma_cmn_vco_cfg_25mhz(struct cdns_torrent_phy *cdns_phy);
|
||||
static void cdns_torrent_dp_pma_cmn_rate(struct cdns_torrent_phy *cdns_phy);
|
||||
static void cdns_torrent_dp_pma_cmn_rate(struct cdns_torrent_phy *cdns_phy,
|
||||
u32 rate, u32 num_lanes);
|
||||
static void cdns_dp_phy_write_field(struct cdns_torrent_phy *cdns_phy,
|
||||
unsigned int offset,
|
||||
unsigned char start_bit,
|
||||
|
@ -137,6 +184,7 @@ static void cdns_dp_phy_write_field(struct cdns_torrent_phy *cdns_phy,
|
|||
|
||||
static const struct phy_ops cdns_torrent_phy_ops = {
|
||||
.init = cdns_torrent_dp_init,
|
||||
.exit = cdns_torrent_dp_exit,
|
||||
.owner = THIS_MODULE,
|
||||
};
|
||||
|
||||
|
@ -209,6 +257,29 @@ static int cdns_torrent_dp_init(struct phy *phy)
|
|||
|
||||
struct cdns_torrent_phy *cdns_phy = phy_get_drvdata(phy);
|
||||
|
||||
ret = clk_prepare_enable(cdns_phy->clk);
|
||||
if (ret) {
|
||||
dev_err(cdns_phy->dev, "Failed to prepare ref clock\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
cdns_phy->ref_clk_rate = clk_get_rate(cdns_phy->clk);
|
||||
if (!(cdns_phy->ref_clk_rate)) {
|
||||
dev_err(cdns_phy->dev, "Failed to get ref clock rate\n");
|
||||
clk_disable_unprepare(cdns_phy->clk);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
switch (cdns_phy->ref_clk_rate) {
|
||||
case REF_CLK_19_2MHz:
|
||||
case REF_CLK_25MHz:
|
||||
/* Valid Ref Clock Rate */
|
||||
break;
|
||||
default:
|
||||
dev_err(cdns_phy->dev, "Unsupported Ref Clock Rate\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
cdns_torrent_dp_write(cdns_phy, PHY_AUX_CTRL, 0x0003); /* enable AUX */
|
||||
|
||||
/* PHY PMA registers configuration function */
|
||||
|
@ -232,8 +303,17 @@ static int cdns_torrent_dp_init(struct phy *phy)
|
|||
cdns_torrent_dp_write(cdns_phy, PHY_PMA_XCVR_PLLCLK_EN, 0x0001);
|
||||
|
||||
/* PHY PMA registers configuration functions */
|
||||
cdns_torrent_dp_pma_cmn_vco_cfg_25mhz(cdns_phy);
|
||||
cdns_torrent_dp_pma_cmn_rate(cdns_phy);
|
||||
/* Initialize PHY with max supported link rate, without SSC. */
|
||||
if (cdns_phy->ref_clk_rate == REF_CLK_19_2MHz)
|
||||
cdns_torrent_dp_pma_cmn_vco_cfg_19_2mhz(cdns_phy,
|
||||
cdns_phy->max_bit_rate,
|
||||
false);
|
||||
else if (cdns_phy->ref_clk_rate == REF_CLK_25MHz)
|
||||
cdns_torrent_dp_pma_cmn_vco_cfg_25mhz(cdns_phy,
|
||||
cdns_phy->max_bit_rate,
|
||||
false);
|
||||
cdns_torrent_dp_pma_cmn_rate(cdns_phy, cdns_phy->max_bit_rate,
|
||||
cdns_phy->num_lanes);
|
||||
|
||||
/* take out of reset */
|
||||
cdns_dp_phy_write_field(cdns_phy, PHY_RESET, 8, 1, 1);
|
||||
|
@ -246,6 +326,14 @@ static int cdns_torrent_dp_init(struct phy *phy)
|
|||
return ret;
|
||||
}
|
||||
|
||||
static int cdns_torrent_dp_exit(struct phy *phy)
|
||||
{
|
||||
struct cdns_torrent_phy *cdns_phy = phy_get_drvdata(phy);
|
||||
|
||||
clk_disable_unprepare(cdns_phy->clk);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static
|
||||
int cdns_torrent_dp_wait_pma_cmn_ready(struct cdns_torrent_phy *cdns_phy)
|
||||
{
|
||||
|
@ -268,14 +356,237 @@ static void cdns_torrent_dp_pma_cfg(struct cdns_torrent_phy *cdns_phy)
|
|||
{
|
||||
unsigned int i;
|
||||
|
||||
/* PMA common configuration */
|
||||
cdns_torrent_dp_pma_cmn_cfg_25mhz(cdns_phy);
|
||||
if (cdns_phy->ref_clk_rate == REF_CLK_19_2MHz)
|
||||
/* PMA common configuration 19.2MHz */
|
||||
cdns_torrent_dp_pma_cmn_cfg_19_2mhz(cdns_phy);
|
||||
else if (cdns_phy->ref_clk_rate == REF_CLK_25MHz)
|
||||
/* PMA common configuration 25MHz */
|
||||
cdns_torrent_dp_pma_cmn_cfg_25mhz(cdns_phy);
|
||||
|
||||
/* PMA lane configuration to deal with multi-link operation */
|
||||
for (i = 0; i < cdns_phy->num_lanes; i++)
|
||||
cdns_torrent_dp_pma_lane_cfg(cdns_phy, i);
|
||||
}
|
||||
|
||||
static
|
||||
void cdns_torrent_dp_pma_cmn_cfg_19_2mhz(struct cdns_torrent_phy *cdns_phy)
|
||||
{
|
||||
/* refclock registers - assumes 19.2 MHz refclock */
|
||||
cdns_torrent_phy_write(cdns_phy, CMN_SSM_BIAS_TMR, 0x0014);
|
||||
cdns_torrent_phy_write(cdns_phy, CMN_PLLSM0_PLLPRE_TMR, 0x0027);
|
||||
cdns_torrent_phy_write(cdns_phy, CMN_PLLSM0_PLLLOCK_TMR, 0x00A1);
|
||||
cdns_torrent_phy_write(cdns_phy, CMN_PLLSM1_PLLPRE_TMR, 0x0027);
|
||||
cdns_torrent_phy_write(cdns_phy, CMN_PLLSM1_PLLLOCK_TMR, 0x00A1);
|
||||
cdns_torrent_phy_write(cdns_phy, CMN_BGCAL_INIT_TMR, 0x0060);
|
||||
cdns_torrent_phy_write(cdns_phy, CMN_BGCAL_ITER_TMR, 0x0060);
|
||||
cdns_torrent_phy_write(cdns_phy, CMN_IBCAL_INIT_TMR, 0x0014);
|
||||
cdns_torrent_phy_write(cdns_phy, CMN_TXPUCAL_INIT_TMR, 0x0018);
|
||||
cdns_torrent_phy_write(cdns_phy, CMN_TXPUCAL_ITER_TMR, 0x0005);
|
||||
cdns_torrent_phy_write(cdns_phy, CMN_TXPDCAL_INIT_TMR, 0x0018);
|
||||
cdns_torrent_phy_write(cdns_phy, CMN_TXPDCAL_ITER_TMR, 0x0005);
|
||||
cdns_torrent_phy_write(cdns_phy, CMN_RXCAL_INIT_TMR, 0x0240);
|
||||
cdns_torrent_phy_write(cdns_phy, CMN_RXCAL_ITER_TMR, 0x0005);
|
||||
cdns_torrent_phy_write(cdns_phy, CMN_SD_CAL_INIT_TMR, 0x0002);
|
||||
cdns_torrent_phy_write(cdns_phy, CMN_SD_CAL_ITER_TMR, 0x0002);
|
||||
cdns_torrent_phy_write(cdns_phy, CMN_SD_CAL_REFTIM_START, 0x000B);
|
||||
cdns_torrent_phy_write(cdns_phy, CMN_SD_CAL_PLLCNT_START, 0x0137);
|
||||
|
||||
/* PLL registers */
|
||||
cdns_torrent_phy_write(cdns_phy, CMN_PDIAG_PLL0_CP_PADJ_M0, 0x0509);
|
||||
cdns_torrent_phy_write(cdns_phy, CMN_PDIAG_PLL0_CP_IADJ_M0, 0x0F00);
|
||||
cdns_torrent_phy_write(cdns_phy, CMN_PDIAG_PLL0_FILT_PADJ_M0, 0x0F08);
|
||||
cdns_torrent_phy_write(cdns_phy, CMN_PLL0_DSM_DIAG_M0, 0x0004);
|
||||
cdns_torrent_phy_write(cdns_phy, CMN_PDIAG_PLL1_CP_PADJ_M0, 0x0509);
|
||||
cdns_torrent_phy_write(cdns_phy, CMN_PDIAG_PLL1_CP_IADJ_M0, 0x0F00);
|
||||
cdns_torrent_phy_write(cdns_phy, CMN_PDIAG_PLL1_FILT_PADJ_M0, 0x0F08);
|
||||
cdns_torrent_phy_write(cdns_phy, CMN_PLL1_DSM_DIAG_M0, 0x0004);
|
||||
cdns_torrent_phy_write(cdns_phy, CMN_PLL0_VCOCAL_INIT_TMR, 0x00C0);
|
||||
cdns_torrent_phy_write(cdns_phy, CMN_PLL0_VCOCAL_ITER_TMR, 0x0004);
|
||||
cdns_torrent_phy_write(cdns_phy, CMN_PLL1_VCOCAL_INIT_TMR, 0x00C0);
|
||||
cdns_torrent_phy_write(cdns_phy, CMN_PLL1_VCOCAL_ITER_TMR, 0x0004);
|
||||
cdns_torrent_phy_write(cdns_phy, CMN_PLL0_VCOCAL_REFTIM_START, 0x0260);
|
||||
cdns_torrent_phy_write(cdns_phy, CMN_PLL0_VCOCAL_TCTRL, 0x0003);
|
||||
cdns_torrent_phy_write(cdns_phy, CMN_PLL1_VCOCAL_REFTIM_START, 0x0260);
|
||||
cdns_torrent_phy_write(cdns_phy, CMN_PLL1_VCOCAL_TCTRL, 0x0003);
|
||||
}
|
||||
|
||||
/*
|
||||
* Set registers responsible for enabling and configuring SSC, with second and
|
||||
* third register values provided by parameters.
|
||||
*/
|
||||
static
|
||||
void cdns_torrent_dp_enable_ssc_19_2mhz(struct cdns_torrent_phy *cdns_phy,
|
||||
u32 ctrl2_val, u32 ctrl3_val)
|
||||
{
|
||||
cdns_torrent_phy_write(cdns_phy, CMN_PLL0_SS_CTRL1_M0, 0x0001);
|
||||
cdns_torrent_phy_write(cdns_phy, CMN_PLL0_SS_CTRL1_M0, ctrl2_val);
|
||||
cdns_torrent_phy_write(cdns_phy, CMN_PLL0_SS_CTRL1_M0, ctrl3_val);
|
||||
cdns_torrent_phy_write(cdns_phy, CMN_PLL0_SS_CTRL4_M0, 0x0003);
|
||||
cdns_torrent_phy_write(cdns_phy, CMN_PLL1_SS_CTRL1_M0, 0x0001);
|
||||
cdns_torrent_phy_write(cdns_phy, CMN_PLL1_SS_CTRL1_M0, ctrl2_val);
|
||||
cdns_torrent_phy_write(cdns_phy, CMN_PLL1_SS_CTRL1_M0, ctrl3_val);
|
||||
cdns_torrent_phy_write(cdns_phy, CMN_PLL1_SS_CTRL4_M0, 0x0003);
|
||||
}
|
||||
|
||||
static
|
||||
void cdns_torrent_dp_pma_cmn_vco_cfg_19_2mhz(struct cdns_torrent_phy *cdns_phy,
|
||||
u32 rate, bool ssc)
|
||||
{
|
||||
/* Assumes 19.2 MHz refclock */
|
||||
switch (rate) {
|
||||
/* Setting VCO for 10.8GHz */
|
||||
case 2700:
|
||||
case 5400:
|
||||
cdns_torrent_phy_write(cdns_phy,
|
||||
CMN_PLL0_INTDIV_M0, 0x0119);
|
||||
cdns_torrent_phy_write(cdns_phy,
|
||||
CMN_PLL0_FRACDIVL_M0, 0x4000);
|
||||
cdns_torrent_phy_write(cdns_phy,
|
||||
CMN_PLL0_FRACDIVH_M0, 0x0002);
|
||||
cdns_torrent_phy_write(cdns_phy,
|
||||
CMN_PLL0_HIGH_THR_M0, 0x00BC);
|
||||
cdns_torrent_phy_write(cdns_phy,
|
||||
CMN_PDIAG_PLL0_CTRL_M0, 0x0012);
|
||||
cdns_torrent_phy_write(cdns_phy,
|
||||
CMN_PLL1_INTDIV_M0, 0x0119);
|
||||
cdns_torrent_phy_write(cdns_phy,
|
||||
CMN_PLL1_FRACDIVL_M0, 0x4000);
|
||||
cdns_torrent_phy_write(cdns_phy,
|
||||
CMN_PLL1_FRACDIVH_M0, 0x0002);
|
||||
cdns_torrent_phy_write(cdns_phy,
|
||||
CMN_PLL1_HIGH_THR_M0, 0x00BC);
|
||||
cdns_torrent_phy_write(cdns_phy,
|
||||
CMN_PDIAG_PLL1_CTRL_M0, 0x0012);
|
||||
if (ssc)
|
||||
cdns_torrent_dp_enable_ssc_19_2mhz(cdns_phy, 0x033A,
|
||||
0x006A);
|
||||
break;
|
||||
/* Setting VCO for 9.72GHz */
|
||||
case 1620:
|
||||
case 2430:
|
||||
case 3240:
|
||||
cdns_torrent_phy_write(cdns_phy,
|
||||
CMN_PLL0_INTDIV_M0, 0x01FA);
|
||||
cdns_torrent_phy_write(cdns_phy,
|
||||
CMN_PLL0_FRACDIVL_M0, 0x4000);
|
||||
cdns_torrent_phy_write(cdns_phy,
|
||||
CMN_PLL0_FRACDIVH_M0, 0x0002);
|
||||
cdns_torrent_phy_write(cdns_phy,
|
||||
CMN_PLL0_HIGH_THR_M0, 0x0152);
|
||||
cdns_torrent_phy_write(cdns_phy,
|
||||
CMN_PDIAG_PLL0_CTRL_M0, 0x0002);
|
||||
cdns_torrent_phy_write(cdns_phy,
|
||||
CMN_PLL1_INTDIV_M0, 0x01FA);
|
||||
cdns_torrent_phy_write(cdns_phy,
|
||||
CMN_PLL1_FRACDIVL_M0, 0x4000);
|
||||
cdns_torrent_phy_write(cdns_phy,
|
||||
CMN_PLL1_FRACDIVH_M0, 0x0002);
|
||||
cdns_torrent_phy_write(cdns_phy,
|
||||
CMN_PLL1_HIGH_THR_M0, 0x0152);
|
||||
cdns_torrent_phy_write(cdns_phy,
|
||||
CMN_PDIAG_PLL1_CTRL_M0, 0x0002);
|
||||
if (ssc)
|
||||
cdns_torrent_dp_enable_ssc_19_2mhz(cdns_phy, 0x05DD,
|
||||
0x0069);
|
||||
break;
|
||||
/* Setting VCO for 8.64GHz */
|
||||
case 2160:
|
||||
case 4320:
|
||||
cdns_torrent_phy_write(cdns_phy,
|
||||
CMN_PLL0_INTDIV_M0, 0x01C2);
|
||||
cdns_torrent_phy_write(cdns_phy,
|
||||
CMN_PLL0_FRACDIVL_M0, 0x0000);
|
||||
cdns_torrent_phy_write(cdns_phy,
|
||||
CMN_PLL0_FRACDIVH_M0, 0x0002);
|
||||
cdns_torrent_phy_write(cdns_phy,
|
||||
CMN_PLL0_HIGH_THR_M0, 0x012C);
|
||||
cdns_torrent_phy_write(cdns_phy,
|
||||
CMN_PDIAG_PLL0_CTRL_M0, 0x0002);
|
||||
cdns_torrent_phy_write(cdns_phy,
|
||||
CMN_PLL1_INTDIV_M0, 0x01C2);
|
||||
cdns_torrent_phy_write(cdns_phy,
|
||||
CMN_PLL1_FRACDIVL_M0, 0x0000);
|
||||
cdns_torrent_phy_write(cdns_phy,
|
||||
CMN_PLL1_FRACDIVH_M0, 0x0002);
|
||||
cdns_torrent_phy_write(cdns_phy,
|
||||
CMN_PLL1_HIGH_THR_M0, 0x012C);
|
||||
cdns_torrent_phy_write(cdns_phy,
|
||||
CMN_PDIAG_PLL1_CTRL_M0, 0x0002);
|
||||
if (ssc)
|
||||
cdns_torrent_dp_enable_ssc_19_2mhz(cdns_phy, 0x0536,
|
||||
0x0069);
|
||||
break;
|
||||
/* Setting VCO for 8.1GHz */
|
||||
case 8100:
|
||||
cdns_torrent_phy_write(cdns_phy,
|
||||
CMN_PLL0_INTDIV_M0, 0x01A5);
|
||||
cdns_torrent_phy_write(cdns_phy,
|
||||
CMN_PLL0_FRACDIVL_M0, 0xE000);
|
||||
cdns_torrent_phy_write(cdns_phy,
|
||||
CMN_PLL0_FRACDIVH_M0, 0x0002);
|
||||
cdns_torrent_phy_write(cdns_phy,
|
||||
CMN_PLL0_HIGH_THR_M0, 0x011A);
|
||||
cdns_torrent_phy_write(cdns_phy,
|
||||
CMN_PDIAG_PLL0_CTRL_M0, 0x0002);
|
||||
cdns_torrent_phy_write(cdns_phy,
|
||||
CMN_PLL1_INTDIV_M0, 0x01A5);
|
||||
cdns_torrent_phy_write(cdns_phy,
|
||||
CMN_PLL1_FRACDIVL_M0, 0xE000);
|
||||
cdns_torrent_phy_write(cdns_phy,
|
||||
CMN_PLL1_FRACDIVH_M0, 0x0002);
|
||||
cdns_torrent_phy_write(cdns_phy,
|
||||
CMN_PLL1_HIGH_THR_M0, 0x011A);
|
||||
cdns_torrent_phy_write(cdns_phy,
|
||||
CMN_PDIAG_PLL1_CTRL_M0, 0x0002);
|
||||
if (ssc)
|
||||
cdns_torrent_dp_enable_ssc_19_2mhz(cdns_phy, 0x04D7,
|
||||
0x006A);
|
||||
break;
|
||||
}
|
||||
|
||||
if (ssc) {
|
||||
cdns_torrent_phy_write(cdns_phy,
|
||||
CMN_PLL0_VCOCAL_PLLCNT_START, 0x025E);
|
||||
cdns_torrent_phy_write(cdns_phy,
|
||||
CMN_PLL0_LOCK_PLLCNT_THR, 0x0005);
|
||||
cdns_torrent_phy_write(cdns_phy,
|
||||
CMN_PLL1_VCOCAL_PLLCNT_START, 0x025E);
|
||||
cdns_torrent_phy_write(cdns_phy,
|
||||
CMN_PLL1_LOCK_PLLCNT_THR, 0x0005);
|
||||
} else {
|
||||
cdns_torrent_phy_write(cdns_phy,
|
||||
CMN_PLL0_VCOCAL_PLLCNT_START, 0x0260);
|
||||
cdns_torrent_phy_write(cdns_phy,
|
||||
CMN_PLL1_VCOCAL_PLLCNT_START, 0x0260);
|
||||
/* Set reset register values to disable SSC */
|
||||
cdns_torrent_phy_write(cdns_phy,
|
||||
CMN_PLL0_SS_CTRL1_M0, 0x0002);
|
||||
cdns_torrent_phy_write(cdns_phy,
|
||||
CMN_PLL0_SS_CTRL2_M0, 0x0000);
|
||||
cdns_torrent_phy_write(cdns_phy,
|
||||
CMN_PLL0_SS_CTRL3_M0, 0x0000);
|
||||
cdns_torrent_phy_write(cdns_phy,
|
||||
CMN_PLL0_SS_CTRL4_M0, 0x0000);
|
||||
cdns_torrent_phy_write(cdns_phy,
|
||||
CMN_PLL0_LOCK_PLLCNT_THR, 0x0003);
|
||||
cdns_torrent_phy_write(cdns_phy,
|
||||
CMN_PLL1_SS_CTRL1_M0, 0x0002);
|
||||
cdns_torrent_phy_write(cdns_phy,
|
||||
CMN_PLL1_SS_CTRL2_M0, 0x0000);
|
||||
cdns_torrent_phy_write(cdns_phy,
|
||||
CMN_PLL1_SS_CTRL3_M0, 0x0000);
|
||||
cdns_torrent_phy_write(cdns_phy,
|
||||
CMN_PLL1_SS_CTRL4_M0, 0x0000);
|
||||
cdns_torrent_phy_write(cdns_phy,
|
||||
CMN_PLL1_LOCK_PLLCNT_THR, 0x0003);
|
||||
}
|
||||
|
||||
cdns_torrent_phy_write(cdns_phy, CMN_PLL0_LOCK_REFCNT_START, 0x0099);
|
||||
cdns_torrent_phy_write(cdns_phy, CMN_PLL0_LOCK_PLLCNT_START, 0x0099);
|
||||
cdns_torrent_phy_write(cdns_phy, CMN_PLL1_LOCK_REFCNT_START, 0x0099);
|
||||
cdns_torrent_phy_write(cdns_phy, CMN_PLL1_LOCK_PLLCNT_START, 0x0099);
|
||||
}
|
||||
|
||||
static
|
||||
void cdns_torrent_dp_pma_cmn_cfg_25mhz(struct cdns_torrent_phy *cdns_phy)
|
||||
{
|
||||
|
@ -300,22 +611,47 @@ void cdns_torrent_dp_pma_cmn_cfg_25mhz(struct cdns_torrent_phy *cdns_phy)
|
|||
cdns_torrent_phy_write(cdns_phy, CMN_SD_CAL_PLLCNT_START, 0x012B);
|
||||
|
||||
/* PLL registers */
|
||||
cdns_torrent_phy_write(cdns_phy, CMN_PDIAG_PLL0_CP_PADJ_M0, 0x0409);
|
||||
cdns_torrent_phy_write(cdns_phy, CMN_PDIAG_PLL0_CP_IADJ_M0, 0x1001);
|
||||
cdns_torrent_phy_write(cdns_phy, CMN_PDIAG_PLL0_CP_PADJ_M0, 0x0509);
|
||||
cdns_torrent_phy_write(cdns_phy, CMN_PDIAG_PLL0_CP_IADJ_M0, 0x0F00);
|
||||
cdns_torrent_phy_write(cdns_phy, CMN_PDIAG_PLL0_FILT_PADJ_M0, 0x0F08);
|
||||
cdns_torrent_phy_write(cdns_phy, CMN_PLL0_DSM_DIAG_M0, 0x0004);
|
||||
cdns_torrent_phy_write(cdns_phy, CMN_PDIAG_PLL1_CP_PADJ_M0, 0x0509);
|
||||
cdns_torrent_phy_write(cdns_phy, CMN_PDIAG_PLL1_CP_IADJ_M0, 0x0F00);
|
||||
cdns_torrent_phy_write(cdns_phy, CMN_PDIAG_PLL1_FILT_PADJ_M0, 0x0F08);
|
||||
cdns_torrent_phy_write(cdns_phy, CMN_PLL1_DSM_DIAG_M0, 0x0004);
|
||||
cdns_torrent_phy_write(cdns_phy, CMN_PLL0_VCOCAL_INIT_TMR, 0x00FA);
|
||||
cdns_torrent_phy_write(cdns_phy, CMN_PLL0_VCOCAL_ITER_TMR, 0x0004);
|
||||
cdns_torrent_phy_write(cdns_phy, CMN_PLL1_VCOCAL_INIT_TMR, 0x00FA);
|
||||
cdns_torrent_phy_write(cdns_phy, CMN_PLL1_VCOCAL_ITER_TMR, 0x0004);
|
||||
cdns_torrent_phy_write(cdns_phy, CMN_PLL0_VCOCAL_REFTIM_START, 0x0318);
|
||||
cdns_torrent_phy_write(cdns_phy, CMN_PLL0_VCOCAL_REFTIM_START, 0x0317);
|
||||
cdns_torrent_phy_write(cdns_phy, CMN_PLL0_VCOCAL_TCTRL, 0x0003);
|
||||
cdns_torrent_phy_write(cdns_phy, CMN_PLL1_VCOCAL_REFTIM_START, 0x0317);
|
||||
cdns_torrent_phy_write(cdns_phy, CMN_PLL1_VCOCAL_TCTRL, 0x0003);
|
||||
}
|
||||
|
||||
/*
|
||||
* Set registers responsible for enabling and configuring SSC, with second
|
||||
* register value provided by a parameter.
|
||||
*/
|
||||
static void cdns_torrent_dp_enable_ssc_25mhz(struct cdns_torrent_phy *cdns_phy,
|
||||
u32 ctrl2_val)
|
||||
{
|
||||
cdns_torrent_phy_write(cdns_phy, CMN_PLL0_SS_CTRL1_M0, 0x0001);
|
||||
cdns_torrent_phy_write(cdns_phy, CMN_PLL0_SS_CTRL1_M0, ctrl2_val);
|
||||
cdns_torrent_phy_write(cdns_phy, CMN_PLL0_SS_CTRL1_M0, 0x007F);
|
||||
cdns_torrent_phy_write(cdns_phy, CMN_PLL0_SS_CTRL4_M0, 0x0003);
|
||||
cdns_torrent_phy_write(cdns_phy, CMN_PLL1_SS_CTRL1_M0, 0x0001);
|
||||
cdns_torrent_phy_write(cdns_phy, CMN_PLL1_SS_CTRL1_M0, ctrl2_val);
|
||||
cdns_torrent_phy_write(cdns_phy, CMN_PLL1_SS_CTRL1_M0, 0x007F);
|
||||
cdns_torrent_phy_write(cdns_phy, CMN_PLL1_SS_CTRL4_M0, 0x0003);
|
||||
}
|
||||
|
||||
static
|
||||
void cdns_torrent_dp_pma_cmn_vco_cfg_25mhz(struct cdns_torrent_phy *cdns_phy)
|
||||
void cdns_torrent_dp_pma_cmn_vco_cfg_25mhz(struct cdns_torrent_phy *cdns_phy,
|
||||
u32 rate, bool ssc)
|
||||
{
|
||||
/* Assumes 25 MHz refclock */
|
||||
switch (cdns_phy->max_bit_rate) {
|
||||
switch (rate) {
|
||||
/* Setting VCO for 10.8GHz */
|
||||
case 2700:
|
||||
case 5400:
|
||||
|
@ -323,14 +659,27 @@ void cdns_torrent_dp_pma_cmn_vco_cfg_25mhz(struct cdns_torrent_phy *cdns_phy)
|
|||
cdns_torrent_phy_write(cdns_phy, CMN_PLL0_FRACDIVL_M0, 0x0000);
|
||||
cdns_torrent_phy_write(cdns_phy, CMN_PLL0_FRACDIVH_M0, 0x0002);
|
||||
cdns_torrent_phy_write(cdns_phy, CMN_PLL0_HIGH_THR_M0, 0x0120);
|
||||
cdns_torrent_phy_write(cdns_phy, CMN_PLL1_INTDIV_M0, 0x01B0);
|
||||
cdns_torrent_phy_write(cdns_phy, CMN_PLL1_FRACDIVL_M0, 0x0000);
|
||||
cdns_torrent_phy_write(cdns_phy, CMN_PLL1_FRACDIVH_M0, 0x0002);
|
||||
cdns_torrent_phy_write(cdns_phy, CMN_PLL1_HIGH_THR_M0, 0x0120);
|
||||
if (ssc)
|
||||
cdns_torrent_dp_enable_ssc_25mhz(cdns_phy, 0x0423);
|
||||
break;
|
||||
/* Setting VCO for 9.72GHz */
|
||||
case 1620:
|
||||
case 2430:
|
||||
case 3240:
|
||||
cdns_torrent_phy_write(cdns_phy, CMN_PLL0_INTDIV_M0, 0x0184);
|
||||
cdns_torrent_phy_write(cdns_phy, CMN_PLL0_FRACDIVL_M0, 0xCCCD);
|
||||
cdns_torrent_phy_write(cdns_phy, CMN_PLL0_FRACDIVH_M0, 0x0002);
|
||||
cdns_torrent_phy_write(cdns_phy, CMN_PLL0_HIGH_THR_M0, 0x0104);
|
||||
cdns_torrent_phy_write(cdns_phy, CMN_PLL1_INTDIV_M0, 0x0184);
|
||||
cdns_torrent_phy_write(cdns_phy, CMN_PLL1_FRACDIVL_M0, 0xCCCD);
|
||||
cdns_torrent_phy_write(cdns_phy, CMN_PLL1_FRACDIVH_M0, 0x0002);
|
||||
cdns_torrent_phy_write(cdns_phy, CMN_PLL1_HIGH_THR_M0, 0x0104);
|
||||
if (ssc)
|
||||
cdns_torrent_dp_enable_ssc_25mhz(cdns_phy, 0x03B9);
|
||||
break;
|
||||
/* Setting VCO for 8.64GHz */
|
||||
case 2160:
|
||||
|
@ -339,6 +688,12 @@ void cdns_torrent_dp_pma_cmn_vco_cfg_25mhz(struct cdns_torrent_phy *cdns_phy)
|
|||
cdns_torrent_phy_write(cdns_phy, CMN_PLL0_FRACDIVL_M0, 0x999A);
|
||||
cdns_torrent_phy_write(cdns_phy, CMN_PLL0_FRACDIVH_M0, 0x0002);
|
||||
cdns_torrent_phy_write(cdns_phy, CMN_PLL0_HIGH_THR_M0, 0x00E7);
|
||||
cdns_torrent_phy_write(cdns_phy, CMN_PLL1_INTDIV_M0, 0x0159);
|
||||
cdns_torrent_phy_write(cdns_phy, CMN_PLL1_FRACDIVL_M0, 0x999A);
|
||||
cdns_torrent_phy_write(cdns_phy, CMN_PLL1_FRACDIVH_M0, 0x0002);
|
||||
cdns_torrent_phy_write(cdns_phy, CMN_PLL1_HIGH_THR_M0, 0x00E7);
|
||||
if (ssc)
|
||||
cdns_torrent_dp_enable_ssc_25mhz(cdns_phy, 0x034F);
|
||||
break;
|
||||
/* Setting VCO for 8.1GHz */
|
||||
case 8100:
|
||||
|
@ -346,14 +701,55 @@ void cdns_torrent_dp_pma_cmn_vco_cfg_25mhz(struct cdns_torrent_phy *cdns_phy)
|
|||
cdns_torrent_phy_write(cdns_phy, CMN_PLL0_FRACDIVL_M0, 0x0000);
|
||||
cdns_torrent_phy_write(cdns_phy, CMN_PLL0_FRACDIVH_M0, 0x0002);
|
||||
cdns_torrent_phy_write(cdns_phy, CMN_PLL0_HIGH_THR_M0, 0x00D8);
|
||||
cdns_torrent_phy_write(cdns_phy, CMN_PLL1_INTDIV_M0, 0x0144);
|
||||
cdns_torrent_phy_write(cdns_phy, CMN_PLL1_FRACDIVL_M0, 0x0000);
|
||||
cdns_torrent_phy_write(cdns_phy, CMN_PLL1_FRACDIVH_M0, 0x0002);
|
||||
cdns_torrent_phy_write(cdns_phy, CMN_PLL1_HIGH_THR_M0, 0x00D8);
|
||||
if (ssc)
|
||||
cdns_torrent_dp_enable_ssc_25mhz(cdns_phy, 0x031A);
|
||||
break;
|
||||
}
|
||||
|
||||
cdns_torrent_phy_write(cdns_phy, CMN_PDIAG_PLL0_CTRL_M0, 0x0002);
|
||||
cdns_torrent_phy_write(cdns_phy, CMN_PLL0_VCOCAL_PLLCNT_START, 0x0318);
|
||||
cdns_torrent_phy_write(cdns_phy, CMN_PDIAG_PLL1_CTRL_M0, 0x0002);
|
||||
|
||||
if (ssc) {
|
||||
cdns_torrent_phy_write(cdns_phy,
|
||||
CMN_PLL0_VCOCAL_PLLCNT_START, 0x0315);
|
||||
cdns_torrent_phy_write(cdns_phy,
|
||||
CMN_PLL0_LOCK_PLLCNT_THR, 0x0005);
|
||||
cdns_torrent_phy_write(cdns_phy,
|
||||
CMN_PLL1_VCOCAL_PLLCNT_START, 0x0315);
|
||||
cdns_torrent_phy_write(cdns_phy,
|
||||
CMN_PLL1_LOCK_PLLCNT_THR, 0x0005);
|
||||
} else {
|
||||
cdns_torrent_phy_write(cdns_phy,
|
||||
CMN_PLL0_VCOCAL_PLLCNT_START, 0x0317);
|
||||
cdns_torrent_phy_write(cdns_phy,
|
||||
CMN_PLL1_VCOCAL_PLLCNT_START, 0x0317);
|
||||
/* Set reset register values to disable SSC */
|
||||
cdns_torrent_phy_write(cdns_phy, CMN_PLL0_SS_CTRL1_M0, 0x0002);
|
||||
cdns_torrent_phy_write(cdns_phy, CMN_PLL0_SS_CTRL2_M0, 0x0000);
|
||||
cdns_torrent_phy_write(cdns_phy, CMN_PLL0_SS_CTRL3_M0, 0x0000);
|
||||
cdns_torrent_phy_write(cdns_phy, CMN_PLL0_SS_CTRL4_M0, 0x0000);
|
||||
cdns_torrent_phy_write(cdns_phy,
|
||||
CMN_PLL0_LOCK_PLLCNT_THR, 0x0003);
|
||||
cdns_torrent_phy_write(cdns_phy, CMN_PLL1_SS_CTRL1_M0, 0x0002);
|
||||
cdns_torrent_phy_write(cdns_phy, CMN_PLL1_SS_CTRL2_M0, 0x0000);
|
||||
cdns_torrent_phy_write(cdns_phy, CMN_PLL1_SS_CTRL3_M0, 0x0000);
|
||||
cdns_torrent_phy_write(cdns_phy, CMN_PLL1_SS_CTRL4_M0, 0x0000);
|
||||
cdns_torrent_phy_write(cdns_phy,
|
||||
CMN_PLL1_LOCK_PLLCNT_THR, 0x0003);
|
||||
}
|
||||
|
||||
cdns_torrent_phy_write(cdns_phy, CMN_PLL0_LOCK_REFCNT_START, 0x00C7);
|
||||
cdns_torrent_phy_write(cdns_phy, CMN_PLL0_LOCK_PLLCNT_START, 0x00C7);
|
||||
cdns_torrent_phy_write(cdns_phy, CMN_PLL1_LOCK_REFCNT_START, 0x00C7);
|
||||
cdns_torrent_phy_write(cdns_phy, CMN_PLL1_LOCK_PLLCNT_START, 0x00C7);
|
||||
}
|
||||
|
||||
static void cdns_torrent_dp_pma_cmn_rate(struct cdns_torrent_phy *cdns_phy)
|
||||
static void cdns_torrent_dp_pma_cmn_rate(struct cdns_torrent_phy *cdns_phy,
|
||||
u32 rate, u32 num_lanes)
|
||||
{
|
||||
unsigned int clk_sel_val = 0;
|
||||
unsigned int hsclk_div_val = 0;
|
||||
|
@ -362,7 +758,7 @@ static void cdns_torrent_dp_pma_cmn_rate(struct cdns_torrent_phy *cdns_phy)
|
|||
/* 16'h0000 for single DP link configuration */
|
||||
cdns_torrent_phy_write(cdns_phy, PHY_PLL_CFG, 0x0000);
|
||||
|
||||
switch (cdns_phy->max_bit_rate) {
|
||||
switch (rate) {
|
||||
case 1620:
|
||||
clk_sel_val = 0x0f01;
|
||||
hsclk_div_val = 2;
|
||||
|
@ -390,9 +786,11 @@ static void cdns_torrent_dp_pma_cmn_rate(struct cdns_torrent_phy *cdns_phy)
|
|||
|
||||
cdns_torrent_phy_write(cdns_phy,
|
||||
CMN_PDIAG_PLL0_CLK_SEL_M0, clk_sel_val);
|
||||
cdns_torrent_phy_write(cdns_phy,
|
||||
CMN_PDIAG_PLL1_CLK_SEL_M0, clk_sel_val);
|
||||
|
||||
/* PMA lane configuration to deal with multi-link operation */
|
||||
for (i = 0; i < cdns_phy->num_lanes; i++)
|
||||
for (i = 0; i < num_lanes; i++)
|
||||
cdns_torrent_phy_write(cdns_phy,
|
||||
(XCVR_DIAG_HSCLK_DIV | (i << 11)),
|
||||
hsclk_div_val);
|
||||
|
@ -403,6 +801,14 @@ static void cdns_torrent_dp_pma_lane_cfg(struct cdns_torrent_phy *cdns_phy,
|
|||
{
|
||||
unsigned int lane_bits = (lane & LANE_MASK) << 11;
|
||||
|
||||
/* Per lane, refclock-dependent receiver detection setting */
|
||||
if (cdns_phy->ref_clk_rate == REF_CLK_19_2MHz)
|
||||
cdns_torrent_phy_write(cdns_phy,
|
||||
(TX_RCVDET_ST_TMR | lane_bits), 0x0780);
|
||||
else if (cdns_phy->ref_clk_rate == REF_CLK_25MHz)
|
||||
cdns_torrent_phy_write(cdns_phy,
|
||||
(TX_RCVDET_ST_TMR | lane_bits), 0x09C4);
|
||||
|
||||
/* Writing Tx/Rx Power State Controllers registers */
|
||||
cdns_torrent_phy_write(cdns_phy, (TX_PSC_A0 | lane_bits), 0x00FB);
|
||||
cdns_torrent_phy_write(cdns_phy, (TX_PSC_A2 | lane_bits), 0x04AA);
|
||||
|
@ -411,6 +817,17 @@ static void cdns_torrent_dp_pma_lane_cfg(struct cdns_torrent_phy *cdns_phy,
|
|||
cdns_torrent_phy_write(cdns_phy, (RX_PSC_A2 | lane_bits), 0x0000);
|
||||
cdns_torrent_phy_write(cdns_phy, (RX_PSC_A3 | lane_bits), 0x0000);
|
||||
|
||||
cdns_torrent_phy_write(cdns_phy, (RX_PSC_CAL | lane_bits), 0x0000);
|
||||
|
||||
cdns_torrent_phy_write(cdns_phy,
|
||||
(RX_REE_GCSM1_CTRL | lane_bits), 0x0000);
|
||||
cdns_torrent_phy_write(cdns_phy,
|
||||
(RX_REE_GCSM2_CTRL | lane_bits), 0x0000);
|
||||
cdns_torrent_phy_write(cdns_phy,
|
||||
(RX_REE_PERGCSM_CTRL | lane_bits), 0x0000);
|
||||
|
||||
cdns_torrent_phy_write(cdns_phy,
|
||||
(XCVR_DIAG_BIDI_CTRL | lane_bits), 0x000F);
|
||||
cdns_torrent_phy_write(cdns_phy,
|
||||
(XCVR_DIAG_PLLDRC_CTRL | lane_bits), 0x0001);
|
||||
cdns_torrent_phy_write(cdns_phy,
|
||||
|
@ -582,6 +999,7 @@ static int cdns_torrent_phy_probe(struct platform_device *pdev)
|
|||
cdns_phy->max_bit_rate = DEFAULT_MAX_BIT_RATE;
|
||||
|
||||
switch (cdns_phy->max_bit_rate) {
|
||||
case 1620:
|
||||
case 2160:
|
||||
case 2430:
|
||||
case 2700:
|
||||
|
@ -597,6 +1015,12 @@ static int cdns_torrent_phy_probe(struct platform_device *pdev)
|
|||
return -EINVAL;
|
||||
}
|
||||
|
||||
cdns_phy->clk = devm_clk_get(dev, "refclk");
|
||||
if (IS_ERR(cdns_phy->clk)) {
|
||||
dev_err(dev, "phy ref clock not found\n");
|
||||
return PTR_ERR(cdns_phy->clk);
|
||||
}
|
||||
|
||||
phy_set_drvdata(phy, cdns_phy);
|
||||
|
||||
phy_provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate);
|
||||
|
|
Loading…
Reference in New Issue