Merge branch 'next' of git://git.kernel.org/pub/scm/linux/kernel/git/phy/linux-phy.git

This commit is contained in:
Stephen Rothwell 2024-12-20 14:20:10 +11:00
commit 112c40f86b
29 changed files with 867 additions and 147 deletions

View File

@ -13,6 +13,7 @@ properties:
compatible:
enum:
- rockchip,rk3568-naneng-combphy
- rockchip,rk3576-naneng-combphy
- rockchip,rk3588-naneng-combphy
reg:

View File

@ -18,6 +18,7 @@ properties:
oneOf:
- items:
- enum:
- qcom,ipq5424-qusb2-phy
- qcom,ipq6018-qusb2-phy
- qcom,ipq8074-qusb2-phy
- qcom,ipq9574-qusb2-phy

View File

@ -16,8 +16,10 @@ description:
properties:
compatible:
enum:
- qcom,qcs615-qmp-gen3x1-pcie-phy
- qcom,sa8775p-qmp-gen4x2-pcie-phy
- qcom,sa8775p-qmp-gen4x4-pcie-phy
- qcom,sar2130p-qmp-gen3x2-pcie-phy
- qcom,sc8180x-qmp-pcie-phy
- qcom,sc8280xp-qmp-gen3x1-pcie-phy
- qcom,sc8280xp-qmp-gen3x2-pcie-phy
@ -139,6 +141,7 @@ allOf:
compatible:
contains:
enum:
- qcom,sar2130p-qmp-gen3x2-pcie-phy
- qcom,sc8180x-qmp-pcie-phy
- qcom,sdm845-qhp-pcie-phy
- qcom,sdm845-qmp-pcie-phy
@ -167,6 +170,7 @@ allOf:
compatible:
contains:
enum:
- qcom,qcs615-qmp-gen3x1-pcie-phy
- qcom,sc8280xp-qmp-gen3x1-pcie-phy
- qcom,sc8280xp-qmp-gen3x2-pcie-phy
- qcom,sc8280xp-qmp-gen3x4-pcie-phy

View File

@ -16,6 +16,7 @@ description:
properties:
compatible:
enum:
- qcom,ipq5424-qmp-usb3-phy
- qcom,ipq6018-qmp-usb3-phy
- qcom,ipq8074-qmp-usb3-phy
- qcom,ipq9574-qmp-usb3-phy
@ -89,6 +90,7 @@ allOf:
compatible:
contains:
enum:
- qcom,ipq5424-qmp-usb3-phy
- qcom,ipq6018-qmp-usb3-phy
- qcom,ipq8074-qmp-usb3-phy
- qcom,ipq9574-qmp-usb3-phy

View File

@ -16,6 +16,7 @@ description:
properties:
compatible:
enum:
- qcom,sar2130p-qmp-usb3-dp-phy
- qcom,sc7180-qmp-usb3-dp-phy
- qcom,sc7280-qmp-usb3-dp-phy
- qcom,sc8180x-qmp-usb3-dp-phy
@ -127,6 +128,7 @@ allOf:
properties:
compatible:
enum:
- qcom,sar2130p-qmp-usb3-dp-phy
- qcom,sc8280xp-qmp-usb43dp-phy
- qcom,sm6350-qmp-usb3-dp-phy
- qcom,sm8550-qmp-usb3-dp-phy

View File

@ -22402,7 +22402,6 @@ F: drivers/phy/starfive/phy-jh7110-dphy-rx.c
STARFIVE JH7110 DPHY TX DRIVER
M: Keith Zhao <keith.zhao@starfivetech.com>
M: Shengyang Chen <shengyang.chen@starfivetech.com>
S: Supported
F: Documentation/devicetree/bindings/phy/starfive,jh7110-dphy-tx.yaml
F: drivers/phy/starfive/phy-jh7110-dphy-tx.c

View File

@ -23,7 +23,6 @@
#include <linux/module.h>
#include <linux/mutex.h>
#include <linux/of.h>
#include <linux/of_gpio.h>
#include <linux/phy/phy.h>
#include <linux/phy/phy-sun4i-usb.h>
#include <linux/platform_device.h>

View File

@ -331,25 +331,17 @@ fsl_samsung_hdmi_phy_configure_pll_lock_det(struct fsl_samsung_hdmi_phy *phy,
{
u32 pclk = cfg->pixclk;
u32 fld_tg_code;
u32 pclk_khz;
u8 div = 1;
u32 int_pllclk;
u8 div;
switch (cfg->pixclk) {
case 22250000 ... 47500000:
div = 1;
break;
case 50349650 ... 99000000:
div = 2;
break;
case 100699300 ... 198000000:
div = 4;
break;
case 205000000 ... 297000000:
div = 8;
break;
/* Find int_pllclk speed */
for (div = 0; div < 4; div++) {
int_pllclk = pclk / (1 << div);
if (int_pllclk < (50 * MHZ))
break;
}
writeb(FIELD_PREP(REG12_CK_DIV_MASK, ilog2(div)), phy->regs + PHY_REG(12));
writeb(FIELD_PREP(REG12_CK_DIV_MASK, div), phy->regs + PHY_REG(12));
/*
* Calculation for the frequency lock detector target code (fld_tg_code)
@ -362,10 +354,8 @@ fsl_samsung_hdmi_phy_configure_pll_lock_det(struct fsl_samsung_hdmi_phy *phy,
* settings rounding up always too. TODO: Check if that is
* correct.
*/
pclk /= div;
pclk_khz = pclk / 1000;
fld_tg_code = 256 * 1000 * 1000 / pclk_khz * 24;
fld_tg_code = DIV_ROUND_UP(fld_tg_code, 1000);
fld_tg_code = DIV_ROUND_UP(24 * MHZ * 256, int_pllclk);
/* FLD_TOL and FLD_RP_CODE taken from downstream driver */
writeb(FIELD_PREP(REG13_TG_CODE_LOW_MASK, fld_tg_code),
@ -406,16 +396,15 @@ static unsigned long fsl_samsung_hdmi_phy_find_pms(unsigned long fout, u8 *p, u1
continue;
/*
* TODO: Ref Manual doesn't state the range of _m
* so this should be further refined if possible.
* This range was set based on the original values
* in the lookup table
* The Ref manual doesn't explicitly state the range of M,
* but it does show it as an 8-bit value, so reject
* any value above 255.
*/
tmp = (u64)fout * (_p * _s);
do_div(tmp, 24 * MHZ);
_m = tmp;
if (_m < 0x30 || _m > 0x7b)
if (tmp > 255)
continue;
_m = tmp;
/*
* Rev 2 of the Ref Manual states the
@ -441,9 +430,13 @@ static unsigned long fsl_samsung_hdmi_phy_find_pms(unsigned long fout, u8 *p, u1
min_delta = delta;
best_freq = tmp;
}
/* If we have an exact match, stop looking for a better value */
if (!delta)
goto done;
}
}
done:
if (best_freq) {
*p = best_p;
*m = best_m;

View File

@ -16,15 +16,20 @@
*/
#include <linux/bitfield.h>
#include <linux/bits.h>
#include <linux/clk.h>
#include <linux/gpio.h>
#include <linux/kernel.h>
#include <linux/delay.h>
#include <linux/device.h>
#include <linux/err.h>
#include <linux/io.h>
#include <linux/mfd/syscon.h>
#include <linux/mod_devicetable.h>
#include <linux/module.h>
#include <linux/of_gpio.h>
#include <linux/of.h>
#include <linux/phy/phy.h>
#include <linux/platform_device.h>
#include <linux/regmap.h>
#include <linux/types.h>
#define AXI_CLK_FREQ 207500000
#define REF_CLK_FREQ 100000000

View File

@ -422,7 +422,7 @@ static int mvebu_comphy_ethernet_init_reset(struct mvebu_comphy_lane *lane)
/* wait until clocks are ready */
mdelay(1);
/* exlicitly disable 40B, the bits isn't clear on reset */
/* explicitly disable 40B, the bits isn't clear on reset */
regmap_read(priv->regmap, MVEBU_COMPHY_CONF6(lane->id), &val);
val &= ~MVEBU_COMPHY_CONF6_40B;
regmap_write(priv->regmap, MVEBU_COMPHY_CONF6(lane->id), val);

View File

@ -9,6 +9,8 @@
#include <linux/module.h>
#include <linux/phy/phy.h>
#include <linux/platform_device.h>
#include <linux/regulator/driver.h>
#include <linux/regulator/of_regulator.h>
#include <linux/types.h>
#include <linux/units.h>
#include <linux/nvmem-consumer.h>
@ -478,8 +480,50 @@ static int mtk_hdmi_phy_configure(struct phy *phy, union phy_configure_opts *opt
return ret;
}
static int mtk_hdmi_phy_pwr5v_enable(struct regulator_dev *rdev)
{
struct mtk_hdmi_phy *hdmi_phy = rdev_get_drvdata(rdev);
mtk_phy_set_bits(hdmi_phy->regs + HDMI_CTL_1, RG_HDMITX_PWR5V_O);
return 0;
}
static int mtk_hdmi_phy_pwr5v_disable(struct regulator_dev *rdev)
{
struct mtk_hdmi_phy *hdmi_phy = rdev_get_drvdata(rdev);
mtk_phy_clear_bits(hdmi_phy->regs + HDMI_CTL_1, RG_HDMITX_PWR5V_O);
return 0;
}
static int mtk_hdmi_phy_pwr5v_is_enabled(struct regulator_dev *rdev)
{
struct mtk_hdmi_phy *hdmi_phy = rdev_get_drvdata(rdev);
return !!(readl(hdmi_phy->regs + HDMI_CTL_1) & RG_HDMITX_PWR5V_O);
}
static const struct regulator_ops mtk_hdmi_pwr5v_regulator_ops = {
.enable = mtk_hdmi_phy_pwr5v_enable,
.disable = mtk_hdmi_phy_pwr5v_disable,
.is_enabled = mtk_hdmi_phy_pwr5v_is_enabled
};
static const struct regulator_desc mtk_hdmi_phy_pwr5v_desc = {
.name = "hdmi-pwr5v",
.id = -1,
.n_voltages = 1,
.fixed_uV = 5000000,
.ops = &mtk_hdmi_pwr5v_regulator_ops,
.type = REGULATOR_VOLTAGE,
.owner = THIS_MODULE,
};
struct mtk_hdmi_phy_conf mtk_hdmi_phy_8195_conf = {
.flags = CLK_SET_RATE_PARENT | CLK_SET_RATE_GATE,
.hdmi_phy_regulator_desc = &mtk_hdmi_phy_pwr5v_desc,
.hdmi_phy_clk_ops = &mtk_hdmi_pll_ops,
.hdmi_phy_enable_tmds = mtk_hdmi_phy_enable_tmds,
.hdmi_phy_disable_tmds = mtk_hdmi_phy_disable_tmds,

View File

@ -103,6 +103,9 @@
#define HDMI_ANA_CTL 0x7c
#define REG_ANA_HDMI20_FIFO_EN BIT(16)
#define HDMI_CTL_1 0xc4
#define RG_HDMITX_PWR5V_O BIT(9)
#define HDMI_CTL_3 0xcc
#define REG_HDMITXPLL_DIV GENMASK(4, 0)
#define REG_HDMITX_REF_XTAL_SEL BIT(7)

View File

@ -75,6 +75,28 @@ static void mtk_hdmi_phy_clk_get_data(struct mtk_hdmi_phy *hdmi_phy,
clk_init->ops = hdmi_phy->conf->hdmi_phy_clk_ops;
}
static int mtk_hdmi_phy_register_regulators(struct mtk_hdmi_phy *hdmi_phy)
{
const struct regulator_desc *vreg_desc = hdmi_phy->conf->hdmi_phy_regulator_desc;
const struct regulator_init_data vreg_init_data = {
.constraints = {
.valid_ops_mask = REGULATOR_CHANGE_STATUS,
}
};
struct regulator_config vreg_config = {
.dev = hdmi_phy->dev,
.driver_data = hdmi_phy,
.init_data = &vreg_init_data,
.of_node = hdmi_phy->dev->of_node
};
hdmi_phy->rdev = devm_regulator_register(hdmi_phy->dev, vreg_desc, &vreg_config);
if (IS_ERR(hdmi_phy->rdev))
return PTR_ERR(hdmi_phy->rdev);
return 0;
}
static int mtk_hdmi_phy_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
@ -150,6 +172,12 @@ static int mtk_hdmi_phy_probe(struct platform_device *pdev)
if (hdmi_phy->conf->pll_default_off)
hdmi_phy->conf->hdmi_phy_disable_tmds(hdmi_phy);
if (hdmi_phy->conf->hdmi_phy_regulator_desc) {
ret = mtk_hdmi_phy_register_regulators(hdmi_phy);
if (ret)
return ret;
}
return of_clk_add_provider(dev->of_node, of_clk_src_simple_get,
hdmi_phy->pll);
}

View File

@ -13,6 +13,8 @@
#include <linux/module.h>
#include <linux/phy/phy.h>
#include <linux/platform_device.h>
#include <linux/regulator/driver.h>
#include <linux/regulator/machine.h>
#include <linux/types.h>
struct mtk_hdmi_phy;
@ -20,6 +22,7 @@ struct mtk_hdmi_phy;
struct mtk_hdmi_phy_conf {
unsigned long flags;
bool pll_default_off;
const struct regulator_desc *hdmi_phy_regulator_desc;
const struct clk_ops *hdmi_phy_clk_ops;
void (*hdmi_phy_enable_tmds)(struct mtk_hdmi_phy *hdmi_phy);
void (*hdmi_phy_disable_tmds)(struct mtk_hdmi_phy *hdmi_phy);
@ -32,6 +35,7 @@ struct mtk_hdmi_phy {
struct mtk_hdmi_phy_conf *conf;
struct clk *pll;
struct clk_hw pll_hw;
struct regulator_dev *rdev;
unsigned long pll_rate;
unsigned char drv_imp_clk;
unsigned char drv_imp_d2;

View File

@ -400,6 +400,57 @@ static const struct qmp_phy_init_tbl qmp_v3_usb3_pcs_tbl[] = {
QMP_PHY_INIT_CFG(QPHY_V3_PCS_RXEQTRAINING_RUN_TIME, 0x13),
};
static const struct qmp_phy_init_tbl sar2130p_usb3_serdes_tbl[] = {
QMP_PHY_INIT_CFG(QSERDES_V6_COM_SSC_STEP_SIZE1_MODE1, 0x55),
QMP_PHY_INIT_CFG(QSERDES_V6_COM_SSC_STEP_SIZE2_MODE1, 0x0e),
QMP_PHY_INIT_CFG(QSERDES_V6_COM_CP_CTRL_MODE1, 0x02),
QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_RCTRL_MODE1, 0x16),
QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_CCTRL_MODE1, 0x36),
QMP_PHY_INIT_CFG(QSERDES_V6_COM_CORECLK_DIV_MODE1, 0x04),
QMP_PHY_INIT_CFG(QSERDES_V6_COM_LOCK_CMP1_MODE1, 0x2e),
QMP_PHY_INIT_CFG(QSERDES_V6_COM_LOCK_CMP2_MODE1, 0x82),
QMP_PHY_INIT_CFG(QSERDES_V6_COM_DEC_START_MODE1, 0x04),
QMP_PHY_INIT_CFG(QSERDES_V6_COM_DEC_START_MSB_MODE1, 0x01),
QMP_PHY_INIT_CFG(QSERDES_V6_COM_DIV_FRAC_START1_MODE1, 0x55),
QMP_PHY_INIT_CFG(QSERDES_V6_COM_DIV_FRAC_START2_MODE1, 0xd5),
QMP_PHY_INIT_CFG(QSERDES_V6_COM_DIV_FRAC_START3_MODE1, 0x05),
QMP_PHY_INIT_CFG(QSERDES_V6_COM_HSCLK_SEL_1, 0x01),
QMP_PHY_INIT_CFG(QSERDES_V6_COM_VCO_TUNE1_MODE1, 0x25),
QMP_PHY_INIT_CFG(QSERDES_V6_COM_VCO_TUNE2_MODE1, 0x02),
QMP_PHY_INIT_CFG(QSERDES_V6_COM_BIN_VCOCAL_CMP_CODE1_MODE1, 0xb7),
QMP_PHY_INIT_CFG(QSERDES_V6_COM_BIN_VCOCAL_CMP_CODE2_MODE1, 0x1e),
QMP_PHY_INIT_CFG(QSERDES_V6_COM_BIN_VCOCAL_CMP_CODE1_MODE0, 0xb7),
QMP_PHY_INIT_CFG(QSERDES_V6_COM_BIN_VCOCAL_CMP_CODE2_MODE0, 0x1e),
QMP_PHY_INIT_CFG(QSERDES_V6_COM_SSC_STEP_SIZE1_MODE0, 0x55),
QMP_PHY_INIT_CFG(QSERDES_V6_COM_SSC_STEP_SIZE2_MODE0, 0x0e),
QMP_PHY_INIT_CFG(QSERDES_V6_COM_CP_CTRL_MODE0, 0x02),
QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_RCTRL_MODE0, 0x16),
QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_CCTRL_MODE0, 0x36),
QMP_PHY_INIT_CFG(QSERDES_V6_COM_LOCK_CMP1_MODE0, 0x12),
QMP_PHY_INIT_CFG(QSERDES_V6_COM_LOCK_CMP2_MODE0, 0x34),
QMP_PHY_INIT_CFG(QSERDES_V6_COM_DEC_START_MODE0, 0x04),
QMP_PHY_INIT_CFG(QSERDES_V6_COM_DEC_START_MSB_MODE0, 0x01),
QMP_PHY_INIT_CFG(QSERDES_V6_COM_DIV_FRAC_START1_MODE0, 0x55),
QMP_PHY_INIT_CFG(QSERDES_V6_COM_DIV_FRAC_START2_MODE0, 0xd5),
QMP_PHY_INIT_CFG(QSERDES_V6_COM_DIV_FRAC_START3_MODE0, 0x05),
QMP_PHY_INIT_CFG(QSERDES_V6_COM_VCO_TUNE1_MODE0, 0x25),
QMP_PHY_INIT_CFG(QSERDES_V6_COM_VCO_TUNE2_MODE0, 0x02),
QMP_PHY_INIT_CFG(QSERDES_V6_COM_BG_TIMER, 0x0e),
QMP_PHY_INIT_CFG(QSERDES_V6_COM_SSC_EN_CENTER, 0x01),
QMP_PHY_INIT_CFG(QSERDES_V6_COM_SSC_PER1, 0x31),
QMP_PHY_INIT_CFG(QSERDES_V6_COM_SSC_PER2, 0x01),
QMP_PHY_INIT_CFG(QSERDES_V6_COM_SYSCLK_BUF_ENABLE, 0x0c),
QMP_PHY_INIT_CFG(QSERDES_V6_COM_SYSCLK_EN_SEL, 0x1a),
QMP_PHY_INIT_CFG(QSERDES_V6_COM_LOCK_CMP_CFG, 0x14),
QMP_PHY_INIT_CFG(QSERDES_V6_COM_VCO_TUNE_MAP, 0x04),
QMP_PHY_INIT_CFG(QSERDES_V6_COM_CORE_CLK_EN, 0x20),
QMP_PHY_INIT_CFG(QSERDES_V6_COM_CMN_CONFIG_1, 0x04),
QMP_PHY_INIT_CFG(QSERDES_V6_COM_AUTO_GAIN_ADJ_CTRL_1, 0xb6),
QMP_PHY_INIT_CFG(QSERDES_V6_COM_AUTO_GAIN_ADJ_CTRL_2, 0x4b),
QMP_PHY_INIT_CFG(QSERDES_V6_COM_AUTO_GAIN_ADJ_CTRL_3, 0x37),
QMP_PHY_INIT_CFG(QSERDES_V6_COM_ADDITIONAL_MISC, 0x0c),
};
static const struct qmp_phy_init_tbl sm6350_usb3_rx_tbl[] = {
QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_FASTLOCK_FO_GAIN, 0x0b),
QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_EQU_ADAPTOR_CNTRL2, 0x0f),
@ -1730,6 +1781,51 @@ static const struct qmp_combo_offsets qmp_combo_offsets_v5 = {
.dp_dp_phy = 0x2200,
};
static const struct qmp_phy_cfg sar2130p_usb3dpphy_cfg = {
.offsets = &qmp_combo_offsets_v3,
.serdes_tbl = sar2130p_usb3_serdes_tbl,
.serdes_tbl_num = ARRAY_SIZE(sar2130p_usb3_serdes_tbl),
.tx_tbl = sm8550_usb3_tx_tbl,
.tx_tbl_num = ARRAY_SIZE(sm8550_usb3_tx_tbl),
.rx_tbl = sm8550_usb3_rx_tbl,
.rx_tbl_num = ARRAY_SIZE(sm8550_usb3_rx_tbl),
.pcs_tbl = sm8550_usb3_pcs_tbl,
.pcs_tbl_num = ARRAY_SIZE(sm8550_usb3_pcs_tbl),
.pcs_usb_tbl = sm8550_usb3_pcs_usb_tbl,
.pcs_usb_tbl_num = ARRAY_SIZE(sm8550_usb3_pcs_usb_tbl),
.dp_serdes_tbl = qmp_v6_dp_serdes_tbl,
.dp_serdes_tbl_num = ARRAY_SIZE(qmp_v6_dp_serdes_tbl),
.dp_tx_tbl = qmp_v6_dp_tx_tbl,
.dp_tx_tbl_num = ARRAY_SIZE(qmp_v6_dp_tx_tbl),
.serdes_tbl_rbr = qmp_v6_dp_serdes_tbl_rbr,
.serdes_tbl_rbr_num = ARRAY_SIZE(qmp_v6_dp_serdes_tbl_rbr),
.serdes_tbl_hbr = qmp_v6_dp_serdes_tbl_hbr,
.serdes_tbl_hbr_num = ARRAY_SIZE(qmp_v6_dp_serdes_tbl_hbr),
.serdes_tbl_hbr2 = qmp_v6_dp_serdes_tbl_hbr2,
.serdes_tbl_hbr2_num = ARRAY_SIZE(qmp_v6_dp_serdes_tbl_hbr2),
.serdes_tbl_hbr3 = qmp_v6_dp_serdes_tbl_hbr3,
.serdes_tbl_hbr3_num = ARRAY_SIZE(qmp_v6_dp_serdes_tbl_hbr3),
.swing_hbr_rbr = &qmp_dp_v5_voltage_swing_hbr_rbr,
.pre_emphasis_hbr_rbr = &qmp_dp_v6_pre_emphasis_hbr_rbr,
.swing_hbr3_hbr2 = &qmp_dp_v5_voltage_swing_hbr3_hbr2,
.pre_emphasis_hbr3_hbr2 = &qmp_dp_v5_pre_emphasis_hbr3_hbr2,
.dp_aux_init = qmp_v4_dp_aux_init,
.configure_dp_tx = qmp_v4_configure_dp_tx,
.configure_dp_phy = qmp_v4_configure_dp_phy,
.calibrate_dp_phy = qmp_v4_calibrate_dp_phy,
.regs = qmp_v6_usb3phy_regs_layout,
.reset_list = msm8996_usb3phy_reset_l,
.num_resets = ARRAY_SIZE(msm8996_usb3phy_reset_l),
.vreg_list = qmp_phy_vreg_l,
.num_vregs = ARRAY_SIZE(qmp_phy_vreg_l),
};
static const struct qmp_phy_cfg sc7180_usb3dpphy_cfg = {
.offsets = &qmp_combo_offsets_v3,
@ -3767,6 +3863,10 @@ static int qmp_combo_probe(struct platform_device *pdev)
}
static const struct of_device_id qmp_combo_of_match_table[] = {
{
.compatible = "qcom,sar2130p-qmp-usb3-dp-phy",
.data = &sar2130p_usb3dpphy_cfg,
},
{
.compatible = "qcom,sc7180-qmp-usb3-dp-phy",
.data = &sc7180_usb3dpphy_cfg,

View File

@ -728,6 +728,83 @@ static const struct qmp_phy_init_tbl ipq9574_gen3x2_pcie_pcs_misc_tbl[] = {
QMP_PHY_INIT_CFG(QPHY_V5_PCS_PCIE_ENDPOINT_REFCLK_DRIVE, 0xc1),
};
static const struct qmp_phy_init_tbl qcs615_pcie_serdes_tbl[] = {
QMP_PHY_INIT_CFG(QSERDES_COM_BIAS_EN_CLKBUFLR_EN, 0x18),
QMP_PHY_INIT_CFG(QSERDES_COM_CLK_ENABLE1, 0x10),
QMP_PHY_INIT_CFG(QSERDES_COM_BG_TRIM, 0xf),
QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP_EN, 0x1),
QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE_MAP, 0x0),
QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE_TIMER1, 0xff),
QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE_TIMER2, 0x1f),
QMP_PHY_INIT_CFG(QSERDES_COM_CMN_CONFIG, 0x6),
QMP_PHY_INIT_CFG(QSERDES_COM_PLL_IVCO, 0xf),
QMP_PHY_INIT_CFG(QSERDES_COM_HSCLK_SEL, 0x0),
QMP_PHY_INIT_CFG(QSERDES_COM_SVS_MODE_CLK_SEL, 0x1),
QMP_PHY_INIT_CFG(QSERDES_COM_CORE_CLK_EN, 0x20),
QMP_PHY_INIT_CFG(QSERDES_COM_CORECLK_DIV, 0xa),
QMP_PHY_INIT_CFG(QSERDES_COM_RESETSM_CNTRL, 0x20),
QMP_PHY_INIT_CFG(QSERDES_COM_BG_TIMER, 0x9),
QMP_PHY_INIT_CFG(QSERDES_COM_SYSCLK_EN_SEL, 0x4),
QMP_PHY_INIT_CFG(QSERDES_COM_DEC_START_MODE0, 0x82),
QMP_PHY_INIT_CFG(QSERDES_COM_DIV_FRAC_START3_MODE0, 0x3),
QMP_PHY_INIT_CFG(QSERDES_COM_DIV_FRAC_START2_MODE0, 0x55),
QMP_PHY_INIT_CFG(QSERDES_COM_DIV_FRAC_START1_MODE0, 0x55),
QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP3_MODE0, 0x0),
QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP2_MODE0, 0xd),
QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP1_MODE0, 0x04),
QMP_PHY_INIT_CFG(QSERDES_COM_CLK_SELECT, 0x35),
QMP_PHY_INIT_CFG(QSERDES_COM_SYS_CLK_CTRL, 0x2),
QMP_PHY_INIT_CFG(QSERDES_COM_SYSCLK_BUF_ENABLE, 0x1f),
QMP_PHY_INIT_CFG(QSERDES_COM_CP_CTRL_MODE0, 0x4),
QMP_PHY_INIT_CFG(QSERDES_COM_PLL_RCTRL_MODE0, 0x16),
QMP_PHY_INIT_CFG(QSERDES_COM_PLL_CCTRL_MODE0, 0x30),
QMP_PHY_INIT_CFG(QSERDES_COM_INTEGLOOP_GAIN1_MODE0, 0x0),
QMP_PHY_INIT_CFG(QSERDES_COM_INTEGLOOP_GAIN0_MODE0, 0x80),
QMP_PHY_INIT_CFG(QSERDES_COM_BIAS_EN_CTRL_BY_PSM, 0x1),
QMP_PHY_INIT_CFG(QSERDES_COM_BG_TIMER, 0xa),
QMP_PHY_INIT_CFG(QSERDES_COM_SSC_EN_CENTER, 0x1),
QMP_PHY_INIT_CFG(QSERDES_COM_SSC_PER1, 0x31),
QMP_PHY_INIT_CFG(QSERDES_COM_SSC_PER2, 0x1),
QMP_PHY_INIT_CFG(QSERDES_COM_SSC_ADJ_PER1, 0x2),
QMP_PHY_INIT_CFG(QSERDES_COM_SSC_ADJ_PER2, 0x0),
QMP_PHY_INIT_CFG(QSERDES_COM_SSC_STEP_SIZE1, 0x2f),
QMP_PHY_INIT_CFG(QSERDES_COM_SSC_STEP_SIZE2, 0x19),
QMP_PHY_INIT_CFG(QSERDES_COM_CLK_EP_DIV, 0x19),
};
static const struct qmp_phy_init_tbl qcs615_pcie_rx_tbl[] = {
QMP_PHY_INIT_CFG(QSERDES_RX_SIGDET_ENABLES, 0x1c),
QMP_PHY_INIT_CFG(QSERDES_RX_SIGDET_DEGLITCH_CNTRL, 0x14),
QMP_PHY_INIT_CFG(QSERDES_RX_RX_EQU_ADAPTOR_CNTRL2, 0x1),
QMP_PHY_INIT_CFG(QSERDES_RX_RX_EQU_ADAPTOR_CNTRL3, 0x0),
QMP_PHY_INIT_CFG(QSERDES_RX_RX_EQU_ADAPTOR_CNTRL4, 0xdb),
QMP_PHY_INIT_CFG(QSERDES_RX_UCDR_SO_SATURATION_AND_ENABLE, 0x4b),
QMP_PHY_INIT_CFG(QSERDES_RX_UCDR_SO_GAIN, 0x4),
QMP_PHY_INIT_CFG(QSERDES_RX_UCDR_SO_GAIN_HALF, 0x4),
};
static const struct qmp_phy_init_tbl qcs615_pcie_tx_tbl[] = {
QMP_PHY_INIT_CFG(QSERDES_TX_HIGHZ_TRANSCEIVEREN_BIAS_DRVR_EN, 0x45),
QMP_PHY_INIT_CFG(QSERDES_TX_LANE_MODE, 0x6),
QMP_PHY_INIT_CFG(QSERDES_TX_RES_CODE_LANE_OFFSET, 0x2),
QMP_PHY_INIT_CFG(QSERDES_TX_RCV_DETECT_LVL_2, 0x12),
};
static const struct qmp_phy_init_tbl qcs615_pcie_pcs_tbl[] = {
QMP_PHY_INIT_CFG(QPHY_V2_PCS_ENDPOINT_REFCLK_DRIVE, 0x4),
QMP_PHY_INIT_CFG(QPHY_V2_PCS_OSC_DTCT_ACTIONS, 0x0),
QMP_PHY_INIT_CFG(QPHY_V2_PCS_PWRUP_RESET_DLY_TIME_AUXCLK, 0x40),
QMP_PHY_INIT_CFG(QPHY_V2_PCS_L1SS_WAKEUP_DLY_TIME_AUXCLK_MSB, 0x0),
QMP_PHY_INIT_CFG(QPHY_V2_PCS_L1SS_WAKEUP_DLY_TIME_AUXCLK_LSB, 0x40),
QMP_PHY_INIT_CFG(QPHY_V2_PCS_PLL_LOCK_CHK_DLY_TIME_AUXCLK_LSB, 0x0),
QMP_PHY_INIT_CFG(QPHY_V2_PCS_LP_WAKEUP_DLY_TIME_AUXCLK, 0x40),
QMP_PHY_INIT_CFG(QPHY_V2_PCS_PLL_LOCK_CHK_DLY_TIME, 0x73),
QMP_PHY_INIT_CFG(QPHY_V2_PCS_SIGDET_CNTRL, 0x7),
QMP_PHY_INIT_CFG(QPHY_V2_PCS_RX_SIGDET_LVL, 0x99),
QMP_PHY_INIT_CFG(QPHY_V2_PCS_TXDEEMPH_M6DB_V0, 0x15),
QMP_PHY_INIT_CFG(QPHY_V2_PCS_TXDEEMPH_M3P5DB_V0, 0xe),
};
static const struct qmp_phy_init_tbl sdm845_qmp_pcie_serdes_tbl[] = {
QMP_PHY_INIT_CFG(QSERDES_V3_COM_BIAS_EN_CLKBUFLR_EN, 0x14),
QMP_PHY_INIT_CFG(QSERDES_V3_COM_CLK_SELECT, 0x30),
@ -1773,7 +1850,7 @@ static const struct qmp_phy_init_tbl sdx55_qmp_pcie_rc_pcs_misc_tbl[] = {
QMP_PHY_INIT_CFG(QPHY_V4_20_PCS_PCIE_OSC_DTCT_ACTIONS, 0x00),
};
static const struct qmp_phy_init_tbl sdx55_qmp_pcie_ep_pcs_misc_tbl[] = {
static const struct qmp_phy_init_tbl sdx55_qmp_pcie_ep_pcs_lane1_tbl[] = {
QMP_PHY_INIT_CFG(QPHY_V4_20_PCS_LANE1_INSIG_SW_CTRL2, 0x00),
QMP_PHY_INIT_CFG(QPHY_V4_20_PCS_LANE1_INSIG_MX_CTRL2, 0x00),
};
@ -1907,6 +1984,9 @@ static const struct qmp_phy_init_tbl sdx65_qmp_pcie_pcs_misc_tbl[] = {
QMP_PHY_INIT_CFG(QPHY_V5_20_PCS_PCIE_G4_EQ_CONFIG2, 0x0d),
QMP_PHY_INIT_CFG(QPHY_V5_20_PCS_PCIE_G4_EQ_CONFIG5, 0x02),
QMP_PHY_INIT_CFG(QPHY_V5_20_PCS_PCIE_G4_PRE_GAIN, 0x2e),
};
static const struct qmp_phy_init_tbl sdx65_qmp_pcie_pcs_lane1_tbl[] = {
QMP_PHY_INIT_CFG(QPHY_V5_20_PCS_LANE1_INSIG_SW_CTRL2, 0x00),
QMP_PHY_INIT_CFG(QPHY_V5_20_PCS_LANE1_INSIG_MX_CTRL2, 0x00),
};
@ -2582,8 +2662,6 @@ static const struct qmp_phy_init_tbl sa8775p_qmp_gen4_pcie_rc_pcs_misc_tbl[] = {
static const struct qmp_phy_init_tbl sa8775p_qmp_gen4x2_pcie_pcs_alt_tbl[] = {
QMP_PHY_INIT_CFG(QPHY_V5_20_PCS_EQ_CONFIG4, 0x16),
QMP_PHY_INIT_CFG(QPHY_V5_20_PCS_EQ_CONFIG5, 0x22),
QMP_PHY_INIT_CFG(QPHY_V5_20_PCS_LANE1_INSIG_SW_CTRL2, 0x00),
QMP_PHY_INIT_CFG(QPHY_V5_20_PCS_LANE1_INSIG_MX_CTRL2, 0x00),
QMP_PHY_INIT_CFG(QPHY_V5_20_PCS_G3S2_PRE_GAIN, 0x2e),
QMP_PHY_INIT_CFG(QPHY_V5_20_PCS_RX_SIGDET_LVL, 0x66),
};
@ -2724,10 +2802,106 @@ static const struct qmp_phy_init_tbl sa8775p_qmp_gen4x2_pcie_ep_pcs_alt_tbl[] =
QMP_PHY_INIT_CFG(QPHY_V5_20_PCS_INSIG_SW_CTRL7, 0x00),
};
static const struct qmp_phy_init_tbl sar2130p_qmp_gen3x2_pcie_rc_serdes_tbl[] = {
QMP_PHY_INIT_CFG(QSERDES_V6_COM_SSC_EN_CENTER, 0x01),
QMP_PHY_INIT_CFG(QSERDES_V6_COM_SSC_PER1, 0x31),
QMP_PHY_INIT_CFG(QSERDES_V6_COM_SSC_PER2, 0x01),
QMP_PHY_INIT_CFG(QSERDES_V6_COM_SSC_STEP_SIZE1_MODE0, 0xff),
QMP_PHY_INIT_CFG(QSERDES_V6_COM_SSC_STEP_SIZE2_MODE0, 0x06),
QMP_PHY_INIT_CFG(QSERDES_V6_COM_SSC_STEP_SIZE1_MODE1, 0x4c),
QMP_PHY_INIT_CFG(QSERDES_V6_COM_SSC_STEP_SIZE2_MODE1, 0x06),
QMP_PHY_INIT_CFG(QSERDES_V6_COM_CLK_ENABLE1, 0x90),
QMP_PHY_INIT_CFG(QSERDES_V6_COM_SYS_CLK_CTRL, 0x82),
QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_IVCO, 0x07),
QMP_PHY_INIT_CFG(QSERDES_V6_COM_CP_CTRL_MODE0, 0x02),
QMP_PHY_INIT_CFG(QSERDES_V6_COM_CP_CTRL_MODE1, 0x02),
QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_RCTRL_MODE0, 0x16),
QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_RCTRL_MODE1, 0x16),
QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_CCTRL_MODE0, 0x36),
QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_CCTRL_MODE1, 0x36),
QMP_PHY_INIT_CFG(QSERDES_V6_COM_SYSCLK_EN_SEL, 0x08),
QMP_PHY_INIT_CFG(QSERDES_V6_COM_BG_TIMER, 0x0e),
QMP_PHY_INIT_CFG(QSERDES_V6_COM_LOCK_CMP_EN, 0x42),
QMP_PHY_INIT_CFG(QSERDES_V6_COM_LOCK_CMP1_MODE0, 0x08),
QMP_PHY_INIT_CFG(QSERDES_V6_COM_LOCK_CMP2_MODE0, 0x1a),
QMP_PHY_INIT_CFG(QSERDES_V6_COM_LOCK_CMP1_MODE1, 0x14),
QMP_PHY_INIT_CFG(QSERDES_V6_COM_LOCK_CMP2_MODE1, 0x34),
QMP_PHY_INIT_CFG(QSERDES_V6_COM_DEC_START_MODE0, 0x82),
QMP_PHY_INIT_CFG(QSERDES_V6_COM_DEC_START_MODE1, 0x68),
QMP_PHY_INIT_CFG(QSERDES_V6_COM_DIV_FRAC_START1_MODE0, 0xab),
QMP_PHY_INIT_CFG(QSERDES_V6_COM_DIV_FRAC_START2_MODE0, 0xea),
QMP_PHY_INIT_CFG(QSERDES_V6_COM_DIV_FRAC_START3_MODE0, 0x02),
QMP_PHY_INIT_CFG(QSERDES_V6_COM_DIV_FRAC_START1_MODE1, 0xab),
QMP_PHY_INIT_CFG(QSERDES_V6_COM_DIV_FRAC_START2_MODE1, 0xaa),
QMP_PHY_INIT_CFG(QSERDES_V6_COM_DIV_FRAC_START3_MODE1, 0x02),
QMP_PHY_INIT_CFG(QSERDES_V6_COM_VCO_TUNE_MAP, 0x14),
QMP_PHY_INIT_CFG(QSERDES_V6_COM_CLK_SELECT, 0x34),
QMP_PHY_INIT_CFG(QSERDES_V6_COM_HSCLK_SEL_1, 0x01),
QMP_PHY_INIT_CFG(QSERDES_V6_COM_CORECLK_DIV_MODE1, 0x04),
QMP_PHY_INIT_CFG(QSERDES_V6_COM_CMN_CONFIG_1, 0x16),
QMP_PHY_INIT_CFG(QSERDES_V6_COM_ADDITIONAL_MISC_3, 0x0f),
QMP_PHY_INIT_CFG(QSERDES_V6_COM_CORE_CLK_EN, 0xa0),
};
static const struct qmp_phy_init_tbl sar2130p_qmp_gen3x2_pcie_pcs_lane1_tbl[] = {
QMP_PHY_INIT_CFG(QPHY_PCIE_V6_PCS_LANE1_INSIG_SW_CTRL2, 0x01),
QMP_PHY_INIT_CFG(QPHY_PCIE_V6_PCS_LANE1_INSIG_MX_CTRL2, 0x01),
};
static const struct qmp_phy_init_tbl sar2130p_qmp_gen3x2_pcie_rc_tx_tbl[] = {
QMP_PHY_INIT_CFG_LANE(QSERDES_V6_TX_BIST_MODE_LANENO, 0x00, 2),
};
static const struct qmp_phy_init_tbl sar2130p_qmp_gen3x2_pcie_rc_pcs_tbl[] = {
QMP_PHY_INIT_CFG(QPHY_V6_PCS_G12S1_TXDEEMPH_M6DB, 0x17),
QMP_PHY_INIT_CFG(QPHY_V6_PCS_G3S2_PRE_GAIN, 0x2e),
};
static const struct qmp_phy_init_tbl sar2130p_qmp_gen3x2_pcie_ep_serdes_tbl[] = {
QMP_PHY_INIT_CFG(QSERDES_V6_COM_SYSCLK_EN_SEL, 0x00),
QMP_PHY_INIT_CFG(QSERDES_V6_COM_BG_TIMER, 0x06),
QMP_PHY_INIT_CFG(QSERDES_V6_COM_SYS_CLK_CTRL, 0x07),
QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_IVCO, 0x07),
QMP_PHY_INIT_CFG(QSERDES_V6_COM_CP_CTRL_MODE0, 0x28),
QMP_PHY_INIT_CFG(QSERDES_V6_COM_CP_CTRL_MODE1, 0x28),
QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_RCTRL_MODE0, 0x0d),
QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_RCTRL_MODE1, 0x0d),
QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_CCTRL_MODE0, 0x00),
QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_CCTRL_MODE1, 0x00),
QMP_PHY_INIT_CFG(QSERDES_V6_COM_LOCK_CMP_EN, 0x42),
QMP_PHY_INIT_CFG(QSERDES_V6_COM_LOCK_CMP1_MODE0, 0xff),
QMP_PHY_INIT_CFG(QSERDES_V6_COM_LOCK_CMP2_MODE0, 0x04),
QMP_PHY_INIT_CFG(QSERDES_V6_COM_LOCK_CMP1_MODE1, 0xff),
QMP_PHY_INIT_CFG(QSERDES_V6_COM_LOCK_CMP2_MODE1, 0x09),
QMP_PHY_INIT_CFG(QSERDES_V6_COM_DEC_START_MODE0, 0x19),
QMP_PHY_INIT_CFG(QSERDES_V6_COM_DEC_START_MODE1, 0x14),
QMP_PHY_INIT_CFG(QSERDES_V6_COM_INTEGLOOP_GAIN0_MODE0, 0xfb),
QMP_PHY_INIT_CFG(QSERDES_V6_COM_INTEGLOOP_GAIN1_MODE0, 0x03),
QMP_PHY_INIT_CFG(QSERDES_V6_COM_INTEGLOOP_GAIN0_MODE1, 0xfb),
QMP_PHY_INIT_CFG(QSERDES_V6_COM_INTEGLOOP_GAIN1_MODE1, 0x03),
QMP_PHY_INIT_CFG(QSERDES_V6_COM_VCO_TUNE_MAP, 0x14),
QMP_PHY_INIT_CFG(QSERDES_V6_COM_HSCLK_SEL_1, 0x01),
QMP_PHY_INIT_CFG(QSERDES_V6_COM_CORECLK_DIV_MODE1, 0x04),
QMP_PHY_INIT_CFG(QSERDES_V6_COM_CMN_CONFIG_1, 0x16),
QMP_PHY_INIT_CFG(QSERDES_V6_COM_CMN_MODE, 0x14),
QMP_PHY_INIT_CFG(QSERDES_V6_COM_CORE_CLK_EN, 0xa0),
};
static const struct qmp_phy_init_tbl sar2130p_qmp_gen3x2_pcie_ep_pcs_tbl[] = {
QMP_PHY_INIT_CFG(QPHY_V6_PCS_G12S1_TXDEEMPH_M6DB, 0x17),
};
static const struct qmp_phy_init_tbl sar2130p_qmp_gen3x2_pcie_ep_pcs_misc_tbl[] = {
QMP_PHY_INIT_CFG(QPHY_PCIE_V6_PCS_PCIE_EQ_CONFIG1, 0x1e),
QMP_PHY_INIT_CFG(QPHY_PCIE_V6_PCS_PCIE_POWER_STATE_CONFIG2, 0x14),
QMP_PHY_INIT_CFG(QPHY_PCIE_V6_PCS_PCIE_POWER_STATE_CONFIG4, 0x07),
};
struct qmp_pcie_offsets {
u16 serdes;
u16 pcs;
u16 pcs_misc;
u16 pcs_lane1;
u16 tx;
u16 rx;
u16 tx2;
@ -2752,6 +2926,8 @@ struct qmp_phy_cfg_tbls {
int pcs_num;
const struct qmp_phy_init_tbl *pcs_misc;
int pcs_misc_num;
const struct qmp_phy_init_tbl *pcs_lane1;
int pcs_lane1_num;
const struct qmp_phy_init_tbl *ln_shrd;
int ln_shrd_num;
};
@ -2811,6 +2987,7 @@ struct qmp_pcie {
void __iomem *serdes;
void __iomem *pcs;
void __iomem *pcs_misc;
void __iomem *pcs_lane1;
void __iomem *tx;
void __iomem *rx;
void __iomem *tx2;
@ -2927,6 +3104,7 @@ static const struct qmp_pcie_offsets qmp_pcie_offsets_v4_20 = {
.serdes = 0x1000,
.pcs = 0x1200,
.pcs_misc = 0x1600,
.pcs_lane1 = 0x1e00,
.tx = 0x0000,
.rx = 0x0200,
.tx2 = 0x0800,
@ -2957,6 +3135,7 @@ static const struct qmp_pcie_offsets qmp_pcie_offsets_v5_20 = {
.serdes = 0x1000,
.pcs = 0x1200,
.pcs_misc = 0x1400,
.pcs_lane1 = 0x1e00,
.tx = 0x0000,
.rx = 0x0200,
.tx2 = 0x0800,
@ -3132,6 +3311,31 @@ static const struct qmp_phy_cfg ipq9574_gen3x2_pciephy_cfg = {
.pipe_clock_rate = 250000000,
};
static const struct qmp_phy_cfg qcs615_pciephy_cfg = {
.lanes = 1,
.offsets = &qmp_pcie_offsets_v2,
.tbls = {
.serdes = qcs615_pcie_serdes_tbl,
.serdes_num = ARRAY_SIZE(qcs615_pcie_serdes_tbl),
.tx = qcs615_pcie_tx_tbl,
.tx_num = ARRAY_SIZE(qcs615_pcie_tx_tbl),
.rx = qcs615_pcie_rx_tbl,
.rx_num = ARRAY_SIZE(qcs615_pcie_rx_tbl),
.pcs = qcs615_pcie_pcs_tbl,
.pcs_num = ARRAY_SIZE(qcs615_pcie_pcs_tbl),
},
.reset_list = sdm845_pciephy_reset_l,
.num_resets = ARRAY_SIZE(sdm845_pciephy_reset_l),
.vreg_list = qmp_phy_vreg_l,
.num_vregs = ARRAY_SIZE(qmp_phy_vreg_l),
.regs = pciephy_v2_regs_layout,
.pwrdn_ctrl = SW_PWRDN | REFCLK_DRV_DSBL,
.phy_status = PHYSTATUS,
};
static const struct qmp_phy_cfg sdm845_qmp_pciephy_cfg = {
.lanes = 1,
@ -3283,6 +3487,49 @@ static const struct qmp_phy_cfg msm8998_pciephy_cfg = {
.skip_start_delay = true,
};
static const struct qmp_phy_cfg sar2130p_qmp_gen3x2_pciephy_cfg = {
.lanes = 2,
.offsets = &qmp_pcie_offsets_v5,
.tbls = {
.tx = sm8550_qmp_gen3x2_pcie_tx_tbl,
.tx_num = ARRAY_SIZE(sm8550_qmp_gen3x2_pcie_tx_tbl),
.rx = sm8550_qmp_gen3x2_pcie_rx_tbl,
.rx_num = ARRAY_SIZE(sm8550_qmp_gen3x2_pcie_rx_tbl),
.pcs = sm8550_qmp_gen3x2_pcie_pcs_tbl,
.pcs_num = ARRAY_SIZE(sm8550_qmp_gen3x2_pcie_pcs_tbl),
.pcs_lane1 = sar2130p_qmp_gen3x2_pcie_pcs_lane1_tbl,
.pcs_lane1_num = ARRAY_SIZE(sar2130p_qmp_gen3x2_pcie_pcs_lane1_tbl),
},
.tbls_rc = &(const struct qmp_phy_cfg_tbls) {
.serdes = sar2130p_qmp_gen3x2_pcie_rc_serdes_tbl,
.serdes_num = ARRAY_SIZE(sar2130p_qmp_gen3x2_pcie_rc_serdes_tbl),
.tx = sar2130p_qmp_gen3x2_pcie_rc_tx_tbl,
.tx_num = ARRAY_SIZE(sar2130p_qmp_gen3x2_pcie_rc_tx_tbl),
.pcs = sar2130p_qmp_gen3x2_pcie_rc_pcs_tbl,
.pcs_num = ARRAY_SIZE(sar2130p_qmp_gen3x2_pcie_rc_pcs_tbl),
.pcs_misc = sm8550_qmp_gen3x2_pcie_pcs_misc_tbl,
.pcs_misc_num = ARRAY_SIZE(sm8550_qmp_gen3x2_pcie_pcs_misc_tbl),
},
.tbls_ep = &(const struct qmp_phy_cfg_tbls) {
.serdes = sar2130p_qmp_gen3x2_pcie_ep_serdes_tbl,
.serdes_num = ARRAY_SIZE(sar2130p_qmp_gen3x2_pcie_ep_serdes_tbl),
.pcs = sar2130p_qmp_gen3x2_pcie_ep_pcs_tbl,
.pcs_num = ARRAY_SIZE(sar2130p_qmp_gen3x2_pcie_ep_pcs_tbl),
.pcs_misc = sar2130p_qmp_gen3x2_pcie_ep_pcs_misc_tbl,
.pcs_misc_num = ARRAY_SIZE(sar2130p_qmp_gen3x2_pcie_ep_pcs_misc_tbl),
},
.reset_list = sdm845_pciephy_reset_l,
.num_resets = ARRAY_SIZE(sdm845_pciephy_reset_l),
.vreg_list = qmp_phy_vreg_l,
.num_vregs = ARRAY_SIZE(qmp_phy_vreg_l),
.regs = pciephy_v5_regs_layout,
.pwrdn_ctrl = SW_PWRDN | REFCLK_DRV_DSBL,
.phy_status = PHYSTATUS,
};
static const struct qmp_phy_cfg sc8180x_pciephy_cfg = {
.lanes = 2,
@ -3440,8 +3687,8 @@ static const struct qmp_phy_cfg sdx55_qmp_pciephy_cfg = {
.tbls_ep = &(const struct qmp_phy_cfg_tbls) {
.serdes = sdx55_qmp_pcie_ep_serdes_tbl,
.serdes_num = ARRAY_SIZE(sdx55_qmp_pcie_ep_serdes_tbl),
.pcs_misc = sdx55_qmp_pcie_ep_pcs_misc_tbl,
.pcs_misc_num = ARRAY_SIZE(sdx55_qmp_pcie_ep_pcs_misc_tbl),
.pcs_lane1 = sdx55_qmp_pcie_ep_pcs_lane1_tbl,
.pcs_lane1_num = ARRAY_SIZE(sdx55_qmp_pcie_ep_pcs_lane1_tbl),
},
.reset_list = sdm845_pciephy_reset_l,
@ -3540,6 +3787,8 @@ static const struct qmp_phy_cfg sdx65_qmp_pciephy_cfg = {
.pcs_num = ARRAY_SIZE(sdx65_qmp_pcie_pcs_tbl),
.pcs_misc = sdx65_qmp_pcie_pcs_misc_tbl,
.pcs_misc_num = ARRAY_SIZE(sdx65_qmp_pcie_pcs_misc_tbl),
.pcs_lane1 = sdx65_qmp_pcie_pcs_lane1_tbl,
.pcs_lane1_num = ARRAY_SIZE(sdx65_qmp_pcie_pcs_lane1_tbl),
},
.reset_list = sdm845_pciephy_reset_l,
.num_resets = ARRAY_SIZE(sdm845_pciephy_reset_l),
@ -3739,6 +3988,8 @@ static const struct qmp_phy_cfg sa8775p_qmp_gen4x2_pciephy_cfg = {
.pcs_num = ARRAY_SIZE(sa8775p_qmp_gen4x2_pcie_pcs_alt_tbl),
.pcs_misc = sa8775p_qmp_gen4_pcie_pcs_misc_tbl,
.pcs_misc_num = ARRAY_SIZE(sa8775p_qmp_gen4_pcie_pcs_misc_tbl),
.pcs_lane1 = sdx65_qmp_pcie_pcs_lane1_tbl,
.pcs_lane1_num = ARRAY_SIZE(sdx65_qmp_pcie_pcs_lane1_tbl),
},
.tbls_rc = &(const struct qmp_phy_cfg_tbls) {
@ -3945,6 +4196,7 @@ static void qmp_pcie_init_registers(struct qmp_pcie *qmp, const struct qmp_phy_c
void __iomem *rx2 = qmp->rx2;
void __iomem *pcs = qmp->pcs;
void __iomem *pcs_misc = qmp->pcs_misc;
void __iomem *pcs_lane1 = qmp->pcs_lane1;
void __iomem *ln_shrd = qmp->ln_shrd;
if (!tbls)
@ -3969,6 +4221,7 @@ static void qmp_pcie_init_registers(struct qmp_pcie *qmp, const struct qmp_phy_c
qmp_configure(qmp->dev, pcs, tbls->pcs, tbls->pcs_num);
qmp_configure(qmp->dev, pcs_misc, tbls->pcs_misc, tbls->pcs_misc_num);
qmp_configure(qmp->dev, pcs_lane1, tbls->pcs_lane1, tbls->pcs_lane1_num);
if (cfg->lanes >= 4 && qmp->tcsr_4ln_config) {
qmp_configure(qmp->dev, serdes, cfg->serdes_4ln_tbl,
@ -4420,6 +4673,14 @@ static int qmp_pcie_parse_dt_legacy(struct qmp_pcie *qmp, struct device_node *np
}
}
/*
* For all platforms where legacy bindings existed, PCS_LANE1 was
* mapped as a part of the PCS_MISC region.
*/
if (!IS_ERR(qmp->pcs_misc) && cfg->offsets->pcs_lane1 != 0)
qmp->pcs_lane1 = qmp->pcs_misc +
(cfg->offsets->pcs_lane1 - cfg->offsets->pcs_misc);
clk = devm_get_clk_from_child(dev, np, NULL);
if (IS_ERR(clk)) {
return dev_err_probe(dev, PTR_ERR(clk),
@ -4487,6 +4748,7 @@ static int qmp_pcie_parse_dt(struct qmp_pcie *qmp)
qmp->serdes = base + offs->serdes;
qmp->pcs = base + offs->pcs;
qmp->pcs_misc = base + offs->pcs_misc;
qmp->pcs_lane1 = base + offs->pcs_lane1;
qmp->tx = base + offs->tx;
qmp->rx = base + offs->rx;
@ -4611,12 +4873,18 @@ static const struct of_device_id qmp_pcie_of_match_table[] = {
}, {
.compatible = "qcom,msm8998-qmp-pcie-phy",
.data = &msm8998_pciephy_cfg,
}, {
.compatible = "qcom,qcs615-qmp-gen3x1-pcie-phy",
.data = &qcs615_pciephy_cfg,
}, {
.compatible = "qcom,sa8775p-qmp-gen4x2-pcie-phy",
.data = &sa8775p_qmp_gen4x2_pciephy_cfg,
}, {
.compatible = "qcom,sa8775p-qmp-gen4x4-pcie-phy",
.data = &sa8775p_qmp_gen4x4_pciephy_cfg,
}, {
.compatible = "qcom,sar2130p-qmp-gen3x2-pcie-phy",
.data = &sar2130p_qmp_gen3x2_pciephy_cfg,
}, {
.compatible = "qcom,sc8180x-qmp-pcie-phy",
.data = &sc8180x_pciephy_cfg,

View File

@ -13,7 +13,8 @@
#define QPHY_V4_20_PCS_PCIE_G4_RXEQEVAL_TIME 0x0f4
#define QPHY_V4_20_PCS_PCIE_G4_EQ_CONFIG2 0x0fc
#define QPHY_V4_20_PCS_PCIE_G4_EQ_CONFIG5 0x108
#define QPHY_V4_20_PCS_LANE1_INSIG_SW_CTRL2 0x824
#define QPHY_V4_20_PCS_LANE1_INSIG_MX_CTRL2 0x828
#define QPHY_V4_20_PCS_LANE1_INSIG_SW_CTRL2 0x024
#define QPHY_V4_20_PCS_LANE1_INSIG_MX_CTRL2 0x028
#endif

View File

@ -17,7 +17,8 @@
#define QPHY_V5_20_PCS_PCIE_G4_EQ_CONFIG5 0x108
#define QPHY_V5_20_PCS_PCIE_G4_PRE_GAIN 0x15c
#define QPHY_V5_20_PCS_PCIE_RX_MARGINING_CONFIG3 0x184
#define QPHY_V5_20_PCS_LANE1_INSIG_SW_CTRL2 0xa24
#define QPHY_V5_20_PCS_LANE1_INSIG_MX_CTRL2 0xa28
#define QPHY_V5_20_PCS_LANE1_INSIG_SW_CTRL2 0x024
#define QPHY_V5_20_PCS_LANE1_INSIG_MX_CTRL2 0x028
#endif

View File

@ -14,4 +14,7 @@
#define QPHY_PCIE_V6_PCS_PCIE_ENDPOINT_REFCLK_DRIVE 0x20
#define QPHY_PCIE_V6_PCS_PCIE_OSC_DTCT_ACTIONS 0x94
#define QPHY_PCIE_V6_PCS_LANE1_INSIG_SW_CTRL2 0x024
#define QPHY_PCIE_V6_PCS_LANE1_INSIG_MX_CTRL2 0x028
#endif

View File

@ -34,6 +34,7 @@
#define QPHY_V2_PCS_USB_PCS_STATUS 0x17c /* USB */
#define QPHY_V2_PCS_PLL_LOCK_CHK_DLY_TIME_AUXCLK_LSB 0x1a8
#define QPHY_V2_PCS_OSC_DTCT_ACTIONS 0x1ac
#define QPHY_V2_PCS_SIGDET_CNTRL 0x1b0
#define QPHY_V2_PCS_RX_SIGDET_LVL 0x1d8
#define QPHY_V2_PCS_L1SS_WAKEUP_DLY_TIME_AUXCLK_LSB 0x1dc
#define QPHY_V2_PCS_L1SS_WAKEUP_DLY_TIME_AUXCLK_MSB 0x1e0

View File

@ -17,6 +17,8 @@
#define QPHY_V6_PCS_LOCK_DETECT_CONFIG3 0x0cc
#define QPHY_V6_PCS_LOCK_DETECT_CONFIG6 0x0d8
#define QPHY_V6_PCS_REFGEN_REQ_CONFIG1 0x0dc
#define QPHY_V6_PCS_G12S1_TXDEEMPH_M6DB 0x168
#define QPHY_V6_PCS_G3S2_PRE_GAIN 0x170
#define QPHY_V6_PCS_RX_SIGDET_LVL 0x188
#define QPHY_V6_PCS_RCVR_DTCT_DLY_P1U2_L 0x190
#define QPHY_V6_PCS_RCVR_DTCT_DLY_P1U2_H 0x194

View File

@ -6,6 +6,7 @@
#ifndef QCOM_PHY_QMP_QSERDES_TXRX_USB_V6_H_
#define QCOM_PHY_QMP_QSERDES_TXRX_USB_V6_H_
#define QSERDES_V6_TX_BIST_MODE_LANENO 0x00
#define QSERDES_V6_TX_CLKBUF_ENABLE 0x08
#define QSERDES_V6_TX_TX_EMP_POST1_LVL 0x0c
#define QSERDES_V6_TX_TX_DRV_LVL 0x14

View File

@ -2298,6 +2298,9 @@ static int qmp_usb_probe(struct platform_device *pdev)
static const struct of_device_id qmp_usb_of_match_table[] = {
{
.compatible = "qcom,ipq5424-qmp-usb3-phy",
.data = &ipq9574_usb3phy_cfg,
}, {
.compatible = "qcom,ipq6018-qmp-usb3-phy",
.data = &ipq6018_usb3phy_cfg,
}, {

View File

@ -151,6 +151,21 @@ static const struct qusb2_phy_init_tbl ipq6018_init_tbl[] = {
QUSB2_PHY_INIT_CFG(QUSB2PHY_PLL_AUTOPGM_CTL1, 0x9F),
};
static const struct qusb2_phy_init_tbl ipq5424_init_tbl[] = {
QUSB2_PHY_INIT_CFG(QUSB2PHY_PLL, 0x14),
QUSB2_PHY_INIT_CFG_L(QUSB2PHY_PORT_TUNE1, 0x00),
QUSB2_PHY_INIT_CFG_L(QUSB2PHY_PORT_TUNE2, 0x53),
QUSB2_PHY_INIT_CFG_L(QUSB2PHY_PORT_TUNE4, 0xc3),
QUSB2_PHY_INIT_CFG(QUSB2PHY_PLL_TUNE, 0x30),
QUSB2_PHY_INIT_CFG(QUSB2PHY_PLL_USER_CTL1, 0x79),
QUSB2_PHY_INIT_CFG(QUSB2PHY_PLL_USER_CTL2, 0x21),
QUSB2_PHY_INIT_CFG_L(QUSB2PHY_PORT_TUNE5, 0x00),
QUSB2_PHY_INIT_CFG(QUSB2PHY_PLL_PWR_CTRL, 0x00),
QUSB2_PHY_INIT_CFG_L(QUSB2PHY_PORT_TEST2, 0x14),
QUSB2_PHY_INIT_CFG(QUSB2PHY_PLL_TEST, 0x80),
QUSB2_PHY_INIT_CFG(QUSB2PHY_PLL_AUTOPGM_CTL1, 0x9f),
};
static const unsigned int ipq6018_regs_layout[] = {
[QUSB2PHY_PLL_STATUS] = 0x38,
[QUSB2PHY_PORT_TUNE1] = 0x80,
@ -331,6 +346,16 @@ static const struct qusb2_phy_cfg ipq6018_phy_cfg = {
.autoresume_en = BIT(0),
};
static const struct qusb2_phy_cfg ipq5424_phy_cfg = {
.tbl = ipq5424_init_tbl,
.tbl_num = ARRAY_SIZE(ipq5424_init_tbl),
.regs = ipq6018_regs_layout,
.disable_ctrl = POWER_DOWN,
.mask_core_ready = PLL_LOCKED,
.autoresume_en = BIT(0),
};
static const struct qusb2_phy_cfg qusb2_v2_phy_cfg = {
.tbl = qusb2_v2_init_tbl,
.tbl_num = ARRAY_SIZE(qusb2_v2_init_tbl),
@ -905,6 +930,9 @@ static const struct phy_ops qusb2_phy_gen_ops = {
static const struct of_device_id qusb2_phy_of_match_table[] = {
{
.compatible = "qcom,ipq5424-qusb2-phy",
.data = &ipq5424_phy_cfg,
}, {
.compatible = "qcom,ipq6018-qusb2-phy",
.data = &ipq6018_phy_cfg,
}, {

View File

@ -37,6 +37,10 @@
#define PHYREG8 0x1C
#define PHYREG8_SSC_EN BIT(4)
#define PHYREG10 0x24
#define PHYREG10_SSC_PCM_MASK GENMASK(3, 0)
#define PHYREG10_SSC_PCM_3500PPM 7
#define PHYREG11 0x28
#define PHYREG11_SU_TRIM_0_7 0xF0
@ -61,17 +65,26 @@
#define PHYREG16 0x3C
#define PHYREG16_SSC_CNT_VALUE 0x5f
#define PHYREG17 0x40
#define PHYREG18 0x44
#define PHYREG18_PLL_LOOP 0x32
#define PHYREG21 0x50
#define PHYREG21_RX_SQUELCH_VAL 0x0D
#define PHYREG27 0x6C
#define PHYREG27_RX_TRIM_RK3588 0x4C
#define PHYREG30 0x74
#define PHYREG32 0x7C
#define PHYREG32_SSC_MASK GENMASK(7, 4)
#define PHYREG32_SSC_DIR_MASK GENMASK(5, 4)
#define PHYREG32_SSC_DIR_SHIFT 4
#define PHYREG32_SSC_UPWARD 0
#define PHYREG32_SSC_DOWNWARD 1
#define PHYREG32_SSC_OFFSET_MASK GENMASK(7, 6)
#define PHYREG32_SSC_OFFSET_SHIFT 6
#define PHYREG32_SSC_OFFSET_500PPM 1
@ -79,6 +92,7 @@
#define PHYREG33_PLL_KVCO_MASK GENMASK(4, 2)
#define PHYREG33_PLL_KVCO_SHIFT 2
#define PHYREG33_PLL_KVCO_VALUE 2
#define PHYREG33_PLL_KVCO_VALUE_RK3576 4
struct rockchip_combphy_priv;
@ -98,6 +112,7 @@ struct rockchip_combphy_grfcfg {
struct combphy_reg pipe_rxterm_set;
struct combphy_reg pipe_txelec_set;
struct combphy_reg pipe_txcomp_set;
struct combphy_reg pipe_clk_24m;
struct combphy_reg pipe_clk_25m;
struct combphy_reg pipe_clk_100m;
struct combphy_reg pipe_phymode_sel;
@ -584,6 +599,266 @@ static const struct rockchip_combphy_cfg rk3568_combphy_cfgs = {
.combphy_cfg = rk3568_combphy_cfg,
};
static int rk3576_combphy_cfg(struct rockchip_combphy_priv *priv)
{
const struct rockchip_combphy_grfcfg *cfg = priv->cfg->grfcfg;
unsigned long rate;
u32 val;
switch (priv->type) {
case PHY_TYPE_PCIE:
/* Set SSC downward spread spectrum */
val = FIELD_PREP(PHYREG32_SSC_MASK, PHYREG32_SSC_DOWNWARD);
rockchip_combphy_updatel(priv, PHYREG32_SSC_MASK, val, PHYREG32);
rockchip_combphy_param_write(priv->phy_grf, &cfg->con0_for_pcie, true);
rockchip_combphy_param_write(priv->phy_grf, &cfg->con1_for_pcie, true);
rockchip_combphy_param_write(priv->phy_grf, &cfg->con2_for_pcie, true);
rockchip_combphy_param_write(priv->phy_grf, &cfg->con3_for_pcie, true);
break;
case PHY_TYPE_USB3:
/* Set SSC downward spread spectrum */
val = FIELD_PREP(PHYREG32_SSC_MASK, PHYREG32_SSC_DOWNWARD);
rockchip_combphy_updatel(priv, PHYREG32_SSC_MASK, val, PHYREG32);
/* Enable adaptive CTLE for USB3.0 Rx */
val = readl(priv->mmio + PHYREG15);
val |= PHYREG15_CTLE_EN;
writel(val, priv->mmio + PHYREG15);
/* Set PLL KVCO fine tuning signals */
rockchip_combphy_updatel(priv, PHYREG33_PLL_KVCO_MASK, BIT(3), PHYREG33);
/* Set PLL LPF R1 to su_trim[10:7]=1001 */
writel(PHYREG12_PLL_LPF_ADJ_VALUE, priv->mmio + PHYREG12);
/* Set PLL input clock divider 1/2 */
val = FIELD_PREP(PHYREG6_PLL_DIV_MASK, PHYREG6_PLL_DIV_2);
rockchip_combphy_updatel(priv, PHYREG6_PLL_DIV_MASK, val, PHYREG6);
/* Set PLL loop divider */
writel(PHYREG18_PLL_LOOP, priv->mmio + PHYREG18);
/* Set PLL KVCO to min and set PLL charge pump current to max */
writel(PHYREG11_SU_TRIM_0_7, priv->mmio + PHYREG11);
/* Set Rx squelch input filler bandwidth */
writel(PHYREG21_RX_SQUELCH_VAL, priv->mmio + PHYREG21);
rockchip_combphy_param_write(priv->phy_grf, &cfg->pipe_txcomp_sel, false);
rockchip_combphy_param_write(priv->phy_grf, &cfg->pipe_txelec_sel, false);
rockchip_combphy_param_write(priv->phy_grf, &cfg->usb_mode_set, true);
break;
case PHY_TYPE_SATA:
/* Enable adaptive CTLE for SATA Rx */
val = readl(priv->mmio + PHYREG15);
val |= PHYREG15_CTLE_EN;
writel(val, priv->mmio + PHYREG15);
/* Set tx_rterm = 50 ohm and rx_rterm = 43.5 ohm */
val = PHYREG7_TX_RTERM_50OHM << PHYREG7_TX_RTERM_SHIFT;
val |= PHYREG7_RX_RTERM_44OHM << PHYREG7_RX_RTERM_SHIFT;
writel(val, priv->mmio + PHYREG7);
rockchip_combphy_param_write(priv->phy_grf, &cfg->con0_for_sata, true);
rockchip_combphy_param_write(priv->phy_grf, &cfg->con1_for_sata, true);
rockchip_combphy_param_write(priv->phy_grf, &cfg->con2_for_sata, true);
rockchip_combphy_param_write(priv->phy_grf, &cfg->con3_for_sata, true);
rockchip_combphy_param_write(priv->pipe_grf, &cfg->pipe_con0_for_sata, true);
rockchip_combphy_param_write(priv->pipe_grf, &cfg->pipe_con1_for_sata, true);
break;
default:
dev_err(priv->dev, "incompatible PHY type\n");
return -EINVAL;
}
rate = clk_get_rate(priv->refclk);
switch (rate) {
case REF_CLOCK_24MHz:
rockchip_combphy_param_write(priv->phy_grf, &cfg->pipe_clk_24m, true);
if (priv->type == PHY_TYPE_USB3 || priv->type == PHY_TYPE_SATA) {
/* Set ssc_cnt[9:0]=0101111101 & 31.5KHz */
val = FIELD_PREP(PHYREG15_SSC_CNT_MASK, PHYREG15_SSC_CNT_VALUE);
rockchip_combphy_updatel(priv, PHYREG15_SSC_CNT_MASK,
val, PHYREG15);
writel(PHYREG16_SSC_CNT_VALUE, priv->mmio + PHYREG16);
} else if (priv->type == PHY_TYPE_PCIE) {
/* PLL KVCO tuning fine */
val = FIELD_PREP(PHYREG33_PLL_KVCO_MASK, PHYREG33_PLL_KVCO_VALUE_RK3576);
rockchip_combphy_updatel(priv, PHYREG33_PLL_KVCO_MASK,
val, PHYREG33);
/* Set up rx_pck invert and rx msb to disable */
writel(0x00, priv->mmio + PHYREG27);
/*
* Set up SU adjust signal:
* su_trim[7:0], PLL KVCO adjust bits[2:0] to min
* su_trim[15:8], PLL LPF R1 adujst bits[9:7]=3'b011
* su_trim[31:24], CKDRV adjust
*/
writel(0x90, priv->mmio + PHYREG11);
writel(0x02, priv->mmio + PHYREG12);
writel(0x57, priv->mmio + PHYREG14);
writel(PHYREG16_SSC_CNT_VALUE, priv->mmio + PHYREG16);
}
break;
case REF_CLOCK_25MHz:
rockchip_combphy_param_write(priv->phy_grf, &cfg->pipe_clk_25m, true);
break;
case REF_CLOCK_100MHz:
rockchip_combphy_param_write(priv->phy_grf, &cfg->pipe_clk_100m, true);
if (priv->type == PHY_TYPE_PCIE) {
/* gate_tx_pck_sel length select work for L1SS */
writel(0xc0, priv->mmio + PHYREG30);
/* PLL KVCO tuning fine */
val = FIELD_PREP(PHYREG33_PLL_KVCO_MASK, PHYREG33_PLL_KVCO_VALUE_RK3576);
rockchip_combphy_updatel(priv, PHYREG33_PLL_KVCO_MASK,
val, PHYREG33);
/* Set up rx_trim: PLL LPF C1 85pf R1 1.25kohm */
writel(0x4c, priv->mmio + PHYREG27);
/*
* Set up SU adjust signal:
* su_trim[7:0], PLL KVCO adjust bits[2:0] to min
* su_trim[15:8], bypass PLL loop divider code, and
* PLL LPF R1 adujst bits[9:7]=3'b101
* su_trim[23:16], CKRCV adjust
* su_trim[31:24], CKDRV adjust
*/
writel(0x90, priv->mmio + PHYREG11);
writel(0x43, priv->mmio + PHYREG12);
writel(0x88, priv->mmio + PHYREG13);
writel(0x56, priv->mmio + PHYREG14);
} else if (priv->type == PHY_TYPE_SATA) {
/* downward spread spectrum +500ppm */
val = FIELD_PREP(PHYREG32_SSC_DIR_MASK, PHYREG32_SSC_DOWNWARD);
val |= FIELD_PREP(PHYREG32_SSC_OFFSET_MASK, PHYREG32_SSC_OFFSET_500PPM);
rockchip_combphy_updatel(priv, PHYREG32_SSC_MASK, val, PHYREG32);
/* ssc ppm adjust to 3500ppm */
rockchip_combphy_updatel(priv, PHYREG10_SSC_PCM_MASK,
PHYREG10_SSC_PCM_3500PPM,
PHYREG10);
}
break;
default:
dev_err(priv->dev, "Unsupported rate: %lu\n", rate);
return -EINVAL;
}
if (priv->ext_refclk) {
rockchip_combphy_param_write(priv->phy_grf, &cfg->pipe_clk_ext, true);
if (priv->type == PHY_TYPE_PCIE && rate == REF_CLOCK_100MHz) {
val = FIELD_PREP(PHYREG33_PLL_KVCO_MASK, PHYREG33_PLL_KVCO_VALUE_RK3576);
rockchip_combphy_updatel(priv, PHYREG33_PLL_KVCO_MASK,
val, PHYREG33);
/* Set up rx_trim: PLL LPF C1 85pf R1 2.5kohm */
writel(0x0c, priv->mmio + PHYREG27);
/*
* Set up SU adjust signal:
* su_trim[7:0], PLL KVCO adjust bits[2:0] to min
* su_trim[15:8], bypass PLL loop divider code, and
* PLL LPF R1 adujst bits[9:7]=3'b101.
* su_trim[23:16], CKRCV adjust
* su_trim[31:24], CKDRV adjust
*/
writel(0x90, priv->mmio + PHYREG11);
writel(0x43, priv->mmio + PHYREG12);
writel(0x88, priv->mmio + PHYREG13);
writel(0x56, priv->mmio + PHYREG14);
}
}
if (priv->enable_ssc) {
val = readl(priv->mmio + PHYREG8);
val |= PHYREG8_SSC_EN;
writel(val, priv->mmio + PHYREG8);
if (priv->type == PHY_TYPE_PCIE && rate == REF_CLOCK_24MHz) {
/* Set PLL loop divider */
writel(0x00, priv->mmio + PHYREG17);
writel(PHYREG18_PLL_LOOP, priv->mmio + PHYREG18);
/* Set up rx_pck invert and rx msb to disable */
writel(0x00, priv->mmio + PHYREG27);
/*
* Set up SU adjust signal:
* su_trim[7:0], PLL KVCO adjust bits[2:0] to min
* su_trim[15:8], PLL LPF R1 adujst bits[9:7]=3'b101
* su_trim[23:16], CKRCV adjust
* su_trim[31:24], CKDRV adjust
*/
writel(0x90, priv->mmio + PHYREG11);
writel(0x02, priv->mmio + PHYREG12);
writel(0x08, priv->mmio + PHYREG13);
writel(0x57, priv->mmio + PHYREG14);
writel(0x40, priv->mmio + PHYREG15);
writel(PHYREG16_SSC_CNT_VALUE, priv->mmio + PHYREG16);
val = FIELD_PREP(PHYREG33_PLL_KVCO_MASK, PHYREG33_PLL_KVCO_VALUE_RK3576);
writel(val, priv->mmio + PHYREG33);
}
}
return 0;
}
static const struct rockchip_combphy_grfcfg rk3576_combphy_grfcfgs = {
/* pipe-phy-grf */
.pcie_mode_set = { 0x0000, 5, 0, 0x00, 0x11 },
.usb_mode_set = { 0x0000, 5, 0, 0x00, 0x04 },
.pipe_rxterm_set = { 0x0000, 12, 12, 0x00, 0x01 },
.pipe_txelec_set = { 0x0004, 1, 1, 0x00, 0x01 },
.pipe_txcomp_set = { 0x0004, 4, 4, 0x00, 0x01 },
.pipe_clk_24m = { 0x0004, 14, 13, 0x00, 0x00 },
.pipe_clk_25m = { 0x0004, 14, 13, 0x00, 0x01 },
.pipe_clk_100m = { 0x0004, 14, 13, 0x00, 0x02 },
.pipe_phymode_sel = { 0x0008, 1, 1, 0x00, 0x01 },
.pipe_rate_sel = { 0x0008, 2, 2, 0x00, 0x01 },
.pipe_rxterm_sel = { 0x0008, 8, 8, 0x00, 0x01 },
.pipe_txelec_sel = { 0x0008, 12, 12, 0x00, 0x01 },
.pipe_txcomp_sel = { 0x0008, 15, 15, 0x00, 0x01 },
.pipe_clk_ext = { 0x000c, 9, 8, 0x02, 0x01 },
.pipe_phy_status = { 0x0034, 6, 6, 0x01, 0x00 },
.con0_for_pcie = { 0x0000, 15, 0, 0x00, 0x1000 },
.con1_for_pcie = { 0x0004, 15, 0, 0x00, 0x0000 },
.con2_for_pcie = { 0x0008, 15, 0, 0x00, 0x0101 },
.con3_for_pcie = { 0x000c, 15, 0, 0x00, 0x0200 },
.con0_for_sata = { 0x0000, 15, 0, 0x00, 0x0129 },
.con1_for_sata = { 0x0004, 15, 0, 0x00, 0x0000 },
.con2_for_sata = { 0x0008, 15, 0, 0x00, 0x80c1 },
.con3_for_sata = { 0x000c, 15, 0, 0x00, 0x0407 },
/* php-grf */
.pipe_con0_for_sata = { 0x001C, 2, 0, 0x00, 0x2 },
.pipe_con1_for_sata = { 0x0020, 2, 0, 0x00, 0x2 },
};
static const struct rockchip_combphy_cfg rk3576_combphy_cfgs = {
.num_phys = 2,
.phy_ids = {
0x2b050000,
0x2b060000
},
.grfcfg = &rk3576_combphy_grfcfgs,
.combphy_cfg = rk3576_combphy_cfg,
};
static int rk3588_combphy_cfg(struct rockchip_combphy_priv *priv)
{
const struct rockchip_combphy_grfcfg *cfg = priv->cfg->grfcfg;
@ -775,6 +1050,10 @@ static const struct of_device_id rockchip_combphy_of_match[] = {
.compatible = "rockchip,rk3568-naneng-combphy",
.data = &rk3568_combphy_cfgs,
},
{
.compatible = "rockchip,rk3576-naneng-combphy",
.data = &rk3576_combphy_cfgs,
},
{
.compatible = "rockchip,rk3588-naneng-combphy",
.data = &rk3588_combphy_cfgs,

View File

@ -124,7 +124,7 @@ static int rockchip_pcie_phy_power_off(struct phy *phy)
struct rockchip_pcie_phy *rk_phy = to_pcie_phy(inst);
int err = 0;
mutex_lock(&rk_phy->pcie_mutex);
guard(mutex)(&rk_phy->pcie_mutex);
regmap_write(rk_phy->reg_base,
rk_phy->phy_data->pcie_laneoff,
@ -132,27 +132,22 @@ static int rockchip_pcie_phy_power_off(struct phy *phy)
PHY_LANE_IDLE_MASK,
PHY_LANE_IDLE_A_SHIFT + inst->index));
if (--rk_phy->pwr_cnt)
goto err_out;
if (--rk_phy->pwr_cnt) {
return 0;
}
err = reset_control_assert(rk_phy->phy_rst);
if (err) {
dev_err(&phy->dev, "assert phy_rst err %d\n", err);
goto err_restore;
rk_phy->pwr_cnt++;
regmap_write(rk_phy->reg_base,
rk_phy->phy_data->pcie_laneoff,
HIWORD_UPDATE(!PHY_LANE_IDLE_OFF,
PHY_LANE_IDLE_MASK,
PHY_LANE_IDLE_A_SHIFT + inst->index));
return err;
}
err_out:
mutex_unlock(&rk_phy->pcie_mutex);
return 0;
err_restore:
rk_phy->pwr_cnt++;
regmap_write(rk_phy->reg_base,
rk_phy->phy_data->pcie_laneoff,
HIWORD_UPDATE(!PHY_LANE_IDLE_OFF,
PHY_LANE_IDLE_MASK,
PHY_LANE_IDLE_A_SHIFT + inst->index));
mutex_unlock(&rk_phy->pcie_mutex);
return err;
}
@ -162,17 +157,18 @@ static int rockchip_pcie_phy_power_on(struct phy *phy)
struct rockchip_pcie_phy *rk_phy = to_pcie_phy(inst);
int err = 0;
u32 status;
unsigned long timeout;
mutex_lock(&rk_phy->pcie_mutex);
guard(mutex)(&rk_phy->pcie_mutex);
if (rk_phy->pwr_cnt++)
goto err_out;
if (rk_phy->pwr_cnt++) {
return 0;
}
err = reset_control_deassert(rk_phy->phy_rst);
if (err) {
dev_err(&phy->dev, "deassert phy_rst err %d\n", err);
goto err_pwr_cnt;
rk_phy->pwr_cnt--;
return err;
}
regmap_write(rk_phy->reg_base, rk_phy->phy_data->pcie_conf,
@ -191,21 +187,11 @@ static int rockchip_pcie_phy_power_on(struct phy *phy)
* so we make it large enough here. And we use loop-break
* method which should not be harmful.
*/
timeout = jiffies + msecs_to_jiffies(1000);
err = -EINVAL;
while (time_before(jiffies, timeout)) {
regmap_read(rk_phy->reg_base,
rk_phy->phy_data->pcie_status,
&status);
if (status & PHY_PLL_LOCKED) {
dev_dbg(&phy->dev, "pll locked!\n");
err = 0;
break;
}
msleep(20);
}
err = regmap_read_poll_timeout(rk_phy->reg_base,
rk_phy->phy_data->pcie_status,
status,
status & PHY_PLL_LOCKED,
200, 100000);
if (err) {
dev_err(&phy->dev, "pll lock timeout!\n");
goto err_pll_lock;
@ -214,19 +200,11 @@ static int rockchip_pcie_phy_power_on(struct phy *phy)
phy_wr_cfg(rk_phy, PHY_CFG_CLK_TEST, PHY_CFG_SEPE_RATE);
phy_wr_cfg(rk_phy, PHY_CFG_CLK_SCC, PHY_CFG_PLL_100M);
err = -ETIMEDOUT;
while (time_before(jiffies, timeout)) {
regmap_read(rk_phy->reg_base,
rk_phy->phy_data->pcie_status,
&status);
if (!(status & PHY_PLL_OUTPUT)) {
dev_dbg(&phy->dev, "pll output enable done!\n");
err = 0;
break;
}
msleep(20);
}
err = regmap_read_poll_timeout(rk_phy->reg_base,
rk_phy->phy_data->pcie_status,
status,
!(status & PHY_PLL_OUTPUT),
200, 100000);
if (err) {
dev_err(&phy->dev, "pll output enable timeout!\n");
goto err_pll_lock;
@ -236,33 +214,22 @@ static int rockchip_pcie_phy_power_on(struct phy *phy)
HIWORD_UPDATE(PHY_CFG_PLL_LOCK,
PHY_CFG_ADDR_MASK,
PHY_CFG_ADDR_SHIFT));
err = -EINVAL;
while (time_before(jiffies, timeout)) {
regmap_read(rk_phy->reg_base,
rk_phy->phy_data->pcie_status,
&status);
if (status & PHY_PLL_LOCKED) {
dev_dbg(&phy->dev, "pll relocked!\n");
err = 0;
break;
}
msleep(20);
}
err = regmap_read_poll_timeout(rk_phy->reg_base,
rk_phy->phy_data->pcie_status,
status,
status & PHY_PLL_LOCKED,
200, 100000);
if (err) {
dev_err(&phy->dev, "pll relock timeout!\n");
goto err_pll_lock;
}
err_out:
mutex_unlock(&rk_phy->pcie_mutex);
return 0;
return err;
err_pll_lock:
reset_control_assert(rk_phy->phy_rst);
err_pwr_cnt:
rk_phy->pwr_cnt--;
mutex_unlock(&rk_phy->pcie_mutex);
return err;
}
@ -272,33 +239,19 @@ static int rockchip_pcie_phy_init(struct phy *phy)
struct rockchip_pcie_phy *rk_phy = to_pcie_phy(inst);
int err = 0;
mutex_lock(&rk_phy->pcie_mutex);
guard(mutex)(&rk_phy->pcie_mutex);
if (rk_phy->init_cnt++)
goto err_out;
err = clk_prepare_enable(rk_phy->clk_pciephy_ref);
if (err) {
dev_err(&phy->dev, "Fail to enable pcie ref clock.\n");
goto err_refclk;
if (rk_phy->init_cnt++) {
return 0;
}
err = reset_control_assert(rk_phy->phy_rst);
if (err) {
dev_err(&phy->dev, "assert phy_rst err %d\n", err);
goto err_reset;
rk_phy->init_cnt--;
return err;
}
err_out:
mutex_unlock(&rk_phy->pcie_mutex);
return 0;
err_reset:
clk_disable_unprepare(rk_phy->clk_pciephy_ref);
err_refclk:
rk_phy->init_cnt--;
mutex_unlock(&rk_phy->pcie_mutex);
return err;
}
@ -307,15 +260,12 @@ static int rockchip_pcie_phy_exit(struct phy *phy)
struct phy_pcie_instance *inst = phy_get_drvdata(phy);
struct rockchip_pcie_phy *rk_phy = to_pcie_phy(inst);
mutex_lock(&rk_phy->pcie_mutex);
guard(mutex)(&rk_phy->pcie_mutex);
if (--rk_phy->init_cnt)
goto err_init_cnt;
clk_disable_unprepare(rk_phy->clk_pciephy_ref);
err_init_cnt:
mutex_unlock(&rk_phy->pcie_mutex);
return 0;
}
@ -371,18 +321,14 @@ static int rockchip_pcie_phy_probe(struct platform_device *pdev)
mutex_init(&rk_phy->pcie_mutex);
rk_phy->phy_rst = devm_reset_control_get(dev, "phy");
if (IS_ERR(rk_phy->phy_rst)) {
if (PTR_ERR(rk_phy->phy_rst) != -EPROBE_DEFER)
dev_err(dev,
"missing phy property for reset controller\n");
return PTR_ERR(rk_phy->phy_rst);
}
if (IS_ERR(rk_phy->phy_rst))
return dev_err_probe(&pdev->dev, PTR_ERR(rk_phy->phy_rst),
"missing phy property for reset controller\n");
rk_phy->clk_pciephy_ref = devm_clk_get(dev, "refclk");
if (IS_ERR(rk_phy->clk_pciephy_ref)) {
dev_err(dev, "refclk not found.\n");
return PTR_ERR(rk_phy->clk_pciephy_ref);
}
rk_phy->clk_pciephy_ref = devm_clk_get_enabled(dev, "refclk");
if (IS_ERR(rk_phy->clk_pciephy_ref))
return dev_err_probe(&pdev->dev, PTR_ERR(rk_phy->clk_pciephy_ref),
"failed to get phyclk\n");
/* parse #phy-cells to see if it's legacy PHY model */
if (of_property_read_u32(dev->of_node, "#phy-cells", &phy_num))

View File

@ -33,6 +33,7 @@ config PHY_SAMSUNG_UFS
tristate "Exynos SoC series UFS PHY driver"
depends on OF && (ARCH_EXYNOS || COMPILE_TEST)
select GENERIC_PHY
select MFD_SYSCON
help
Enable this to support the Samsung Exynos SoC UFS PHY driver for
Samsung Exynos SoCs. This driver provides the interface for UFS host

View File

@ -13,11 +13,11 @@
#include <linux/of.h>
#include <linux/io.h>
#include <linux/iopoll.h>
#include <linux/mfd/syscon.h>
#include <linux/module.h>
#include <linux/phy/phy.h>
#include <linux/platform_device.h>
#include <linux/regmap.h>
#include <linux/soc/samsung/exynos-pmu.h>
#include "phy-samsung-ufs.h"
@ -268,8 +268,8 @@ static int samsung_ufs_phy_probe(struct platform_device *pdev)
goto out;
}
phy->reg_pmu = exynos_get_pmu_regmap_by_phandle(dev->of_node,
"samsung,pmu-syscon");
phy->reg_pmu = syscon_regmap_lookup_by_phandle(dev->of_node,
"samsung,pmu-syscon");
if (IS_ERR(phy->reg_pmu)) {
err = PTR_ERR(phy->reg_pmu);
dev_err(dev, "failed syscon remap for pmu\n");

View File

@ -13,7 +13,8 @@ config PHY_TEGRA_XUSB
config PHY_TEGRA194_P2U
tristate "NVIDIA Tegra194 PIPE2UPHY PHY driver"
depends on ARCH_TEGRA_194_SOC || COMPILE_TEST
depends on ARCH_TEGRA_194_SOC || ARCH_TEGRA_234_SOC || COMPILE_TEST
select GENERIC_PHY
help
Enable this to support the P2U (PIPE to UPHY) that is part of Tegra 19x SOCs.
Enable this to support the P2U (PIPE to UPHY) that is part of Tegra 19x
and 234 SOCs.