@ -13,10 +13,102 @@
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation .
*
* This code manages " OMAP modules " ( on - chip devices ) and their
* integration with Linux device driver and bus code .
*
* References :
* Introduction
* - - - - - - - - - - - -
* One way to view an OMAP SoC is as a collection of largely unrelated
* IP blocks connected by interconnects . The IP blocks include
* devices such as ARM processors , audio serial interfaces , UARTs ,
* etc . Some of these devices , like the DSP , are created by TI ;
* others , like the SGX , largely originate from external vendors . In
* TI ' s documentation , on - chip devices are referred to as " OMAP
* modules . " Some of these IP blocks are identical across several
* OMAP versions . Others are revised frequently .
*
* These OMAP modules are tied together by various interconnects .
* Most of the address and data flow between modules is via OCP - based
* interconnects such as the L3 and L4 buses ; but there are other
* interconnects that distribute the hardware clock tree , handle idle
* and reset signaling , supply power , and connect the modules to
* various pads or balls on the OMAP package .
*
* OMAP hwmod provides a consistent way to describe the on - chip
* hardware blocks and their integration into the rest of the chip .
* This description can be automatically generated from the TI
* hardware database . OMAP hwmod provides a standard , consistent API
* to reset , enable , idle , and disable these hardware blocks . And
* hwmod provides a way for other core code , such as the Linux device
* code or the OMAP power management and address space mapping code ,
* to query the hardware database .
*
* Using hwmod
* - - - - - - - - - - -
* Drivers won ' t call hwmod functions directly . That is done by the
* omap_device code , and in rare occasions , by custom integration code
* in arch / arm / * omap * . The omap_device code includes functions to
* build a struct platform_device using omap_hwmod data , and that is
* currently how hwmod data is communicated to drivers and to the
* Linux driver model . Most drivers will call omap_hwmod functions only
* indirectly , via pm_runtime * ( ) functions .
*
* From a layering perspective , here is where the OMAP hwmod code
* fits into the kernel software stack :
*
* + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +
* | Device driver code |
* | ( e . g . , drivers / ) |
* + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +
* | Linux driver model |
* | ( platform_device / |
* | platform_driver data / code ) |
* + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +
* | OMAP core - driver integration |
* | ( arch / arm / mach - omap2 / devices . c ) |
* + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +
* | omap_device code |
* | ( . . / plat - omap / omap_device . c ) |
* + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +
* - - - - > | omap_hwmod code / data | < - - - - -
* | ( . . / mach - omap2 / omap_hwmod * ) |
* + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +
* | OMAP clock / PRCM / register fns |
* | ( __raw_ { read , write } l , clk * ) |
* + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +
*
* Device drivers should not contain any OMAP - specific code or data in
* them . They should only contain code to operate the IP block that
* the driver is responsible for . This is because these IP blocks can
* also appear in other SoCs , either from TI ( such as DaVinci ) or from
* other manufacturers ; and drivers should be reusable across other
* platforms .
*
* The OMAP hwmod code also will attempt to reset and idle all on - chip
* devices upon boot . The goal here is for the kernel to be
* completely self - reliant and independent from bootloaders . This is
* to ensure a repeatable configuration , both to ensure consistent
* runtime behavior , and to make it easier for others to reproduce
* bugs .
*
* OMAP module activity states
* - - - - - - - - - - - - - - - - - - - - - - - - - - -
* The hwmod code considers modules to be in one of several activity
* states . IP blocks start out in an UNKNOWN state , then once they
* are registered via the hwmod code , proceed to the REGISTERED state .
* Once their clock names are resolved to clock pointers , the module
* enters the CLKS_INITED state ; and finally , once the module has been
* reset and the integration registers programmed , the INITIALIZED state
* is entered . The hwmod code will then place the module into either
* the IDLE state to save power , or in the case of a critical system
* module , the ENABLED state .
*
* OMAP core integration code can then call omap_hwmod * ( ) functions
* directly to move the module between the IDLE , ENABLED , and DISABLED
* states , as needed . This is done during both the PM idle loop , and
* in the OMAP core integration code ' s implementation of the PM runtime
* functions .
*
* References
* - - - - - - - - - -
* This is a partial list .
* - OMAP2420 Multimedia Processor Silicon Revision 2.1 .1 , 2.2 ( SWPU064 )
* - OMAP2430 Multimedia Device POP Silicon Revision 2.1 ( SWPU090 )
* - OMAP34xx Multimedia Device Silicon Revision 3.1 ( SWPU108 )
@ -654,7 +746,7 @@ static void __iomem *_find_mpu_rt_base(struct omap_hwmod *oh, u8 index)
}
/**
* _sysc_ enable - try to bring a module out of idle via OCP_SYSCONFIG
* _enable_sysc - try to bring a module out of idle via OCP_SYSCONFIG
* @ oh : struct omap_hwmod *
*
* If module is marked as SWSUP_SIDLE , force the module out of slave
@ -662,7 +754,7 @@ static void __iomem *_find_mpu_rt_base(struct omap_hwmod *oh, u8 index)
* as SWSUP_MSUSPEND , force the module out of master standby ;
* otherwise , configure it for smart - standby . No return value .
*/
static void _sysc_ enable ( struct omap_hwmod * oh )
static void _enable_sysc ( struct omap_hwmod * oh )
{
u8 idlemode , sf ;
u32 v ;
@ -708,7 +800,7 @@ static void _sysc_enable(struct omap_hwmod *oh)
}
/**
* _sysc_ idle - try to put a module into idle via OCP_SYSCONFIG
* _idle_sysc - try to put a module into idle via OCP_SYSCONFIG
* @ oh : struct omap_hwmod *
*
* If module is marked as SWSUP_SIDLE , force the module into slave
@ -716,7 +808,7 @@ static void _sysc_enable(struct omap_hwmod *oh)
* as SWSUP_MSUSPEND , force the module into master standby ; otherwise ,
* configure it for smart - standby . No return value .
*/
static void _sysc_ idle ( struct omap_hwmod * oh )
static void _idle_sysc ( struct omap_hwmod * oh )
{
u8 idlemode , sf ;
u32 v ;
@ -743,13 +835,13 @@ static void _sysc_idle(struct omap_hwmod *oh)
}
/**
* _sysc_s hutdown - force a module into idle via OCP_SYSCONFIG
* _shutdown_sysc - force a module into idle via OCP_SYSCONFIG
* @ oh : struct omap_hwmod *
*
* Force the module into slave idle and master suspend . No return
* value .
*/
static void _sysc_s hutdown ( struct omap_hwmod * oh )
static void _shutdown_sysc ( struct omap_hwmod * oh )
{
u32 v ;
u8 sf ;
@ -1071,8 +1163,11 @@ dis_opt_clks:
* @ oh : struct omap_hwmod *
*
* Enables an omap_hwmod @ oh such that the MPU can access the hwmod ' s
* register target . Returns - EINVAL if the hwmod is in the wrong
* state or passes along the return value of _wait_target_ready ( ) .
* register target . ( This function has a full name - -
* _omap_hwmod_enable ( ) rather than simply _enable ( ) - - because it is
* currently required by the pm34xx . c idle loop . ) Returns - EINVAL if
* the hwmod is in the wrong state or passes along the return value of
* _wait_target_ready ( ) .
*/
int _omap_hwmod_enable ( struct omap_hwmod * oh )
{
@ -1110,7 +1205,7 @@ int _omap_hwmod_enable(struct omap_hwmod *oh)
if ( oh - > class - > sysc ) {
if ( ! ( oh - > _int_flags & _HWMOD_SYSCONFIG_LOADED ) )
_update_sysc_cache ( oh ) ;
_sysc_ enable ( oh ) ;
_enable_sysc ( oh ) ;
}
} else {
pr_debug ( " omap_hwmod: %s: _wait_target_ready: %d \n " ,
@ -1121,12 +1216,14 @@ int _omap_hwmod_enable(struct omap_hwmod *oh)
}
/**
* _idle - idle an omap_hwmod
* _omap_hwmod_ idle - idle an omap_hwmod
* @ oh : struct omap_hwmod *
*
* Idles an omap_hwmod @ oh . This should be called once the hwmod has
* no further work . Returns - EINVAL if the hwmod is in the wrong
* state or returns 0.
* no further work . ( This function has a full name - -
* _omap_hwmod_idle ( ) rather than simply _idle ( ) - - because it is
* currently required by the pm34xx . c idle loop . ) Returns - EINVAL if
* the hwmod is in the wrong state or returns 0.
*/
int _omap_hwmod_idle ( struct omap_hwmod * oh )
{
@ -1139,7 +1236,7 @@ int _omap_hwmod_idle(struct omap_hwmod *oh)
pr_debug ( " omap_hwmod: %s: idling \n " , oh - > name ) ;
if ( oh - > class - > sysc )
_sysc_ idle ( oh ) ;
_idle_sysc ( oh ) ;
_del_initiator_dep ( oh , mpu_oh ) ;
_disable_clocks ( oh ) ;
@ -1169,7 +1266,7 @@ static int _shutdown(struct omap_hwmod *oh)
pr_debug ( " omap_hwmod: %s: disabling \n " , oh - > name ) ;
if ( oh - > class - > sysc )
_sysc_s hutdown ( oh ) ;
_shutdown_sysc ( oh ) ;
/*
* If an IP contains only one HW reset line , then assert it
@ -1262,7 +1359,7 @@ static int _setup(struct omap_hwmod *oh, void *data)
*/
if ( oh - > class - > sysc ) {
_update_sysc_cache ( oh ) ;
_sysc_ enable ( oh ) ;
_enable_sysc ( oh ) ;
}
}
@ -1518,7 +1615,7 @@ int omap_hwmod_unregister(struct omap_hwmod *oh)
* omap_hwmod_enable - enable an omap_hwmod
* @ oh : struct omap_hwmod *
*
* Enable an omap_hwo md @ oh . Intended to be called by omap_device_enable ( ) .
* Enable an omap_hwmo d @ oh . Intended to be called by omap_device_enable ( ) .
* Returns - EINVAL on error or passes along the return value from _enable ( ) .
*/
int omap_hwmod_enable ( struct omap_hwmod * oh )
@ -1540,7 +1637,7 @@ int omap_hwmod_enable(struct omap_hwmod *oh)
* omap_hwmod_idle - idle an omap_hwmod
* @ oh : struct omap_hwmod *
*
* Idle an omap_hwo md @ oh . Intended to be called by omap_device_idle ( ) .
* Idle an omap_hwmo d @ oh . Intended to be called by omap_device_idle ( ) .
* Returns - EINVAL on error or passes along the return value from _idle ( ) .
*/
int omap_hwmod_idle ( struct omap_hwmod * oh )
@ -1559,7 +1656,7 @@ int omap_hwmod_idle(struct omap_hwmod *oh)
* omap_hwmod_shutdown - shutdown an omap_hwmod
* @ oh : struct omap_hwmod *
*
* Shutdown an omap_hwo md @ oh . Intended to be called by
* Shutdown an omap_hwmo d @ oh . Intended to be called by
* omap_device_shutdown ( ) . Returns - EINVAL on error or passes along
* the return value from _shutdown ( ) .
*/