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
, 0, OSC
);
92 clk_register_clkdev(clk
, "osc_33m_clk", NULL
);
94 /* clock derived from 33 MHz OSC clk */
95 clk
= clk_register_pll(NULL
, "pll_clk", "osc_33m_clk", 0);
96 clk_register_clkdev(clk
, "pll_clk", NULL
);
98 /* clock derived from PLL clk */
100 * _______________________| |
101 * OSC ___/ | MUX |___ CPU CLK
102 * \___ PLL ___ CPU DIV ___| |
105 clk
= clk_register_divider(NULL
, "cpu_clk_div", "pll_clk",
106 CLK_GET_RATE_NOCACHE
, LS1X_CLK_PLL_DIV
,
107 DIV_CPU_SHIFT
, DIV_CPU_WIDTH
,
108 CLK_DIVIDER_ONE_BASED
|
109 CLK_DIVIDER_ROUND_CLOSEST
, &_lock
);
110 clk_register_clkdev(clk
, "cpu_clk_div", NULL
);
111 clk
= clk_register_mux(NULL
, "cpu_clk", cpu_parents
,
112 ARRAY_SIZE(cpu_parents
),
113 CLK_SET_RATE_NO_REPARENT
, LS1X_CLK_PLL_DIV
,
114 BYPASS_CPU_SHIFT
, BYPASS_CPU_WIDTH
, 0, &_lock
);
115 clk_register_clkdev(clk
, "cpu_clk", NULL
);
118 * _______________________| |
119 * OSC ___/ | MUX |___ DC CLK
120 * \___ PLL ___ DC DIV ___| |
123 clk
= clk_register_divider(NULL
, "dc_clk_div", "pll_clk",
124 0, LS1X_CLK_PLL_DIV
, DIV_DC_SHIFT
,
125 DIV_DC_WIDTH
, CLK_DIVIDER_ONE_BASED
, &_lock
);
126 clk_register_clkdev(clk
, "dc_clk_div", NULL
);
127 clk
= clk_register_mux(NULL
, "dc_clk", dc_parents
,
128 ARRAY_SIZE(dc_parents
),
129 CLK_SET_RATE_NO_REPARENT
, LS1X_CLK_PLL_DIV
,
130 BYPASS_DC_SHIFT
, BYPASS_DC_WIDTH
, 0, &_lock
);
131 clk_register_clkdev(clk
, "dc_clk", NULL
);
134 * _______________________| |
135 * OSC ___/ | MUX |___ DDR CLK
136 * \___ PLL ___ DDR DIV ___| |
139 clk
= clk_register_divider(NULL
, "ahb_clk_div", "pll_clk",
140 0, LS1X_CLK_PLL_DIV
, DIV_DDR_SHIFT
,
141 DIV_DDR_WIDTH
, CLK_DIVIDER_ONE_BASED
,
143 clk_register_clkdev(clk
, "ahb_clk_div", NULL
);
144 clk
= clk_register_mux(NULL
, "ahb_clk", ahb_parents
,
145 ARRAY_SIZE(ahb_parents
),
146 CLK_SET_RATE_NO_REPARENT
, LS1X_CLK_PLL_DIV
,
147 BYPASS_DDR_SHIFT
, BYPASS_DDR_WIDTH
, 0, &_lock
);
148 clk_register_clkdev(clk
, "ahb_clk", NULL
);
149 clk_register_clkdev(clk
, "stmmaceth", NULL
);
151 /* clock derived from AHB clk */
152 /* APB clk is always half of the AHB clk */
153 clk
= clk_register_fixed_factor(NULL
, "apb_clk", "ahb_clk", 0, 1,
155 clk_register_clkdev(clk
, "apb_clk", NULL
);
156 clk_register_clkdev(clk
, "ls1x_i2c", NULL
);
157 clk_register_clkdev(clk
, "ls1x_pwmtimer", NULL
);
158 clk_register_clkdev(clk
, "ls1x_spi", NULL
);
159 clk_register_clkdev(clk
, "ls1x_wdt", NULL
);
160 clk_register_clkdev(clk
, "serial8250", NULL
);