Date:2013-04-28 21:38:56 (10 years 10 months ago)
Author:Lars C.
Commit:940358c464328ae06fa10d59fe81300503a868f9
Message:MIPS: jz4740: Use common clock framework

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
Files: arch/mips/Kconfig (1 diff)
arch/mips/jz4740/Makefile (1 diff)
arch/mips/jz4740/clock-debugfs.c (1 diff)
arch/mips/jz4740/clock.c (12 diffs)
arch/mips/jz4740/clock.h (1 diff)

Change Details

arch/mips/Kconfig
248248    select HAVE_CLK
249249    select GENERIC_IRQ_CHIP
250250    select CPU_SUPPORTS_CPUFREQ
251    select COMMON_CLK
251252
252253config LANTIQ
253254    bool "Lantiq based platforms"
arch/mips/jz4740/Makefile
77obj-y += prom.o irq.o time.o reset.o setup.o \
88    gpio.o clock.o platform.o timer.o serial.o
99
10obj-$(CONFIG_DEBUG_FS) += clock-debugfs.o
11
1210# board specific support
1311
1412obj-$(CONFIG_JZ4740_QI_LB60) += board-qi_lb60.o
arch/mips/jz4740/clock-debugfs.c
1/*
2 * Copyright (C) 2010, Lars-Peter Clausen <lars@metafoo.de>
3 * JZ4740 SoC clock support debugfs entries
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License as published by the
7 * Free Software Foundation; either version 2 of the License, or (at your
8 * option) any later version.
9 *
10 * You should have received a copy of the GNU General Public License along
11 * with this program; if not, write to the Free Software Foundation, Inc.,
12 * 675 Mass Ave, Cambridge, MA 02139, USA.
13 *
14 */
15
16#include <linux/kernel.h>
17#include <linux/module.h>
18#include <linux/clk.h>
19#include <linux/err.h>
20
21#include <linux/debugfs.h>
22#include <linux/uaccess.h>
23
24#include <asm/mach-jz4740/clock.h>
25#include "clock.h"
26
27static struct dentry *jz4740_clock_debugfs;
28
29static int jz4740_clock_debugfs_show_enabled(void *data, uint64_t *value)
30{
31    struct clk *clk = data;
32    *value = clk_is_enabled(clk);
33
34    return 0;
35}
36
37static int jz4740_clock_debugfs_set_enabled(void *data, uint64_t value)
38{
39    struct clk *clk = data;
40
41    if (value)
42        return clk_enable(clk);
43    else
44        clk_disable(clk);
45
46    return 0;
47}
48
49DEFINE_SIMPLE_ATTRIBUTE(jz4740_clock_debugfs_ops_enabled,
50    jz4740_clock_debugfs_show_enabled,
51    jz4740_clock_debugfs_set_enabled,
52    "%llu\n");
53
54static int jz4740_clock_debugfs_show_rate(void *data, uint64_t *value)
55{
56    struct clk *clk = data;
57    *value = clk_get_rate(clk);
58
59    return 0;
60}
61
62DEFINE_SIMPLE_ATTRIBUTE(jz4740_clock_debugfs_ops_rate,
63    jz4740_clock_debugfs_show_rate,
64    NULL,
65    "%llu\n");
66
67void jz4740_clock_debugfs_add_clk(struct clk *clk)
68{
69    if (!jz4740_clock_debugfs)
70        return;
71
72    clk->debugfs_entry = debugfs_create_dir(clk->name, jz4740_clock_debugfs);
73    debugfs_create_file("rate", S_IWUGO | S_IRUGO, clk->debugfs_entry, clk,
74                &jz4740_clock_debugfs_ops_rate);
75    debugfs_create_file("enabled", S_IRUGO, clk->debugfs_entry, clk,
76                &jz4740_clock_debugfs_ops_enabled);
77
78    if (clk->parent) {
79        char parent_path[100];
80        snprintf(parent_path, 100, "../%s", clk->parent->name);
81        clk->debugfs_parent_entry = debugfs_create_symlink("parent",
82                        clk->debugfs_entry,
83                        parent_path);
84    }
85}
86
87/* TODO: Locking */
88void jz4740_clock_debugfs_update_parent(struct clk *clk)
89{
90    debugfs_remove(clk->debugfs_parent_entry);
91
92    if (clk->parent) {
93        char parent_path[100];
94        snprintf(parent_path, 100, "../%s", clk->parent->name);
95        clk->debugfs_parent_entry = debugfs_create_symlink("parent",
96                        clk->debugfs_entry,
97                        parent_path);
98    } else {
99        clk->debugfs_parent_entry = NULL;
100    }
101}
102
103void jz4740_clock_debugfs_init(void)
104{
105    jz4740_clock_debugfs = debugfs_create_dir("jz4740-clock", NULL);
106    if (IS_ERR(jz4740_clock_debugfs))
107        jz4740_clock_debugfs = NULL;
108}
arch/mips/jz4740/clock.c
2424#include <linux/module.h>
2525#include <linux/list.h>
2626#include <linux/err.h>
27#include <linux/clk-provider.h>
28#include <linux/clkdev.h>
2729
2830#include <asm/mach-jz4740/clock.h>
2931#include <asm/mach-jz4740/base.h>
...... 
4143#define JZ_REG_CLOCK_UHC 0x6C
4244#define JZ_REG_CLOCK_SPI 0x74
4345
44#define JZ_CLOCK_CTRL_I2S_SRC_PLL BIT(31)
45#define JZ_CLOCK_CTRL_KO_ENABLE BIT(30)
46#define JZ_CLOCK_CTRL_KO_ENABLE 30
4647#define JZ_CLOCK_CTRL_UDC_SRC_PLL BIT(29)
4748#define JZ_CLOCK_CTRL_CHANGE_ENABLE BIT(22)
4849#define JZ_CLOCK_CTRL_PLL_HALF BIT(21)
...... 
5354#define JZ_CLOCK_CTRL_HDIV_OFFSET 4
5455#define JZ_CLOCK_CTRL_CDIV_OFFSET 0
5556#define JZ_CLOCK_CTRL_UDIV_MASK (0x3f << JZ_CLOCK_CTRL_UDIV_OFFSET)
56#define JZ_CLOCK_CTRL_LDIV_MASK (0x1f << JZ_CLOCK_CTRL_LDIV_OFFSET)
5757#define JZ_CLOCK_CTRL_MDIV_MASK (0x0f << JZ_CLOCK_CTRL_MDIV_OFFSET)
5858#define JZ_CLOCK_CTRL_PDIV_MASK (0x0f << JZ_CLOCK_CTRL_PDIV_OFFSET)
5959#define JZ_CLOCK_CTRL_HDIV_MASK (0x0f << JZ_CLOCK_CTRL_HDIV_OFFSET)
6060#define JZ_CLOCK_CTRL_CDIV_MASK (0x0f << JZ_CLOCK_CTRL_CDIV_OFFSET)
6161
62#define JZ_CLOCK_GATE_UART0 BIT(0)
63#define JZ_CLOCK_GATE_TCU BIT(1)
64#define JZ_CLOCK_GATE_RTC BIT(2)
65#define JZ_CLOCK_GATE_I2C BIT(3)
66#define JZ_CLOCK_GATE_SPI BIT(4)
67#define JZ_CLOCK_GATE_AIC BIT(5)
68#define JZ_CLOCK_GATE_I2S BIT(6)
69#define JZ_CLOCK_GATE_MMC BIT(7)
70#define JZ_CLOCK_GATE_ADC BIT(8)
71#define JZ_CLOCK_GATE_CIM BIT(9)
72#define JZ_CLOCK_GATE_LCD BIT(10)
73#define JZ_CLOCK_GATE_UDC BIT(11)
74#define JZ_CLOCK_GATE_DMAC BIT(12)
75#define JZ_CLOCK_GATE_IPU BIT(13)
76#define JZ_CLOCK_GATE_UHC BIT(14)
77#define JZ_CLOCK_GATE_UART1 BIT(15)
78
79#define JZ_CLOCK_I2S_DIV_MASK 0x01ff
80
81#define JZ_CLOCK_LCD_DIV_MASK 0x01ff
82
83#define JZ_CLOCK_MMC_DIV_MASK 0x001f
84
85#define JZ_CLOCK_UHC_DIV_MASK 0x000f
86
87#define JZ_CLOCK_SPI_SRC_PLL BIT(31)
88#define JZ_CLOCK_SPI_DIV_MASK 0x000f
62#define JZ_CLOCK_GATE_UART0 0
63#define JZ_CLOCK_GATE_TCU 1
64#define JZ_CLOCK_GATE_RTC 2
65#define JZ_CLOCK_GATE_I2C 3
66#define JZ_CLOCK_GATE_SPI 4
67#define JZ_CLOCK_GATE_AIC 5
68#define JZ_CLOCK_GATE_I2S 6
69#define JZ_CLOCK_GATE_MMC 7
70#define JZ_CLOCK_GATE_ADC 8
71#define JZ_CLOCK_GATE_CIM 9
72#define JZ_CLOCK_GATE_LCD 10
73#define JZ_CLOCK_GATE_UDC 11
74#define JZ_CLOCK_GATE_DMAC 12
75#define JZ_CLOCK_GATE_IPU 13
76#define JZ_CLOCK_GATE_UHC 14
77#define JZ_CLOCK_GATE_UART1 15
78
79#define JZ_CLOCK_SPI_SRC_PLL 31
8980
9081#define JZ_CLOCK_PLL_M_MASK 0x01ff
9182#define JZ_CLOCK_PLL_N_MASK 0x001f
...... 
10394#define JZ_CLOCK_LOW_POWER_MODE_SLEEP BIT(0)
10495
10596#define JZ_CLOCK_SLEEP_CTRL_SUSPEND_UHC BIT(7)
106#define JZ_CLOCK_SLEEP_CTRL_ENABLE_UDC BIT(6)
97#define JZ_CLOCK_SLEEP_CTRL_ENABLE_UDC 6
10798
10899#define JZ_REG_EMC_RTCNT 0x88
109100#define JZ_REG_EMC_RTCOR 0x8C
110101
111static void __iomem *jz_clock_base;
112static spinlock_t jz_clock_lock;
113static LIST_HEAD(jz_clocks);
102static void __iomem *jz4740_clk_base;
103static spinlock_t jz4740_clk_lock;
114104
115105static void __iomem *jz_emc_base;
116106
117struct main_clk {
118    struct clk clk;
119    uint32_t div_offset;
120};
121
122struct divided_clk {
123    struct clk clk;
124    uint32_t reg;
125    uint32_t mask;
126};
127
128struct static_clk {
129    struct clk clk;
130    unsigned long rate;
131};
132
133107static uint32_t jz_clk_reg_read(int reg)
134108{
135    return readl(jz_clock_base + reg);
109    return readl(jz4740_clk_base + reg);
136110}
137
111/*
138112static void jz_clk_reg_write_mask(int reg, uint32_t val, uint32_t mask)
139113{
140114    uint32_t val2;
141115
142    spin_lock(&jz_clock_lock);
143    val2 = readl(jz_clock_base + reg);
116    spin_lock(&jz4740_clk_lock);
117    val2 = readl(jz4740_clk_base + reg);
144118    val2 &= ~mask;
145119    val2 |= val;
146    writel(val2, jz_clock_base + reg);
147    spin_unlock(&jz_clock_lock);
120    writel(val2, jz4740_clk_base + reg);
121    spin_unlock(&jz4740_clk_lock);
148122}
149
123*/
150124static void jz_clk_reg_set_bits(int reg, uint32_t mask)
151125{
152126    uint32_t val;
153127
154    spin_lock(&jz_clock_lock);
155    val = readl(jz_clock_base + reg);
128    spin_lock(&jz4740_clk_lock);
129    val = readl(jz4740_clk_base + reg);
156130    val |= mask;
157    writel(val, jz_clock_base + reg);
158    spin_unlock(&jz_clock_lock);
131    writel(val, jz4740_clk_base + reg);
132    spin_unlock(&jz4740_clk_lock);
159133}
160134
161135static void jz_clk_reg_clear_bits(int reg, uint32_t mask)
162136{
163137    uint32_t val;
164138
165    spin_lock(&jz_clock_lock);
166    val = readl(jz_clock_base + reg);
139    spin_lock(&jz4740_clk_lock);
140    val = readl(jz4740_clk_base + reg);
167141    val &= ~mask;
168    writel(val, jz_clock_base + reg);
169    spin_unlock(&jz_clock_lock);
142    writel(val, jz4740_clk_base + reg);
143    spin_unlock(&jz4740_clk_lock);
170144}
171145
172static int jz_clk_enable_gating(struct clk *clk)
146static unsigned long jz_clk_pll_calc_rate(unsigned long parent_rate,
147    unsigned int in_div, unsigned int feedback, unsigned int out_div)
173148{
174    if (clk->gate_bit == JZ4740_CLK_NOT_GATED)
175        return -EINVAL;
176
177    jz_clk_reg_clear_bits(JZ_REG_CLOCK_GATE, clk->gate_bit);
178    return 0;
149    return ((parent_rate / in_div) * feedback) / out_div;
179150}
180151
181static int jz_clk_disable_gating(struct clk *clk)
182{
183    if (clk->gate_bit == JZ4740_CLK_NOT_GATED)
184        return -EINVAL;
185
186    jz_clk_reg_set_bits(JZ_REG_CLOCK_GATE, clk->gate_bit);
187    return 0;
188}
152static const int pllno[] = {1, 2, 2, 4};
189153
190static int jz_clk_is_enabled_gating(struct clk *clk)
154static unsigned long jz4740_clk_pll_recalc_rate(struct clk_hw *hwclk,
155    unsigned long parent_rate)
191156{
192    if (clk->gate_bit == JZ4740_CLK_NOT_GATED)
193        return 1;
157    uint32_t val;
158    unsigned int in_div, feedback, out_div;
194159
195    return !(jz_clk_reg_read(JZ_REG_CLOCK_GATE) & clk->gate_bit);
196}
160    val = jz_clk_reg_read(JZ_REG_CLOCK_PLL);
197161
198static unsigned long jz_clk_static_get_rate(struct clk *clk)
199{
200    return ((struct static_clk *)clk)->rate;
201}
162    if (val & JZ_CLOCK_PLL_BYPASS)
163        return parent_rate;
202164
203static int jz_clk_ko_enable(struct clk *clk)
204{
205    jz_clk_reg_set_bits(JZ_REG_CLOCK_CTRL, JZ_CLOCK_CTRL_KO_ENABLE);
206    return 0;
207}
165    feedback = ((val >> 23) & 0x1ff) + 2;
166    in_div = ((val >> 18) & 0x1f) + 2;
167    out_div = pllno[(val >> 16) & 0x3];
208168
209static int jz_clk_ko_disable(struct clk *clk)
210{
211    jz_clk_reg_clear_bits(JZ_REG_CLOCK_CTRL, JZ_CLOCK_CTRL_KO_ENABLE);
212    return 0;
213}
169    printk("recalc pll: %lu\n", jz_clk_pll_calc_rate(parent_rate, in_div,
170    feedback, out_div));
214171
215static int jz_clk_ko_is_enabled(struct clk *clk)
216{
217    return !!(jz_clk_reg_read(JZ_REG_CLOCK_CTRL) & JZ_CLOCK_CTRL_KO_ENABLE);
172    return jz_clk_pll_calc_rate(parent_rate, in_div, feedback, out_div);
218173}
219174
220static struct static_clk jz_clk_ext;
175static const struct clk_ops jz4740_clk_pll_ops = {
176    .recalc_rate = jz4740_clk_pll_recalc_rate,
177};
221178
222static unsigned long jz_clk_pll_calc_rate(
223    unsigned int in_div, unsigned int feedback, unsigned int out_div)
224{
225    return ((jz_clk_ext.rate / in_div) * feedback) / out_div;
226}
179#if 0
227180
228181static void jz_clk_pll_calc_dividers(unsigned long rate,
229182    unsigned int *in_div, unsigned int *feedback, unsigned int *out_div)
...... 
282235    return jz_clk_pll_calc_rate(in_div, feedback, out_div);
283236}
284237
285static const int pllno[] = {1, 2, 2, 4};
286
287static unsigned long jz_clk_pll_get_rate(struct clk *clk)
288{
289    uint32_t val;
290    unsigned int in_div, feedback, out_div;
291
292    val = jz_clk_reg_read(JZ_REG_CLOCK_PLL);
293
294    if (val & JZ_CLOCK_PLL_BYPASS)
295        return clk_get_rate(clk->parent);
296
297    feedback = ((val >> 23) & 0x1ff) + 2;
298    in_div = ((val >> 18) & 0x1f) + 2;
299    out_div = pllno[(val >> 16) & 0x3];
300
301    return jz_clk_pll_calc_rate(in_div, feedback, out_div);
302}
303
304static unsigned long jz_clk_pll_half_get_rate(struct clk *clk)
305{
306    uint32_t reg;
307
308    reg = jz_clk_reg_read(JZ_REG_CLOCK_CTRL);
309    if (reg & JZ_CLOCK_CTRL_PLL_HALF)
310        return jz_clk_pll_get_rate(clk->parent);
311    return jz_clk_pll_get_rate(clk->parent) >> 1;
312}
313238
314239#define SDRAM_TREF 15625 /* Refresh period: 4096 refresh cycles/64ms */
315240
...... 
337262    pllout2 = (ctrl & JZ_CLOCK_CTRL_PLL_HALF) ? pllout : (pllout / 2);
338263
339264    /* Init UHC clock */
340    writel(pllout2 / 48000000 - 1, jz_clock_base + JZ_REG_CLOCK_UHC);
265    writel(pllout2 / 48000000 - 1, jz4740_clk_base + JZ_REG_CLOCK_UHC);
341266
342267    plcr1 = ((feedback - 2) << JZ_CLOCK_PLL_M_OFFSET) |
343268        ((in_div - 2) << JZ_CLOCK_PLL_N_OFFSET) |
...... 
348273    sdram_set_pll(pllout);
349274
350275    /* LCD pixclock */
351    writel(pllout2 / 12000000 - 1, jz_clock_base + JZ_REG_CLOCK_LCD);
276    writel(pllout2 / 12000000 - 1, jz4740_clk_base + JZ_REG_CLOCK_LCD);
352277
353278    /* configure PLL */
354279    __asm__ __volatile__(
...... 
364289        "nop\n\t"
365290        ".set reorder\n\t"
366291        :
367        : "r" (jz_clock_base + JZ_REG_CLOCK_PLL), "r" (plcr1));
292        : "r" (jz4740_clk_base + JZ_REG_CLOCK_PLL), "r" (plcr1));
368293
369294    /* MtH: For some reason the MSC will have problems if this flag is not
370295            restored, even though the MSC is supposedly the only divider
...... 
374299    return 0;
375300}
376301
377static const unsigned int jz_clk_main_divs[] = {
378    1, 2, 3, 4, 6, 8, 12, 16, 24, 32
379};
380302static const unsigned int jz_clk_main_divs_inv[] = {
381303    -1, 0, 1, 2, 3, -1, 4, -1, 5, -1, -1, -1, 6, -1, -1, -1,
382304     7, -1, -1, -1, -1, -1, -1, -1, 8, -1, -1, -1, -1, -1, -1, -1,
383305     9
384306};
385307
386static unsigned long jz_clk_main_round_rate(struct clk *clk, unsigned long rate)
387{
388    unsigned long parent_rate = jz_clk_pll_get_rate(clk->parent);
389    int div;
390
391    div = parent_rate / rate;
392    if (div > 32)
393        return parent_rate / 32;
394    else if (div < 1)
395        return parent_rate;
396
397    div &= (0x3 << (ffs(div) - 1));
398
399    return parent_rate / div;
400}
401
402static unsigned long jz_clk_main_get_rate(struct clk *clk)
403{
404    struct main_clk *mclk = (struct main_clk *)clk;
405    uint32_t div;
406
407    div = jz_clk_reg_read(JZ_REG_CLOCK_CTRL);
408
409    div >>= mclk->div_offset;
410    div &= 0xf;
411
412    if (div >= ARRAY_SIZE(jz_clk_main_divs))
413        div = ARRAY_SIZE(jz_clk_main_divs) - 1;
414
415    return jz_clk_pll_get_rate(clk->parent) / jz_clk_main_divs[div];
416}
417
418static int jz_clk_main_set_rate(struct clk *clk, unsigned long rate)
419{
420    struct main_clk *mclk = (struct main_clk *)clk;
421    int i;
422    int div;
423    unsigned long parent_rate = jz_clk_pll_get_rate(clk->parent);
424
425    rate = jz_clk_main_round_rate(clk, rate);
426
427    div = parent_rate / rate;
428
429    i = (ffs(div) - 1) << 1;
430    if (i > 0 && !(div & BIT(i-1)))
431        i -= 1;
432
433    jz_clk_reg_write_mask(JZ_REG_CLOCK_CTRL, i << mclk->div_offset,
434                0xf << mclk->div_offset);
435
436    return 0;
437}
438
439308static struct main_clk jz_clk_cpu;
440309
441310int clk_main_set_dividers(bool immediate, unsigned int cdiv, unsigned int hdiv,
...... 
487356        "nop\n\t"
488357        ".set reorder\n\t"
489358        : "=r" (tmp)
490        : "r" (jz_clock_base + JZ_REG_CLOCK_CTRL), "r" (ctrl),
359        : "r" (jz4740_clk_base + JZ_REG_CLOCK_CTRL), "r" (ctrl),
491360          "r" (wait));
492361
493362    return 0;
494363}
495364EXPORT_SYMBOL_GPL(clk_main_set_dividers);
496365
497static struct clk_ops jz_clk_static_ops = {
498    .get_rate = jz_clk_static_get_rate,
499    .enable = jz_clk_enable_gating,
500    .disable = jz_clk_disable_gating,
501    .is_enabled = jz_clk_is_enabled_gating,
366#endif
367
368static const struct clk_div_table jz4740_clk_main_divs[] = {
369    { 0, 1 },
370    { 1, 2 },
371    { 2, 3 },
372    { 3, 4 },
373    { 4, 6 },
374    { 5, 7 },
375    { 6, 12 },
376    { 7, 16 },
377    { 8, 24 },
378    { 9, 32 },
379    { },
502380};
503381
504static struct static_clk jz_clk_ext = {
505    .clk = {
506        .name = "ext",
507        .gate_bit = JZ4740_CLK_NOT_GATED,
508        .ops = &jz_clk_static_ops,
509    },
510};
511
512static struct clk_ops jz_clk_pll_ops = {
513    .get_rate = jz_clk_pll_get_rate,
514    .set_rate = jz_clk_pll_set_rate,
515    .round_rate = jz_clk_pll_round_rate,
516};
517
518static struct clk jz_clk_pll = {
519    .name = "pll",
520    .parent = &jz_clk_ext.clk,
521    .ops = &jz_clk_pll_ops,
522};
523
524static struct clk_ops jz_clk_pll_half_ops = {
525    .get_rate = jz_clk_pll_half_get_rate,
526};
527
528static struct clk jz_clk_pll_half = {
529    .name = "pll half",
530    .parent = &jz_clk_pll,
531    .ops = &jz_clk_pll_half_ops,
532};
533
534static const struct clk_ops jz_clk_main_ops = {
535    .get_rate = jz_clk_main_get_rate,
536    .set_rate = jz_clk_main_set_rate,
537    .round_rate = jz_clk_main_round_rate,
538};
539
540static struct main_clk jz_clk_cpu = {
541    .clk = {
542        .name = "cclk",
543        .parent = &jz_clk_pll,
544        .ops = &jz_clk_main_ops,
545    },
546    .div_offset = JZ_CLOCK_CTRL_CDIV_OFFSET,
547};
548
549static struct main_clk jz_clk_memory = {
550    .clk = {
551        .name = "mclk",
552        .parent = &jz_clk_pll,
553        .ops = &jz_clk_main_ops,
554    },
555    .div_offset = JZ_CLOCK_CTRL_MDIV_OFFSET,
556};
557
558static struct main_clk jz_clk_high_speed_peripheral = {
559    .clk = {
560        .name = "hclk",
561        .parent = &jz_clk_pll,
562        .ops = &jz_clk_main_ops,
563    },
564    .div_offset = JZ_CLOCK_CTRL_HDIV_OFFSET,
565};
566
567
568static struct main_clk jz_clk_low_speed_peripheral = {
569    .clk = {
570        .name = "pclk",
571        .parent = &jz_clk_pll,
572        .ops = &jz_clk_main_ops,
573    },
574    .div_offset = JZ_CLOCK_CTRL_PDIV_OFFSET,
575};
576
577static const struct clk_ops jz_clk_ko_ops = {
578    .enable = jz_clk_ko_enable,
579    .disable = jz_clk_ko_disable,
580    .is_enabled = jz_clk_ko_is_enabled,
581};
582
583static struct clk jz_clk_ko = {
584    .name = "cko",
585    .parent = &jz_clk_memory.clk,
586    .ops = &jz_clk_ko_ops,
587};
588
589static int jz_clk_spi_set_parent(struct clk *clk, struct clk *parent)
590{
591    if (parent == &jz_clk_pll)
592        jz_clk_reg_set_bits(JZ_CLOCK_SPI_SRC_PLL, JZ_REG_CLOCK_SPI);
593    else if (parent == &jz_clk_ext.clk)
594        jz_clk_reg_clear_bits(JZ_CLOCK_SPI_SRC_PLL, JZ_REG_CLOCK_SPI);
595    else
596        return -EINVAL;
597
598    clk->parent = parent;
599
600    return 0;
601}
602
603static int jz_clk_i2s_set_parent(struct clk *clk, struct clk *parent)
604{
605    if (parent == &jz_clk_pll_half)
606        jz_clk_reg_set_bits(JZ_REG_CLOCK_CTRL, JZ_CLOCK_CTRL_I2S_SRC_PLL);
607    else if (parent == &jz_clk_ext.clk)
608        jz_clk_reg_clear_bits(JZ_REG_CLOCK_CTRL, JZ_CLOCK_CTRL_I2S_SRC_PLL);
609    else
610        return -EINVAL;
611
612    clk->parent = parent;
613
614    return 0;
615}
616
617static int jz_clk_udc_enable(struct clk *clk)
618{
619    jz_clk_reg_set_bits(JZ_REG_CLOCK_SLEEP_CTRL,
620            JZ_CLOCK_SLEEP_CTRL_ENABLE_UDC);
621
622    return 0;
623}
624
625static int jz_clk_udc_disable(struct clk *clk)
626{
627    jz_clk_reg_clear_bits(JZ_REG_CLOCK_SLEEP_CTRL,
628            JZ_CLOCK_SLEEP_CTRL_ENABLE_UDC);
629
630    return 0;
631}
632
633static int jz_clk_udc_is_enabled(struct clk *clk)
634{
635    return !!(jz_clk_reg_read(JZ_REG_CLOCK_SLEEP_CTRL) &
636            JZ_CLOCK_SLEEP_CTRL_ENABLE_UDC);
637}
638
639static int jz_clk_udc_set_parent(struct clk *clk, struct clk *parent)
640{
641    if (parent == &jz_clk_pll_half)
642        jz_clk_reg_set_bits(JZ_REG_CLOCK_CTRL, JZ_CLOCK_CTRL_UDC_SRC_PLL);
643    else if (parent == &jz_clk_ext.clk)
644        jz_clk_reg_clear_bits(JZ_REG_CLOCK_CTRL, JZ_CLOCK_CTRL_UDC_SRC_PLL);
645    else
646        return -EINVAL;
647
648    clk->parent = parent;
649
650    return 0;
651}
652
653static int jz_clk_udc_set_rate(struct clk *clk, unsigned long rate)
654{
655    int div;
656
657    if (clk->parent == &jz_clk_ext.clk)
658        return -EINVAL;
659
660    div = clk_get_rate(clk->parent) / rate - 1;
661
662    if (div < 0)
663        div = 0;
664    else if (div > 63)
665        div = 63;
666
667    jz_clk_reg_write_mask(JZ_REG_CLOCK_CTRL, div << JZ_CLOCK_CTRL_UDIV_OFFSET,
668                JZ_CLOCK_CTRL_UDIV_MASK);
669    return 0;
670}
671
672static unsigned long jz_clk_udc_get_rate(struct clk *clk)
673{
674    int div;
675
676    if (clk->parent == &jz_clk_ext.clk)
677        return clk_get_rate(clk->parent);
678
679    div = (jz_clk_reg_read(JZ_REG_CLOCK_CTRL) & JZ_CLOCK_CTRL_UDIV_MASK);
680    div >>= JZ_CLOCK_CTRL_UDIV_OFFSET;
681    div += 1;
682
683    return clk_get_rate(clk->parent) / div;
684}
685
686static unsigned long jz_clk_divided_get_rate(struct clk *clk)
687{
688    struct divided_clk *dclk = (struct divided_clk *)clk;
689    int div;
690
691    if (clk->parent == &jz_clk_ext.clk)
692        return clk_get_rate(clk->parent);
693
694    div = (jz_clk_reg_read(dclk->reg) & dclk->mask) + 1;
695
696    return clk_get_rate(clk->parent) / div;
697}
698
699static int jz_clk_divided_set_rate(struct clk *clk, unsigned long rate)
700{
701    struct divided_clk *dclk = (struct divided_clk *)clk;
702    int div;
703
704    if (clk->parent == &jz_clk_ext.clk)
705        return -EINVAL;
706
707    div = clk_get_rate(clk->parent) / rate - 1;
708
709    if (div < 0)
710        div = 0;
711    else if (div > dclk->mask)
712        div = dclk->mask;
713
714    jz_clk_reg_write_mask(dclk->reg, div, dclk->mask);
715
716    return 0;
717}
718
719static unsigned long jz_clk_ldclk_round_rate(struct clk *clk, unsigned long rate)
382static struct clk *jz4740_register_main_clock(const char *name,
383    unsigned int div_shift)
720384{
721    int div;
722    unsigned long parent_rate = jz_clk_pll_half_get_rate(clk->parent);
723
724    if (rate > 150000000)
725        return 150000000;
726
727    div = parent_rate / rate;
728    if (div < 1)
729        div = 1;
730    else if (div > 32)
731        div = 32;
732
733    return parent_rate / div;
385    return clk_register_divider_table(NULL, name, "PLL", 0,
386        jz4740_clk_base + JZ_REG_CLOCK_CTRL, div_shift, 4, 0,
387        jz4740_clk_main_divs, &jz4740_clk_lock);
734388}
735389
736static int jz_clk_ldclk_set_rate(struct clk *clk, unsigned long rate)
390static struct clk *jz4740_register_peripheral_clock(const char *name,
391    const char *bypass_name, unsigned int mux_reg, unsigned int mux_shift,
392    unsigned int div_reg, unsigned int div_shift, unsigned int div_width,
393    unsigned int gate_reg, unsigned int gate_bit)
737394{
738    int div;
739
740    if (rate > 150000000)
741        return -EINVAL;
395    char gate_name[20], mux_name[20], div_name[20];
396    const char *mux_parents[2];
397    char *gate_parent;
398    unsigned int flags;
399    struct clk *clk;
742400
743    div = jz_clk_pll_half_get_rate(clk->parent) / rate - 1;
744    if (div < 0)
745        div = 0;
746    else if (div > 31)
747        div = 31;
401    snprintf(div_name, sizeof(div_name), "%s-div", name);
402    snprintf(mux_name, sizeof(mux_name), "%s-mux", name);
403    snprintf(gate_name, sizeof(gate_name), "%s-gate", name);
404
405    clk = clk_register_divider(NULL, div_name, "PERIP CLK", 0,
406            jz4740_clk_base + div_reg, div_shift, div_width, 0,
407            &jz4740_clk_lock);
408
409    if (bypass_name) {
410        mux_parents[0] = bypass_name;
411        mux_parents[1] = div_name;
412        clk = clk_register_mux(NULL, mux_name, mux_parents, 2,
413            CLK_SET_RATE_PARENT,
414            jz4740_clk_base + mux_reg, mux_shift, 1, 0,
415            &jz4740_clk_lock);
416        gate_parent = mux_name;
417    } else {
418        gate_parent = div_name;
419    }
748420
749    jz_clk_reg_write_mask(JZ_REG_CLOCK_CTRL, div << JZ_CLOCK_CTRL_LDIV_OFFSET,
750                JZ_CLOCK_CTRL_LDIV_MASK);
421    if (gate_reg) {
422        if (gate_reg == JZ_REG_CLOCK_GATE)
423            flags = CLK_GATE_SET_TO_DISABLE;
424        else
425            flags = 0;
426        clk = clk_register_gate(NULL, gate_name, gate_parent,
427            CLK_SET_RATE_PARENT,
428            jz4740_clk_base + gate_reg, gate_bit,
429            flags, &jz4740_clk_lock);
430    }
751431
752    return 0;
432    return clk;
753433}
754434
755static unsigned long jz_clk_ldclk_get_rate(struct clk *clk)
435static struct clk *jz4740_register_gate(const char *name,
436    const char *parent_name, u8 gate_bit)
756437{
757    int div;
758
759    div = jz_clk_reg_read(JZ_REG_CLOCK_CTRL) & JZ_CLOCK_CTRL_LDIV_MASK;
760    div >>= JZ_CLOCK_CTRL_LDIV_OFFSET;
761
762    return jz_clk_pll_half_get_rate(clk->parent) / (div + 1);
438    return clk_register_gate(NULL, name, parent_name, 0,
439        jz4740_clk_base + JZ_REG_CLOCK_GATE, gate_bit,
440        CLK_GATE_SET_TO_DISABLE, &jz4740_clk_lock);
763441}
764442
765static const struct clk_ops jz_clk_ops_ld = {
766    .set_rate = jz_clk_ldclk_set_rate,
767    .get_rate = jz_clk_ldclk_get_rate,
768    .round_rate = jz_clk_ldclk_round_rate,
769    .enable = jz_clk_enable_gating,
770    .disable = jz_clk_disable_gating,
771    .is_enabled = jz_clk_is_enabled_gating,
772};
773
774static struct clk jz_clk_ld = {
775    .name = "lcd",
776    .gate_bit = JZ_CLOCK_GATE_LCD,
777    .parent = &jz_clk_pll_half,
778    .ops = &jz_clk_ops_ld,
779};
780
781static const struct clk_ops jz_clk_i2s_ops = {
782    .set_rate = jz_clk_divided_set_rate,
783    .get_rate = jz_clk_divided_get_rate,
784    .enable = jz_clk_enable_gating,
785    .disable = jz_clk_disable_gating,
786    .is_enabled = jz_clk_is_enabled_gating,
787    .set_parent = jz_clk_i2s_set_parent,
788};
789
790static const struct clk_ops jz_clk_spi_ops = {
791    .set_rate = jz_clk_divided_set_rate,
792    .get_rate = jz_clk_divided_get_rate,
793    .enable = jz_clk_enable_gating,
794    .disable = jz_clk_disable_gating,
795    .is_enabled = jz_clk_is_enabled_gating,
796    .set_parent = jz_clk_spi_set_parent,
797};
798
799static const struct clk_ops jz_clk_divided_ops = {
800    .set_rate = jz_clk_divided_set_rate,
801    .get_rate = jz_clk_divided_get_rate,
802    .enable = jz_clk_enable_gating,
803    .disable = jz_clk_disable_gating,
804    .is_enabled = jz_clk_is_enabled_gating,
805};
806
807static struct divided_clk jz4740_clock_divided_clks[] = {
808    [0] = {
809        .clk = {
810            .name = "i2s",
811            .parent = &jz_clk_ext.clk,
812            .gate_bit = JZ_CLOCK_GATE_I2S,
813            .ops = &jz_clk_i2s_ops,
814        },
815        .reg = JZ_REG_CLOCK_I2S,
816        .mask = JZ_CLOCK_I2S_DIV_MASK,
817    },
818    [1] = {
819        .clk = {
820            .name = "spi",
821            .parent = &jz_clk_ext.clk,
822            .gate_bit = JZ_CLOCK_GATE_SPI,
823            .ops = &jz_clk_spi_ops,
824        },
825        .reg = JZ_REG_CLOCK_SPI,
826        .mask = JZ_CLOCK_SPI_DIV_MASK,
827    },
828    [2] = {
829        .clk = {
830            .name = "lcd_pclk",
831            .parent = &jz_clk_pll_half,
832            .gate_bit = JZ4740_CLK_NOT_GATED,
833            .ops = &jz_clk_divided_ops,
834        },
835        .reg = JZ_REG_CLOCK_LCD,
836        .mask = JZ_CLOCK_LCD_DIV_MASK,
837    },
838    [3] = {
839        .clk = {
840            .name = "mmc",
841            .parent = &jz_clk_pll_half,
842            .gate_bit = JZ_CLOCK_GATE_MMC,
843            .ops = &jz_clk_divided_ops,
844        },
845        .reg = JZ_REG_CLOCK_MMC,
846        .mask = JZ_CLOCK_MMC_DIV_MASK,
847    },
848    [4] = {
849        .clk = {
850            .name = "uhc",
851            .parent = &jz_clk_pll_half,
852            .gate_bit = JZ_CLOCK_GATE_UHC,
853            .ops = &jz_clk_divided_ops,
854        },
855        .reg = JZ_REG_CLOCK_UHC,
856        .mask = JZ_CLOCK_UHC_DIV_MASK,
857    },
443static const struct clk_div_table jz4740_perip_clk_div_table[] = {
444    { 0, 2 },
445    { 1, 1 },
446    { },
858447};
859448
860static const struct clk_ops jz_clk_udc_ops = {
861    .set_parent = jz_clk_udc_set_parent,
862    .set_rate = jz_clk_udc_set_rate,
863    .get_rate = jz_clk_udc_get_rate,
864    .enable = jz_clk_udc_enable,
865    .disable = jz_clk_udc_disable,
866    .is_enabled = jz_clk_udc_is_enabled,
867};
449static const char *pll_clk_parent = "EXCLK";
868450
869static const struct clk_ops jz_clk_simple_ops = {
870    .enable = jz_clk_enable_gating,
871    .disable = jz_clk_disable_gating,
872    .is_enabled = jz_clk_is_enabled_gating,
451static struct clk_init_data pll_clk_init = {
452    .name = "PLL",
453    .ops = &jz4740_clk_pll_ops,
454    .flags = 0,
455    .parent_names = &pll_clk_parent,
456    .num_parents = 1,
873457};
874458
875static struct clk jz4740_clock_simple_clks[] = {
876    [0] = {
877        .name = "udc",
878        .parent = &jz_clk_ext.clk,
879        .ops = &jz_clk_udc_ops,
880    },
881    [1] = {
882        .name = "uart0",
883        .parent = &jz_clk_ext.clk,
884        .gate_bit = JZ_CLOCK_GATE_UART0,
885        .ops = &jz_clk_simple_ops,
886    },
887    [2] = {
888        .name = "uart1",
889        .parent = &jz_clk_ext.clk,
890        .gate_bit = JZ_CLOCK_GATE_UART1,
891        .ops = &jz_clk_simple_ops,
892    },
893    [3] = {
894        .name = "dma",
895        .parent = &jz_clk_high_speed_peripheral.clk,
896        .gate_bit = JZ_CLOCK_GATE_DMAC,
897        .ops = &jz_clk_simple_ops,
898    },
899    [4] = {
900        .name = "ipu",
901        .parent = &jz_clk_high_speed_peripheral.clk,
902        .gate_bit = JZ_CLOCK_GATE_IPU,
903        .ops = &jz_clk_simple_ops,
904    },
905    [5] = {
906        .name = "adc",
907        .parent = &jz_clk_ext.clk,
908        .gate_bit = JZ_CLOCK_GATE_ADC,
909        .ops = &jz_clk_simple_ops,
910    },
911    [6] = {
912        .name = "i2c",
913        .parent = &jz_clk_ext.clk,
914        .gate_bit = JZ_CLOCK_GATE_I2C,
915        .ops = &jz_clk_simple_ops,
916    },
917    [7] = {
918        .name = "aic",
919        .parent = &jz_clk_ext.clk,
920        .gate_bit = JZ_CLOCK_GATE_AIC,
921        .ops = &jz_clk_simple_ops,
922    },
459static struct clk_hw pll_clk = {
460    .init = &pll_clk_init,
923461};
924462
925static struct static_clk jz_clk_rtc = {
926    .clk = {
927        .name = "rtc",
928        .gate_bit = JZ_CLOCK_GATE_RTC,
929        .ops = &jz_clk_static_ops,
930    },
931    .rate = 32768,
932};
933
934int clk_enable(struct clk *clk)
463static void __init clk_register_clks(void)
935464{
936    if (!clk->ops->enable)
937        return -EINVAL;
465    struct clk *clk;
938466
939    return clk->ops->enable(clk);
940}
941EXPORT_SYMBOL_GPL(clk_enable);
467    clk = clk_register_fixed_rate(NULL, "EXCLK", NULL, CLK_IS_ROOT,
468        jz4740_clock_bdata.ext_rate);
469    clk_register_clkdev(clk, "ext", "jz4740-pwm");
942470
943void clk_disable(struct clk *clk)
944{
945    if (clk->ops->disable)
946        clk->ops->disable(clk);
947}
948EXPORT_SYMBOL_GPL(clk_disable);
471    clk_register(NULL, &pll_clk);
949472
950int clk_is_enabled(struct clk *clk)
951{
952    if (clk->ops->is_enabled)
953        return clk->ops->is_enabled(clk);
473    clk_register_fixed_rate(NULL, "RTCLK_XI", NULL, CLK_IS_ROOT,
474        jz4740_clock_bdata.rtc_rate);
954475
955    return 1;
956}
476    jz4740_register_main_clock("MCLK", JZ_CLOCK_CTRL_MDIV_OFFSET);
477    jz4740_register_main_clock("PCLK", JZ_CLOCK_CTRL_PDIV_OFFSET);
478    jz4740_register_main_clock("HCLK", JZ_CLOCK_CTRL_HDIV_OFFSET);
479    jz4740_register_main_clock("CCLK", JZ_CLOCK_CTRL_CDIV_OFFSET);
957480
958unsigned long clk_get_rate(struct clk *clk)
959{
960    if (clk->ops->get_rate)
961        return clk->ops->get_rate(clk);
962    if (clk->parent)
963        return clk_get_rate(clk->parent);
481    clk = jz4740_register_gate("rtc", "RTCLK_XI", JZ_CLOCK_GATE_RTC);
482    clk_register_clkdev(clk, "rtc", "jz4740-rtc");
483    clk_register_clkdev(clk, "rtc", "jz4740-wdt");
964484
965    return -EINVAL;
966}
967EXPORT_SYMBOL_GPL(clk_get_rate);
485#if 0
486    jz4740_register_gate("uart0", "EXCLK", JZ_CLOCK_GATE_UART0);
487    jz4740_register_gate("uart1", "EXCLK", JZ_CLOCK_GATE_UART1);
968488
969int clk_set_rate(struct clk *clk, unsigned long rate)
970{
971    if (!clk->ops->set_rate)
972        return -EINVAL;
973    return clk->ops->set_rate(clk, rate);
974}
975EXPORT_SYMBOL_GPL(clk_set_rate);
489    clk_register_gate(NULL, "ko", "MCLK", 0,
490        jz4740_clk_base + JZ_REG_CLOCK_CTRL, 30,
491        0, &jz4740_clk_lock);
492#endif
976493
977long clk_round_rate(struct clk *clk, unsigned long rate)
978{
979    if (clk->ops->round_rate)
980        return clk->ops->round_rate(clk, rate);
494    jz4740_register_gate("ipu", "HCLK", JZ_CLOCK_GATE_IPU);
981495
982    return -EINVAL;
983}
984EXPORT_SYMBOL_GPL(clk_round_rate);
496    clk = jz4740_register_gate("dma", "HCLK", JZ_CLOCK_GATE_DMAC);
497    clk_register_clkdev(clk, "dma", "jz4740-dma");
985498
986int clk_set_parent(struct clk *clk, struct clk *parent)
987{
988    int ret;
989    int enabled;
499    clk = jz4740_register_gate("adc", "EXCLK", JZ_CLOCK_GATE_ADC);
500    clk_register_clkdev(clk, "adc", "jz4740-adc");
990501
991    if (!clk->ops->set_parent)
992        return -EINVAL;
502    jz4740_register_gate("i2c", "EXCLK", JZ_CLOCK_GATE_I2C);
993503
994    enabled = clk_is_enabled(clk);
995    if (enabled)
996        clk_disable(clk);
997    ret = clk->ops->set_parent(clk, parent);
998    if (enabled)
999        clk_enable(clk);
504    clk = jz4740_register_gate("aic", "EXCLK", JZ_CLOCK_GATE_AIC);
505    clk_register_clkdev(clk, "aic", "jz4740-i2s");
1000506
1001    jz4740_clock_debugfs_update_parent(clk);
507    clk_register_divider_table(NULL, "PERIP CLK", "PLL", 0,
508        jz4740_clk_base + JZ_REG_CLOCK_CTRL, 21, 1, 0,
509        jz4740_perip_clk_div_table, &jz4740_clk_lock);
1002510
1003    return ret;
1004}
1005EXPORT_SYMBOL_GPL(clk_set_parent);
511    clk = jz4740_register_peripheral_clock("i2s", "EXCLK",
512        JZ_REG_CLOCK_CTRL, 31,
513        JZ_REG_CLOCK_I2S, 0, 9,
514        JZ_REG_CLOCK_GATE, JZ_CLOCK_GATE_I2S);
515    clk_register_clkdev(clk, "i2s", "jz4740-i2s");
1006516
1007struct clk *clk_get(struct device *dev, const char *name)
1008{
1009    struct clk *clk;
517    jz4740_register_peripheral_clock("spi", "EXCLK",
518        JZ_REG_CLOCK_SPI, 31,
519        JZ_REG_CLOCK_SPI, 0, 4,
520        JZ_REG_CLOCK_GATE, JZ_CLOCK_GATE_SPI);
1010521
1011    list_for_each_entry(clk, &jz_clocks, list) {
1012        if (strcmp(clk->name, name) == 0)
1013            return clk;
1014    }
1015    return ERR_PTR(-ENXIO);
1016}
1017EXPORT_SYMBOL_GPL(clk_get);
522    clk = jz4740_register_peripheral_clock("lcd_pclk", NULL, 0, 0,
523        JZ_REG_CLOCK_LCD, 0, 11,
524        0, 0);
525    clk_register_clkdev(clk, "lcd_pclk", "jz4740-fb");
1018526
1019void clk_put(struct clk *clk)
1020{
1021}
1022EXPORT_SYMBOL_GPL(clk_put);
527    clk = jz4740_register_peripheral_clock("lcd", NULL, 0, 0,
528        JZ_REG_CLOCK_CTRL, JZ_CLOCK_CTRL_LDIV_OFFSET, 5,
529        JZ_REG_CLOCK_GATE, JZ_CLOCK_GATE_LCD);
530    clk_register_clkdev(clk, "lcd", "jz4740-fb");
1023531
1024static inline void clk_add(struct clk *clk)
1025{
1026    list_add_tail(&clk->list, &jz_clocks);
532    clk = jz4740_register_peripheral_clock("mmc", NULL, 0, 0,
533        JZ_REG_CLOCK_MMC, 0, 5,
534        JZ_REG_CLOCK_GATE, JZ_CLOCK_GATE_MMC);
535    clk_register_clkdev(clk, "mmc", "jz4740-mmc.0");
1027536
1028    jz4740_clock_debugfs_add_clk(clk);
1029}
537    clk = jz4740_register_peripheral_clock("uhc", NULL, 0, 0,
538        JZ_REG_CLOCK_UHC, 0, 4,
539        JZ_REG_CLOCK_GATE, JZ_CLOCK_GATE_UHC);
540    clk_register_clkdev(clk, "uhc", "jz4740-ohci");
1030541
1031static void clk_register_clks(void)
1032{
1033    size_t i;
1034
1035    clk_add(&jz_clk_ext.clk);
1036    clk_add(&jz_clk_pll);
1037    clk_add(&jz_clk_pll_half);
1038    clk_add(&jz_clk_cpu.clk);
1039    clk_add(&jz_clk_high_speed_peripheral.clk);
1040    clk_add(&jz_clk_low_speed_peripheral.clk);
1041    clk_add(&jz_clk_ko);
1042    clk_add(&jz_clk_ld);
1043    clk_add(&jz_clk_rtc.clk);
1044
1045    for (i = 0; i < ARRAY_SIZE(jz4740_clock_divided_clks); ++i)
1046        clk_add(&jz4740_clock_divided_clks[i].clk);
1047
1048    for (i = 0; i < ARRAY_SIZE(jz4740_clock_simple_clks); ++i)
1049        clk_add(&jz4740_clock_simple_clks[i]);
542    clk = jz4740_register_peripheral_clock("udc", "EXCLK", JZ_REG_CLOCK_CTRL, 29,
543        JZ_REG_CLOCK_CTRL, JZ_CLOCK_CTRL_UDIV_OFFSET, 6,
544        JZ_REG_CLOCK_SLEEP_CTRL, JZ_CLOCK_SLEEP_CTRL_ENABLE_UDC);
545    clk_register_clkdev(clk, "udc", "jz-udc");
1050546}
1051547
1052548void jz4740_clock_set_wait_mode(enum jz4740_wait_mode mode)
...... 
1063559
1064560void jz4740_clock_udc_disable_auto_suspend(void)
1065561{
1066    jz_clk_reg_clear_bits(JZ_REG_CLOCK_GATE, JZ_CLOCK_GATE_UDC);
562    jz_clk_reg_clear_bits(JZ_REG_CLOCK_GATE, BIT(JZ_CLOCK_GATE_UDC));
1067563}
1068564EXPORT_SYMBOL_GPL(jz4740_clock_udc_disable_auto_suspend);
1069565
1070566void jz4740_clock_udc_enable_auto_suspend(void)
1071567{
1072    jz_clk_reg_set_bits(JZ_REG_CLOCK_GATE, JZ_CLOCK_GATE_UDC);
568    jz_clk_reg_set_bits(JZ_REG_CLOCK_GATE, BIT(JZ_CLOCK_GATE_UDC));
1073569}
1074570EXPORT_SYMBOL_GPL(jz4740_clock_udc_enable_auto_suspend);
1075571
...... 
1095591        JZ_CLOCK_GATE_TCU | JZ_CLOCK_GATE_DMAC | JZ_CLOCK_GATE_UART0);
1096592}
1097593
1098static int jz4740_clock_init(void)
594static int __init jz4740_clock_init(void)
1099595{
1100    uint32_t val;
1101
1102    jz_clock_base = ioremap(JZ4740_CPM_BASE_ADDR, 0x100);
1103    if (!jz_clock_base)
596    jz4740_clk_base = ioremap(JZ4740_CPM_BASE_ADDR, 0x100);
597    if (!jz4740_clk_base)
1104598        return -EBUSY;
1105599
1106600    jz_emc_base = ioremap(JZ4740_EMC_BASE_ADDR, 0x100);
1107601    if (!jz_emc_base)
1108602        return -EBUSY;
1109603
1110    spin_lock_init(&jz_clock_lock);
1111
1112    jz_clk_ext.rate = jz4740_clock_bdata.ext_rate;
1113    jz_clk_rtc.rate = jz4740_clock_bdata.rtc_rate;
1114
1115    val = jz_clk_reg_read(JZ_REG_CLOCK_SPI);
1116
1117    if (val & JZ_CLOCK_SPI_SRC_PLL)
1118        jz4740_clock_divided_clks[1].clk.parent = &jz_clk_pll_half;
1119
1120    val = jz_clk_reg_read(JZ_REG_CLOCK_CTRL);
1121
1122    if (val & JZ_CLOCK_CTRL_I2S_SRC_PLL)
1123        jz4740_clock_divided_clks[0].clk.parent = &jz_clk_pll_half;
1124
1125    if (val & JZ_CLOCK_CTRL_UDC_SRC_PLL)
1126        jz4740_clock_simple_clks[0].parent = &jz_clk_pll_half;
1127
1128    jz4740_clock_debugfs_init();
604    spin_lock_init(&jz4740_clk_lock);
1129605
1130606    clk_register_clks();
1131607
arch/mips/jz4740/clock.h
3131
3232struct clk;
3333
34struct clk_ops {
35    unsigned long (*get_rate)(struct clk *clk);
36    unsigned long (*round_rate)(struct clk *clk, unsigned long rate);
37    int (*set_rate)(struct clk *clk, unsigned long rate);
38    int (*enable)(struct clk *clk);
39    int (*disable)(struct clk *clk);
40    int (*is_enabled)(struct clk *clk);
41
42    int (*set_parent)(struct clk *clk, struct clk *parent);
43
44};
45
46struct clk {
47    const char *name;
48    struct clk *parent;
49
50    uint32_t gate_bit;
51
52    const struct clk_ops *ops;
53
54    struct list_head list;
55
56#ifdef CONFIG_DEBUG_FS
57    struct dentry *debugfs_entry;
58    struct dentry *debugfs_parent_entry;
59#endif
60
61};
62
63#define JZ4740_CLK_NOT_GATED ((uint32_t)-1)
64
65int clk_is_enabled(struct clk *clk);
66
6734int clk_main_set_dividers(bool immediate, unsigned int cdiv, unsigned int hdiv,
6835              unsigned int mdiv, unsigned int pdiv);
6936
70#ifdef CONFIG_DEBUG_FS
71void jz4740_clock_debugfs_init(void);
72void jz4740_clock_debugfs_add_clk(struct clk *clk);
73void jz4740_clock_debugfs_update_parent(struct clk *clk);
74#else
75static inline void jz4740_clock_debugfs_init(void) {};
76static inline void jz4740_clock_debugfs_add_clk(struct clk *clk) {};
77static inline void jz4740_clock_debugfs_update_parent(struct clk *clk) {};
78#endif
79
8037#endif

Archive Download the corresponding diff file



interactive