|
@@ -24,7 +24,7 @@
|
|
#define ASPEED_MPLL_PARAM 0x20
|
|
#define ASPEED_MPLL_PARAM 0x20
|
|
#define ASPEED_HPLL_PARAM 0x24
|
|
#define ASPEED_HPLL_PARAM 0x24
|
|
#define AST2500_HPLL_BYPASS_EN BIT(20)
|
|
#define AST2500_HPLL_BYPASS_EN BIT(20)
|
|
-#define AST2400_HPLL_STRAPPED BIT(18)
|
|
|
|
|
|
+#define AST2400_HPLL_PROGRAMMED BIT(18)
|
|
#define AST2400_HPLL_BYPASS_EN BIT(17)
|
|
#define AST2400_HPLL_BYPASS_EN BIT(17)
|
|
#define ASPEED_MISC_CTRL 0x2c
|
|
#define ASPEED_MISC_CTRL 0x2c
|
|
#define UART_DIV13_EN BIT(12)
|
|
#define UART_DIV13_EN BIT(12)
|
|
@@ -91,8 +91,8 @@ static const struct aspeed_gate_data aspeed_gates[] = {
|
|
[ASPEED_CLK_GATE_GCLK] = { 1, 7, "gclk-gate", NULL, 0 }, /* 2D engine */
|
|
[ASPEED_CLK_GATE_GCLK] = { 1, 7, "gclk-gate", NULL, 0 }, /* 2D engine */
|
|
[ASPEED_CLK_GATE_MCLK] = { 2, -1, "mclk-gate", "mpll", CLK_IS_CRITICAL }, /* SDRAM */
|
|
[ASPEED_CLK_GATE_MCLK] = { 2, -1, "mclk-gate", "mpll", CLK_IS_CRITICAL }, /* SDRAM */
|
|
[ASPEED_CLK_GATE_VCLK] = { 3, 6, "vclk-gate", NULL, 0 }, /* Video Capture */
|
|
[ASPEED_CLK_GATE_VCLK] = { 3, 6, "vclk-gate", NULL, 0 }, /* Video Capture */
|
|
- [ASPEED_CLK_GATE_BCLK] = { 4, 8, "bclk-gate", "bclk", 0 }, /* PCIe/PCI */
|
|
|
|
- [ASPEED_CLK_GATE_DCLK] = { 5, -1, "dclk-gate", NULL, 0 }, /* DAC */
|
|
|
|
|
|
+ [ASPEED_CLK_GATE_BCLK] = { 4, 8, "bclk-gate", "bclk", CLK_IS_CRITICAL }, /* PCIe/PCI */
|
|
|
|
+ [ASPEED_CLK_GATE_DCLK] = { 5, -1, "dclk-gate", NULL, CLK_IS_CRITICAL }, /* DAC */
|
|
[ASPEED_CLK_GATE_REFCLK] = { 6, -1, "refclk-gate", "clkin", CLK_IS_CRITICAL },
|
|
[ASPEED_CLK_GATE_REFCLK] = { 6, -1, "refclk-gate", "clkin", CLK_IS_CRITICAL },
|
|
[ASPEED_CLK_GATE_USBPORT2CLK] = { 7, 3, "usb-port2-gate", NULL, 0 }, /* USB2.0 Host port 2 */
|
|
[ASPEED_CLK_GATE_USBPORT2CLK] = { 7, 3, "usb-port2-gate", NULL, 0 }, /* USB2.0 Host port 2 */
|
|
[ASPEED_CLK_GATE_LCLK] = { 8, 5, "lclk-gate", NULL, 0 }, /* LPC */
|
|
[ASPEED_CLK_GATE_LCLK] = { 8, 5, "lclk-gate", NULL, 0 }, /* LPC */
|
|
@@ -212,9 +212,22 @@ static int aspeed_clk_is_enabled(struct clk_hw *hw)
|
|
{
|
|
{
|
|
struct aspeed_clk_gate *gate = to_aspeed_clk_gate(hw);
|
|
struct aspeed_clk_gate *gate = to_aspeed_clk_gate(hw);
|
|
u32 clk = BIT(gate->clock_idx);
|
|
u32 clk = BIT(gate->clock_idx);
|
|
|
|
+ u32 rst = BIT(gate->reset_idx);
|
|
u32 enval = (gate->flags & CLK_GATE_SET_TO_DISABLE) ? 0 : clk;
|
|
u32 enval = (gate->flags & CLK_GATE_SET_TO_DISABLE) ? 0 : clk;
|
|
u32 reg;
|
|
u32 reg;
|
|
|
|
|
|
|
|
+ /*
|
|
|
|
+ * 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;
|
|
|
|
+ }
|
|
|
|
+
|
|
regmap_read(gate->map, ASPEED_CLK_STOP_CTRL, ®);
|
|
regmap_read(gate->map, ASPEED_CLK_STOP_CTRL, ®);
|
|
|
|
|
|
return ((reg & clk) == enval) ? 1 : 0;
|
|
return ((reg & clk) == enval) ? 1 : 0;
|
|
@@ -565,29 +578,45 @@ builtin_platform_driver(aspeed_clk_driver);
|
|
static void __init aspeed_ast2400_cc(struct regmap *map)
|
|
static void __init aspeed_ast2400_cc(struct regmap *map)
|
|
{
|
|
{
|
|
struct clk_hw *hw;
|
|
struct clk_hw *hw;
|
|
- u32 val, freq, div;
|
|
|
|
|
|
+ u32 val, div, clkin, hpll;
|
|
|
|
+ const u16 hpll_rates[][4] = {
|
|
|
|
+ {384, 360, 336, 408},
|
|
|
|
+ {400, 375, 350, 425},
|
|
|
|
+ };
|
|
|
|
+ int rate;
|
|
|
|
|
|
/*
|
|
/*
|
|
* CLKIN is the crystal oscillator, 24, 48 or 25MHz selected by
|
|
* CLKIN is the crystal oscillator, 24, 48 or 25MHz selected by
|
|
* strapping
|
|
* strapping
|
|
*/
|
|
*/
|
|
regmap_read(map, ASPEED_STRAP, &val);
|
|
regmap_read(map, ASPEED_STRAP, &val);
|
|
- if (val & CLKIN_25MHZ_EN)
|
|
|
|
- freq = 25000000;
|
|
|
|
- else if (val & AST2400_CLK_SOURCE_SEL)
|
|
|
|
- freq = 48000000;
|
|
|
|
- else
|
|
|
|
- freq = 24000000;
|
|
|
|
- hw = clk_hw_register_fixed_rate(NULL, "clkin", NULL, 0, freq);
|
|
|
|
- pr_debug("clkin @%u MHz\n", freq / 1000000);
|
|
|
|
|
|
+ rate = (val >> 8) & 3;
|
|
|
|
+ if (val & CLKIN_25MHZ_EN) {
|
|
|
|
+ clkin = 25000000;
|
|
|
|
+ hpll = hpll_rates[1][rate];
|
|
|
|
+ } else if (val & AST2400_CLK_SOURCE_SEL) {
|
|
|
|
+ clkin = 48000000;
|
|
|
|
+ hpll = hpll_rates[0][rate];
|
|
|
|
+ } else {
|
|
|
|
+ clkin = 24000000;
|
|
|
|
+ hpll = hpll_rates[0][rate];
|
|
|
|
+ }
|
|
|
|
+ hw = clk_hw_register_fixed_rate(NULL, "clkin", NULL, 0, clkin);
|
|
|
|
+ pr_debug("clkin @%u MHz\n", clkin / 1000000);
|
|
|
|
|
|
/*
|
|
/*
|
|
* High-speed PLL clock derived from the crystal. This the CPU clock,
|
|
* High-speed PLL clock derived from the crystal. This the CPU clock,
|
|
- * and we assume that it is enabled
|
|
|
|
|
|
+ * 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);
|
|
regmap_read(map, ASPEED_HPLL_PARAM, &val);
|
|
- WARN(val & AST2400_HPLL_STRAPPED, "hpll is strapped not configured");
|
|
|
|
- aspeed_clk_data->hws[ASPEED_CLK_HPLL] = aspeed_ast2400_calc_pll("hpll", 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)
|
|
* Strap bits 11:10 define the CPU/AHB clock frequency ratio (aka HCLK)
|