ARM: OMAP1: clock: Convert to CCF

OMAP1 still uses its own implementation of standard clock API defined in
include/linux/clk.h.  Internals of that implementation are not visible
outside OMAP1 directory.  As a consequence, device drivers are not able to
register clocks potentially provided by peripheral devices.

Drop OMAP1 implementation of the clock API and enable common clock
framework.  Modify the remaining low level code to be compatible with
clock provider API and register the clocks with CCF.

Move initialisation of clocks to omap1_timer_init() to avoid memory
allocation issues at early setup phase from where omap1_init_early() is
called.  Register the clocks after initialization of clock I/O registers,
local clock pointers used by OMAP1 clock ops, and local .rate fields of
clocks with no local implementation of .recalc ops, so CCF structures are
populated with correct data during clock registration.  Instead of
enabling some of the registered clocks, flag them for CCF as critical.
Introduce .is_enabled op using code that verifies hardware status of clock
enablement, split out from implementation of .disable_unused op, so the
latter is actually called by CCF for not requested but hardware enabled
clocks.  Add .round_rate ops where missing so .set_rate ops are called by
CCF as expected.  Since CCF allows parallel execution of .enable/.disable
and .set_rate ops, protect registers shared among those groups of ops from
concurrent access with spinlocks.  Drop local debugfs support in favor of
that provided by CCF.

v2: flag tc2_ck as CLK_IS_CRITICAL (Aaro)
v3: rebase on top of soc/omap1-multiplatform-5.18,
  - drop no longer needed includes from arch/arm/mach-omap1/io.c

Signed-off-by: Janusz Krzysztofik <jmkrzyszt@gmail.com>
Acked-by: Tony Lindgren <tony@atomide.com>
Signed-off-by: Arnd Bergmann <arnd@arndb.de>
This commit is contained in:
Janusz Krzysztofik 2022-04-10 15:07:57 +02:00 committed by Arnd Bergmann
parent 6f9b5ed8ca
commit c73b9099da
5 changed files with 563 additions and 764 deletions

File diff suppressed because it is too large Load Diff

View File

@ -11,12 +11,11 @@
#define __ARCH_ARM_MACH_OMAP1_CLOCK_H
#include <linux/clk.h>
#include <linux/list.h>
#include <linux/clkdev.h>
#include <linux/clk-provider.h>
struct module;
struct clk;
struct omap1_clk;
struct omap_clk {
u16 cpu;
@ -29,7 +28,7 @@ struct omap_clk {
.lk = { \
.dev_id = dev, \
.con_id = con, \
.clk = ck, \
.clk_hw = ck, \
}, \
}
@ -40,10 +39,6 @@ struct omap_clk {
#define CK_16XX (1 << 3) /* 16xx, 17xx, 5912 */
#define CK_1710 (1 << 4) /* 1710 extra for rate selection */
/* Temporary, needed during the common clock framework conversion */
#define __clk_get_name(clk) (clk->name)
/**
* struct clkops - some clock function pointers
* @enable: fn ptr that enables the current clock in hardware
@ -51,8 +46,8 @@ struct omap_clk {
* @allow_idle: fn ptr that enables autoidle for the current clock in hardware
*/
struct clkops {
int (*enable)(struct clk *);
void (*disable)(struct clk *);
int (*enable)(struct omap1_clk *clk);
void (*disable)(struct omap1_clk *clk);
};
/*
@ -65,13 +60,9 @@ struct clkops {
#define CLOCK_NO_IDLE_PARENT (1 << 2)
/**
* struct clk - OMAP struct clk
* @node: list_head connecting this clock into the full clock list
* struct omap1_clk - OMAP1 struct clk
* @hw: struct clk_hw for common clock framework integration
* @ops: struct clkops * for this clock
* @name: the name of the clock in the hardware (used in hwmod data and debug)
* @parent: pointer to this clock's parent struct clk
* @children: list_head connecting to the child clks' @sibling list_heads
* @sibling: list_head connecting this clk to its parent clk's @children
* @rate: current clock rate
* @enable_reg: register to write to enable the clock (see @enable_bit)
* @recalc: fn ptr that returns the clock's current rate
@ -79,102 +70,65 @@ struct clkops {
* @round_rate: fn ptr that can round the clock's current rate
* @init: fn ptr to do clock-specific initialization
* @enable_bit: bitshift to write to enable/disable the clock (see @enable_reg)
* @usecount: number of users that have requested this clock to be enabled
* @fixed_div: when > 0, this clock's rate is its parent's rate / @fixed_div
* @flags: see "struct clk.flags possibilities" above
* @rate_offset: bitshift for rate selection bitfield (OMAP1 only)
*
* XXX @rate_offset should probably be removed and OMAP1
* clock code converted to use clksel.
*
* XXX @usecount is poorly named. It should be "enable_count" or
* something similar. "users" in the description refers to kernel
* code (core code or drivers) that have called clk_enable() and not
* yet called clk_disable(); the usecount of parent clocks is also
* incremented by the clock code when clk_enable() is called on child
* clocks and decremented by the clock code when clk_disable() is
* called on child clocks.
*
* XXX @usecount, @children, @sibling should be marked for
* internal use only.
*
* @children and @sibling are used to optimize parent-to-child clock
* tree traversals. (child-to-parent traversals use @parent.)
*
* XXX The notion of the clock's current rate probably needs to be
* separated from the clock's target rate.
*/
struct clk {
struct list_head node;
struct omap1_clk {
struct clk_hw hw;
const struct clkops *ops;
const char *name;
struct clk *parent;
struct list_head children;
struct list_head sibling; /* node for children */
unsigned long rate;
void __iomem *enable_reg;
unsigned long (*recalc)(struct clk *);
int (*set_rate)(struct clk *, unsigned long);
long (*round_rate)(struct clk *, unsigned long);
void (*init)(struct clk *);
unsigned long (*recalc)(struct omap1_clk *clk, unsigned long rate);
int (*set_rate)(struct omap1_clk *clk, unsigned long rate,
unsigned long p_rate);
long (*round_rate)(struct omap1_clk *clk, unsigned long rate,
unsigned long *p_rate);
int (*init)(struct omap1_clk *clk);
u8 enable_bit;
s8 usecount;
u8 fixed_div;
u8 flags;
u8 rate_offset;
#if defined(CONFIG_PM_DEBUG) && defined(CONFIG_DEBUG_FS)
struct dentry *dent; /* For visible tree hierarchy */
#endif
};
#define to_omap1_clk(_hw) container_of(_hw, struct omap1_clk, hw)
extern void clk_preinit(struct clk *clk);
extern int clk_register(struct clk *clk);
extern void clk_unregister(struct clk *clk);
extern void propagate_rate(struct clk *clk);
extern unsigned long followparent_recalc(struct clk *clk);
unsigned long omap_fixed_divisor_recalc(struct clk *clk);
void propagate_rate(struct omap1_clk *clk);
unsigned long followparent_recalc(struct omap1_clk *clk, unsigned long p_rate);
unsigned long omap_fixed_divisor_recalc(struct omap1_clk *clk, unsigned long p_rate);
extern const struct clkops clkops_null;
extern struct clk dummy_ck;
extern struct omap1_clk dummy_ck;
int omap1_clk_init(void);
void omap1_clk_late_init(void);
extern int omap1_clk_enable(struct clk *clk);
extern void omap1_clk_disable(struct clk *clk);
extern long omap1_clk_round_rate(struct clk *clk, unsigned long rate);
extern int omap1_clk_set_rate(struct clk *clk, unsigned long rate);
extern unsigned long omap1_ckctl_recalc(struct clk *clk);
extern int omap1_set_sossi_rate(struct clk *clk, unsigned long rate);
extern unsigned long omap1_sossi_recalc(struct clk *clk);
extern unsigned long omap1_ckctl_recalc_dsp_domain(struct clk *clk);
extern int omap1_clk_set_rate_dsp_domain(struct clk *clk, unsigned long rate);
extern int omap1_set_uart_rate(struct clk *clk, unsigned long rate);
extern unsigned long omap1_uart_recalc(struct clk *clk);
extern int omap1_set_ext_clk_rate(struct clk *clk, unsigned long rate);
extern long omap1_round_ext_clk_rate(struct clk *clk, unsigned long rate);
extern void omap1_init_ext_clk(struct clk *clk);
extern int omap1_select_table_rate(struct clk *clk, unsigned long rate);
extern long omap1_round_to_table_rate(struct clk *clk, unsigned long rate);
extern int omap1_clk_set_rate_ckctl_arm(struct clk *clk, unsigned long rate);
extern long omap1_clk_round_rate_ckctl_arm(struct clk *clk, unsigned long rate);
#ifdef CONFIG_OMAP_RESET_CLOCKS
extern void omap1_clk_disable_unused(struct clk *clk);
#else
#define omap1_clk_disable_unused NULL
#endif
unsigned long omap1_ckctl_recalc(struct omap1_clk *clk, unsigned long p_rate);
long omap1_round_sossi_rate(struct omap1_clk *clk, unsigned long rate, unsigned long *p_rate);
int omap1_set_sossi_rate(struct omap1_clk *clk, unsigned long rate, unsigned long p_rate);
unsigned long omap1_sossi_recalc(struct omap1_clk *clk, unsigned long p_rate);
unsigned long omap1_ckctl_recalc_dsp_domain(struct omap1_clk *clk, unsigned long p_rate);
int omap1_clk_set_rate_dsp_domain(struct omap1_clk *clk, unsigned long rate,
unsigned long p_rate);
long omap1_round_uart_rate(struct omap1_clk *clk, unsigned long rate, unsigned long *p_rate);
int omap1_set_uart_rate(struct omap1_clk *clk, unsigned long rate, unsigned long p_rate);
unsigned long omap1_uart_recalc(struct omap1_clk *clk, unsigned long p_rate);
int omap1_set_ext_clk_rate(struct omap1_clk *clk, unsigned long rate, unsigned long p_rate);
long omap1_round_ext_clk_rate(struct omap1_clk *clk, unsigned long rate, unsigned long *p_rate);
int omap1_init_ext_clk(struct omap1_clk *clk);
int omap1_select_table_rate(struct omap1_clk *clk, unsigned long rate, unsigned long p_rate);
long omap1_round_to_table_rate(struct omap1_clk *clk, unsigned long rate, unsigned long *p_rate);
int omap1_clk_set_rate_ckctl_arm(struct omap1_clk *clk, unsigned long rate, unsigned long p_rate);
long omap1_clk_round_rate_ckctl_arm(struct omap1_clk *clk, unsigned long rate,
unsigned long *p_rate);
struct uart_clk {
struct clk clk;
unsigned long sysc_addr;
struct omap1_clk clk;
unsigned long sysc_addr;
};
/* Provide a method for preventing idling some ARM IDLECT clocks */
struct arm_idlect1_clk {
struct clk clk;
unsigned long no_idle_count;
__u8 idlect_shift;
struct omap1_clk clk;
unsigned long no_idle_count;
__u8 idlect_shift;
};
/* ARM_CKCTL bit shifts */
@ -224,7 +178,7 @@ struct arm_idlect1_clk {
#define SOFT_REQ_REG2 0xfffe0880
extern __u32 arm_idlect1_mask;
extern struct clk *api_ck_p, *ck_dpll1_p, *ck_ref_p;
extern struct omap1_clk *api_ck_p, *ck_dpll1_p, *ck_ref_p;
extern const struct clkops clkops_dspck;
extern const struct clkops clkops_uart_16xx;
@ -233,4 +187,9 @@ extern const struct clkops clkops_generic;
/* used for passing SoC type to omap1_{select,round_to}_table_rate() */
extern u32 cpu_mask;
extern const struct clk_ops omap1_clk_null_ops;
extern const struct clk_ops omap1_clk_gate_ops;
extern const struct clk_ops omap1_clk_rate_ops;
extern const struct clk_ops omap1_clk_full_ops;
#endif

View File

@ -14,6 +14,8 @@
#include <linux/kernel.h>
#include <linux/io.h>
#include <linux/clk.h>
#include <linux/clkdev.h>
#include <linux/clk-provider.h>
#include <linux/cpufreq.h>
#include <linux/delay.h>
#include <linux/soc/ti/omap1-io.h>
@ -71,16 +73,18 @@
* Omap1 clocks
*/
static struct clk ck_ref = {
.name = "ck_ref",
.ops = &clkops_null,
static struct omap1_clk ck_ref = {
.hw.init = CLK_HW_INIT_NO_PARENT("ck_ref", &omap1_clk_rate_ops, 0),
.rate = 12000000,
};
static struct clk ck_dpll1 = {
.name = "ck_dpll1",
.ops = &clkops_null,
.parent = &ck_ref,
static struct omap1_clk ck_dpll1 = {
.hw.init = CLK_HW_INIT("ck_dpll1", "ck_ref", &omap1_clk_rate_ops,
/*
* force recursive refresh of rates of the clock
* and its children when clk_get_rate() is called
*/
CLK_GET_RATE_NOCACHE),
};
/*
@ -89,32 +93,28 @@ static struct clk ck_dpll1 = {
*/
static struct arm_idlect1_clk ck_dpll1out = {
.clk = {
.name = "ck_dpll1out",
.hw.init = CLK_HW_INIT("ck_dpll1out", "ck_dpll1", &omap1_clk_gate_ops, 0),
.ops = &clkops_generic,
.parent = &ck_dpll1,
.flags = CLOCK_IDLE_CONTROL | ENABLE_REG_32BIT,
.enable_reg = OMAP1_IO_ADDRESS(ARM_IDLECT2),
.enable_bit = EN_CKOUT_ARM,
.recalc = &followparent_recalc,
},
.idlect_shift = IDL_CLKOUT_ARM_SHIFT,
};
static struct clk sossi_ck = {
.name = "ck_sossi",
static struct omap1_clk sossi_ck = {
.hw.init = CLK_HW_INIT("ck_sossi", "ck_dpll1out", &omap1_clk_full_ops, 0),
.ops = &clkops_generic,
.parent = &ck_dpll1out.clk,
.flags = CLOCK_NO_IDLE_PARENT | ENABLE_REG_32BIT,
.enable_reg = OMAP1_IO_ADDRESS(MOD_CONF_CTRL_1),
.enable_bit = CONF_MOD_SOSSI_CLK_EN_R,
.recalc = &omap1_sossi_recalc,
.round_rate = &omap1_round_sossi_rate,
.set_rate = &omap1_set_sossi_rate,
};
static struct clk arm_ck = {
.name = "arm_ck",
.ops = &clkops_null,
.parent = &ck_dpll1,
static struct omap1_clk arm_ck = {
.hw.init = CLK_HW_INIT("arm_ck", "ck_dpll1", &omap1_clk_rate_ops, 0),
.rate_offset = CKCTL_ARMDIV_OFFSET,
.recalc = &omap1_ckctl_recalc,
.round_rate = omap1_clk_round_rate_ckctl_arm,
@ -123,9 +123,9 @@ static struct clk arm_ck = {
static struct arm_idlect1_clk armper_ck = {
.clk = {
.name = "armper_ck",
.hw.init = CLK_HW_INIT("armper_ck", "ck_dpll1", &omap1_clk_full_ops,
CLK_IS_CRITICAL),
.ops = &clkops_generic,
.parent = &ck_dpll1,
.flags = CLOCK_IDLE_CONTROL,
.enable_reg = OMAP1_IO_ADDRESS(ARM_IDLECT2),
.enable_bit = EN_PERCK,
@ -141,46 +141,41 @@ static struct arm_idlect1_clk armper_ck = {
* FIXME: This clock seems to be necessary but no-one has asked for its
* activation. [ GPIO code for 1510 ]
*/
static struct clk arm_gpio_ck = {
.name = "ick",
static struct omap1_clk arm_gpio_ck = {
.hw.init = CLK_HW_INIT("ick", "ck_dpll1", &omap1_clk_gate_ops, CLK_IS_CRITICAL),
.ops = &clkops_generic,
.parent = &ck_dpll1,
.enable_reg = OMAP1_IO_ADDRESS(ARM_IDLECT2),
.enable_bit = EN_GPIOCK,
.recalc = &followparent_recalc,
};
static struct arm_idlect1_clk armxor_ck = {
.clk = {
.name = "armxor_ck",
.hw.init = CLK_HW_INIT("armxor_ck", "ck_ref", &omap1_clk_gate_ops,
CLK_IS_CRITICAL),
.ops = &clkops_generic,
.parent = &ck_ref,
.flags = CLOCK_IDLE_CONTROL,
.enable_reg = OMAP1_IO_ADDRESS(ARM_IDLECT2),
.enable_bit = EN_XORPCK,
.recalc = &followparent_recalc,
},
.idlect_shift = IDLXORP_ARM_SHIFT,
};
static struct arm_idlect1_clk armtim_ck = {
.clk = {
.name = "armtim_ck",
.hw.init = CLK_HW_INIT("armtim_ck", "ck_ref", &omap1_clk_gate_ops,
CLK_IS_CRITICAL),
.ops = &clkops_generic,
.parent = &ck_ref,
.flags = CLOCK_IDLE_CONTROL,
.enable_reg = OMAP1_IO_ADDRESS(ARM_IDLECT2),
.enable_bit = EN_TIMCK,
.recalc = &followparent_recalc,
},
.idlect_shift = IDLTIM_ARM_SHIFT,
};
static struct arm_idlect1_clk armwdt_ck = {
.clk = {
.name = "armwdt_ck",
.hw.init = CLK_HW_INIT("armwdt_ck", "ck_ref", &omap1_clk_full_ops, 0),
.ops = &clkops_generic,
.parent = &ck_ref,
.flags = CLOCK_IDLE_CONTROL,
.enable_reg = OMAP1_IO_ADDRESS(ARM_IDLECT2),
.enable_bit = EN_WDTCK,
@ -190,11 +185,8 @@ static struct arm_idlect1_clk armwdt_ck = {
.idlect_shift = IDLWDT_ARM_SHIFT,
};
static struct clk arminth_ck16xx = {
.name = "arminth_ck",
.ops = &clkops_null,
.parent = &arm_ck,
.recalc = &followparent_recalc,
static struct omap1_clk arminth_ck16xx = {
.hw.init = CLK_HW_INIT("arminth_ck", "arm_ck", &omap1_clk_null_ops, 0),
/* Note: On 16xx the frequency can be divided by 2 by programming
* ARM_CKCTL:ARM_INTHCK_SEL(14) to 1
*
@ -202,10 +194,9 @@ static struct clk arminth_ck16xx = {
*/
};
static struct clk dsp_ck = {
.name = "dsp_ck",
static struct omap1_clk dsp_ck = {
.hw.init = CLK_HW_INIT("dsp_ck", "ck_dpll1", &omap1_clk_full_ops, 0),
.ops = &clkops_generic,
.parent = &ck_dpll1,
.enable_reg = OMAP1_IO_ADDRESS(ARM_CKCTL),
.enable_bit = EN_DSPCK,
.rate_offset = CKCTL_DSPDIV_OFFSET,
@ -214,20 +205,17 @@ static struct clk dsp_ck = {
.set_rate = omap1_clk_set_rate_ckctl_arm,
};
static struct clk dspmmu_ck = {
.name = "dspmmu_ck",
.ops = &clkops_null,
.parent = &ck_dpll1,
static struct omap1_clk dspmmu_ck = {
.hw.init = CLK_HW_INIT("dspmmu_ck", "ck_dpll1", &omap1_clk_rate_ops, 0),
.rate_offset = CKCTL_DSPMMUDIV_OFFSET,
.recalc = &omap1_ckctl_recalc,
.round_rate = omap1_clk_round_rate_ckctl_arm,
.set_rate = omap1_clk_set_rate_ckctl_arm,
};
static struct clk dspper_ck = {
.name = "dspper_ck",
static struct omap1_clk dspper_ck = {
.hw.init = CLK_HW_INIT("dspper_ck", "ck_dpll1", &omap1_clk_full_ops, 0),
.ops = &clkops_dspck,
.parent = &ck_dpll1,
.enable_reg = DSP_IDLECT2,
.enable_bit = EN_PERCK,
.rate_offset = CKCTL_PERDIV_OFFSET,
@ -236,29 +224,23 @@ static struct clk dspper_ck = {
.set_rate = &omap1_clk_set_rate_dsp_domain,
};
static struct clk dspxor_ck = {
.name = "dspxor_ck",
static struct omap1_clk dspxor_ck = {
.hw.init = CLK_HW_INIT("dspxor_ck", "ck_ref", &omap1_clk_gate_ops, 0),
.ops = &clkops_dspck,
.parent = &ck_ref,
.enable_reg = DSP_IDLECT2,
.enable_bit = EN_XORPCK,
.recalc = &followparent_recalc,
};
static struct clk dsptim_ck = {
.name = "dsptim_ck",
static struct omap1_clk dsptim_ck = {
.hw.init = CLK_HW_INIT("dsptim_ck", "ck_ref", &omap1_clk_gate_ops, 0),
.ops = &clkops_dspck,
.parent = &ck_ref,
.enable_reg = DSP_IDLECT2,
.enable_bit = EN_DSPTIMCK,
.recalc = &followparent_recalc,
};
static struct arm_idlect1_clk tc_ck = {
.clk = {
.name = "tc_ck",
.ops = &clkops_null,
.parent = &ck_dpll1,
.hw.init = CLK_HW_INIT("tc_ck", "ck_dpll1", &omap1_clk_rate_ops, 0),
.flags = CLOCK_IDLE_CONTROL,
.rate_offset = CKCTL_TCDIV_OFFSET,
.recalc = &omap1_ckctl_recalc,
@ -268,116 +250,88 @@ static struct arm_idlect1_clk tc_ck = {
.idlect_shift = IDLIF_ARM_SHIFT,
};
static struct clk arminth_ck1510 = {
.name = "arminth_ck",
.ops = &clkops_null,
.parent = &tc_ck.clk,
.recalc = &followparent_recalc,
static struct omap1_clk arminth_ck1510 = {
.hw.init = CLK_HW_INIT("arminth_ck", "tc_ck", &omap1_clk_null_ops, 0),
/* Note: On 1510 the frequency follows TC_CK
*
* 16xx version is in MPU clocks.
*/
};
static struct clk tipb_ck = {
static struct omap1_clk tipb_ck = {
/* No-idle controlled by "tc_ck" */
.name = "tipb_ck",
.ops = &clkops_null,
.parent = &tc_ck.clk,
.recalc = &followparent_recalc,
.hw.init = CLK_HW_INIT("tipb_ck", "tc_ck", &omap1_clk_null_ops, 0),
};
static struct clk l3_ocpi_ck = {
static struct omap1_clk l3_ocpi_ck = {
/* No-idle controlled by "tc_ck" */
.name = "l3_ocpi_ck",
.hw.init = CLK_HW_INIT("l3_ocpi_ck", "tc_ck", &omap1_clk_gate_ops, 0),
.ops = &clkops_generic,
.parent = &tc_ck.clk,
.enable_reg = OMAP1_IO_ADDRESS(ARM_IDLECT3),
.enable_bit = EN_OCPI_CK,
.recalc = &followparent_recalc,
};
static struct clk tc1_ck = {
.name = "tc1_ck",
static struct omap1_clk tc1_ck = {
.hw.init = CLK_HW_INIT("tc1_ck", "tc_ck", &omap1_clk_gate_ops, 0),
.ops = &clkops_generic,
.parent = &tc_ck.clk,
.enable_reg = OMAP1_IO_ADDRESS(ARM_IDLECT3),
.enable_bit = EN_TC1_CK,
.recalc = &followparent_recalc,
};
/*
* FIXME: This clock seems to be necessary but no-one has asked for its
* activation. [ pm.c (SRAM), CCP, Camera ]
*/
static struct clk tc2_ck = {
.name = "tc2_ck",
static struct omap1_clk tc2_ck = {
.hw.init = CLK_HW_INIT("tc2_ck", "tc_ck", &omap1_clk_gate_ops, CLK_IS_CRITICAL),
.ops = &clkops_generic,
.parent = &tc_ck.clk,
.enable_reg = OMAP1_IO_ADDRESS(ARM_IDLECT3),
.enable_bit = EN_TC2_CK,
.recalc = &followparent_recalc,
};
static struct clk dma_ck = {
static struct omap1_clk dma_ck = {
/* No-idle controlled by "tc_ck" */
.name = "dma_ck",
.ops = &clkops_null,
.parent = &tc_ck.clk,
.recalc = &followparent_recalc,
.hw.init = CLK_HW_INIT("dma_ck", "tc_ck", &omap1_clk_null_ops, 0),
};
static struct clk dma_lcdfree_ck = {
.name = "dma_lcdfree_ck",
.ops = &clkops_null,
.parent = &tc_ck.clk,
.recalc = &followparent_recalc,
static struct omap1_clk dma_lcdfree_ck = {
.hw.init = CLK_HW_INIT("dma_lcdfree_ck", "tc_ck", &omap1_clk_null_ops, 0),
};
static struct arm_idlect1_clk api_ck = {
.clk = {
.name = "api_ck",
.hw.init = CLK_HW_INIT("api_ck", "tc_ck", &omap1_clk_gate_ops, 0),
.ops = &clkops_generic,
.parent = &tc_ck.clk,
.flags = CLOCK_IDLE_CONTROL,
.enable_reg = OMAP1_IO_ADDRESS(ARM_IDLECT2),
.enable_bit = EN_APICK,
.recalc = &followparent_recalc,
},
.idlect_shift = IDLAPI_ARM_SHIFT,
};
static struct arm_idlect1_clk lb_ck = {
.clk = {
.name = "lb_ck",
.hw.init = CLK_HW_INIT("lb_ck", "tc_ck", &omap1_clk_gate_ops, 0),
.ops = &clkops_generic,
.parent = &tc_ck.clk,
.flags = CLOCK_IDLE_CONTROL,
.enable_reg = OMAP1_IO_ADDRESS(ARM_IDLECT2),
.enable_bit = EN_LBCK,
.recalc = &followparent_recalc,
},
.idlect_shift = IDLLB_ARM_SHIFT,
};
static struct clk rhea1_ck = {
.name = "rhea1_ck",
.ops = &clkops_null,
.parent = &tc_ck.clk,
.recalc = &followparent_recalc,
static struct omap1_clk rhea1_ck = {
.hw.init = CLK_HW_INIT("rhea1_ck", "tc_ck", &omap1_clk_null_ops, 0),
};
static struct clk rhea2_ck = {
.name = "rhea2_ck",
.ops = &clkops_null,
.parent = &tc_ck.clk,
.recalc = &followparent_recalc,
static struct omap1_clk rhea2_ck = {
.hw.init = CLK_HW_INIT("rhea2_ck", "tc_ck", &omap1_clk_null_ops, 0),
};
static struct clk lcd_ck_16xx = {
.name = "lcd_ck",
static struct omap1_clk lcd_ck_16xx = {
.hw.init = CLK_HW_INIT("lcd_ck", "ck_dpll1", &omap1_clk_full_ops, 0),
.ops = &clkops_generic,
.parent = &ck_dpll1,
.enable_reg = OMAP1_IO_ADDRESS(ARM_IDLECT2),
.enable_bit = EN_LCDCK,
.rate_offset = CKCTL_LCDDIV_OFFSET,
@ -388,9 +342,8 @@ static struct clk lcd_ck_16xx = {
static struct arm_idlect1_clk lcd_ck_1510 = {
.clk = {
.name = "lcd_ck",
.hw.init = CLK_HW_INIT("lcd_ck", "ck_dpll1", &omap1_clk_full_ops, 0),
.ops = &clkops_generic,
.parent = &ck_dpll1,
.flags = CLOCK_IDLE_CONTROL,
.enable_reg = OMAP1_IO_ADDRESS(ARM_IDLECT2),
.enable_bit = EN_LCDCK,
@ -402,37 +355,35 @@ static struct arm_idlect1_clk lcd_ck_1510 = {
.idlect_shift = OMAP1510_IDLLCD_ARM_SHIFT,
};
/*
* XXX The enable_bit here is misused - it simply switches between 12MHz
* and 48MHz. Reimplement with clksel.
* and 48MHz. Reimplement with clk_mux.
*
* XXX does this need SYSC register handling?
*/
static struct clk uart1_1510 = {
.name = "uart1_ck",
.ops = &clkops_null,
static struct omap1_clk uart1_1510 = {
/* Direct from ULPD, no real parent */
.parent = &armper_ck.clk,
.rate = 12000000,
.hw.init = CLK_HW_INIT("uart1_ck", "armper_ck", &omap1_clk_full_ops, 0),
.flags = ENABLE_REG_32BIT | CLOCK_NO_IDLE_PARENT,
.enable_reg = OMAP1_IO_ADDRESS(MOD_CONF_CTRL_0),
.enable_bit = CONF_MOD_UART1_CLK_MODE_R,
.round_rate = &omap1_round_uart_rate,
.set_rate = &omap1_set_uart_rate,
.recalc = &omap1_uart_recalc,
};
/*
* XXX The enable_bit here is misused - it simply switches between 12MHz
* and 48MHz. Reimplement with clksel.
* and 48MHz. Reimplement with clk_mux.
*
* XXX SYSC register handling does not belong in the clock framework
*/
static struct uart_clk uart1_16xx = {
.clk = {
.name = "uart1_ck",
.ops = &clkops_uart_16xx,
/* Direct from ULPD, no real parent */
.parent = &armper_ck.clk,
.hw.init = CLK_HW_INIT("uart1_ck", "armper_ck", &omap1_clk_full_ops, 0),
.rate = 48000000,
.flags = ENABLE_REG_32BIT | CLOCK_NO_IDLE_PARENT,
.enable_reg = OMAP1_IO_ADDRESS(MOD_CONF_CTRL_0),
@ -443,54 +394,49 @@ static struct uart_clk uart1_16xx = {
/*
* XXX The enable_bit here is misused - it simply switches between 12MHz
* and 48MHz. Reimplement with clksel.
* and 48MHz. Reimplement with clk_mux.
*
* XXX does this need SYSC register handling?
*/
static struct clk uart2_ck = {
.name = "uart2_ck",
.ops = &clkops_null,
static struct omap1_clk uart2_ck = {
/* Direct from ULPD, no real parent */
.parent = &armper_ck.clk,
.rate = 12000000,
.hw.init = CLK_HW_INIT("uart2_ck", "armper_ck", &omap1_clk_full_ops, 0),
.flags = ENABLE_REG_32BIT | CLOCK_NO_IDLE_PARENT,
.enable_reg = OMAP1_IO_ADDRESS(MOD_CONF_CTRL_0),
.enable_bit = CONF_MOD_UART2_CLK_MODE_R,
.round_rate = &omap1_round_uart_rate,
.set_rate = &omap1_set_uart_rate,
.recalc = &omap1_uart_recalc,
};
/*
* XXX The enable_bit here is misused - it simply switches between 12MHz
* and 48MHz. Reimplement with clksel.
* and 48MHz. Reimplement with clk_mux.
*
* XXX does this need SYSC register handling?
*/
static struct clk uart3_1510 = {
.name = "uart3_ck",
.ops = &clkops_null,
static struct omap1_clk uart3_1510 = {
/* Direct from ULPD, no real parent */
.parent = &armper_ck.clk,
.rate = 12000000,
.hw.init = CLK_HW_INIT("uart3_ck", "armper_ck", &omap1_clk_full_ops, 0),
.flags = ENABLE_REG_32BIT | CLOCK_NO_IDLE_PARENT,
.enable_reg = OMAP1_IO_ADDRESS(MOD_CONF_CTRL_0),
.enable_bit = CONF_MOD_UART3_CLK_MODE_R,
.round_rate = &omap1_round_uart_rate,
.set_rate = &omap1_set_uart_rate,
.recalc = &omap1_uart_recalc,
};
/*
* XXX The enable_bit here is misused - it simply switches between 12MHz
* and 48MHz. Reimplement with clksel.
* and 48MHz. Reimplement with clk_mux.
*
* XXX SYSC register handling does not belong in the clock framework
*/
static struct uart_clk uart3_16xx = {
.clk = {
.name = "uart3_ck",
.ops = &clkops_uart_16xx,
/* Direct from ULPD, no real parent */
.parent = &armper_ck.clk,
.hw.init = CLK_HW_INIT("uart3_ck", "armper_ck", &omap1_clk_full_ops, 0),
.rate = 48000000,
.flags = ENABLE_REG_32BIT | CLOCK_NO_IDLE_PARENT,
.enable_reg = OMAP1_IO_ADDRESS(MOD_CONF_CTRL_0),
@ -499,30 +445,30 @@ static struct uart_clk uart3_16xx = {
.sysc_addr = 0xfffb9854,
};
static struct clk usb_clko = { /* 6 MHz output on W4_USB_CLKO */
.name = "usb_clko",
static struct omap1_clk usb_clko = { /* 6 MHz output on W4_USB_CLKO */
.ops = &clkops_generic,
/* Direct from ULPD, no parent */
.hw.init = CLK_HW_INIT_NO_PARENT("usb_clko", &omap1_clk_full_ops, 0),
.rate = 6000000,
.flags = ENABLE_REG_32BIT,
.enable_reg = OMAP1_IO_ADDRESS(ULPD_CLOCK_CTRL),
.enable_bit = USB_MCLK_EN_BIT,
};
static struct clk usb_hhc_ck1510 = {
.name = "usb_hhc_ck",
static struct omap1_clk usb_hhc_ck1510 = {
.ops = &clkops_generic,
/* Direct from ULPD, no parent */
.hw.init = CLK_HW_INIT_NO_PARENT("usb_hhc_ck", &omap1_clk_full_ops, 0),
.rate = 48000000, /* Actually 2 clocks, 12MHz and 48MHz */
.flags = ENABLE_REG_32BIT,
.enable_reg = OMAP1_IO_ADDRESS(MOD_CONF_CTRL_0),
.enable_bit = USB_HOST_HHC_UHOST_EN,
};
static struct clk usb_hhc_ck16xx = {
.name = "usb_hhc_ck",
static struct omap1_clk usb_hhc_ck16xx = {
.ops = &clkops_generic,
/* Direct from ULPD, no parent */
.hw.init = CLK_HW_INIT_NO_PARENT("usb_hhc_ck", &omap1_clk_full_ops, 0),
.rate = 48000000,
/* OTG_SYSCON_2.OTG_PADEN == 0 (not 1510-compatible) */
.flags = ENABLE_REG_32BIT,
@ -530,46 +476,46 @@ static struct clk usb_hhc_ck16xx = {
.enable_bit = OTG_SYSCON_2_UHOST_EN_SHIFT
};
static struct clk usb_dc_ck = {
.name = "usb_dc_ck",
static struct omap1_clk usb_dc_ck = {
.ops = &clkops_generic,
/* Direct from ULPD, no parent */
.hw.init = CLK_HW_INIT_NO_PARENT("usb_dc_ck", &omap1_clk_full_ops, 0),
.rate = 48000000,
.enable_reg = OMAP1_IO_ADDRESS(SOFT_REQ_REG),
.enable_bit = SOFT_USB_OTG_DPLL_REQ_SHIFT,
};
static struct clk uart1_7xx = {
.name = "uart1_ck",
static struct omap1_clk uart1_7xx = {
.ops = &clkops_generic,
/* Direct from ULPD, no parent */
.hw.init = CLK_HW_INIT_NO_PARENT("uart1_ck", &omap1_clk_full_ops, 0),
.rate = 12000000,
.enable_reg = OMAP1_IO_ADDRESS(SOFT_REQ_REG),
.enable_bit = 9,
};
static struct clk uart2_7xx = {
.name = "uart2_ck",
static struct omap1_clk uart2_7xx = {
.ops = &clkops_generic,
/* Direct from ULPD, no parent */
.hw.init = CLK_HW_INIT_NO_PARENT("uart2_ck", &omap1_clk_full_ops, 0),
.rate = 12000000,
.enable_reg = OMAP1_IO_ADDRESS(SOFT_REQ_REG),
.enable_bit = 11,
};
static struct clk mclk_1510 = {
.name = "mclk",
static struct omap1_clk mclk_1510 = {
.ops = &clkops_generic,
/* Direct from ULPD, no parent. May be enabled by ext hardware. */
.hw.init = CLK_HW_INIT_NO_PARENT("mclk", &omap1_clk_full_ops, 0),
.rate = 12000000,
.enable_reg = OMAP1_IO_ADDRESS(SOFT_REQ_REG),
.enable_bit = SOFT_COM_MCKO_REQ_SHIFT,
};
static struct clk mclk_16xx = {
.name = "mclk",
static struct omap1_clk mclk_16xx = {
.ops = &clkops_generic,
/* Direct from ULPD, no parent. May be enabled by ext hardware. */
.hw.init = CLK_HW_INIT_NO_PARENT("mclk", &omap1_clk_full_ops, 0),
.enable_reg = OMAP1_IO_ADDRESS(COM_CLK_DIV_CTRL_SEL),
.enable_bit = COM_ULPD_PLL_CLK_REQ,
.set_rate = &omap1_set_ext_clk_rate,
@ -577,17 +523,16 @@ static struct clk mclk_16xx = {
.init = &omap1_init_ext_clk,
};
static struct clk bclk_1510 = {
.name = "bclk",
.ops = &clkops_generic,
static struct omap1_clk bclk_1510 = {
/* Direct from ULPD, no parent. May be enabled by ext hardware. */
.hw.init = CLK_HW_INIT_NO_PARENT("bclk", &omap1_clk_rate_ops, 0),
.rate = 12000000,
};
static struct clk bclk_16xx = {
.name = "bclk",
static struct omap1_clk bclk_16xx = {
.ops = &clkops_generic,
/* Direct from ULPD, no parent. May be enabled by ext hardware. */
.hw.init = CLK_HW_INIT_NO_PARENT("bclk", &omap1_clk_full_ops, 0),
.enable_reg = OMAP1_IO_ADDRESS(SWD_CLK_DIV_CTRL_SEL),
.enable_bit = SWD_ULPD_PLL_CLK_REQ,
.set_rate = &omap1_set_ext_clk_rate,
@ -595,11 +540,10 @@ static struct clk bclk_16xx = {
.init = &omap1_init_ext_clk,
};
static struct clk mmc1_ck = {
.name = "mmc1_ck",
static struct omap1_clk mmc1_ck = {
.ops = &clkops_generic,
/* Functional clock is direct from ULPD, interface clock is ARMPER */
.parent = &armper_ck.clk,
.hw.init = CLK_HW_INIT("mmc1_ck", "armper_ck", &omap1_clk_full_ops, 0),
.rate = 48000000,
.flags = ENABLE_REG_32BIT | CLOCK_NO_IDLE_PARENT,
.enable_reg = OMAP1_IO_ADDRESS(MOD_CONF_CTRL_0),
@ -610,32 +554,29 @@ static struct clk mmc1_ck = {
* XXX MOD_CONF_CTRL_0 bit 20 is defined in the 1510 TRM as
* CONF_MOD_MCBSP3_AUXON ??
*/
static struct clk mmc2_ck = {
.name = "mmc2_ck",
static struct omap1_clk mmc2_ck = {
.ops = &clkops_generic,
/* Functional clock is direct from ULPD, interface clock is ARMPER */
.parent = &armper_ck.clk,
.hw.init = CLK_HW_INIT("mmc2_ck", "armper_ck", &omap1_clk_full_ops, 0),
.rate = 48000000,
.flags = ENABLE_REG_32BIT | CLOCK_NO_IDLE_PARENT,
.enable_reg = OMAP1_IO_ADDRESS(MOD_CONF_CTRL_0),
.enable_bit = 20,
};
static struct clk mmc3_ck = {
.name = "mmc3_ck",
static struct omap1_clk mmc3_ck = {
.ops = &clkops_generic,
/* Functional clock is direct from ULPD, interface clock is ARMPER */
.parent = &armper_ck.clk,
.hw.init = CLK_HW_INIT("mmc3_ck", "armper_ck", &omap1_clk_full_ops, 0),
.rate = 48000000,
.flags = ENABLE_REG_32BIT | CLOCK_NO_IDLE_PARENT,
.enable_reg = OMAP1_IO_ADDRESS(SOFT_REQ_REG),
.enable_bit = SOFT_MMC_DPLL_REQ_SHIFT,
};
static struct clk virtual_ck_mpu = {
.name = "mpu",
.ops = &clkops_null,
.parent = &arm_ck, /* Is smarter alias for */
static struct omap1_clk virtual_ck_mpu = {
/* Is smarter alias for arm_ck */
.hw.init = CLK_HW_INIT("mpu", "arm_ck", &omap1_clk_rate_ops, 0),
.recalc = &followparent_recalc,
.set_rate = &omap1_select_table_rate,
.round_rate = &omap1_round_to_table_rate,
@ -643,20 +584,14 @@ static struct clk virtual_ck_mpu = {
/* virtual functional clock domain for I2C. Just for making sure that ARMXOR_CK
remains active during MPU idle whenever this is enabled */
static struct clk i2c_fck = {
.name = "i2c_fck",
.ops = &clkops_null,
static struct omap1_clk i2c_fck = {
.hw.init = CLK_HW_INIT("i2c_fck", "armxor_ck", &omap1_clk_gate_ops, 0),
.flags = CLOCK_NO_IDLE_PARENT,
.parent = &armxor_ck.clk,
.recalc = &followparent_recalc,
};
static struct clk i2c_ick = {
.name = "i2c_ick",
.ops = &clkops_null,
static struct omap1_clk i2c_ick = {
.hw.init = CLK_HW_INIT("i2c_ick", "armper_ck", &omap1_clk_gate_ops, 0),
.flags = CLOCK_NO_IDLE_PARENT,
.parent = &armper_ck.clk,
.recalc = &followparent_recalc,
};
/*
@ -665,81 +600,81 @@ static struct clk i2c_ick = {
static struct omap_clk omap_clks[] = {
/* non-ULPD clocks */
CLK(NULL, "ck_ref", &ck_ref, CK_16XX | CK_1510 | CK_310 | CK_7XX),
CLK(NULL, "ck_dpll1", &ck_dpll1, CK_16XX | CK_1510 | CK_310 | CK_7XX),
CLK(NULL, "ck_ref", &ck_ref.hw, CK_16XX | CK_1510 | CK_310 | CK_7XX),
CLK(NULL, "ck_dpll1", &ck_dpll1.hw, CK_16XX | CK_1510 | CK_310 | CK_7XX),
/* CK_GEN1 clocks */
CLK(NULL, "ck_dpll1out", &ck_dpll1out.clk, CK_16XX),
CLK(NULL, "ck_sossi", &sossi_ck, CK_16XX),
CLK(NULL, "arm_ck", &arm_ck, CK_16XX | CK_1510 | CK_310),
CLK(NULL, "armper_ck", &armper_ck.clk, CK_16XX | CK_1510 | CK_310),
CLK("omap_gpio.0", "ick", &arm_gpio_ck, CK_1510 | CK_310),
CLK(NULL, "armxor_ck", &armxor_ck.clk, CK_16XX | CK_1510 | CK_310 | CK_7XX),
CLK(NULL, "armtim_ck", &armtim_ck.clk, CK_16XX | CK_1510 | CK_310),
CLK("omap_wdt", "fck", &armwdt_ck.clk, CK_16XX | CK_1510 | CK_310),
CLK("omap_wdt", "ick", &armper_ck.clk, CK_16XX),
CLK("omap_wdt", "ick", &dummy_ck, CK_1510 | CK_310),
CLK(NULL, "arminth_ck", &arminth_ck1510, CK_1510 | CK_310),
CLK(NULL, "arminth_ck", &arminth_ck16xx, CK_16XX),
CLK(NULL, "ck_dpll1out", &ck_dpll1out.clk.hw, CK_16XX),
CLK(NULL, "ck_sossi", &sossi_ck.hw, CK_16XX),
CLK(NULL, "arm_ck", &arm_ck.hw, CK_16XX | CK_1510 | CK_310),
CLK(NULL, "armper_ck", &armper_ck.clk.hw, CK_16XX | CK_1510 | CK_310),
CLK("omap_gpio.0", "ick", &arm_gpio_ck.hw, CK_1510 | CK_310),
CLK(NULL, "armxor_ck", &armxor_ck.clk.hw, CK_16XX | CK_1510 | CK_310 | CK_7XX),
CLK(NULL, "armtim_ck", &armtim_ck.clk.hw, CK_16XX | CK_1510 | CK_310),
CLK("omap_wdt", "fck", &armwdt_ck.clk.hw, CK_16XX | CK_1510 | CK_310),
CLK("omap_wdt", "ick", &armper_ck.clk.hw, CK_16XX),
CLK("omap_wdt", "ick", &dummy_ck.hw, CK_1510 | CK_310),
CLK(NULL, "arminth_ck", &arminth_ck1510.hw, CK_1510 | CK_310),
CLK(NULL, "arminth_ck", &arminth_ck16xx.hw, CK_16XX),
/* CK_GEN2 clocks */
CLK(NULL, "dsp_ck", &dsp_ck, CK_16XX | CK_1510 | CK_310),
CLK(NULL, "dspmmu_ck", &dspmmu_ck, CK_16XX | CK_1510 | CK_310),
CLK(NULL, "dspper_ck", &dspper_ck, CK_16XX | CK_1510 | CK_310),
CLK(NULL, "dspxor_ck", &dspxor_ck, CK_16XX | CK_1510 | CK_310),
CLK(NULL, "dsptim_ck", &dsptim_ck, CK_16XX | CK_1510 | CK_310),
CLK(NULL, "dsp_ck", &dsp_ck.hw, CK_16XX | CK_1510 | CK_310),
CLK(NULL, "dspmmu_ck", &dspmmu_ck.hw, CK_16XX | CK_1510 | CK_310),
CLK(NULL, "dspper_ck", &dspper_ck.hw, CK_16XX | CK_1510 | CK_310),
CLK(NULL, "dspxor_ck", &dspxor_ck.hw, CK_16XX | CK_1510 | CK_310),
CLK(NULL, "dsptim_ck", &dsptim_ck.hw, CK_16XX | CK_1510 | CK_310),
/* CK_GEN3 clocks */
CLK(NULL, "tc_ck", &tc_ck.clk, CK_16XX | CK_1510 | CK_310 | CK_7XX),
CLK(NULL, "tipb_ck", &tipb_ck, CK_1510 | CK_310),
CLK(NULL, "l3_ocpi_ck", &l3_ocpi_ck, CK_16XX | CK_7XX),
CLK(NULL, "tc1_ck", &tc1_ck, CK_16XX),
CLK(NULL, "tc2_ck", &tc2_ck, CK_16XX),
CLK(NULL, "dma_ck", &dma_ck, CK_16XX | CK_1510 | CK_310),
CLK(NULL, "dma_lcdfree_ck", &dma_lcdfree_ck, CK_16XX),
CLK(NULL, "api_ck", &api_ck.clk, CK_16XX | CK_1510 | CK_310 | CK_7XX),
CLK(NULL, "lb_ck", &lb_ck.clk, CK_1510 | CK_310),
CLK(NULL, "rhea1_ck", &rhea1_ck, CK_16XX),
CLK(NULL, "rhea2_ck", &rhea2_ck, CK_16XX),
CLK(NULL, "lcd_ck", &lcd_ck_16xx, CK_16XX | CK_7XX),
CLK(NULL, "lcd_ck", &lcd_ck_1510.clk, CK_1510 | CK_310),
CLK(NULL, "tc_ck", &tc_ck.clk.hw, CK_16XX | CK_1510 | CK_310 | CK_7XX),
CLK(NULL, "tipb_ck", &tipb_ck.hw, CK_1510 | CK_310),
CLK(NULL, "l3_ocpi_ck", &l3_ocpi_ck.hw, CK_16XX | CK_7XX),
CLK(NULL, "tc1_ck", &tc1_ck.hw, CK_16XX),
CLK(NULL, "tc2_ck", &tc2_ck.hw, CK_16XX),
CLK(NULL, "dma_ck", &dma_ck.hw, CK_16XX | CK_1510 | CK_310),
CLK(NULL, "dma_lcdfree_ck", &dma_lcdfree_ck.hw, CK_16XX),
CLK(NULL, "api_ck", &api_ck.clk.hw, CK_16XX | CK_1510 | CK_310 | CK_7XX),
CLK(NULL, "lb_ck", &lb_ck.clk.hw, CK_1510 | CK_310),
CLK(NULL, "rhea1_ck", &rhea1_ck.hw, CK_16XX),
CLK(NULL, "rhea2_ck", &rhea2_ck.hw, CK_16XX),
CLK(NULL, "lcd_ck", &lcd_ck_16xx.hw, CK_16XX | CK_7XX),
CLK(NULL, "lcd_ck", &lcd_ck_1510.clk.hw, CK_1510 | CK_310),
/* ULPD clocks */
CLK(NULL, "uart1_ck", &uart1_1510, CK_1510 | CK_310),
CLK(NULL, "uart1_ck", &uart1_16xx.clk, CK_16XX),
CLK(NULL, "uart1_ck", &uart1_7xx, CK_7XX),
CLK(NULL, "uart2_ck", &uart2_ck, CK_16XX | CK_1510 | CK_310),
CLK(NULL, "uart2_ck", &uart2_7xx, CK_7XX),
CLK(NULL, "uart3_ck", &uart3_1510, CK_1510 | CK_310),
CLK(NULL, "uart3_ck", &uart3_16xx.clk, CK_16XX),
CLK(NULL, "usb_clko", &usb_clko, CK_16XX | CK_1510 | CK_310),
CLK(NULL, "usb_hhc_ck", &usb_hhc_ck1510, CK_1510 | CK_310),
CLK(NULL, "usb_hhc_ck", &usb_hhc_ck16xx, CK_16XX),
CLK(NULL, "usb_dc_ck", &usb_dc_ck, CK_16XX | CK_7XX),
CLK(NULL, "mclk", &mclk_1510, CK_1510 | CK_310),
CLK(NULL, "mclk", &mclk_16xx, CK_16XX),
CLK(NULL, "bclk", &bclk_1510, CK_1510 | CK_310),
CLK(NULL, "bclk", &bclk_16xx, CK_16XX),
CLK("mmci-omap.0", "fck", &mmc1_ck, CK_16XX | CK_1510 | CK_310),
CLK("mmci-omap.0", "fck", &mmc3_ck, CK_7XX),
CLK("mmci-omap.0", "ick", &armper_ck.clk, CK_16XX | CK_1510 | CK_310 | CK_7XX),
CLK("mmci-omap.1", "fck", &mmc2_ck, CK_16XX),
CLK("mmci-omap.1", "ick", &armper_ck.clk, CK_16XX),
CLK(NULL, "uart1_ck", &uart1_1510.hw, CK_1510 | CK_310),
CLK(NULL, "uart1_ck", &uart1_16xx.clk.hw, CK_16XX),
CLK(NULL, "uart1_ck", &uart1_7xx.hw, CK_7XX),
CLK(NULL, "uart2_ck", &uart2_ck.hw, CK_16XX | CK_1510 | CK_310),
CLK(NULL, "uart2_ck", &uart2_7xx.hw, CK_7XX),
CLK(NULL, "uart3_ck", &uart3_1510.hw, CK_1510 | CK_310),
CLK(NULL, "uart3_ck", &uart3_16xx.clk.hw, CK_16XX),
CLK(NULL, "usb_clko", &usb_clko.hw, CK_16XX | CK_1510 | CK_310),
CLK(NULL, "usb_hhc_ck", &usb_hhc_ck1510.hw, CK_1510 | CK_310),
CLK(NULL, "usb_hhc_ck", &usb_hhc_ck16xx.hw, CK_16XX),
CLK(NULL, "usb_dc_ck", &usb_dc_ck.hw, CK_16XX | CK_7XX),
CLK(NULL, "mclk", &mclk_1510.hw, CK_1510 | CK_310),
CLK(NULL, "mclk", &mclk_16xx.hw, CK_16XX),
CLK(NULL, "bclk", &bclk_1510.hw, CK_1510 | CK_310),
CLK(NULL, "bclk", &bclk_16xx.hw, CK_16XX),
CLK("mmci-omap.0", "fck", &mmc1_ck.hw, CK_16XX | CK_1510 | CK_310),
CLK("mmci-omap.0", "fck", &mmc3_ck.hw, CK_7XX),
CLK("mmci-omap.0", "ick", &armper_ck.clk.hw, CK_16XX | CK_1510 | CK_310 | CK_7XX),
CLK("mmci-omap.1", "fck", &mmc2_ck.hw, CK_16XX),
CLK("mmci-omap.1", "ick", &armper_ck.clk.hw, CK_16XX),
/* Virtual clocks */
CLK(NULL, "mpu", &virtual_ck_mpu, CK_16XX | CK_1510 | CK_310),
CLK("omap_i2c.1", "fck", &i2c_fck, CK_16XX | CK_1510 | CK_310 | CK_7XX),
CLK("omap_i2c.1", "ick", &i2c_ick, CK_16XX),
CLK("omap_i2c.1", "ick", &dummy_ck, CK_1510 | CK_310 | CK_7XX),
CLK("omap1_spi100k.1", "fck", &dummy_ck, CK_7XX),
CLK("omap1_spi100k.1", "ick", &dummy_ck, CK_7XX),
CLK("omap1_spi100k.2", "fck", &dummy_ck, CK_7XX),
CLK("omap1_spi100k.2", "ick", &dummy_ck, CK_7XX),
CLK("omap_uwire", "fck", &armxor_ck.clk, CK_16XX | CK_1510 | CK_310),
CLK("omap-mcbsp.1", "ick", &dspper_ck, CK_16XX),
CLK("omap-mcbsp.1", "ick", &dummy_ck, CK_1510 | CK_310),
CLK("omap-mcbsp.2", "ick", &armper_ck.clk, CK_16XX),
CLK("omap-mcbsp.2", "ick", &dummy_ck, CK_1510 | CK_310),
CLK("omap-mcbsp.3", "ick", &dspper_ck, CK_16XX),
CLK("omap-mcbsp.3", "ick", &dummy_ck, CK_1510 | CK_310),
CLK("omap-mcbsp.1", "fck", &dspxor_ck, CK_16XX | CK_1510 | CK_310),
CLK("omap-mcbsp.2", "fck", &armper_ck.clk, CK_16XX | CK_1510 | CK_310),
CLK("omap-mcbsp.3", "fck", &dspxor_ck, CK_16XX | CK_1510 | CK_310),
CLK(NULL, "mpu", &virtual_ck_mpu.hw, CK_16XX | CK_1510 | CK_310),
CLK("omap_i2c.1", "fck", &i2c_fck.hw, CK_16XX | CK_1510 | CK_310 | CK_7XX),
CLK("omap_i2c.1", "ick", &i2c_ick.hw, CK_16XX),
CLK("omap_i2c.1", "ick", &dummy_ck.hw, CK_1510 | CK_310 | CK_7XX),
CLK("omap1_spi100k.1", "fck", &dummy_ck.hw, CK_7XX),
CLK("omap1_spi100k.1", "ick", &dummy_ck.hw, CK_7XX),
CLK("omap1_spi100k.2", "fck", &dummy_ck.hw, CK_7XX),
CLK("omap1_spi100k.2", "ick", &dummy_ck.hw, CK_7XX),
CLK("omap_uwire", "fck", &armxor_ck.clk.hw, CK_16XX | CK_1510 | CK_310),
CLK("omap-mcbsp.1", "ick", &dspper_ck.hw, CK_16XX),
CLK("omap-mcbsp.1", "ick", &dummy_ck.hw, CK_1510 | CK_310),
CLK("omap-mcbsp.2", "ick", &armper_ck.clk.hw, CK_16XX),
CLK("omap-mcbsp.2", "ick", &dummy_ck.hw, CK_1510 | CK_310),
CLK("omap-mcbsp.3", "ick", &dspper_ck.hw, CK_16XX),
CLK("omap-mcbsp.3", "ick", &dummy_ck.hw, CK_1510 | CK_310),
CLK("omap-mcbsp.1", "fck", &dspxor_ck.hw, CK_16XX | CK_1510 | CK_310),
CLK("omap-mcbsp.2", "fck", &armper_ck.clk.hw, CK_16XX | CK_1510 | CK_310),
CLK("omap-mcbsp.3", "fck", &dspxor_ck.hw, CK_16XX | CK_1510 | CK_310),
};
/*
@ -778,9 +713,6 @@ int __init omap1_clk_init(void)
/* By default all idlect1 clocks are allowed to idle */
arm_idlect1_mask = ~0;
for (c = omap_clks; c < omap_clks + ARRAY_SIZE(omap_clks); c++)
clk_preinit(c->lk.clk);
cpu_mask = 0;
if (cpu_is_omap1710())
cpu_mask |= CK_1710;
@ -793,16 +725,10 @@ int __init omap1_clk_init(void)
if (cpu_is_omap310())
cpu_mask |= CK_310;
for (c = omap_clks; c < omap_clks + ARRAY_SIZE(omap_clks); c++)
if (c->cpu & cpu_mask) {
clkdev_add(&c->lk);
clk_register(c->lk.clk);
}
/* Pointers to these clocks are needed by code in clock.c */
api_ck_p = clk_get(NULL, "api_ck");
ck_dpll1_p = clk_get(NULL, "ck_dpll1");
ck_ref_p = clk_get(NULL, "ck_ref");
api_ck_p = &api_ck.clk;
ck_dpll1_p = &ck_dpll1;
ck_ref_p = &ck_ref;
if (cpu_is_omap7xx())
ck_ref.rate = 13000000;
@ -844,10 +770,7 @@ int __init omap1_clk_init(void)
}
}
}
propagate_rate(&ck_dpll1);
/* Cache rates for clocks connected to ck_ref (not dpll1) */
propagate_rate(&ck_ref);
omap1_show_rates();
if (machine_is_omap_perseus2() || machine_is_omap_fsample()) {
/* Select slicer output as OMAP input clock */
omap_writew(omap_readw(OMAP7XX_PCC_UPLD_CTRL) & ~0x1,
@ -879,16 +802,28 @@ int __init omap1_clk_init(void)
*/
omap_writew(0x0000, ARM_IDLECT2); /* Turn LCD clock off also */
/*
* Only enable those clocks we will need, let the drivers
* enable other clocks as necessary
*/
clk_enable(&armper_ck.clk);
clk_enable(&armxor_ck.clk);
clk_enable(&armtim_ck.clk); /* This should be done by timer code */
for (c = omap_clks; c < omap_clks + ARRAY_SIZE(omap_clks); c++) {
if (!(c->cpu & cpu_mask))
continue;
if (cpu_is_omap15xx())
clk_enable(&arm_gpio_ck);
if (c->lk.clk_hw->init) { /* NULL if provider already registered */
const struct clk_init_data *init = c->lk.clk_hw->init;
const char *name = c->lk.clk_hw->init->name;
int err;
err = clk_hw_register(NULL, c->lk.clk_hw);
if (err < 0) {
pr_err("failed to register clock \"%s\"! (%d)\n", name, err);
/* may be tried again, restore init data */
c->lk.clk_hw->init = init;
continue;
}
}
clk_hw_register_clkdev(c->lk.clk_hw, c->lk.con_id, c->lk.dev_id);
}
omap1_show_rates();
return 0;
}
@ -900,7 +835,7 @@ void __init omap1_clk_late_init(void)
unsigned long rate = ck_dpll1.rate;
/* Find the highest supported frequency and enable it */
if (omap1_select_table_rate(&virtual_ck_mpu, ~0)) {
if (omap1_select_table_rate(&virtual_ck_mpu, ~0, arm_ck.rate)) {
pr_err("System frequencies not set, using default. Check your config.\n");
/*
* Reprogramming the DPLL is tricky, it must be done from SRAM.

View File

@ -15,10 +15,8 @@
#include <asm/mach/map.h>
#include "tc.h"
#include "mux.h"
#include "iomap.h"
#include "common.h"
#include "clock.h"
/*
* The machine specific code may provide the extra mapping besides the
@ -125,11 +123,6 @@ void __init omap1_init_early(void)
*/
omap_writew(0x0, MPU_PUBLIC_TIPB_CNTL);
omap_writew(0x0, MPU_PRIVATE_TIPB_CNTL);
/* Must init clocks early to assure that timer interrupt works
*/
omap1_clk_init();
omap1_mux_init();
}
void __init omap1_init_late(void)

View File

@ -51,8 +51,10 @@
#include <asm/mach/time.h>
#include "hardware.h"
#include "mux.h"
#include "iomap.h"
#include "common.h"
#include "clock.h"
#ifdef CONFIG_OMAP_MPU_TIMER
@ -224,6 +226,9 @@ static inline void omap_mpu_timer_init(void)
*/
void __init omap1_timer_init(void)
{
omap1_clk_init();
omap1_mux_init();
if (omap_32k_timer_init() != 0)
omap_mpu_timer_init();
}