phy: fixes for 5.17
Fixes for bunch of drivers: - clk params for dphy - arg fix for mtk-tphy - refcount leak fix for stm32 - bus width fix for zynqmp - sentinel fix ti - PHY_BRCM_USB Kconfig fix - clk fix for usb phy -----BEGIN PGP SIGNATURE----- iQIzBAABCAAdFiEE+vs47OPLdNbVcHzyfBQHDyUjg0cFAmH9V/0ACgkQfBQHDyUj g0edyQ//bJjAoEnUWNcUjS4FYn/tAFAcsDD7pXQFoQoxWcQ3OxLGUulakIirmSgH 4PNxI6IPvYzWLRKfiqIF6gSPQC8SVc1pfXH10KbouSOk7ss9uynyBrnS44q9lzFe dLIVwSFSyXCBWP9jGQx/0Y7iIS4FtIrfxaYlDkJwt4JGWh4u5JTwNFhzhRGf6jee 8+hm6zEPNWKFYuMpfS+v45COJbcZ68WLJQOltZHHxqaKT1m8CSh3eWJOSTwCqtju iADLEOu8S/oJ3PGBHT+PZIk2hI7udgVlTxjPx0ENTcXyC5oq/3b77Xxelrp0+3dI M+wM8mfN49xW/YyM/Ya0H0pDFyLLnujoT+tDeHlVVPz6rt/KyKowwyQPnTHxUA8u HYf2Nbfs/Hxx52eYP1+JB4r5OYeX4zzWr5itPN3FXwGmHWtKJcaDVTdon/H5I9ag airSy8IDIZPRHGGEFnecBFG6geSsbIFKv3Hvk2v2OpxKRbMMxptOoCfqvZSoNwi8 WV+JyuyVH8E3QIxAGa5TUvkyweMHwJ97HYmTJwcvPDz23yVIRtxkhxwuxLFzNPnl 57U2uYd/3rYpLCyRMlnjizhjzLd/D/Mnbs3u35xp2OZPp6qCffmUx4+0n7xvFu4+ 2jpa1Liob4gPtxhMD7usAhPDv25uPF6cUBCYQfzh+BeHlWp5bvs= =Av3W -----END PGP SIGNATURE----- Merge tag 'phy-fixes-5.17' of git://git.kernel.org/pub/scm/linux/kernel/git/phy/linux-phy into char-misc-next Vinod writes: phy: fixes for 5.17 Fixes for bunch of drivers: - clk params for dphy - arg fix for mtk-tphy - refcount leak fix for stm32 - bus width fix for zynqmp - sentinel fix ti - PHY_BRCM_USB Kconfig fix - clk fix for usb phy * tag 'phy-fixes-5.17' of git://git.kernel.org/pub/scm/linux/kernel/git/phy/linux-phy: phy: dphy: Correct clk_pre parameter phy: phy-mtk-tphy: Fix duplicated argument in phy-mtk-tphy phy: stm32: fix a refcount leak in stm32_usbphyc_pll_enable() phy: xilinx: zynqmp: Fix bus width setting for SGMII phy: cadence: Sierra: fix error handling bugs in probe() phy: ti: Fix missing sentinel for clk_div_table phy: broadcom: Kconfig: Fix PHY_BRCM_USB config option phy: usb: Leave some clocks running during suspend
This commit is contained in:
Коммит
9ccdcc73d3
|
@ -7,6 +7,7 @@
|
|||
*/
|
||||
|
||||
#include <linux/bitfield.h>
|
||||
#include <linux/bits.h>
|
||||
#include <linux/clk.h>
|
||||
#include <linux/irq.h>
|
||||
#include <linux/math64.h>
|
||||
|
@ -196,12 +197,9 @@ static u32 ps2bc(struct nwl_dsi *dsi, unsigned long long ps)
|
|||
/*
|
||||
* ui2bc - UI time periods to byte clock cycles
|
||||
*/
|
||||
static u32 ui2bc(struct nwl_dsi *dsi, unsigned long long ui)
|
||||
static u32 ui2bc(unsigned int ui)
|
||||
{
|
||||
u32 bpp = mipi_dsi_pixel_format_to_bpp(dsi->format);
|
||||
|
||||
return DIV64_U64_ROUND_UP(ui * dsi->lanes,
|
||||
dsi->mode.clock * 1000 * bpp);
|
||||
return DIV_ROUND_UP(ui, BITS_PER_BYTE);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -232,12 +230,12 @@ static int nwl_dsi_config_host(struct nwl_dsi *dsi)
|
|||
}
|
||||
|
||||
/* values in byte clock cycles */
|
||||
cycles = ui2bc(dsi, cfg->clk_pre);
|
||||
cycles = ui2bc(cfg->clk_pre);
|
||||
DRM_DEV_DEBUG_DRIVER(dsi->dev, "cfg_t_pre: 0x%x\n", cycles);
|
||||
nwl_dsi_write(dsi, NWL_DSI_CFG_T_PRE, cycles);
|
||||
cycles = ps2bc(dsi, cfg->lpx + cfg->clk_prepare + cfg->clk_zero);
|
||||
DRM_DEV_DEBUG_DRIVER(dsi->dev, "cfg_tx_gap (pre): 0x%x\n", cycles);
|
||||
cycles += ui2bc(dsi, cfg->clk_pre);
|
||||
cycles += ui2bc(cfg->clk_pre);
|
||||
DRM_DEV_DEBUG_DRIVER(dsi->dev, "cfg_t_post: 0x%x\n", cycles);
|
||||
nwl_dsi_write(dsi, NWL_DSI_CFG_T_POST, cycles);
|
||||
cycles = ps2bc(dsi, cfg->hs_exit);
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
|
||||
#include <linux/bitfield.h>
|
||||
#include <linux/bitops.h>
|
||||
#include <linux/bits.h>
|
||||
#include <linux/clk.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/io.h>
|
||||
|
@ -250,7 +251,7 @@ static int phy_meson_axg_mipi_dphy_power_on(struct phy *phy)
|
|||
(DIV_ROUND_UP(priv->config.clk_zero, temp) << 16) |
|
||||
(DIV_ROUND_UP(priv->config.clk_prepare, temp) << 24));
|
||||
regmap_write(priv->regmap, MIPI_DSI_CLK_TIM1,
|
||||
DIV_ROUND_UP(priv->config.clk_pre, temp));
|
||||
DIV_ROUND_UP(priv->config.clk_pre, BITS_PER_BYTE));
|
||||
|
||||
regmap_write(priv->regmap, MIPI_DSI_HS_TIM,
|
||||
DIV_ROUND_UP(priv->config.hs_exit, temp) |
|
||||
|
|
|
@ -97,8 +97,7 @@ config PHY_BRCM_USB
|
|||
depends on OF
|
||||
select GENERIC_PHY
|
||||
select SOC_BRCMSTB if ARCH_BRCMSTB
|
||||
default ARCH_BCM4908
|
||||
default ARCH_BRCMSTB
|
||||
default ARCH_BCM4908 || ARCH_BRCMSTB
|
||||
help
|
||||
Enable this to support the Broadcom STB USB PHY.
|
||||
This driver is required by the USB XHCI, EHCI and OHCI
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
#include <linux/soc/brcmstb/brcmstb.h>
|
||||
#include <dt-bindings/phy/phy.h>
|
||||
#include <linux/mfd/syscon.h>
|
||||
#include <linux/suspend.h>
|
||||
|
||||
#include "phy-brcm-usb-init.h"
|
||||
|
||||
|
@ -70,12 +71,35 @@ struct brcm_usb_phy_data {
|
|||
int init_count;
|
||||
int wake_irq;
|
||||
struct brcm_usb_phy phys[BRCM_USB_PHY_ID_MAX];
|
||||
struct notifier_block pm_notifier;
|
||||
bool pm_active;
|
||||
};
|
||||
|
||||
static s8 *node_reg_names[BRCM_REGS_MAX] = {
|
||||
"crtl", "xhci_ec", "xhci_gbl", "usb_phy", "usb_mdio", "bdc_ec"
|
||||
};
|
||||
|
||||
static int brcm_pm_notifier(struct notifier_block *notifier,
|
||||
unsigned long pm_event,
|
||||
void *unused)
|
||||
{
|
||||
struct brcm_usb_phy_data *priv =
|
||||
container_of(notifier, struct brcm_usb_phy_data, pm_notifier);
|
||||
|
||||
switch (pm_event) {
|
||||
case PM_HIBERNATION_PREPARE:
|
||||
case PM_SUSPEND_PREPARE:
|
||||
priv->pm_active = true;
|
||||
break;
|
||||
case PM_POST_RESTORE:
|
||||
case PM_POST_HIBERNATION:
|
||||
case PM_POST_SUSPEND:
|
||||
priv->pm_active = false;
|
||||
break;
|
||||
}
|
||||
return NOTIFY_DONE;
|
||||
}
|
||||
|
||||
static irqreturn_t brcm_usb_phy_wake_isr(int irq, void *dev_id)
|
||||
{
|
||||
struct phy *gphy = dev_id;
|
||||
|
@ -91,6 +115,9 @@ static int brcm_usb_phy_init(struct phy *gphy)
|
|||
struct brcm_usb_phy_data *priv =
|
||||
container_of(phy, struct brcm_usb_phy_data, phys[phy->id]);
|
||||
|
||||
if (priv->pm_active)
|
||||
return 0;
|
||||
|
||||
/*
|
||||
* Use a lock to make sure a second caller waits until
|
||||
* the base phy is inited before using it.
|
||||
|
@ -120,6 +147,9 @@ static int brcm_usb_phy_exit(struct phy *gphy)
|
|||
struct brcm_usb_phy_data *priv =
|
||||
container_of(phy, struct brcm_usb_phy_data, phys[phy->id]);
|
||||
|
||||
if (priv->pm_active)
|
||||
return 0;
|
||||
|
||||
dev_dbg(&gphy->dev, "EXIT\n");
|
||||
if (phy->id == BRCM_USB_PHY_2_0)
|
||||
brcm_usb_uninit_eohci(&priv->ini);
|
||||
|
@ -488,6 +518,9 @@ static int brcm_usb_phy_probe(struct platform_device *pdev)
|
|||
if (err)
|
||||
return err;
|
||||
|
||||
priv->pm_notifier.notifier_call = brcm_pm_notifier;
|
||||
register_pm_notifier(&priv->pm_notifier);
|
||||
|
||||
mutex_init(&priv->mutex);
|
||||
|
||||
/* make sure invert settings are correct */
|
||||
|
@ -528,7 +561,10 @@ static int brcm_usb_phy_probe(struct platform_device *pdev)
|
|||
|
||||
static int 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;
|
||||
}
|
||||
|
@ -539,6 +575,7 @@ static int brcm_usb_phy_suspend(struct device *dev)
|
|||
struct brcm_usb_phy_data *priv = dev_get_drvdata(dev);
|
||||
|
||||
if (priv->init_count) {
|
||||
dev_dbg(dev, "SUSPEND\n");
|
||||
priv->ini.wake_enabled = device_may_wakeup(dev);
|
||||
if (priv->phys[BRCM_USB_PHY_3_0].inited)
|
||||
brcm_usb_uninit_xhci(&priv->ini);
|
||||
|
@ -578,6 +615,7 @@ static int brcm_usb_phy_resume(struct device *dev)
|
|||
* Uninitialize anything that wasn't previously initialized.
|
||||
*/
|
||||
if (priv->init_count) {
|
||||
dev_dbg(dev, "RESUME\n");
|
||||
if (priv->wake_irq >= 0)
|
||||
disable_irq_wake(priv->wake_irq);
|
||||
brcm_usb_init_common(&priv->ini);
|
||||
|
|
|
@ -1338,7 +1338,7 @@ static int cdns_sierra_phy_probe(struct platform_device *pdev)
|
|||
struct device *dev = &pdev->dev;
|
||||
const struct cdns_sierra_data *data;
|
||||
unsigned int id_value;
|
||||
int i, ret, node = 0;
|
||||
int ret, node = 0;
|
||||
void __iomem *base;
|
||||
struct device_node *dn = dev->of_node, *child;
|
||||
|
||||
|
@ -1416,7 +1416,8 @@ static int cdns_sierra_phy_probe(struct platform_device *pdev)
|
|||
dev_err(dev, "failed to get reset %s\n",
|
||||
child->full_name);
|
||||
ret = PTR_ERR(sp->phys[node].lnk_rst);
|
||||
goto put_child2;
|
||||
of_node_put(child);
|
||||
goto put_control;
|
||||
}
|
||||
|
||||
if (!sp->autoconf) {
|
||||
|
@ -1424,7 +1425,9 @@ static int cdns_sierra_phy_probe(struct platform_device *pdev)
|
|||
if (ret) {
|
||||
dev_err(dev, "missing property in node %s\n",
|
||||
child->name);
|
||||
goto put_child;
|
||||
of_node_put(child);
|
||||
reset_control_put(sp->phys[node].lnk_rst);
|
||||
goto put_control;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1434,7 +1437,9 @@ static int cdns_sierra_phy_probe(struct platform_device *pdev)
|
|||
|
||||
if (IS_ERR(gphy)) {
|
||||
ret = PTR_ERR(gphy);
|
||||
goto put_child;
|
||||
of_node_put(child);
|
||||
reset_control_put(sp->phys[node].lnk_rst);
|
||||
goto put_control;
|
||||
}
|
||||
sp->phys[node].phy = gphy;
|
||||
phy_set_drvdata(gphy, &sp->phys[node]);
|
||||
|
@ -1446,26 +1451,28 @@ static int cdns_sierra_phy_probe(struct platform_device *pdev)
|
|||
if (sp->num_lanes > SIERRA_MAX_LANES) {
|
||||
ret = -EINVAL;
|
||||
dev_err(dev, "Invalid lane configuration\n");
|
||||
goto put_child2;
|
||||
goto put_control;
|
||||
}
|
||||
|
||||
/* If more than one subnode, configure the PHY as multilink */
|
||||
if (!sp->autoconf && sp->nsubnodes > 1) {
|
||||
ret = cdns_sierra_phy_configure_multilink(sp);
|
||||
if (ret)
|
||||
goto put_child2;
|
||||
goto put_control;
|
||||
}
|
||||
|
||||
pm_runtime_enable(dev);
|
||||
phy_provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate);
|
||||
return PTR_ERR_OR_ZERO(phy_provider);
|
||||
if (IS_ERR(phy_provider)) {
|
||||
ret = PTR_ERR(phy_provider);
|
||||
goto put_control;
|
||||
}
|
||||
|
||||
put_child:
|
||||
node++;
|
||||
put_child2:
|
||||
for (i = 0; i < node; i++)
|
||||
reset_control_put(sp->phys[i].lnk_rst);
|
||||
of_node_put(child);
|
||||
return 0;
|
||||
|
||||
put_control:
|
||||
while (--node >= 0)
|
||||
reset_control_put(sp->phys[node].lnk_rst);
|
||||
clk_disable:
|
||||
cdns_sierra_phy_disable_clocks(sp);
|
||||
reset_control_assert(sp->apb_rst);
|
||||
|
|
|
@ -992,7 +992,7 @@ static int phy_efuse_get(struct mtk_tphy *tphy, struct mtk_phy_instance *instanc
|
|||
/* no efuse, ignore it */
|
||||
if (!instance->efuse_intr &&
|
||||
!instance->efuse_rx_imp &&
|
||||
!instance->efuse_rx_imp) {
|
||||
!instance->efuse_tx_imp) {
|
||||
dev_warn(dev, "no u3 intr efuse, but dts enable it\n");
|
||||
instance->efuse_sw_en = 0;
|
||||
break;
|
||||
|
|
|
@ -36,7 +36,7 @@ int phy_mipi_dphy_get_default_config(unsigned long pixel_clock,
|
|||
|
||||
cfg->clk_miss = 0;
|
||||
cfg->clk_post = 60000 + 52 * ui;
|
||||
cfg->clk_pre = 8000;
|
||||
cfg->clk_pre = 8;
|
||||
cfg->clk_prepare = 38000;
|
||||
cfg->clk_settle = 95000;
|
||||
cfg->clk_term_en = 0;
|
||||
|
@ -97,7 +97,7 @@ int phy_mipi_dphy_config_validate(struct phy_configure_opts_mipi_dphy *cfg)
|
|||
if (cfg->clk_post < (60000 + 52 * ui))
|
||||
return -EINVAL;
|
||||
|
||||
if (cfg->clk_pre < 8000)
|
||||
if (cfg->clk_pre < 8)
|
||||
return -EINVAL;
|
||||
|
||||
if (cfg->clk_prepare < 38000 || cfg->clk_prepare > 95000)
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
* Author: Wyon Bi <bivvy.bi@rock-chips.com>
|
||||
*/
|
||||
|
||||
#include <linux/bits.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/clk.h>
|
||||
#include <linux/iopoll.h>
|
||||
|
@ -364,7 +365,7 @@ static void inno_dsidphy_mipi_mode_enable(struct inno_dsidphy *inno)
|
|||
* The value of counter for HS Tclk-pre
|
||||
* Tclk-pre = Tpin_txbyteclkhs * value
|
||||
*/
|
||||
clk_pre = DIV_ROUND_UP(cfg->clk_pre, t_txbyteclkhs);
|
||||
clk_pre = DIV_ROUND_UP(cfg->clk_pre, BITS_PER_BYTE);
|
||||
|
||||
/*
|
||||
* The value of counter for HS Tlpx Time
|
||||
|
|
|
@ -304,7 +304,7 @@ static int stm32_usbphyc_pll_enable(struct stm32_usbphyc *usbphyc)
|
|||
|
||||
ret = __stm32_usbphyc_pll_disable(usbphyc);
|
||||
if (ret)
|
||||
return ret;
|
||||
goto dec_n_pll_cons;
|
||||
}
|
||||
|
||||
ret = stm32_usbphyc_regulators_enable(usbphyc);
|
||||
|
|
|
@ -233,6 +233,7 @@ static const struct clk_div_table clk_div_table[] = {
|
|||
{ .val = 1, .div = 2, },
|
||||
{ .val = 2, .div = 4, },
|
||||
{ .val = 3, .div = 8, },
|
||||
{ /* sentinel */ },
|
||||
};
|
||||
|
||||
static const struct wiz_clk_div_sel clk_div_sel[] = {
|
||||
|
|
|
@ -134,7 +134,8 @@
|
|||
#define PROT_BUS_WIDTH_10 0x0
|
||||
#define PROT_BUS_WIDTH_20 0x1
|
||||
#define PROT_BUS_WIDTH_40 0x2
|
||||
#define PROT_BUS_WIDTH_SHIFT 2
|
||||
#define PROT_BUS_WIDTH_SHIFT(n) ((n) * 2)
|
||||
#define PROT_BUS_WIDTH_MASK(n) GENMASK((n) * 2 + 1, (n) * 2)
|
||||
|
||||
/* Number of GT lanes */
|
||||
#define NUM_LANES 4
|
||||
|
@ -445,12 +446,12 @@ static void xpsgtr_phy_init_sata(struct xpsgtr_phy *gtr_phy)
|
|||
static void xpsgtr_phy_init_sgmii(struct xpsgtr_phy *gtr_phy)
|
||||
{
|
||||
struct xpsgtr_dev *gtr_dev = gtr_phy->dev;
|
||||
u32 mask = PROT_BUS_WIDTH_MASK(gtr_phy->lane);
|
||||
u32 val = PROT_BUS_WIDTH_10 << PROT_BUS_WIDTH_SHIFT(gtr_phy->lane);
|
||||
|
||||
/* Set SGMII protocol TX and RX bus width to 10 bits. */
|
||||
xpsgtr_write(gtr_dev, TX_PROT_BUS_WIDTH,
|
||||
PROT_BUS_WIDTH_10 << (gtr_phy->lane * PROT_BUS_WIDTH_SHIFT));
|
||||
xpsgtr_write(gtr_dev, RX_PROT_BUS_WIDTH,
|
||||
PROT_BUS_WIDTH_10 << (gtr_phy->lane * PROT_BUS_WIDTH_SHIFT));
|
||||
xpsgtr_clr_set(gtr_dev, TX_PROT_BUS_WIDTH, mask, val);
|
||||
xpsgtr_clr_set(gtr_dev, RX_PROT_BUS_WIDTH, mask, val);
|
||||
|
||||
xpsgtr_bypass_scrambler_8b10b(gtr_phy);
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче