Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 260660
b: refs/heads/master
c: d0f0631
h: refs/heads/master
v: v3
  • Loading branch information
Benoit Cousson authored and Paul Walmsley committed Jul 10, 2011
1 parent cc7cc7d commit 8988e8b
Show file tree
Hide file tree
Showing 7 changed files with 199 additions and 98 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 6ae769973adf1325115d0dfe3fec17e26cbacd81
refs/heads/master: d0f0631ddc61026dca71b5b679803000d70fde50
8 changes: 1 addition & 7 deletions trunk/arch/arm/mach-omap2/cm44xx.h
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/*
* OMAP4 Clock Management (CM) definitions
*
* Copyright (C) 2007-2009 Texas Instruments, Inc.
* Copyright (C) 2007-2011 Texas Instruments, Inc.
* Copyright (C) 2007-2009 Nokia Corporation
*
* Written by Paul Walmsley
Expand All @@ -23,10 +23,4 @@
#define OMAP4_CM_CLKSTCTRL 0x0000
#define OMAP4_CM_STATICDEP 0x0004

/* Function prototypes */
# ifndef __ASSEMBLER__

extern int omap4_cm_wait_module_ready(void __iomem *clkctrl_reg);

# endif
#endif
87 changes: 69 additions & 18 deletions trunk/arch/arm/mach-omap2/cminst44xx.c
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
* OMAP4 CM instance functions
*
* Copyright (C) 2009 Nokia Corporation
* Copyright (C) 2011 Texas Instruments, Inc.
* Paul Walmsley
*
* This program is free software; you can redistribute it and/or modify
Expand Down Expand Up @@ -32,6 +33,22 @@
#include "prm44xx.h"
#include "prcm_mpu44xx.h"

/*
* CLKCTRL_IDLEST_*: possible values for the CM_*_CLKCTRL.IDLEST bitfield:
*
* 0x0 func: Module is fully functional, including OCP
* 0x1 trans: Module is performing transition: wakeup, or sleep, or sleep
* abortion
* 0x2 idle: Module is in Idle mode (only OCP part). It is functional if
* using separate functional clock
* 0x3 disabled: Module is disabled and cannot be accessed
*
*/
#define CLKCTRL_IDLEST_FUNCTIONAL 0x0
#define CLKCTRL_IDLEST_INTRANSITION 0x1
#define CLKCTRL_IDLEST_INTERFACE_IDLE 0x2
#define CLKCTRL_IDLEST_DISABLED 0x3

static u32 _cm_bases[OMAP4_MAX_PRCM_PARTITIONS] = {
[OMAP4430_INVALID_PRCM_PARTITION] = 0,
[OMAP4430_PRM_PARTITION] = OMAP4430_PRM_BASE,
Expand All @@ -41,6 +58,48 @@ static u32 _cm_bases[OMAP4_MAX_PRCM_PARTITIONS] = {
[OMAP4430_PRCM_MPU_PARTITION] = OMAP4430_PRCM_MPU_BASE,
};

/* Private functions */

/**
* _clkctrl_idlest - read a CM_*_CLKCTRL register; mask & shift IDLEST bitfield
* @part: PRCM partition ID that the CM_CLKCTRL register exists in
* @inst: CM instance register offset (*_INST macro)
* @cdoffs: Clockdomain register offset (*_CDOFFS macro)
* @clkctrl_offs: Module clock control register offset (*_CLKCTRL macro)
*
* Return the IDLEST bitfield of a CM_*_CLKCTRL register, shifted down to
* bit 0.
*/
static u32 _clkctrl_idlest(u8 part, u16 inst, s16 cdoffs, u16 clkctrl_offs)
{
u32 v = omap4_cminst_read_inst_reg(part, inst, clkctrl_offs);
v &= OMAP4430_IDLEST_MASK;
v >>= OMAP4430_IDLEST_SHIFT;
return v;
}

/**
* _is_module_ready - can module registers be accessed without causing an abort?
* @part: PRCM partition ID that the CM_CLKCTRL register exists in
* @inst: CM instance register offset (*_INST macro)
* @cdoffs: Clockdomain register offset (*_CDOFFS macro)
* @clkctrl_offs: Module clock control register offset (*_CLKCTRL macro)
*
* Returns true if the module's CM_*_CLKCTRL.IDLEST bitfield is either
* *FUNCTIONAL or *INTERFACE_IDLE; false otherwise.
*/
static bool _is_module_ready(u8 part, u16 inst, s16 cdoffs, u16 clkctrl_offs)
{
u32 v;

v = _clkctrl_idlest(part, inst, cdoffs, clkctrl_offs);

return (v == CLKCTRL_IDLEST_FUNCTIONAL ||
v == CLKCTRL_IDLEST_INTERFACE_IDLE) ? true : false;
}

/* Public functions */

/* Read a register in a CM instance */
u32 omap4_cminst_read_inst_reg(u8 part, s16 inst, u16 idx)
{
Expand Down Expand Up @@ -200,35 +259,27 @@ void omap4_cminst_clkdm_force_wakeup(u8 part, s16 inst, u16 cdoffs)
*/

/**
* omap4_cm_wait_module_ready - wait for a module to be in 'func' state
* @clkctrl_reg: CLKCTRL module address
* omap4_cminst_wait_module_ready - wait for a module to be in 'func' state
* @part: PRCM partition ID that the CM_CLKCTRL register exists in
* @inst: CM instance register offset (*_INST macro)
* @cdoffs: Clockdomain register offset (*_CDOFFS macro)
* @clkctrl_offs: Module clock control register offset (*_CLKCTRL macro)
*
* Wait for the module IDLEST to be functional. If the idle state is in any
* the non functional state (trans, idle or disabled), module and thus the
* sysconfig cannot be accessed and will probably lead to an "imprecise
* external abort"
*
* Module idle state:
* 0x0 func: Module is fully functional, including OCP
* 0x1 trans: Module is performing transition: wakeup, or sleep, or sleep
* abortion
* 0x2 idle: Module is in Idle mode (only OCP part). It is functional if
* using separate functional clock
* 0x3 disabled: Module is disabled and cannot be accessed
*
*/
int omap4_cm_wait_module_ready(void __iomem *clkctrl_reg)
int omap4_cminst_wait_module_ready(u8 part, u16 inst, s16 cdoffs,
u16 clkctrl_offs)
{
int i = 0;

if (!clkctrl_reg)
if (!clkctrl_offs)
return 0;

omap_test_timeout((
((__raw_readl(clkctrl_reg) & OMAP4430_IDLEST_MASK) == 0) ||
(((__raw_readl(clkctrl_reg) & OMAP4430_IDLEST_MASK) >>
OMAP4430_IDLEST_SHIFT) == 0x2)),
MAX_MODULE_READY_TIME, i);
omap_test_timeout(_is_module_ready(part, inst, cdoffs, clkctrl_offs),
MAX_MODULE_READY_TIME, i);

return (i < MAX_MODULE_READY_TIME) ? 0 : -EBUSY;
}
Expand Down
4 changes: 2 additions & 2 deletions trunk/arch/arm/mach-omap2/cminst44xx.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ extern void omap4_cminst_clkdm_disable_hwsup(u8 part, s16 inst, u16 cdoffs);
extern void omap4_cminst_clkdm_force_sleep(u8 part, s16 inst, u16 cdoffs);
extern void omap4_cminst_clkdm_force_wakeup(u8 part, s16 inst, u16 cdoffs);

extern int omap4_cminst_wait_module_ready(u8 part, u16 inst, s16 cdoffs, u16 clkctrl_offs);

/*
* In an ideal world, we would not export these low-level functions,
* but this will probably take some time to fix properly
Expand All @@ -32,6 +34,4 @@ extern u32 omap4_cminst_clear_inst_reg_bits(u32 bits, u8 part, s16 inst,
extern u32 omap4_cminst_read_inst_reg_bits(u8 part, u16 inst, s16 idx,
u32 mask);

extern int omap4_cm_wait_module_ready(void __iomem *clkctrl_reg);

#endif
12 changes: 9 additions & 3 deletions trunk/arch/arm/mach-omap2/omap_hwmod.c
Original file line number Diff line number Diff line change
Expand Up @@ -146,7 +146,7 @@
#include <plat/prcm.h>

#include "cm2xxx_3xxx.h"
#include "cm44xx.h"
#include "cminst44xx.h"
#include "prm2xxx_3xxx.h"
#include "prm44xx.h"
#include "mux.h"
Expand Down Expand Up @@ -1060,7 +1060,7 @@ static int _init_clocks(struct omap_hwmod *oh, void *data)
* Wait for a module @oh to leave slave idle. Returns 0 if the module
* does not have an IDLEST bit or if the module successfully leaves
* slave idle; otherwise, pass along the return value of the
* appropriate *_cm_wait_module_ready() function.
* appropriate *_cm*_wait_module_ready() function.
*/
static int _wait_target_ready(struct omap_hwmod *oh)
{
Expand All @@ -1087,7 +1087,13 @@ static int _wait_target_ready(struct omap_hwmod *oh)
oh->prcm.omap2.idlest_reg_id,
oh->prcm.omap2.idlest_idle_bit);
} else if (cpu_is_omap44xx()) {
ret = omap4_cm_wait_module_ready(oh->prcm.omap4.clkctrl_reg);
if (!oh->clkdm)
return -EINVAL;

ret = omap4_cminst_wait_module_ready(oh->clkdm->prcm_partition,
oh->clkdm->cm_inst,
oh->clkdm->clkdm_offs,
oh->prcm.omap4.clkctrl_offs);
} else {
BUG();
};
Expand Down
Loading

0 comments on commit 8988e8b

Please sign in to comment.