clock-sh7757.c 4.0 KB
Newer Older
1 2 3 4 5
/*
 * arch/sh/kernel/cpu/sh4/clock-sh7757.c
 *
 * SH7757 support for the clock framework
 *
6
 *  Copyright (C) 2009-2010  Renesas Solutions Corp.
7 8 9 10 11 12 13 14
 *
 * This file is subject to the terms and conditions of the GNU General Public
 * License.  See the file "COPYING" in the main directory of this archive
 * for more details.
 */
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/io.h>
15
#include <linux/clkdev.h>
16 17 18
#include <asm/clock.h>
#include <asm/freq.h>

19 20 21 22 23 24 25
/*
 * Default rate for the root input clock, reset this with clk_set_rate()
 * from the platform code.
 */
static struct clk extal_clk = {
	.rate		= 48000000,
};
26

27
static unsigned long pll_recalc(struct clk *clk)
28
{
29
	int multiplier;
30

31
	multiplier = test_mode_pin(MODE_PIN0) ? 24 : 16;
32

33
	return clk->parent->rate * multiplier;
34 35
}

36 37
static struct clk_ops pll_clk_ops = {
	.recalc		= pll_recalc,
38 39
};

40 41 42 43 44
static struct clk pll_clk = {
	.ops		= &pll_clk_ops,
	.parent		= &extal_clk,
	.flags		= CLK_ENABLE_ON_INIT,
};
45

46 47 48
static struct clk *clks[] = {
	&extal_clk,
	&pll_clk,
49 50
};

51 52
static unsigned int div2[] = { 1, 1, 2, 1, 1, 4, 1, 6,
			       1, 1, 1, 16, 1, 24, 1, 1 };
53

54 55 56
static struct clk_div_mult_table div4_div_mult_table = {
	.divisors = div2,
	.nr_divisors = ARRAY_SIZE(div2),
57 58
};

59 60
static struct clk_div4_table div4_table = {
	.div_mult_table = &div4_div_mult_table,
61 62
};

63
enum { DIV4_I, DIV4_SH, DIV4_P, DIV4_NR };
64

65 66
#define DIV4(_bit, _mask, _flags) \
  SH_CLK_DIV4(&pll_clk, FRQCR, _bit, _mask, _flags)
67

68 69 70 71 72 73 74 75
struct clk div4_clks[DIV4_NR] = {
	/*
	 * P clock is always enable, because some P clock modules is used
	 * by Host PC.
	 */
	[DIV4_P] = DIV4(0, 0x2800, CLK_ENABLE_ON_INIT),
	[DIV4_SH] = DIV4(12, 0x00a0, CLK_ENABLE_ON_INIT),
	[DIV4_I] = DIV4(20, 0x0004, CLK_ENABLE_ON_INIT),
76 77
};

78 79
#define MSTPCR0		0xffc80030
#define MSTPCR1		0xffc80034
80
#define MSTPCR2		0xffc10028
81 82

enum { MSTP004, MSTP000, MSTP114, MSTP113, MSTP112,
83
       MSTP111, MSTP110, MSTP103, MSTP102, MSTP220,
84 85 86 87 88 89 90 91 92 93 94 95 96 97 98
       MSTP_NR };

static struct clk mstp_clks[MSTP_NR] = {
	/* MSTPCR0 */
	[MSTP004] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR0, 4, 0),
	[MSTP000] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR0, 0, 0),

	/* MSTPCR1 */
	[MSTP114] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR1, 14, 0),
	[MSTP113] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR1, 13, 0),
	[MSTP112] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR1, 12, 0),
	[MSTP111] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR1, 11, 0),
	[MSTP110] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR1, 10, 0),
	[MSTP103] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR1, 3, 0),
	[MSTP102] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR1, 2, 0),
99 100 101

	/* MSTPCR2 */
	[MSTP220] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR2, 20, 0),
102 103
};

M
Magnus Damm 已提交
104 105 106 107
#define CLKDEV_CON_ID(_id, _clk) { .con_id = _id, .clk = _clk }

static struct clk_lookup lookups[] = {
	/* main clocks */
108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146
	CLKDEV_CON_ID("extal", &extal_clk),
	CLKDEV_CON_ID("pll_clk", &pll_clk),

	/* DIV4 clocks */
	CLKDEV_CON_ID("peripheral_clk", &div4_clks[DIV4_P]),
	CLKDEV_CON_ID("shyway_clk", &div4_clks[DIV4_SH]),
	CLKDEV_CON_ID("cpu_clk", &div4_clks[DIV4_I]),

	/* MSTP32 clocks */
	CLKDEV_CON_ID("sdhi0", &mstp_clks[MSTP004]),
	CLKDEV_CON_ID("riic", &mstp_clks[MSTP000]),
	{
		/* TMU0 */
		.dev_id		= "sh_tmu.0",
		.con_id		= "tmu_fck",
		.clk		= &mstp_clks[MSTP113],
	}, {
		/* TMU1 */
		.dev_id		= "sh_tmu.1",
		.con_id		= "tmu_fck",
		.clk		= &mstp_clks[MSTP114],
	},
	{
		/* SCIF4 (But, ID is 2) */
		.dev_id		= "sh-sci.2",
		.con_id		= "sci_fck",
		.clk		= &mstp_clks[MSTP112],
	}, {
		/* SCIF3 */
		.dev_id		= "sh-sci.1",
		.con_id		= "sci_fck",
		.clk		= &mstp_clks[MSTP111],
	}, {
		/* SCIF2 */
		.dev_id		= "sh-sci.0",
		.con_id		= "sci_fck",
		.clk		= &mstp_clks[MSTP110],
	},
	CLKDEV_CON_ID("usb0", &mstp_clks[MSTP102]),
147
	CLKDEV_CON_ID("mmc0", &mstp_clks[MSTP220]),
M
Magnus Damm 已提交
148 149
};

150
int __init arch_clk_init(void)
151
{
152
	int i, ret = 0;
153

154 155 156 157
	for (i = 0; i < ARRAY_SIZE(clks); i++)
		ret |= clk_register(clks[i]);
	for (i = 0; i < ARRAY_SIZE(lookups); i++)
		clkdev_add(&lookups[i]);
158

159 160 161 162 163
	if (!ret)
		ret = sh_clk_div4_register(div4_clks, ARRAY_SIZE(div4_clks),
					   &div4_table);
	if (!ret)
		ret = sh_clk_mstp32_register(mstp_clks, MSTP_NR);
164

165
	return ret;
166 167
}