val = readl(phy->regs + SUNXI_PHY_EXTERNAL_CONTROL);
val |= SUNXI_PEC_EXTERN_VBUS;
val |= SUNXI_PEC_SSC_EN | SUNXI_PEC_REF_SSP_EN;
writel(val, phy->regs + SUNXI_PHY_EXTERNAL_CONTROL);
val = readl(phy->regs + SUNXI_PIPE_CLOCK_CONTROL);
val |= SUNXI_PCC_PIPE_CLK_OPEN;
writel(val, phy->regs + SUNXI_PIPE_CLOCK_CONTROL);
val = readl(phy->regs + SUNXI_ISCR);
val |= SUNXI_ISCR_FORCE_VBUS;
writel(val, phy->regs + SUNXI_ISCR);
/* * All the magic numbers written to the PHY_TUNE_{LOW_HIGH} * registers are directly taken from the BSP USB3 driver from * Allwiner.
*/
writel(0x0047fc87, phy->regs + SUNXI_PHY_TUNE_LOW);
val = readl(phy->regs + SUNXI_PHY_TUNE_HIGH);
val &= ~(SUNXI_TXVBOOSTLVL_MASK | SUNXI_LOS_BIAS_MASK |
SUNXI_TX_SWING_FULL_MASK | SUNXI_TX_DEEMPH_6GB_MASK |
SUNXI_TX_DEEMPH_3P5DB_MASK);
val |= SUNXI_TXVBOOSTLVL(0x7);
val |= SUNXI_LOS_BIAS(0x7);
val |= SUNXI_TX_SWING_FULL(0x55);
val |= SUNXI_TX_DEEMPH_6DB(0x20);
val |= SUNXI_TX_DEEMPH_3P5DB(0x15);
writel(val, phy->regs + SUNXI_PHY_TUNE_HIGH);
}
phy = devm_kzalloc(dev, sizeof(*phy), GFP_KERNEL); if (!phy) return -ENOMEM;
phy->clk = devm_clk_get(dev, NULL); if (IS_ERR(phy->clk)) { if (PTR_ERR(phy->clk) != -EPROBE_DEFER)
dev_err(dev, "failed to get phy clock\n"); return PTR_ERR(phy->clk);
}
phy->reset = devm_reset_control_get(dev, NULL); if (IS_ERR(phy->reset)) {
dev_err(dev, "failed to get reset control\n"); return PTR_ERR(phy->reset);
}
phy->regs = devm_platform_ioremap_resource(pdev, 0); if (IS_ERR(phy->regs)) return PTR_ERR(phy->regs);
phy->phy = devm_phy_create(dev, NULL, &sun50i_usb3_phy_ops); if (IS_ERR(phy->phy)) {
dev_err(dev, "failed to create PHY\n"); return PTR_ERR(phy->phy);
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.