diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2023-05-03 11:17:34 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2023-05-03 11:17:34 -0700 |
commit | 54bdf8a39931cf8fe2c74432e715353d9a1c1107 (patch) | |
tree | 8d77f0f072ca80baeab464c623134d93dd76d9c8 /drivers/phy | |
parent | 7994beabfbb9a15c069eba7833a00f5ff4da1172 (diff) | |
parent | a0106132372120dd0abf5ad7636614e5aeb5da08 (diff) |
Merge tag 'phy-for-6.4' of git://git.kernel.org/pub/scm/linux/kernel/git/phy/linux-phy
Pull phy updates from Vinod Koul:
"New support:
- UFS PHY for Qualcomm SA8775p, SM7150
- PCIe 2 lane phy support for sc8180x and PCIe PHY for SDX65
- Mediatke hdmi phy support for mt8195
- rockchip naneng combo phy support for RK358
Updates:
- Drop Thunder Bay eMMC PHY driver
- RC support for PCIe phy for Qualcomm SDX55
- SGMII support in WIZ driver for J721E
- PCIe and multilink SGMII PHY support in cadence driver
- Big pile of platform remove callback returning void conversions"
* tag 'phy-for-6.4' of git://git.kernel.org/pub/scm/linux/kernel/git/phy/linux-phy: (77 commits)
phy: cadence: cdns-dphy-rx: Add common module reset support
phy: ti: j721e-wiz: Add SGMII support in WIZ driver for J721E
dt-bindings: phy: ti: phy-gmii-sel: Add support for J784S4 CPSW9G
phy: ti: j721e-wiz: Fix unreachable code in wiz_mode_select()
phy: cadence: Sierra: Add PCIe + SGMII PHY multilink configuration
phy: mediatek: add support for phy-mtk-hdmi-mt8195
phy: phy-mtk-hdmi: Add generic phy configure callback
dt-bindings: phy: mediatek: hdmi-phy: Add mt8195 compatible
phy: tegra: xusb: Add missing tegra_xusb_port_unregister for usb2_port and ulpi_port
dt-bindings: phy: ti,phy-j721e-wiz: document clock-output-names
dt-bindings: phy: ti,phy-j721e-wiz: drop assigned-clocks
dt-bindings: phy: ti,phy-am654-serdes: drop assigned-clocks type
dt-bindings: phy: cadence-torrent: drop assigned-clocks
dt-bindings: phy: cadence-sierra: drop assigned-clocks
phy: rockchip: remove unused hw_to_inno function
phy: qualcomm: phy-qcom-qmp-ufs: add definitions for sa8775p
dt-bindings: phy: qmp-ufs: describe the UFS PHY for sa8775p
phy: qcom-qmp-pcie: drop sdm845_qhp_pcie_rx_tbl
phy: qcom-qmp-pcie: sc8180x PCIe PHY has 2 lanes
phy: qcom-qmp-ufs: Add SM7150 support
...
Diffstat (limited to 'drivers/phy')
60 files changed, 1514 insertions, 821 deletions
diff --git a/drivers/phy/Kconfig b/drivers/phy/Kconfig index 7bd00a11d074..f46e3148d286 100644 --- a/drivers/phy/Kconfig +++ b/drivers/phy/Kconfig @@ -44,7 +44,7 @@ config PHY_PISTACHIO_USB config PHY_XGENE tristate "APM X-Gene 15Gbps PHY support" - depends on HAS_IOMEM && OF && (ARM64 || COMPILE_TEST) + depends on HAS_IOMEM && OF && (ARCH_XGENE || COMPILE_TEST) select GENERIC_PHY help This option enables support for APM X-Gene SoC multi-purpose PHY. diff --git a/drivers/phy/allwinner/phy-sun4i-usb.c b/drivers/phy/allwinner/phy-sun4i-usb.c index fbcd7014ab43..56d53f78d002 100644 --- a/drivers/phy/allwinner/phy-sun4i-usb.c +++ b/drivers/phy/allwinner/phy-sun4i-usb.c @@ -698,7 +698,7 @@ static struct phy *sun4i_usb_phy_xlate(struct device *dev, return data->phys[args->args[0]].phy; } -static int sun4i_usb_phy_remove(struct platform_device *pdev) +static void sun4i_usb_phy_remove(struct platform_device *pdev) { struct device *dev = &pdev->dev; struct sun4i_usb_phy_data *data = dev_get_drvdata(dev); @@ -711,8 +711,6 @@ static int sun4i_usb_phy_remove(struct platform_device *pdev) devm_free_irq(dev, data->vbus_det_irq, data); cancel_delayed_work_sync(&data->detect); - - return 0; } static const unsigned int sun4i_usb_phy0_cable[] = { @@ -758,7 +756,7 @@ static int sun4i_usb_phy_probe(struct platform_device *pdev) return PTR_ERR(data->vbus_det_gpio); } - if (of_find_property(np, "usb0_vbus_power-supply", NULL)) { + if (of_property_present(np, "usb0_vbus_power-supply")) { data->vbus_power_supply = devm_power_supply_get_by_phandle(dev, "usb0_vbus_power-supply"); if (IS_ERR(data->vbus_power_supply)) { @@ -1054,7 +1052,7 @@ MODULE_DEVICE_TABLE(of, sun4i_usb_phy_of_match); static struct platform_driver sun4i_usb_phy_driver = { .probe = sun4i_usb_phy_probe, - .remove = sun4i_usb_phy_remove, + .remove_new = sun4i_usb_phy_remove, .driver = { .of_match_table = sun4i_usb_phy_of_match, .name = "sun4i-usb-phy", diff --git a/drivers/phy/amlogic/phy-meson-axg-mipi-dphy.c b/drivers/phy/amlogic/phy-meson-axg-mipi-dphy.c index 32d1ff09befb..6e9af79e152c 100644 --- a/drivers/phy/amlogic/phy-meson-axg-mipi-dphy.c +++ b/drivers/phy/amlogic/phy-meson-axg-mipi-dphy.c @@ -335,7 +335,6 @@ static int phy_meson_axg_mipi_dphy_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; struct phy_provider *phy_provider; - struct resource *res; struct phy_meson_axg_mipi_dphy_priv *priv; struct phy *phy; void __iomem *base; @@ -348,8 +347,7 @@ static int phy_meson_axg_mipi_dphy_probe(struct platform_device *pdev) priv->dev = dev; platform_set_drvdata(pdev, priv); - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - base = devm_ioremap_resource(dev, res); + base = devm_platform_ioremap_resource(pdev, 0); if (IS_ERR(base)) return PTR_ERR(base); diff --git a/drivers/phy/broadcom/phy-bcm-ns-usb2.c b/drivers/phy/broadcom/phy-bcm-ns-usb2.c index 6a36e187d100..269564bdf687 100644 --- a/drivers/phy/broadcom/phy-bcm-ns-usb2.c +++ b/drivers/phy/broadcom/phy-bcm-ns-usb2.c @@ -107,7 +107,7 @@ static int bcm_ns_usb2_probe(struct platform_device *pdev) return -ENOMEM; usb2->dev = dev; - if (of_find_property(dev->of_node, "brcm,syscon-clkset", NULL)) { + if (of_property_present(dev->of_node, "brcm,syscon-clkset")) { usb2->base = devm_platform_ioremap_resource(pdev, 0); if (IS_ERR(usb2->base)) { dev_err(dev, "Failed to map control reg\n"); diff --git a/drivers/phy/broadcom/phy-brcm-usb.c b/drivers/phy/broadcom/phy-brcm-usb.c index 4de39999f43d..a4cfb777dd83 100644 --- a/drivers/phy/broadcom/phy-brcm-usb.c +++ b/drivers/phy/broadcom/phy-brcm-usb.c @@ -572,14 +572,12 @@ static int brcm_usb_phy_probe(struct platform_device *pdev) return PTR_ERR_OR_ZERO(phy_provider); } -static int brcm_usb_phy_remove(struct platform_device *pdev) +static void brcm_usb_phy_remove(struct platform_device *pdev) { struct brcm_usb_phy_data *priv = dev_get_drvdata(&pdev->dev); sysfs_remove_group(&pdev->dev.kobj, &brcm_usb_phy_group); unregister_pm_notifier(&priv->pm_notifier); - - return 0; } #ifdef CONFIG_PM_SLEEP @@ -670,7 +668,7 @@ MODULE_DEVICE_TABLE(of, brcm_usb_dt_ids); static struct platform_driver brcm_usb_driver = { .probe = brcm_usb_phy_probe, - .remove = brcm_usb_phy_remove, + .remove_new = brcm_usb_phy_remove, .driver = { .name = "brcmstb-usb-phy", .pm = &brcm_usb_phy_pm_ops, diff --git a/drivers/phy/cadence/cdns-dphy-rx.c b/drivers/phy/cadence/cdns-dphy-rx.c index 572c70089a94..c05b043893a9 100644 --- a/drivers/phy/cadence/cdns-dphy-rx.c +++ b/drivers/phy/cadence/cdns-dphy-rx.c @@ -11,10 +11,12 @@ #include <linux/phy/phy.h> #include <linux/phy/phy-mipi-dphy.h> #include <linux/platform_device.h> +#include <linux/sys_soc.h> #define DPHY_PMA_CMN(reg) (reg) #define DPHY_PCS(reg) (0xb00 + (reg)) #define DPHY_ISO(reg) (0xc00 + (reg)) +#define DPHY_WRAP(reg) (0x1000 + (reg)) #define DPHY_CMN_SSM DPHY_PMA_CMN(0x20) #define DPHY_CMN_RX_MODE_EN BIT(10) @@ -33,6 +35,9 @@ #define DPHY_POWER_ISLAND_EN_CLK DPHY_PCS(0xc) #define DPHY_POWER_ISLAND_EN_CLK_VAL 0xaa +#define DPHY_LANE DPHY_WRAP(0x0) +#define DPHY_LANE_RESET_CMN_EN BIT(23) + #define DPHY_ISO_CL_CTRL_L DPHY_ISO(0x10) #define DPHY_ISO_DL_CTRL_L0 DPHY_ISO(0x14) #define DPHY_ISO_DL_CTRL_L1 DPHY_ISO(0x20) @@ -57,6 +62,10 @@ struct cdns_dphy_rx_band { unsigned int max_rate; }; +struct cdns_dphy_soc_data { + bool has_hw_cmn_rstb; +}; + /* Order of bands is important since the index is the band number. */ static const struct cdns_dphy_rx_band bands[] = { { 80, 100 }, { 100, 120 }, { 120, 160 }, { 160, 200 }, { 200, 240 }, @@ -142,13 +151,36 @@ static int cdns_dphy_rx_wait_lane_ready(struct cdns_dphy_rx *dphy, return 0; } +static struct cdns_dphy_soc_data j721e_soc_data = { + .has_hw_cmn_rstb = true, +}; + +static const struct soc_device_attribute cdns_dphy_socinfo[] = { + { + .family = "J721E", + .revision = "SR1.0", + .data = &j721e_soc_data, + }, + {/* sentinel */} +}; + static int cdns_dphy_rx_configure(struct phy *phy, union phy_configure_opts *opts) { struct cdns_dphy_rx *dphy = phy_get_drvdata(phy); unsigned int reg, lanes = opts->mipi_dphy.lanes; + const struct cdns_dphy_soc_data *soc_data = NULL; + const struct soc_device_attribute *soc; int band_ctrl, ret; + soc = soc_device_match(cdns_dphy_socinfo); + if (soc && soc->data) + soc_data = soc->data; + if (!soc || (soc_data && !soc_data->has_hw_cmn_rstb)) { + reg = DPHY_LANE_RESET_CMN_EN; + writel(reg, dphy->regs + DPHY_LANE); + } + /* Data lanes. Minimum one lane is mandatory. */ if (lanes < DPHY_LANES_MIN || lanes > DPHY_LANES_MAX) return -EINVAL; diff --git a/drivers/phy/cadence/cdns-dphy.c b/drivers/phy/cadence/cdns-dphy.c index 3dfdfb33cd0a..6e58012b6488 100644 --- a/drivers/phy/cadence/cdns-dphy.c +++ b/drivers/phy/cadence/cdns-dphy.c @@ -456,14 +456,12 @@ static int cdns_dphy_probe(struct platform_device *pdev) return PTR_ERR_OR_ZERO(phy_provider); } -static int cdns_dphy_remove(struct platform_device *pdev) +static void cdns_dphy_remove(struct platform_device *pdev) { struct cdns_dphy *dphy = dev_get_drvdata(&pdev->dev); if (dphy->ops->remove) dphy->ops->remove(dphy); - - return 0; } static const struct of_device_id cdns_dphy_of_match[] = { @@ -475,7 +473,7 @@ MODULE_DEVICE_TABLE(of, cdns_dphy_of_match); static struct platform_driver cdns_dphy_platform_driver = { .probe = cdns_dphy_probe, - .remove = cdns_dphy_remove, + .remove_new = cdns_dphy_remove, .driver = { .name = "cdns-mipi-dphy", .of_match_table = cdns_dphy_of_match, diff --git a/drivers/phy/cadence/phy-cadence-sierra.c b/drivers/phy/cadence/phy-cadence-sierra.c index 6e86a6517f37..13fcd3a65fe9 100644 --- a/drivers/phy/cadence/phy-cadence-sierra.c +++ b/drivers/phy/cadence/phy-cadence-sierra.c @@ -24,7 +24,7 @@ #include <dt-bindings/phy/phy-cadence.h> #define NUM_SSC_MODE 3 -#define NUM_PHY_TYPE 4 +#define NUM_PHY_TYPE 5 /* PHY register offsets */ #define SIERRA_COMMON_CDB_OFFSET 0x0 @@ -46,7 +46,9 @@ #define SIERRA_CMN_REFRCV_PREG 0x98 #define SIERRA_CMN_REFRCV1_PREG 0xB8 #define SIERRA_CMN_PLLLC1_GEN_PREG 0xC2 +#define SIERRA_CMN_PLLLC1_FBDIV_INT_PREG 0xC3 #define SIERRA_CMN_PLLLC1_LF_COEFF_MODE0_PREG 0xCA +#define SIERRA_CMN_PLLLC1_CLK0_PREG 0xCE #define SIERRA_CMN_PLLLC1_BWCAL_MODE0_PREG 0xD0 #define SIERRA_CMN_PLLLC1_SS_TIME_STEPSIZE_MODE_PREG 0xE2 @@ -74,6 +76,7 @@ #define SIERRA_PSC_RX_A1_PREG 0x031 #define SIERRA_PSC_RX_A2_PREG 0x032 #define SIERRA_PSC_RX_A3_PREG 0x033 +#define SIERRA_PLLCTRL_FBDIV_MODE01_PREG 0x039 #define SIERRA_PLLCTRL_SUBRATE_PREG 0x03A #define SIERRA_PLLCTRL_GEN_A_PREG 0x03B #define SIERRA_PLLCTRL_GEN_D_PREG 0x03E @@ -206,13 +209,11 @@ #define PLL_LOCK_TIME 100000 #define CDNS_SIERRA_OUTPUT_CLOCKS 3 -#define CDNS_SIERRA_INPUT_CLOCKS 5 +#define CDNS_SIERRA_INPUT_CLOCKS 3 enum cdns_sierra_clock_input { PHY_CLK, CMN_REFCLK_DIG_DIV, CMN_REFCLK1_DIG_DIV, - PLL0_REFCLK, - PLL1_REFCLK, }; #define SIERRA_NUM_CMN_PLLC 2 @@ -274,9 +275,18 @@ struct cdns_sierra_pll_mux { #define to_cdns_sierra_pll_mux(_hw) \ container_of(_hw, struct cdns_sierra_pll_mux, hw) -static const int pll_mux_parent_index[][SIERRA_NUM_CMN_PLLC_PARENTS] = { - [CMN_PLLLC] = { PLL0_REFCLK, PLL1_REFCLK }, - [CMN_PLLLC1] = { PLL1_REFCLK, PLL0_REFCLK }, +#define PLL0_REFCLK_NAME "pll0_refclk" +#define PLL1_REFCLK_NAME "pll1_refclk" + +static const struct clk_parent_data pll_mux_parent_data[][SIERRA_NUM_CMN_PLLC_PARENTS] = { + [CMN_PLLLC] = { + { .fw_name = PLL0_REFCLK_NAME }, + { .fw_name = PLL1_REFCLK_NAME } + }, + [CMN_PLLLC1] = { + { .fw_name = PLL1_REFCLK_NAME }, + { .fw_name = PLL0_REFCLK_NAME } + }, }; static u32 cdns_sierra_pll_mux_table[][SIERRA_NUM_CMN_PLLC_PARENTS] = { @@ -298,6 +308,7 @@ enum cdns_sierra_phy_type { TYPE_NONE, TYPE_PCIE, TYPE_USB, + TYPE_SGMII, TYPE_QSGMII }; @@ -371,8 +382,8 @@ struct cdns_sierra_phy { u32 num_lanes; bool autoconf; int already_configured; - struct clk_onecell_data clk_data; - struct clk *output_clks[CDNS_SIERRA_OUTPUT_CLOCKS]; + struct clk *pll_clks[SIERRA_NUM_CMN_PLLC]; + struct clk_hw_onecell_data clk_data; }; static int cdns_regmap_write(void *context, unsigned int reg, unsigned int val) @@ -722,38 +733,21 @@ static int cdns_sierra_pll_mux_register(struct cdns_sierra_phy *sp, struct cdns_sierra_pll_mux *mux; struct device *dev = sp->dev; struct clk_init_data *init; - const char **parent_names; - unsigned int num_parents; char clk_name[100]; - struct clk *clk; - int i; + int ret; mux = devm_kzalloc(dev, sizeof(*mux), GFP_KERNEL); if (!mux) return -ENOMEM; - num_parents = SIERRA_NUM_CMN_PLLC_PARENTS; - parent_names = devm_kzalloc(dev, (sizeof(char *) * num_parents), GFP_KERNEL); - if (!parent_names) - return -ENOMEM; - - for (i = 0; i < num_parents; i++) { - clk = sp->input_clks[pll_mux_parent_index[clk_index][i]]; - if (IS_ERR_OR_NULL(clk)) { - dev_err(dev, "No parent clock for PLL mux clocks\n"); - return IS_ERR(clk) ? PTR_ERR(clk) : -ENOENT; - } - parent_names[i] = __clk_get_name(clk); - } - snprintf(clk_name, sizeof(clk_name), "%s_%s", dev_name(dev), clk_names[clk_index]); init = &mux->clk_data; init->ops = &cdns_sierra_pll_mux_ops; init->flags = CLK_SET_RATE_NO_REPARENT; - init->parent_names = parent_names; - init->num_parents = num_parents; + init->parent_data = pll_mux_parent_data[clk_index]; + init->num_parents = SIERRA_NUM_CMN_PLLC_PARENTS; init->name = clk_name; mux->pfdclk_sel_preg = pfdclk1_sel_field; @@ -761,11 +755,14 @@ static int cdns_sierra_pll_mux_register(struct cdns_sierra_phy *sp, mux->termen_field = termen_field; mux->hw.init = init; - clk = devm_clk_register(dev, &mux->hw); - if (IS_ERR(clk)) - return PTR_ERR(clk); + ret = devm_clk_hw_register(dev, &mux->hw); + if (ret) + return ret; - sp->output_clks[clk_index] = clk; + sp->clk_data.hws[clk_index] = &mux->hw; + + sp->pll_clks[clk_index] = devm_clk_hw_get_clk(dev, &mux->hw, + clk_names[clk_index]); return 0; } @@ -838,7 +835,7 @@ static int cdns_sierra_derived_refclk_register(struct cdns_sierra_phy *sp) struct clk_init_data *init; struct regmap *regmap; char clk_name[100]; - struct clk *clk; + int ret; derived_refclk = devm_kzalloc(dev, sizeof(*derived_refclk), GFP_KERNEL); if (!derived_refclk) @@ -871,11 +868,11 @@ static int cdns_sierra_derived_refclk_register(struct cdns_sierra_phy *sp) derived_refclk->hw.init = init; - clk = devm_clk_register(dev, &derived_refclk->hw); - if (IS_ERR(clk)) - return PTR_ERR(clk); + ret = devm_clk_hw_register(dev, &derived_refclk->hw); + if (ret) + return ret; - sp->output_clks[CDNS_SIERRA_DERIVED_REFCLK] = clk; + sp->clk_data.hws[CDNS_SIERRA_DERIVED_REFCLK] = &derived_refclk->hw; return 0; } @@ -906,9 +903,9 @@ static int cdns_sierra_clk_register(struct cdns_sierra_phy *sp) return ret; } - sp->clk_data.clks = sp->output_clks; - sp->clk_data.clk_num = CDNS_SIERRA_OUTPUT_CLOCKS; - ret = of_clk_add_provider(node, of_clk_src_onecell_get, &sp->clk_data); + sp->clk_data.num = CDNS_SIERRA_OUTPUT_CLOCKS; + ret = of_clk_add_hw_provider(node, of_clk_hw_onecell_get, + &sp->clk_data); if (ret) dev_err(dev, "Failed to add clock provider: %s\n", node->name); @@ -936,6 +933,9 @@ static int cdns_sierra_get_optional(struct cdns_sierra_inst *inst, case PHY_TYPE_USB3: inst->phy_type = TYPE_USB; break; + case PHY_TYPE_SGMII: + inst->phy_type = TYPE_SGMII; + break; case PHY_TYPE_QSGMII: inst->phy_type = TYPE_QSGMII; break; @@ -1147,22 +1147,6 @@ static int cdns_sierra_phy_get_clocks(struct cdns_sierra_phy *sp, } sp->input_clks[CMN_REFCLK1_DIG_DIV] = clk; - clk = devm_clk_get_optional(dev, "pll0_refclk"); - if (IS_ERR(clk)) { - dev_err(dev, "pll0_refclk clock not found\n"); - ret = PTR_ERR(clk); - return ret; - } - sp->input_clks[PLL0_REFCLK] = clk; - - clk = devm_clk_get_optional(dev, "pll1_refclk"); - if (IS_ERR(clk)) { - dev_err(dev, "pll1_refclk clock not found\n"); - ret = PTR_ERR(clk); - return ret; - } - sp->input_clks[PLL1_REFCLK] = clk; - return 0; } @@ -1190,26 +1174,26 @@ static int cdns_sierra_phy_enable_clocks(struct cdns_sierra_phy *sp) { int ret; - ret = clk_prepare_enable(sp->output_clks[CDNS_SIERRA_PLL_CMNLC]); + ret = clk_prepare_enable(sp->pll_clks[CDNS_SIERRA_PLL_CMNLC]); if (ret) return ret; - ret = clk_prepare_enable(sp->output_clks[CDNS_SIERRA_PLL_CMNLC1]); + ret = clk_prepare_enable(sp->pll_clks[CDNS_SIERRA_PLL_CMNLC1]); if (ret) goto err_pll_cmnlc1; return 0; err_pll_cmnlc1: - clk_disable_unprepare(sp->output_clks[CDNS_SIERRA_PLL_CMNLC]); + clk_disable_unprepare(sp->pll_clks[CDNS_SIERRA_PLL_CMNLC]); return ret; } static void cdns_sierra_phy_disable_clocks(struct cdns_sierra_phy *sp) { - clk_disable_unprepare(sp->output_clks[CDNS_SIERRA_PLL_CMNLC1]); - clk_disable_unprepare(sp->output_clks[CDNS_SIERRA_PLL_CMNLC]); + clk_disable_unprepare(sp->pll_clks[CDNS_SIERRA_PLL_CMNLC1]); + clk_disable_unprepare(sp->pll_clks[CDNS_SIERRA_PLL_CMNLC]); if (!sp->already_configured) clk_disable_unprepare(sp->input_clks[PHY_CLK]); } @@ -1339,7 +1323,7 @@ static int cdns_sierra_phy_configure_multilink(struct cdns_sierra_phy *sp) } } - if (phy_t1 == TYPE_QSGMII) + if (phy_t1 == TYPE_SGMII || phy_t1 == TYPE_QSGMII) reset_control_deassert(sp->phys[node].lnk_rst); } @@ -1370,7 +1354,9 @@ static int cdns_sierra_phy_probe(struct platform_device *pdev) if (!data) return -EINVAL; - sp = devm_kzalloc(dev, sizeof(*sp), GFP_KERNEL); + sp = devm_kzalloc(dev, struct_size(sp, clk_data.hws, + CDNS_SIERRA_OUTPUT_CLOCKS), + GFP_KERNEL); if (!sp) return -ENOMEM; dev_set_drvdata(dev, sp); @@ -1513,7 +1499,7 @@ unregister_clk: return ret; } -static int cdns_sierra_phy_remove(struct platform_device *pdev) +static void cdns_sierra_phy_remove(struct platform_device *pdev) { struct cdns_sierra_phy *phy = platform_get_drvdata(pdev); int i; @@ -1533,10 +1519,73 @@ static int cdns_sierra_phy_remove(struct platform_device *pdev) } cdns_sierra_clk_unregister(phy); - - return 0; } +/* SGMII PHY PMA lane configuration */ +static struct cdns_reg_pairs sgmii_phy_pma_ln_regs[] = { + {0x9010, SIERRA_PHY_PMA_XCVR_CTRL} +}; + +static struct cdns_sierra_vals sgmii_phy_pma_ln_vals = { + .reg_pairs = sgmii_phy_pma_ln_regs, + .num_regs = ARRAY_SIZE(sgmii_phy_pma_ln_regs), +}; + +/* SGMII refclk 100MHz, no ssc, opt3 and GE1 links using PLL LC1 */ +static const struct cdns_reg_pairs sgmii_100_no_ssc_plllc1_opt3_cmn_regs[] = { + {0x002D, SIERRA_CMN_PLLLC1_FBDIV_INT_PREG}, + {0x2085, SIERRA_CMN_PLLLC1_LF_COEFF_MODE0_PREG}, + {0x1005, SIERRA_CMN_PLLLC1_CLK0_PREG}, + {0x0000, SIERRA_CMN_PLLLC1_BWCAL_MODE0_PREG}, + {0x0800, SIERRA_CMN_PLLLC1_SS_TIME_STEPSIZE_MODE_PREG} +}; + +static const struct cdns_reg_pairs sgmii_100_no_ssc_plllc1_opt3_ln_regs[] = { + {0x688E, SIERRA_DET_STANDEC_D_PREG}, + {0x0004, SIERRA_PSC_LN_IDLE_PREG}, + {0x0FFE, SIERRA_PSC_RX_A0_PREG}, + {0x0106, SIERRA_PLLCTRL_FBDIV_MODE01_PREG}, + {0x0013, SIERRA_PLLCTRL_SUBRATE_PREG}, + {0x0003, SIERRA_PLLCTRL_GEN_A_PREG}, + {0x0106, SIERRA_PLLCTRL_GEN_D_PREG}, + {0x5231, SIERRA_PLLCTRL_CPGAIN_MODE_PREG }, + {0x0000, SIERRA_DRVCTRL_ATTEN_PREG}, + {0x9702, SIERRA_DRVCTRL_BOOST_PREG}, + {0x0051, SIERRA_RX_CREQ_FLTR_A_MODE0_PREG}, + {0x3C0E, SIERRA_CREQ_CCLKDET_MODE01_PREG}, + {0x3220, SIERRA_CREQ_FSMCLK_SEL_PREG}, + {0x0000, SIERRA_CREQ_EQ_CTRL_PREG}, + {0x0002, SIERRA_DEQ_PHALIGN_CTRL}, + {0x0186, SIERRA_DEQ_GLUT0}, + {0x0186, SIERRA_DEQ_GLUT1}, + {0x0186, SIERRA_DEQ_GLUT2}, + {0x0186, SIERRA_DEQ_GLUT3}, + {0x0186, SIERRA_DEQ_GLUT4}, + {0x0861, SIERRA_DEQ_ALUT0}, + {0x07E0, SIERRA_DEQ_ALUT1}, + {0x079E, SIERRA_DEQ_ALUT2}, + {0x071D, SIERRA_DEQ_ALUT3}, + {0x03F5, SIERRA_DEQ_DFETAP_CTRL_PREG}, + {0x0C01, SIERRA_DEQ_TAU_CTRL1_FAST_MAINT_PREG}, + {0x3C40, SIERRA_DEQ_TAU_CTRL1_SLOW_MAINT_PREG}, + {0x1C04, SIERRA_DEQ_TAU_CTRL2_PREG}, + {0x0033, SIERRA_DEQ_PICTRL_PREG}, + {0x0000, SIERRA_CPI_OUTBUF_RATESEL_PREG}, + {0x0B6D, SIERRA_CPI_RESBIAS_BIN_PREG}, + {0x0102, SIERRA_RXBUFFER_CTLECTRL_PREG}, + {0x0002, SIERRA_RXBUFFER_RCDFECTRL_PREG} +}; + +static struct cdns_sierra_vals sgmii_100_no_ssc_plllc1_opt3_cmn_vals = { + .reg_pairs = sgmii_100_no_ssc_plllc1_opt3_cmn_regs, + .num_regs = ARRAY_SIZE(sgmii_100_no_ssc_plllc1_opt3_cmn_regs), +}; + +static struct cdns_sierra_vals sgmii_100_no_ssc_plllc1_opt3_ln_vals = { + .reg_pairs = sgmii_100_no_ssc_plllc1_opt3_ln_regs, + .num_regs = ARRAY_SIZE(sgmii_100_no_ssc_plllc1_opt3_ln_regs), +}; + /* QSGMII PHY PMA lane configuration */ static struct cdns_reg_pairs qsgmii_phy_pma_ln_regs[] = { {0x9010, SIERRA_PHY_PMA_XCVR_CTRL} @@ -2363,6 +2412,11 @@ static const struct cdns_sierra_data cdns_map_sierra = { [EXTERNAL_SSC] = &pcie_phy_pcs_cmn_vals, [INTERNAL_SSC] = &pcie_phy_pcs_cmn_vals, }, + [TYPE_SGMII] = { + [NO_SSC] = &pcie_phy_pcs_cmn_vals, + [EXTERNAL_SSC] = &pcie_phy_pcs_cmn_vals, + [INTERNAL_SSC] = &pcie_phy_pcs_cmn_vals, + }, [TYPE_QSGMII] = { [NO_SSC] = &pcie_phy_pcs_cmn_vals, [EXTERNAL_SSC] = &pcie_phy_pcs_cmn_vals, @@ -2377,6 +2431,11 @@ static const struct cdns_sierra_data cdns_map_sierra = { [EXTERNAL_SSC] = &pcie_100_ext_ssc_cmn_vals, [INTERNAL_SSC] = &pcie_100_int_ssc_cmn_vals, }, + [TYPE_SGMII] = { + [NO_SSC] = &pcie_100_no_ssc_plllc_cmn_vals, + [EXTERNAL_SSC] = &pcie_100_ext_ssc_plllc_cmn_vals, + [INTERNAL_SSC] = &pcie_100_int_ssc_plllc_cmn_vals, + }, [TYPE_QSGMII] = { [NO_SSC] = &pcie_100_no_ssc_plllc_cmn_vals, [EXTERNAL_SSC] = &pcie_100_ext_ssc_plllc_cmn_vals, @@ -2388,6 +2447,13 @@ static const struct cdns_sierra_data cdns_map_sierra = { [EXTERNAL_SSC] = &usb_100_ext_ssc_cmn_vals, }, }, + [TYPE_SGMII] = { + [TYPE_PCIE] = { + [NO_SSC] = &sgmii_100_no_ssc_plllc1_opt3_cmn_vals, + [EXTERNAL_SSC] = &sgmii_100_no_ssc_plllc1_opt3_cmn_vals, + [INTERNAL_SSC] = &sgmii_100_no_ssc_plllc1_opt3_cmn_vals, + }, + }, [TYPE_QSGMII] = { [TYPE_PCIE] = { [NO_SSC] = &qsgmii_100_no_ssc_plllc1_cmn_vals, @@ -2403,6 +2469,11 @@ static const struct cdns_sierra_data cdns_map_sierra = { [EXTERNAL_SSC] = &pcie_100_ext_ssc_ln_vals, [INTERNAL_SSC] = &pcie_100_int_ssc_ln_vals, }, + [TYPE_SGMII] = { + [NO_SSC] = &ml_pcie_100_no_ssc_ln_vals, + [EXTERNAL_SSC] = &ml_pcie_100_ext_ssc_ln_vals, + [INTERNAL_SSC] = &ml_pcie_100_int_ssc_ln_vals, + }, [TYPE_QSGMII] = { [NO_SSC] = &ml_pcie_100_no_ssc_ln_vals, [EXTERNAL_SSC] = &ml_pcie_100_ext_ssc_ln_vals, @@ -2414,6 +2485,13 @@ static const struct cdns_sierra_data cdns_map_sierra = { [EXTERNAL_SSC] = &usb_100_ext_ssc_ln_vals, }, }, + [TYPE_SGMII] = { + [TYPE_PCIE] = { + [NO_SSC] = &sgmii_100_no_ssc_plllc1_opt3_ln_vals, + [EXTERNAL_SSC] = &sgmii_100_no_ssc_plllc1_opt3_ln_vals, + [INTERNAL_SSC] = &sgmii_100_no_ssc_plllc1_opt3_ln_vals, + }, + }, [TYPE_QSGMII] = { [TYPE_PCIE] = { [NO_SSC] = &qsgmii_100_no_ssc_plllc1_ln_vals, @@ -2435,6 +2513,11 @@ static const struct cdns_sierra_data cdns_ti_map_sierra = { [EXTERNAL_SSC] = &pcie_phy_pcs_cmn_vals, [INTERNAL_SSC] = &pcie_phy_pcs_cmn_vals, }, + [TYPE_SGMII] = { + [NO_SSC] = &pcie_phy_pcs_cmn_vals, + [EXTERNAL_SSC] = &pcie_phy_pcs_cmn_vals, + [INTERNAL_SSC] = &pcie_phy_pcs_cmn_vals, + }, [TYPE_QSGMII] = { [NO_SSC] = &pcie_phy_pcs_cmn_vals, [EXTERNAL_SSC] = &pcie_phy_pcs_cmn_vals, @@ -2443,6 +2526,13 @@ static const struct cdns_sierra_data cdns_ti_map_sierra = { }, }, .phy_pma_ln_vals = { + [TYPE_SGMII] = { + [TYPE_PCIE] = { + [NO_SSC] = &sgmii_phy_pma_ln_vals, + [EXTERNAL_SSC] = &sgmii_phy_pma_ln_vals, + [INTERNAL_SSC] = &sgmii_phy_pma_ln_vals, + }, + }, [TYPE_QSGMII] = { [TYPE_PCIE] = { [NO_SSC] = &qsgmii_phy_pma_ln_vals, @@ -2458,6 +2548,11 @@ static const struct cdns_sierra_data cdns_ti_map_sierra = { [EXTERNAL_SSC] = &pcie_100_ext_ssc_cmn_vals, [INTERNAL_SSC] = &pcie_100_int_ssc_cmn_vals, }, + [TYPE_SGMII] = { + [NO_SSC] = &pcie_100_no_ssc_plllc_cmn_vals, + [EXTERNAL_SSC] = &pcie_100_ext_ssc_plllc_cmn_vals, + [INTERNAL_SSC] = &pcie_100_int_ssc_plllc_cmn_vals, + }, [TYPE_QSGMII] = { [NO_SSC] = &pcie_100_no_ssc_plllc_cmn_vals, [EXTERNAL_SSC] = &pcie_100_ext_ssc_plllc_cmn_vals, @@ -2469,6 +2564,13 @@ static const struct cdns_sierra_data cdns_ti_map_sierra = { [EXTERNAL_SSC] = &usb_100_ext_ssc_cmn_vals, }, }, + [TYPE_SGMII] = { + [TYPE_PCIE] = { + [NO_SSC] = &sgmii_100_no_ssc_plllc1_opt3_cmn_vals, + [EXTERNAL_SSC] = &sgmii_100_no_ssc_plllc1_opt3_cmn_vals, + [INTERNAL_SSC] = &sgmii_100_no_ssc_plllc1_opt3_cmn_vals, + }, + }, [TYPE_QSGMII] = { [TYPE_PCIE] = { [NO_SSC] = &qsgmii_100_no_ssc_plllc1_cmn_vals, @@ -2484,6 +2586,11 @@ static const struct cdns_sierra_data cdns_ti_map_sierra = { [EXTERNAL_SSC] = &pcie_100_ext_ssc_ln_vals, [INTERNAL_SSC] = &pcie_100_int_ssc_ln_vals, }, + [TYPE_SGMII] = { + [NO_SSC] = &ti_ml_pcie_100_no_ssc_ln_vals, + [EXTERNAL_SSC] = &ti_ml_pcie_100_ext_ssc_ln_vals, + [INTERNAL_SSC] = &ti_ml_pcie_100_int_ssc_ln_vals, + }, [TYPE_QSGMII] = { [NO_SSC] = &ti_ml_pcie_100_no_ssc_ln_vals, [EXTERNAL_SSC] = &ti_ml_pcie_100_ext_ssc_ln_vals, @@ -2495,6 +2602,13 @@ static const struct cdns_sierra_data cdns_ti_map_sierra = { [EXTERNAL_SSC] = &usb_100_ext_ssc_ln_vals, }, }, + [TYPE_SGMII] = { + [TYPE_PCIE] = { + [NO_SSC] = &sgmii_100_no_ssc_plllc1_opt3_ln_vals, + [EXTERNAL_SSC] = &sgmii_100_no_ssc_plllc1_opt3_ln_vals, + [INTERNAL_SSC] = &sgmii_100_no_ssc_plllc1_opt3_ln_vals, + }, + }, [TYPE_QSGMII] = { [TYPE_PCIE] = { [NO_SSC] = &qsgmii_100_no_ssc_plllc1_ln_vals, @@ -2520,7 +2634,7 @@ MODULE_DEVICE_TABLE(of, cdns_sierra_id_table); static struct platform_driver cdns_sierra_driver = { .probe = cdns_sierra_phy_probe, - .remove = cdns_sierra_phy_remove, + .remove_new = cdns_sierra_phy_remove, .driver = { .name = "cdns-sierra-phy", .of_match_table = cdns_sierra_id_table, diff --git a/drivers/phy/cadence/phy-cadence-torrent.c b/drivers/phy/cadence/phy-cadence-torrent.c index f099053c583c..3831f596d50c 100644 --- a/drivers/phy/cadence/phy-cadence-torrent.c +++ b/drivers/phy/cadence/phy-cadence-torrent.c @@ -2777,7 +2777,7 @@ clk_cleanup: return ret; } -static int cdns_torrent_phy_remove(struct platform_device *pdev) +static void cdns_torrent_phy_remove(struct platform_device *pdev) { struct cdns_torrent_phy *cdns_phy = platform_get_drvdata(pdev); int i; @@ -2791,8 +2791,6 @@ static int cdns_torrent_phy_remove(struct platform_device *pdev) clk_disable_unprepare(cdns_phy->clk); cdns_torrent_clk_cleanup(cdns_phy); - - return 0; } /* Single DisplayPort(DP) link configuration */ @@ -4708,7 +4706,7 @@ MODULE_DEVICE_TABLE(of, cdns_torrent_phy_of_match); static struct platform_driver cdns_torrent_phy_driver = { .probe = cdns_torrent_phy_probe, - .remove = cdns_torrent_phy_remove, + .remove_new = cdns_torrent_phy_remove, .driver = { .name = "cdns-torrent-phy", .of_match_table = cdns_torrent_phy_of_match, diff --git a/drivers/phy/freescale/phy-fsl-imx8qm-lvds-phy.c b/drivers/phy/freescale/phy-fsl-imx8qm-lvds-phy.c index e514b64bfdab..0ae052df3765 100644 --- a/drivers/phy/freescale/phy-fsl-imx8qm-lvds-phy.c +++ b/drivers/phy/freescale/phy-fsl-imx8qm-lvds-phy.c @@ -391,11 +391,9 @@ err: return ret; } -static int mixel_lvds_phy_remove(struct platform_device *pdev) +static void mixel_lvds_phy_remove(struct platform_device *pdev) { pm_runtime_disable(&pdev->dev); - - return 0; } static int __maybe_unused mixel_lvds_phy_runtime_suspend(struct device *dev) @@ -436,7 +434,7 @@ MODULE_DEVICE_TABLE(of, mixel_lvds_phy_of_match); static struct platform_driver mixel_lvds_phy_driver = { .probe = mixel_lvds_phy_probe, - .remove = mixel_lvds_phy_remove, + .remove_new = mixel_lvds_phy_remove, .driver = { .pm = &mixel_lvds_phy_pm_ops, .name = "mixel-lvds-phy", diff --git a/drivers/phy/intel/Kconfig b/drivers/phy/intel/Kconfig index 18a3cc5b98c0..ac42bb2fb394 100644 --- a/drivers/phy/intel/Kconfig +++ b/drivers/phy/intel/Kconfig @@ -46,13 +46,3 @@ config PHY_INTEL_LGM_EMMC select GENERIC_PHY help Enable this to support the Intel EMMC PHY - -config PHY_INTEL_THUNDERBAY_EMMC - tristate "Intel Thunder Bay eMMC PHY driver" - depends on OF && (ARCH_THUNDERBAY || COMPILE_TEST) - select GENERIC_PHY - help - This option enables support for Intel Thunder Bay SoC eMMC PHY. - - To compile this driver as a module, choose M here: the module - will be called phy-intel-thunderbay-emmc.ko. diff --git a/drivers/phy/intel/Makefile b/drivers/phy/intel/Makefile index b7321d56b0bb..14550981a707 100644 --- a/drivers/phy/intel/Makefile +++ b/drivers/phy/intel/Makefile @@ -3,4 +3,3 @@ obj-$(CONFIG_PHY_INTEL_KEEMBAY_EMMC) += phy-intel-keembay-emmc.o obj-$(CONFIG_PHY_INTEL_KEEMBAY_USB) += phy-intel-keembay-usb.o obj-$(CONFIG_PHY_INTEL_LGM_COMBO) += phy-intel-lgm-combo.o obj-$(CONFIG_PHY_INTEL_LGM_EMMC) += phy-intel-lgm-emmc.o -obj-$(CONFIG_PHY_INTEL_THUNDERBAY_EMMC) += phy-intel-thunderbay-emmc.o diff --git a/drivers/phy/intel/phy-intel-lgm-combo.c b/drivers/phy/intel/phy-intel-lgm-combo.c index 8c764c457c1c..d32e267c0001 100644 --- a/drivers/phy/intel/phy-intel-lgm-combo.c +++ b/drivers/phy/intel/phy-intel-lgm-combo.c @@ -589,13 +589,12 @@ static int intel_cbphy_probe(struct platform_device *pdev) return intel_cbphy_create(cbphy); } -static int intel_cbphy_remove(struct platform_device *pdev) +static void intel_cbphy_remove(struct platform_device *pdev) { struct intel_combo_phy *cbphy = platform_get_drvdata(pdev); intel_cbphy_rst_assert(cbphy); clk_disable_unprepare(cbphy->core_clk); - return 0; } static const struct of_device_id of_intel_cbphy_match[] = { @@ -606,7 +605,7 @@ static const struct of_device_id of_intel_cbphy_match[] = { static struct platform_driver intel_cbphy_driver = { .probe = intel_cbphy_probe, - .remove = intel_cbphy_remove, + .remove_new = intel_cbphy_remove, .driver = { .name = "intel-combo-phy", .of_match_table = of_intel_cbphy_match, diff --git a/drivers/phy/intel/phy-intel-thunderbay-emmc.c b/drivers/phy/intel/phy-intel-thunderbay-emmc.c deleted file mode 100644 index 593f6970b81e..000000000000 --- a/drivers/phy/intel/phy-intel-thunderbay-emmc.c +++ /dev/null @@ -1,509 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/* - * Intel ThunderBay eMMC PHY driver - * - * Copyright (C) 2021 Intel Corporation - * - */ - -#include <linux/clk.h> -#include <linux/delay.h> -#include <linux/io.h> -#include <linux/iopoll.h> -#include <linux/module.h> -#include <linux/of.h> -#include <linux/phy/phy.h> -#include <linux/platform_device.h> - -/* eMMC/SD/SDIO core/phy configuration registers */ -#define CTRL_CFG_0 0x00 -#define CTRL_CFG_1 0x04 -#define CTRL_PRESET_0 0x08 -#define CTRL_PRESET_1 0x0c -#define CTRL_PRESET_2 0x10 -#define CTRL_PRESET_3 0x14 -#define CTRL_PRESET_4 0x18 -#define CTRL_CFG_2 0x1c -#define CTRL_CFG_3 0x20 -#define PHY_CFG_0 0x24 -#define PHY_CFG_1 0x28 -#define PHY_CFG_2 0x2c -#define PHYBIST_CTRL 0x30 -#define SDHC_STAT3 0x34 -#define PHY_STAT 0x38 -#define PHYBIST_STAT_0 0x3c -#define PHYBIST_STAT_1 0x40 -#define EMMC_AXI 0x44 - -/* CTRL_PRESET_3 */ -#define CTRL_PRESET3_MASK GENMASK(31, 0) -#define CTRL_PRESET3_SHIFT 0 - -/* CTRL_CFG_0 bit fields */ -#define SUPPORT_HS_MASK BIT(26) -#define SUPPORT_HS_SHIFT 26 - -#define SUPPORT_8B_MASK BIT(24) -#define SUPPORT_8B_SHIFT 24 - -/* CTRL_CFG_1 bit fields */ -#define SUPPORT_SDR50_MASK BIT(28) -#define SUPPORT_SDR50_SHIFT 28 -#define SLOT_TYPE_MASK GENMASK(27, 26) -#define SLOT_TYPE_OFFSET 26 -#define SUPPORT_64B_MASK BIT(24) -#define SUPPORT_64B_SHIFT 24 -#define SUPPORT_HS400_MASK BIT(2) -#define SUPPORT_HS400_SHIFT 2 -#define SUPPORT_DDR50_MASK BIT(1) -#define SUPPORT_DDR50_SHIFT 1 -#define SUPPORT_SDR104_MASK BIT(0) -#define SUPPORT_SDR104_SHIFT 0 - -/* PHY_CFG_0 bit fields */ -#define SEL_DLY_TXCLK_MASK BIT(29) -#define SEL_DLY_TXCLK_SHIFT 29 -#define SEL_DLY_RXCLK_MASK BIT(28) -#define SEL_DLY_RXCLK_SHIFT 28 - -#define OTAP_DLY_ENA_MASK BIT(27) -#define OTAP_DLY_ENA_SHIFT 27 -#define OTAP_DLY_SEL_MASK GENMASK(26, 23) -#define OTAP_DLY_SEL_SHIFT 23 -#define ITAP_CHG_WIN_MASK BIT(22) -#define ITAP_CHG_WIN_SHIFT 22 -#define ITAP_DLY_ENA_MASK BIT(21) -#define ITAP_DLY_ENA_SHIFT 21 -#define ITAP_DLY_SEL_MASK GENMASK(20, 16) -#define ITAP_DLY_SEL_SHIFT 16 -#define RET_ENB_MASK BIT(15) -#define RET_ENB_SHIFT 15 -#define RET_EN_MASK BIT(14) -#define RET_EN_SHIFT 14 -#define DLL_IFF_MASK GENMASK(13, 11) -#define DLL_IFF_SHIFT 11 -#define DLL_EN_MASK BIT(10) -#define DLL_EN_SHIFT 10 -#define DLL_TRIM_ICP_MASK GENMASK(9, 6) -#define DLL_TRIM_ICP_SHIFT 6 -#define RETRIM_EN_MASK BIT(5) -#define RETRIM_EN_SHIFT 5 -#define RETRIM_MASK BIT(4) -#define RETRIM_SHIFT 4 -#define DR_TY_MASK GENMASK(3, 1) -#define DR_TY_SHIFT 1 -#define PWR_DOWN_MASK BIT(0) -#define PWR_DOWN_SHIFT 0 - -/* PHY_CFG_1 bit fields */ -#define REN_DAT_MASK GENMASK(19, 12) -#define REN_DAT_SHIFT 12 -#define REN_CMD_MASK BIT(11) -#define REN_CMD_SHIFT 11 -#define REN_STRB_MASK BIT(10) -#define REN_STRB_SHIFT 10 -#define PU_STRB_MASK BIT(20) -#define PU_STRB_SHIFT 20 - -/* PHY_CFG_2 bit fields */ -#define CLKBUF_MASK GENMASK(24, 21) -#define CLKBUF_SHIFT 21 -#define SEL_STRB_MASK GENMASK(20, 13) -#define SEL_STRB_SHIFT 13 -#define SEL_FREQ_MASK GENMASK(12, 10) -#define SEL_FREQ_SHIFT 10 - -/* PHY_STAT bit fields */ -#define CAL_DONE BIT(6) -#define DLL_RDY BIT(5) - -#define OTAP_DLY 0x0 -#define ITAP_DLY 0x0 -#define STRB 0x33 - -/* From ACS_eMMC51_16nFFC_RO1100_Userguide_v1p0.pdf p17 */ -#define FREQSEL_200M_170M 0x0 -#define FREQSEL_170M_140M 0x1 -#define FREQSEL_140M_110M 0x2 -#define FREQSEL_110M_80M 0x3 -#define FREQSEL_80M_50M 0x4 -#define FREQSEL_275M_250M 0x5 -#define FREQSEL_250M_225M 0x6 -#define FREQSEL_225M_200M 0x7 - -/* Phy power status */ -#define PHY_UNINITIALIZED 0 -#define PHY_INITIALIZED 1 - -/* - * During init(400KHz) phy_settings will be called with 200MHZ clock - * To avoid incorrectly setting the phy for init(400KHZ) "phy_power_sts" is used. - * When actual clock is set always phy is powered off once and then powered on. - * (sdhci_arasan_set_clock). That feature will be used to identify whether the - * settings are for init phy_power_on or actual clock phy_power_on - * 0 --> init settings - * 1 --> actual settings - */ - -struct thunderbay_emmc_phy { - void __iomem *reg_base; - struct clk *emmcclk; - int phy_power_sts; -}; - -static inline void update_reg(struct thunderbay_emmc_phy *tbh_phy, u32 offset, - u32 mask, u32 shift, u32 val) -{ - u32 tmp; - - tmp = readl(tbh_phy->reg_base + offset); - tmp &= ~mask; - tmp |= val << shift; - writel(tmp, tbh_phy->reg_base + offset); -} - -static int thunderbay_emmc_phy_power(struct phy *phy, bool power_on) -{ - struct thunderbay_emmc_phy *tbh_phy = phy_get_drvdata(phy); - unsigned int freqsel = FREQSEL_200M_170M; - unsigned long rate; - static int lock; - u32 val; - int ret; - - /* Disable DLL */ - rate = clk_get_rate(tbh_phy->emmcclk); - switch (rate) { - case 200000000: - /* lock dll only when it is used, i.e only if SEL_DLY_TXCLK/RXCLK are 0 */ - update_reg(tbh_phy, PHY_CFG_0, DLL_EN_MASK, DLL_EN_SHIFT, 0x0); - break; - - /* dll lock not required for other frequencies */ - case 50000000 ... 52000000: - case 400000: - default: - break; - } - - if (!power_on) - return 0; - - rate = clk_get_rate(tbh_phy->emmcclk); - switch (rate) { - case 170000001 ... 200000000: - freqsel = FREQSEL_200M_170M; - break; - - case 140000001 ... 170000000: - freqsel = FREQSEL_170M_140M; - break; - - case 110000001 ... 140000000: - freqsel = FREQSEL_140M_110M; - break; - - case 80000001 ... 110000000: - freqsel = FREQSEL_110M_80M; - break; - - case 50000000 ... 80000000: - freqsel = FREQSEL_80M_50M; - break; - - case 250000001 ... 275000000: - freqsel = FREQSEL_275M_250M; - break; - - case 225000001 ... 250000000: - freqsel = FREQSEL_250M_225M; - break; - - case 200000001 ... 225000000: - freqsel = FREQSEL_225M_200M; - break; - default: - break; - } - /* Clock rate is checked against upper limit. It may fall low during init */ - if (rate > 200000000) - dev_warn(&phy->dev, "Unsupported rate: %lu\n", rate); - - udelay(5); - - if (lock == 0) { - /* PDB will be done only once per boot */ - update_reg(tbh_phy, PHY_CFG_0, PWR_DOWN_MASK, - PWR_DOWN_SHIFT, 0x1); - lock = 1; - /* - * According to the user manual, it asks driver to wait 5us for - * calpad busy trimming. However it is documented that this value is - * PVT(A.K.A. process, voltage and temperature) relevant, so some - * failure cases are found which indicates we should be more tolerant - * to calpad busy trimming. - */ - ret = readl_poll_timeout(tbh_phy->reg_base + PHY_STAT, - val, (val & CAL_DONE), 10, 50); - if (ret) { - dev_err(&phy->dev, "caldone failed, ret=%d\n", ret); - return ret; - } - } - rate = clk_get_rate(tbh_phy->emmcclk); - switch (rate) { - case 200000000: - /* Set frequency of the DLL operation */ - update_reg(tbh_phy, PHY_CFG_2, SEL_FREQ_MASK, SEL_FREQ_SHIFT, freqsel); - - /* Enable DLL */ - update_reg(tbh_phy, PHY_CFG_0, DLL_EN_MASK, DLL_EN_SHIFT, 0x1); - - /* - * After enabling analog DLL circuits docs say that we need 10.2 us if - * our source clock is at 50 MHz and that lock time scales linearly - * with clock speed. If we are powering on the PHY and the card clock - * is super slow (like 100kHz) this could take as long as 5.1 ms as - * per the math: 10.2 us * (50000000 Hz / 100000 Hz) => 5.1 ms - * hopefully we won't be running at 100 kHz, but we should still make - * sure we wait long enough. - * - * NOTE: There appear to be corner cases where the DLL seems to take - * extra long to lock for reasons that aren't understood. In some - * extreme cases we've seen it take up to over 10ms (!). We'll be - * generous and give it 50ms. - */ - ret = readl_poll_timeout(tbh_phy->reg_base + PHY_STAT, - val, (val & DLL_RDY), 10, 50 * USEC_PER_MSEC); - if (ret) { - dev_err(&phy->dev, "dllrdy failed, ret=%d\n", ret); - return ret; - } - break; - - default: - break; - } - return 0; -} - -static int thunderbay_emmc_phy_init(struct phy *phy) -{ - struct thunderbay_emmc_phy *tbh_phy = phy_get_drvdata(phy); - - tbh_phy->emmcclk = clk_get(&phy->dev, "emmcclk"); - - return PTR_ERR_OR_ZERO(tbh_phy->emmcclk); -} - -static int thunderbay_emmc_phy_exit(struct phy *phy) -{ - struct thunderbay_emmc_phy *tbh_phy = phy_get_drvdata(phy); - - clk_put(tbh_phy->emmcclk); - - return 0; -} - -static int thunderbay_emmc_phy_power_on(struct phy *phy) -{ - struct thunderbay_emmc_phy *tbh_phy = phy_get_drvdata(phy); - unsigned long rate; - - /* Overwrite capability bits configurable in bootloader */ - update_reg(tbh_phy, CTRL_CFG_0, - SUPPORT_HS_MASK, SUPPORT_HS_SHIFT, 0x1); - update_reg(tbh_phy, CTRL_CFG_0, - SUPPORT_8B_MASK, SUPPORT_8B_SHIFT, 0x1); - update_reg(tbh_phy, CTRL_CFG_1, - SUPPORT_SDR50_MASK, SUPPORT_SDR50_SHIFT, 0x1); - update_reg(tbh_phy, CTRL_CFG_1, - SUPPORT_DDR50_MASK, SUPPORT_DDR50_SHIFT, 0x1); - update_reg(tbh_phy, CTRL_CFG_1, - SUPPORT_SDR104_MASK, SUPPORT_SDR104_SHIFT, 0x1); - update_reg(tbh_phy, CTRL_CFG_1, - SUPPORT_HS400_MASK, SUPPORT_HS400_SHIFT, 0x1); - update_reg(tbh_phy, CTRL_CFG_1, - SUPPORT_64B_MASK, SUPPORT_64B_SHIFT, 0x1); - - if (tbh_phy->phy_power_sts == PHY_UNINITIALIZED) { - /* Indicates initialization, settings for init, same as 400KHZ setting */ - update_reg(tbh_phy, PHY_CFG_0, SEL_DLY_TXCLK_MASK, SEL_DLY_TXCLK_SHIFT, 0x1); - update_reg(tbh_phy, PHY_CFG_0, SEL_DLY_RXCLK_MASK, SEL_DLY_RXCLK_SHIFT, 0x1); - update_reg(tbh_phy, PHY_CFG_0, ITAP_DLY_ENA_MASK, ITAP_DLY_ENA_SHIFT, 0x0); - update_reg(tbh_phy, PHY_CFG_0, ITAP_DLY_SEL_MASK, ITAP_DLY_SEL_SHIFT, 0x0); - update_reg(tbh_phy, PHY_CFG_0, OTAP_DLY_ENA_MASK, OTAP_DLY_ENA_SHIFT, 0x0); - update_reg(tbh_phy, PHY_CFG_0, OTAP_DLY_SEL_MASK, OTAP_DLY_SEL_SHIFT, 0); - update_reg(tbh_phy, PHY_CFG_0, DLL_TRIM_ICP_MASK, DLL_TRIM_ICP_SHIFT, 0); - update_reg(tbh_phy, PHY_CFG_0, DR_TY_MASK, DR_TY_SHIFT, 0x1); - - } else if (tbh_phy->phy_power_sts == PHY_INITIALIZED) { - /* Indicates actual clock setting */ - rate = clk_get_rate(tbh_phy->emmcclk); - switch (rate) { - case 200000000: - update_reg(tbh_phy, PHY_CFG_0, SEL_DLY_TXCLK_MASK, - SEL_DLY_TXCLK_SHIFT, 0x0); - update_reg(tbh_phy, PHY_CFG_0, SEL_DLY_RXCLK_MASK, - SEL_DLY_RXCLK_SHIFT, 0x0); - update_reg(tbh_phy, PHY_CFG_0, ITAP_DLY_ENA_MASK, - ITAP_DLY_ENA_SHIFT, 0x0); - update_reg(tbh_phy, PHY_CFG_0, ITAP_DLY_SEL_MASK, - ITAP_DLY_SEL_SHIFT, 0x0); - update_reg(tbh_phy, PHY_CFG_0, OTAP_DLY_ENA_MASK, - OTAP_DLY_ENA_SHIFT, 0x1); - update_reg(tbh_phy, PHY_CFG_0, OTAP_DLY_SEL_MASK, - OTAP_DLY_SEL_SHIFT, 2); - update_reg(tbh_phy, PHY_CFG_0, DLL_TRIM_ICP_MASK, - DLL_TRIM_ICP_SHIFT, 0x8); - update_reg(tbh_phy, PHY_CFG_0, DR_TY_MASK, - DR_TY_SHIFT, 0x1); - /* For HS400 only */ - update_reg(tbh_phy, PHY_CFG_2, SEL_STRB_MASK, - SEL_STRB_SHIFT, STRB); - break; - - case 50000000 ... 52000000: - /* For both HS and DDR52 this setting works */ - update_reg(tbh_phy, PHY_CFG_0, SEL_DLY_TXCLK_MASK, - SEL_DLY_TXCLK_SHIFT, 0x1); - update_reg(tbh_phy, PHY_CFG_0, SEL_DLY_RXCLK_MASK, - SEL_DLY_RXCLK_SHIFT, 0x1); - update_reg(tbh_phy, PHY_CFG_0, ITAP_DLY_ENA_MASK, - ITAP_DLY_ENA_SHIFT, 0x0); - update_reg(tbh_phy, PHY_CFG_0, ITAP_DLY_SEL_MASK, - ITAP_DLY_SEL_SHIFT, 0x0); - update_reg(tbh_phy, PHY_CFG_0, OTAP_DLY_ENA_MASK, - OTAP_DLY_ENA_SHIFT, 0x1); - update_reg(tbh_phy, PHY_CFG_0, OTAP_DLY_SEL_MASK, - OTAP_DLY_SEL_SHIFT, 4); - update_reg(tbh_phy, PHY_CFG_0, DLL_TRIM_ICP_MASK, - DLL_TRIM_ICP_SHIFT, 0x8); - update_reg(tbh_phy, PHY_CFG_0, - DR_TY_MASK, DR_TY_SHIFT, 0x1); - break; - - case 400000: - update_reg(tbh_phy, PHY_CFG_0, SEL_DLY_TXCLK_MASK, - SEL_DLY_TXCLK_SHIFT, 0x1); - update_reg(tbh_phy, PHY_CFG_0, SEL_DLY_RXCLK_MASK, - SEL_DLY_RXCLK_SHIFT, 0x1); - update_reg(tbh_phy, PHY_CFG_0, ITAP_DLY_ENA_MASK, - ITAP_DLY_ENA_SHIFT, 0x0); - update_reg(tbh_phy, PHY_CFG_0, ITAP_DLY_SEL_MASK, - ITAP_DLY_SEL_SHIFT, 0x0); - update_reg(tbh_phy, PHY_CFG_0, OTAP_DLY_ENA_MASK, - OTAP_DLY_ENA_SHIFT, 0x0); - update_reg(tbh_phy, PHY_CFG_0, OTAP_DLY_SEL_MASK, - OTAP_DLY_SEL_SHIFT, 0); - update_reg(tbh_phy, PHY_CFG_0, DLL_TRIM_ICP_MASK, - DLL_TRIM_ICP_SHIFT, 0); - update_reg(tbh_phy, PHY_CFG_0, DR_TY_MASK, DR_TY_SHIFT, 0x1); - break; - - default: - update_reg(tbh_phy, PHY_CFG_0, SEL_DLY_TXCLK_MASK, - SEL_DLY_TXCLK_SHIFT, 0x1); - update_reg(tbh_phy, PHY_CFG_0, SEL_DLY_RXCLK_MASK, - SEL_DLY_RXCLK_SHIFT, 0x1); - update_reg(tbh_phy, PHY_CFG_0, ITAP_DLY_ENA_MASK, - ITAP_DLY_ENA_SHIFT, 0x0); - update_reg(tbh_phy, PHY_CFG_0, ITAP_DLY_SEL_MASK, - ITAP_DLY_SEL_SHIFT, 0x0); - update_reg(tbh_phy, PHY_CFG_0, OTAP_DLY_ENA_MASK, - OTAP_DLY_ENA_SHIFT, 0x1); - update_reg(tbh_phy, PHY_CFG_0, OTAP_DLY_SEL_MASK, - OTAP_DLY_SEL_SHIFT, 2); - update_reg(tbh_phy, PHY_CFG_0, DLL_TRIM_ICP_MASK, - DLL_TRIM_ICP_SHIFT, 0x8); - update_reg(tbh_phy, PHY_CFG_0, DR_TY_MASK, - DR_TY_SHIFT, 0x1); - break; - } - /* Reset, init seq called without phy_power_off, this indicates init seq */ - tbh_phy->phy_power_sts = PHY_UNINITIALIZED; - } - - update_reg(tbh_phy, PHY_CFG_0, RETRIM_EN_MASK, RETRIM_EN_SHIFT, 0x1); - update_reg(tbh_phy, PHY_CFG_0, RETRIM_MASK, RETRIM_SHIFT, 0x0); - - return thunderbay_emmc_phy_power(phy, 1); -} - -static int thunderbay_emmc_phy_power_off(struct phy *phy) -{ - struct thunderbay_emmc_phy *tbh_phy = phy_get_drvdata(phy); - - tbh_phy->phy_power_sts = PHY_INITIALIZED; - - return thunderbay_emmc_phy_power(phy, 0); -} - -static const struct phy_ops thunderbay_emmc_phy_ops = { - .init = thunderbay_emmc_phy_init, - .exit = thunderbay_emmc_phy_exit, - .power_on = thunderbay_emmc_phy_power_on, - .power_off = thunderbay_emmc_phy_power_off, - .owner = THIS_MODULE, -}; - -static const struct of_device_id thunderbay_emmc_phy_of_match[] = { - { .compatible = "intel,thunderbay-emmc-phy", - (void *)&thunderbay_emmc_phy_ops }, - {} -}; -MODULE_DEVICE_TABLE(of, thunderbay_emmc_phy_of_match); - -static int thunderbay_emmc_phy_probe(struct platform_device *pdev) -{ - struct thunderbay_emmc_phy *tbh_phy; - struct phy_provider *phy_provider; - struct device *dev = &pdev->dev; - const struct of_device_id *id; - struct phy *generic_phy; - struct resource *res; - - if (!dev->of_node) - return -ENODEV; - - tbh_phy = devm_kzalloc(dev, sizeof(*tbh_phy), GFP_KERNEL); - if (!tbh_phy) - return -ENOMEM; - - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - tbh_phy->reg_base = devm_ioremap_resource(&pdev->dev, res); - if (IS_ERR(tbh_phy->reg_base)) - return PTR_ERR(tbh_phy->reg_base); - - tbh_phy->phy_power_sts = PHY_UNINITIALIZED; - id = of_match_node(thunderbay_emmc_phy_of_match, pdev->dev.of_node); - if (!id) { - dev_err(dev, "failed to get match_node\n"); - return -EINVAL; - } - - generic_phy = devm_phy_create(dev, dev->of_node, id->data); - if (IS_ERR(generic_phy)) { - dev_err(dev, "failed to create PHY\n"); - return PTR_ERR(generic_phy); - } - - phy_set_drvdata(generic_phy, tbh_phy); - phy_provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate); - - return PTR_ERR_OR_ZERO(phy_provider); -} - -static struct platform_driver thunderbay_emmc_phy_driver = { - .probe = thunderbay_emmc_phy_probe, - .driver = { - .name = "thunderbay-emmc-phy", - .of_match_table = thunderbay_emmc_phy_of_match, - }, -}; -module_platform_driver(thunderbay_emmc_phy_driver); - -MODULE_AUTHOR("Nandhini S <nandhini.srikandan@intel.com>"); -MODULE_AUTHOR("Rashmi A <rashmi.a@intel.com>"); -MODULE_DESCRIPTION("Intel Thunder Bay eMMC PHY driver"); -MODULE_LICENSE("GPL v2"); diff --git a/drivers/phy/marvell/phy-pxa-28nm-hsic.c b/drivers/phy/marvell/phy-pxa-28nm-hsic.c index c5c100563f55..eff6dd6b2dd0 100644 --- a/drivers/phy/marvell/phy-pxa-28nm-hsic.c +++ b/drivers/phy/marvell/phy-pxa-28nm-hsic.c @@ -199,7 +199,7 @@ static struct platform_driver mv_hsic_phy_driver = { .probe = mv_hsic_phy_probe, .driver = { .name = "mv-hsic-phy", - .of_match_table = of_match_ptr(mv_hsic_phy_dt_match), + .of_match_table = mv_hsic_phy_dt_match, }, }; module_platform_driver(mv_hsic_phy_driver); diff --git a/drivers/phy/marvell/phy-pxa-28nm-usb2.c b/drivers/phy/marvell/phy-pxa-28nm-usb2.c index 0b390b9d2ae1..1b2107f80f3a 100644 --- a/drivers/phy/marvell/phy-pxa-28nm-usb2.c +++ b/drivers/phy/marvell/phy-pxa-28nm-usb2.c @@ -331,7 +331,7 @@ static struct platform_driver mv_usb2_phy_driver = { .probe = mv_usb2_phy_probe, .driver = { .name = "mv-usb2-phy", - .of_match_table = of_match_ptr(mv_usbphy_dt_match), + .of_match_table = mv_usbphy_dt_match, }, }; module_platform_driver(mv_usb2_phy_driver); diff --git a/drivers/phy/mediatek/Makefile b/drivers/phy/mediatek/Makefile index fb1f8edaffa7..c9a50395533e 100644 --- a/drivers/phy/mediatek/Makefile +++ b/drivers/phy/mediatek/Makefile @@ -12,6 +12,7 @@ obj-$(CONFIG_PHY_MTK_XSPHY) += phy-mtk-xsphy.o phy-mtk-hdmi-drv-y := phy-mtk-hdmi.o phy-mtk-hdmi-drv-y += phy-mtk-hdmi-mt2701.o phy-mtk-hdmi-drv-y += phy-mtk-hdmi-mt8173.o +phy-mtk-hdmi-drv-y += phy-mtk-hdmi-mt8195.o obj-$(CONFIG_PHY_MTK_HDMI) += phy-mtk-hdmi-drv.o phy-mtk-mipi-dsi-drv-y := phy-mtk-mipi-dsi.o diff --git a/drivers/phy/mediatek/phy-mtk-hdmi-mt8195.c b/drivers/phy/mediatek/phy-mtk-hdmi-mt8195.c new file mode 100644 index 000000000000..abfc077fb0a8 --- /dev/null +++ b/drivers/phy/mediatek/phy-mtk-hdmi-mt8195.c @@ -0,0 +1,495 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2022 MediaTek Inc. + * Copyright (c) 2022 BayLibre, SAS + */ +#include <linux/delay.h> +#include <linux/io.h> +#include <linux/mfd/syscon.h> +#include <linux/module.h> +#include <linux/phy/phy.h> +#include <linux/platform_device.h> +#include <linux/types.h> +#include <linux/units.h> +#include <linux/nvmem-consumer.h> + +#include "phy-mtk-io.h" +#include "phy-mtk-hdmi.h" +#include "phy-mtk-hdmi-mt8195.h" + +static void mtk_hdmi_ana_fifo_en(struct mtk_hdmi_phy *hdmi_phy) +{ + /* make data fifo writable for hdmi2.0 */ + mtk_phy_set_bits(hdmi_phy->regs + HDMI_ANA_CTL, REG_ANA_HDMI20_FIFO_EN); +} + +static void +mtk_phy_tmds_clk_ratio(struct mtk_hdmi_phy *hdmi_phy, bool enable) +{ + void __iomem *regs = hdmi_phy->regs; + + mtk_hdmi_ana_fifo_en(hdmi_phy); + + /* HDMI 2.0 specification, 3.4Gbps <= TMDS Bit Rate <= 6G, + * clock bit ratio 1:40, under 3.4Gbps, clock bit ratio 1:10 + */ + if (enable) + mtk_phy_update_field(regs + HDMI20_CLK_CFG, REG_TXC_DIV, 3); + else + mtk_phy_clear_bits(regs + HDMI20_CLK_CFG, REG_TXC_DIV); +} + +static void mtk_hdmi_pll_sel_src(struct clk_hw *hw) +{ + struct mtk_hdmi_phy *hdmi_phy = to_mtk_hdmi_phy(hw); + void __iomem *regs = hdmi_phy->regs; + + mtk_phy_clear_bits(regs + HDMI_CTL_3, REG_HDMITX_REF_XTAL_SEL); + mtk_phy_clear_bits(regs + HDMI_CTL_3, REG_HDMITX_REF_RESPLL_SEL); + + /* DA_HDMITX21_REF_CK for TXPLL input source */ + mtk_phy_clear_bits(regs + HDMI_1_CFG_10, RG_HDMITXPLL_REF_CK_SEL); +} + +static void mtk_hdmi_pll_perf(struct clk_hw *hw) +{ + struct mtk_hdmi_phy *hdmi_phy = to_mtk_hdmi_phy(hw); + void __iomem *regs = hdmi_phy->regs; + + mtk_phy_set_bits(regs + HDMI_1_PLL_CFG_0, RG_HDMITXPLL_BP2); + mtk_phy_set_bits(regs + HDMI_1_PLL_CFG_2, RG_HDMITXPLL_BC); + mtk_phy_update_field(regs + HDMI_1_PLL_CFG_2, RG_HDMITXPLL_IC, 0x1); + mtk_phy_update_field(regs + HDMI_1_PLL_CFG_2, RG_HDMITXPLL_BR, 0x2); + mtk_phy_update_field(regs + HDMI_1_PLL_CFG_2, RG_HDMITXPLL_IR, 0x2); + mtk_phy_set_bits(regs + HDMI_1_PLL_CFG_2, RG_HDMITXPLL_BP); + mtk_phy_clear_bits(regs + HDMI_1_PLL_CFG_0, RG_HDMITXPLL_IBAND_FIX_EN); + mtk_phy_clear_bits(regs + HDMI_1_PLL_CFG_1, RG_HDMITXPLL_RESERVE_BIT14); + mtk_phy_clear_bits(regs + HDMI_1_PLL_CFG_2, RG_HDMITXPLL_HIKVCO); + mtk_phy_update_field(regs + HDMI_1_PLL_CFG_0, RG_HDMITXPLL_HREN, 0x1); + mtk_phy_update_field(regs + HDMI_1_PLL_CFG_0, RG_HDMITXPLL_LVR_SEL, 0x1); + mtk_phy_set_bits(regs + HDMI_1_PLL_CFG_1, RG_HDMITXPLL_RESERVE_BIT12_11); + mtk_phy_set_bits(regs + HDMI_1_PLL_CFG_0, RG_HDMITXPLL_TCL_EN); +} + +static int mtk_hdmi_pll_set_hw(struct clk_hw *hw, u8 prediv, + u8 fbkdiv_high, + u32 fbkdiv_low, + u8 fbkdiv_hs3, u8 posdiv1, + u8 posdiv2, u8 txprediv, + u8 txposdiv, + u8 digital_div) +{ + u8 txposdiv_value; + u8 div3_ctrl_value; + u8 posdiv_vallue; + u8 div_ctrl_value; + u8 reserve_3_2_value; + u8 prediv_value; + u8 reserve13_value; + struct mtk_hdmi_phy *hdmi_phy = to_mtk_hdmi_phy(hw); + void __iomem *regs = hdmi_phy->regs; + + mtk_hdmi_pll_sel_src(hw); + + mtk_hdmi_pll_perf(hw); + + mtk_phy_update_field(regs + HDMI_1_CFG_10, RG_HDMITX21_BIAS_PE_BG_VREF_SEL, 0x2); + mtk_phy_clear_bits(regs + HDMI_1_CFG_10, RG_HDMITX21_VREF_SEL); + mtk_phy_update_field(regs + HDMI_1_CFG_9, RG_HDMITX21_SLDO_VREF_SEL, 0x2); + mtk_phy_clear_bits(regs + HDMI_1_CFG_10, RG_HDMITX21_BIAS_PE_VREF_SELB); + mtk_phy_set_bits(regs + HDMI_1_CFG_3, RG_HDMITX21_SLDOLPF_EN); + mtk_phy_update_field(regs + HDMI_1_CFG_6, RG_HDMITX21_INTR_CAL, 0x11); + mtk_phy_set_bits(regs + HDMI_1_PLL_CFG_2, RG_HDMITXPLL_PWD); + + /* TXPOSDIV */ + txposdiv_value = ilog2(txposdiv); + + mtk_phy_update_field(regs + HDMI_1_CFG_6, RG_HDMITX21_TX_POSDIV, txposdiv_value); + mtk_phy_set_bits(regs + HDMI_1_CFG_6, RG_HDMITX21_TX_POSDIV_EN); + mtk_phy_clear_bits(regs + HDMI_1_CFG_6, RG_HDMITX21_FRL_EN); + + /* TXPREDIV */ + switch (txprediv) { + case 2: + div3_ctrl_value = 0x0; + posdiv_vallue = 0x0; + break; + case 4: + div3_ctrl_value = 0x0; + posdiv_vallue = 0x1; + break; + case 6: + div3_ctrl_value = 0x1; + posdiv_vallue = 0x0; + break; + case 12: + div3_ctrl_value = 0x1; + posdiv_vallue = 0x1; + break; + default: + return -EINVAL; + } + + mtk_phy_update_field(regs + HDMI_1_PLL_CFG_4, RG_HDMITXPLL_POSDIV_DIV3_CTRL, div3_ctrl_value); + mtk_phy_update_field(regs + HDMI_1_PLL_CFG_4, RG_HDMITXPLL_POSDIV, posdiv_vallue); + + /* POSDIV1 */ + switch (posdiv1) { + case 5: + div_ctrl_value = 0x0; + break; + case 10: + div_ctrl_value = 0x1; + break; + case 12: + div_ctrl_value = 0x2; + break; + case 15: + div_ctrl_value = 0x3; + break; + default: + return -EINVAL; + } + + mtk_phy_update_field(regs + HDMI_1_PLL_CFG_4, RG_HDMITXPLL_DIV_CTRL, div_ctrl_value); + + /* DE add new setting */ + mtk_phy_clear_bits(regs + HDMI_1_PLL_CFG_1, RG_HDMITXPLL_RESERVE_BIT14); + + /* POSDIV2 */ + switch (posdiv2) { + case 1: + reserve_3_2_value = 0x0; + break; + case 2: + reserve_3_2_value = 0x1; + break; + case 4: + reserve_3_2_value = 0x2; + break; + case 6: + reserve_3_2_value = 0x3; + break; + default: + return -EINVAL; + } + + mtk_phy_update_field(regs + HDMI_1_PLL_CFG_1, RG_HDMITXPLL_RESERVE_BIT3_2, reserve_3_2_value); + + /* DE add new setting */ + mtk_phy_update_field(regs + HDMI_1_PLL_CFG_1, RG_HDMITXPLL_RESERVE_BIT1_0, 0x2); + + /* PREDIV */ + prediv_value = ilog2(prediv); + + mtk_phy_update_field(regs + HDMI_1_PLL_CFG_4, RG_HDMITXPLL_PREDIV, prediv_value); + + /* FBKDIV_HS3 */ + reserve13_value = ilog2(fbkdiv_hs3); + + mtk_phy_update_field(regs + HDMI_1_PLL_CFG_1, RG_HDMITXPLL_RESERVE_BIT13, reserve13_value); + + /* FBDIV */ + mtk_phy_update_field(regs + HDMI_1_PLL_CFG_4, RG_HDMITXPLL_FBKDIV_HIGH, fbkdiv_high); + mtk_phy_update_field(regs + HDMI_1_PLL_CFG_3, RG_HDMITXPLL_FBKDIV_LOW, fbkdiv_low); + + /* Digital DIVIDER */ + mtk_phy_clear_bits(regs + HDMI_CTL_3, REG_PIXEL_CLOCK_SEL); + + if (digital_div == 1) { + mtk_phy_clear_bits(regs + HDMI_CTL_3, REG_HDMITX_PIXEL_CLOCK); + } else { + mtk_phy_set_bits(regs + HDMI_CTL_3, REG_HDMITX_PIXEL_CLOCK); + mtk_phy_update_field(regs + HDMI_CTL_3, REG_HDMITXPLL_DIV, digital_div - 1); + } + + return 0; +} + +static int mtk_hdmi_pll_calc(struct mtk_hdmi_phy *hdmi_phy, struct clk_hw *hw, + unsigned long rate, unsigned long parent_rate) +{ + u8 digital_div, txprediv, txposdiv, fbkdiv_high, posdiv1, posdiv2; + u64 tmds_clk, pixel_clk, da_hdmitx21_ref_ck, ns_hdmipll_ck, pcw; + u8 txpredivs[4] = { 2, 4, 6, 12 }; + u32 fbkdiv_low; + int i, ret; + + pixel_clk = rate; + tmds_clk = pixel_clk; + + if (tmds_clk < 25 * MEGA || tmds_clk > 594 * MEGA) + return -EINVAL; + + if (tmds_clk >= 340 * MEGA) + hdmi_phy->tmds_over_340M = true; + else + hdmi_phy->tmds_over_340M = false; + + /* in Hz */ + da_hdmitx21_ref_ck = 26 * MEGA; + + /* TXPOSDIV stage treatment: + * 0M < TMDS clk < 54M /8 + * 54M <= TMDS clk < 148.35M /4 + * 148.35M <=TMDS clk < 296.7M /2 + * 296.7 <=TMDS clk <= 594M /1 + */ + if (tmds_clk < 54 * MEGA) + txposdiv = 8; + else if (tmds_clk >= 54 * MEGA && tmds_clk < 148.35 * MEGA) + txposdiv = 4; + else if (tmds_clk >= 148.35 * MEGA && tmds_clk < 296.7 * MEGA) + txposdiv = 2; + else if (tmds_clk >= 296.7 * MEGA && tmds_clk <= 594 * MEGA) + txposdiv = 1; + else + return -EINVAL; + + /* calculate txprediv: can be 2, 4, 6, 12 + * ICO clk = 5*TMDS_CLK*TXPOSDIV*TXPREDIV + * ICO clk constraint: 5G =< ICO clk <= 12G + */ + for (i = 0; i < ARRAY_SIZE(txpredivs); i++) { + ns_hdmipll_ck = 5 * tmds_clk * txposdiv * txpredivs[i]; + if (ns_hdmipll_ck >= 5 * GIGA && + ns_hdmipll_ck <= 1 * GIGA) + break; + } + if (i == (ARRAY_SIZE(txpredivs) - 1) && + (ns_hdmipll_ck < 5 * GIGA || ns_hdmipll_ck > 12 * GIGA)) { + return -EINVAL; + } + if (i == ARRAY_SIZE(txpredivs)) + return -EINVAL; + + txprediv = txpredivs[i]; + + /* PCW calculation: FBKDIV + * formula: pcw=(frequency_out*2^pcw_bit) / frequency_in / FBKDIV_HS3; + * RG_HDMITXPLL_FBKDIV[32:0]: + * [32,24] 9bit integer, [23,0]:24bit fraction + */ + pcw = div_u64(((u64)ns_hdmipll_ck) << PCW_DECIMAL_WIDTH, + da_hdmitx21_ref_ck / PLL_FBKDIV_HS3); + + if (pcw > GENMASK_ULL(32, 0)) + return -EINVAL; + + fbkdiv_high = FIELD_GET(GENMASK_ULL(63, 32), pcw); + fbkdiv_low = FIELD_GET(GENMASK(31, 0), pcw); + + /* posdiv1: + * posdiv1 stage treatment according to color_depth: + * 24bit -> posdiv1 /10, 30bit -> posdiv1 /12.5, + * 36bit -> posdiv1 /15, 48bit -> posdiv1 /10 + */ + posdiv1 = 10; + posdiv2 = 1; + + /* Digital clk divider, max /32 */ + digital_div = div_u64((u64)ns_hdmipll_ck, posdiv1 / posdiv2 / pixel_clk); + if (!(digital_div <= 32 && digital_div >= 1)) + return -EINVAL; + + mtk_hdmi_pll_set_hw(hw, PLL_PREDIV, fbkdiv_high, fbkdiv_low, + PLL_FBKDIV_HS3, posdiv1, posdiv2, txprediv, + txposdiv, digital_div); + if (ret) + return -EINVAL; + + return 0; +} + +static int mtk_hdmi_pll_drv_setting(struct clk_hw *hw) +{ + struct mtk_hdmi_phy *hdmi_phy = to_mtk_hdmi_phy(hw); + void __iomem *regs = hdmi_phy->regs; + u8 data_channel_bias, clk_channel_bias; + u8 impedance, impedance_en; + u32 tmds_clk; + u32 pixel_clk = hdmi_phy->pll_rate; + + tmds_clk = pixel_clk; + + /* bias & impedance setting: + * 3G < data rate <= 6G: enable impedance 100ohm, + * data channel bias 24mA, clock channel bias 20mA + * pixel clk >= HD, 74.175MHZ <= pixel clk <= 300MHZ: + * enalbe impedance 100ohm + * data channel 20mA, clock channel 16mA + * 27M =< pixel clk < 74.175: disable impedance + * data channel & clock channel bias 10mA + */ + + /* 3G < data rate <= 6G, 300M < tmds rate <= 594M */ + if (tmds_clk > 300 * MEGA && tmds_clk <= 594 * MEGA) { + data_channel_bias = 0x3c; /* 24mA */ + clk_channel_bias = 0x34; /* 20mA */ + impedance_en = 0xf; + impedance = 0x36; /* 100ohm */ + } else if (pixel_clk >= 74.175 * MEGA && pixel_clk <= 300 * MEGA) { + data_channel_bias = 0x34; /* 20mA */ + clk_channel_bias = 0x2c; /* 16mA */ + impedance_en = 0xf; + impedance = 0x36; /* 100ohm */ + } else if (pixel_clk >= 27 * MEGA && pixel_clk < 74.175 * MEGA) { + data_channel_bias = 0x14; /* 10mA */ + clk_channel_bias = 0x14; /* 10mA */ + impedance_en = 0x0; + impedance = 0x0; + } else { + return -EINVAL; + } + + /* bias */ + mtk_phy_update_field(regs + HDMI_1_CFG_1, RG_HDMITX21_DRV_IBIAS_D0, data_channel_bias); + mtk_phy_update_field(regs + HDMI_1_CFG_1, RG_HDMITX21_DRV_IBIAS_D1, data_channel_bias); + mtk_phy_update_field(regs + HDMI_1_CFG_1, RG_HDMITX21_DRV_IBIAS_D2, data_channel_bias); + mtk_phy_update_field(regs + HDMI_1_CFG_0, RG_HDMITX21_DRV_IBIAS_CLK, clk_channel_bias); + + /* impedance */ + mtk_phy_update_field(regs + HDMI_1_CFG_0, RG_HDMITX21_DRV_IMP_EN, impedance_en); + mtk_phy_update_field(regs + HDMI_1_CFG_2, RG_HDMITX21_DRV_IMP_D0_EN1, impedance); + mtk_phy_update_field(regs + HDMI_1_CFG_2, RG_HDMITX21_DRV_IMP_D1_EN1, impedance); + mtk_phy_update_field(regs + HDMI_1_CFG_2, RG_HDMITX21_DRV_IMP_D2_EN1, impedance); + mtk_phy_update_field(regs + HDMI_1_CFG_2, RG_HDMITX21_DRV_IMP_CLK_EN1, impedance); + + return 0; +} + +static int mtk_hdmi_pll_prepare(struct clk_hw *hw) +{ + struct mtk_hdmi_phy *hdmi_phy = to_mtk_hdmi_phy(hw); + void __iomem *regs = hdmi_phy->regs; + + mtk_phy_set_bits(regs + HDMI_1_CFG_6, RG_HDMITX21_TX_POSDIV_EN); + + mtk_phy_set_bits(regs + HDMI_1_CFG_0, RG_HDMITX21_SER_EN); + mtk_phy_set_bits(regs + HDMI_1_CFG_6, RG_HDMITX21_D0_DRV_OP_EN); + mtk_phy_set_bits(regs + HDMI_1_CFG_6, RG_HDMITX21_D1_DRV_OP_EN); + mtk_phy_set_bits(regs + HDMI_1_CFG_6, RG_HDMITX21_D2_DRV_OP_EN); + mtk_phy_set_bits(regs + HDMI_1_CFG_6, RG_HDMITX21_CK_DRV_OP_EN); + + mtk_phy_clear_bits(regs + HDMI_1_CFG_6, RG_HDMITX21_FRL_D0_EN); + mtk_phy_clear_bits(regs + HDMI_1_CFG_6, RG_HDMITX21_FRL_D1_EN); + mtk_phy_clear_bits(regs + HDMI_1_CFG_6, RG_HDMITX21_FRL_D2_EN); + mtk_phy_clear_bits(regs + HDMI_1_CFG_6, RG_HDMITX21_FRL_CK_EN); + + mtk_hdmi_pll_drv_setting(hw); + + mtk_phy_clear_bits(regs + HDMI_1_CFG_10, RG_HDMITX21_BG_PWD); + mtk_phy_set_bits(regs + HDMI_1_CFG_6, RG_HDMITX21_BIAS_EN); + mtk_phy_set_bits(regs + HDMI_1_CFG_3, RG_HDMITX21_CKLDO_EN); + mtk_phy_set_bits(regs + HDMI_1_CFG_3, RG_HDMITX21_SLDO_EN); + + mtk_phy_set_bits(regs + HDMI_1_PLL_CFG_4, DA_HDMITXPLL_PWR_ON); + usleep_range(5, 10); + mtk_phy_clear_bits(regs + HDMI_1_PLL_CFG_4, DA_HDMITXPLL_ISO_EN); + usleep_range(5, 10); + mtk_phy_clear_bits(regs + HDMI_1_PLL_CFG_2, RG_HDMITXPLL_PWD); + usleep_range(30, 50); + return 0; +} + +static void mtk_hdmi_pll_unprepare(struct clk_hw *hw) +{ + struct mtk_hdmi_phy *hdmi_phy = to_mtk_hdmi_phy(hw); + void __iomem *regs = hdmi_phy->regs; + + mtk_phy_set_bits(regs + HDMI_1_CFG_10, RG_HDMITX21_BG_PWD); + mtk_phy_clear_bits(regs + HDMI_1_CFG_6, RG_HDMITX21_BIAS_EN); + mtk_phy_clear_bits(regs + HDMI_1_CFG_3, RG_HDMITX21_CKLDO_EN); + mtk_phy_clear_bits(regs + HDMI_1_CFG_3, RG_HDMITX21_SLDO_EN); + + mtk_phy_set_bits(regs + HDMI_1_PLL_CFG_2, RG_HDMITXPLL_PWD); + usleep_range(10, 20); + mtk_phy_set_bits(regs + HDMI_1_PLL_CFG_4, DA_HDMITXPLL_ISO_EN); + usleep_range(10, 20); + mtk_phy_clear_bits(regs + HDMI_1_PLL_CFG_4, DA_HDMITXPLL_PWR_ON); +} + +static int mtk_hdmi_pll_set_rate(struct clk_hw *hw, unsigned long rate, + unsigned long parent_rate) +{ + struct mtk_hdmi_phy *hdmi_phy = to_mtk_hdmi_phy(hw); + + dev_dbg(hdmi_phy->dev, "%s: %lu Hz, parent: %lu Hz\n", __func__, rate, + parent_rate); + + return mtk_hdmi_pll_calc(hdmi_phy, hw, rate, parent_rate); +} + +static long mtk_hdmi_pll_round_rate(struct clk_hw *hw, unsigned long rate, + unsigned long *parent_rate) +{ + struct mtk_hdmi_phy *hdmi_phy = to_mtk_hdmi_phy(hw); + + hdmi_phy->pll_rate = rate; + return rate; +} + +static unsigned long mtk_hdmi_pll_recalc_rate(struct clk_hw *hw, + unsigned long parent_rate) +{ + struct mtk_hdmi_phy *hdmi_phy = to_mtk_hdmi_phy(hw); + + return hdmi_phy->pll_rate; +} + +static const struct clk_ops mtk_hdmi_pll_ops = { + .prepare = mtk_hdmi_pll_prepare, + .unprepare = mtk_hdmi_pll_unprepare, + .set_rate = mtk_hdmi_pll_set_rate, + .round_rate = mtk_hdmi_pll_round_rate, + .recalc_rate = mtk_hdmi_pll_recalc_rate, +}; + +static void vtx_signal_en(struct mtk_hdmi_phy *hdmi_phy, bool on) +{ + void __iomem *regs = hdmi_phy->regs; + + if (on) + mtk_phy_set_bits(regs + HDMI_1_CFG_0, RG_HDMITX21_DRV_EN); + else + mtk_phy_clear_bits(regs + HDMI_1_CFG_0, RG_HDMITX21_DRV_EN); +} + +static void mtk_hdmi_phy_enable_tmds(struct mtk_hdmi_phy *hdmi_phy) +{ + vtx_signal_en(hdmi_phy, true); + usleep_range(100, 150); +} + +static void mtk_hdmi_phy_disable_tmds(struct mtk_hdmi_phy *hdmi_phy) +{ + vtx_signal_en(hdmi_phy, false); +} + +static int mtk_hdmi_phy_configure(struct phy *phy, union phy_configure_opts *opts) +{ + struct phy_configure_opts_dp *dp_opts = &opts->dp; + struct mtk_hdmi_phy *hdmi_phy = phy_get_drvdata(phy); + int ret; + + ret = clk_set_rate(hdmi_phy->pll, dp_opts->link_rate); + + if (ret) + return ret; + + mtk_phy_tmds_clk_ratio(hdmi_phy, hdmi_phy->tmds_over_340M); + + return ret; +} + +struct mtk_hdmi_phy_conf mtk_hdmi_phy_8195_conf = { + .flags = CLK_SET_RATE_PARENT | CLK_SET_RATE_GATE, + .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, + .hdmi_phy_configure = mtk_hdmi_phy_configure, +}; + +MODULE_AUTHOR("Can Zeng <can.zeng@mediatek.com>"); +MODULE_DESCRIPTION("MediaTek MT8195 HDMI PHY Driver"); +MODULE_LICENSE("GPL v2"); diff --git a/drivers/phy/mediatek/phy-mtk-hdmi-mt8195.h b/drivers/phy/mediatek/phy-mtk-hdmi-mt8195.h new file mode 100644 index 000000000000..22a68dc9550c --- /dev/null +++ b/drivers/phy/mediatek/phy-mtk-hdmi-mt8195.h @@ -0,0 +1,113 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2022 MediaTek Inc. + * Copyright (c) 2022 BayLibre, SAS + */ + +#ifndef _MTK_HDMI_PHY_8195_H +#define _MTK_HDMI_PHY_8195_H + +#include <linux/clk.h> +#include <linux/clk-provider.h> +#include <linux/types.h> + +#define PCW_DECIMAL_WIDTH 24 +#define PLL_PREDIV 1 +#define PLL_FBKDIV_HS3 1 + +#define HDMI20_CLK_CFG 0x70 +#define REG_TXC_DIV GENMASK(31, 30) + +#define HDMI_1_CFG_0 0x00 +#define RG_HDMITX21_DRV_IBIAS_CLK GENMASK(10, 5) +#define RG_HDMITX21_DRV_IMP_EN GENMASK(23, 20) +#define RG_HDMITX21_DRV_EN GENMASK(27, 24) +#define RG_HDMITX21_SER_EN GENMASK(31, 28) + +#define HDMI_1_CFG_1 0x04 +#define RG_HDMITX21_DRV_IBIAS_D0 GENMASK(19, 14) +#define RG_HDMITX21_DRV_IBIAS_D1 GENMASK(25, 20) +#define RG_HDMITX21_DRV_IBIAS_D2 GENMASK(31, 26) + +#define HDMI_1_CFG_10 0x40 +#define RG_HDMITXPLL_REF_CK_SEL GENMASK(2, 1) +#define RG_HDMITX21_VREF_SEL BIT(4) +#define RG_HDMITX21_BIAS_PE_VREF_SELB BIT(10) +#define RG_HDMITX21_BIAS_PE_BG_VREF_SEL GENMASK(16, 15) +#define RG_HDMITX21_BG_PWD BIT(20) + +#define HDMI_1_CFG_2 0x08 +#define RG_HDMITX21_DRV_IMP_D0_EN1 GENMASK(13, 8) +#define RG_HDMITX21_DRV_IMP_D1_EN1 GENMASK(19, 14) +#define RG_HDMITX21_DRV_IMP_D2_EN1 GENMASK(25, 20) +#define RG_HDMITX21_DRV_IMP_CLK_EN1 GENMASK(31, 26) + +#define HDMI_1_CFG_3 0x0c +#define RG_HDMITX21_CKLDO_EN BIT(3) +#define RG_HDMITX21_SLDOLPF_EN BIT(7) +#define RG_HDMITX21_SLDO_EN GENMASK(11, 8) + +#define HDMI_1_CFG_6 0x18 +#define RG_HDMITX21_D2_DRV_OP_EN BIT(8) +#define RG_HDMITX21_D1_DRV_OP_EN BIT(9) +#define RG_HDMITX21_D0_DRV_OP_EN BIT(10) +#define RG_HDMITX21_CK_DRV_OP_EN BIT(11) +#define RG_HDMITX21_FRL_EN BIT(12) +#define RG_HDMITX21_FRL_CK_EN BIT(13) +#define RG_HDMITX21_FRL_D0_EN BIT(14) +#define RG_HDMITX21_FRL_D1_EN BIT(15) +#define RG_HDMITX21_FRL_D2_EN BIT(16) +#define RG_HDMITX21_INTR_CAL GENMASK(22, 18) +#define RG_HDMITX21_TX_POSDIV GENMASK(27, 26) +#define RG_HDMITX21_TX_POSDIV_EN BIT(28) +#define RG_HDMITX21_BIAS_EN BIT(29) + +#define HDMI_1_CFG_9 0x24 +#define RG_HDMITX21_SLDO_VREF_SEL GENMASK(5, 4) + +#define HDMI_1_PLL_CFG_0 0x44 +#define RG_HDMITXPLL_HREN GENMASK(13, 12) +#define RG_HDMITXPLL_IBAND_FIX_EN BIT(24) +#define RG_HDMITXPLL_LVR_SEL GENMASK(27, 26) +#define RG_HDMITXPLL_BP2 BIT(30) +#define RG_HDMITXPLL_TCL_EN BIT(31) + +#define HDMI_1_PLL_CFG_1 0x48 +#define RG_HDMITXPLL_RESERVE_BIT1_0 GENMASK(1, 0) +#define RG_HDMITXPLL_RESERVE_BIT3_2 GENMASK(3, 2) +#define RG_HDMITXPLL_RESERVE_BIT12_11 GENMASK(12, 11) +#define RG_HDMITXPLL_RESERVE_BIT13 BIT(13) +#define RG_HDMITXPLL_RESERVE_BIT14 BIT(14) + +#define HDMI_1_PLL_CFG_2 0x4c +#define RG_HDMITXPLL_BC GENMASK(28, 27) +#define RG_HDMITXPLL_IC GENMASK(26, 22) +#define RG_HDMITXPLL_BR GENMASK(21, 19) +#define RG_HDMITXPLL_IR GENMASK(18, 14) +#define RG_HDMITXPLL_BP GENMASK(13, 10) +#define RG_HDMITXPLL_HIKVCO BIT(29) +#define RG_HDMITXPLL_PWD BIT(31) + +#define HDMI_1_PLL_CFG_3 0x50 +#define RG_HDMITXPLL_FBKDIV_LOW GENMASK(31, 0) + +#define HDMI_1_PLL_CFG_4 0x54 +#define DA_HDMITXPLL_ISO_EN BIT(1) +#define DA_HDMITXPLL_PWR_ON BIT(2) +#define RG_HDMITXPLL_POSDIV_DIV3_CTRL BIT(21) +#define RG_HDMITXPLL_POSDIV GENMASK(23, 22) +#define RG_HDMITXPLL_DIV_CTRL GENMASK(25, 24) +#define RG_HDMITXPLL_PREDIV GENMASK(29, 28) +#define RG_HDMITXPLL_FBKDIV_HIGH BIT(31) + +#define HDMI_ANA_CTL 0x7c +#define REG_ANA_HDMI20_FIFO_EN BIT(16) + +#define HDMI_CTL_3 0xcc +#define REG_HDMITXPLL_DIV GENMASK(4, 0) +#define REG_HDMITX_REF_XTAL_SEL BIT(7) +#define REG_HDMITX_REF_RESPLL_SEL BIT(9) +#define REG_PIXEL_CLOCK_SEL BIT(10) +#define REG_HDMITX_PIXEL_CLOCK BIT(23) + +#endif /* MTK_HDMI_PHY_8195_H */ diff --git a/drivers/phy/mediatek/phy-mtk-hdmi.c b/drivers/phy/mediatek/phy-mtk-hdmi.c index b16d437d6721..d2e824771f9d 100644 --- a/drivers/phy/mediatek/phy-mtk-hdmi.c +++ b/drivers/phy/mediatek/phy-mtk-hdmi.c @@ -8,10 +8,12 @@ static int mtk_hdmi_phy_power_on(struct phy *phy); static int mtk_hdmi_phy_power_off(struct phy *phy); +static int mtk_hdmi_phy_configure(struct phy *phy, union phy_configure_opts *opts); static const struct phy_ops mtk_hdmi_phy_dev_ops = { .power_on = mtk_hdmi_phy_power_on, .power_off = mtk_hdmi_phy_power_off, + .configure = mtk_hdmi_phy_configure, .owner = THIS_MODULE, }; @@ -43,6 +45,16 @@ static int mtk_hdmi_phy_power_off(struct phy *phy) return 0; } +static int mtk_hdmi_phy_configure(struct phy *phy, union phy_configure_opts *opts) +{ + struct mtk_hdmi_phy *hdmi_phy = phy_get_drvdata(phy); + + if (hdmi_phy->conf->hdmi_phy_configure) + return hdmi_phy->conf->hdmi_phy_configure(phy, opts); + + return 0; +} + static const struct phy_ops * mtk_hdmi_phy_dev_get_ops(const struct mtk_hdmi_phy *hdmi_phy) { @@ -149,6 +161,9 @@ static const struct of_device_id mtk_hdmi_phy_match[] = { { .compatible = "mediatek,mt8173-hdmi-phy", .data = &mtk_hdmi_phy_8173_conf, }, + { .compatible = "mediatek,mt8195-hdmi-phy", + .data = &mtk_hdmi_phy_8195_conf, + }, {}, }; MODULE_DEVICE_TABLE(of, mtk_hdmi_phy_match); diff --git a/drivers/phy/mediatek/phy-mtk-hdmi.h b/drivers/phy/mediatek/phy-mtk-hdmi.h index c7fa65cff989..fc2ad6a0527f 100644 --- a/drivers/phy/mediatek/phy-mtk-hdmi.h +++ b/drivers/phy/mediatek/phy-mtk-hdmi.h @@ -24,6 +24,7 @@ struct mtk_hdmi_phy_conf { 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); + int (*hdmi_phy_configure)(struct phy *phy, union phy_configure_opts *opts); }; struct mtk_hdmi_phy { @@ -39,10 +40,12 @@ struct mtk_hdmi_phy { unsigned char drv_imp_d0; unsigned int ibias; unsigned int ibias_up; + bool tmds_over_340M; }; struct mtk_hdmi_phy *to_mtk_hdmi_phy(struct clk_hw *hw); +extern struct mtk_hdmi_phy_conf mtk_hdmi_phy_8195_conf; extern struct mtk_hdmi_phy_conf mtk_hdmi_phy_8173_conf; extern struct mtk_hdmi_phy_conf mtk_hdmi_phy_2701_conf; diff --git a/drivers/phy/mediatek/phy-mtk-mipi-dsi.c b/drivers/phy/mediatek/phy-mtk-mipi-dsi.c index cf9c386385bb..526c05a4af5e 100644 --- a/drivers/phy/mediatek/phy-mtk-mipi-dsi.c +++ b/drivers/phy/mediatek/phy-mtk-mipi-dsi.c @@ -180,10 +180,9 @@ static int mtk_mipi_tx_probe(struct platform_device *pdev) mipi_tx->pll); } -static int mtk_mipi_tx_remove(struct platform_device *pdev) +static void mtk_mipi_tx_remove(struct platform_device *pdev) { of_clk_del_provider(pdev->dev.of_node); - return 0; } static const struct of_device_id mtk_mipi_tx_match[] = { @@ -199,7 +198,7 @@ MODULE_DEVICE_TABLE(of, mtk_mipi_tx_match); static struct platform_driver mtk_mipi_tx_driver = { .probe = mtk_mipi_tx_probe, - .remove = mtk_mipi_tx_remove, + .remove_new = mtk_mipi_tx_remove, .driver = { .name = "mediatek-mipi-tx", .of_match_table = mtk_mipi_tx_match, diff --git a/drivers/phy/motorola/phy-cpcap-usb.c b/drivers/phy/motorola/phy-cpcap-usb.c index 2f8210167b77..74333e814221 100644 --- a/drivers/phy/motorola/phy-cpcap-usb.c +++ b/drivers/phy/motorola/phy-cpcap-usb.c @@ -692,7 +692,7 @@ out_reg_disable: return error; } -static int cpcap_usb_phy_remove(struct platform_device *pdev) +static void cpcap_usb_phy_remove(struct platform_device *pdev) { struct cpcap_phy_ddata *ddata = platform_get_drvdata(pdev); int error; @@ -707,13 +707,11 @@ static int cpcap_usb_phy_remove(struct platform_device *pdev) usb_remove_phy(&ddata->phy); cancel_delayed_work_sync(&ddata->detect_work); regulator_disable(ddata->vusb); - - return 0; } static struct platform_driver cpcap_usb_phy_driver = { .probe = cpcap_usb_phy_probe, - .remove = cpcap_usb_phy_remove, + .remove_new = cpcap_usb_phy_remove, .driver = { .name = "cpcap-usb-phy", .of_match_table = of_match_ptr(cpcap_usb_phy_id_table), diff --git a/drivers/phy/motorola/phy-mapphone-mdm6600.c b/drivers/phy/motorola/phy-mapphone-mdm6600.c index 3cd4d51c247c..1d567604b650 100644 --- a/drivers/phy/motorola/phy-mapphone-mdm6600.c +++ b/drivers/phy/motorola/phy-mapphone-mdm6600.c @@ -634,7 +634,7 @@ cleanup: return error; } -static int phy_mdm6600_remove(struct platform_device *pdev) +static void phy_mdm6600_remove(struct platform_device *pdev) { struct phy_mdm6600 *ddata = platform_get_drvdata(pdev); struct gpio_desc *reset_gpio = ddata->ctrl_gpios[PHY_MDM6600_RESET]; @@ -653,13 +653,11 @@ static int phy_mdm6600_remove(struct platform_device *pdev) cancel_delayed_work_sync(&ddata->modem_wake_work); cancel_delayed_work_sync(&ddata->bootup_work); cancel_delayed_work_sync(&ddata->status_work); - - return 0; } static struct platform_driver phy_mdm6600_driver = { .probe = phy_mdm6600_probe, - .remove = phy_mdm6600_remove, + .remove_new = phy_mdm6600_remove, .driver = { .name = "phy-mapphone-mdm6600", .pm = &phy_mdm6600_pm_ops, diff --git a/drivers/phy/phy-lgm-usb.c b/drivers/phy/phy-lgm-usb.c index 309c8f0e0724..410729c7f513 100644 --- a/drivers/phy/phy-lgm-usb.c +++ b/drivers/phy/phy-lgm-usb.c @@ -252,13 +252,11 @@ static int phy_probe(struct platform_device *pdev) return usb_add_phy_dev(phy); } -static int phy_remove(struct platform_device *pdev) +static void phy_remove(struct platform_device *pdev) { struct tca_apb *ta = platform_get_drvdata(pdev); usb_remove_phy(&ta->phy); - - return 0; } static const struct of_device_id intel_usb_phy_dt_ids[] = { @@ -273,7 +271,7 @@ static struct platform_driver lgm_phy_driver = { .of_match_table = intel_usb_phy_dt_ids, }, .probe = phy_probe, - .remove = phy_remove, + .remove_new = phy_remove, }; module_platform_driver(lgm_phy_driver); diff --git a/drivers/phy/qualcomm/phy-qcom-apq8064-sata.c b/drivers/phy/qualcomm/phy-qcom-apq8064-sata.c index d437a249cd73..8814f4322adf 100644 --- a/drivers/phy/qualcomm/phy-qcom-apq8064-sata.c +++ b/drivers/phy/qualcomm/phy-qcom-apq8064-sata.c @@ -243,13 +243,11 @@ static int qcom_apq8064_sata_phy_probe(struct platform_device *pdev) return 0; } -static int qcom_apq8064_sata_phy_remove(struct platform_device *pdev) +static void qcom_apq8064_sata_phy_remove(struct platform_device *pdev) { struct qcom_apq8064_sata_phy *phy = platform_get_drvdata(pdev); clk_disable_unprepare(phy->cfg_clk); - - return 0; } static const struct of_device_id qcom_apq8064_sata_phy_of_match[] = { @@ -260,7 +258,7 @@ MODULE_DEVICE_TABLE(of, qcom_apq8064_sata_phy_of_match); static struct platform_driver qcom_apq8064_sata_phy_driver = { .probe = qcom_apq8064_sata_phy_probe, - .remove = qcom_apq8064_sata_phy_remove, + .remove_new = qcom_apq8064_sata_phy_remove, .driver = { .name = "qcom-apq8064-sata-phy", .of_match_table = qcom_apq8064_sata_phy_of_match, diff --git a/drivers/phy/qualcomm/phy-qcom-eusb2-repeater.c b/drivers/phy/qualcomm/phy-qcom-eusb2-repeater.c index 3f265ac2df20..90f8543ba265 100644 --- a/drivers/phy/qualcomm/phy-qcom-eusb2-repeater.c +++ b/drivers/phy/qualcomm/phy-qcom-eusb2-repeater.c @@ -223,16 +223,14 @@ static int eusb2_repeater_probe(struct platform_device *pdev) return 0; } -static int eusb2_repeater_remove(struct platform_device *pdev) +static void eusb2_repeater_remove(struct platform_device *pdev) { struct eusb2_repeater *rptr = platform_get_drvdata(pdev); if (!rptr) - return 0; + return; eusb2_repeater_exit(rptr->phy); - - return 0; } static const struct of_device_id eusb2_repeater_of_match_table[] = { @@ -246,7 +244,7 @@ MODULE_DEVICE_TABLE(of, eusb2_repeater_of_match_table); static struct platform_driver eusb2_repeater_driver = { .probe = eusb2_repeater_probe, - .remove = eusb2_repeater_remove, + .remove_new = eusb2_repeater_remove, .driver = { .name = "qcom-eusb2-repeater", .of_match_table = eusb2_repeater_of_match_table, diff --git a/drivers/phy/qualcomm/phy-qcom-ipq806x-sata.c b/drivers/phy/qualcomm/phy-qcom-ipq806x-sata.c index 0fc2a1ed39b3..f0a72b82c770 100644 --- a/drivers/phy/qualcomm/phy-qcom-ipq806x-sata.c +++ b/drivers/phy/qualcomm/phy-qcom-ipq806x-sata.c @@ -170,13 +170,11 @@ static int qcom_ipq806x_sata_phy_probe(struct platform_device *pdev) return 0; } -static int qcom_ipq806x_sata_phy_remove(struct platform_device *pdev) +static void qcom_ipq806x_sata_phy_remove(struct platform_device *pdev) { struct qcom_ipq806x_sata_phy *phy = platform_get_drvdata(pdev); clk_disable_unprepare(phy->cfg_clk); - - return 0; } static const struct of_device_id qcom_ipq806x_sata_phy_of_match[] = { @@ -187,7 +185,7 @@ MODULE_DEVICE_TABLE(of, qcom_ipq806x_sata_phy_of_match); static struct platform_driver qcom_ipq806x_sata_phy_driver = { .probe = qcom_ipq806x_sata_phy_probe, - .remove = qcom_ipq806x_sata_phy_remove, + .remove_new = qcom_ipq806x_sata_phy_remove, .driver = { .name = "qcom-ipq806x-sata-phy", .of_match_table = qcom_ipq806x_sata_phy_of_match, diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-combo.c b/drivers/phy/qualcomm/phy-qcom-qmp-combo.c index c1483e157af4..6850e04c329b 100644 --- a/drivers/phy/qualcomm/phy-qcom-qmp-combo.c +++ b/drivers/phy/qualcomm/phy-qcom-qmp-combo.c @@ -1396,6 +1396,7 @@ static const struct qmp_combo_offsets qmp_combo_offsets_v3 = { .usb3_serdes = 0x1000, .usb3_pcs_misc = 0x1a00, .usb3_pcs = 0x1c00, + .usb3_pcs_usb = 0x1f00, .dp_serdes = 0x2000, .dp_txa = 0x2200, .dp_txb = 0x2600, @@ -1416,22 +1417,6 @@ static const struct qmp_combo_offsets qmp_combo_offsets_v5 = { .dp_dp_phy = 0x2200, }; -static const struct qmp_combo_offsets qmp_combo_offsets_v6 = { - .com = 0x0000, - .txa = 0x1200, - .rxa = 0x1400, - .txb = 0x1600, - .rxb = 0x1800, - .usb3_serdes = 0x1000, - .usb3_pcs_misc = 0x1a00, - .usb3_pcs = 0x1c00, - .usb3_pcs_usb = 0x1f00, - .dp_serdes = 0x2000, - .dp_txa = 0x2200, - .dp_txb = 0x2600, - .dp_dp_phy = 0x2a00, -}; - static const struct qmp_phy_cfg sc7180_usb3dpphy_cfg = { .serdes_tbl = qmp_v3_usb3_serdes_tbl, .serdes_tbl_num = ARRAY_SIZE(qmp_v3_usb3_serdes_tbl), @@ -1758,7 +1743,7 @@ static const struct qmp_phy_cfg sm8350_usb3dpphy_cfg = { }; static const struct qmp_phy_cfg sm8550_usb3dpphy_cfg = { - .offsets = &qmp_combo_offsets_v6, + .offsets = &qmp_combo_offsets_v3, .serdes_tbl = sm8550_usb3_serdes_tbl, .serdes_tbl_num = ARRAY_SIZE(sm8550_usb3_serdes_tbl), diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-pcie.c b/drivers/phy/qualcomm/phy-qcom-qmp-pcie.c index 5182aeac43ee..df505279edfd 100644 --- a/drivers/phy/qualcomm/phy-qcom-qmp-pcie.c +++ b/drivers/phy/qualcomm/phy-qcom-qmp-pcie.c @@ -725,9 +725,6 @@ static const struct qmp_phy_init_tbl sdm845_qhp_pcie_tx_tbl[] = { QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_L0_RSM_START, 0x01), }; -static const struct qmp_phy_init_tbl sdm845_qhp_pcie_rx_tbl[] = { -}; - static const struct qmp_phy_init_tbl sdm845_qhp_pcie_pcs_tbl[] = { QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_PHY_POWER_STATE_CONFIG, 0x3f), QMP_PHY_INIT_CFG(PCIE_GEN3_QHP_PHY_PCS_TX_RX_CONFIG, 0x50), @@ -1130,10 +1127,60 @@ static const struct qmp_phy_init_tbl sm8250_qmp_gen3x2_pcie_pcs_misc_tbl[] = { }; static const struct qmp_phy_init_tbl sdx55_qmp_pcie_serdes_tbl[] = { - QMP_PHY_INIT_CFG(QSERDES_V4_COM_BG_TIMER, 0x02), QMP_PHY_INIT_CFG(QSERDES_V4_COM_BIAS_EN_CLKBUFLR_EN, 0x18), - QMP_PHY_INIT_CFG(QSERDES_V4_COM_SYS_CLK_CTRL, 0x07), QMP_PHY_INIT_CFG(QSERDES_V4_COM_PLL_IVCO, 0x0f), + QMP_PHY_INIT_CFG(QSERDES_V4_COM_LOCK_CMP_EN, 0x46), + QMP_PHY_INIT_CFG(QSERDES_V4_COM_LOCK_CMP_CFG, 0x04), + QMP_PHY_INIT_CFG(QSERDES_V4_COM_VCO_TUNE_MAP, 0x02), + QMP_PHY_INIT_CFG(QSERDES_V4_COM_HSCLK_SEL, 0x12), + QMP_PHY_INIT_CFG(QSERDES_V4_COM_HSCLK_HS_SWITCH_SEL, 0x00), + QMP_PHY_INIT_CFG(QSERDES_V4_COM_CORECLK_DIV_MODE0, 0x05), + QMP_PHY_INIT_CFG(QSERDES_V4_COM_CORECLK_DIV_MODE1, 0x04), + QMP_PHY_INIT_CFG(QSERDES_V4_COM_CMN_MISC1, 0x88), + QMP_PHY_INIT_CFG(QSERDES_V4_COM_CMN_MISC2, 0x03), + QMP_PHY_INIT_CFG(QSERDES_V4_COM_CMN_MODE, 0x17), + QMP_PHY_INIT_CFG(QSERDES_V4_COM_VCO_DC_LEVEL_CTRL, 0x0b), + QMP_PHY_INIT_CFG(QSERDES_V4_COM_BIN_VCOCAL_HSCLK_SEL, 0x22), +}; + +static const struct qmp_phy_init_tbl sdx55_qmp_pcie_rc_serdes_tbl[] = { + QMP_PHY_INIT_CFG(QSERDES_V4_COM_SSC_EN_CENTER, 0x01), + QMP_PHY_INIT_CFG(QSERDES_V4_COM_SSC_PER1, 0x31), + QMP_PHY_INIT_CFG(QSERDES_V4_COM_SSC_PER2, 0x01), + QMP_PHY_INIT_CFG(QSERDES_V4_COM_SSC_STEP_SIZE1_MODE0, 0xce), + QMP_PHY_INIT_CFG(QSERDES_V4_COM_SSC_STEP_SIZE2_MODE0, 0x0b), + QMP_PHY_INIT_CFG(QSERDES_V4_COM_SSC_STEP_SIZE1_MODE1, 0x97), + QMP_PHY_INIT_CFG(QSERDES_V4_COM_SSC_STEP_SIZE2_MODE1, 0x0c), + QMP_PHY_INIT_CFG(QSERDES_V4_COM_CLK_ENABLE1, 0x90), + QMP_PHY_INIT_CFG(QSERDES_V4_COM_CLK_EP_DIV_MODE0, 0x0a), + QMP_PHY_INIT_CFG(QSERDES_V4_COM_CLK_EP_DIV_MODE1, 0x10), + QMP_PHY_INIT_CFG(QSERDES_V4_COM_CP_CTRL_MODE0, 0x06), + QMP_PHY_INIT_CFG(QSERDES_V4_COM_CP_CTRL_MODE1, 0x06), + QMP_PHY_INIT_CFG(QSERDES_V4_COM_PLL_RCTRL_MODE0, 0x16), + QMP_PHY_INIT_CFG(QSERDES_V4_COM_PLL_RCTRL_MODE1, 0x16), + QMP_PHY_INIT_CFG(QSERDES_V4_COM_PLL_CCTRL_MODE0, 0x36), + QMP_PHY_INIT_CFG(QSERDES_V4_COM_PLL_CCTRL_MODE1, 0x36), + QMP_PHY_INIT_CFG(QSERDES_V4_COM_SYSCLK_EN_SEL, 0x08), + QMP_PHY_INIT_CFG(QSERDES_V4_COM_LOCK_CMP1_MODE0, 0x04), + QMP_PHY_INIT_CFG(QSERDES_V4_COM_LOCK_CMP2_MODE0, 0x0d), + QMP_PHY_INIT_CFG(QSERDES_V4_COM_LOCK_CMP1_MODE1, 0x0a), + QMP_PHY_INIT_CFG(QSERDES_V4_COM_LOCK_CMP2_MODE1, 0x1a), + QMP_PHY_INIT_CFG(QSERDES_V4_COM_DEC_START_MODE0, 0xc3), + QMP_PHY_INIT_CFG(QSERDES_V4_COM_DEC_START_MODE1, 0xd0), + QMP_PHY_INIT_CFG(QSERDES_V4_COM_DIV_FRAC_START3_MODE0, 0x05), + QMP_PHY_INIT_CFG(QSERDES_V4_COM_DIV_FRAC_START1_MODE1, 0x55), + QMP_PHY_INIT_CFG(QSERDES_V4_COM_DIV_FRAC_START2_MODE1, 0x55), + QMP_PHY_INIT_CFG(QSERDES_V4_COM_DIV_FRAC_START3_MODE1, 0x05), + QMP_PHY_INIT_CFG(QSERDES_V4_COM_CLK_SELECT, 0x34), + QMP_PHY_INIT_CFG(QSERDES_V4_COM_BIN_VCOCAL_CMP_CODE1_MODE0, 0xca), + QMP_PHY_INIT_CFG(QSERDES_V4_COM_BIN_VCOCAL_CMP_CODE2_MODE0, 0x1e), + QMP_PHY_INIT_CFG(QSERDES_V4_COM_BIN_VCOCAL_CMP_CODE1_MODE1, 0xd8), + QMP_PHY_INIT_CFG(QSERDES_V4_COM_BIN_VCOCAL_CMP_CODE2_MODE1, 0x20), +}; + +static const struct qmp_phy_init_tbl sdx55_qmp_pcie_ep_serdes_tbl[] = { + QMP_PHY_INIT_CFG(QSERDES_V4_COM_BG_TIMER, 0x02), + QMP_PHY_INIT_CFG(QSERDES_V4_COM_SYS_CLK_CTRL, 0x07), QMP_PHY_INIT_CFG(QSERDES_V4_COM_CP_CTRL_MODE0, 0x0a), QMP_PHY_INIT_CFG(QSERDES_V4_COM_CP_CTRL_MODE1, 0x0a), QMP_PHY_INIT_CFG(QSERDES_V4_COM_PLL_RCTRL_MODE0, 0x19), @@ -1141,8 +1188,6 @@ static const struct qmp_phy_init_tbl sdx55_qmp_pcie_serdes_tbl[] = { QMP_PHY_INIT_CFG(QSERDES_V4_COM_PLL_CCTRL_MODE0, 0x03), QMP_PHY_INIT_CFG(QSERDES_V4_COM_PLL_CCTRL_MODE1, 0x03), QMP_PHY_INIT_CFG(QSERDES_V4_COM_SYSCLK_EN_SEL, 0x00), - QMP_PHY_INIT_CFG(QSERDES_V4_COM_LOCK_CMP_EN, 0x46), - QMP_PHY_INIT_CFG(QSERDES_V4_COM_LOCK_CMP_CFG, 0x04), QMP_PHY_INIT_CFG(QSERDES_V4_COM_LOCK_CMP1_MODE0, 0x7f), QMP_PHY_INIT_CFG(QSERDES_V4_COM_LOCK_CMP2_MODE0, 0x02), QMP_PHY_INIT_CFG(QSERDES_V4_COM_LOCK_CMP1_MODE1, 0xff), @@ -1154,21 +1199,11 @@ static const struct qmp_phy_init_tbl sdx55_qmp_pcie_serdes_tbl[] = { QMP_PHY_INIT_CFG(QSERDES_V4_COM_INTEGLOOP_GAIN1_MODE0, 0x01), QMP_PHY_INIT_CFG(QSERDES_V4_COM_INTEGLOOP_GAIN0_MODE1, 0xfb), QMP_PHY_INIT_CFG(QSERDES_V4_COM_INTEGLOOP_GAIN1_MODE1, 0x01), - QMP_PHY_INIT_CFG(QSERDES_V4_COM_VCO_TUNE_MAP, 0x02), - QMP_PHY_INIT_CFG(QSERDES_V4_COM_HSCLK_SEL, 0x12), - QMP_PHY_INIT_CFG(QSERDES_V4_COM_HSCLK_HS_SWITCH_SEL, 0x00), - QMP_PHY_INIT_CFG(QSERDES_V4_COM_CORECLK_DIV_MODE0, 0x05), - QMP_PHY_INIT_CFG(QSERDES_V4_COM_CORECLK_DIV_MODE1, 0x04), QMP_PHY_INIT_CFG(QSERDES_V4_COM_CMN_CONFIG, 0x04), - QMP_PHY_INIT_CFG(QSERDES_V4_COM_CMN_MISC1, 0x88), - QMP_PHY_INIT_CFG(QSERDES_V4_COM_CMN_MISC2, 0x03), - QMP_PHY_INIT_CFG(QSERDES_V4_COM_CMN_MODE, 0x17), - QMP_PHY_INIT_CFG(QSERDES_V4_COM_VCO_DC_LEVEL_CTRL, 0x0b), QMP_PHY_INIT_CFG(QSERDES_V4_COM_BIN_VCOCAL_CMP_CODE1_MODE0, 0x56), QMP_PHY_INIT_CFG(QSERDES_V4_COM_BIN_VCOCAL_CMP_CODE2_MODE0, 0x1d), QMP_PHY_INIT_CFG(QSERDES_V4_COM_BIN_VCOCAL_CMP_CODE1_MODE1, 0x4b), QMP_PHY_INIT_CFG(QSERDES_V4_COM_BIN_VCOCAL_CMP_CODE2_MODE1, 0x1f), - QMP_PHY_INIT_CFG(QSERDES_V4_COM_BIN_VCOCAL_HSCLK_SEL, 0x22), }; static const struct qmp_phy_init_tbl sdx55_qmp_pcie_tx_tbl[] = { @@ -1220,10 +1255,151 @@ static const struct qmp_phy_init_tbl sdx55_qmp_pcie_pcs_misc_tbl[] = { QMP_PHY_INIT_CFG(QPHY_V4_20_PCS_PCIE_G4_RXEQEVAL_TIME, 0x13), QMP_PHY_INIT_CFG(QPHY_V4_20_PCS_PCIE_G4_EQ_CONFIG2, 0x01), QMP_PHY_INIT_CFG(QPHY_V4_20_PCS_PCIE_G4_EQ_CONFIG5, 0x02), +}; + +static const struct qmp_phy_init_tbl sdx55_qmp_pcie_rc_pcs_misc_tbl[] = { + QMP_PHY_INIT_CFG(QPHY_V4_20_PCS_PCIE_ENDPOINT_REFCLK_DRIVE, 0xc1), + 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[] = { 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), }; +static const struct qmp_phy_init_tbl sdx65_qmp_pcie_serdes_tbl[] = { + QMP_PHY_INIT_CFG(QSERDES_V5_COM_BG_TIMER, 0x02), + QMP_PHY_INIT_CFG(QSERDES_V5_COM_BIAS_EN_CLKBUFLR_EN, 0x14), + QMP_PHY_INIT_CFG(QSERDES_V5_COM_SYS_CLK_CTRL, 0x07), + QMP_PHY_INIT_CFG(QSERDES_V5_COM_PLL_IVCO, 0x0f), + QMP_PHY_INIT_CFG(QSERDES_V5_COM_CP_CTRL_MODE0, 0x27), + QMP_PHY_INIT_CFG(QSERDES_V5_COM_CP_CTRL_MODE1, 0x0a), + QMP_PHY_INIT_CFG(QSERDES_V5_COM_PLL_RCTRL_MODE0, 0x17), + QMP_PHY_INIT_CFG(QSERDES_V5_COM_PLL_RCTRL_MODE1, 0x19), + QMP_PHY_INIT_CFG(QSERDES_V5_COM_PLL_CCTRL_MODE0, 0x00), + QMP_PHY_INIT_CFG(QSERDES_V5_COM_PLL_CCTRL_MODE1, 0x03), + QMP_PHY_INIT_CFG(QSERDES_V5_COM_SYSCLK_EN_SEL, 0x00), + QMP_PHY_INIT_CFG(QSERDES_V5_COM_LOCK_CMP_EN, 0x46), + QMP_PHY_INIT_CFG(QSERDES_V5_COM_LOCK_CMP_CFG, 0x04), + QMP_PHY_INIT_CFG(QSERDES_V5_COM_LOCK_CMP1_MODE0, 0xff), + QMP_PHY_INIT_CFG(QSERDES_V5_COM_LOCK_CMP2_MODE0, 0x04), + QMP_PHY_INIT_CFG(QSERDES_V5_COM_LOCK_CMP1_MODE1, 0xff), + QMP_PHY_INIT_CFG(QSERDES_V5_COM_LOCK_CMP2_MODE1, 0x09), + QMP_PHY_INIT_CFG(QSERDES_V5_COM_DEC_START_MODE0, 0x19), + QMP_PHY_INIT_CFG(QSERDES_V5_COM_DEC_START_MODE1, 0x28), + QMP_PHY_INIT_CFG(QSERDES_V5_COM_INTEGLOOP_GAIN0_MODE0, 0xfb), + QMP_PHY_INIT_CFG(QSERDES_V5_COM_INTEGLOOP_GAIN1_MODE0, 0x01), + QMP_PHY_INIT_CFG(QSERDES_V5_COM_INTEGLOOP_GAIN0_MODE1, 0xfb), + QMP_PHY_INIT_CFG(QSERDES_V5_COM_INTEGLOOP_GAIN1_MODE1, 0x01), + QMP_PHY_INIT_CFG(QSERDES_V5_COM_VCO_TUNE_MAP, 0x02), + QMP_PHY_INIT_CFG(QSERDES_V5_COM_HSCLK_SEL, 0x12), + QMP_PHY_INIT_CFG(QSERDES_V5_COM_HSCLK_HS_SWITCH_SEL, 0x00), + QMP_PHY_INIT_CFG(QSERDES_V5_COM_CORECLK_DIV_MODE0, 0x0a), + QMP_PHY_INIT_CFG(QSERDES_V5_COM_CORECLK_DIV_MODE1, 0x04), + QMP_PHY_INIT_CFG(QSERDES_V5_COM_CORE_CLK_EN, 0x60), + QMP_PHY_INIT_CFG(QSERDES_V5_COM_CMN_MISC1, 0x88), + QMP_PHY_INIT_CFG(QSERDES_V5_COM_CMN_CONFIG, 0x06), + QMP_PHY_INIT_CFG(QSERDES_V5_COM_CMN_MODE, 0x14), + QMP_PHY_INIT_CFG(QSERDES_V5_COM_CMN_MODE_CONTD, 0x00), + QMP_PHY_INIT_CFG(QSERDES_V5_COM_VCO_DC_LEVEL_CTRL, 0x0f), +}; + +static const struct qmp_phy_init_tbl sdx65_qmp_pcie_tx_tbl[] = { + QMP_PHY_INIT_CFG(QSERDES_V5_20_TX_LANE_MODE_1, 0x05), + QMP_PHY_INIT_CFG(QSERDES_V5_20_TX_LANE_MODE_2, 0xf6), + QMP_PHY_INIT_CFG(QSERDES_V5_20_TX_LANE_MODE_3, 0x00), + QMP_PHY_INIT_CFG(QSERDES_V5_20_TX_VMODE_CTRL1, 0x00), + QMP_PHY_INIT_CFG(QSERDES_V5_20_TX_PI_QEC_CTRL, 0x00), + QMP_PHY_INIT_CFG(QSERDES_V5_20_TX_RES_CODE_LANE_OFFSET_TX, 0x1a), + QMP_PHY_INIT_CFG(QSERDES_V5_20_TX_RES_CODE_LANE_OFFSET_RX, 0x0c), + QMP_PHY_INIT_CFG(QSERDES_V5_20_TX_RCV_DETECT_LVL_2, 0x12), +}; + +static const struct qmp_phy_init_tbl sdx65_qmp_pcie_rx_tbl[] = { + QMP_PHY_INIT_CFG(QSERDES_V5_20_RX_AUX_DATA_THRESH_BIN_RATE_0_1, 0x3f), + QMP_PHY_INIT_CFG(QSERDES_V5_20_RX_DFE_1, 0x06), + QMP_PHY_INIT_CFG(QSERDES_V5_20_RX_DFE_2, 0x06), + QMP_PHY_INIT_CFG(QSERDES_V5_20_RX_TX_ADAPT_PRE_THRESH1, 0x3e), + QMP_PHY_INIT_CFG(QSERDES_V5_20_RX_TX_ADAPT_PRE_THRESH2, 0x1e), + QMP_PHY_INIT_CFG(QSERDES_V5_20_RX_TX_ADAPT_POST_THRESH1, 0x00), + QMP_PHY_INIT_CFG(QSERDES_V5_20_RX_TX_ADAPT_POST_THRESH2, 0x1f), + QMP_PHY_INIT_CFG(QSERDES_V5_20_RX_TX_ADAPT_MAIN_THRESH1, 0x02), + QMP_PHY_INIT_CFG(QSERDES_V5_20_RX_TX_ADAPT_MAIN_THRESH2, 0x1d), + QMP_PHY_INIT_CFG(QSERDES_V5_20_RX_VGA_CAL_CNTRL1, 0x44), + QMP_PHY_INIT_CFG(QSERDES_V5_20_RX_VGA_CAL_CNTRL2, 0x00), + QMP_PHY_INIT_CFG(QSERDES_V5_20_RX_RX_EQU_ADAPTOR_CNTRL2, 0x00), + QMP_PHY_INIT_CFG(QSERDES_V5_20_RX_RX_EQU_ADAPTOR_CNTRL3, 0x4a), + QMP_PHY_INIT_CFG(QSERDES_V5_20_RX_RX_EQ_OFFSET_ADAPTOR_CNTRL1, 0x74), + QMP_PHY_INIT_CFG(QSERDES_V5_20_RX_RX_OFFSET_ADAPTOR_CNTRL2, 0x00), + QMP_PHY_INIT_CFG(QSERDES_V5_20_RX_SIGDET_ENABLES, 0x1c), + QMP_PHY_INIT_CFG(QSERDES_V5_20_RX_SIGDET_CNTRL, 0x03), + QMP_PHY_INIT_CFG(QSERDES_V5_20_RX_SIGDET_DEGLITCH_CNTRL, 0x14), + QMP_PHY_INIT_CFG(QSERDES_V5_20_RX_RX_MODE_RATE_0_1_B0, 0x04), + QMP_PHY_INIT_CFG(QSERDES_V5_20_RX_RX_MODE_RATE_0_1_B1, 0xcc), + QMP_PHY_INIT_CFG(QSERDES_V5_20_RX_RX_MODE_RATE_0_1_B2, 0x12), + QMP_PHY_INIT_CFG(QSERDES_V5_20_RX_RX_MODE_RATE_0_1_B3, 0xcc), + QMP_PHY_INIT_CFG(QSERDES_V5_20_RX_RX_MODE_RATE_0_1_B4, 0x64), + QMP_PHY_INIT_CFG(QSERDES_V5_20_RX_RX_MODE_RATE_0_1_B5, 0x4a), + QMP_PHY_INIT_CFG(QSERDES_V5_20_RX_RX_MODE_RATE_0_1_B6, 0x29), + QMP_PHY_INIT_CFG(QSERDES_V5_20_RX_PHPRE_CTRL, 0x20), + QMP_PHY_INIT_CFG(QSERDES_V5_20_RX_DCC_CTRL1, 0x0c), + QMP_PHY_INIT_CFG(QSERDES_V5_20_RX_RX_MARG_COARSE_THRESH1_RATE210, 0x1f), + QMP_PHY_INIT_CFG(QSERDES_V5_20_RX_RX_MARG_COARSE_THRESH1_RATE3, 0x1f), + QMP_PHY_INIT_CFG(QSERDES_V5_20_RX_RX_MARG_COARSE_THRESH2_RATE210, 0x1f), + QMP_PHY_INIT_CFG(QSERDES_V5_20_RX_RX_MARG_COARSE_THRESH2_RATE3, 0x1f), + QMP_PHY_INIT_CFG(QSERDES_V5_20_RX_RX_MARG_COARSE_THRESH3_RATE210, 0x1f), + QMP_PHY_INIT_CFG(QSERDES_V5_20_RX_RX_MARG_COARSE_THRESH3_RATE3, 0x1f), + QMP_PHY_INIT_CFG(QSERDES_V5_20_RX_RX_MARG_COARSE_THRESH4_RATE3, 0x1f), + QMP_PHY_INIT_CFG(QSERDES_V5_20_RX_RX_MARG_COARSE_THRESH5_RATE3, 0x1f), + QMP_PHY_INIT_CFG(QSERDES_V5_20_RX_RX_MARG_COARSE_THRESH6_RATE3, 0x1f), + QMP_PHY_INIT_CFG(QSERDES_V5_20_RX_UCDR_FO_GAIN_RATE2, 0x0c), + QMP_PHY_INIT_CFG(QSERDES_V5_20_RX_UCDR_FO_GAIN_RATE3, 0x0a), + QMP_PHY_INIT_CFG(QSERDES_V5_20_RX_UCDR_PI_CONTROLS, 0x16), + QMP_PHY_INIT_CFG(QSERDES_V5_20_RX_AUX_DATA_THRESH_BIN_RATE_2_3, 0x37), + QMP_PHY_INIT_CFG(QSERDES_V5_20_RX_RX_IDAC_SAOFFSET, 0x10), + QMP_PHY_INIT_CFG(QSERDES_V5_20_RX_DFE_3, 0x05), + QMP_PHY_INIT_CFG(QSERDES_V5_20_RX_DFE_DAC_ENABLE1, 0x00), + QMP_PHY_INIT_CFG(QSERDES_V5_20_RX_DFE_DAC_ENABLE2, 0x00), + QMP_PHY_INIT_CFG(QSERDES_V5_20_RX_VGA_CAL_MAN_VAL, 0x0a), + QMP_PHY_INIT_CFG(QSERDES_V5_20_RX_GM_CAL, 0x0f), + QMP_PHY_INIT_CFG(QSERDES_V5_20_RX_RX_EQU_ADAPTOR_CNTRL4, 0x0b), + QMP_PHY_INIT_CFG(QSERDES_V5_20_RX_RX_MODE_RATE2_B0, 0xc5), + QMP_PHY_INIT_CFG(QSERDES_V5_20_RX_RX_MODE_RATE2_B1, 0xac), + QMP_PHY_INIT_CFG(QSERDES_V5_20_RX_RX_MODE_RATE2_B2, 0xb6), + QMP_PHY_INIT_CFG(QSERDES_V5_20_RX_RX_MODE_RATE2_B3, 0xc0), + QMP_PHY_INIT_CFG(QSERDES_V5_20_RX_RX_MODE_RATE2_B4, 0x07), + QMP_PHY_INIT_CFG(QSERDES_V5_20_RX_RX_MODE_RATE2_B5, 0xfb), + QMP_PHY_INIT_CFG(QSERDES_V5_20_RX_RX_MODE_RATE2_B6, 0x0d), + QMP_PHY_INIT_CFG(QSERDES_V5_20_RX_RX_MODE_RATE3_B0, 0xc5), + QMP_PHY_INIT_CFG(QSERDES_V5_20_RX_RX_MODE_RATE3_B1, 0xee), + QMP_PHY_INIT_CFG(QSERDES_V5_20_RX_RX_MODE_RATE3_B2, 0xbf), + QMP_PHY_INIT_CFG(QSERDES_V5_20_RX_RX_MODE_RATE3_B3, 0xa0), + QMP_PHY_INIT_CFG(QSERDES_V5_20_RX_RX_MODE_RATE3_B4, 0x81), + QMP_PHY_INIT_CFG(QSERDES_V5_20_RX_RX_MODE_RATE3_B5, 0xde), + QMP_PHY_INIT_CFG(QSERDES_V5_20_RX_RX_MODE_RATE3_B6, 0x7f), + QMP_PHY_INIT_CFG(QSERDES_V5_20_RX_DFE_EN_TIMER, 0x28), + QMP_PHY_INIT_CFG(QSERDES_V5_20_RX_DFE_CTLE_POST_CAL_OFFSET, 0x38), +}; + +static const struct qmp_phy_init_tbl sdx65_qmp_pcie_pcs_tbl[] = { + QMP_PHY_INIT_CFG(QPHY_V5_20_PCS_G3S2_PRE_GAIN, 0x2e), + QMP_PHY_INIT_CFG(QPHY_V5_20_PCS_RX_SIGDET_LVL, 0xaa), + QMP_PHY_INIT_CFG(QPHY_V5_20_PCS_EQ_CONFIG2, 0x0d), + QMP_PHY_INIT_CFG(QPHY_V5_20_PCS_EQ_CONFIG4, 0x16), + QMP_PHY_INIT_CFG(QPHY_V5_20_PCS_EQ_CONFIG5, 0x22), +}; + +static const struct qmp_phy_init_tbl sdx65_qmp_pcie_pcs_misc_tbl[] = { + QMP_PHY_INIT_CFG(QPHY_V5_20_PCS_PCIE_EQ_CONFIG1, 0x16), + QMP_PHY_INIT_CFG(QPHY_V5_20_PCS_PCIE_RX_MARGINING_CONFIG3, 0x28), + QMP_PHY_INIT_CFG(QPHY_V5_20_PCS_PCIE_OSC_DTCT_MODE2_CONFIG5, 0x08), + 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), + 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), +}; + static const struct qmp_phy_init_tbl sm8450_qmp_gen3_pcie_serdes_tbl[] = { QMP_PHY_INIT_CFG(QSERDES_V5_COM_SYSCLK_EN_SEL, 0x08), QMP_PHY_INIT_CFG(QSERDES_V5_COM_CLK_SELECT, 0x34), @@ -2033,8 +2209,6 @@ static const struct qmp_phy_cfg sdm845_qhp_pciephy_cfg = { .serdes_num = ARRAY_SIZE(sdm845_qhp_pcie_serdes_tbl), .tx = sdm845_qhp_pcie_tx_tbl, .tx_num = ARRAY_SIZE(sdm845_qhp_pcie_tx_tbl), - .rx = sdm845_qhp_pcie_rx_tbl, - .rx_num = ARRAY_SIZE(sdm845_qhp_pcie_rx_tbl), .pcs = sdm845_qhp_pcie_pcs_tbl, .pcs_num = ARRAY_SIZE(sdm845_qhp_pcie_pcs_tbl), }, @@ -2152,7 +2326,7 @@ static const struct qmp_phy_cfg msm8998_pciephy_cfg = { }; static const struct qmp_phy_cfg sc8180x_pciephy_cfg = { - .lanes = 1, + .lanes = 2, .tbls = { .serdes = sc8180x_qmp_pcie_serdes_tbl, @@ -2301,6 +2475,21 @@ static const struct qmp_phy_cfg sdx55_qmp_pciephy_cfg = { .pcs_misc = sdx55_qmp_pcie_pcs_misc_tbl, .pcs_misc_num = ARRAY_SIZE(sdx55_qmp_pcie_pcs_misc_tbl), }, + + .tbls_rc = &(const struct qmp_phy_cfg_tbls) { + .serdes = sdx55_qmp_pcie_rc_serdes_tbl, + .serdes_num = ARRAY_SIZE(sdx55_qmp_pcie_rc_serdes_tbl), + .pcs_misc = sdx55_qmp_pcie_rc_pcs_misc_tbl, + .pcs_misc_num = ARRAY_SIZE(sdx55_qmp_pcie_rc_pcs_misc_tbl), + }, + + .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), + }, + .clk_list = sdm845_pciephy_clk_l, .num_clks = ARRAY_SIZE(sdm845_pciephy_clk_l), .reset_list = sdm845_pciephy_reset_l, @@ -2309,7 +2498,7 @@ static const struct qmp_phy_cfg sdx55_qmp_pciephy_cfg = { .num_vregs = ARRAY_SIZE(qmp_phy_vreg_l), .regs = pciephy_v4_regs_layout, - .pwrdn_ctrl = SW_PWRDN, + .pwrdn_ctrl = SW_PWRDN | REFCLK_DRV_DSBL, .phy_status = PHYSTATUS_4_20, }; @@ -2387,6 +2576,35 @@ static const struct qmp_phy_cfg sm8350_qmp_gen3x2_pciephy_cfg = { .phy_status = PHYSTATUS, }; +static const struct qmp_phy_cfg sdx65_qmp_pciephy_cfg = { + .lanes = 2, + + .offsets = &qmp_pcie_offsets_v6_20, + + .tbls = { + .serdes = sdx65_qmp_pcie_serdes_tbl, + .serdes_num = ARRAY_SIZE(sdx65_qmp_pcie_serdes_tbl), + .tx = sdx65_qmp_pcie_tx_tbl, + .tx_num = ARRAY_SIZE(sdx65_qmp_pcie_tx_tbl), + .rx = sdx65_qmp_pcie_rx_tbl, + .rx_num = ARRAY_SIZE(sdx65_qmp_pcie_rx_tbl), + .pcs = sdx65_qmp_pcie_pcs_tbl, + .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), + }, + .clk_list = sdm845_pciephy_clk_l, + .num_clks = ARRAY_SIZE(sdm845_pciephy_clk_l), + .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, + .phy_status = PHYSTATUS_4_20, +}; + static const struct qmp_phy_cfg sm8450_qmp_gen3x1_pciephy_cfg = { .lanes = 1, @@ -3181,6 +3399,9 @@ static const struct of_device_id qmp_pcie_of_match_table[] = { .compatible = "qcom,sdx55-qmp-pcie-phy", .data = &sdx55_qmp_pciephy_cfg, }, { + .compatible = "qcom,sdx65-qmp-gen4x2-pcie-phy", + .data = &sdx65_qmp_pciephy_cfg, + }, { .compatible = "qcom,sm8250-qmp-gen3x1-pcie-phy", .data = &sm8250_qmp_gen3x1_pciephy_cfg, }, { diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-pcs-pcie-v4_20.h b/drivers/phy/qualcomm/phy-qcom-qmp-pcs-pcie-v4_20.h index af273602998e..ac872a9eff9a 100644 --- a/drivers/phy/qualcomm/phy-qcom-qmp-pcs-pcie-v4_20.h +++ b/drivers/phy/qualcomm/phy-qcom-qmp-pcs-pcie-v4_20.h @@ -6,6 +6,8 @@ #ifndef QCOM_PHY_QMP_PCS_PCIE_V4_20_H_ #define QCOM_PHY_QMP_PCS_PCIE_V4_20_H_ +#define QPHY_V4_20_PCS_PCIE_ENDPOINT_REFCLK_DRIVE 0x01c +#define QPHY_V4_20_PCS_PCIE_OSC_DTCT_ACTIONS 0x090 #define QPHY_V4_20_PCS_PCIE_EQ_CONFIG1 0x0a0 #define QPHY_V4_20_PCS_PCIE_G3_RXEQEVAL_TIME 0x0f0 #define QPHY_V4_20_PCS_PCIE_G4_RXEQEVAL_TIME 0x0f4 diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-pcs-pcie-v5_20.h b/drivers/phy/qualcomm/phy-qcom-qmp-pcs-pcie-v5_20.h index 3d9713d348fe..a3a056741fc7 100644 --- a/drivers/phy/qualcomm/phy-qcom-qmp-pcs-pcie-v5_20.h +++ b/drivers/phy/qualcomm/phy-qcom-qmp-pcs-pcie-v5_20.h @@ -12,8 +12,11 @@ #define QPHY_V5_20_PCS_PCIE_OSC_DTCT_ACTIONS 0x090 #define QPHY_V5_20_PCS_PCIE_EQ_CONFIG1 0x0a0 #define QPHY_V5_20_PCS_PCIE_PRESET_P10_POST 0x0e0 +#define QPHY_V5_20_PCS_PCIE_G4_EQ_CONFIG2 0x0fc #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 #endif diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-pcs-v5_20.h b/drivers/phy/qualcomm/phy-qcom-qmp-pcs-v5_20.h index 9a5a20daf62c..f0754b6f9e3a 100644 --- a/drivers/phy/qualcomm/phy-qcom-qmp-pcs-v5_20.h +++ b/drivers/phy/qualcomm/phy-qcom-qmp-pcs-v5_20.h @@ -8,6 +8,7 @@ #define QPHY_V5_20_PCS_G3S2_PRE_GAIN 0x170 #define QPHY_V5_20_PCS_RX_SIGDET_LVL 0x188 +#define QPHY_V5_20_PCS_EQ_CONFIG2 0x1d8 #define QPHY_V5_20_PCS_EQ_CONFIG4 0x1e0 #define QPHY_V5_20_PCS_EQ_CONFIG5 0x1e4 diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-qserdes-txrx-v5_20.h b/drivers/phy/qualcomm/phy-qcom-qmp-qserdes-txrx-v5_20.h index 86c01104799e..c7b12c1fb7f5 100644 --- a/drivers/phy/qualcomm/phy-qcom-qmp-qserdes-txrx-v5_20.h +++ b/drivers/phy/qualcomm/phy-qcom-qmp-qserdes-txrx-v5_20.h @@ -11,6 +11,10 @@ #define QSERDES_V5_20_TX_RES_CODE_LANE_OFFSET_RX 0x34 #define QSERDES_V5_20_TX_LANE_MODE_1 0x78 #define QSERDES_V5_20_TX_LANE_MODE_2 0x7c +#define QSERDES_V5_20_TX_LANE_MODE_3 0x80 +#define QSERDES_V5_20_TX_RCV_DETECT_LVL_2 0x90 +#define QSERDES_V5_20_TX_VMODE_CTRL1 0xb0 +#define QSERDES_V5_20_TX_PI_QEC_CTRL 0xcc /* Only for QMP V5_20 PHY - RX registers */ #define QSERDES_V5_20_RX_UCDR_FO_GAIN_RATE2 0x008 @@ -19,16 +23,33 @@ #define QSERDES_V5_20_RX_AUX_DATA_THRESH_BIN_RATE_0_1 0x02c #define QSERDES_V5_20_RX_AUX_DATA_THRESH_BIN_RATE_2_3 0x030 #define QSERDES_V5_20_RX_RX_IDAC_SAOFFSET 0x07c +#define QSERDES_V5_20_RX_DFE_1 0x088 +#define QSERDES_V5_20_RX_DFE_2 0x08c #define QSERDES_V5_20_RX_DFE_3 0x090 #define QSERDES_V5_20_RX_DFE_DAC_ENABLE1 0x0b4 +#define QSERDES_V5_20_RX_TX_ADAPT_PRE_THRESH1 0x0bc +#define QSERDES_V5_20_RX_TX_ADAPT_PRE_THRESH2 0x0c0 #define QSERDES_V5_20_RX_TX_ADAPT_POST_THRESH1 0x0c4 #define QSERDES_V5_20_RX_TX_ADAPT_POST_THRESH2 0x0c8 +#define QSERDES_V5_20_RX_TX_ADAPT_MAIN_THRESH1 0x0cc +#define QSERDES_V5_20_RX_TX_ADAPT_MAIN_THRESH2 0x0d0 +#define QSERDES_V5_20_RX_VGA_CAL_CNTRL1 0x0d4 +#define QSERDES_V5_20_RX_VGA_CAL_CNTRL2 0x0d8 #define QSERDES_V5_20_RX_VGA_CAL_MAN_VAL 0x0dc #define QSERDES_V5_20_RX_GM_CAL 0x0ec +#define QSERDES_V5_20_RX_RX_EQU_ADAPTOR_CNTRL2 0x100 +#define QSERDES_V5_20_RX_RX_EQU_ADAPTOR_CNTRL3 0x104 #define QSERDES_V5_20_RX_RX_EQU_ADAPTOR_CNTRL4 0x108 +#define QSERDES_V5_20_RX_RX_EQ_OFFSET_ADAPTOR_CNTRL1 0x118 +#define QSERDES_V5_20_RX_RX_OFFSET_ADAPTOR_CNTRL2 0x11c +#define QSERDES_V5_20_RX_SIGDET_ENABLES 0x120 +#define QSERDES_V5_20_RX_SIGDET_CNTRL 0x124 +#define QSERDES_V5_20_RX_SIGDET_DEGLITCH_CNTRL 0x12c +#define QSERDES_V5_20_RX_RX_MODE_RATE_0_1_B0 0x160 #define QSERDES_V5_20_RX_RX_MODE_RATE_0_1_B1 0x164 #define QSERDES_V5_20_RX_RX_MODE_RATE_0_1_B2 0x168 #define QSERDES_V5_20_RX_RX_MODE_RATE_0_1_B3 0x16c +#define QSERDES_V5_20_RX_RX_MODE_RATE_0_1_B4 0x170 #define QSERDES_V5_20_RX_RX_MODE_RATE_0_1_B5 0x174 #define QSERDES_V5_20_RX_RX_MODE_RATE_0_1_B6 0x178 #define QSERDES_V5_20_RX_RX_MODE_RATE2_B0 0x17c @@ -46,7 +67,10 @@ #define QSERDES_V5_20_RX_RX_MODE_RATE3_B5 0x1ac #define QSERDES_V5_20_RX_RX_MODE_RATE3_B6 0x1b0 #define QSERDES_V5_20_RX_PHPRE_CTRL 0x1b4 +#define QSERDES_V5_20_RX_DFE_DAC_ENABLE2 0x1b8 +#define QSERDES_V5_20_RX_DFE_EN_TIMER 0x1bc #define QSERDES_V5_20_RX_DFE_CTLE_POST_CAL_OFFSET 0x1c0 +#define QSERDES_V5_20_RX_DCC_CTRL1 0x1c4 #define QSERDES_V5_20_RX_RX_MARG_COARSE_THRESH1_RATE210 0x1f4 #define QSERDES_V5_20_RX_RX_MARG_COARSE_THRESH1_RATE3 0x1f8 #define QSERDES_V5_20_RX_RX_MARG_COARSE_THRESH2_RATE210 0x1fc diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-ufs.c b/drivers/phy/qualcomm/phy-qcom-qmp-ufs.c index 994ddd5d4a81..8c877b668bb9 100644 --- a/drivers/phy/qualcomm/phy-qcom-qmp-ufs.c +++ b/drivers/phy/qualcomm/phy-qcom-qmp-ufs.c @@ -349,6 +349,36 @@ static const struct qmp_phy_init_tbl sdm845_ufsphy_pcs[] = { QMP_PHY_INIT_CFG(QPHY_V3_PCS_UFS_MULTI_LANE_CTRL1, 0x02), }; +static const struct qmp_phy_init_tbl sm7150_ufsphy_rx[] = { + QMP_PHY_INIT_CFG(QSERDES_V3_RX_SIGDET_LVL, 0x24), + QMP_PHY_INIT_CFG(QSERDES_V3_RX_SIGDET_CNTRL, 0x0f), + QMP_PHY_INIT_CFG(QSERDES_V3_RX_SIGDET_DEGLITCH_CNTRL, 0x1e), + QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_INTERFACE_MODE, 0x40), + QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_FASTLOCK_FO_GAIN, 0x0b), + QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_TERM_BW, 0x5b), + QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_EQU_ADAPTOR_CNTRL2, 0x06), + QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_EQU_ADAPTOR_CNTRL3, 0x04), + QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_EQU_ADAPTOR_CNTRL4, 0x1b), + QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_SVS_SO_GAIN_HALF, 0x04), + QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_SVS_SO_GAIN_QUARTER, 0x04), + QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_SVS_SO_GAIN, 0x04), + QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_SO_SATURATION_AND_ENABLE, 0x5b), + QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_PI_CONTROLS, 0x81), + QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_FASTLOCK_COUNT_LOW, 0x80), + QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_MODE_00, 0x59), +}; + +static const struct qmp_phy_init_tbl sm7150_ufsphy_pcs[] = { + QMP_PHY_INIT_CFG(QPHY_V3_PCS_UFS_RX_SIGDET_CTRL2, 0x6f), + QMP_PHY_INIT_CFG(QPHY_V3_PCS_UFS_TX_LARGE_AMP_DRV_LVL, 0x0f), + QMP_PHY_INIT_CFG(QPHY_V3_PCS_UFS_TX_SMALL_AMP_DRV_LVL, 0x02), + QMP_PHY_INIT_CFG(QPHY_V3_PCS_UFS_RX_SYM_RESYNC_CTRL, 0x03), + QMP_PHY_INIT_CFG(QPHY_V3_PCS_UFS_TX_MID_TERM_CTRL1, 0x43), + QMP_PHY_INIT_CFG(QPHY_V3_PCS_UFS_RX_SIGDET_CTRL1, 0x0f), + QMP_PHY_INIT_CFG(QPHY_V3_PCS_UFS_RX_MIN_HIBERN8_TIME, 0xff), + QMP_PHY_INIT_CFG(QPHY_V3_PCS_UFS_MULTI_LANE_CTRL1, 0x02), +}; + static const struct qmp_phy_init_tbl sm8150_ufsphy_serdes[] = { QMP_PHY_INIT_CFG(QSERDES_V4_COM_SYSCLK_EN_SEL, 0xd9), QMP_PHY_INIT_CFG(QSERDES_V4_COM_HSCLK_SEL, 0x11), @@ -823,6 +853,40 @@ static const struct qmp_phy_cfg msm8996_ufsphy_cfg = { .no_pcs_sw_reset = true, }; +static const struct qmp_phy_cfg sa8775p_ufsphy_cfg = { + .lanes = 2, + + .offsets = &qmp_ufs_offsets, + + .tbls = { + .serdes = sm8350_ufsphy_serdes, + .serdes_num = ARRAY_SIZE(sm8350_ufsphy_serdes), + .tx = sm8350_ufsphy_tx, + .tx_num = ARRAY_SIZE(sm8350_ufsphy_tx), + .rx = sm8350_ufsphy_rx, + .rx_num = ARRAY_SIZE(sm8350_ufsphy_rx), + .pcs = sm8350_ufsphy_pcs, + .pcs_num = ARRAY_SIZE(sm8350_ufsphy_pcs), + }, + .tbls_hs_b = { + .serdes = sm8350_ufsphy_hs_b_serdes, + .serdes_num = ARRAY_SIZE(sm8350_ufsphy_hs_b_serdes), + }, + .tbls_hs_g4 = { + .tx = sm8350_ufsphy_g4_tx, + .tx_num = ARRAY_SIZE(sm8350_ufsphy_g4_tx), + .rx = sm8350_ufsphy_g4_rx, + .rx_num = ARRAY_SIZE(sm8350_ufsphy_g4_rx), + .pcs = sm8350_ufsphy_g4_pcs, + .pcs_num = ARRAY_SIZE(sm8350_ufsphy_g4_pcs), + }, + .clk_list = sm8450_ufs_phy_clk_l, + .num_clks = ARRAY_SIZE(sm8450_ufs_phy_clk_l), + .vreg_list = qmp_phy_vreg_l, + .num_vregs = ARRAY_SIZE(qmp_phy_vreg_l), + .regs = ufsphy_v5_regs_layout, +}; + static const struct qmp_phy_cfg sc8280xp_ufsphy_cfg = { .lanes = 2, @@ -911,6 +975,34 @@ static const struct qmp_phy_cfg sm6115_ufsphy_cfg = { .no_pcs_sw_reset = true, }; +static const struct qmp_phy_cfg sm7150_ufsphy_cfg = { + .lanes = 1, + + .offsets = &qmp_ufs_offsets, + + .tbls = { + .serdes = sdm845_ufsphy_serdes, + .serdes_num = ARRAY_SIZE(sdm845_ufsphy_serdes), + .tx = sdm845_ufsphy_tx, + .tx_num = ARRAY_SIZE(sdm845_ufsphy_tx), + .rx = sm7150_ufsphy_rx, + .rx_num = ARRAY_SIZE(sm7150_ufsphy_rx), + .pcs = sm7150_ufsphy_pcs, + .pcs_num = ARRAY_SIZE(sm7150_ufsphy_pcs), + }, + .tbls_hs_b = { + .serdes = sdm845_ufsphy_hs_b_serdes, + .serdes_num = ARRAY_SIZE(sdm845_ufsphy_hs_b_serdes), + }, + .clk_list = sdm845_ufs_phy_clk_l, + .num_clks = ARRAY_SIZE(sdm845_ufs_phy_clk_l), + .vreg_list = qmp_phy_vreg_l, + .num_vregs = ARRAY_SIZE(qmp_phy_vreg_l), + .regs = ufsphy_v3_regs_layout, + + .no_pcs_sw_reset = true, +}; + static const struct qmp_phy_cfg sm8150_ufsphy_cfg = { .lanes = 2, @@ -1543,6 +1635,9 @@ static const struct of_device_id qmp_ufs_of_match_table[] = { .compatible = "qcom,msm8998-qmp-ufs-phy", .data = &sdm845_ufsphy_cfg, }, { + .compatible = "qcom,sa8775p-qmp-ufs-phy", + .data = &sa8775p_ufsphy_cfg, + }, { .compatible = "qcom,sc8180x-qmp-ufs-phy", .data = &sm8150_ufsphy_cfg, }, { @@ -1561,6 +1656,9 @@ static const struct of_device_id qmp_ufs_of_match_table[] = { .compatible = "qcom,sm6350-qmp-ufs-phy", .data = &sdm845_ufsphy_cfg, }, { + .compatible = "qcom,sm7150-qmp-ufs-phy", + .data = &sm7150_ufsphy_cfg, + }, { .compatible = "qcom,sm8150-qmp-ufs-phy", .data = &sm8150_ufsphy_cfg, }, { diff --git a/drivers/phy/renesas/phy-rcar-gen3-pcie.c b/drivers/phy/renesas/phy-rcar-gen3-pcie.c index 4dc721eb9577..9cf786a7daac 100644 --- a/drivers/phy/renesas/phy-rcar-gen3-pcie.c +++ b/drivers/phy/renesas/phy-rcar-gen3-pcie.c @@ -126,11 +126,9 @@ error: return error; } -static int rcar_gen3_phy_pcie_remove(struct platform_device *pdev) +static void rcar_gen3_phy_pcie_remove(struct platform_device *pdev) { pm_runtime_disable(&pdev->dev); - - return 0; }; static struct platform_driver rcar_gen3_phy_driver = { @@ -139,7 +137,7 @@ static struct platform_driver rcar_gen3_phy_driver = { .of_match_table = rcar_gen3_phy_pcie_match_table, }, .probe = rcar_gen3_phy_pcie_probe, - .remove = rcar_gen3_phy_pcie_remove, + .remove_new = rcar_gen3_phy_pcie_remove, }; module_platform_driver(rcar_gen3_phy_driver); diff --git a/drivers/phy/renesas/phy-rcar-gen3-usb2.c b/drivers/phy/renesas/phy-rcar-gen3-usb2.c index 9de617ca9daa..d4e2ee7e4efb 100644 --- a/drivers/phy/renesas/phy-rcar-gen3-usb2.c +++ b/drivers/phy/renesas/phy-rcar-gen3-usb2.c @@ -755,7 +755,7 @@ error: return ret; } -static int rcar_gen3_phy_usb2_remove(struct platform_device *pdev) +static void rcar_gen3_phy_usb2_remove(struct platform_device *pdev) { struct rcar_gen3_chan *channel = platform_get_drvdata(pdev); @@ -763,8 +763,6 @@ static int rcar_gen3_phy_usb2_remove(struct platform_device *pdev) device_remove_file(&pdev->dev, &dev_attr_role); pm_runtime_disable(&pdev->dev); - - return 0; }; static struct platform_driver rcar_gen3_phy_usb2_driver = { @@ -773,7 +771,7 @@ static struct platform_driver rcar_gen3_phy_usb2_driver = { .of_match_table = rcar_gen3_phy_usb2_match_table, }, .probe = rcar_gen3_phy_usb2_probe, - .remove = rcar_gen3_phy_usb2_remove, + .remove_new = rcar_gen3_phy_usb2_remove, }; module_platform_driver(rcar_gen3_phy_usb2_driver); diff --git a/drivers/phy/renesas/phy-rcar-gen3-usb3.c b/drivers/phy/renesas/phy-rcar-gen3-usb3.c index f27d6f471629..e2d630edd992 100644 --- a/drivers/phy/renesas/phy-rcar-gen3-usb3.c +++ b/drivers/phy/renesas/phy-rcar-gen3-usb3.c @@ -199,11 +199,9 @@ error: return ret; } -static int rcar_gen3_phy_usb3_remove(struct platform_device *pdev) +static void rcar_gen3_phy_usb3_remove(struct platform_device *pdev) { pm_runtime_disable(&pdev->dev); - - return 0; }; static struct platform_driver rcar_gen3_phy_usb3_driver = { @@ -212,7 +210,7 @@ static struct platform_driver rcar_gen3_phy_usb3_driver = { .of_match_table = rcar_gen3_phy_usb3_match_table, }, .probe = rcar_gen3_phy_usb3_probe, - .remove = rcar_gen3_phy_usb3_remove, + .remove_new = rcar_gen3_phy_usb3_remove, }; module_platform_driver(rcar_gen3_phy_usb3_driver); diff --git a/drivers/phy/renesas/r8a779f0-ether-serdes.c b/drivers/phy/renesas/r8a779f0-ether-serdes.c index c5206ef9195b..55b7bdfc10d3 100644 --- a/drivers/phy/renesas/r8a779f0-ether-serdes.c +++ b/drivers/phy/renesas/r8a779f0-ether-serdes.c @@ -388,19 +388,17 @@ static int r8a779f0_eth_serdes_probe(struct platform_device *pdev) return 0; } -static int r8a779f0_eth_serdes_remove(struct platform_device *pdev) +static void r8a779f0_eth_serdes_remove(struct platform_device *pdev) { pm_runtime_put(&pdev->dev); pm_runtime_disable(&pdev->dev); platform_set_drvdata(pdev, NULL); - - return 0; } static struct platform_driver r8a779f0_eth_serdes_driver_platform = { .probe = r8a779f0_eth_serdes_probe, - .remove = r8a779f0_eth_serdes_remove, + .remove_new = r8a779f0_eth_serdes_remove, .driver = { .name = "r8a779f0_eth_serdes", .of_match_table = r8a779f0_eth_serdes_of_table, diff --git a/drivers/phy/rockchip/phy-rockchip-inno-csidphy.c b/drivers/phy/rockchip/phy-rockchip-inno-csidphy.c index 75f948bdea6a..98c92d6c482f 100644 --- a/drivers/phy/rockchip/phy-rockchip-inno-csidphy.c +++ b/drivers/phy/rockchip/phy-rockchip-inno-csidphy.c @@ -459,13 +459,11 @@ static int rockchip_inno_csidphy_probe(struct platform_device *pdev) return 0; } -static int rockchip_inno_csidphy_remove(struct platform_device *pdev) +static void rockchip_inno_csidphy_remove(struct platform_device *pdev) { struct rockchip_inno_csidphy *priv = platform_get_drvdata(pdev); pm_runtime_disable(priv->dev); - - return 0; } static struct platform_driver rockchip_inno_csidphy_driver = { @@ -474,7 +472,7 @@ static struct platform_driver rockchip_inno_csidphy_driver = { .of_match_table = rockchip_inno_csidphy_match_id, }, .probe = rockchip_inno_csidphy_probe, - .remove = rockchip_inno_csidphy_remove, + .remove_new = rockchip_inno_csidphy_remove, }; module_platform_driver(rockchip_inno_csidphy_driver); diff --git a/drivers/phy/rockchip/phy-rockchip-inno-dsidphy.c b/drivers/phy/rockchip/phy-rockchip-inno-dsidphy.c index 2c5847faff63..401b0aabb159 100644 --- a/drivers/phy/rockchip/phy-rockchip-inno-dsidphy.c +++ b/drivers/phy/rockchip/phy-rockchip-inno-dsidphy.c @@ -281,11 +281,6 @@ struct inno_mipi_dphy_timing inno_mipi_dphy_timing_table_max_2_5ghz[] = { {2500000000, 0x15, 0x54, 0x7f, 0x15, 0x6a}, }; -static inline struct inno_dsidphy *hw_to_inno(struct clk_hw *hw) -{ - return container_of(hw, struct inno_dsidphy, pll.hw); -} - static void phy_update_bits(struct inno_dsidphy *inno, u8 first, u8 second, u8 mask, u8 val) { @@ -755,13 +750,11 @@ static int inno_dsidphy_probe(struct platform_device *pdev) return 0; } -static int inno_dsidphy_remove(struct platform_device *pdev) +static void inno_dsidphy_remove(struct platform_device *pdev) { struct inno_dsidphy *inno = platform_get_drvdata(pdev); pm_runtime_disable(inno->dev); - - return 0; } static const struct of_device_id inno_dsidphy_of_match[] = { @@ -788,7 +781,7 @@ static struct platform_driver inno_dsidphy_driver = { .of_match_table = of_match_ptr(inno_dsidphy_of_match), }, .probe = inno_dsidphy_probe, - .remove = inno_dsidphy_remove, + .remove_new = inno_dsidphy_remove, }; module_platform_driver(inno_dsidphy_driver); diff --git a/drivers/phy/rockchip/phy-rockchip-inno-hdmi.c b/drivers/phy/rockchip/phy-rockchip-inno-hdmi.c index 80acca4e9e14..1e1563f5fffc 100644 --- a/drivers/phy/rockchip/phy-rockchip-inno-hdmi.c +++ b/drivers/phy/rockchip/phy-rockchip-inno-hdmi.c @@ -1246,11 +1246,9 @@ static int inno_hdmi_phy_probe(struct platform_device *pdev) return PTR_ERR_OR_ZERO(phy_provider); } -static int inno_hdmi_phy_remove(struct platform_device *pdev) +static void inno_hdmi_phy_remove(struct platform_device *pdev) { of_clk_del_provider(pdev->dev.of_node); - - return 0; } static const struct of_device_id inno_hdmi_phy_of_match[] = { @@ -1266,7 +1264,7 @@ MODULE_DEVICE_TABLE(of, inno_hdmi_phy_of_match); static struct platform_driver inno_hdmi_phy_driver = { .probe = inno_hdmi_phy_probe, - .remove = inno_hdmi_phy_remove, + .remove_new = inno_hdmi_phy_remove, .driver = { .name = "inno-hdmi-phy", .of_match_table = inno_hdmi_phy_of_match, diff --git a/drivers/phy/rockchip/phy-rockchip-naneng-combphy.c b/drivers/phy/rockchip/phy-rockchip-naneng-combphy.c index 7b213825fb5d..7b8b001e4f9e 100644 --- a/drivers/phy/rockchip/phy-rockchip-naneng-combphy.c +++ b/drivers/phy/rockchip/phy-rockchip-naneng-combphy.c @@ -63,6 +63,9 @@ #define PHYREG18 0x44 #define PHYREG18_PLL_LOOP 0x32 +#define PHYREG27 0x6C +#define PHYREG27_RX_TRIM_RK3588 0x4C + #define PHYREG32 0x7C #define PHYREG32_SSC_MASK GENMASK(7, 4) #define PHYREG32_SSC_DIR_SHIFT 4 @@ -114,7 +117,10 @@ struct rockchip_combphy_grfcfg { struct combphy_reg con2_for_sata; struct combphy_reg con3_for_sata; struct combphy_reg pipe_con0_for_sata; + struct combphy_reg pipe_con1_for_sata; struct combphy_reg pipe_xpcs_phy_ready; + struct combphy_reg pipe_pcie1l0_sel; + struct combphy_reg pipe_pcie1l1_sel; }; struct rockchip_combphy_cfg { @@ -559,11 +565,189 @@ static const struct rockchip_combphy_cfg rk3568_combphy_cfgs = { .combphy_cfg = rk3568_combphy_cfg, }; +static int rk3588_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: + 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); + rockchip_combphy_param_write(priv->pipe_grf, &cfg->pipe_pcie1l0_sel, true); + rockchip_combphy_param_write(priv->pipe_grf, &cfg->pipe_pcie1l1_sel, true); + break; + case PHY_TYPE_USB3: + /* Set SSC downward spread spectrum */ + rockchip_combphy_updatel(priv, PHYREG32_SSC_MASK, + PHYREG32_SSC_DOWNWARD << PHYREG32_SSC_DIR_SHIFT, + 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, + PHYREG33_PLL_KVCO_VALUE << PHYREG33_PLL_KVCO_SHIFT, + PHYREG33); + + /* Enable controlling random jitter. */ + writel(PHYREG12_PLL_LPF_ADJ_VALUE, priv->mmio + PHYREG12); + + /* Set PLL input clock divider 1/2. */ + rockchip_combphy_updatel(priv, PHYREG6_PLL_DIV_MASK, + PHYREG6_PLL_DIV_2 << PHYREG6_PLL_DIV_SHIFT, + PHYREG6); + + writel(PHYREG18_PLL_LOOP, priv->mmio + PHYREG18); + writel(PHYREG11_SU_TRIM_0_7, priv->mmio + PHYREG11); + + 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=50ohm and rx_rterm=44ohm for SATA. + * 0: 60ohm, 8: 50ohm 15: 44ohm (by step abort 1ohm) + */ + 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; + case PHY_TYPE_SGMII: + case PHY_TYPE_QSGMII: + default: + dev_err(priv->dev, "incompatible PHY type\n"); + return -EINVAL; + } + + rate = clk_get_rate(priv->refclk); + + switch (rate) { + case REF_CLOCK_24MHz: + if (priv->type == PHY_TYPE_USB3 || priv->type == PHY_TYPE_SATA) { + /* Set ssc_cnt[9:0]=0101111101 & 31.5KHz. */ + val = PHYREG15_SSC_CNT_VALUE << PHYREG15_SSC_CNT_SHIFT; + rockchip_combphy_updatel(priv, PHYREG15_SSC_CNT_MASK, + val, PHYREG15); + + 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) { + /* PLL KVCO fine tuning. */ + val = 4 << PHYREG33_PLL_KVCO_SHIFT; + rockchip_combphy_updatel(priv, PHYREG33_PLL_KVCO_MASK, + val, PHYREG33); + + /* Enable controlling random jitter. */ + writel(PHYREG12_PLL_LPF_ADJ_VALUE, priv->mmio + PHYREG12); + + /* Set up rx_trim: PLL LPF C1 85pf R1 1.25kohm */ + writel(PHYREG27_RX_TRIM_RK3588, priv->mmio + PHYREG27); + + /* Set up su_trim: */ + writel(PHYREG11_SU_TRIM_0_7, priv->mmio + PHYREG11); + } else if (priv->type == PHY_TYPE_SATA) { + /* downward spread spectrum +500ppm */ + val = PHYREG32_SSC_DOWNWARD << PHYREG32_SSC_DIR_SHIFT; + val |= PHYREG32_SSC_OFFSET_500PPM << PHYREG32_SSC_OFFSET_SHIFT; + rockchip_combphy_updatel(priv, PHYREG32_SSC_MASK, val, PHYREG32); + } + 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 = PHYREG13_RESISTER_HIGH_Z << PHYREG13_RESISTER_SHIFT; + val |= PHYREG13_CKRCV_AMP0; + rockchip_combphy_updatel(priv, PHYREG13_RESISTER_MASK, val, PHYREG13); + + val = readl(priv->mmio + PHYREG14); + val |= PHYREG14_CKRCV_AMP1; + writel(val, priv->mmio + PHYREG14); + } + } + + if (priv->enable_ssc) { + val = readl(priv->mmio + PHYREG8); + val |= PHYREG8_SSC_EN; + writel(val, priv->mmio + PHYREG8); + } + + return 0; +} + +static const struct rockchip_combphy_grfcfg rk3588_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_25m = { 0x0004, 14, 13, 0x00, 0x01 }, + .pipe_clk_100m = { 0x0004, 14, 13, 0x00, 0x02 }, + .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 }, + /* pipe-grf */ + .pipe_con0_for_sata = { 0x0000, 11, 5, 0x00, 0x22 }, + .pipe_con1_for_sata = { 0x0000, 2, 0, 0x00, 0x2 }, + .pipe_pcie1l0_sel = { 0x0100, 0, 0, 0x01, 0x0 }, + .pipe_pcie1l1_sel = { 0x0100, 1, 1, 0x01, 0x0 }, +}; + +static const struct rockchip_combphy_cfg rk3588_combphy_cfgs = { + .grfcfg = &rk3588_combphy_grfcfgs, + .combphy_cfg = rk3588_combphy_cfg, +}; + static const struct of_device_id rockchip_combphy_of_match[] = { { .compatible = "rockchip,rk3568-naneng-combphy", .data = &rk3568_combphy_cfgs, }, + { + .compatible = "rockchip,rk3588-naneng-combphy", + .data = &rk3588_combphy_cfgs, + }, { }, }; MODULE_DEVICE_TABLE(of, rockchip_combphy_of_match); diff --git a/drivers/phy/rockchip/phy-rockchip-pcie.c b/drivers/phy/rockchip/phy-rockchip-pcie.c index 75216091d901..8234b83fdd88 100644 --- a/drivers/phy/rockchip/phy-rockchip-pcie.c +++ b/drivers/phy/rockchip/phy-rockchip-pcie.c @@ -119,21 +119,6 @@ static inline void phy_wr_cfg(struct rockchip_pcie_phy *rk_phy, PHY_CFG_WR_SHIFT)); } -static inline u32 phy_rd_cfg(struct rockchip_pcie_phy *rk_phy, - u32 addr) -{ - u32 val; - - regmap_write(rk_phy->reg_base, rk_phy->phy_data->pcie_conf, - HIWORD_UPDATE(addr, - PHY_CFG_RD_MASK, - PHY_CFG_ADDR_SHIFT)); - regmap_read(rk_phy->reg_base, - rk_phy->phy_data->pcie_status, - &val); - return val; -} - static int rockchip_pcie_phy_power_off(struct phy *phy) { struct phy_pcie_instance *inst = phy_get_drvdata(phy); diff --git a/drivers/phy/rockchip/phy-rockchip-typec.c b/drivers/phy/rockchip/phy-rockchip-typec.c index 39db8acde61a..8b1667be4915 100644 --- a/drivers/phy/rockchip/phy-rockchip-typec.c +++ b/drivers/phy/rockchip/phy-rockchip-typec.c @@ -1194,11 +1194,9 @@ static int rockchip_typec_phy_probe(struct platform_device *pdev) return 0; } -static int rockchip_typec_phy_remove(struct platform_device *pdev) +static void rockchip_typec_phy_remove(struct platform_device *pdev) { pm_runtime_disable(&pdev->dev); - - return 0; } static const struct of_device_id rockchip_typec_phy_dt_ids[] = { @@ -1213,7 +1211,7 @@ MODULE_DEVICE_TABLE(of, rockchip_typec_phy_dt_ids); static struct platform_driver rockchip_typec_phy_driver = { .probe = rockchip_typec_phy_probe, - .remove = rockchip_typec_phy_remove, + .remove_new = rockchip_typec_phy_remove, .driver = { .name = "rockchip-typec-phy", .of_match_table = rockchip_typec_phy_dt_ids, diff --git a/drivers/phy/st/phy-miphy28lp.c b/drivers/phy/st/phy-miphy28lp.c index 068160a34f5c..e30305b77f0d 100644 --- a/drivers/phy/st/phy-miphy28lp.c +++ b/drivers/phy/st/phy-miphy28lp.c @@ -9,6 +9,7 @@ #include <linux/platform_device.h> #include <linux/io.h> +#include <linux/iopoll.h> #include <linux/kernel.h> #include <linux/module.h> #include <linux/of.h> @@ -484,19 +485,11 @@ static inline void miphy28lp_pcie_config_gen(struct miphy28lp_phy *miphy_phy) static inline int miphy28lp_wait_compensation(struct miphy28lp_phy *miphy_phy) { - unsigned long finish = jiffies + 5 * HZ; u8 val; /* Waiting for Compensation to complete */ - do { - val = readb_relaxed(miphy_phy->base + MIPHY_COMP_FSM_6); - - if (time_after_eq(jiffies, finish)) - return -EBUSY; - cpu_relax(); - } while (!(val & COMP_DONE)); - - return 0; + return readb_relaxed_poll_timeout(miphy_phy->base + MIPHY_COMP_FSM_6, + val, val & COMP_DONE, 1, 5 * USEC_PER_SEC); } @@ -805,7 +798,6 @@ static inline void miphy28lp_configure_usb3(struct miphy28lp_phy *miphy_phy) static inline int miphy_is_ready(struct miphy28lp_phy *miphy_phy) { - unsigned long finish = jiffies + 5 * HZ; u8 mask = HFC_PLL | HFC_RDY; u8 val; @@ -816,21 +808,14 @@ static inline int miphy_is_ready(struct miphy28lp_phy *miphy_phy) if (miphy_phy->type == PHY_TYPE_SATA) mask |= PHY_RDY; - do { - val = readb_relaxed(miphy_phy->base + MIPHY_STATUS_1); - if ((val & mask) != mask) - cpu_relax(); - else - return 0; - } while (!time_after_eq(jiffies, finish)); - - return -EBUSY; + return readb_relaxed_poll_timeout(miphy_phy->base + MIPHY_STATUS_1, + val, (val & mask) == mask, 1, + 5 * USEC_PER_SEC); } static int miphy_osc_is_ready(struct miphy28lp_phy *miphy_phy) { struct miphy28lp_dev *miphy_dev = miphy_phy->phydev; - unsigned long finish = jiffies + 5 * HZ; u32 val; if (!miphy_phy->osc_rdy) @@ -839,17 +824,10 @@ static int miphy_osc_is_ready(struct miphy28lp_phy *miphy_phy) if (!miphy_phy->syscfg_reg[SYSCFG_STATUS]) return -EINVAL; - do { - regmap_read(miphy_dev->regmap, - miphy_phy->syscfg_reg[SYSCFG_STATUS], &val); - - if ((val & MIPHY_OSC_RDY) != MIPHY_OSC_RDY) - cpu_relax(); - else - return 0; - } while (!time_after_eq(jiffies, finish)); - - return -EBUSY; + return regmap_read_poll_timeout(miphy_dev->regmap, + miphy_phy->syscfg_reg[SYSCFG_STATUS], + val, val & MIPHY_OSC_RDY, 1, + 5 * USEC_PER_SEC); } static int miphy28lp_get_resource_byname(struct device_node *child, diff --git a/drivers/phy/st/phy-spear1310-miphy.c b/drivers/phy/st/phy-spear1310-miphy.c index 8871cd186304..292413db7da4 100644 --- a/drivers/phy/st/phy-spear1310-miphy.c +++ b/drivers/phy/st/phy-spear1310-miphy.c @@ -246,7 +246,7 @@ static struct platform_driver spear1310_miphy_driver = { .probe = spear1310_miphy_probe, .driver = { .name = "spear1310-miphy", - .of_match_table = of_match_ptr(spear1310_miphy_of_match), + .of_match_table = spear1310_miphy_of_match, }, }; diff --git a/drivers/phy/st/phy-spear1340-miphy.c b/drivers/phy/st/phy-spear1340-miphy.c index ed4d0e2df053..c1d9ffa5a311 100644 --- a/drivers/phy/st/phy-spear1340-miphy.c +++ b/drivers/phy/st/phy-spear1340-miphy.c @@ -279,7 +279,7 @@ static struct platform_driver spear1340_miphy_driver = { .driver = { .name = "spear1340-miphy", .pm = &spear1340_miphy_pm_ops, - .of_match_table = of_match_ptr(spear1340_miphy_of_match), + .of_match_table = spear1340_miphy_of_match, }, }; diff --git a/drivers/phy/st/phy-stm32-usbphyc.c b/drivers/phy/st/phy-stm32-usbphyc.c index 5bb9647b078f..0a8552628cbd 100644 --- a/drivers/phy/st/phy-stm32-usbphyc.c +++ b/drivers/phy/st/phy-stm32-usbphyc.c @@ -317,6 +317,9 @@ static int stm32_usbphyc_pll_enable(struct stm32_usbphyc *usbphyc) stm32_usbphyc_set_bits(pll_reg, PLLEN); + /* Wait for maximum lock time */ + usleep_range(200, 300); + return 0; reg_disable: @@ -766,7 +769,7 @@ clk_disable: return ret; } -static int stm32_usbphyc_remove(struct platform_device *pdev) +static void stm32_usbphyc_remove(struct platform_device *pdev) { struct stm32_usbphyc *usbphyc = dev_get_drvdata(&pdev->dev); int port; @@ -779,8 +782,6 @@ static int stm32_usbphyc_remove(struct platform_device *pdev) stm32_usbphyc_clk48_unregister(usbphyc); clk_disable_unprepare(usbphyc->clk); - - return 0; } static int __maybe_unused stm32_usbphyc_resume(struct device *dev) @@ -810,7 +811,7 @@ MODULE_DEVICE_TABLE(of, stm32_usbphyc_of_match); static struct platform_driver stm32_usbphyc_driver = { .probe = stm32_usbphyc_probe, - .remove = stm32_usbphyc_remove, + .remove_new = stm32_usbphyc_remove, .driver = { .of_match_table = stm32_usbphyc_of_match, .name = "stm32-usbphyc", diff --git a/drivers/phy/tegra/xusb-tegra186.c b/drivers/phy/tegra/xusb-tegra186.c index 1aae8535f452..0f60d5d1c167 100644 --- a/drivers/phy/tegra/xusb-tegra186.c +++ b/drivers/phy/tegra/xusb-tegra186.c @@ -145,6 +145,8 @@ #define MODE_HS MODE(0) #define MODE_RST MODE(1) +#define XUSB_AO_UTMIP_SLEEPWALK_STATUS(x) (0xa0 + (x) * 4) + #define XUSB_AO_UTMIP_SLEEPWALK_CFG(x) (0xd0 + (x) * 4) #define XUSB_AO_UHSIC_SLEEPWALK_CFG(x) (0xf0 + (x) * 4) #define FAKE_USBOP_VAL BIT(0) @@ -172,24 +174,30 @@ #define AP_A BIT(4) #define AN_A BIT(5) #define HIGHZ_A BIT(6) +#define MASTER_ENABLE_A BIT(7) /* phase B */ #define USBOP_RPD_B BIT(8) #define USBON_RPD_B BIT(9) #define AP_B BIT(12) #define AN_B BIT(13) #define HIGHZ_B BIT(14) +#define MASTER_ENABLE_B BIT(15) /* phase C */ #define USBOP_RPD_C BIT(16) #define USBON_RPD_C BIT(17) #define AP_C BIT(20) #define AN_C BIT(21) #define HIGHZ_C BIT(22) +#define MASTER_ENABLE_C BIT(23) /* phase D */ #define USBOP_RPD_D BIT(24) #define USBON_RPD_D BIT(25) #define AP_D BIT(28) #define AN_D BIT(29) #define HIGHZ_D BIT(30) +#define MASTER_ENABLE_D BIT(31) +#define MASTER_ENABLE_B_C_D \ + (MASTER_ENABLE_B | MASTER_ENABLE_C | MASTER_ENABLE_D) #define XUSB_AO_UHSIC_SLEEPWALK(x) (0x120 + (x) * 4) /* phase A */ @@ -417,6 +425,8 @@ static int tegra186_utmi_enable_phy_sleepwalk(struct tegra_xusb_lane *lane, value |= HIGHZ_A; value |= AP_A; value |= AN_B | AN_C | AN_D; + if (padctl->soc->supports_lp_cfg_en) + value |= MASTER_ENABLE_B_C_D; break; case USB_SPEED_LOW: @@ -424,6 +434,8 @@ static int tegra186_utmi_enable_phy_sleepwalk(struct tegra_xusb_lane *lane, value |= HIGHZ_A; value |= AN_A; value |= AP_B | AP_C | AP_D; + if (padctl->soc->supports_lp_cfg_en) + value |= MASTER_ENABLE_B_C_D; break; default: @@ -488,6 +500,13 @@ static int tegra186_utmi_disable_phy_sleepwalk(struct tegra_xusb_lane *lane) value |= WAKE_VAL_NONE; ao_writel(priv, value, XUSB_AO_UTMIP_SLEEPWALK_CFG(index)); + if (padctl->soc->supports_lp_cfg_en) { + /* disable the four stages of sleepwalk */ + value = ao_readl(priv, XUSB_AO_UTMIP_SLEEPWALK(index)); + value &= ~(MASTER_ENABLE_A | MASTER_ENABLE_B_C_D); + ao_writel(priv, value, XUSB_AO_UTMIP_SLEEPWALK(index)); + } + /* power down the line state detectors of the port */ value = ao_readl(priv, XUSB_AO_UTMIP_PAD_CFG(index)); value |= USBOP_VAL_PD | USBON_VAL_PD; @@ -1673,6 +1692,7 @@ const struct tegra_xusb_padctl_soc tegra234_xusb_padctl_soc = { .supports_gen2 = true, .poll_trk_completed = true, .trk_hw_mode = true, + .supports_lp_cfg_en = true, }; EXPORT_SYMBOL_GPL(tegra234_xusb_padctl_soc); #endif diff --git a/drivers/phy/tegra/xusb.c b/drivers/phy/tegra/xusb.c index 78045bd6c214..b55d4e9f42b5 100644 --- a/drivers/phy/tegra/xusb.c +++ b/drivers/phy/tegra/xusb.c @@ -805,6 +805,7 @@ static int tegra_xusb_add_usb2_port(struct tegra_xusb_padctl *padctl, usb2->base.lane = usb2->base.ops->map(&usb2->base); if (IS_ERR(usb2->base.lane)) { err = PTR_ERR(usb2->base.lane); + tegra_xusb_port_unregister(&usb2->base); goto out; } @@ -871,6 +872,7 @@ static int tegra_xusb_add_ulpi_port(struct tegra_xusb_padctl *padctl, ulpi->base.lane = ulpi->base.ops->map(&ulpi->base); if (IS_ERR(ulpi->base.lane)) { err = PTR_ERR(ulpi->base.lane); + tegra_xusb_port_unregister(&ulpi->base); goto out; } @@ -1267,7 +1269,7 @@ remove: return err; } -static int tegra_xusb_padctl_remove(struct platform_device *pdev) +static void tegra_xusb_padctl_remove(struct platform_device *pdev) { struct tegra_xusb_padctl *padctl = platform_get_drvdata(pdev); int err; @@ -1285,8 +1287,6 @@ static int tegra_xusb_padctl_remove(struct platform_device *pdev) dev_err(&pdev->dev, "failed to assert reset: %d\n", err); padctl->soc->ops->remove(padctl); - - return 0; } static __maybe_unused int tegra_xusb_padctl_suspend_noirq(struct device *dev) @@ -1321,7 +1321,7 @@ static struct platform_driver tegra_xusb_padctl_driver = { .pm = &tegra_xusb_padctl_pm_ops, }, .probe = tegra_xusb_padctl_probe, - .remove = tegra_xusb_padctl_remove, + .remove_new = tegra_xusb_padctl_remove, }; module_platform_driver(tegra_xusb_padctl_driver); diff --git a/drivers/phy/tegra/xusb.h b/drivers/phy/tegra/xusb.h index 8bd6cd281119..6e45d194c689 100644 --- a/drivers/phy/tegra/xusb.h +++ b/drivers/phy/tegra/xusb.h @@ -434,6 +434,7 @@ struct tegra_xusb_padctl_soc { bool need_fake_usb3_port; bool poll_trk_completed; bool trk_hw_mode; + bool supports_lp_cfg_en; }; struct tegra_xusb_padctl { diff --git a/drivers/phy/ti/phy-am654-serdes.c b/drivers/phy/ti/phy-am654-serdes.c index 0be727bb9f79..4ed2d951d3df 100644 --- a/drivers/phy/ti/phy-am654-serdes.c +++ b/drivers/phy/ti/phy-am654-serdes.c @@ -842,20 +842,18 @@ clk_err: return ret; } -static int serdes_am654_remove(struct platform_device *pdev) +static void serdes_am654_remove(struct platform_device *pdev) { struct serdes_am654 *am654_phy = platform_get_drvdata(pdev); struct device_node *node = am654_phy->of_node; pm_runtime_disable(&pdev->dev); of_clk_del_provider(node); - - return 0; } static struct platform_driver serdes_am654_driver = { .probe = serdes_am654_probe, - .remove = serdes_am654_remove, + .remove_new = serdes_am654_remove, .driver = { .name = "phy-am654", .of_match_table = serdes_am654_id_table, diff --git a/drivers/phy/ti/phy-da8xx-usb.c b/drivers/phy/ti/phy-da8xx-usb.c index 83bc0a9afe12..b7a9ef3f4654 100644 --- a/drivers/phy/ti/phy-da8xx-usb.c +++ b/drivers/phy/ti/phy-da8xx-usb.c @@ -211,7 +211,7 @@ static int da8xx_usb_phy_probe(struct platform_device *pdev) return 0; } -static int da8xx_usb_phy_remove(struct platform_device *pdev) +static void da8xx_usb_phy_remove(struct platform_device *pdev) { struct da8xx_usb_phy *d_phy = platform_get_drvdata(pdev); @@ -219,8 +219,6 @@ static int da8xx_usb_phy_remove(struct platform_device *pdev) phy_remove_lookup(d_phy->usb20_phy, "usb-phy", "musb-da8xx"); phy_remove_lookup(d_phy->usb11_phy, "usb-phy", "ohci-da8xx"); } - - return 0; } static const struct of_device_id da8xx_usb_phy_ids[] = { @@ -231,7 +229,7 @@ MODULE_DEVICE_TABLE(of, da8xx_usb_phy_ids); static struct platform_driver da8xx_usb_phy_driver = { .probe = da8xx_usb_phy_probe, - .remove = da8xx_usb_phy_remove, + .remove_new = da8xx_usb_phy_remove, .driver = { .name = "da8xx-usb-phy", .of_match_table = da8xx_usb_phy_ids, diff --git a/drivers/phy/ti/phy-dm816x-usb.c b/drivers/phy/ti/phy-dm816x-usb.c index fb619908f912..db153a55f4e1 100644 --- a/drivers/phy/ti/phy-dm816x-usb.c +++ b/drivers/phy/ti/phy-dm816x-usb.c @@ -257,20 +257,18 @@ clk_unprepare: return error; } -static int dm816x_usb_phy_remove(struct platform_device *pdev) +static void dm816x_usb_phy_remove(struct platform_device *pdev) { struct dm816x_usb_phy *phy = platform_get_drvdata(pdev); usb_remove_phy(&phy->phy); pm_runtime_disable(phy->dev); clk_unprepare(phy->refclk); - - return 0; } static struct platform_driver dm816x_usb_phy_driver = { .probe = dm816x_usb_phy_probe, - .remove = dm816x_usb_phy_remove, + .remove_new = dm816x_usb_phy_remove, .driver = { .name = "dm816x-usb-phy", .pm = &dm816x_usb_phy_pm_ops, diff --git a/drivers/phy/ti/phy-j721e-wiz.c b/drivers/phy/ti/phy-j721e-wiz.c index 1b83c98a78f0..d91923799df2 100644 --- a/drivers/phy/ti/phy-j721e-wiz.c +++ b/drivers/phy/ti/phy-j721e-wiz.c @@ -443,18 +443,17 @@ static int wiz_mode_select(struct wiz *wiz) int i; for (i = 0; i < num_lanes; i++) { - if (wiz->lane_phy_type[i] == PHY_TYPE_DP) + if (wiz->lane_phy_type[i] == PHY_TYPE_DP) { mode = LANE_MODE_GEN1; - else if (wiz->lane_phy_type[i] == PHY_TYPE_QSGMII) + } else if (wiz->lane_phy_type[i] == PHY_TYPE_QSGMII) { mode = LANE_MODE_GEN2; - else - continue; - - if (wiz->lane_phy_type[i] == PHY_TYPE_USXGMII) { + } else if (wiz->lane_phy_type[i] == PHY_TYPE_USXGMII) { ret = regmap_field_write(wiz->p0_mac_src_sel[i], 0x3); ret = regmap_field_write(wiz->p0_rxfclk_sel[i], 0x3); ret = regmap_field_write(wiz->p0_refclk_sel[i], 0x3); mode = LANE_MODE_GEN1; + } else { + continue; } ret = regmap_field_write(wiz->p_standard_mode[i], mode); @@ -1235,6 +1234,8 @@ static int wiz_phy_fullrt_div(struct wiz *wiz, int lane) if (wiz->lane_phy_type[lane] == PHY_TYPE_PCIE) return regmap_field_write(wiz->p0_fullrt_div[lane], 0x1); break; + + case J721E_WIZ_16G: case J721E_WIZ_10G: case J7200_WIZ_10G: case J721S2_WIZ_10G: @@ -1636,7 +1637,7 @@ err_addr_to_resource: return ret; } -static int wiz_remove(struct platform_device *pdev) +static void wiz_remove(struct platform_device *pdev) { struct device *dev = &pdev->dev; struct device_node *node = dev->of_node; @@ -1650,13 +1651,11 @@ static int wiz_remove(struct platform_device *pdev) wiz_clock_cleanup(wiz, node); pm_runtime_put(dev); pm_runtime_disable(dev); - - return 0; } static struct platform_driver wiz_driver = { .probe = wiz_probe, - .remove = wiz_remove, + .remove_new = wiz_remove, .driver = { .name = "wiz", .of_match_table = wiz_id_table, diff --git a/drivers/phy/ti/phy-omap-usb2.c b/drivers/phy/ti/phy-omap-usb2.c index 31a775877f6e..762d3de8b3c5 100644 --- a/drivers/phy/ti/phy-omap-usb2.c +++ b/drivers/phy/ti/phy-omap-usb2.c @@ -445,11 +445,9 @@ static int omap_usb2_probe(struct platform_device *pdev) PTR_ERR(phy->wkupclk)); phy->wkupclk = devm_clk_get(phy->dev, "usb_phy_cm_clk32k"); - if (IS_ERR(phy->wkupclk)) { - if (PTR_ERR(phy->wkupclk) != -EPROBE_DEFER) - dev_err(&pdev->dev, "unable to get usb_phy_cm_clk32k\n"); - return PTR_ERR(phy->wkupclk); - } + if (IS_ERR(phy->wkupclk)) + return dev_err_probe(&pdev->dev, PTR_ERR(phy->wkupclk), + "unable to get usb_phy_cm_clk32k\n"); dev_warn(&pdev->dev, "found usb_phy_cm_clk32k, please fix DTS\n"); @@ -506,19 +504,17 @@ static int omap_usb2_probe(struct platform_device *pdev) return 0; } -static int omap_usb2_remove(struct platform_device *pdev) +static void omap_usb2_remove(struct platform_device *pdev) { struct omap_usb *phy = platform_get_drvdata(pdev); usb_remove_phy(&phy->phy); pm_runtime_disable(phy->dev); - - return 0; } static struct platform_driver omap_usb2_driver = { .probe = omap_usb2_probe, - .remove = omap_usb2_remove, + .remove_new = omap_usb2_remove, .driver = { .name = "omap-usb2", .of_match_table = omap_usb2_id_table, diff --git a/drivers/phy/ti/phy-ti-pipe3.c b/drivers/phy/ti/phy-ti-pipe3.c index f502c36f3be5..507e1552db5e 100644 --- a/drivers/phy/ti/phy-ti-pipe3.c +++ b/drivers/phy/ti/phy-ti-pipe3.c @@ -841,7 +841,7 @@ static int ti_pipe3_probe(struct platform_device *pdev) return PTR_ERR_OR_ZERO(phy_provider); } -static int ti_pipe3_remove(struct platform_device *pdev) +static void ti_pipe3_remove(struct platform_device *pdev) { struct ti_pipe3 *phy = platform_get_drvdata(pdev); @@ -850,8 +850,6 @@ static int ti_pipe3_remove(struct platform_device *pdev) phy->sata_refclk_enabled = false; } pm_runtime_disable(&pdev->dev); - - return 0; } static int ti_pipe3_enable_clocks(struct ti_pipe3 *phy) @@ -928,7 +926,7 @@ MODULE_DEVICE_TABLE(of, ti_pipe3_id_table); static struct platform_driver ti_pipe3_driver = { .probe = ti_pipe3_probe, - .remove = ti_pipe3_remove, + .remove_new = ti_pipe3_remove, .driver = { .name = "ti-pipe3", .of_match_table = ti_pipe3_id_table, diff --git a/drivers/phy/ti/phy-twl4030-usb.c b/drivers/phy/ti/phy-twl4030-usb.c index ac71017a0bc1..da50732625d1 100644 --- a/drivers/phy/ti/phy-twl4030-usb.c +++ b/drivers/phy/ti/phy-twl4030-usb.c @@ -787,7 +787,7 @@ static int twl4030_usb_probe(struct platform_device *pdev) return 0; } -static int twl4030_usb_remove(struct platform_device *pdev) +static void twl4030_usb_remove(struct platform_device *pdev) { struct twl4030_usb *twl = platform_get_drvdata(pdev); int val; @@ -821,8 +821,6 @@ static int twl4030_usb_remove(struct platform_device *pdev) /* disable complete OTG block */ twl4030_usb_clear_bits(twl, POWER_CTRL, POWER_CTRL_OTG_ENAB); - - return 0; } #ifdef CONFIG_OF @@ -835,7 +833,7 @@ MODULE_DEVICE_TABLE(of, twl4030_usb_id_table); static struct platform_driver twl4030_usb_driver = { .probe = twl4030_usb_probe, - .remove = twl4030_usb_remove, + .remove_new = twl4030_usb_remove, .driver = { .name = "twl4030_usb", .pm = &twl4030_usb_pm_ops, diff --git a/drivers/phy/xilinx/phy-zynqmp.c b/drivers/phy/xilinx/phy-zynqmp.c index 9be9535ad7ab..8833680923a1 100644 --- a/drivers/phy/xilinx/phy-zynqmp.c +++ b/drivers/phy/xilinx/phy-zynqmp.c @@ -8,9 +8,8 @@ * Author: Subbaraya Sundeep <sundeep.lkml@gmail.com> * Author: Laurent Pinchart <laurent.pinchart@ideasonboard.com> * - * This driver is tested for USB, SATA and Display Port currently. - * Other controllers PCIe and SGMII should also work but that is - * experimental as of now. + * This driver is tested for USB, SGMII, SATA and Display Port currently. + * PCIe should also work but that is experimental as of now. */ #include <linux/clk.h> |