[PATCH] sh: Simplistic clock framework

This adds a relatively simplistic clock framework for sh.  The initial goal
behind this is to clean up the arch/sh/kernel/time.c mess and to get the CPU
subtype-specific frequency setting and calculation code moved somewhere more
sensible.

This only deals with the core clocks at the moment, though it's trivial for
other drivers to define their own clocks as desired.

Signed-off-by: Paul Mundt <lethal@linux-sh.org>
Cc: john stultz <johnstul@us.ibm.com>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Этот коммит содержится в:
Paul Mundt
2006-01-16 22:14:17 -08:00
коммит произвёл Linus Torvalds
родитель b66c1a3919
Коммит 36ddf31b68
19 изменённых файлов: 1287 добавлений и 623 удалений

Просмотреть файл

@@ -2,7 +2,7 @@
# Makefile for the STMicroelectronics Overdrive specific parts of the kernel
#
obj-y := mach.o setup.o io.o irq.o led.o time.o
obj-y := mach.o setup.o io.o irq.o led.o
obj-$(CONFIG_PCI) += fpga.o galileo.o pcidma.o

Просмотреть файл

@@ -17,8 +17,6 @@
#include <asm/overdrive/overdrive.h>
#include <asm/overdrive/fpga.h>
extern void od_time_init(void);
const char *get_system_type(void)
{
return "SH7750 Overdrive";
@@ -31,11 +29,9 @@ int __init platform_setup(void)
{
#ifdef CONFIG_PCI
init_overdrive_fpga();
galileo_init();
galileo_init();
#endif
board_time_init = od_time_init;
/* Enable RS232 receive buffers */
writel(0x1e, OVERDRIVE_CTRL);
}

Просмотреть файл

@@ -1,119 +0,0 @@
/*
* arch/sh/boards/overdrive/time.c
*
* Copyright (C) 2000 Stuart Menefy (stuart.menefy@st.com)
* Copyright (C) 2002 Paul Mundt (lethal@chaoticdreams.org)
*
* May be copied or modified under the terms of the GNU General Public
* License. See linux/COPYING for more information.
*
* STMicroelectronics Overdrive Support.
*/
void od_time_init(void)
{
struct frqcr_data {
unsigned short frqcr;
struct {
unsigned char multiplier;
unsigned char divisor;
} factor[3];
};
static struct frqcr_data st40_frqcr_table[] = {
{ 0x000, {{1,1}, {1,1}, {1,2}}},
{ 0x002, {{1,1}, {1,1}, {1,4}}},
{ 0x004, {{1,1}, {1,1}, {1,8}}},
{ 0x008, {{1,1}, {1,2}, {1,2}}},
{ 0x00A, {{1,1}, {1,2}, {1,4}}},
{ 0x00C, {{1,1}, {1,2}, {1,8}}},
{ 0x011, {{1,1}, {2,3}, {1,6}}},
{ 0x013, {{1,1}, {2,3}, {1,3}}},
{ 0x01A, {{1,1}, {1,2}, {1,4}}},
{ 0x01C, {{1,1}, {1,2}, {1,8}}},
{ 0x023, {{1,1}, {2,3}, {1,3}}},
{ 0x02C, {{1,1}, {1,2}, {1,8}}},
{ 0x048, {{1,2}, {1,2}, {1,4}}},
{ 0x04A, {{1,2}, {1,2}, {1,6}}},
{ 0x04C, {{1,2}, {1,2}, {1,8}}},
{ 0x05A, {{1,2}, {1,3}, {1,6}}},
{ 0x05C, {{1,2}, {1,3}, {1,6}}},
{ 0x063, {{1,2}, {1,4}, {1,4}}},
{ 0x06C, {{1,2}, {1,4}, {1,8}}},
{ 0x091, {{1,3}, {1,3}, {1,6}}},
{ 0x093, {{1,3}, {1,3}, {1,6}}},
{ 0x0A3, {{1,3}, {1,6}, {1,6}}},
{ 0x0DA, {{1,4}, {1,4}, {1,8}}},
{ 0x0DC, {{1,4}, {1,4}, {1,8}}},
{ 0x0EC, {{1,4}, {1,8}, {1,8}}},
{ 0x123, {{1,4}, {1,4}, {1,8}}},
{ 0x16C, {{1,4}, {1,8}, {1,8}}},
};
struct memclk_data {
unsigned char multiplier;
unsigned char divisor;
};
static struct memclk_data st40_memclk_table[8] = {
{1,1}, // 000
{1,2}, // 001
{1,3}, // 010
{2,3}, // 011
{1,4}, // 100
{1,6}, // 101
{1,8}, // 110
{1,8} // 111
};
unsigned long pvr;
/*
* This should probably be moved into the SH3 probing code, and then
* use the processor structure to determine which CPU we are running
* on.
*/
pvr = ctrl_inl(CCN_PVR);
printk("PVR %08x\n", pvr);
if (((pvr >> CCN_PVR_CHIP_SHIFT) & CCN_PVR_CHIP_MASK) == CCN_PVR_CHIP_ST40STB1) {
/*
* Unfortunatly the STB1 FRQCR values are different from the
* 7750 ones.
*/
struct frqcr_data *d;
int a;
unsigned long memclkcr;
struct memclk_data *e;
for (a=0; a<ARRAY_SIZE(st40_frqcr_table); a++) {
d = &st40_frqcr_table[a];
if (d->frqcr == (frqcr & 0x1ff))
break;
}
if (a == ARRAY_SIZE(st40_frqcr_table)) {
d = st40_frqcr_table;
printk("ERROR: Unrecognised FRQCR value, using default multipliers\n");
}
memclkcr = ctrl_inl(CLOCKGEN_MEMCLKCR);
e = &st40_memclk_table[memclkcr & MEMCLKCR_RATIO_MASK];
printk("Clock multipliers: CPU: %d/%d Bus: %d/%d Mem: %d/%d Periph: %d/%d\n",
d->factor[0].multiplier, d->factor[0].divisor,
d->factor[1].multiplier, d->factor[1].divisor,
e->multiplier, e->divisor,
d->factor[2].multiplier, d->factor[2].divisor);
current_cpu_data.master_clock = current_cpu_data.module_clock *
d->factor[2].divisor /
d->factor[2].multiplier;
current_cpu_data.bus_clock = current_cpu_data.master_clock *
d->factor[1].multiplier /
d->factor[1].divisor;
current_cpu_data.memory_clock = current_cpu_data.master_clock *
e->multiplier / e->divisor;
current_cpu_data.cpu_clock = current_cpu_data.master_clock *
d->factor[0].multiplier /
d->factor[0].divisor;
}