2 * Copyright (c) 2012 Zhang, Keguang <keguang.zhang@gmail.com>
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms of the GNU General Public License as published by the
6 * Free Software Foundation; either version 2 of the License, or (at your
7 * option) any later version.
10 #include <linux/clkdev.h>
11 #include <linux/clk-provider.h>
13 #include <linux/slab.h>
14 #include <linux/err.h>
16 #include <loongson1.h>
18 #define OSC (33 * 1000000)
21 static DEFINE_SPINLOCK(_lock
);
23 static int ls1x_pll_clk_enable(struct clk_hw
*hw
)
28 static void ls1x_pll_clk_disable(struct clk_hw
*hw
)
32 static unsigned long ls1x_pll_recalc_rate(struct clk_hw
*hw
,
33 unsigned long parent_rate
)
37 pll
= __raw_readl(LS1X_CLK_PLL_FREQ
);
38 rate
= 12 + (pll
& 0x3f) + (((pll
>> 8) & 0x3ff) >> 10);
45 static const struct clk_ops ls1x_pll_clk_ops
= {
46 .enable
= ls1x_pll_clk_enable
,
47 .disable
= ls1x_pll_clk_disable
,
48 .recalc_rate
= ls1x_pll_recalc_rate
,
51 static struct clk
*__init
clk_register_pll(struct device
*dev
,
53 const char *parent_name
,
58 struct clk_init_data init
;
60 /* allocate the divider */
61 hw
= kzalloc(sizeof(struct clk_hw
), GFP_KERNEL
);
63 pr_err("%s: could not allocate clk_hw\n", __func__
);
64 return ERR_PTR(-ENOMEM
);
68 init
.ops
= &ls1x_pll_clk_ops
;
69 init
.flags
= flags
| CLK_IS_BASIC
;
70 init
.parent_names
= (parent_name
? &parent_name
: NULL
);
71 init
.num_parents
= (parent_name
? 1 : 0);
74 /* register the clock */
75 clk
= clk_register(dev
, hw
);
83 static const char const *cpu_parents
[] = { "cpu_clk_div", "osc_33m_clk", };
84 static const char const *ahb_parents
[] = { "ahb_clk_div", "osc_33m_clk", };
85 static const char const *dc_parents
[] = { "dc_clk_div", "osc_33m_clk", };
87 void __init
ls1x_clk_init(void)
91 clk
= clk_register_fixed_rate(NULL
, "osc_33m_clk", NULL
, CLK_IS_ROOT
,
93 clk_register_clkdev(clk
, "osc_33m_clk", NULL
);
95 /* clock derived from 33 MHz OSC clk */
96 clk
= clk_register_pll(NULL
, "pll_clk", "osc_33m_clk", 0);
97 clk_register_clkdev(clk
, "pll_clk", NULL
);
99 /* clock derived from PLL clk */
101 * _______________________| |
102 * OSC ___/ | MUX |___ CPU CLK
103 * \___ PLL ___ CPU DIV ___| |
106 clk
= clk_register_divider(NULL
, "cpu_clk_div", "pll_clk",
107 CLK_GET_RATE_NOCACHE
, LS1X_CLK_PLL_DIV
,
108 DIV_CPU_SHIFT
, DIV_CPU_WIDTH
,
109 CLK_DIVIDER_ONE_BASED
|
110 CLK_DIVIDER_ROUND_CLOSEST
, &_lock
);
111 clk_register_clkdev(clk
, "cpu_clk_div", NULL
);
112 clk
= clk_register_mux(NULL
, "cpu_clk", cpu_parents
,
113 ARRAY_SIZE(cpu_parents
),
114 CLK_SET_RATE_NO_REPARENT
, LS1X_CLK_PLL_DIV
,
115 BYPASS_CPU_SHIFT
, BYPASS_CPU_WIDTH
, 0, &_lock
);
116 clk_register_clkdev(clk
, "cpu_clk", NULL
);
119 * _______________________| |
120 * OSC ___/ | MUX |___ DC CLK
121 * \___ PLL ___ DC DIV ___| |
124 clk
= clk_register_divider(NULL
, "dc_clk_div", "pll_clk",
125 0, LS1X_CLK_PLL_DIV
, DIV_DC_SHIFT
,
126 DIV_DC_WIDTH
, CLK_DIVIDER_ONE_BASED
, &_lock
);
127 clk_register_clkdev(clk
, "dc_clk_div", NULL
);
128 clk
= clk_register_mux(NULL
, "dc_clk", dc_parents
,
129 ARRAY_SIZE(dc_parents
),
130 CLK_SET_RATE_NO_REPARENT
, LS1X_CLK_PLL_DIV
,
131 BYPASS_DC_SHIFT
, BYPASS_DC_WIDTH
, 0, &_lock
);
132 clk_register_clkdev(clk
, "dc_clk", NULL
);
135 * _______________________| |
136 * OSC ___/ | MUX |___ DDR CLK
137 * \___ PLL ___ DDR DIV ___| |
140 clk
= clk_register_divider(NULL
, "ahb_clk_div", "pll_clk",
141 0, LS1X_CLK_PLL_DIV
, DIV_DDR_SHIFT
,
142 DIV_DDR_WIDTH
, CLK_DIVIDER_ONE_BASED
,
144 clk_register_clkdev(clk
, "ahb_clk_div", NULL
);
145 clk
= clk_register_mux(NULL
, "ahb_clk", ahb_parents
,
146 ARRAY_SIZE(ahb_parents
),
147 CLK_SET_RATE_NO_REPARENT
, LS1X_CLK_PLL_DIV
,
148 BYPASS_DDR_SHIFT
, BYPASS_DDR_WIDTH
, 0, &_lock
);
149 clk_register_clkdev(clk
, "ahb_clk", NULL
);
150 clk_register_clkdev(clk
, "stmmaceth", NULL
);
152 /* clock derived from AHB clk */
153 /* APB clk is always half of the AHB clk */
154 clk
= clk_register_fixed_factor(NULL
, "apb_clk", "ahb_clk", 0, 1,
156 clk_register_clkdev(clk
, "apb_clk", NULL
);
157 clk_register_clkdev(clk
, "ls1x_i2c", NULL
);
158 clk_register_clkdev(clk
, "ls1x_pwmtimer", NULL
);
159 clk_register_clkdev(clk
, "ls1x_spi", NULL
);
160 clk_register_clkdev(clk
, "ls1x_wdt", NULL
);
161 clk_register_clkdev(clk
, "serial8250", NULL
);