Skip to content

Commit 2a10814

Browse files
clk: add ast2600 support
Most of the commands like writing to the FMC require the clock driver. Signed-off-by: Tan Siewert <tan@siewert.io>
1 parent 8d731fd commit 2a10814

2 files changed

Lines changed: 102 additions & 5 deletions

File tree

src/devicetree/g6.dts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,10 @@
6767
compatible = "aspeed,ast2600-scu", "syscon", "simple-mfd";
6868
reg = <0x1e6e2000 0x1000>;
6969

70+
clock {
71+
compatible = "aspeed,ast2600-clock";
72+
};
73+
7074
strapping {
7175
compatible = "aspeed,ast2600-strapping";
7276
};

src/soc/clk.c

Lines changed: 98 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -28,11 +28,29 @@
2828
#define SCU_SILICON_REVISION 0x7c
2929

3030
#define AST2500_SCU_H_PLL 0x24
31-
#define AST2500_SCU_H_PLL_P_MASK GENMASK(18, 13)
32-
#define AST2500_SCU_H_PLL_P_SHIFT 13
33-
#define AST2500_SCU_H_PLL_M_MASK GENMASK(12, 5)
34-
#define AST2500_SCU_H_PLL_M_SHIFT 5
35-
#define AST2500_SCU_H_PLL_N_MASK GENMASK(4, 0)
31+
#define AST2500_SCU_H_PLL_P_MASK GENMASK(18, 13)
32+
#define AST2500_SCU_H_PLL_P_SHIFT 13
33+
#define AST2500_SCU_H_PLL_M_MASK GENMASK(12, 5)
34+
#define AST2500_SCU_H_PLL_M_SHIFT 5
35+
#define AST2500_SCU_H_PLL_N_MASK GENMASK(4, 0)
36+
37+
/* We only care about SCU004 for now, revision is not required here */
38+
#define AST2600_SCU_SILICON_REVISION 0x04
39+
40+
#define AST2600_SCU_H_PLL 0x200
41+
#define AST2600_SCU_H_PLL_P_MASK GENMASK(22, 19)
42+
#define AST2600_SCU_H_PLL_P_SHIFT 19
43+
#define AST2600_SCU_H_PLL_N_MASK GENMASK(18, 13)
44+
#define AST2600_SCU_H_PLL_N_SHIFT 13
45+
#define AST2600_SCU_H_PLL_M_MASK GENMASK(12, 0)
46+
47+
#define AST2600_SCU_HW_STRAP1 0x500
48+
#define AST2600_SCU_HW_STRAP1_ARM_CLK BIT(0)
49+
#define AST2600_SCU_HW_STRAP1_CPU_AXI_RATIO BIT(16)
50+
#define AST2600_SCU_HW_STRAP1_AHB_FREQ_RATIO_MASK GENMASK(12, 11)
51+
#define AST2600_SCU_HW_STRAP1_AHB_FREQ_RATIO_SHIFT 11
52+
53+
#define AST2600_SCU_HW_STRAP1_CLEAR 0x504
3654

3755
struct clk_ops {
3856
int64_t (*rate_ahb)(struct clk *ctx);
@@ -256,9 +274,84 @@ static const struct clk_ops ast2500_clk_ops = {
256274
.enable = ast2500_clk_enable,
257275
};
258276

277+
static int64_t ast2600_clk_rate_ahb(struct clk *ctx)
278+
{
279+
uint32_t h_pll_reg, h_pll, h_pll_m, h_pll_n, h_pll_p;
280+
uint32_t strap, ahb_ratio, cpu_axi_ratio, hclk;
281+
int rc;
282+
283+
if ((rc = scu_readl(ctx->scu, AST2600_SCU_HW_STRAP1, &strap)) < 0)
284+
return rc;
285+
286+
/* The H-PLL register allows us to calculate the CPU freq */
287+
if ((rc = scu_readl(ctx->scu, AST2600_SCU_H_PLL, &h_pll_reg)) < 0)
288+
return rc;
289+
290+
h_pll_p = ((h_pll_reg & AST2600_SCU_H_PLL_P_MASK) >> AST2600_SCU_H_PLL_P_SHIFT) + 1;
291+
h_pll_n = ((h_pll_reg & AST2600_SCU_H_PLL_N_MASK) >> AST2600_SCU_H_PLL_N_SHIFT) + 1;
292+
h_pll_m = (h_pll_reg & AST2600_SCU_H_PLL_M_MASK) + 1;
293+
294+
/* H-PLL = CLKIN (always 25 MHz) * (M+1/N+1) / P+1 */
295+
h_pll = 25 * (h_pll_m / h_pll_n) / h_pll_p;
296+
logt("clk: ast2600: calculated h-pll is %d MHz\n", h_pll);
297+
298+
cpu_axi_ratio = (strap & AST2600_SCU_HW_STRAP1_CPU_AXI_RATIO);
299+
300+
/* AXI/AHB clock frequency ratio selection */
301+
ahb_ratio = (strap & AST2600_SCU_HW_STRAP1_AHB_FREQ_RATIO_MASK) >> AST2600_SCU_HW_STRAP1_AHB_FREQ_RATIO_SHIFT;
302+
if (!ahb_ratio)
303+
return -EINVAL;
304+
305+
/*
306+
* If cpu_axi_ratio is set, then the ratios are default, 4, 6, 8.
307+
* Otherwise, the ratios are default, 2, 3, 4.
308+
* The default is "that makes HCLK = 200MHz", but there's no explanation
309+
* how HCLK is being calculated so I'll just return 200 MHz as AHB Rate if no
310+
* ratio is set lol
311+
*/
312+
if (!ahb_ratio)
313+
return 200;
314+
315+
/* Ratio calc from the binary value */
316+
ahb_ratio++;
317+
if (cpu_axi_ratio)
318+
ahb_ratio *= 2;
319+
320+
logt("clk: ast2600: ahb ratio: %d:1\n", ahb_ratio);
321+
322+
/* I'm just gonna assume that HCLK = H-PLL / 2 / ahb_ratio */
323+
hclk = h_pll / 2 / ahb_ratio;
324+
logt("clk: ast2600: ahb freq: %d MHz\n", hclk);
325+
326+
return hclk;
327+
}
328+
329+
int ast2600_clk_disable(struct clk *ctx, enum clksrc src)
330+
{
331+
if (src != clk_arm)
332+
return -ENOTSUP;
333+
334+
return scu_writel(ctx->scu, AST2600_SCU_HW_STRAP1, AST2600_SCU_HW_STRAP1_ARM_CLK);
335+
}
336+
337+
int ast2600_clk_enable(struct clk *ctx, enum clksrc src)
338+
{
339+
if (src != clk_arm)
340+
return -ENOTSUP;
341+
342+
return scu_writel(ctx->scu, AST2600_SCU_HW_STRAP1_CLEAR, AST2600_SCU_HW_STRAP1_ARM_CLK);
343+
}
344+
345+
static const struct clk_ops ast2600_clk_ops = {
346+
.rate_ahb = ast2600_clk_rate_ahb,
347+
.disable = ast2600_clk_disable,
348+
.enable = ast2600_clk_enable,
349+
};
350+
259351
static const struct soc_device_id clk_match[] = {
260352
{ .compatible = "aspeed,ast2400-clock", .data = &ast2400_clk_ops },
261353
{ .compatible = "aspeed,ast2500-clock", .data = &ast2500_clk_ops },
354+
{ .compatible = "aspeed,ast2600-clock", .data = &ast2600_clk_ops },
262355
{ },
263356
};
264357

0 commit comments

Comments
 (0)