Commit 9af13088 authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'arm-multiplatform-5.19-3' of git://git.kernel.org/pub/scm/linux/kernel/git/soc/soc

Pull yet more ARM multiplatform updates from Arnd Bergmann:
 "This is the third and final bit of the multiplatform conversion for
  ARMv5, finishing off OMAP1. One patch enables the common-clk
  interface, and the other ones does the Kconfig change.

  These were waiting on a few dependencies to trickle in for common-clk,
  and the last one of those was in the USB tree"

* tag 'arm-multiplatform-5.19-3' of git://git.kernel.org/pub/scm/linux/kernel/git/soc/soc:
  ARM: omap1: enable multiplatform
  ARM: OMAP1: clock: Convert to CCF
parents c6f2f3e2 7036440e
...@@ -396,19 +396,6 @@ config ARCH_SA1100 ...@@ -396,19 +396,6 @@ config ARCH_SA1100
help help
Support for StrongARM 11x0 based boards. Support for StrongARM 11x0 based boards.
config ARCH_OMAP1
bool "TI OMAP1"
depends on CPU_LITTLE_ENDIAN
select CLKSRC_MMIO
select FORCE_PCI if PCCARD
select GENERIC_IRQ_CHIP
select GPIOLIB
select HAVE_LEGACY_CLK
select IRQ_DOMAIN
select SPARSE_IRQ
help
Support for older TI OMAP1 (omap7xx, omap15xx or omap16xx)
endchoice endchoice
menu "Multiple platform selection" menu "Multiple platform selection"
......
...@@ -17,6 +17,9 @@ CONFIG_MODULES=y ...@@ -17,6 +17,9 @@ CONFIG_MODULES=y
CONFIG_MODULE_UNLOAD=y CONFIG_MODULE_UNLOAD=y
CONFIG_MODULE_FORCE_UNLOAD=y CONFIG_MODULE_FORCE_UNLOAD=y
# CONFIG_BLK_DEV_BSG is not set # CONFIG_BLK_DEV_BSG is not set
CONFIG_ARCH_MULTI_V4T=y
CONFIG_ARCH_MULTI_V5=y
# CONFIG_ARCH_MULTI_V7 is not set
CONFIG_ARCH_OMAP=y CONFIG_ARCH_OMAP=y
CONFIG_ARCH_OMAP1=y CONFIG_ARCH_OMAP1=y
CONFIG_OMAP_RESET_CLOCKS=y CONFIG_OMAP_RESET_CLOCKS=y
......
# SPDX-License-Identifier: GPL-2.0-only # SPDX-License-Identifier: GPL-2.0-only
menuconfig ARCH_OMAP1
bool "TI OMAP1"
depends on ARCH_MULTI_V4T || ARCH_MULTI_V5
depends on CPU_LITTLE_ENDIAN
select ARCH_HAS_HOLES_MEMORYMODEL
select ARCH_OMAP
select CLKSRC_MMIO
select FORCE_PCI if PCCARD
select GPIOLIB
help
Support for older TI OMAP1 (omap7xx, omap15xx or omap16xx)
if ARCH_OMAP1 if ARCH_OMAP1
menu "TI OMAP1 specific features" menu "TI OMAP1 specific features"
...@@ -6,23 +18,27 @@ menu "TI OMAP1 specific features" ...@@ -6,23 +18,27 @@ menu "TI OMAP1 specific features"
comment "OMAP Core Type" comment "OMAP Core Type"
config ARCH_OMAP730 config ARCH_OMAP730
depends on ARCH_MULTI_V5
bool "OMAP730 Based System" bool "OMAP730 Based System"
select ARCH_OMAP_OTG select ARCH_OMAP_OTG
select CPU_ARM926T select CPU_ARM926T
select OMAP_MPU_TIMER select OMAP_MPU_TIMER
config ARCH_OMAP850 config ARCH_OMAP850
depends on ARCH_MULTI_V5
bool "OMAP850 Based System" bool "OMAP850 Based System"
select ARCH_OMAP_OTG select ARCH_OMAP_OTG
select CPU_ARM926T select CPU_ARM926T
config ARCH_OMAP15XX config ARCH_OMAP15XX
depends on ARCH_MULTI_V4T
default y default y
bool "OMAP15xx Based System" bool "OMAP15xx Based System"
select CPU_ARM925T select CPU_ARM925T
select OMAP_MPU_TIMER select OMAP_MPU_TIMER
config ARCH_OMAP16XX config ARCH_OMAP16XX
depends on ARCH_MULTI_V5
bool "OMAP16xx Based System" bool "OMAP16xx Based System"
select ARCH_OMAP_OTG select ARCH_OMAP_OTG
select CPU_ARM926T select CPU_ARM926T
......
...@@ -16,7 +16,9 @@ ...@@ -16,7 +16,9 @@
#include <linux/io.h> #include <linux/io.h>
#include <linux/clk.h> #include <linux/clk.h>
#include <linux/clkdev.h> #include <linux/clkdev.h>
#include <linux/clk-provider.h>
#include <linux/soc/ti/omap1-io.h> #include <linux/soc/ti/omap1-io.h>
#include <linux/spinlock.h>
#include <asm/mach-types.h> #include <asm/mach-types.h>
...@@ -28,33 +30,37 @@ ...@@ -28,33 +30,37 @@
#include "sram.h" #include "sram.h"
__u32 arm_idlect1_mask; __u32 arm_idlect1_mask;
struct clk *api_ck_p, *ck_dpll1_p, *ck_ref_p; /* provide direct internal access (not via clk API) to some clocks */
struct omap1_clk *api_ck_p, *ck_dpll1_p, *ck_ref_p;
static LIST_HEAD(clocks); /* protect registeres shared among clk_enable/disable() and clk_set_rate() operations */
static DEFINE_MUTEX(clocks_mutex); static DEFINE_SPINLOCK(arm_ckctl_lock);
static DEFINE_SPINLOCK(clockfw_lock); static DEFINE_SPINLOCK(arm_idlect2_lock);
static DEFINE_SPINLOCK(mod_conf_ctrl_0_lock);
static DEFINE_SPINLOCK(mod_conf_ctrl_1_lock);
static DEFINE_SPINLOCK(swd_clk_div_ctrl_sel_lock);
/* /*
* Omap1 specific clock functions * Omap1 specific clock functions
*/ */
unsigned long omap1_uart_recalc(struct clk *clk) unsigned long omap1_uart_recalc(struct omap1_clk *clk, unsigned long p_rate)
{ {
unsigned int val = __raw_readl(clk->enable_reg); unsigned int val = __raw_readl(clk->enable_reg);
return val & 1 << clk->enable_bit ? 48000000 : 12000000; return val & 1 << clk->enable_bit ? 48000000 : 12000000;
} }
unsigned long omap1_sossi_recalc(struct clk *clk) unsigned long omap1_sossi_recalc(struct omap1_clk *clk, unsigned long p_rate)
{ {
u32 div = omap_readl(MOD_CONF_CTRL_1); u32 div = omap_readl(MOD_CONF_CTRL_1);
div = (div >> 17) & 0x7; div = (div >> 17) & 0x7;
div++; div++;
return clk->parent->rate / div; return p_rate / div;
} }
static void omap1_clk_allow_idle(struct clk *clk) static void omap1_clk_allow_idle(struct omap1_clk *clk)
{ {
struct arm_idlect1_clk * iclk = (struct arm_idlect1_clk *)clk; struct arm_idlect1_clk * iclk = (struct arm_idlect1_clk *)clk;
...@@ -65,7 +71,7 @@ static void omap1_clk_allow_idle(struct clk *clk) ...@@ -65,7 +71,7 @@ static void omap1_clk_allow_idle(struct clk *clk)
arm_idlect1_mask |= 1 << iclk->idlect_shift; arm_idlect1_mask |= 1 << iclk->idlect_shift;
} }
static void omap1_clk_deny_idle(struct clk *clk) static void omap1_clk_deny_idle(struct omap1_clk *clk)
{ {
struct arm_idlect1_clk * iclk = (struct arm_idlect1_clk *)clk; struct arm_idlect1_clk * iclk = (struct arm_idlect1_clk *)clk;
...@@ -129,7 +135,7 @@ static __u16 verify_ckctl_value(__u16 newval) ...@@ -129,7 +135,7 @@ static __u16 verify_ckctl_value(__u16 newval)
return newval; return newval;
} }
static int calc_dsor_exp(struct clk *clk, unsigned long rate) static int calc_dsor_exp(unsigned long rate, unsigned long realrate)
{ {
/* Note: If target frequency is too low, this function will return 4, /* Note: If target frequency is too low, this function will return 4,
* which is invalid value. Caller must check for this value and act * which is invalid value. Caller must check for this value and act
...@@ -142,15 +148,11 @@ static int calc_dsor_exp(struct clk *clk, unsigned long rate) ...@@ -142,15 +148,11 @@ static int calc_dsor_exp(struct clk *clk, unsigned long rate)
* DSP_CK >= TC_CK * DSP_CK >= TC_CK
* DSPMMU_CK >= TC_CK * DSPMMU_CK >= TC_CK
*/ */
unsigned long realrate;
struct clk * parent;
unsigned dsor_exp; unsigned dsor_exp;
parent = clk->parent; if (unlikely(realrate == 0))
if (unlikely(parent == NULL))
return -EIO; return -EIO;
realrate = parent->rate;
for (dsor_exp=0; dsor_exp<4; dsor_exp++) { for (dsor_exp=0; dsor_exp<4; dsor_exp++) {
if (realrate <= rate) if (realrate <= rate)
break; break;
...@@ -161,16 +163,50 @@ static int calc_dsor_exp(struct clk *clk, unsigned long rate) ...@@ -161,16 +163,50 @@ static int calc_dsor_exp(struct clk *clk, unsigned long rate)
return dsor_exp; return dsor_exp;
} }
unsigned long omap1_ckctl_recalc(struct clk *clk) unsigned long omap1_ckctl_recalc(struct omap1_clk *clk, unsigned long p_rate)
{ {
/* Calculate divisor encoded as 2-bit exponent */ /* Calculate divisor encoded as 2-bit exponent */
int dsor = 1 << (3 & (omap_readw(ARM_CKCTL) >> clk->rate_offset)); int dsor = 1 << (3 & (omap_readw(ARM_CKCTL) >> clk->rate_offset));
return clk->parent->rate / dsor; /* update locally maintained rate, required by arm_ck for omap1_show_rates() */
clk->rate = p_rate / dsor;
return clk->rate;
} }
unsigned long omap1_ckctl_recalc_dsp_domain(struct clk *clk) static int omap1_clk_is_enabled(struct clk_hw *hw)
{ {
struct omap1_clk *clk = to_omap1_clk(hw);
bool api_ck_was_enabled = true;
__u32 regval32;
int ret;
if (!clk->ops) /* no gate -- always enabled */
return 1;
if (clk->ops == &clkops_dspck) {
api_ck_was_enabled = omap1_clk_is_enabled(&api_ck_p->hw);
if (!api_ck_was_enabled)
if (api_ck_p->ops->enable(api_ck_p) < 0)
return 0;
}
if (clk->flags & ENABLE_REG_32BIT)
regval32 = __raw_readl(clk->enable_reg);
else
regval32 = __raw_readw(clk->enable_reg);
ret = regval32 & (1 << clk->enable_bit);
if (!api_ck_was_enabled)
api_ck_p->ops->disable(api_ck_p);
return ret;
}
unsigned long omap1_ckctl_recalc_dsp_domain(struct omap1_clk *clk, unsigned long p_rate)
{
bool api_ck_was_enabled;
int dsor; int dsor;
/* Calculate divisor encoded as 2-bit exponent /* Calculate divisor encoded as 2-bit exponent
...@@ -180,15 +216,18 @@ unsigned long omap1_ckctl_recalc_dsp_domain(struct clk *clk) ...@@ -180,15 +216,18 @@ unsigned long omap1_ckctl_recalc_dsp_domain(struct clk *clk)
* Note that DSP_CKCTL virt addr = phys addr, so * Note that DSP_CKCTL virt addr = phys addr, so
* we must use __raw_readw() instead of omap_readw(). * we must use __raw_readw() instead of omap_readw().
*/ */
omap1_clk_enable(api_ck_p); api_ck_was_enabled = omap1_clk_is_enabled(&api_ck_p->hw);
if (!api_ck_was_enabled)
api_ck_p->ops->enable(api_ck_p);
dsor = 1 << (3 & (__raw_readw(DSP_CKCTL) >> clk->rate_offset)); dsor = 1 << (3 & (__raw_readw(DSP_CKCTL) >> clk->rate_offset));
omap1_clk_disable(api_ck_p); if (!api_ck_was_enabled)
api_ck_p->ops->disable(api_ck_p);
return clk->parent->rate / dsor; return p_rate / dsor;
} }
/* MPU virtual clock functions */ /* MPU virtual clock functions */
int omap1_select_table_rate(struct clk *clk, unsigned long rate) int omap1_select_table_rate(struct omap1_clk *clk, unsigned long rate, unsigned long p_rate)
{ {
/* Find the highest supported frequency <= rate and switch to it */ /* Find the highest supported frequency <= rate and switch to it */
struct mpu_rate * ptr; struct mpu_rate * ptr;
...@@ -223,12 +262,12 @@ int omap1_select_table_rate(struct clk *clk, unsigned long rate) ...@@ -223,12 +262,12 @@ int omap1_select_table_rate(struct clk *clk, unsigned long rate)
return 0; return 0;
} }
int omap1_clk_set_rate_dsp_domain(struct clk *clk, unsigned long rate) int omap1_clk_set_rate_dsp_domain(struct omap1_clk *clk, unsigned long rate, unsigned long p_rate)
{ {
int dsor_exp; int dsor_exp;
u16 regval; u16 regval;
dsor_exp = calc_dsor_exp(clk, rate); dsor_exp = calc_dsor_exp(rate, p_rate);
if (dsor_exp > 3) if (dsor_exp > 3)
dsor_exp = -EINVAL; dsor_exp = -EINVAL;
if (dsor_exp < 0) if (dsor_exp < 0)
...@@ -238,42 +277,51 @@ int omap1_clk_set_rate_dsp_domain(struct clk *clk, unsigned long rate) ...@@ -238,42 +277,51 @@ int omap1_clk_set_rate_dsp_domain(struct clk *clk, unsigned long rate)
regval &= ~(3 << clk->rate_offset); regval &= ~(3 << clk->rate_offset);
regval |= dsor_exp << clk->rate_offset; regval |= dsor_exp << clk->rate_offset;
__raw_writew(regval, DSP_CKCTL); __raw_writew(regval, DSP_CKCTL);
clk->rate = clk->parent->rate / (1 << dsor_exp); clk->rate = p_rate / (1 << dsor_exp);
return 0; return 0;
} }
long omap1_clk_round_rate_ckctl_arm(struct clk *clk, unsigned long rate) long omap1_clk_round_rate_ckctl_arm(struct omap1_clk *clk, unsigned long rate,
unsigned long *p_rate)
{ {
int dsor_exp = calc_dsor_exp(clk, rate); int dsor_exp = calc_dsor_exp(rate, *p_rate);
if (dsor_exp < 0) if (dsor_exp < 0)
return dsor_exp; return dsor_exp;
if (dsor_exp > 3) if (dsor_exp > 3)
dsor_exp = 3; dsor_exp = 3;
return clk->parent->rate / (1 << dsor_exp); return *p_rate / (1 << dsor_exp);
} }
int omap1_clk_set_rate_ckctl_arm(struct clk *clk, unsigned long rate) int omap1_clk_set_rate_ckctl_arm(struct omap1_clk *clk, unsigned long rate, unsigned long p_rate)
{ {
unsigned long flags;
int dsor_exp; int dsor_exp;
u16 regval; u16 regval;
dsor_exp = calc_dsor_exp(clk, rate); dsor_exp = calc_dsor_exp(rate, p_rate);
if (dsor_exp > 3) if (dsor_exp > 3)
dsor_exp = -EINVAL; dsor_exp = -EINVAL;
if (dsor_exp < 0) if (dsor_exp < 0)
return dsor_exp; return dsor_exp;
/* protect ARM_CKCTL register from concurrent access via clk_enable/disable() */
spin_lock_irqsave(&arm_ckctl_lock, flags);
regval = omap_readw(ARM_CKCTL); regval = omap_readw(ARM_CKCTL);
regval &= ~(3 << clk->rate_offset); regval &= ~(3 << clk->rate_offset);
regval |= dsor_exp << clk->rate_offset; regval |= dsor_exp << clk->rate_offset;
regval = verify_ckctl_value(regval); regval = verify_ckctl_value(regval);
omap_writew(regval, ARM_CKCTL); omap_writew(regval, ARM_CKCTL);
clk->rate = clk->parent->rate / (1 << dsor_exp); clk->rate = p_rate / (1 << dsor_exp);
spin_unlock_irqrestore(&arm_ckctl_lock, flags);
return 0; return 0;
} }
long omap1_round_to_table_rate(struct clk *clk, unsigned long rate) long omap1_round_to_table_rate(struct omap1_clk *clk, unsigned long rate, unsigned long *p_rate)
{ {
/* Find the highest supported frequency <= rate */ /* Find the highest supported frequency <= rate */
struct mpu_rate * ptr; struct mpu_rate * ptr;
...@@ -324,26 +372,40 @@ static unsigned calc_ext_dsor(unsigned long rate) ...@@ -324,26 +372,40 @@ static unsigned calc_ext_dsor(unsigned long rate)
} }
/* XXX Only needed on 1510 */ /* XXX Only needed on 1510 */
int omap1_set_uart_rate(struct clk *clk, unsigned long rate) long omap1_round_uart_rate(struct omap1_clk *clk, unsigned long rate, unsigned long *p_rate)
{ {
return rate > 24000000 ? 48000000 : 12000000;
}
int omap1_set_uart_rate(struct omap1_clk *clk, unsigned long rate, unsigned long p_rate)
{
unsigned long flags;
unsigned int val; unsigned int val;
val = __raw_readl(clk->enable_reg);
if (rate == 12000000) if (rate == 12000000)
val &= ~(1 << clk->enable_bit); val = 0;
else if (rate == 48000000) else if (rate == 48000000)
val |= (1 << clk->enable_bit); val = 1 << clk->enable_bit;
else else
return -EINVAL; return -EINVAL;
/* protect MOD_CONF_CTRL_0 register from concurrent access via clk_enable/disable() */
spin_lock_irqsave(&mod_conf_ctrl_0_lock, flags);
val |= __raw_readl(clk->enable_reg) & ~(1 << clk->enable_bit);
__raw_writel(val, clk->enable_reg); __raw_writel(val, clk->enable_reg);
spin_unlock_irqrestore(&mod_conf_ctrl_0_lock, flags);
clk->rate = rate; clk->rate = rate;
return 0; return 0;
} }
/* External clock (MCLK & BCLK) functions */ /* External clock (MCLK & BCLK) functions */
int omap1_set_ext_clk_rate(struct clk *clk, unsigned long rate) int omap1_set_ext_clk_rate(struct omap1_clk *clk, unsigned long rate, unsigned long p_rate)
{ {
unsigned long flags;
unsigned dsor; unsigned dsor;
__u16 ratio_bits; __u16 ratio_bits;
...@@ -354,25 +416,53 @@ int omap1_set_ext_clk_rate(struct clk *clk, unsigned long rate) ...@@ -354,25 +416,53 @@ int omap1_set_ext_clk_rate(struct clk *clk, unsigned long rate)
else else
ratio_bits = (dsor - 2) << 2; ratio_bits = (dsor - 2) << 2;
/* protect SWD_CLK_DIV_CTRL_SEL register from concurrent access via clk_enable/disable() */
spin_lock_irqsave(&swd_clk_div_ctrl_sel_lock, flags);
ratio_bits |= __raw_readw(clk->enable_reg) & ~0xfd; ratio_bits |= __raw_readw(clk->enable_reg) & ~0xfd;
__raw_writew(ratio_bits, clk->enable_reg); __raw_writew(ratio_bits, clk->enable_reg);
spin_unlock_irqrestore(&swd_clk_div_ctrl_sel_lock, flags);
return 0; return 0;
} }
int omap1_set_sossi_rate(struct clk *clk, unsigned long rate) static int calc_div_sossi(unsigned long rate, unsigned long p_rate)
{ {
u32 l;
int div; int div;
unsigned long p_rate;
p_rate = clk->parent->rate;
/* Round towards slower frequency */ /* Round towards slower frequency */
div = (p_rate + rate - 1) / rate; div = (p_rate + rate - 1) / rate;
div--;
return --div;
}
long omap1_round_sossi_rate(struct omap1_clk *clk, unsigned long rate, unsigned long *p_rate)
{
int div;
div = calc_div_sossi(rate, *p_rate);
if (div < 0)
div = 0;
else if (div > 7)
div = 7;
return *p_rate / (div + 1);
}
int omap1_set_sossi_rate(struct omap1_clk *clk, unsigned long rate, unsigned long p_rate)
{
unsigned long flags;
u32 l;
int div;
div = calc_div_sossi(rate, p_rate);
if (div < 0 || div > 7) if (div < 0 || div > 7)
return -EINVAL; return -EINVAL;
/* protect MOD_CONF_CTRL_1 register from concurrent access via clk_enable/disable() */
spin_lock_irqsave(&mod_conf_ctrl_1_lock, flags);
l = omap_readl(MOD_CONF_CTRL_1); l = omap_readl(MOD_CONF_CTRL_1);
l &= ~(7 << 17); l &= ~(7 << 17);
l |= div << 17; l |= div << 17;
...@@ -380,15 +470,17 @@ int omap1_set_sossi_rate(struct clk *clk, unsigned long rate) ...@@ -380,15 +470,17 @@ int omap1_set_sossi_rate(struct clk *clk, unsigned long rate)
clk->rate = p_rate / (div + 1); clk->rate = p_rate / (div + 1);
spin_unlock_irqrestore(&mod_conf_ctrl_1_lock, flags);
return 0; return 0;
} }
long omap1_round_ext_clk_rate(struct clk *clk, unsigned long rate) long omap1_round_ext_clk_rate(struct omap1_clk *clk, unsigned long rate, unsigned long *p_rate)
{ {
return 96000000 / calc_ext_dsor(rate); return 96000000 / calc_ext_dsor(rate);
} }
void omap1_init_ext_clk(struct clk *clk) int omap1_init_ext_clk(struct omap1_clk *clk)
{ {
unsigned dsor; unsigned dsor;
__u16 ratio_bits; __u16 ratio_bits;
...@@ -404,59 +496,59 @@ void omap1_init_ext_clk(struct clk *clk) ...@@ -404,59 +496,59 @@ void omap1_init_ext_clk(struct clk *clk)
dsor = ratio_bits + 2; dsor = ratio_bits + 2;
clk-> rate = 96000000 / dsor; clk-> rate = 96000000 / dsor;
return 0;
} }
int omap1_clk_enable(struct clk *clk) static int omap1_clk_enable(struct clk_hw *hw)
{ {
struct omap1_clk *clk = to_omap1_clk(hw), *parent = to_omap1_clk(clk_hw_get_parent(hw));
int ret = 0; int ret = 0;
if (clk->usecount++ == 0) { if (parent && clk->flags & CLOCK_NO_IDLE_PARENT)
if (clk->parent) { omap1_clk_deny_idle(parent);
ret = omap1_clk_enable(clk->parent);
if (ret)
goto err;
if (clk->flags & CLOCK_NO_IDLE_PARENT)
omap1_clk_deny_idle(clk->parent);
}
if (clk->ops && !(WARN_ON(!clk->ops->enable)))
ret = clk->ops->enable(clk); ret = clk->ops->enable(clk);
if (ret) {
if (clk->parent)
omap1_clk_disable(clk->parent);
goto err;
}
}
return ret;
err:
clk->usecount--;
return ret; return ret;
} }
void omap1_clk_disable(struct clk *clk) static void omap1_clk_disable(struct clk_hw *hw)
{ {
if (clk->usecount > 0 && !(--clk->usecount)) { struct omap1_clk *clk = to_omap1_clk(hw), *parent = to_omap1_clk(clk_hw_get_parent(hw));
if (clk->ops && !(WARN_ON(!clk->ops->disable)))
clk->ops->disable(clk); clk->ops->disable(clk);
if (likely(clk->parent)) {
omap1_clk_disable(clk->parent); if (likely(parent) && clk->flags & CLOCK_NO_IDLE_PARENT)
if (clk->flags & CLOCK_NO_IDLE_PARENT) omap1_clk_allow_idle(parent);
omap1_clk_allow_idle(clk->parent);
}
}
} }
static int omap1_clk_enable_generic(struct clk *clk) static int omap1_clk_enable_generic(struct omap1_clk *clk)
{ {
unsigned long flags;
__u16 regval16; __u16 regval16;
__u32 regval32; __u32 regval32;
if (unlikely(clk->enable_reg == NULL)) { if (unlikely(clk->enable_reg == NULL)) {
printk(KERN_ERR "clock.c: Enable for %s without enable code\n", printk(KERN_ERR "clock.c: Enable for %s without enable code\n",
clk->name); clk_hw_get_name(&clk->hw));
return -EINVAL; return -EINVAL;
} }
/* protect clk->enable_reg from concurrent access via clk_set_rate() */
if (clk->enable_reg == OMAP1_IO_ADDRESS(ARM_CKCTL))
spin_lock_irqsave(&arm_ckctl_lock, flags);
else if (clk->enable_reg == OMAP1_IO_ADDRESS(ARM_IDLECT2))
spin_lock_irqsave(&arm_idlect2_lock, flags);
else if (clk->enable_reg == OMAP1_IO_ADDRESS(MOD_CONF_CTRL_0))
spin_lock_irqsave(&mod_conf_ctrl_0_lock, flags);
else if (clk->enable_reg == OMAP1_IO_ADDRESS(MOD_CONF_CTRL_1))
spin_lock_irqsave(&mod_conf_ctrl_1_lock, flags);
else if (clk->enable_reg == OMAP1_IO_ADDRESS(SWD_CLK_DIV_CTRL_SEL))
spin_lock_irqsave(&swd_clk_div_ctrl_sel_lock, flags);
if (clk->flags & ENABLE_REG_32BIT) { if (clk->flags & ENABLE_REG_32BIT) {
regval32 = __raw_readl(clk->enable_reg); regval32 = __raw_readl(clk->enable_reg);
regval32 |= (1 << clk->enable_bit); regval32 |= (1 << clk->enable_bit);
...@@ -467,17 +559,41 @@ static int omap1_clk_enable_generic(struct clk *clk) ...@@ -467,17 +559,41 @@ static int omap1_clk_enable_generic(struct clk *clk)
__raw_writew(regval16, clk->enable_reg); __raw_writew(regval16, clk->enable_reg);
} }
if (clk->enable_reg == OMAP1_IO_ADDRESS(ARM_CKCTL))
spin_unlock_irqrestore(&arm_ckctl_lock, flags);
else if (clk->enable_reg == OMAP1_IO_ADDRESS(ARM_IDLECT2))
spin_unlock_irqrestore(&arm_idlect2_lock, flags);
else if (clk->enable_reg == OMAP1_IO_ADDRESS(MOD_CONF_CTRL_0))
spin_unlock_irqrestore(&mod_conf_ctrl_0_lock, flags);
else if (clk->enable_reg == OMAP1_IO_ADDRESS(MOD_CONF_CTRL_1))
spin_unlock_irqrestore(&mod_conf_ctrl_1_lock, flags);
else if (clk->enable_reg == OMAP1_IO_ADDRESS(SWD_CLK_DIV_CTRL_SEL))
spin_unlock_irqrestore(&swd_clk_div_ctrl_sel_lock, flags);
return 0; return 0;
} }
static void omap1_clk_disable_generic(struct clk *clk) static void omap1_clk_disable_generic(struct omap1_clk *clk)
{ {
unsigned long flags;
__u16 regval16; __u16 regval16;
__u32 regval32; __u32 regval32;
if (clk->enable_reg == NULL) if (clk->enable_reg == NULL)
return; return;
/* protect clk->enable_reg from concurrent access via clk_set_rate() */
if (clk->enable_reg == OMAP1_IO_ADDRESS(ARM_CKCTL))
spin_lock_irqsave(&arm_ckctl_lock, flags);
else if (clk->enable_reg == OMAP1_IO_ADDRESS(ARM_IDLECT2))
spin_lock_irqsave(&arm_idlect2_lock, flags);
else if (clk->enable_reg == OMAP1_IO_ADDRESS(MOD_CONF_CTRL_0))
spin_lock_irqsave(&mod_conf_ctrl_0_lock, flags);
else if (clk->enable_reg == OMAP1_IO_ADDRESS(MOD_CONF_CTRL_1))
spin_lock_irqsave(&mod_conf_ctrl_1_lock, flags);
else if (clk->enable_reg == OMAP1_IO_ADDRESS(SWD_CLK_DIV_CTRL_SEL))
spin_lock_irqsave(&swd_clk_div_ctrl_sel_lock, flags);
if (clk->flags & ENABLE_REG_32BIT) { if (clk->flags & ENABLE_REG_32BIT) {
regval32 = __raw_readl(clk->enable_reg); regval32 = __raw_readl(clk->enable_reg);
regval32 &= ~(1 << clk->enable_bit); regval32 &= ~(1 << clk->enable_bit);
...@@ -487,6 +603,17 @@ static void omap1_clk_disable_generic(struct clk *clk) ...@@ -487,6 +603,17 @@ static void omap1_clk_disable_generic(struct clk *clk)
regval16 &= ~(1 << clk->enable_bit); regval16 &= ~(1 << clk->enable_bit);
__raw_writew(regval16, clk->enable_reg); __raw_writew(regval16, clk->enable_reg);
} }
if (clk->enable_reg == OMAP1_IO_ADDRESS(ARM_CKCTL))
spin_unlock_irqrestore(&arm_ckctl_lock, flags);
else if (clk->enable_reg == OMAP1_IO_ADDRESS(ARM_IDLECT2))
spin_unlock_irqrestore(&arm_idlect2_lock, flags);
else if (clk->enable_reg == OMAP1_IO_ADDRESS(MOD_CONF_CTRL_0))
spin_unlock_irqrestore(&mod_conf_ctrl_0_lock, flags);
else if (clk->enable_reg == OMAP1_IO_ADDRESS(MOD_CONF_CTRL_1))
spin_unlock_irqrestore(&mod_conf_ctrl_1_lock, flags);
else if (clk->enable_reg == OMAP1_IO_ADDRESS(SWD_CLK_DIV_CTRL_SEL))
spin_unlock_irqrestore(&swd_clk_div_ctrl_sel_lock, flags);
} }
const struct clkops clkops_generic = { const struct clkops clkops_generic = {
...@@ -494,25 +621,38 @@ const struct clkops clkops_generic = { ...@@ -494,25 +621,38 @@ const struct clkops clkops_generic = {
.disable = omap1_clk_disable_generic, .disable = omap1_clk_disable_generic,
}; };
static int omap1_clk_enable_dsp_domain(struct clk *clk) static int omap1_clk_enable_dsp_domain(struct omap1_clk *clk)
{ {
int retval; bool api_ck_was_enabled;
int retval = 0;
api_ck_was_enabled = omap1_clk_is_enabled(&api_ck_p->hw);
if (!api_ck_was_enabled)
retval = api_ck_p->ops->enable(api_ck_p);
retval = omap1_clk_enable(api_ck_p);
if (!retval) { if (!retval) {
retval = omap1_clk_enable_generic(clk); retval = omap1_clk_enable_generic(clk);
omap1_clk_disable(api_ck_p);
if (!api_ck_was_enabled)
api_ck_p->ops->disable(api_ck_p);
} }
return retval; return retval;
} }
static void omap1_clk_disable_dsp_domain(struct clk *clk) static void omap1_clk_disable_dsp_domain(struct omap1_clk *clk)
{ {
if (omap1_clk_enable(api_ck_p) == 0) { bool api_ck_was_enabled;
omap1_clk_disable_generic(clk);
omap1_clk_disable(api_ck_p); api_ck_was_enabled = omap1_clk_is_enabled(&api_ck_p->hw);
} if (!api_ck_was_enabled)
if (api_ck_p->ops->enable(api_ck_p) < 0)
return;
omap1_clk_disable_generic(clk);
if (!api_ck_was_enabled)
api_ck_p->ops->disable(api_ck_p);
} }
const struct clkops clkops_dspck = { const struct clkops clkops_dspck = {
...@@ -521,7 +661,7 @@ const struct clkops clkops_dspck = { ...@@ -521,7 +661,7 @@ const struct clkops clkops_dspck = {
}; };
/* XXX SYSC register handling does not belong in the clock framework */ /* XXX SYSC register handling does not belong in the clock framework */
static int omap1_clk_enable_uart_functional_16xx(struct clk *clk) static int omap1_clk_enable_uart_functional_16xx(struct omap1_clk *clk)
{ {
int ret; int ret;
struct uart_clk *uclk; struct uart_clk *uclk;
...@@ -538,7 +678,7 @@ static int omap1_clk_enable_uart_functional_16xx(struct clk *clk) ...@@ -538,7 +678,7 @@ static int omap1_clk_enable_uart_functional_16xx(struct clk *clk)
} }
/* XXX SYSC register handling does not belong in the clock framework */ /* XXX SYSC register handling does not belong in the clock framework */
static void omap1_clk_disable_uart_functional_16xx(struct clk *clk) static void omap1_clk_disable_uart_functional_16xx(struct omap1_clk *clk)
{ {
struct uart_clk *uclk; struct uart_clk *uclk;
...@@ -555,20 +695,33 @@ const struct clkops clkops_uart_16xx = { ...@@ -555,20 +695,33 @@ const struct clkops clkops_uart_16xx = {
.disable = omap1_clk_disable_uart_functional_16xx, .disable = omap1_clk_disable_uart_functional_16xx,
}; };
long omap1_clk_round_rate(struct clk *clk, unsigned long rate) static unsigned long omap1_clk_recalc_rate(struct clk_hw *hw, unsigned long p_rate)
{ {
if (clk->round_rate != NULL) struct omap1_clk *clk = to_omap1_clk(hw);
return clk->round_rate(clk, rate);
if (clk->recalc)
return clk->recalc(clk, p_rate);
return clk->rate; return clk->rate;
} }
int omap1_clk_set_rate(struct clk *clk, unsigned long rate) static long omap1_clk_round_rate(struct clk_hw *hw, unsigned long rate, unsigned long *p_rate)
{
struct omap1_clk *clk = to_omap1_clk(hw);
if (clk->round_rate != NULL)
return clk->round_rate(clk, rate, p_rate);
return omap1_clk_recalc_rate(hw, *p_rate);
}
static int omap1_clk_set_rate(struct clk_hw *hw, unsigned long rate, unsigned long p_rate)
{ {
struct omap1_clk *clk = to_omap1_clk(hw);
int ret = -EINVAL; int ret = -EINVAL;
if (clk->set_rate) if (clk->set_rate)
ret = clk->set_rate(clk, rate); ret = clk->set_rate(clk, rate, p_rate);
return ret; return ret;
} }
...@@ -576,243 +729,105 @@ int omap1_clk_set_rate(struct clk *clk, unsigned long rate) ...@@ -576,243 +729,105 @@ int omap1_clk_set_rate(struct clk *clk, unsigned long rate)
* Omap1 clock reset and init functions * Omap1 clock reset and init functions
*/ */
static int omap1_clk_init_op(struct clk_hw *hw)
{
struct omap1_clk *clk = to_omap1_clk(hw);
if (clk->init)
return clk->init(clk);
return 0;
}
#ifdef CONFIG_OMAP_RESET_CLOCKS #ifdef CONFIG_OMAP_RESET_CLOCKS
void omap1_clk_disable_unused(struct clk *clk) static void omap1_clk_disable_unused(struct clk_hw *hw)
{ {
__u32 regval32; struct omap1_clk *clk = to_omap1_clk(hw);
const char *name = clk_hw_get_name(hw);
/* Clocks in the DSP domain need api_ck. Just assume bootloader /* Clocks in the DSP domain need api_ck. Just assume bootloader
* has not enabled any DSP clocks */ * has not enabled any DSP clocks */
if (clk->enable_reg == DSP_IDLECT2) { if (clk->enable_reg == DSP_IDLECT2) {
pr_info("Skipping reset check for DSP domain clock \"%s\"\n", pr_info("Skipping reset check for DSP domain clock \"%s\"\n", name);
clk->name);
return; return;
} }
/* Is the clock already disabled? */ pr_info("Disabling unused clock \"%s\"... ", name);
if (clk->flags & ENABLE_REG_32BIT) omap1_clk_disable(hw);
regval32 = __raw_readl(clk->enable_reg);
else
regval32 = __raw_readw(clk->enable_reg);
if ((regval32 & (1 << clk->enable_bit)) == 0)
return;
printk(KERN_INFO "Disabling unused clock \"%s\"... ", clk->name);
clk->ops->disable(clk);
printk(" done\n"); printk(" done\n");
} }
#endif #endif
const struct clk_ops omap1_clk_gate_ops = {
.enable = omap1_clk_enable,
.disable = omap1_clk_disable,
.is_enabled = omap1_clk_is_enabled,
#ifdef CONFIG_OMAP_RESET_CLOCKS
.disable_unused = omap1_clk_disable_unused,
#endif
};
int clk_enable(struct clk *clk) const struct clk_ops omap1_clk_rate_ops = {
{ .recalc_rate = omap1_clk_recalc_rate,
unsigned long flags; .round_rate = omap1_clk_round_rate,
int ret; .set_rate = omap1_clk_set_rate,
.init = omap1_clk_init_op,
if (IS_ERR_OR_NULL(clk)) };
return -EINVAL;
spin_lock_irqsave(&clockfw_lock, flags);
ret = omap1_clk_enable(clk);
spin_unlock_irqrestore(&clockfw_lock, flags);
return ret;
}
EXPORT_SYMBOL(clk_enable);
void clk_disable(struct clk *clk)
{
unsigned long flags;
if (IS_ERR_OR_NULL(clk))
return;
spin_lock_irqsave(&clockfw_lock, flags);
if (clk->usecount == 0) {
pr_err("Trying disable clock %s with 0 usecount\n",
clk->name);
WARN_ON(1);
goto out;
}
omap1_clk_disable(clk);
out:
spin_unlock_irqrestore(&clockfw_lock, flags);
}
EXPORT_SYMBOL(clk_disable);
unsigned long clk_get_rate(struct clk *clk)
{
unsigned long flags;
unsigned long ret;
if (IS_ERR_OR_NULL(clk))
return 0;
spin_lock_irqsave(&clockfw_lock, flags);
ret = clk->rate;
spin_unlock_irqrestore(&clockfw_lock, flags);
return ret;
}
EXPORT_SYMBOL(clk_get_rate);
/*
* Optional clock functions defined in include/linux/clk.h
*/
long clk_round_rate(struct clk *clk, unsigned long rate)
{
unsigned long flags;
long ret;
if (IS_ERR_OR_NULL(clk))
return 0;
spin_lock_irqsave(&clockfw_lock, flags);
ret = omap1_clk_round_rate(clk, rate);
spin_unlock_irqrestore(&clockfw_lock, flags);
return ret;
}
EXPORT_SYMBOL(clk_round_rate);
int clk_set_rate(struct clk *clk, unsigned long rate)
{
unsigned long flags;
int ret = -EINVAL;
if (IS_ERR_OR_NULL(clk))
return ret;
spin_lock_irqsave(&clockfw_lock, flags);
ret = omap1_clk_set_rate(clk, rate);
if (ret == 0)
propagate_rate(clk);
spin_unlock_irqrestore(&clockfw_lock, flags);
return ret;
}
EXPORT_SYMBOL(clk_set_rate);
int clk_set_parent(struct clk *clk, struct clk *parent)
{
WARN_ONCE(1, "clk_set_parent() not implemented for OMAP1\n");
return -EINVAL;
}
EXPORT_SYMBOL(clk_set_parent);
struct clk *clk_get_parent(struct clk *clk) const struct clk_ops omap1_clk_full_ops = {
{ .enable = omap1_clk_enable,
return clk->parent; .disable = omap1_clk_disable,
} .is_enabled = omap1_clk_is_enabled,
EXPORT_SYMBOL(clk_get_parent); #ifdef CONFIG_OMAP_RESET_CLOCKS
.disable_unused = omap1_clk_disable_unused,
#endif
.recalc_rate = omap1_clk_recalc_rate,
.round_rate = omap1_clk_round_rate,
.set_rate = omap1_clk_set_rate,
.init = omap1_clk_init_op,
};
/* /*
* OMAP specific clock functions shared between omap1 and omap2 * OMAP specific clock functions shared between omap1 and omap2
*/ */
/* Used for clocks that always have same value as the parent clock */ /* Used for clocks that always have same value as the parent clock */
unsigned long followparent_recalc(struct clk *clk) unsigned long followparent_recalc(struct omap1_clk *clk, unsigned long p_rate)
{ {
return clk->parent->rate; return p_rate;
} }
/* /*
* Used for clocks that have the same value as the parent clock, * Used for clocks that have the same value as the parent clock,
* divided by some factor * divided by some factor
*/ */
unsigned long omap_fixed_divisor_recalc(struct clk *clk) unsigned long omap_fixed_divisor_recalc(struct omap1_clk *clk, unsigned long p_rate)
{ {
WARN_ON(!clk->fixed_div); WARN_ON(!clk->fixed_div);
return clk->parent->rate / clk->fixed_div; return p_rate / clk->fixed_div;
} }
/* Propagate rate to children */ /* Propagate rate to children */
void propagate_rate(struct clk *tclk) void propagate_rate(struct omap1_clk *tclk)
{ {
struct clk *clkp; struct clk *clkp;
list_for_each_entry(clkp, &tclk->children, sibling) { /* depend on CCF ability to recalculate new rates across whole clock subtree */
if (clkp->recalc) if (WARN_ON(!(clk_hw_get_flags(&tclk->hw) & CLK_GET_RATE_NOCACHE)))
clkp->rate = clkp->recalc(clkp);
propagate_rate(clkp);
}
}
static LIST_HEAD(root_clks);
/**
* clk_preinit - initialize any fields in the struct clk before clk init
* @clk: struct clk * to initialize
*
* Initialize any struct clk fields needed before normal clk initialization
* can run. No return value.
*/
void clk_preinit(struct clk *clk)
{
INIT_LIST_HEAD(&clk->children);
}
int clk_register(struct clk *clk)
{
if (IS_ERR_OR_NULL(clk))
return -EINVAL;
/*
* trap out already registered clocks
*/
if (clk->node.next || clk->node.prev)
return 0;
mutex_lock(&clocks_mutex);
if (clk->parent)
list_add(&clk->sibling, &clk->parent->children);
else
list_add(&clk->sibling, &root_clks);
list_add(&clk->node, &clocks);
if (clk->init)
clk->init(clk);
mutex_unlock(&clocks_mutex);
return 0;
}
EXPORT_SYMBOL(clk_register);
void clk_unregister(struct clk *clk)
{
if (IS_ERR_OR_NULL(clk))
return; return;
mutex_lock(&clocks_mutex); clkp = clk_get_sys(NULL, clk_hw_get_name(&tclk->hw));
list_del(&clk->sibling); if (WARN_ON(!clkp))
list_del(&clk->node); return;
mutex_unlock(&clocks_mutex);
}
EXPORT_SYMBOL(clk_unregister);
/*
* Low level helpers
*/
static int clkll_enable_null(struct clk *clk)
{
return 0;
}
static void clkll_disable_null(struct clk *clk) clk_get_rate(clkp);
{ clk_put(clkp);
} }
const struct clkops clkops_null = { const struct clk_ops omap1_clk_null_ops = {
.enable = clkll_enable_null,
.disable = clkll_disable_null,
}; };
/* /*
...@@ -820,114 +835,6 @@ const struct clkops clkops_null = { ...@@ -820,114 +835,6 @@ const struct clkops clkops_null = {
* *
* Used for clock aliases that are needed on some OMAPs, but not others * Used for clock aliases that are needed on some OMAPs, but not others
*/ */
struct clk dummy_ck = { struct omap1_clk dummy_ck __refdata = {
.name = "dummy", .hw.init = CLK_HW_INIT_NO_PARENT("dummy", &omap1_clk_null_ops, 0),
.ops = &clkops_null,
}; };
/*
*
*/
#ifdef CONFIG_OMAP_RESET_CLOCKS
/*
* Disable any unused clocks left on by the bootloader
*/
static int __init clk_disable_unused(void)
{
struct clk *ck;
unsigned long flags;
pr_info("clock: disabling unused clocks to save power\n");
spin_lock_irqsave(&clockfw_lock, flags);
list_for_each_entry(ck, &clocks, node) {
if (ck->ops == &clkops_null)
continue;
if (ck->usecount > 0 || !ck->enable_reg)
continue;
omap1_clk_disable_unused(ck);
}
spin_unlock_irqrestore(&clockfw_lock, flags);
return 0;
}
late_initcall(clk_disable_unused);
#endif
#if defined(CONFIG_PM_DEBUG) && defined(CONFIG_DEBUG_FS)
/*
* debugfs support to trace clock tree hierarchy and attributes
*/
#include <linux/debugfs.h>
#include <linux/seq_file.h>
static struct dentry *clk_debugfs_root;
static int debug_clock_show(struct seq_file *s, void *unused)
{
struct clk *c;
struct clk *pa;
mutex_lock(&clocks_mutex);
seq_printf(s, "%-30s %-30s %-10s %s\n",
"clock-name", "parent-name", "rate", "use-count");
list_for_each_entry(c, &clocks, node) {
pa = c->parent;
seq_printf(s, "%-30s %-30s %-10lu %d\n",
c->name, pa ? pa->name : "none", c->rate,
c->usecount);
}
mutex_unlock(&clocks_mutex);
return 0;
}
DEFINE_SHOW_ATTRIBUTE(debug_clock);
static void clk_debugfs_register_one(struct clk *c)
{
struct dentry *d;
struct clk *pa = c->parent;
d = debugfs_create_dir(c->name, pa ? pa->dent : clk_debugfs_root);
c->dent = d;
debugfs_create_u8("usecount", S_IRUGO, c->dent, &c->usecount);
debugfs_create_ulong("rate", S_IRUGO, c->dent, &c->rate);
debugfs_create_x8("flags", S_IRUGO, c->dent, &c->flags);
}
static void clk_debugfs_register(struct clk *c)
{
struct clk *pa = c->parent;
if (pa && !pa->dent)
clk_debugfs_register(pa);
if (!c->dent)
clk_debugfs_register_one(c);
}
static int __init clk_debugfs_init(void)
{
struct clk *c;
struct dentry *d;
d = debugfs_create_dir("clock", NULL);
clk_debugfs_root = d;
list_for_each_entry(c, &clocks, node)
clk_debugfs_register(c);
debugfs_create_file("summary", S_IRUGO, d, NULL, &debug_clock_fops);
return 0;
}
late_initcall(clk_debugfs_init);
#endif /* defined(CONFIG_PM_DEBUG) && defined(CONFIG_DEBUG_FS) */
...@@ -11,12 +11,11 @@ ...@@ -11,12 +11,11 @@
#define __ARCH_ARM_MACH_OMAP1_CLOCK_H #define __ARCH_ARM_MACH_OMAP1_CLOCK_H
#include <linux/clk.h> #include <linux/clk.h>
#include <linux/list.h>
#include <linux/clkdev.h> #include <linux/clkdev.h>
#include <linux/clk-provider.h>
struct module; struct module;
struct clk; struct omap1_clk;
struct omap_clk { struct omap_clk {
u16 cpu; u16 cpu;
...@@ -29,7 +28,7 @@ struct omap_clk { ...@@ -29,7 +28,7 @@ struct omap_clk {
.lk = { \ .lk = { \
.dev_id = dev, \ .dev_id = dev, \
.con_id = con, \ .con_id = con, \
.clk = ck, \ .clk_hw = ck, \
}, \ }, \
} }
...@@ -40,10 +39,6 @@ struct omap_clk { ...@@ -40,10 +39,6 @@ struct omap_clk {
#define CK_16XX (1 << 3) /* 16xx, 17xx, 5912 */ #define CK_16XX (1 << 3) /* 16xx, 17xx, 5912 */
#define CK_1710 (1 << 4) /* 1710 extra for rate selection */ #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 * struct clkops - some clock function pointers
* @enable: fn ptr that enables the current clock in hardware * @enable: fn ptr that enables the current clock in hardware
...@@ -51,8 +46,8 @@ struct omap_clk { ...@@ -51,8 +46,8 @@ struct omap_clk {
* @allow_idle: fn ptr that enables autoidle for the current clock in hardware * @allow_idle: fn ptr that enables autoidle for the current clock in hardware
*/ */
struct clkops { struct clkops {
int (*enable)(struct clk *); int (*enable)(struct omap1_clk *clk);
void (*disable)(struct clk *); void (*disable)(struct omap1_clk *clk);
}; };
/* /*
...@@ -65,13 +60,9 @@ struct clkops { ...@@ -65,13 +60,9 @@ struct clkops {
#define CLOCK_NO_IDLE_PARENT (1 << 2) #define CLOCK_NO_IDLE_PARENT (1 << 2)
/** /**
* struct clk - OMAP struct clk * struct omap1_clk - OMAP1 struct clk
* @node: list_head connecting this clock into the full clock list * @hw: struct clk_hw for common clock framework integration
* @ops: struct clkops * for this clock * @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 * @rate: current clock rate
* @enable_reg: register to write to enable the clock (see @enable_bit) * @enable_reg: register to write to enable the clock (see @enable_bit)
* @recalc: fn ptr that returns the clock's current rate * @recalc: fn ptr that returns the clock's current rate
...@@ -79,102 +70,65 @@ struct clkops { ...@@ -79,102 +70,65 @@ struct clkops {
* @round_rate: fn ptr that can round the clock's current rate * @round_rate: fn ptr that can round the clock's current rate
* @init: fn ptr to do clock-specific initialization * @init: fn ptr to do clock-specific initialization
* @enable_bit: bitshift to write to enable/disable the clock (see @enable_reg) * @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 * @fixed_div: when > 0, this clock's rate is its parent's rate / @fixed_div
* @flags: see "struct clk.flags possibilities" above * @flags: see "struct clk.flags possibilities" above
* @rate_offset: bitshift for rate selection bitfield (OMAP1 only) * @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 omap1_clk {
struct list_head node; struct clk_hw hw;
const struct clkops *ops; const struct clkops *ops;
const char *name;
struct clk *parent;
struct list_head children;
struct list_head sibling; /* node for children */
unsigned long rate; unsigned long rate;
void __iomem *enable_reg; void __iomem *enable_reg;
unsigned long (*recalc)(struct clk *); unsigned long (*recalc)(struct omap1_clk *clk, unsigned long rate);
int (*set_rate)(struct clk *, unsigned long); int (*set_rate)(struct omap1_clk *clk, unsigned long rate,
long (*round_rate)(struct clk *, unsigned long); unsigned long p_rate);
void (*init)(struct clk *); long (*round_rate)(struct omap1_clk *clk, unsigned long rate,
unsigned long *p_rate);
int (*init)(struct omap1_clk *clk);
u8 enable_bit; u8 enable_bit;
s8 usecount;
u8 fixed_div; u8 fixed_div;
u8 flags; u8 flags;
u8 rate_offset; 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); void propagate_rate(struct omap1_clk *clk);
extern int clk_register(struct clk *clk); unsigned long followparent_recalc(struct omap1_clk *clk, unsigned long p_rate);
extern void clk_unregister(struct clk *clk); unsigned long omap_fixed_divisor_recalc(struct omap1_clk *clk, unsigned long p_rate);
extern void propagate_rate(struct clk *clk);
extern unsigned long followparent_recalc(struct clk *clk);
unsigned long omap_fixed_divisor_recalc(struct clk *clk);
extern const struct clkops clkops_null; extern struct omap1_clk dummy_ck;
extern struct clk dummy_ck;
int omap1_clk_init(void); int omap1_clk_init(void);
void omap1_clk_late_init(void); void omap1_clk_late_init(void);
extern int omap1_clk_enable(struct clk *clk); unsigned long omap1_ckctl_recalc(struct omap1_clk *clk, unsigned long p_rate);
extern void omap1_clk_disable(struct clk *clk); long omap1_round_sossi_rate(struct omap1_clk *clk, unsigned long rate, unsigned long *p_rate);
extern long omap1_clk_round_rate(struct clk *clk, unsigned long rate); int omap1_set_sossi_rate(struct omap1_clk *clk, unsigned long rate, unsigned long p_rate);
extern int omap1_clk_set_rate(struct clk *clk, unsigned long rate); unsigned long omap1_sossi_recalc(struct omap1_clk *clk, unsigned long p_rate);
extern unsigned long omap1_ckctl_recalc(struct clk *clk); unsigned long omap1_ckctl_recalc_dsp_domain(struct omap1_clk *clk, unsigned long p_rate);
extern int omap1_set_sossi_rate(struct clk *clk, unsigned long rate); int omap1_clk_set_rate_dsp_domain(struct omap1_clk *clk, unsigned long rate,
extern unsigned long omap1_sossi_recalc(struct clk *clk); unsigned long p_rate);
extern unsigned long omap1_ckctl_recalc_dsp_domain(struct clk *clk); long omap1_round_uart_rate(struct omap1_clk *clk, unsigned long rate, unsigned long *p_rate);
extern int omap1_clk_set_rate_dsp_domain(struct clk *clk, unsigned long rate); int omap1_set_uart_rate(struct omap1_clk *clk, unsigned long rate, unsigned long p_rate);
extern int omap1_set_uart_rate(struct clk *clk, unsigned long rate); unsigned long omap1_uart_recalc(struct omap1_clk *clk, unsigned long p_rate);
extern unsigned long omap1_uart_recalc(struct clk *clk); int omap1_set_ext_clk_rate(struct omap1_clk *clk, unsigned long rate, unsigned long p_rate);
extern int omap1_set_ext_clk_rate(struct clk *clk, unsigned long rate); long omap1_round_ext_clk_rate(struct omap1_clk *clk, unsigned long rate, unsigned long *p_rate);
extern long omap1_round_ext_clk_rate(struct clk *clk, unsigned long rate); int omap1_init_ext_clk(struct omap1_clk *clk);
extern void omap1_init_ext_clk(struct clk *clk); int omap1_select_table_rate(struct omap1_clk *clk, unsigned long rate, unsigned long p_rate);
extern int omap1_select_table_rate(struct clk *clk, unsigned long rate); long omap1_round_to_table_rate(struct omap1_clk *clk, unsigned long rate, unsigned long *p_rate);
extern long omap1_round_to_table_rate(struct clk *clk, unsigned long rate); int omap1_clk_set_rate_ckctl_arm(struct omap1_clk *clk, unsigned long rate, unsigned long p_rate);
extern int omap1_clk_set_rate_ckctl_arm(struct clk *clk, unsigned long rate); long omap1_clk_round_rate_ckctl_arm(struct omap1_clk *clk, unsigned long rate,
extern long omap1_clk_round_rate_ckctl_arm(struct clk *clk, unsigned long rate); unsigned long *p_rate);
#ifdef CONFIG_OMAP_RESET_CLOCKS
extern void omap1_clk_disable_unused(struct clk *clk);
#else
#define omap1_clk_disable_unused NULL
#endif
struct uart_clk { struct uart_clk {
struct clk clk; struct omap1_clk clk;
unsigned long sysc_addr; unsigned long sysc_addr;
}; };
/* Provide a method for preventing idling some ARM IDLECT clocks */ /* Provide a method for preventing idling some ARM IDLECT clocks */
struct arm_idlect1_clk { struct arm_idlect1_clk {
struct clk clk; struct omap1_clk clk;
unsigned long no_idle_count; unsigned long no_idle_count;
__u8 idlect_shift; __u8 idlect_shift;
}; };
/* ARM_CKCTL bit shifts */ /* ARM_CKCTL bit shifts */
...@@ -224,7 +178,7 @@ struct arm_idlect1_clk { ...@@ -224,7 +178,7 @@ struct arm_idlect1_clk {
#define SOFT_REQ_REG2 0xfffe0880 #define SOFT_REQ_REG2 0xfffe0880
extern __u32 arm_idlect1_mask; 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_dspck;
extern const struct clkops clkops_uart_16xx; extern const struct clkops clkops_uart_16xx;
...@@ -233,4 +187,9 @@ extern const struct clkops clkops_generic; ...@@ -233,4 +187,9 @@ extern const struct clkops clkops_generic;
/* used for passing SoC type to omap1_{select,round_to}_table_rate() */ /* used for passing SoC type to omap1_{select,round_to}_table_rate() */
extern u32 cpu_mask; 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 #endif
...@@ -14,6 +14,8 @@ ...@@ -14,6 +14,8 @@
#include <linux/kernel.h> #include <linux/kernel.h>
#include <linux/io.h> #include <linux/io.h>
#include <linux/clk.h> #include <linux/clk.h>
#include <linux/clkdev.h>
#include <linux/clk-provider.h>
#include <linux/cpufreq.h> #include <linux/cpufreq.h>
#include <linux/delay.h> #include <linux/delay.h>
#include <linux/soc/ti/omap1-io.h> #include <linux/soc/ti/omap1-io.h>
...@@ -71,16 +73,18 @@ ...@@ -71,16 +73,18 @@
* Omap1 clocks * Omap1 clocks
*/ */
static struct clk ck_ref = { static struct omap1_clk ck_ref = {
.name = "ck_ref", .hw.init = CLK_HW_INIT_NO_PARENT("ck_ref", &omap1_clk_rate_ops, 0),
.ops = &clkops_null,
.rate = 12000000, .rate = 12000000,
}; };
static struct clk ck_dpll1 = { static struct omap1_clk ck_dpll1 = {
.name = "ck_dpll1", .hw.init = CLK_HW_INIT("ck_dpll1", "ck_ref", &omap1_clk_rate_ops,
.ops = &clkops_null, /*
.parent = &ck_ref, * 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 = { ...@@ -89,32 +93,28 @@ static struct clk ck_dpll1 = {
*/ */
static struct arm_idlect1_clk ck_dpll1out = { static struct arm_idlect1_clk ck_dpll1out = {
.clk = { .clk = {
.name = "ck_dpll1out", .hw.init = CLK_HW_INIT("ck_dpll1out", "ck_dpll1", &omap1_clk_gate_ops, 0),
.ops = &clkops_generic, .ops = &clkops_generic,
.parent = &ck_dpll1,
.flags = CLOCK_IDLE_CONTROL | ENABLE_REG_32BIT, .flags = CLOCK_IDLE_CONTROL | ENABLE_REG_32BIT,
.enable_reg = OMAP1_IO_ADDRESS(ARM_IDLECT2), .enable_reg = OMAP1_IO_ADDRESS(ARM_IDLECT2),
.enable_bit = EN_CKOUT_ARM, .enable_bit = EN_CKOUT_ARM,
.recalc = &followparent_recalc,
}, },
.idlect_shift = IDL_CLKOUT_ARM_SHIFT, .idlect_shift = IDL_CLKOUT_ARM_SHIFT,
}; };
static struct clk sossi_ck = { static struct omap1_clk sossi_ck = {
.name = "ck_sossi", .hw.init = CLK_HW_INIT("ck_sossi", "ck_dpll1out", &omap1_clk_full_ops, 0),
.ops = &clkops_generic, .ops = &clkops_generic,
.parent = &ck_dpll1out.clk,
.flags = CLOCK_NO_IDLE_PARENT | ENABLE_REG_32BIT, .flags = CLOCK_NO_IDLE_PARENT | ENABLE_REG_32BIT,
.enable_reg = OMAP1_IO_ADDRESS(MOD_CONF_CTRL_1), .enable_reg = OMAP1_IO_ADDRESS(MOD_CONF_CTRL_1),
.enable_bit = CONF_MOD_SOSSI_CLK_EN_R, .enable_bit = CONF_MOD_SOSSI_CLK_EN_R,
.recalc = &omap1_sossi_recalc, .recalc = &omap1_sossi_recalc,
.round_rate = &omap1_round_sossi_rate,
.set_rate = &omap1_set_sossi_rate, .set_rate = &omap1_set_sossi_rate,
}; };
static struct clk arm_ck = { static struct omap1_clk arm_ck = {
.name = "arm_ck", .hw.init = CLK_HW_INIT("arm_ck", "ck_dpll1", &omap1_clk_rate_ops, 0),
.ops = &clkops_null,
.parent = &ck_dpll1,
.rate_offset = CKCTL_ARMDIV_OFFSET, .rate_offset = CKCTL_ARMDIV_OFFSET,
.recalc = &omap1_ckctl_recalc, .recalc = &omap1_ckctl_recalc,
.round_rate = omap1_clk_round_rate_ckctl_arm, .round_rate = omap1_clk_round_rate_ckctl_arm,
...@@ -123,9 +123,9 @@ static struct clk arm_ck = { ...@@ -123,9 +123,9 @@ static struct clk arm_ck = {
static struct arm_idlect1_clk armper_ck = { static struct arm_idlect1_clk armper_ck = {
.clk = { .clk = {
.name = "armper_ck", .hw.init = CLK_HW_INIT("armper_ck", "ck_dpll1", &omap1_clk_full_ops,
CLK_IS_CRITICAL),
.ops = &clkops_generic, .ops = &clkops_generic,
.parent = &ck_dpll1,
.flags = CLOCK_IDLE_CONTROL, .flags = CLOCK_IDLE_CONTROL,
.enable_reg = OMAP1_IO_ADDRESS(ARM_IDLECT2), .enable_reg = OMAP1_IO_ADDRESS(ARM_IDLECT2),
.enable_bit = EN_PERCK, .enable_bit = EN_PERCK,
...@@ -141,46 +141,41 @@ static struct arm_idlect1_clk armper_ck = { ...@@ -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 * FIXME: This clock seems to be necessary but no-one has asked for its
* activation. [ GPIO code for 1510 ] * activation. [ GPIO code for 1510 ]
*/ */
static struct clk arm_gpio_ck = { static struct omap1_clk arm_gpio_ck = {
.name = "ick", .hw.init = CLK_HW_INIT("ick", "ck_dpll1", &omap1_clk_gate_ops, CLK_IS_CRITICAL),
.ops = &clkops_generic, .ops = &clkops_generic,
.parent = &ck_dpll1,
.enable_reg = OMAP1_IO_ADDRESS(ARM_IDLECT2), .enable_reg = OMAP1_IO_ADDRESS(ARM_IDLECT2),
.enable_bit = EN_GPIOCK, .enable_bit = EN_GPIOCK,
.recalc = &followparent_recalc,
}; };
static struct arm_idlect1_clk armxor_ck = { static struct arm_idlect1_clk armxor_ck = {
.clk = { .clk = {
.name = "armxor_ck", .hw.init = CLK_HW_INIT("armxor_ck", "ck_ref", &omap1_clk_gate_ops,
CLK_IS_CRITICAL),
.ops = &clkops_generic, .ops = &clkops_generic,
.parent = &ck_ref,
.flags = CLOCK_IDLE_CONTROL, .flags = CLOCK_IDLE_CONTROL,
.enable_reg = OMAP1_IO_ADDRESS(ARM_IDLECT2), .enable_reg = OMAP1_IO_ADDRESS(ARM_IDLECT2),
.enable_bit = EN_XORPCK, .enable_bit = EN_XORPCK,
.recalc = &followparent_recalc,
}, },
.idlect_shift = IDLXORP_ARM_SHIFT, .idlect_shift = IDLXORP_ARM_SHIFT,
}; };
static struct arm_idlect1_clk armtim_ck = { static struct arm_idlect1_clk armtim_ck = {
.clk = { .clk = {
.name = "armtim_ck", .hw.init = CLK_HW_INIT("armtim_ck", "ck_ref", &omap1_clk_gate_ops,
CLK_IS_CRITICAL),
.ops = &clkops_generic, .ops = &clkops_generic,
.parent = &ck_ref,
.flags = CLOCK_IDLE_CONTROL, .flags = CLOCK_IDLE_CONTROL,
.enable_reg = OMAP1_IO_ADDRESS(ARM_IDLECT2), .enable_reg = OMAP1_IO_ADDRESS(ARM_IDLECT2),
.enable_bit = EN_TIMCK, .enable_bit = EN_TIMCK,
.recalc = &followparent_recalc,
}, },
.idlect_shift = IDLTIM_ARM_SHIFT, .idlect_shift = IDLTIM_ARM_SHIFT,
}; };
static struct arm_idlect1_clk armwdt_ck = { static struct arm_idlect1_clk armwdt_ck = {
.clk = { .clk = {
.name = "armwdt_ck", .hw.init = CLK_HW_INIT("armwdt_ck", "ck_ref", &omap1_clk_full_ops, 0),
.ops = &clkops_generic, .ops = &clkops_generic,
.parent = &ck_ref,
.flags = CLOCK_IDLE_CONTROL, .flags = CLOCK_IDLE_CONTROL,
.enable_reg = OMAP1_IO_ADDRESS(ARM_IDLECT2), .enable_reg = OMAP1_IO_ADDRESS(ARM_IDLECT2),
.enable_bit = EN_WDTCK, .enable_bit = EN_WDTCK,
...@@ -190,11 +185,8 @@ static struct arm_idlect1_clk armwdt_ck = { ...@@ -190,11 +185,8 @@ static struct arm_idlect1_clk armwdt_ck = {
.idlect_shift = IDLWDT_ARM_SHIFT, .idlect_shift = IDLWDT_ARM_SHIFT,
}; };
static struct clk arminth_ck16xx = { static struct omap1_clk arminth_ck16xx = {
.name = "arminth_ck", .hw.init = CLK_HW_INIT("arminth_ck", "arm_ck", &omap1_clk_null_ops, 0),
.ops = &clkops_null,
.parent = &arm_ck,
.recalc = &followparent_recalc,
/* Note: On 16xx the frequency can be divided by 2 by programming /* Note: On 16xx the frequency can be divided by 2 by programming
* ARM_CKCTL:ARM_INTHCK_SEL(14) to 1 * ARM_CKCTL:ARM_INTHCK_SEL(14) to 1
* *
...@@ -202,10 +194,9 @@ static struct clk arminth_ck16xx = { ...@@ -202,10 +194,9 @@ static struct clk arminth_ck16xx = {
*/ */
}; };
static struct clk dsp_ck = { static struct omap1_clk dsp_ck = {
.name = "dsp_ck", .hw.init = CLK_HW_INIT("dsp_ck", "ck_dpll1", &omap1_clk_full_ops, 0),
.ops = &clkops_generic, .ops = &clkops_generic,
.parent = &ck_dpll1,
.enable_reg = OMAP1_IO_ADDRESS(ARM_CKCTL), .enable_reg = OMAP1_IO_ADDRESS(ARM_CKCTL),
.enable_bit = EN_DSPCK, .enable_bit = EN_DSPCK,
.rate_offset = CKCTL_DSPDIV_OFFSET, .rate_offset = CKCTL_DSPDIV_OFFSET,
...@@ -214,20 +205,17 @@ static struct clk dsp_ck = { ...@@ -214,20 +205,17 @@ static struct clk dsp_ck = {
.set_rate = omap1_clk_set_rate_ckctl_arm, .set_rate = omap1_clk_set_rate_ckctl_arm,
}; };
static struct clk dspmmu_ck = { static struct omap1_clk dspmmu_ck = {
.name = "dspmmu_ck", .hw.init = CLK_HW_INIT("dspmmu_ck", "ck_dpll1", &omap1_clk_rate_ops, 0),
.ops = &clkops_null,
.parent = &ck_dpll1,
.rate_offset = CKCTL_DSPMMUDIV_OFFSET, .rate_offset = CKCTL_DSPMMUDIV_OFFSET,
.recalc = &omap1_ckctl_recalc, .recalc = &omap1_ckctl_recalc,
.round_rate = omap1_clk_round_rate_ckctl_arm, .round_rate = omap1_clk_round_rate_ckctl_arm,
.set_rate = omap1_clk_set_rate_ckctl_arm, .set_rate = omap1_clk_set_rate_ckctl_arm,
}; };
static struct clk dspper_ck = { static struct omap1_clk dspper_ck = {
.name = "dspper_ck", .hw.init = CLK_HW_INIT("dspper_ck", "ck_dpll1", &omap1_clk_full_ops, 0),
.ops = &clkops_dspck, .ops = &clkops_dspck,
.parent = &ck_dpll1,
.enable_reg = DSP_IDLECT2, .enable_reg = DSP_IDLECT2,
.enable_bit = EN_PERCK, .enable_bit = EN_PERCK,
.rate_offset = CKCTL_PERDIV_OFFSET, .rate_offset = CKCTL_PERDIV_OFFSET,
...@@ -236,29 +224,23 @@ static struct clk dspper_ck = { ...@@ -236,29 +224,23 @@ static struct clk dspper_ck = {
.set_rate = &omap1_clk_set_rate_dsp_domain, .set_rate = &omap1_clk_set_rate_dsp_domain,
}; };
static struct clk dspxor_ck = { static struct omap1_clk dspxor_ck = {
.name = "dspxor_ck", .hw.init = CLK_HW_INIT("dspxor_ck", "ck_ref", &omap1_clk_gate_ops, 0),
.ops = &clkops_dspck, .ops = &clkops_dspck,
.parent = &ck_ref,
.enable_reg = DSP_IDLECT2, .enable_reg = DSP_IDLECT2,
.enable_bit = EN_XORPCK, .enable_bit = EN_XORPCK,
.recalc = &followparent_recalc,
}; };
static struct clk dsptim_ck = { static struct omap1_clk dsptim_ck = {
.name = "dsptim_ck", .hw.init = CLK_HW_INIT("dsptim_ck", "ck_ref", &omap1_clk_gate_ops, 0),
.ops = &clkops_dspck, .ops = &clkops_dspck,
.parent = &ck_ref,
.enable_reg = DSP_IDLECT2, .enable_reg = DSP_IDLECT2,
.enable_bit = EN_DSPTIMCK, .enable_bit = EN_DSPTIMCK,
.recalc = &followparent_recalc,
}; };
static struct arm_idlect1_clk tc_ck = { static struct arm_idlect1_clk tc_ck = {
.clk = { .clk = {
.name = "tc_ck", .hw.init = CLK_HW_INIT("tc_ck", "ck_dpll1", &omap1_clk_rate_ops, 0),
.ops = &clkops_null,
.parent = &ck_dpll1,
.flags = CLOCK_IDLE_CONTROL, .flags = CLOCK_IDLE_CONTROL,
.rate_offset = CKCTL_TCDIV_OFFSET, .rate_offset = CKCTL_TCDIV_OFFSET,
.recalc = &omap1_ckctl_recalc, .recalc = &omap1_ckctl_recalc,
...@@ -268,116 +250,88 @@ static struct arm_idlect1_clk tc_ck = { ...@@ -268,116 +250,88 @@ static struct arm_idlect1_clk tc_ck = {
.idlect_shift = IDLIF_ARM_SHIFT, .idlect_shift = IDLIF_ARM_SHIFT,
}; };
static struct clk arminth_ck1510 = { static struct omap1_clk arminth_ck1510 = {
.name = "arminth_ck", .hw.init = CLK_HW_INIT("arminth_ck", "tc_ck", &omap1_clk_null_ops, 0),
.ops = &clkops_null,
.parent = &tc_ck.clk,
.recalc = &followparent_recalc,
/* Note: On 1510 the frequency follows TC_CK /* Note: On 1510 the frequency follows TC_CK
* *
* 16xx version is in MPU clocks. * 16xx version is in MPU clocks.
*/ */
}; };
static struct clk tipb_ck = { static struct omap1_clk tipb_ck = {
/* No-idle controlled by "tc_ck" */ /* No-idle controlled by "tc_ck" */
.name = "tipb_ck", .hw.init = CLK_HW_INIT("tipb_ck", "tc_ck", &omap1_clk_null_ops, 0),
.ops = &clkops_null,
.parent = &tc_ck.clk,
.recalc = &followparent_recalc,
}; };
static struct clk l3_ocpi_ck = { static struct omap1_clk l3_ocpi_ck = {
/* No-idle controlled by "tc_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, .ops = &clkops_generic,
.parent = &tc_ck.clk,
.enable_reg = OMAP1_IO_ADDRESS(ARM_IDLECT3), .enable_reg = OMAP1_IO_ADDRESS(ARM_IDLECT3),
.enable_bit = EN_OCPI_CK, .enable_bit = EN_OCPI_CK,
.recalc = &followparent_recalc,
}; };
static struct clk tc1_ck = { static struct omap1_clk tc1_ck = {
.name = "tc1_ck", .hw.init = CLK_HW_INIT("tc1_ck", "tc_ck", &omap1_clk_gate_ops, 0),
.ops = &clkops_generic, .ops = &clkops_generic,
.parent = &tc_ck.clk,
.enable_reg = OMAP1_IO_ADDRESS(ARM_IDLECT3), .enable_reg = OMAP1_IO_ADDRESS(ARM_IDLECT3),
.enable_bit = EN_TC1_CK, .enable_bit = EN_TC1_CK,
.recalc = &followparent_recalc,
}; };
/* /*
* FIXME: This clock seems to be necessary but no-one has asked for its * FIXME: This clock seems to be necessary but no-one has asked for its
* activation. [ pm.c (SRAM), CCP, Camera ] * 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, .ops = &clkops_generic,
.parent = &tc_ck.clk,
.enable_reg = OMAP1_IO_ADDRESS(ARM_IDLECT3), .enable_reg = OMAP1_IO_ADDRESS(ARM_IDLECT3),
.enable_bit = EN_TC2_CK, .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" */ /* No-idle controlled by "tc_ck" */
.name = "dma_ck", .hw.init = CLK_HW_INIT("dma_ck", "tc_ck", &omap1_clk_null_ops, 0),
.ops = &clkops_null,
.parent = &tc_ck.clk,
.recalc = &followparent_recalc,
}; };
static struct clk dma_lcdfree_ck = { static struct omap1_clk dma_lcdfree_ck = {
.name = "dma_lcdfree_ck", .hw.init = CLK_HW_INIT("dma_lcdfree_ck", "tc_ck", &omap1_clk_null_ops, 0),
.ops = &clkops_null,
.parent = &tc_ck.clk,
.recalc = &followparent_recalc,
}; };
static struct arm_idlect1_clk api_ck = { static struct arm_idlect1_clk api_ck = {
.clk = { .clk = {
.name = "api_ck", .hw.init = CLK_HW_INIT("api_ck", "tc_ck", &omap1_clk_gate_ops, 0),
.ops = &clkops_generic, .ops = &clkops_generic,
.parent = &tc_ck.clk,
.flags = CLOCK_IDLE_CONTROL, .flags = CLOCK_IDLE_CONTROL,
.enable_reg = OMAP1_IO_ADDRESS(ARM_IDLECT2), .enable_reg = OMAP1_IO_ADDRESS(ARM_IDLECT2),
.enable_bit = EN_APICK, .enable_bit = EN_APICK,
.recalc = &followparent_recalc,
}, },
.idlect_shift = IDLAPI_ARM_SHIFT, .idlect_shift = IDLAPI_ARM_SHIFT,
}; };
static struct arm_idlect1_clk lb_ck = { static struct arm_idlect1_clk lb_ck = {
.clk = { .clk = {
.name = "lb_ck", .hw.init = CLK_HW_INIT("lb_ck", "tc_ck", &omap1_clk_gate_ops, 0),
.ops = &clkops_generic, .ops = &clkops_generic,
.parent = &tc_ck.clk,
.flags = CLOCK_IDLE_CONTROL, .flags = CLOCK_IDLE_CONTROL,
.enable_reg = OMAP1_IO_ADDRESS(ARM_IDLECT2), .enable_reg = OMAP1_IO_ADDRESS(ARM_IDLECT2),
.enable_bit = EN_LBCK, .enable_bit = EN_LBCK,
.recalc = &followparent_recalc,
}, },
.idlect_shift = IDLLB_ARM_SHIFT, .idlect_shift = IDLLB_ARM_SHIFT,
}; };
static struct clk rhea1_ck = { static struct omap1_clk rhea1_ck = {
.name = "rhea1_ck", .hw.init = CLK_HW_INIT("rhea1_ck", "tc_ck", &omap1_clk_null_ops, 0),
.ops = &clkops_null,
.parent = &tc_ck.clk,
.recalc = &followparent_recalc,
}; };
static struct clk rhea2_ck = { static struct omap1_clk rhea2_ck = {
.name = "rhea2_ck", .hw.init = CLK_HW_INIT("rhea2_ck", "tc_ck", &omap1_clk_null_ops, 0),
.ops = &clkops_null,
.parent = &tc_ck.clk,
.recalc = &followparent_recalc,
}; };
static struct clk lcd_ck_16xx = { static struct omap1_clk lcd_ck_16xx = {
.name = "lcd_ck", .hw.init = CLK_HW_INIT("lcd_ck", "ck_dpll1", &omap1_clk_full_ops, 0),
.ops = &clkops_generic, .ops = &clkops_generic,
.parent = &ck_dpll1,
.enable_reg = OMAP1_IO_ADDRESS(ARM_IDLECT2), .enable_reg = OMAP1_IO_ADDRESS(ARM_IDLECT2),
.enable_bit = EN_LCDCK, .enable_bit = EN_LCDCK,
.rate_offset = CKCTL_LCDDIV_OFFSET, .rate_offset = CKCTL_LCDDIV_OFFSET,
...@@ -388,9 +342,8 @@ static struct clk lcd_ck_16xx = { ...@@ -388,9 +342,8 @@ static struct clk lcd_ck_16xx = {
static struct arm_idlect1_clk lcd_ck_1510 = { static struct arm_idlect1_clk lcd_ck_1510 = {
.clk = { .clk = {
.name = "lcd_ck", .hw.init = CLK_HW_INIT("lcd_ck", "ck_dpll1", &omap1_clk_full_ops, 0),
.ops = &clkops_generic, .ops = &clkops_generic,
.parent = &ck_dpll1,
.flags = CLOCK_IDLE_CONTROL, .flags = CLOCK_IDLE_CONTROL,
.enable_reg = OMAP1_IO_ADDRESS(ARM_IDLECT2), .enable_reg = OMAP1_IO_ADDRESS(ARM_IDLECT2),
.enable_bit = EN_LCDCK, .enable_bit = EN_LCDCK,
...@@ -402,37 +355,35 @@ static struct arm_idlect1_clk lcd_ck_1510 = { ...@@ -402,37 +355,35 @@ static struct arm_idlect1_clk lcd_ck_1510 = {
.idlect_shift = OMAP1510_IDLLCD_ARM_SHIFT, .idlect_shift = OMAP1510_IDLLCD_ARM_SHIFT,
}; };
/* /*
* XXX The enable_bit here is misused - it simply switches between 12MHz * 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? * XXX does this need SYSC register handling?
*/ */
static struct clk uart1_1510 = { static struct omap1_clk uart1_1510 = {
.name = "uart1_ck",
.ops = &clkops_null,
/* Direct from ULPD, no real parent */ /* 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 = 12000000,
.flags = ENABLE_REG_32BIT | CLOCK_NO_IDLE_PARENT, .flags = ENABLE_REG_32BIT | CLOCK_NO_IDLE_PARENT,
.enable_reg = OMAP1_IO_ADDRESS(MOD_CONF_CTRL_0), .enable_reg = OMAP1_IO_ADDRESS(MOD_CONF_CTRL_0),
.enable_bit = CONF_MOD_UART1_CLK_MODE_R, .enable_bit = CONF_MOD_UART1_CLK_MODE_R,
.round_rate = &omap1_round_uart_rate,
.set_rate = &omap1_set_uart_rate, .set_rate = &omap1_set_uart_rate,
.recalc = &omap1_uart_recalc, .recalc = &omap1_uart_recalc,
}; };
/* /*
* XXX The enable_bit here is misused - it simply switches between 12MHz * 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 * XXX SYSC register handling does not belong in the clock framework
*/ */
static struct uart_clk uart1_16xx = { static struct uart_clk uart1_16xx = {
.clk = { .clk = {
.name = "uart1_ck",
.ops = &clkops_uart_16xx, .ops = &clkops_uart_16xx,
/* Direct from ULPD, no real parent */ /* 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, .rate = 48000000,
.flags = ENABLE_REG_32BIT | CLOCK_NO_IDLE_PARENT, .flags = ENABLE_REG_32BIT | CLOCK_NO_IDLE_PARENT,
.enable_reg = OMAP1_IO_ADDRESS(MOD_CONF_CTRL_0), .enable_reg = OMAP1_IO_ADDRESS(MOD_CONF_CTRL_0),
...@@ -443,54 +394,49 @@ static struct uart_clk uart1_16xx = { ...@@ -443,54 +394,49 @@ static struct uart_clk uart1_16xx = {
/* /*
* XXX The enable_bit here is misused - it simply switches between 12MHz * 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? * XXX does this need SYSC register handling?
*/ */
static struct clk uart2_ck = { static struct omap1_clk uart2_ck = {
.name = "uart2_ck",
.ops = &clkops_null,
/* Direct from ULPD, no real parent */ /* Direct from ULPD, no real parent */
.parent = &armper_ck.clk, .hw.init = CLK_HW_INIT("uart2_ck", "armper_ck", &omap1_clk_full_ops, 0),
.rate = 12000000,
.flags = ENABLE_REG_32BIT | CLOCK_NO_IDLE_PARENT, .flags = ENABLE_REG_32BIT | CLOCK_NO_IDLE_PARENT,
.enable_reg = OMAP1_IO_ADDRESS(MOD_CONF_CTRL_0), .enable_reg = OMAP1_IO_ADDRESS(MOD_CONF_CTRL_0),
.enable_bit = CONF_MOD_UART2_CLK_MODE_R, .enable_bit = CONF_MOD_UART2_CLK_MODE_R,
.round_rate = &omap1_round_uart_rate,
.set_rate = &omap1_set_uart_rate, .set_rate = &omap1_set_uart_rate,
.recalc = &omap1_uart_recalc, .recalc = &omap1_uart_recalc,
}; };
/* /*
* XXX The enable_bit here is misused - it simply switches between 12MHz * 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? * XXX does this need SYSC register handling?
*/ */
static struct clk uart3_1510 = { static struct omap1_clk uart3_1510 = {
.name = "uart3_ck",
.ops = &clkops_null,
/* Direct from ULPD, no real parent */ /* 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 = 12000000,
.flags = ENABLE_REG_32BIT | CLOCK_NO_IDLE_PARENT, .flags = ENABLE_REG_32BIT | CLOCK_NO_IDLE_PARENT,
.enable_reg = OMAP1_IO_ADDRESS(MOD_CONF_CTRL_0), .enable_reg = OMAP1_IO_ADDRESS(MOD_CONF_CTRL_0),
.enable_bit = CONF_MOD_UART3_CLK_MODE_R, .enable_bit = CONF_MOD_UART3_CLK_MODE_R,
.round_rate = &omap1_round_uart_rate,
.set_rate = &omap1_set_uart_rate, .set_rate = &omap1_set_uart_rate,
.recalc = &omap1_uart_recalc, .recalc = &omap1_uart_recalc,
}; };
/* /*
* XXX The enable_bit here is misused - it simply switches between 12MHz * 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 * XXX SYSC register handling does not belong in the clock framework
*/ */
static struct uart_clk uart3_16xx = { static struct uart_clk uart3_16xx = {
.clk = { .clk = {
.name = "uart3_ck",
.ops = &clkops_uart_16xx, .ops = &clkops_uart_16xx,
/* Direct from ULPD, no real parent */ /* 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, .rate = 48000000,
.flags = ENABLE_REG_32BIT | CLOCK_NO_IDLE_PARENT, .flags = ENABLE_REG_32BIT | CLOCK_NO_IDLE_PARENT,
.enable_reg = OMAP1_IO_ADDRESS(MOD_CONF_CTRL_0), .enable_reg = OMAP1_IO_ADDRESS(MOD_CONF_CTRL_0),
...@@ -499,30 +445,30 @@ static struct uart_clk uart3_16xx = { ...@@ -499,30 +445,30 @@ static struct uart_clk uart3_16xx = {
.sysc_addr = 0xfffb9854, .sysc_addr = 0xfffb9854,
}; };
static struct clk usb_clko = { /* 6 MHz output on W4_USB_CLKO */ static struct omap1_clk usb_clko = { /* 6 MHz output on W4_USB_CLKO */
.name = "usb_clko",
.ops = &clkops_generic, .ops = &clkops_generic,
/* Direct from ULPD, no parent */ /* Direct from ULPD, no parent */
.hw.init = CLK_HW_INIT_NO_PARENT("usb_clko", &omap1_clk_full_ops, 0),
.rate = 6000000, .rate = 6000000,
.flags = ENABLE_REG_32BIT, .flags = ENABLE_REG_32BIT,
.enable_reg = OMAP1_IO_ADDRESS(ULPD_CLOCK_CTRL), .enable_reg = OMAP1_IO_ADDRESS(ULPD_CLOCK_CTRL),
.enable_bit = USB_MCLK_EN_BIT, .enable_bit = USB_MCLK_EN_BIT,
}; };
static struct clk usb_hhc_ck1510 = { static struct omap1_clk usb_hhc_ck1510 = {
.name = "usb_hhc_ck",
.ops = &clkops_generic, .ops = &clkops_generic,
/* Direct from ULPD, no parent */ /* 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 */ .rate = 48000000, /* Actually 2 clocks, 12MHz and 48MHz */
.flags = ENABLE_REG_32BIT, .flags = ENABLE_REG_32BIT,
.enable_reg = OMAP1_IO_ADDRESS(MOD_CONF_CTRL_0), .enable_reg = OMAP1_IO_ADDRESS(MOD_CONF_CTRL_0),
.enable_bit = USB_HOST_HHC_UHOST_EN, .enable_bit = USB_HOST_HHC_UHOST_EN,
}; };
static struct clk usb_hhc_ck16xx = { static struct omap1_clk usb_hhc_ck16xx = {
.name = "usb_hhc_ck",
.ops = &clkops_generic, .ops = &clkops_generic,
/* Direct from ULPD, no parent */ /* Direct from ULPD, no parent */
.hw.init = CLK_HW_INIT_NO_PARENT("usb_hhc_ck", &omap1_clk_full_ops, 0),
.rate = 48000000, .rate = 48000000,
/* OTG_SYSCON_2.OTG_PADEN == 0 (not 1510-compatible) */ /* OTG_SYSCON_2.OTG_PADEN == 0 (not 1510-compatible) */
.flags = ENABLE_REG_32BIT, .flags = ENABLE_REG_32BIT,
...@@ -530,46 +476,46 @@ static struct clk usb_hhc_ck16xx = { ...@@ -530,46 +476,46 @@ static struct clk usb_hhc_ck16xx = {
.enable_bit = OTG_SYSCON_2_UHOST_EN_SHIFT .enable_bit = OTG_SYSCON_2_UHOST_EN_SHIFT
}; };
static struct clk usb_dc_ck = { static struct omap1_clk usb_dc_ck = {
.name = "usb_dc_ck",
.ops = &clkops_generic, .ops = &clkops_generic,
/* Direct from ULPD, no parent */ /* Direct from ULPD, no parent */
.hw.init = CLK_HW_INIT_NO_PARENT("usb_dc_ck", &omap1_clk_full_ops, 0),
.rate = 48000000, .rate = 48000000,
.enable_reg = OMAP1_IO_ADDRESS(SOFT_REQ_REG), .enable_reg = OMAP1_IO_ADDRESS(SOFT_REQ_REG),
.enable_bit = SOFT_USB_OTG_DPLL_REQ_SHIFT, .enable_bit = SOFT_USB_OTG_DPLL_REQ_SHIFT,
}; };
static struct clk uart1_7xx = { static struct omap1_clk uart1_7xx = {
.name = "uart1_ck",
.ops = &clkops_generic, .ops = &clkops_generic,
/* Direct from ULPD, no parent */ /* Direct from ULPD, no parent */
.hw.init = CLK_HW_INIT_NO_PARENT("uart1_ck", &omap1_clk_full_ops, 0),
.rate = 12000000, .rate = 12000000,
.enable_reg = OMAP1_IO_ADDRESS(SOFT_REQ_REG), .enable_reg = OMAP1_IO_ADDRESS(SOFT_REQ_REG),
.enable_bit = 9, .enable_bit = 9,
}; };
static struct clk uart2_7xx = { static struct omap1_clk uart2_7xx = {
.name = "uart2_ck",
.ops = &clkops_generic, .ops = &clkops_generic,
/* Direct from ULPD, no parent */ /* Direct from ULPD, no parent */
.hw.init = CLK_HW_INIT_NO_PARENT("uart2_ck", &omap1_clk_full_ops, 0),
.rate = 12000000, .rate = 12000000,
.enable_reg = OMAP1_IO_ADDRESS(SOFT_REQ_REG), .enable_reg = OMAP1_IO_ADDRESS(SOFT_REQ_REG),
.enable_bit = 11, .enable_bit = 11,
}; };
static struct clk mclk_1510 = { static struct omap1_clk mclk_1510 = {
.name = "mclk",
.ops = &clkops_generic, .ops = &clkops_generic,
/* Direct from ULPD, no parent. May be enabled by ext hardware. */ /* 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, .rate = 12000000,
.enable_reg = OMAP1_IO_ADDRESS(SOFT_REQ_REG), .enable_reg = OMAP1_IO_ADDRESS(SOFT_REQ_REG),
.enable_bit = SOFT_COM_MCKO_REQ_SHIFT, .enable_bit = SOFT_COM_MCKO_REQ_SHIFT,
}; };
static struct clk mclk_16xx = { static struct omap1_clk mclk_16xx = {
.name = "mclk",
.ops = &clkops_generic, .ops = &clkops_generic,
/* Direct from ULPD, no parent. May be enabled by ext hardware. */ /* 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_reg = OMAP1_IO_ADDRESS(COM_CLK_DIV_CTRL_SEL),
.enable_bit = COM_ULPD_PLL_CLK_REQ, .enable_bit = COM_ULPD_PLL_CLK_REQ,
.set_rate = &omap1_set_ext_clk_rate, .set_rate = &omap1_set_ext_clk_rate,
...@@ -577,17 +523,16 @@ static struct clk mclk_16xx = { ...@@ -577,17 +523,16 @@ static struct clk mclk_16xx = {
.init = &omap1_init_ext_clk, .init = &omap1_init_ext_clk,
}; };
static struct clk bclk_1510 = { static struct omap1_clk bclk_1510 = {
.name = "bclk",
.ops = &clkops_generic,
/* Direct from ULPD, no parent. May be enabled by ext hardware. */ /* 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, .rate = 12000000,
}; };
static struct clk bclk_16xx = { static struct omap1_clk bclk_16xx = {
.name = "bclk",
.ops = &clkops_generic, .ops = &clkops_generic,
/* Direct from ULPD, no parent. May be enabled by ext hardware. */ /* 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_reg = OMAP1_IO_ADDRESS(SWD_CLK_DIV_CTRL_SEL),
.enable_bit = SWD_ULPD_PLL_CLK_REQ, .enable_bit = SWD_ULPD_PLL_CLK_REQ,
.set_rate = &omap1_set_ext_clk_rate, .set_rate = &omap1_set_ext_clk_rate,
...@@ -595,11 +540,10 @@ static struct clk bclk_16xx = { ...@@ -595,11 +540,10 @@ static struct clk bclk_16xx = {
.init = &omap1_init_ext_clk, .init = &omap1_init_ext_clk,
}; };
static struct clk mmc1_ck = { static struct omap1_clk mmc1_ck = {
.name = "mmc1_ck",
.ops = &clkops_generic, .ops = &clkops_generic,
/* Functional clock is direct from ULPD, interface clock is ARMPER */ /* 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, .rate = 48000000,
.flags = ENABLE_REG_32BIT | CLOCK_NO_IDLE_PARENT, .flags = ENABLE_REG_32BIT | CLOCK_NO_IDLE_PARENT,
.enable_reg = OMAP1_IO_ADDRESS(MOD_CONF_CTRL_0), .enable_reg = OMAP1_IO_ADDRESS(MOD_CONF_CTRL_0),
...@@ -610,32 +554,29 @@ static struct clk mmc1_ck = { ...@@ -610,32 +554,29 @@ static struct clk mmc1_ck = {
* XXX MOD_CONF_CTRL_0 bit 20 is defined in the 1510 TRM as * XXX MOD_CONF_CTRL_0 bit 20 is defined in the 1510 TRM as
* CONF_MOD_MCBSP3_AUXON ?? * CONF_MOD_MCBSP3_AUXON ??
*/ */
static struct clk mmc2_ck = { static struct omap1_clk mmc2_ck = {
.name = "mmc2_ck",
.ops = &clkops_generic, .ops = &clkops_generic,
/* Functional clock is direct from ULPD, interface clock is ARMPER */ /* 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, .rate = 48000000,
.flags = ENABLE_REG_32BIT | CLOCK_NO_IDLE_PARENT, .flags = ENABLE_REG_32BIT | CLOCK_NO_IDLE_PARENT,
.enable_reg = OMAP1_IO_ADDRESS(MOD_CONF_CTRL_0), .enable_reg = OMAP1_IO_ADDRESS(MOD_CONF_CTRL_0),
.enable_bit = 20, .enable_bit = 20,
}; };
static struct clk mmc3_ck = { static struct omap1_clk mmc3_ck = {
.name = "mmc3_ck",
.ops = &clkops_generic, .ops = &clkops_generic,
/* Functional clock is direct from ULPD, interface clock is ARMPER */ /* 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, .rate = 48000000,
.flags = ENABLE_REG_32BIT | CLOCK_NO_IDLE_PARENT, .flags = ENABLE_REG_32BIT | CLOCK_NO_IDLE_PARENT,
.enable_reg = OMAP1_IO_ADDRESS(SOFT_REQ_REG), .enable_reg = OMAP1_IO_ADDRESS(SOFT_REQ_REG),
.enable_bit = SOFT_MMC_DPLL_REQ_SHIFT, .enable_bit = SOFT_MMC_DPLL_REQ_SHIFT,
}; };
static struct clk virtual_ck_mpu = { static struct omap1_clk virtual_ck_mpu = {
.name = "mpu", /* Is smarter alias for arm_ck */
.ops = &clkops_null, .hw.init = CLK_HW_INIT("mpu", "arm_ck", &omap1_clk_rate_ops, 0),
.parent = &arm_ck, /* Is smarter alias for */
.recalc = &followparent_recalc, .recalc = &followparent_recalc,
.set_rate = &omap1_select_table_rate, .set_rate = &omap1_select_table_rate,
.round_rate = &omap1_round_to_table_rate, .round_rate = &omap1_round_to_table_rate,
...@@ -643,20 +584,14 @@ static struct clk virtual_ck_mpu = { ...@@ -643,20 +584,14 @@ static struct clk virtual_ck_mpu = {
/* virtual functional clock domain for I2C. Just for making sure that ARMXOR_CK /* virtual functional clock domain for I2C. Just for making sure that ARMXOR_CK
remains active during MPU idle whenever this is enabled */ remains active during MPU idle whenever this is enabled */
static struct clk i2c_fck = { static struct omap1_clk i2c_fck = {
.name = "i2c_fck", .hw.init = CLK_HW_INIT("i2c_fck", "armxor_ck", &omap1_clk_gate_ops, 0),
.ops = &clkops_null,
.flags = CLOCK_NO_IDLE_PARENT, .flags = CLOCK_NO_IDLE_PARENT,
.parent = &armxor_ck.clk,
.recalc = &followparent_recalc,
}; };
static struct clk i2c_ick = { static struct omap1_clk i2c_ick = {
.name = "i2c_ick", .hw.init = CLK_HW_INIT("i2c_ick", "armper_ck", &omap1_clk_gate_ops, 0),
.ops = &clkops_null,
.flags = CLOCK_NO_IDLE_PARENT, .flags = CLOCK_NO_IDLE_PARENT,
.parent = &armper_ck.clk,
.recalc = &followparent_recalc,
}; };
/* /*
...@@ -665,81 +600,81 @@ static struct clk i2c_ick = { ...@@ -665,81 +600,81 @@ static struct clk i2c_ick = {
static struct omap_clk omap_clks[] = { static struct omap_clk omap_clks[] = {
/* non-ULPD clocks */ /* non-ULPD clocks */
CLK(NULL, "ck_ref", &ck_ref, 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, 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 */ /* CK_GEN1 clocks */
CLK(NULL, "ck_dpll1out", &ck_dpll1out.clk, CK_16XX), CLK(NULL, "ck_dpll1out", &ck_dpll1out.clk.hw, CK_16XX),
CLK(NULL, "ck_sossi", &sossi_ck, CK_16XX), CLK(NULL, "ck_sossi", &sossi_ck.hw, CK_16XX),
CLK(NULL, "arm_ck", &arm_ck, CK_16XX | CK_1510 | CK_310), CLK(NULL, "arm_ck", &arm_ck.hw, CK_16XX | CK_1510 | CK_310),
CLK(NULL, "armper_ck", &armper_ck.clk, 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, CK_1510 | CK_310), CLK("omap_gpio.0", "ick", &arm_gpio_ck.hw, CK_1510 | CK_310),
CLK(NULL, "armxor_ck", &armxor_ck.clk, CK_16XX | CK_1510 | CK_310 | CK_7XX), CLK(NULL, "armxor_ck", &armxor_ck.clk.hw, CK_16XX | CK_1510 | CK_310 | CK_7XX),
CLK(NULL, "armtim_ck", &armtim_ck.clk, CK_16XX | CK_1510 | CK_310), CLK(NULL, "armtim_ck", &armtim_ck.clk.hw, CK_16XX | CK_1510 | CK_310),
CLK("omap_wdt", "fck", &armwdt_ck.clk, 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, CK_16XX), CLK("omap_wdt", "ick", &armper_ck.clk.hw, CK_16XX),
CLK("omap_wdt", "ick", &dummy_ck, CK_1510 | CK_310), CLK("omap_wdt", "ick", &dummy_ck.hw, CK_1510 | CK_310),
CLK(NULL, "arminth_ck", &arminth_ck1510, CK_1510 | CK_310), CLK(NULL, "arminth_ck", &arminth_ck1510.hw, CK_1510 | CK_310),
CLK(NULL, "arminth_ck", &arminth_ck16xx, CK_16XX), CLK(NULL, "arminth_ck", &arminth_ck16xx.hw, CK_16XX),
/* CK_GEN2 clocks */ /* CK_GEN2 clocks */
CLK(NULL, "dsp_ck", &dsp_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, 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, 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, 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, CK_16XX | CK_1510 | CK_310), CLK(NULL, "dsptim_ck", &dsptim_ck.hw, CK_16XX | CK_1510 | CK_310),
/* CK_GEN3 clocks */ /* CK_GEN3 clocks */
CLK(NULL, "tc_ck", &tc_ck.clk, CK_16XX | CK_1510 | CK_310 | CK_7XX), CLK(NULL, "tc_ck", &tc_ck.clk.hw, CK_16XX | CK_1510 | CK_310 | CK_7XX),
CLK(NULL, "tipb_ck", &tipb_ck, CK_1510 | CK_310), CLK(NULL, "tipb_ck", &tipb_ck.hw, CK_1510 | CK_310),
CLK(NULL, "l3_ocpi_ck", &l3_ocpi_ck, CK_16XX | CK_7XX), CLK(NULL, "l3_ocpi_ck", &l3_ocpi_ck.hw, CK_16XX | CK_7XX),
CLK(NULL, "tc1_ck", &tc1_ck, CK_16XX), CLK(NULL, "tc1_ck", &tc1_ck.hw, CK_16XX),
CLK(NULL, "tc2_ck", &tc2_ck, CK_16XX), CLK(NULL, "tc2_ck", &tc2_ck.hw, CK_16XX),
CLK(NULL, "dma_ck", &dma_ck, CK_16XX | CK_1510 | CK_310), CLK(NULL, "dma_ck", &dma_ck.hw, CK_16XX | CK_1510 | CK_310),
CLK(NULL, "dma_lcdfree_ck", &dma_lcdfree_ck, CK_16XX), CLK(NULL, "dma_lcdfree_ck", &dma_lcdfree_ck.hw, CK_16XX),
CLK(NULL, "api_ck", &api_ck.clk, CK_16XX | CK_1510 | CK_310 | CK_7XX), CLK(NULL, "api_ck", &api_ck.clk.hw, CK_16XX | CK_1510 | CK_310 | CK_7XX),
CLK(NULL, "lb_ck", &lb_ck.clk, CK_1510 | CK_310), CLK(NULL, "lb_ck", &lb_ck.clk.hw, CK_1510 | CK_310),
CLK(NULL, "rhea1_ck", &rhea1_ck, CK_16XX), CLK(NULL, "rhea1_ck", &rhea1_ck.hw, CK_16XX),
CLK(NULL, "rhea2_ck", &rhea2_ck, CK_16XX), CLK(NULL, "rhea2_ck", &rhea2_ck.hw, CK_16XX),
CLK(NULL, "lcd_ck", &lcd_ck_16xx, CK_16XX | CK_7XX), CLK(NULL, "lcd_ck", &lcd_ck_16xx.hw, CK_16XX | CK_7XX),
CLK(NULL, "lcd_ck", &lcd_ck_1510.clk, CK_1510 | CK_310), CLK(NULL, "lcd_ck", &lcd_ck_1510.clk.hw, CK_1510 | CK_310),
/* ULPD clocks */ /* ULPD clocks */
CLK(NULL, "uart1_ck", &uart1_1510, CK_1510 | CK_310), CLK(NULL, "uart1_ck", &uart1_1510.hw, CK_1510 | CK_310),
CLK(NULL, "uart1_ck", &uart1_16xx.clk, CK_16XX), CLK(NULL, "uart1_ck", &uart1_16xx.clk.hw, CK_16XX),
CLK(NULL, "uart1_ck", &uart1_7xx, CK_7XX), CLK(NULL, "uart1_ck", &uart1_7xx.hw, CK_7XX),
CLK(NULL, "uart2_ck", &uart2_ck, CK_16XX | CK_1510 | CK_310), CLK(NULL, "uart2_ck", &uart2_ck.hw, CK_16XX | CK_1510 | CK_310),
CLK(NULL, "uart2_ck", &uart2_7xx, CK_7XX), CLK(NULL, "uart2_ck", &uart2_7xx.hw, CK_7XX),
CLK(NULL, "uart3_ck", &uart3_1510, CK_1510 | CK_310), CLK(NULL, "uart3_ck", &uart3_1510.hw, CK_1510 | CK_310),
CLK(NULL, "uart3_ck", &uart3_16xx.clk, CK_16XX), CLK(NULL, "uart3_ck", &uart3_16xx.clk.hw, CK_16XX),
CLK(NULL, "usb_clko", &usb_clko, CK_16XX | CK_1510 | CK_310), CLK(NULL, "usb_clko", &usb_clko.hw, 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_ck1510.hw, CK_1510 | CK_310),
CLK(NULL, "usb_hhc_ck", &usb_hhc_ck16xx, CK_16XX), CLK(NULL, "usb_hhc_ck", &usb_hhc_ck16xx.hw, CK_16XX),
CLK(NULL, "usb_dc_ck", &usb_dc_ck, CK_16XX | CK_7XX), CLK(NULL, "usb_dc_ck", &usb_dc_ck.hw, CK_16XX | CK_7XX),
CLK(NULL, "mclk", &mclk_1510, CK_1510 | CK_310), CLK(NULL, "mclk", &mclk_1510.hw, CK_1510 | CK_310),
CLK(NULL, "mclk", &mclk_16xx, CK_16XX), CLK(NULL, "mclk", &mclk_16xx.hw, CK_16XX),
CLK(NULL, "bclk", &bclk_1510, CK_1510 | CK_310), CLK(NULL, "bclk", &bclk_1510.hw, CK_1510 | CK_310),
CLK(NULL, "bclk", &bclk_16xx, CK_16XX), CLK(NULL, "bclk", &bclk_16xx.hw, CK_16XX),
CLK("mmci-omap.0", "fck", &mmc1_ck, CK_16XX | CK_1510 | CK_310), CLK("mmci-omap.0", "fck", &mmc1_ck.hw, CK_16XX | CK_1510 | CK_310),
CLK("mmci-omap.0", "fck", &mmc3_ck, CK_7XX), CLK("mmci-omap.0", "fck", &mmc3_ck.hw, CK_7XX),
CLK("mmci-omap.0", "ick", &armper_ck.clk, CK_16XX | CK_1510 | CK_310 | 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, CK_16XX), CLK("mmci-omap.1", "fck", &mmc2_ck.hw, CK_16XX),
CLK("mmci-omap.1", "ick", &armper_ck.clk, CK_16XX), CLK("mmci-omap.1", "ick", &armper_ck.clk.hw, CK_16XX),
/* Virtual clocks */ /* Virtual clocks */
CLK(NULL, "mpu", &virtual_ck_mpu, 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, CK_16XX | CK_1510 | CK_310 | CK_7XX), CLK("omap_i2c.1", "fck", &i2c_fck.hw, CK_16XX | CK_1510 | CK_310 | CK_7XX),
CLK("omap_i2c.1", "ick", &i2c_ick, CK_16XX), CLK("omap_i2c.1", "ick", &i2c_ick.hw, CK_16XX),
CLK("omap_i2c.1", "ick", &dummy_ck, CK_1510 | CK_310 | CK_7XX), CLK("omap_i2c.1", "ick", &dummy_ck.hw, CK_1510 | CK_310 | CK_7XX),
CLK("omap1_spi100k.1", "fck", &dummy_ck, CK_7XX), CLK("omap1_spi100k.1", "fck", &dummy_ck.hw, CK_7XX),
CLK("omap1_spi100k.1", "ick", &dummy_ck, CK_7XX), CLK("omap1_spi100k.1", "ick", &dummy_ck.hw, CK_7XX),
CLK("omap1_spi100k.2", "fck", &dummy_ck, CK_7XX), CLK("omap1_spi100k.2", "fck", &dummy_ck.hw, CK_7XX),
CLK("omap1_spi100k.2", "ick", &dummy_ck, CK_7XX), CLK("omap1_spi100k.2", "ick", &dummy_ck.hw, CK_7XX),
CLK("omap_uwire", "fck", &armxor_ck.clk, CK_16XX | CK_1510 | CK_310), CLK("omap_uwire", "fck", &armxor_ck.clk.hw, CK_16XX | CK_1510 | CK_310),
CLK("omap-mcbsp.1", "ick", &dspper_ck, CK_16XX), CLK("omap-mcbsp.1", "ick", &dspper_ck.hw, CK_16XX),
CLK("omap-mcbsp.1", "ick", &dummy_ck, CK_1510 | CK_310), CLK("omap-mcbsp.1", "ick", &dummy_ck.hw, CK_1510 | CK_310),
CLK("omap-mcbsp.2", "ick", &armper_ck.clk, CK_16XX), CLK("omap-mcbsp.2", "ick", &armper_ck.clk.hw, CK_16XX),
CLK("omap-mcbsp.2", "ick", &dummy_ck, CK_1510 | CK_310), CLK("omap-mcbsp.2", "ick", &dummy_ck.hw, CK_1510 | CK_310),
CLK("omap-mcbsp.3", "ick", &dspper_ck, CK_16XX), CLK("omap-mcbsp.3", "ick", &dspper_ck.hw, CK_16XX),
CLK("omap-mcbsp.3", "ick", &dummy_ck, CK_1510 | CK_310), CLK("omap-mcbsp.3", "ick", &dummy_ck.hw, CK_1510 | CK_310),
CLK("omap-mcbsp.1", "fck", &dspxor_ck, CK_16XX | 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, 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, 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) ...@@ -778,9 +713,6 @@ int __init omap1_clk_init(void)
/* By default all idlect1 clocks are allowed to idle */ /* By default all idlect1 clocks are allowed to idle */
arm_idlect1_mask = ~0; arm_idlect1_mask = ~0;
for (c = omap_clks; c < omap_clks + ARRAY_SIZE(omap_clks); c++)
clk_preinit(c->lk.clk);
cpu_mask = 0; cpu_mask = 0;
if (cpu_is_omap1710()) if (cpu_is_omap1710())
cpu_mask |= CK_1710; cpu_mask |= CK_1710;
...@@ -793,16 +725,10 @@ int __init omap1_clk_init(void) ...@@ -793,16 +725,10 @@ int __init omap1_clk_init(void)
if (cpu_is_omap310()) if (cpu_is_omap310())
cpu_mask |= CK_310; 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 */ /* Pointers to these clocks are needed by code in clock.c */
api_ck_p = clk_get(NULL, "api_ck"); api_ck_p = &api_ck.clk;
ck_dpll1_p = clk_get(NULL, "ck_dpll1"); ck_dpll1_p = &ck_dpll1;
ck_ref_p = clk_get(NULL, "ck_ref"); ck_ref_p = &ck_ref;
if (cpu_is_omap7xx()) if (cpu_is_omap7xx())
ck_ref.rate = 13000000; ck_ref.rate = 13000000;
...@@ -844,10 +770,7 @@ int __init omap1_clk_init(void) ...@@ -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()) { if (machine_is_omap_perseus2() || machine_is_omap_fsample()) {
/* Select slicer output as OMAP input clock */ /* Select slicer output as OMAP input clock */
omap_writew(omap_readw(OMAP7XX_PCC_UPLD_CTRL) & ~0x1, omap_writew(omap_readw(OMAP7XX_PCC_UPLD_CTRL) & ~0x1,
...@@ -879,16 +802,28 @@ int __init omap1_clk_init(void) ...@@ -879,16 +802,28 @@ int __init omap1_clk_init(void)
*/ */
omap_writew(0x0000, ARM_IDLECT2); /* Turn LCD clock off also */ omap_writew(0x0000, ARM_IDLECT2); /* Turn LCD clock off also */
/* for (c = omap_clks; c < omap_clks + ARRAY_SIZE(omap_clks); c++) {
* Only enable those clocks we will need, let the drivers if (!(c->cpu & cpu_mask))
* enable other clocks as necessary continue;
*/
clk_enable(&armper_ck.clk); if (c->lk.clk_hw->init) { /* NULL if provider already registered */
clk_enable(&armxor_ck.clk); const struct clk_init_data *init = c->lk.clk_hw->init;
clk_enable(&armtim_ck.clk); /* This should be done by timer code */ 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);
}
if (cpu_is_omap15xx()) omap1_show_rates();
clk_enable(&arm_gpio_ck);
return 0; return 0;
} }
...@@ -900,7 +835,7 @@ void __init omap1_clk_late_init(void) ...@@ -900,7 +835,7 @@ void __init omap1_clk_late_init(void)
unsigned long rate = ck_dpll1.rate; unsigned long rate = ck_dpll1.rate;
/* Find the highest supported frequency and enable it */ /* 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"); pr_err("System frequencies not set, using default. Check your config.\n");
/* /*
* Reprogramming the DPLL is tricky, it must be done from SRAM. * Reprogramming the DPLL is tricky, it must be done from SRAM.
......
...@@ -64,7 +64,7 @@ static inline u32 omap_cs3_phys(void) ...@@ -64,7 +64,7 @@ static inline u32 omap_cs3_phys(void)
#define OMAP1_IO_OFFSET 0x00f00000 /* Virtual IO = 0xff0b0000 */ #define OMAP1_IO_OFFSET 0x00f00000 /* Virtual IO = 0xff0b0000 */
#define OMAP1_IO_ADDRESS(pa) IOMEM((pa) - OMAP1_IO_OFFSET) #define OMAP1_IO_ADDRESS(pa) IOMEM((pa) - OMAP1_IO_OFFSET)
#include <mach/serial.h> #include "serial.h"
/* /*
* --------------------------------------------------------------------------- * ---------------------------------------------------------------------------
......
/*
* arch/arm/plat-omap/include/mach/uncompress.h
*
* Serial port stubs for kernel decompress status messages
*
* Initially based on:
* linux-2.4.15-rmk1-dsplinux1.6/arch/arm/plat-omap/include/mach1510/uncompress.h
* Copyright (C) 2000 RidgeRun, Inc.
* Author: Greg Lonnon <glonnon@ridgerun.com>
*
* Rewritten by:
* Author: <source@mvista.com>
* 2004 (c) MontaVista Software, Inc.
*
* This file is licensed under the terms of the GNU General Public License
* version 2. This program is licensed "as is" without any warranty of any
* kind, whether express or implied.
*/
#include <linux/types.h>
#include <linux/serial_reg.h>
#include <asm/memory.h>
#include <asm/mach-types.h>
#include "serial.h"
#define MDR1_MODE_MASK 0x07
volatile u8 *uart_base;
int uart_shift;
/*
* Store the DEBUG_LL uart number into memory.
* See also debug-macro.S, and serial.c for related code.
*/
static void set_omap_uart_info(unsigned char port)
{
/*
* Get address of some.bss variable and round it down
* a la CONFIG_AUTO_ZRELADDR.
*/
u32 ram_start = (u32)&uart_shift & 0xf8000000;
u32 *uart_info = (u32 *)(ram_start + OMAP_UART_INFO_OFS);
*uart_info = port;
}
static inline void putc(int c)
{
if (!uart_base)
return;
/* Check for UART 16x mode */
if ((uart_base[UART_OMAP_MDR1 << uart_shift] & MDR1_MODE_MASK) != 0)
return;
while (!(uart_base[UART_LSR << uart_shift] & UART_LSR_THRE))
barrier();
uart_base[UART_TX << uart_shift] = c;
}
static inline void flush(void)
{
}
/*
* Macros to configure UART1 and debug UART
*/
#define _DEBUG_LL_ENTRY(mach, dbg_uart, dbg_shft, dbg_id) \
if (machine_is_##mach()) { \
uart_base = (volatile u8 *)(dbg_uart); \
uart_shift = (dbg_shft); \
port = (dbg_id); \
set_omap_uart_info(port); \
break; \
}
#define DEBUG_LL_OMAP7XX(p, mach) \
_DEBUG_LL_ENTRY(mach, OMAP1_UART##p##_BASE, OMAP7XX_PORT_SHIFT, \
OMAP1UART##p)
#define DEBUG_LL_OMAP1(p, mach) \
_DEBUG_LL_ENTRY(mach, OMAP1_UART##p##_BASE, OMAP_PORT_SHIFT, \
OMAP1UART##p)
static inline void arch_decomp_setup(void)
{
int port = 0;
/*
* Initialize the port based on the machine ID from the bootloader.
* Note that we're using macros here instead of switch statement
* as machine_is functions are optimized out for the boards that
* are not selected.
*/
do {
/* omap7xx/8xx based boards using UART1 with shift 0 */
DEBUG_LL_OMAP7XX(1, herald);
DEBUG_LL_OMAP7XX(1, omap_perseus2);
/* omap15xx/16xx based boards using UART1 */
DEBUG_LL_OMAP1(1, ams_delta);
DEBUG_LL_OMAP1(1, nokia770);
DEBUG_LL_OMAP1(1, omap_h2);
DEBUG_LL_OMAP1(1, omap_h3);
DEBUG_LL_OMAP1(1, omap_innovator);
DEBUG_LL_OMAP1(1, omap_osk);
DEBUG_LL_OMAP1(1, omap_palmte);
DEBUG_LL_OMAP1(1, omap_palmz71);
/* omap15xx/16xx based boards using UART2 */
DEBUG_LL_OMAP1(2, omap_palmtt);
/* omap15xx/16xx based boards using UART3 */
DEBUG_LL_OMAP1(3, sx1);
} while (0);
}
...@@ -15,10 +15,8 @@ ...@@ -15,10 +15,8 @@
#include <asm/mach/map.h> #include <asm/mach/map.h>
#include "tc.h" #include "tc.h"
#include "mux.h"
#include "iomap.h" #include "iomap.h"
#include "common.h" #include "common.h"
#include "clock.h"
/* /*
* The machine specific code may provide the extra mapping besides the * The machine specific code may provide the extra mapping besides the
...@@ -125,11 +123,6 @@ void __init omap1_init_early(void) ...@@ -125,11 +123,6 @@ void __init omap1_init_early(void)
*/ */
omap_writew(0x0, MPU_PUBLIC_TIPB_CNTL); omap_writew(0x0, MPU_PUBLIC_TIPB_CNTL);
omap_writew(0x0, MPU_PRIVATE_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) void __init omap1_init_late(void)
......
...@@ -19,8 +19,7 @@ ...@@ -19,8 +19,7 @@
#include <asm/mach-types.h> #include <asm/mach-types.h>
#include <mach/serial.h> #include "serial.h"
#include "mux.h" #include "mux.h"
#include "pm.h" #include "pm.h"
#include "soc.h" #include "soc.h"
......
...@@ -51,8 +51,10 @@ ...@@ -51,8 +51,10 @@
#include <asm/mach/time.h> #include <asm/mach/time.h>
#include "hardware.h" #include "hardware.h"
#include "mux.h"
#include "iomap.h" #include "iomap.h"
#include "common.h" #include "common.h"
#include "clock.h"
#ifdef CONFIG_OMAP_MPU_TIMER #ifdef CONFIG_OMAP_MPU_TIMER
...@@ -224,6 +226,9 @@ static inline void omap_mpu_timer_init(void) ...@@ -224,6 +226,9 @@ static inline void omap_mpu_timer_init(void)
*/ */
void __init omap1_timer_init(void) void __init omap1_timer_init(void)
{ {
omap1_clk_init();
omap1_mux_init();
if (omap_32k_timer_init() != 0) if (omap_32k_timer_init() != 0)
omap_mpu_timer_init(); omap_mpu_timer_init();
} }
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment