/* Program REF_CLK source */
val = readl(qphy->base + PCIE20_PARF_PHY_REFCLK_CTRL2);
val &= ~BIT(1);
writel(val, qphy->base + PCIE20_PARF_PHY_REFCLK_CTRL2);
usleep_range(1000, 2000);
/* Don't use PAD for refclock */
val = readl(qphy->base + PCIE20_PARF_PHY_REFCLK_CTRL2);
val &= ~BIT(0);
writel(val, qphy->base + PCIE20_PARF_PHY_REFCLK_CTRL2);
/* Program SSP ENABLE */
val = readl(qphy->base + PCIE20_PARF_PHY_REFCLK_CTRL3);
val |= BIT(0);
writel(val, qphy->base + PCIE20_PARF_PHY_REFCLK_CTRL3);
usleep_range(1000, 2000);
/* Assert Phy SW Reset */
val = readl(qphy->base + PCIE2_PHY_RESET_CTRL);
val |= BIT(0);
writel(val, qphy->base + PCIE2_PHY_RESET_CTRL);
/* Program Tx Amplitude */
val = readl(qphy->base + PCIE20_PARF_PCS_SWING_CTRL1);
val &= ~0x7f;
val |= TX_AMP_VAL;
writel(val, qphy->base + PCIE20_PARF_PCS_SWING_CTRL1);
val = readl(qphy->base + PCIE20_PARF_PCS_SWING_CTRL2);
val &= ~0x7f;
val |= TX_AMP_VAL;
writel(val, qphy->base + PCIE20_PARF_PCS_SWING_CTRL2);
/* Program De-Emphasis */
val = readl(qphy->base + PCIE20_PARF_PCS_DEEMPH1);
val &= ~0x3f;
val |= TX_DEEMPH_GEN2_6DB_VAL;
writel(val, qphy->base + PCIE20_PARF_PCS_DEEMPH1);
val = readl(qphy->base + PCIE20_PARF_PCS_DEEMPH2);
val &= ~0x3f;
val |= TX_DEEMPH_GEN2_3_5DB_VAL;
writel(val, qphy->base + PCIE20_PARF_PCS_DEEMPH2);
val = readl(qphy->base + PCIE20_PARF_PCS_DEEMPH3);
val &= ~0x3f;
val |= TX_DEEMPH_GEN1_VAL;
writel(val, qphy->base + PCIE20_PARF_PCS_DEEMPH3);
/* Program Rx_Eq */
val = readl(qphy->base + PCIE20_PARF_CONFIGBITS);
val &= ~0x7;
val |= PHY_RX0_EQ_GEN2_VAL;
writel(val, qphy->base + PCIE20_PARF_CONFIGBITS);
/* Program Tx0_term_offset */
val = readl(qphy->base + PCIE20_PARF_PHY_CTRL3);
val &= ~0x1f;
val |= PHY_TX0_TERM_OFFST_VAL;
writel(val, qphy->base + PCIE20_PARF_PHY_CTRL3);
/* disable Tx2Rx Loopback */
val = readl(qphy->base + PCIE20_PARF_PCS_CTRL);
val &= ~BIT(1);
writel(val, qphy->base + PCIE20_PARF_PCS_CTRL);
/* De-assert Phy SW Reset */
val = readl(qphy->base + PCIE2_PHY_RESET_CTRL);
val &= ~BIT(0);
writel(val, qphy->base + PCIE2_PHY_RESET_CTRL);
usleep_range(1000, 2000);
ret = reset_control_deassert(qphy->pipe_reset); if (ret) {
dev_err(qphy->dev, "cannot deassert pipe reset\n"); goto out;
}
clk_set_rate(qphy->pipe_clk, 250000000);
ret = clk_prepare_enable(qphy->pipe_clk); if (ret) {
dev_err(qphy->dev, "failed to enable pipe clock\n"); goto out;
}
ret = readl_poll_timeout(qphy->base + PCIE20_PARF_PHY_STTS, val,
!(val & BIT(0)), 1000, 10); if (ret)
dev_err(qphy->dev, "phy initialization failed\n");
/* * Register a fixed rate pipe clock. * * The <s>_pipe_clksrc generated by PHY goes to the GCC that gate * controls it. The <s>_pipe_clk coming out of the GCC is requested * by the PHY driver for its operations. * We register the <s>_pipe_clksrc here. The gcc driver takes care * of assigning this <s>_pipe_clksrc as parent to <s>_pipe_clk. * Below picture shows this relationship. * * +---------------+ * | PHY block |<<---------------------------------------+ * | | | * | +-------+ | +-----+ | * I/P---^-->| PLL |---^--->pipe_clksrc--->| GCC |--->pipe_clk---+ * clk | +-------+ | +-----+ * +---------------+
*/ staticint phy_pipe_clksrc_register(struct qcom_phy *qphy)
{ struct device_node *np = qphy->dev->of_node; struct clk_fixed_rate *fixed; struct clk_init_data init = { }; int ret;
ret = of_property_read_string(np, "clock-output-names", &init.name); if (ret) {
dev_err(qphy->dev, "%s: No clock-output-names\n", np->name); return ret;
}
fixed = devm_kzalloc(qphy->dev, sizeof(*fixed), GFP_KERNEL); if (!fixed) return -ENOMEM;
init.ops = &clk_fixed_rate_ops;
/* controllers using QMP phys use 250MHz pipe clock interface */
fixed->fixed_rate = 250000000;
fixed->hw.init = &init;
ret = devm_clk_hw_register(qphy->dev, &fixed->hw); if (ret < 0) return ret;
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.