1 // SPDX-License-Identifier: GPL-2.0
3 * linux/arch/arm/mach-sa1100/clock.c
5 #include <linux/kernel.h>
6 #include <linux/errno.h>
9 #include <linux/clkdev.h>
10 #include <linux/clk-provider.h>
12 #include <linux/spinlock.h>
14 #include <mach/hardware.h>
15 #include <mach/generic.h>
17 static const char * const clk_tucr_parents
[] = {
18 "clk32768", "clk3686400",
21 static DEFINE_SPINLOCK(tucr_lock
);
23 static int clk_gpio27_enable(struct clk_hw
*hw
)
28 * First, set up the 3.6864MHz clock on GPIO 27 for the SA-1111:
29 * (SA-1110 Developer's Manual, section 9.1.2.1)
31 local_irq_save(flags
);
32 GAFR
|= GPIO_32_768kHz
;
33 GPDR
|= GPIO_32_768kHz
;
34 local_irq_restore(flags
);
39 static void clk_gpio27_disable(struct clk_hw
*hw
)
43 local_irq_save(flags
);
44 GPDR
&= ~GPIO_32_768kHz
;
45 GAFR
&= ~GPIO_32_768kHz
;
46 local_irq_restore(flags
);
49 static const struct clk_ops clk_gpio27_ops
= {
50 .enable
= clk_gpio27_enable
,
51 .disable
= clk_gpio27_disable
,
54 static const char * const clk_gpio27_parents
[] = {
58 static const struct clk_init_data clk_gpio27_init_data __initconst
= {
60 .ops
= &clk_gpio27_ops
,
61 .parent_names
= clk_gpio27_parents
,
62 .num_parents
= ARRAY_SIZE(clk_gpio27_parents
),
66 * Derived from the table 8-1 in the SA1110 manual, the MPLL appears to
67 * multiply its input rate by 4 x (4 + PPCR). This calculation gives
68 * the exact rate. The figures given in the table are the rates rounded
69 * to 100kHz. Stick with sa11x0_getspeed() for the time being.
71 static unsigned long clk_mpll_recalc_rate(struct clk_hw
*hw
,
74 return sa11x0_getspeed(0) * 1000;
77 static const struct clk_ops clk_mpll_ops
= {
78 .recalc_rate
= clk_mpll_recalc_rate
,
81 static const char * const clk_mpll_parents
[] = {
85 static const struct clk_init_data clk_mpll_init_data __initconst
= {
88 .parent_names
= clk_mpll_parents
,
89 .num_parents
= ARRAY_SIZE(clk_mpll_parents
),
90 .flags
= CLK_GET_RATE_NOCACHE
| CLK_IS_CRITICAL
,
93 int __init
sa11xx_clk_init(void)
98 hw
= clk_hw_register_fixed_rate(NULL
, "clk32768", NULL
, 0, 32768);
102 clk_hw_register_clkdev(hw
, NULL
, "sa1100-rtc");
104 hw
= clk_hw_register_fixed_rate(NULL
, "clk3686400", NULL
, 0, 3686400);
108 clk_hw_register_clkdev(hw
, "OSTIMER0", NULL
);
110 hw
= kzalloc(sizeof(*hw
), GFP_KERNEL
);
113 hw
->init
= &clk_mpll_init_data
;
114 ret
= clk_hw_register(NULL
, hw
);
120 clk_hw_register_clkdev(hw
, NULL
, "sa11x0-fb");
121 clk_hw_register_clkdev(hw
, NULL
, "sa11x0-pcmcia");
122 clk_hw_register_clkdev(hw
, NULL
, "sa11x0-pcmcia.0");
123 clk_hw_register_clkdev(hw
, NULL
, "sa11x0-pcmcia.1");
124 clk_hw_register_clkdev(hw
, NULL
, "1800");
126 hw
= clk_hw_register_mux(NULL
, "tucr-mux", clk_tucr_parents
,
127 ARRAY_SIZE(clk_tucr_parents
), 0,
128 (void __iomem
*)&TUCR
, FShft(TUCR_TSEL
),
129 FAlnMsk(TUCR_TSEL
), 0, &tucr_lock
);
130 clk_set_rate(hw
->clk
, 3686400);
132 hw
= kzalloc(sizeof(*hw
), GFP_KERNEL
);
135 hw
->init
= &clk_gpio27_init_data
;
136 ret
= clk_hw_register(NULL
, hw
);
142 clk_hw_register_clkdev(hw
, NULL
, "sa1111.0");