提交 d0f0631d 编写于 作者: B Benoit Cousson 提交者: Paul Walmsley

OMAP4: hwmod: Replace CLKCTRL absolute address with offset macros

The CLKCTRL register was accessed using an absolute address.
The usage of hardcoded macros to calculate virtual address from physical
one should be avoided as much as possible.
The usage of a offset will allow future improvement like migration from
the current architecture code toward a module driver.

Update cm_xxx accessor, move definition to the proper header file and
update copyrights.
Signed-off-by: NBenoit Cousson <b-cousson@ti.com>
Cc: Paul Walmsley <paul@pwsan.com>
Cc: Rajendra Nayak <rnayak@ti.com>
Cc: Todd Poynor <toddpoynor@google.com>
[paul@pwsan.com: renamed 'omap4_cm_' fns to 'omap4_cminst_'; removed empty
 fn prototype section from cm44xx.h; incorporated comments from Todd;
 documented some functions]
Signed-off-by: NPaul Walmsley <paul@pwsan.com>
上级 6ae76997
/*
* 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
......@@ -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
......@@ -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
......@@ -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,
......@@ -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)
{
......@@ -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;
}
......
......@@ -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
......@@ -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
......@@ -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"
......@@ -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)
{
......@@ -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();
};
......
......@@ -360,7 +360,7 @@ struct omap_hwmod_omap2_prcm {
* @submodule_wkdep_bit: bit shift of the WKDEP range
*/
struct omap_hwmod_omap4_prcm {
void __iomem *clkctrl_reg;
u16 clkctrl_offs;
void __iomem *rstctrl_reg;
u8 submodule_wkdep_bit;
};
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册