/* * If the IP is in reset, treat the clock as not enabled, * this happens with some clocks such as the USB one when * coming from cold reset. Without this, aspeed_clk_enable() * will fail to lift the reset.
*/ if (gate->reset_idx >= 0) {
regmap_read(gate->map, ASPEED_RESET_CTRL, ®); if (reg & rst) return 0;
}
ret = devm_reset_controller_register(dev, &ar->rcdev); if (ret) {
dev_err(dev, "could not register reset controller\n"); return ret;
}
/* SoC generations share common layouts but have different divisors */
soc_data = of_device_get_match_data(dev); if (!soc_data) {
dev_err(dev, "no match data for platform\n"); return -EINVAL;
}
/* UART clock div13 setting */
regmap_read(map, ASPEED_MISC_CTRL, &val); if (val & UART_DIV13_EN)
rate = 24000000 / 13; else
rate = 24000000; /* TODO: Find the parent data for the uart clock */
hw = clk_hw_register_fixed_rate(dev, "uart", NULL, 0, rate); if (IS_ERR(hw)) return PTR_ERR(hw);
aspeed_clk_data->hws[ASPEED_CLK_UART] = hw;
/* * Memory controller (M-PLL) PLL. This clock is configured by the * bootloader, and is exposed to Linux as a read-only clock rate.
*/
regmap_read(map, ASPEED_MPLL_PARAM, &val);
hw = soc_data->calc_pll("mpll", val); if (IS_ERR(hw)) return PTR_ERR(hw);
aspeed_clk_data->hws[ASPEED_CLK_MPLL] = hw;
/* * TODO: There are a number of clocks that not included in this driver * as more information is required: * D2-PLL * D-PLL * YCLK * RGMII * RMII * UART[1..5] clock source mux
*/
for (i = 0; i < ARRAY_SIZE(aspeed_gates); i++) { conststruct aspeed_gate_data *gd = &aspeed_gates[i];
u32 gate_flags;
/* Special case: the USB port 1 clock (bit 14) is always * working the opposite way from the other ones.
*/
gate_flags = (gd->clock_idx == 14) ? 0 : CLK_GATE_SET_TO_DISABLE;
hw = aspeed_clk_hw_register_gate(dev,
gd->name,
gd->parent_name,
gd->flags,
map,
gd->clock_idx,
gd->reset_idx,
gate_flags,
&aspeed_clk_lock); if (IS_ERR(hw)) return PTR_ERR(hw);
aspeed_clk_data->hws[i] = hw;
}
/* * High-speed PLL clock derived from the crystal. This the CPU clock, * and we assume that it is enabled. It can be configured through the * HPLL_PARAM register, or set to a specified frequency by strapping.
*/
regmap_read(map, ASPEED_HPLL_PARAM, &val); if (val & AST2400_HPLL_PROGRAMMED)
hw = aspeed_ast2400_calc_pll("hpll", val); else
hw = clk_hw_register_fixed_rate(NULL, "hpll", "clkin", 0,
hpll * 1000000);
aspeed_clk_data->hws[ASPEED_CLK_HPLL] = hw;
/* * Strap bits 11:10 define the CPU/AHB clock frequency ratio (aka HCLK) * 00: Select CPU:AHB = 1:1 * 01: Select CPU:AHB = 2:1 * 10: Select CPU:AHB = 4:1 * 11: Select CPU:AHB = 3:1
*/
regmap_read(map, ASPEED_STRAP, &val);
val = (val >> 10) & 0x3;
div = val + 1; if (div == 3)
div = 4; elseif (div == 4)
div = 3;
hw = clk_hw_register_fixed_factor(NULL, "ahb", "hpll", 0, 1, div);
aspeed_clk_data->hws[ASPEED_CLK_AHB] = hw;
/* CLKIN is the crystal oscillator, 24 or 25MHz selected by strapping */
regmap_read(map, ASPEED_STRAP, &val); if (val & CLKIN_25MHZ_EN)
freq = 25000000; else
freq = 24000000;
hw = clk_hw_register_fixed_rate(NULL, "clkin", NULL, 0, freq);
pr_debug("clkin @%u MHz\n", freq / 1000000);
/* * High-speed PLL clock derived from the crystal. This the CPU clock, * and we assume that it is enabled
*/
regmap_read(map, ASPEED_HPLL_PARAM, &val);
aspeed_clk_data->hws[ASPEED_CLK_HPLL] = aspeed_ast2500_calc_pll("hpll", val);
/* Strap bits 11:9 define the AXI/AHB clock frequency ratio (aka HCLK)*/
regmap_read(map, ASPEED_STRAP, &val);
val = (val >> 9) & 0x7;
WARN(val == 0, "strapping is zero: cannot determine ahb clock");
div = 2 * (val + 1);
hw = clk_hw_register_fixed_factor(NULL, "ahb", "hpll", 0, 1, div);
aspeed_clk_data->hws[ASPEED_CLK_AHB] = hw;
/* * This way all clocks fetched before the platform device probes, * except those we assign here for early use, will be deferred.
*/ for (i = 0; i < ASPEED_NUM_CLKS; i++)
aspeed_clk_data->hws[i] = ERR_PTR(-EPROBE_DEFER);
map = syscon_node_to_regmap(np); if (IS_ERR(map)) {
pr_err("no syscon regmap\n"); return;
} /* * We check that the regmap works on this very first access, * but as this is an MMIO-backed regmap, subsequent regmap * access is not going to fail and we skip error checks from * this point.
*/
ret = regmap_read(map, ASPEED_STRAP, &val); if (ret) {
pr_err("failed to read strapping register\n"); return;
}
if (of_device_is_compatible(np, "aspeed,ast2400-scu"))
aspeed_ast2400_cc(map); elseif (of_device_is_compatible(np, "aspeed,ast2500-scu"))
aspeed_ast2500_cc(map); else
pr_err("unknown platform, failed to add clocks\n");
ret = of_clk_add_hw_provider(np, of_clk_hw_onecell_get, aspeed_clk_data); if (ret)
pr_err("failed to add DT provider: %d\n", ret);
};
CLK_OF_DECLARE_DRIVER(aspeed_cc_g5, "aspeed,ast2500-scu", aspeed_cc_init);
CLK_OF_DECLARE_DRIVER(aspeed_cc_g4, "aspeed,ast2400-scu", aspeed_cc_init);
Messung V0.5 in Prozent
¤ Dauer der Verarbeitung: 0.14 Sekunden
(vorverarbeitet am 2026-04-26)
¤
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.