2009-09-04 01:14:03 +08:00
|
|
|
/*
|
|
|
|
* omap_hwmod macros, structures
|
|
|
|
*
|
2011-03-01 02:58:14 +08:00
|
|
|
* Copyright (C) 2009-2011 Nokia Corporation
|
ARM: OMAP2+: hwmod: Add support for per hwmod/module context lost count
OMAP4 has module specific context lost registers which makes it now
possible to have module level context loss count, instead of relying
on the powerdomain level context count.
Add 2 private hwmod api's to update/clear the hwmod/module specific
context lost counters/register.
Update the module specific context_lost_counter and clear the hardware
bits just after enabling the module.
omap_hwmod_get_context_loss_count() now returns the hwmod context loss
count them on platforms where they exist (OMAP4), else fall back on
the pwrdm level counters for older platforms.
Signed-off-by: Rajendra Nayak <rnayak@ti.com>
[paul@pwsan.com: added function kerneldoc, fixed structure kerneldoc,
rearranged structure to avoid memory waste, marked fns as OMAP4-specific,
prevent fn entry on non-OMAP4 chips, reduced indentation, merged update
and clear, merged patches]
[t-kristo@ti.com: added support for arch specific hwmod ops, and changed
the no context offset indicator to USHRT_MAX]
Signed-off-by: Tero Kristo <t-kristo@ti.com>
[paul@pwsan.com: use NO_CONTEXT_LOSS_BIT flag rather than USHRT_MAX;
convert unsigned context lost counter to int to match the return type;
get rid of hwmod_ops in favor of the existing soc_ops mechanism;
move context loss low-level accesses to the PRM code]
Signed-off-by: Paul Walmsley <paul@pwsan.com>
2012-11-22 07:15:17 +08:00
|
|
|
* Copyright (C) 2011-2012 Texas Instruments, Inc.
|
2009-09-04 01:14:03 +08:00
|
|
|
* Paul Walmsley
|
|
|
|
*
|
2010-02-23 13:09:34 +08:00
|
|
|
* Created in collaboration with (alphabetical order): Benoît Cousson,
|
2009-09-04 01:14:03 +08:00
|
|
|
* Kevin Hilman, Tony Lindgren, Rajendra Nayak, Vikram Pandita, Sakari
|
|
|
|
* Poussa, Anand Sawant, Santosh Shilimkar, Richard Woodruff
|
|
|
|
*
|
|
|
|
* This program is free software; you can redistribute it and/or modify
|
|
|
|
* it under the terms of the GNU General Public License version 2 as
|
|
|
|
* published by the Free Software Foundation.
|
|
|
|
*
|
|
|
|
* These headers and macros are used to define OMAP on-chip module
|
|
|
|
* data and their integration with other OMAP modules and Linux.
|
2010-09-22 05:02:23 +08:00
|
|
|
* Copious documentation and references can also be found in the
|
|
|
|
* omap_hwmod code, in arch/arm/mach-omap2/omap_hwmod.c (as of this
|
|
|
|
* writing).
|
2009-09-04 01:14:03 +08:00
|
|
|
*
|
|
|
|
* To do:
|
|
|
|
* - add interconnect error log structures
|
|
|
|
* - add pinmuxing
|
|
|
|
* - init_conn_id_bit (CONNID_BIT_VECTOR)
|
|
|
|
* - implement default hwmod SMS/SDRC flags?
|
2010-12-15 03:42:36 +08:00
|
|
|
* - move Linux-specific data ("non-ROM data") out
|
2009-09-04 01:14:03 +08:00
|
|
|
*
|
|
|
|
*/
|
|
|
|
#ifndef __ARCH_ARM_PLAT_OMAP_INCLUDE_MACH_OMAP_HWMOD_H
|
|
|
|
#define __ARCH_ARM_PLAT_OMAP_INCLUDE_MACH_OMAP_HWMOD_H
|
|
|
|
|
|
|
|
#include <linux/kernel.h>
|
2011-02-23 15:14:07 +08:00
|
|
|
#include <linux/init.h>
|
2010-02-25 03:05:58 +08:00
|
|
|
#include <linux/list.h>
|
2009-09-04 01:14:03 +08:00
|
|
|
#include <linux/ioport.h>
|
OMAP2+: hwmod: upgrade per-hwmod mutex to a spinlock
Change the per-hwmod mutex to a spinlock. (The per-hwmod lock
serializes most post-initialization hwmod operations such as enable,
idle, and shutdown.) Spinlocks are needed, because in some cases,
hwmods must be enabled from timer interrupt disabled-context, such as
an ISR. The current use-case that is driving this is the OMAP GPIO
block ISR: it can trigger interrupts even with its clocks disabled,
but these clocks are needed for register accesses in the ISR to succeed.
This patch also effectively reverts commit
848240223c35fcc71c424ad51a8e8aef42d3879c - this patch makes
_omap_hwmod_enable() and _omap_hwmod_init() static, renames them back
to _enable() and _idle(), and changes their callers to call the
spinlocking versions. Previously, since omap_hwmod_{enable,init}()
attempted to take mutexes, these functions could not be called while
the timer interrupt was disabled; but now that the functions use
spinlocks and save and restore the IRQ state, it is appropriate to
call them directly.
Kevin Hilman <khilman@deeprootsystems.com> originally proposed this
patch - thanks Kevin.
Signed-off-by: Paul Walmsley <paul@pwsan.com>
Cc: Kevin Hilman <khilman@deeprootsystems.com>
Cc: Benoît Cousson <b-cousson@ti.com>
2010-12-15 03:42:35 +08:00
|
|
|
#include <linux/spinlock.h>
|
2009-09-04 01:14:03 +08:00
|
|
|
|
|
|
|
struct omap_device;
|
|
|
|
|
2010-02-25 03:05:58 +08:00
|
|
|
extern struct omap_hwmod_sysc_fields omap_hwmod_sysc_type1;
|
|
|
|
extern struct omap_hwmod_sysc_fields omap_hwmod_sysc_type2;
|
2012-07-04 17:40:59 +08:00
|
|
|
extern struct omap_hwmod_sysc_fields omap_hwmod_sysc_type3;
|
2010-02-25 03:05:58 +08:00
|
|
|
|
|
|
|
/*
|
|
|
|
* OCP SYSCONFIG bit shifts/masks TYPE1. These are for IPs compliant
|
|
|
|
* with the original PRCM protocol defined for OMAP2420
|
|
|
|
*/
|
|
|
|
#define SYSC_TYPE1_MIDLEMODE_SHIFT 12
|
2012-02-17 19:26:01 +08:00
|
|
|
#define SYSC_TYPE1_MIDLEMODE_MASK (0x3 << SYSC_TYPE1_MIDLEMODE_SHIFT)
|
2010-02-25 03:05:58 +08:00
|
|
|
#define SYSC_TYPE1_CLOCKACTIVITY_SHIFT 8
|
2012-02-17 19:26:01 +08:00
|
|
|
#define SYSC_TYPE1_CLOCKACTIVITY_MASK (0x3 << SYSC_TYPE1_CLOCKACTIVITY_SHIFT)
|
2010-02-25 03:05:58 +08:00
|
|
|
#define SYSC_TYPE1_SIDLEMODE_SHIFT 3
|
2012-02-17 19:26:01 +08:00
|
|
|
#define SYSC_TYPE1_SIDLEMODE_MASK (0x3 << SYSC_TYPE1_SIDLEMODE_SHIFT)
|
2010-02-25 03:05:58 +08:00
|
|
|
#define SYSC_TYPE1_ENAWAKEUP_SHIFT 2
|
2012-02-17 19:26:01 +08:00
|
|
|
#define SYSC_TYPE1_ENAWAKEUP_MASK (1 << SYSC_TYPE1_ENAWAKEUP_SHIFT)
|
2010-02-25 03:05:58 +08:00
|
|
|
#define SYSC_TYPE1_SOFTRESET_SHIFT 1
|
2012-02-17 19:26:01 +08:00
|
|
|
#define SYSC_TYPE1_SOFTRESET_MASK (1 << SYSC_TYPE1_SOFTRESET_SHIFT)
|
2010-02-25 03:05:58 +08:00
|
|
|
#define SYSC_TYPE1_AUTOIDLE_SHIFT 0
|
2012-02-17 19:26:01 +08:00
|
|
|
#define SYSC_TYPE1_AUTOIDLE_MASK (1 << SYSC_TYPE1_AUTOIDLE_SHIFT)
|
2010-02-25 03:05:58 +08:00
|
|
|
|
|
|
|
/*
|
|
|
|
* OCP SYSCONFIG bit shifts/masks TYPE2. These are for IPs compliant
|
|
|
|
* with the new PRCM protocol defined for new OMAP4 IPs.
|
|
|
|
*/
|
|
|
|
#define SYSC_TYPE2_SOFTRESET_SHIFT 0
|
|
|
|
#define SYSC_TYPE2_SOFTRESET_MASK (1 << SYSC_TYPE2_SOFTRESET_SHIFT)
|
|
|
|
#define SYSC_TYPE2_SIDLEMODE_SHIFT 2
|
|
|
|
#define SYSC_TYPE2_SIDLEMODE_MASK (0x3 << SYSC_TYPE2_SIDLEMODE_SHIFT)
|
|
|
|
#define SYSC_TYPE2_MIDLEMODE_SHIFT 4
|
|
|
|
#define SYSC_TYPE2_MIDLEMODE_MASK (0x3 << SYSC_TYPE2_MIDLEMODE_SHIFT)
|
2012-07-04 19:09:21 +08:00
|
|
|
#define SYSC_TYPE2_DMADISABLE_SHIFT 16
|
|
|
|
#define SYSC_TYPE2_DMADISABLE_MASK (0x1 << SYSC_TYPE2_DMADISABLE_SHIFT)
|
2009-09-04 01:14:03 +08:00
|
|
|
|
2012-07-04 17:40:59 +08:00
|
|
|
/*
|
|
|
|
* OCP SYSCONFIG bit shifts/masks TYPE3.
|
|
|
|
* This is applicable for some IPs present in AM33XX
|
|
|
|
*/
|
|
|
|
#define SYSC_TYPE3_SIDLEMODE_SHIFT 0
|
|
|
|
#define SYSC_TYPE3_SIDLEMODE_MASK (0x3 << SYSC_TYPE3_SIDLEMODE_SHIFT)
|
|
|
|
#define SYSC_TYPE3_MIDLEMODE_SHIFT 2
|
|
|
|
#define SYSC_TYPE3_MIDLEMODE_MASK (0x3 << SYSC_TYPE3_MIDLEMODE_SHIFT)
|
2009-09-04 01:14:03 +08:00
|
|
|
|
|
|
|
/* OCP SYSSTATUS bit shifts/masks */
|
|
|
|
#define SYSS_RESETDONE_SHIFT 0
|
|
|
|
#define SYSS_RESETDONE_MASK (1 << SYSS_RESETDONE_SHIFT)
|
|
|
|
|
|
|
|
/* Master standby/slave idle mode flags */
|
|
|
|
#define HWMOD_IDLEMODE_FORCE (1 << 0)
|
|
|
|
#define HWMOD_IDLEMODE_NO (1 << 1)
|
|
|
|
#define HWMOD_IDLEMODE_SMART (1 << 2)
|
2010-12-22 12:31:28 +08:00
|
|
|
#define HWMOD_IDLEMODE_SMART_WKUP (1 << 3)
|
2009-09-04 01:14:03 +08:00
|
|
|
|
2011-07-10 19:56:32 +08:00
|
|
|
/* modulemode control type (SW or HW) */
|
|
|
|
#define MODULEMODE_HWCTRL 1
|
|
|
|
#define MODULEMODE_SWCTRL 2
|
|
|
|
|
2013-07-29 13:01:48 +08:00
|
|
|
#define DEBUG_OMAP2UART1_FLAGS 0
|
|
|
|
#define DEBUG_OMAP2UART2_FLAGS 0
|
|
|
|
#define DEBUG_OMAP2UART3_FLAGS 0
|
|
|
|
#define DEBUG_OMAP3UART3_FLAGS 0
|
|
|
|
#define DEBUG_OMAP3UART4_FLAGS 0
|
|
|
|
#define DEBUG_OMAP4UART3_FLAGS 0
|
|
|
|
#define DEBUG_OMAP4UART4_FLAGS 0
|
|
|
|
#define DEBUG_TI81XXUART1_FLAGS 0
|
|
|
|
#define DEBUG_TI81XXUART2_FLAGS 0
|
|
|
|
#define DEBUG_TI81XXUART3_FLAGS 0
|
|
|
|
#define DEBUG_AM33XXUART1_FLAGS 0
|
|
|
|
|
|
|
|
#define DEBUG_OMAPUART_FLAGS (HWMOD_INIT_NO_IDLE | HWMOD_INIT_NO_RESET)
|
|
|
|
|
|
|
|
#if defined(CONFIG_DEBUG_OMAP2UART1)
|
|
|
|
#undef DEBUG_OMAP2UART1_FLAGS
|
|
|
|
#define DEBUG_OMAP2UART1_FLAGS DEBUG_OMAPUART_FLAGS
|
|
|
|
#elif defined(CONFIG_DEBUG_OMAP2UART2)
|
|
|
|
#undef DEBUG_OMAP2UART2_FLAGS
|
|
|
|
#define DEBUG_OMAP2UART2_FLAGS DEBUG_OMAPUART_FLAGS
|
|
|
|
#elif defined(CONFIG_DEBUG_OMAP2UART3)
|
|
|
|
#undef DEBUG_OMAP2UART3_FLAGS
|
|
|
|
#define DEBUG_OMAP2UART3_FLAGS DEBUG_OMAPUART_FLAGS
|
|
|
|
#elif defined(CONFIG_DEBUG_OMAP3UART3)
|
|
|
|
#undef DEBUG_OMAP3UART3_FLAGS
|
|
|
|
#define DEBUG_OMAP3UART3_FLAGS DEBUG_OMAPUART_FLAGS
|
|
|
|
#elif defined(CONFIG_DEBUG_OMAP3UART4)
|
|
|
|
#undef DEBUG_OMAP3UART4_FLAGS
|
|
|
|
#define DEBUG_OMAP3UART4_FLAGS DEBUG_OMAPUART_FLAGS
|
|
|
|
#elif defined(CONFIG_DEBUG_OMAP4UART3)
|
|
|
|
#undef DEBUG_OMAP4UART3_FLAGS
|
|
|
|
#define DEBUG_OMAP4UART3_FLAGS DEBUG_OMAPUART_FLAGS
|
|
|
|
#elif defined(CONFIG_DEBUG_OMAP4UART4)
|
|
|
|
#undef DEBUG_OMAP4UART4_FLAGS
|
|
|
|
#define DEBUG_OMAP4UART4_FLAGS DEBUG_OMAPUART_FLAGS
|
|
|
|
#elif defined(CONFIG_DEBUG_TI81XXUART1)
|
|
|
|
#undef DEBUG_TI81XXUART1_FLAGS
|
|
|
|
#define DEBUG_TI81XXUART1_FLAGS DEBUG_OMAPUART_FLAGS
|
|
|
|
#elif defined(CONFIG_DEBUG_TI81XXUART2)
|
|
|
|
#undef DEBUG_TI81XXUART2_FLAGS
|
|
|
|
#define DEBUG_TI81XXUART2_FLAGS DEBUG_OMAPUART_FLAGS
|
|
|
|
#elif defined(CONFIG_DEBUG_TI81XXUART3)
|
|
|
|
#undef DEBUG_TI81XXUART3_FLAGS
|
|
|
|
#define DEBUG_TI81XXUART3_FLAGS DEBUG_OMAPUART_FLAGS
|
|
|
|
#elif defined(CONFIG_DEBUG_AM33XXUART1)
|
|
|
|
#undef DEBUG_AM33XXUART1_FLAGS
|
|
|
|
#define DEBUG_AM33XXUART1_FLAGS DEBUG_OMAPUART_FLAGS
|
|
|
|
#endif
|
2011-07-10 19:56:32 +08:00
|
|
|
|
2010-12-23 10:42:35 +08:00
|
|
|
/**
|
|
|
|
* struct omap_hwmod_mux_info - hwmod specific mux configuration
|
|
|
|
* @pads: array of omap_device_pad entries
|
|
|
|
* @nr_pads: number of omap_device_pad entries
|
|
|
|
*
|
|
|
|
* Note that this is currently built during init as needed.
|
|
|
|
*/
|
|
|
|
struct omap_hwmod_mux_info {
|
|
|
|
int nr_pads;
|
|
|
|
struct omap_device_pad *pads;
|
2011-03-12 03:32:25 +08:00
|
|
|
int nr_pads_dynamic;
|
|
|
|
struct omap_device_pad **pads_dynamic;
|
2011-12-17 05:36:59 +08:00
|
|
|
int *irqs;
|
2011-03-12 03:32:25 +08:00
|
|
|
bool enabled;
|
2010-12-23 10:42:35 +08:00
|
|
|
};
|
|
|
|
|
2009-09-04 01:14:03 +08:00
|
|
|
/**
|
2009-12-09 07:34:16 +08:00
|
|
|
* struct omap_hwmod_irq_info - MPU IRQs used by the hwmod
|
|
|
|
* @name: name of the IRQ channel (module local name)
|
2011-07-10 09:14:06 +08:00
|
|
|
* @irq: IRQ channel ID (should be non-negative except -1 = terminator)
|
2009-12-09 07:34:16 +08:00
|
|
|
*
|
|
|
|
* @name should be something short, e.g., "tx" or "rx". It is for use
|
|
|
|
* by platform_get_resource_byname(). It is defined locally to the
|
|
|
|
* hwmod.
|
|
|
|
*/
|
|
|
|
struct omap_hwmod_irq_info {
|
|
|
|
const char *name;
|
2011-07-10 09:14:06 +08:00
|
|
|
s16 irq;
|
2009-12-09 07:34:16 +08:00
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
|
|
|
* struct omap_hwmod_dma_info - DMA channels used by the hwmod
|
2009-09-04 01:14:03 +08:00
|
|
|
* @name: name of the DMA channel (module local name)
|
2011-07-10 09:14:07 +08:00
|
|
|
* @dma_req: DMA request ID (should be non-negative except -1 = terminator)
|
2009-09-04 01:14:03 +08:00
|
|
|
*
|
|
|
|
* @name should be something short, e.g., "tx" or "rx". It is for use
|
|
|
|
* by platform_get_resource_byname(). It is defined locally to the
|
|
|
|
* hwmod.
|
|
|
|
*/
|
|
|
|
struct omap_hwmod_dma_info {
|
|
|
|
const char *name;
|
2011-07-10 09:14:07 +08:00
|
|
|
s16 dma_req;
|
2009-09-04 01:14:03 +08:00
|
|
|
};
|
|
|
|
|
OMAP: hwmod: Add hardreset management support
Most processor IPs does have a hardreset signal controlled by the PRM.
This is different of the softreset used for local IP reset from the
SYSCONFIG register.
The granularity can be much finer than orginal HWMOD, for ex, the IVA
hwmod contains 3 reset lines, the IPU 3 as well, the DSP 2...
Since this granularity is needed by the driver, we have to ensure
than one hwmod exist for each hardreset line.
- Store reset lines as hwmod resources that a driver can query by name like
an irq or sdma line.
- Add two functions for asserting / deasserting reset lines in hwmods
processor that require manual reset control.
- Add one functions to get the current reset state.
- If an hwmod contains only one line, an automatic assertion / de-assertion
is done.
-> de-assert the hardreset line only during enable from disable transition
-> assert the hardreset line only during shutdown
Note: The hwmods with hardreset line and HWMOD_INIT_NO_RESET flag must be
kept in INITIALIZED state.
They can be properly enabled only if the hardreset line is de-asserted
before.
For information here is the list of IPs with HW reset control
on an OMAP4430 device:
RM_DSP_RSTCTRL
1,1,'RST2','RW','1','DSP - MMU, cache and slave interface reset control'
0,0,'RST1','RW','1','DSP - DSP reset control'
RM_IVA_RSTCTRL
2,2,'RST3','RW','1','IVA logic and SL2 reset control'
1,1,'RST2','RW','1','IVA Sequencer2 reset control'
0,0,'RST1','RW','1','IVA sequencer1 reset control'
RM_IPU_RSTCTRL
2,2,'RST3','RW','1','IPU MMU and CACHE interface reset control.'
1,1,'RST2','RW','1','IPU Cortex M3 CPU2 reset control.'
0,0,'RST1','RW','1','IPU Cortex M3 CPU1 reset control.'
PRM_RSTCTRL
1,1,'RST_GLOBAL_COLD_SW','RW','0','Global COLD software reset control.'
0,0,'RST_GLOBAL_WARM_SW','RW','0','Global WARM software reset control.'
RM_CPU0_CPU0_RSTCTRL
RM_CPU1_CPU1_RSTCTRL
0,0,'RST','RW','0','Cortex A9 CPU0&1 warm local reset control'
Signed-off-by: Benoit Cousson <b-cousson@ti.com>
[paul@pwsan.com: made the hardreset functions static; moved the register
twiddling into prm*.c functions in previous patches; changed the
function names to conform with hwmod practice]
Signed-off-by: Paul Walmsley <paul@pwsan.com>
Cc: Kevin Hilman <khilman@deeprootsystems.com>
Cc: Rajendra Nayak <rnayak@ti.com>
2010-09-22 00:34:11 +08:00
|
|
|
/**
|
|
|
|
* struct omap_hwmod_rst_info - IPs reset lines use by hwmod
|
|
|
|
* @name: name of the reset line (module local name)
|
|
|
|
* @rst_shift: Offset of the reset bit
|
2011-03-05 04:32:44 +08:00
|
|
|
* @st_shift: Offset of the reset status bit (OMAP2/3 only)
|
OMAP: hwmod: Add hardreset management support
Most processor IPs does have a hardreset signal controlled by the PRM.
This is different of the softreset used for local IP reset from the
SYSCONFIG register.
The granularity can be much finer than orginal HWMOD, for ex, the IVA
hwmod contains 3 reset lines, the IPU 3 as well, the DSP 2...
Since this granularity is needed by the driver, we have to ensure
than one hwmod exist for each hardreset line.
- Store reset lines as hwmod resources that a driver can query by name like
an irq or sdma line.
- Add two functions for asserting / deasserting reset lines in hwmods
processor that require manual reset control.
- Add one functions to get the current reset state.
- If an hwmod contains only one line, an automatic assertion / de-assertion
is done.
-> de-assert the hardreset line only during enable from disable transition
-> assert the hardreset line only during shutdown
Note: The hwmods with hardreset line and HWMOD_INIT_NO_RESET flag must be
kept in INITIALIZED state.
They can be properly enabled only if the hardreset line is de-asserted
before.
For information here is the list of IPs with HW reset control
on an OMAP4430 device:
RM_DSP_RSTCTRL
1,1,'RST2','RW','1','DSP - MMU, cache and slave interface reset control'
0,0,'RST1','RW','1','DSP - DSP reset control'
RM_IVA_RSTCTRL
2,2,'RST3','RW','1','IVA logic and SL2 reset control'
1,1,'RST2','RW','1','IVA Sequencer2 reset control'
0,0,'RST1','RW','1','IVA sequencer1 reset control'
RM_IPU_RSTCTRL
2,2,'RST3','RW','1','IPU MMU and CACHE interface reset control.'
1,1,'RST2','RW','1','IPU Cortex M3 CPU2 reset control.'
0,0,'RST1','RW','1','IPU Cortex M3 CPU1 reset control.'
PRM_RSTCTRL
1,1,'RST_GLOBAL_COLD_SW','RW','0','Global COLD software reset control.'
0,0,'RST_GLOBAL_WARM_SW','RW','0','Global WARM software reset control.'
RM_CPU0_CPU0_RSTCTRL
RM_CPU1_CPU1_RSTCTRL
0,0,'RST','RW','0','Cortex A9 CPU0&1 warm local reset control'
Signed-off-by: Benoit Cousson <b-cousson@ti.com>
[paul@pwsan.com: made the hardreset functions static; moved the register
twiddling into prm*.c functions in previous patches; changed the
function names to conform with hwmod practice]
Signed-off-by: Paul Walmsley <paul@pwsan.com>
Cc: Kevin Hilman <khilman@deeprootsystems.com>
Cc: Rajendra Nayak <rnayak@ti.com>
2010-09-22 00:34:11 +08:00
|
|
|
*
|
|
|
|
* @name should be something short, e.g., "cpu0" or "rst". It is defined
|
|
|
|
* locally to the hwmod.
|
|
|
|
*/
|
|
|
|
struct omap_hwmod_rst_info {
|
|
|
|
const char *name;
|
|
|
|
u8 rst_shift;
|
2011-03-05 04:32:44 +08:00
|
|
|
u8 st_shift;
|
OMAP: hwmod: Add hardreset management support
Most processor IPs does have a hardreset signal controlled by the PRM.
This is different of the softreset used for local IP reset from the
SYSCONFIG register.
The granularity can be much finer than orginal HWMOD, for ex, the IVA
hwmod contains 3 reset lines, the IPU 3 as well, the DSP 2...
Since this granularity is needed by the driver, we have to ensure
than one hwmod exist for each hardreset line.
- Store reset lines as hwmod resources that a driver can query by name like
an irq or sdma line.
- Add two functions for asserting / deasserting reset lines in hwmods
processor that require manual reset control.
- Add one functions to get the current reset state.
- If an hwmod contains only one line, an automatic assertion / de-assertion
is done.
-> de-assert the hardreset line only during enable from disable transition
-> assert the hardreset line only during shutdown
Note: The hwmods with hardreset line and HWMOD_INIT_NO_RESET flag must be
kept in INITIALIZED state.
They can be properly enabled only if the hardreset line is de-asserted
before.
For information here is the list of IPs with HW reset control
on an OMAP4430 device:
RM_DSP_RSTCTRL
1,1,'RST2','RW','1','DSP - MMU, cache and slave interface reset control'
0,0,'RST1','RW','1','DSP - DSP reset control'
RM_IVA_RSTCTRL
2,2,'RST3','RW','1','IVA logic and SL2 reset control'
1,1,'RST2','RW','1','IVA Sequencer2 reset control'
0,0,'RST1','RW','1','IVA sequencer1 reset control'
RM_IPU_RSTCTRL
2,2,'RST3','RW','1','IPU MMU and CACHE interface reset control.'
1,1,'RST2','RW','1','IPU Cortex M3 CPU2 reset control.'
0,0,'RST1','RW','1','IPU Cortex M3 CPU1 reset control.'
PRM_RSTCTRL
1,1,'RST_GLOBAL_COLD_SW','RW','0','Global COLD software reset control.'
0,0,'RST_GLOBAL_WARM_SW','RW','0','Global WARM software reset control.'
RM_CPU0_CPU0_RSTCTRL
RM_CPU1_CPU1_RSTCTRL
0,0,'RST','RW','0','Cortex A9 CPU0&1 warm local reset control'
Signed-off-by: Benoit Cousson <b-cousson@ti.com>
[paul@pwsan.com: made the hardreset functions static; moved the register
twiddling into prm*.c functions in previous patches; changed the
function names to conform with hwmod practice]
Signed-off-by: Paul Walmsley <paul@pwsan.com>
Cc: Kevin Hilman <khilman@deeprootsystems.com>
Cc: Rajendra Nayak <rnayak@ti.com>
2010-09-22 00:34:11 +08:00
|
|
|
};
|
|
|
|
|
2009-09-04 01:14:03 +08:00
|
|
|
/**
|
|
|
|
* struct omap_hwmod_opt_clk - optional clocks used by this hwmod
|
|
|
|
* @role: "sys", "32k", "tv", etc -- for use in clk_get()
|
2010-02-23 13:09:31 +08:00
|
|
|
* @clk: opt clock: OMAP clock name
|
2009-09-04 01:14:03 +08:00
|
|
|
* @_clk: pointer to the struct clk (filled in at runtime)
|
|
|
|
*
|
|
|
|
* The module's interface clock and main functional clock should not
|
|
|
|
* be added as optional clocks.
|
|
|
|
*/
|
|
|
|
struct omap_hwmod_opt_clk {
|
|
|
|
const char *role;
|
2010-02-23 13:09:31 +08:00
|
|
|
const char *clk;
|
2009-09-04 01:14:03 +08:00
|
|
|
struct clk *_clk;
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
/* omap_hwmod_omap2_firewall.flags bits */
|
|
|
|
#define OMAP_FIREWALL_L3 (1 << 0)
|
|
|
|
#define OMAP_FIREWALL_L4 (1 << 1)
|
|
|
|
|
|
|
|
/**
|
|
|
|
* struct omap_hwmod_omap2_firewall - OMAP2/3 device firewall data
|
|
|
|
* @l3_perm_bit: bit shift for L3_PM_*_PERMISSION_*
|
|
|
|
* @l4_fw_region: L4 firewall region ID
|
|
|
|
* @l4_prot_group: L4 protection group ID
|
|
|
|
* @flags: (see omap_hwmod_omap2_firewall.flags macros above)
|
|
|
|
*/
|
|
|
|
struct omap_hwmod_omap2_firewall {
|
|
|
|
u8 l3_perm_bit;
|
|
|
|
u8 l4_fw_region;
|
|
|
|
u8 l4_prot_group;
|
|
|
|
u8 flags;
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
* omap_hwmod_addr_space.flags bits
|
|
|
|
*
|
|
|
|
* ADDR_MAP_ON_INIT: Map this address space during omap_hwmod init.
|
|
|
|
* ADDR_TYPE_RT: Address space contains module register target data.
|
|
|
|
*/
|
2010-12-15 03:42:36 +08:00
|
|
|
#define ADDR_MAP_ON_INIT (1 << 0) /* XXX does not belong */
|
2009-09-04 01:14:03 +08:00
|
|
|
#define ADDR_TYPE_RT (1 << 1)
|
|
|
|
|
|
|
|
/**
|
2011-02-25 04:51:45 +08:00
|
|
|
* struct omap_hwmod_addr_space - address space handled by the hwmod
|
|
|
|
* @name: name of the address space
|
2009-09-04 01:14:03 +08:00
|
|
|
* @pa_start: starting physical address
|
|
|
|
* @pa_end: ending physical address
|
|
|
|
* @flags: (see omap_hwmod_addr_space.flags macros above)
|
|
|
|
*
|
|
|
|
* Address space doesn't necessarily follow physical interconnect
|
|
|
|
* structure. GPMC is one example.
|
|
|
|
*/
|
|
|
|
struct omap_hwmod_addr_space {
|
2011-02-25 04:51:45 +08:00
|
|
|
const char *name;
|
2009-09-04 01:14:03 +08:00
|
|
|
u32 pa_start;
|
|
|
|
u32 pa_end;
|
|
|
|
u8 flags;
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
* omap_hwmod_ocp_if.user bits: these indicate the initiators that use this
|
|
|
|
* interface to interact with the hwmod. Used to add sleep dependencies
|
|
|
|
* when the module is enabled or disabled.
|
|
|
|
*/
|
|
|
|
#define OCP_USER_MPU (1 << 0)
|
|
|
|
#define OCP_USER_SDMA (1 << 1)
|
2012-04-19 18:03:55 +08:00
|
|
|
#define OCP_USER_DSP (1 << 2)
|
2012-04-20 03:33:54 +08:00
|
|
|
#define OCP_USER_IVA (1 << 3)
|
2009-09-04 01:14:03 +08:00
|
|
|
|
|
|
|
/* omap_hwmod_ocp_if.flags bits */
|
2010-05-21 02:31:09 +08:00
|
|
|
#define OCPIF_SWSUP_IDLE (1 << 0)
|
|
|
|
#define OCPIF_CAN_BURST (1 << 1)
|
2009-09-04 01:14:03 +08:00
|
|
|
|
2012-04-19 18:04:30 +08:00
|
|
|
/* omap_hwmod_ocp_if._int_flags possibilities */
|
|
|
|
#define _OCPIF_INT_FLAGS_REGISTERED (1 << 0)
|
|
|
|
|
|
|
|
|
2009-09-04 01:14:03 +08:00
|
|
|
/**
|
|
|
|
* struct omap_hwmod_ocp_if - OCP interface data
|
|
|
|
* @master: struct omap_hwmod that initiates OCP transactions on this link
|
|
|
|
* @slave: struct omap_hwmod that responds to OCP transactions on this link
|
|
|
|
* @addr: address space associated with this link
|
2010-02-23 13:09:31 +08:00
|
|
|
* @clk: interface clock: OMAP clock name
|
2009-09-04 01:14:03 +08:00
|
|
|
* @_clk: pointer to the interface struct clk (filled in at runtime)
|
|
|
|
* @fw: interface firewall data
|
|
|
|
* @width: OCP data width
|
|
|
|
* @user: initiators using this interface (see OCP_USER_* macros above)
|
|
|
|
* @flags: OCP interface flags (see OCPIF_* macros above)
|
2012-04-19 18:04:30 +08:00
|
|
|
* @_int_flags: internal flags (see _OCPIF_INT_FLAGS* macros above)
|
2009-09-04 01:14:03 +08:00
|
|
|
*
|
|
|
|
* It may also be useful to add a tag_cnt field for OCP2.x devices.
|
|
|
|
*
|
|
|
|
* Parameter names beginning with an underscore are managed internally by
|
|
|
|
* the omap_hwmod code and should not be set during initialization.
|
|
|
|
*/
|
|
|
|
struct omap_hwmod_ocp_if {
|
|
|
|
struct omap_hwmod *master;
|
|
|
|
struct omap_hwmod *slave;
|
|
|
|
struct omap_hwmod_addr_space *addr;
|
2010-02-23 13:09:31 +08:00
|
|
|
const char *clk;
|
2009-09-04 01:14:03 +08:00
|
|
|
struct clk *_clk;
|
|
|
|
union {
|
|
|
|
struct omap_hwmod_omap2_firewall omap2;
|
|
|
|
} fw;
|
|
|
|
u8 width;
|
|
|
|
u8 user;
|
|
|
|
u8 flags;
|
2012-04-19 18:04:30 +08:00
|
|
|
u8 _int_flags;
|
2009-09-04 01:14:03 +08:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
/* Macros for use in struct omap_hwmod_sysconfig */
|
|
|
|
|
|
|
|
/* Flags for use in omap_hwmod_sysconfig.idlemodes */
|
2010-12-22 12:31:28 +08:00
|
|
|
#define MASTER_STANDBY_SHIFT 4
|
2009-09-04 01:14:03 +08:00
|
|
|
#define SLAVE_IDLE_SHIFT 0
|
|
|
|
#define SIDLE_FORCE (HWMOD_IDLEMODE_FORCE << SLAVE_IDLE_SHIFT)
|
|
|
|
#define SIDLE_NO (HWMOD_IDLEMODE_NO << SLAVE_IDLE_SHIFT)
|
|
|
|
#define SIDLE_SMART (HWMOD_IDLEMODE_SMART << SLAVE_IDLE_SHIFT)
|
2010-12-22 12:31:28 +08:00
|
|
|
#define SIDLE_SMART_WKUP (HWMOD_IDLEMODE_SMART_WKUP << SLAVE_IDLE_SHIFT)
|
2009-09-04 01:14:03 +08:00
|
|
|
#define MSTANDBY_FORCE (HWMOD_IDLEMODE_FORCE << MASTER_STANDBY_SHIFT)
|
|
|
|
#define MSTANDBY_NO (HWMOD_IDLEMODE_NO << MASTER_STANDBY_SHIFT)
|
|
|
|
#define MSTANDBY_SMART (HWMOD_IDLEMODE_SMART << MASTER_STANDBY_SHIFT)
|
2011-07-02 04:54:00 +08:00
|
|
|
#define MSTANDBY_SMART_WKUP (HWMOD_IDLEMODE_SMART_WKUP << MASTER_STANDBY_SHIFT)
|
2009-09-04 01:14:03 +08:00
|
|
|
|
|
|
|
/* omap_hwmod_sysconfig.sysc_flags capability flags */
|
|
|
|
#define SYSC_HAS_AUTOIDLE (1 << 0)
|
|
|
|
#define SYSC_HAS_SOFTRESET (1 << 1)
|
|
|
|
#define SYSC_HAS_ENAWAKEUP (1 << 2)
|
|
|
|
#define SYSC_HAS_EMUFREE (1 << 3)
|
|
|
|
#define SYSC_HAS_CLOCKACTIVITY (1 << 4)
|
|
|
|
#define SYSC_HAS_SIDLEMODE (1 << 5)
|
|
|
|
#define SYSC_HAS_MIDLEMODE (1 << 6)
|
2010-09-22 00:57:59 +08:00
|
|
|
#define SYSS_HAS_RESET_STATUS (1 << 7)
|
2010-01-20 08:30:51 +08:00
|
|
|
#define SYSC_NO_CACHE (1 << 8) /* XXX SW flag, belongs elsewhere */
|
2010-09-22 00:57:59 +08:00
|
|
|
#define SYSC_HAS_RESET_STATUS (1 << 9)
|
2012-07-04 19:09:21 +08:00
|
|
|
#define SYSC_HAS_DMADISABLE (1 << 10)
|
2009-09-04 01:14:03 +08:00
|
|
|
|
|
|
|
/* omap_hwmod_sysconfig.clockact flags */
|
|
|
|
#define CLOCKACT_TEST_BOTH 0x0
|
|
|
|
#define CLOCKACT_TEST_MAIN 0x1
|
|
|
|
#define CLOCKACT_TEST_ICLK 0x2
|
|
|
|
#define CLOCKACT_TEST_NONE 0x3
|
|
|
|
|
2010-02-25 03:05:58 +08:00
|
|
|
/**
|
|
|
|
* struct omap_hwmod_sysc_fields - hwmod OCP_SYSCONFIG register field offsets.
|
|
|
|
* @midle_shift: Offset of the midle bit
|
|
|
|
* @clkact_shift: Offset of the clockactivity bit
|
|
|
|
* @sidle_shift: Offset of the sidle bit
|
|
|
|
* @enwkup_shift: Offset of the enawakeup bit
|
|
|
|
* @srst_shift: Offset of the softreset bit
|
2010-02-23 13:09:34 +08:00
|
|
|
* @autoidle_shift: Offset of the autoidle bit
|
2012-07-04 19:09:21 +08:00
|
|
|
* @dmadisable_shift: Offset of the dmadisable bit
|
2010-02-25 03:05:58 +08:00
|
|
|
*/
|
|
|
|
struct omap_hwmod_sysc_fields {
|
|
|
|
u8 midle_shift;
|
|
|
|
u8 clkact_shift;
|
|
|
|
u8 sidle_shift;
|
|
|
|
u8 enwkup_shift;
|
|
|
|
u8 srst_shift;
|
|
|
|
u8 autoidle_shift;
|
2012-07-04 19:09:21 +08:00
|
|
|
u8 dmadisable_shift;
|
2010-02-25 03:05:58 +08:00
|
|
|
};
|
|
|
|
|
2009-09-04 01:14:03 +08:00
|
|
|
/**
|
2010-02-23 13:09:34 +08:00
|
|
|
* struct omap_hwmod_class_sysconfig - hwmod class OCP_SYS* data
|
2009-09-04 01:14:03 +08:00
|
|
|
* @rev_offs: IP block revision register offset (from module base addr)
|
|
|
|
* @sysc_offs: OCP_SYSCONFIG register offset (from module base addr)
|
|
|
|
* @syss_offs: OCP_SYSSTATUS register offset (from module base addr)
|
2012-04-13 19:08:03 +08:00
|
|
|
* @srst_udelay: Delay needed after doing a softreset in usecs
|
2009-09-04 01:14:03 +08:00
|
|
|
* @idlemodes: One or more of {SIDLE,MSTANDBY}_{OFF,FORCE,SMART}
|
|
|
|
* @sysc_flags: SYS{C,S}_HAS* flags indicating SYSCONFIG bits supported
|
|
|
|
* @clockact: the default value of the module CLOCKACTIVITY bits
|
|
|
|
*
|
|
|
|
* @clockact describes to the module which clocks are likely to be
|
|
|
|
* disabled when the PRCM issues its idle request to the module. Some
|
|
|
|
* modules have separate clockdomains for the interface clock and main
|
|
|
|
* functional clock, and can check whether they should acknowledge the
|
|
|
|
* idle request based on the internal module functionality that has
|
|
|
|
* been associated with the clocks marked in @clockact. This field is
|
|
|
|
* only used if HWMOD_SET_DEFAULT_CLOCKACT is set (see below)
|
|
|
|
*
|
2010-02-25 03:05:58 +08:00
|
|
|
* @sysc_fields: structure containing the offset positions of various bits in
|
|
|
|
* SYSCONFIG register. This can be populated using omap_hwmod_sysc_type1 or
|
|
|
|
* omap_hwmod_sysc_type2 defined in omap_hwmod_common_data.c depending on
|
|
|
|
* whether the device ip is compliant with the original PRCM protocol
|
2010-02-23 13:09:34 +08:00
|
|
|
* defined for OMAP2420 or the new PRCM protocol for new OMAP4 IPs.
|
|
|
|
* If the device follows a different scheme for the sysconfig register ,
|
2010-02-25 03:05:58 +08:00
|
|
|
* then this field has to be populated with the correct offset structure.
|
2009-09-04 01:14:03 +08:00
|
|
|
*/
|
2010-02-23 13:09:34 +08:00
|
|
|
struct omap_hwmod_class_sysconfig {
|
2012-04-19 18:03:57 +08:00
|
|
|
u32 rev_offs;
|
|
|
|
u32 sysc_offs;
|
|
|
|
u32 syss_offs;
|
2010-03-31 18:16:29 +08:00
|
|
|
u16 sysc_flags;
|
2012-04-13 19:08:03 +08:00
|
|
|
struct omap_hwmod_sysc_fields *sysc_fields;
|
|
|
|
u8 srst_udelay;
|
2009-09-04 01:14:03 +08:00
|
|
|
u8 idlemodes;
|
|
|
|
u8 clockact;
|
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
|
|
|
* struct omap_hwmod_omap2_prcm - OMAP2/3-specific PRCM data
|
|
|
|
* @module_offs: PRCM submodule offset from the start of the PRM/CM
|
|
|
|
* @prcm_reg_id: PRCM register ID (e.g., 3 for CM_AUTOIDLE3)
|
|
|
|
* @module_bit: register bit shift for AUTOIDLE, WKST, WKEN, GRPSEL regs
|
|
|
|
* @idlest_reg_id: IDLEST register ID (e.g., 3 for CM_IDLEST3)
|
|
|
|
* @idlest_idle_bit: register bit shift for CM_IDLEST slave idle bit
|
|
|
|
* @idlest_stdby_bit: register bit shift for CM_IDLEST master standby bit
|
|
|
|
*
|
|
|
|
* @prcm_reg_id and @module_bit are specific to the AUTOIDLE, WKST,
|
|
|
|
* WKEN, GRPSEL registers. In an ideal world, no extra information
|
|
|
|
* would be needed for IDLEST information, but alas, there are some
|
|
|
|
* exceptions, so @idlest_reg_id, @idlest_idle_bit, @idlest_stdby_bit
|
|
|
|
* are needed for the IDLEST registers (c.f. 2430 I2CHS, 3430 USBHOST)
|
|
|
|
*/
|
|
|
|
struct omap_hwmod_omap2_prcm {
|
|
|
|
s16 module_offs;
|
|
|
|
u8 prcm_reg_id;
|
|
|
|
u8 module_bit;
|
|
|
|
u8 idlest_reg_id;
|
|
|
|
u8 idlest_idle_bit;
|
|
|
|
u8 idlest_stdby_bit;
|
|
|
|
};
|
|
|
|
|
2012-09-24 07:28:20 +08:00
|
|
|
/*
|
|
|
|
* Possible values for struct omap_hwmod_omap4_prcm.flags
|
|
|
|
*
|
|
|
|
* HWMOD_OMAP4_NO_CONTEXT_LOSS_BIT: Some IP blocks don't have a PRCM
|
|
|
|
* module-level context loss register associated with them; this
|
|
|
|
* flag bit should be set in those cases
|
|
|
|
*/
|
|
|
|
#define HWMOD_OMAP4_NO_CONTEXT_LOSS_BIT (1 << 0)
|
2009-09-04 01:14:03 +08:00
|
|
|
|
|
|
|
/**
|
|
|
|
* struct omap_hwmod_omap4_prcm - OMAP4-specific PRCM data
|
ARM: OMAP2+: hwmod: Add support for per hwmod/module context lost count
OMAP4 has module specific context lost registers which makes it now
possible to have module level context loss count, instead of relying
on the powerdomain level context count.
Add 2 private hwmod api's to update/clear the hwmod/module specific
context lost counters/register.
Update the module specific context_lost_counter and clear the hardware
bits just after enabling the module.
omap_hwmod_get_context_loss_count() now returns the hwmod context loss
count them on platforms where they exist (OMAP4), else fall back on
the pwrdm level counters for older platforms.
Signed-off-by: Rajendra Nayak <rnayak@ti.com>
[paul@pwsan.com: added function kerneldoc, fixed structure kerneldoc,
rearranged structure to avoid memory waste, marked fns as OMAP4-specific,
prevent fn entry on non-OMAP4 chips, reduced indentation, merged update
and clear, merged patches]
[t-kristo@ti.com: added support for arch specific hwmod ops, and changed
the no context offset indicator to USHRT_MAX]
Signed-off-by: Tero Kristo <t-kristo@ti.com>
[paul@pwsan.com: use NO_CONTEXT_LOSS_BIT flag rather than USHRT_MAX;
convert unsigned context lost counter to int to match the return type;
get rid of hwmod_ops in favor of the existing soc_ops mechanism;
move context loss low-level accesses to the PRM code]
Signed-off-by: Paul Walmsley <paul@pwsan.com>
2012-11-22 07:15:17 +08:00
|
|
|
* @clkctrl_offs: offset of the PRCM clock control register
|
|
|
|
* @rstctrl_offs: offset of the XXX_RSTCTRL register located in the PRM
|
|
|
|
* @context_offs: offset of the RM_*_CONTEXT register
|
2012-09-24 07:28:19 +08:00
|
|
|
* @lostcontext_mask: bitmask for selecting bits from RM_*_CONTEXT register
|
2012-07-04 17:41:03 +08:00
|
|
|
* @rstst_reg: (AM33XX only) address of the XXX_RSTST register in the PRM
|
2009-09-04 01:14:03 +08:00
|
|
|
* @submodule_wkdep_bit: bit shift of the WKDEP range
|
2012-09-24 07:28:20 +08:00
|
|
|
* @flags: PRCM register capabilities for this IP block
|
ARM: OMAP2+: hwmod: Add support for per hwmod/module context lost count
OMAP4 has module specific context lost registers which makes it now
possible to have module level context loss count, instead of relying
on the powerdomain level context count.
Add 2 private hwmod api's to update/clear the hwmod/module specific
context lost counters/register.
Update the module specific context_lost_counter and clear the hardware
bits just after enabling the module.
omap_hwmod_get_context_loss_count() now returns the hwmod context loss
count them on platforms where they exist (OMAP4), else fall back on
the pwrdm level counters for older platforms.
Signed-off-by: Rajendra Nayak <rnayak@ti.com>
[paul@pwsan.com: added function kerneldoc, fixed structure kerneldoc,
rearranged structure to avoid memory waste, marked fns as OMAP4-specific,
prevent fn entry on non-OMAP4 chips, reduced indentation, merged update
and clear, merged patches]
[t-kristo@ti.com: added support for arch specific hwmod ops, and changed
the no context offset indicator to USHRT_MAX]
Signed-off-by: Tero Kristo <t-kristo@ti.com>
[paul@pwsan.com: use NO_CONTEXT_LOSS_BIT flag rather than USHRT_MAX;
convert unsigned context lost counter to int to match the return type;
get rid of hwmod_ops in favor of the existing soc_ops mechanism;
move context loss low-level accesses to the PRM code]
Signed-off-by: Paul Walmsley <paul@pwsan.com>
2012-11-22 07:15:17 +08:00
|
|
|
* @modulemode: allowable modulemodes
|
|
|
|
* @context_lost_counter: Count of module level context lost
|
2012-09-24 07:28:19 +08:00
|
|
|
*
|
|
|
|
* If @lostcontext_mask is not defined, context loss check code uses
|
|
|
|
* whole register without masking. @lostcontext_mask should only be
|
|
|
|
* defined in cases where @context_offs register is shared by two or
|
|
|
|
* more hwmods.
|
2009-09-04 01:14:03 +08:00
|
|
|
*/
|
|
|
|
struct omap_hwmod_omap4_prcm {
|
2011-07-10 19:56:30 +08:00
|
|
|
u16 clkctrl_offs;
|
2011-07-10 19:56:31 +08:00
|
|
|
u16 rstctrl_offs;
|
2012-07-04 17:41:03 +08:00
|
|
|
u16 rstst_offs;
|
2011-07-10 19:56:32 +08:00
|
|
|
u16 context_offs;
|
2012-09-24 07:28:19 +08:00
|
|
|
u32 lostcontext_mask;
|
2010-05-21 02:31:08 +08:00
|
|
|
u8 submodule_wkdep_bit;
|
2011-07-10 19:56:32 +08:00
|
|
|
u8 modulemode;
|
2012-09-24 07:28:20 +08:00
|
|
|
u8 flags;
|
ARM: OMAP2+: hwmod: Add support for per hwmod/module context lost count
OMAP4 has module specific context lost registers which makes it now
possible to have module level context loss count, instead of relying
on the powerdomain level context count.
Add 2 private hwmod api's to update/clear the hwmod/module specific
context lost counters/register.
Update the module specific context_lost_counter and clear the hardware
bits just after enabling the module.
omap_hwmod_get_context_loss_count() now returns the hwmod context loss
count them on platforms where they exist (OMAP4), else fall back on
the pwrdm level counters for older platforms.
Signed-off-by: Rajendra Nayak <rnayak@ti.com>
[paul@pwsan.com: added function kerneldoc, fixed structure kerneldoc,
rearranged structure to avoid memory waste, marked fns as OMAP4-specific,
prevent fn entry on non-OMAP4 chips, reduced indentation, merged update
and clear, merged patches]
[t-kristo@ti.com: added support for arch specific hwmod ops, and changed
the no context offset indicator to USHRT_MAX]
Signed-off-by: Tero Kristo <t-kristo@ti.com>
[paul@pwsan.com: use NO_CONTEXT_LOSS_BIT flag rather than USHRT_MAX;
convert unsigned context lost counter to int to match the return type;
get rid of hwmod_ops in favor of the existing soc_ops mechanism;
move context loss low-level accesses to the PRM code]
Signed-off-by: Paul Walmsley <paul@pwsan.com>
2012-11-22 07:15:17 +08:00
|
|
|
int context_lost_counter;
|
2009-09-04 01:14:03 +08:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
* omap_hwmod.flags definitions
|
|
|
|
*
|
|
|
|
* HWMOD_SWSUP_SIDLE: omap_hwmod code should manually bring module in and out
|
|
|
|
* of idle, rather than relying on module smart-idle
|
2013-03-12 03:49:00 +08:00
|
|
|
* HWMOD_SWSUP_MSTANDBY: omap_hwmod code should manually bring module in and
|
|
|
|
* out of standby, rather than relying on module smart-standby
|
2009-09-04 01:14:03 +08:00
|
|
|
* HWMOD_INIT_NO_RESET: don't reset this module at boot - important for
|
2010-12-15 03:42:36 +08:00
|
|
|
* SDRAM controller, etc. XXX probably belongs outside the main hwmod file
|
2011-03-01 02:58:14 +08:00
|
|
|
* XXX Should be HWMOD_SETUP_NO_RESET
|
2009-09-04 01:14:03 +08:00
|
|
|
* HWMOD_INIT_NO_IDLE: don't idle this module at boot - important for SDRAM
|
2010-12-15 03:42:36 +08:00
|
|
|
* controller, etc. XXX probably belongs outside the main hwmod file
|
2011-03-01 02:58:14 +08:00
|
|
|
* XXX Should be HWMOD_SETUP_NO_IDLE
|
2011-03-04 06:22:42 +08:00
|
|
|
* HWMOD_NO_OCP_AUTOIDLE: disable module autoidle (OCP_SYSCONFIG.AUTOIDLE)
|
2009-12-09 07:34:15 +08:00
|
|
|
* when module is enabled, rather than the default, which is to
|
|
|
|
* enable autoidle
|
2009-09-04 01:14:03 +08:00
|
|
|
* HWMOD_SET_DEFAULT_CLOCKACT: program CLOCKACTIVITY bits at startup
|
OMAP2+: hwmod: add support for per-class custom device reset functions
The standard omap_hwmod.c _reset() code relies on an IP block's
OCP_SYSCONFIG.SOFTRESET register bit to reset the IP block. This
works for most IP blocks on the chip, but unfortunately not all. For
example, initiator-only IP blocks often don't have any MPU-accessible
OCP-header registers, and therefore the MPU can't write to any
OCP_SYSCONFIG registers in that block. Other IP blocks, such as the
IVA and I2C, require a specialized reset sequence.
Since we need to be able to reset these IP blocks as well, allow
custom IP block reset functions to be passed into the hwmod code via a
per-hwmod-class reset function pointer, struct omap_hwmod_class.reset.
If .reset is non-null, then the hwmod _reset() code will call the custom
function instead of the standard OCP SOFTRESET-based code.
As part of this change, rename most of the existing _reset() function
code to _ocp_softreset(), to indicate more clearly that it does not work
for all cases.
Signed-off-by: Paul Walmsley <paul@pwsan.com>
Cc: Benoît Cousson <b-cousson@ti.com>
Cc: Paul Hunt <hunt@ti.com>
Cc: Stanley Liu <stanley_liu@ti.com>
2010-12-15 03:42:35 +08:00
|
|
|
* HWMOD_NO_IDLEST: this module does not have idle status - this is the case
|
2010-05-21 02:31:09 +08:00
|
|
|
* only for few initiator modules on OMAP2 & 3.
|
2010-09-22 00:57:58 +08:00
|
|
|
* HWMOD_CONTROL_OPT_CLKS_IN_RESET: Enable all optional clocks during reset.
|
|
|
|
* This is needed for devices like DSS that require optional clocks enabled
|
|
|
|
* in order to complete the reset. Optional clocks will be disabled
|
|
|
|
* again after the reset.
|
2010-10-09 01:23:22 +08:00
|
|
|
* HWMOD_16BIT_REG: Module has 16bit registers
|
2012-10-30 12:11:50 +08:00
|
|
|
* HWMOD_EXT_OPT_MAIN_CLK: The only main functional clock source for
|
|
|
|
* this IP block comes from an off-chip source and is not always
|
|
|
|
* enabled. This prevents the hwmod code from being able to
|
|
|
|
* enable and reset the IP block early. XXX Eventually it should
|
|
|
|
* be possible to query the clock framework for this information.
|
2013-01-26 15:48:56 +08:00
|
|
|
* HWMOD_BLOCK_WFI: Some OMAP peripherals apparently don't work
|
|
|
|
* correctly if the MPU is allowed to go idle while the
|
|
|
|
* peripherals are active. This is apparently true for the I2C on
|
|
|
|
* OMAP2420, and also the EMAC on AM3517/3505. It's unlikely that
|
|
|
|
* this is really true -- we're probably not configuring something
|
|
|
|
* correctly, or this is being abused to deal with some PM latency
|
|
|
|
* issues -- but we're currently suffering from a shortage of
|
|
|
|
* folks who are able to track these issues down properly.
|
2013-03-12 03:49:00 +08:00
|
|
|
* HWMOD_FORCE_MSTANDBY: Always keep MIDLEMODE bits cleared so that device
|
|
|
|
* is kept in force-standby mode. Failing to do so causes PM problems
|
|
|
|
* with musb on OMAP3630 at least. Note that musb has a dedicated register
|
|
|
|
* to control MSTANDBY signal when MIDLEMODE is set to force-standby.
|
2013-05-15 22:48:38 +08:00
|
|
|
* HWMOD_SWSUP_SIDLE_ACT: omap_hwmod code should manually bring the module
|
|
|
|
* out of idle, but rely on smart-idle to the put it back in idle,
|
|
|
|
* so the wakeups are still functional (Only known case for now is UART)
|
2014-09-18 23:58:28 +08:00
|
|
|
* HWMOD_RECONFIG_IO_CHAIN: omap_hwmod code needs to reconfigure wake-up
|
|
|
|
* events by calling _reconfigure_io_chain() when a device is enabled
|
|
|
|
* or idled.
|
2009-09-04 01:14:03 +08:00
|
|
|
*/
|
|
|
|
#define HWMOD_SWSUP_SIDLE (1 << 0)
|
|
|
|
#define HWMOD_SWSUP_MSTANDBY (1 << 1)
|
|
|
|
#define HWMOD_INIT_NO_RESET (1 << 2)
|
|
|
|
#define HWMOD_INIT_NO_IDLE (1 << 3)
|
2009-12-09 07:34:15 +08:00
|
|
|
#define HWMOD_NO_OCP_AUTOIDLE (1 << 4)
|
|
|
|
#define HWMOD_SET_DEFAULT_CLOCKACT (1 << 5)
|
2010-05-21 02:31:09 +08:00
|
|
|
#define HWMOD_NO_IDLEST (1 << 6)
|
2010-09-22 00:57:58 +08:00
|
|
|
#define HWMOD_CONTROL_OPT_CLKS_IN_RESET (1 << 7)
|
2010-10-09 01:23:22 +08:00
|
|
|
#define HWMOD_16BIT_REG (1 << 8)
|
2012-10-30 12:11:50 +08:00
|
|
|
#define HWMOD_EXT_OPT_MAIN_CLK (1 << 9)
|
2013-01-26 15:48:56 +08:00
|
|
|
#define HWMOD_BLOCK_WFI (1 << 10)
|
2013-03-12 03:49:00 +08:00
|
|
|
#define HWMOD_FORCE_MSTANDBY (1 << 11)
|
2013-05-15 22:48:38 +08:00
|
|
|
#define HWMOD_SWSUP_SIDLE_ACT (1 << 12)
|
2014-09-18 23:58:28 +08:00
|
|
|
#define HWMOD_RECONFIG_IO_CHAIN (1 << 13)
|
2009-09-04 01:14:03 +08:00
|
|
|
|
|
|
|
/*
|
|
|
|
* omap_hwmod._int_flags definitions
|
|
|
|
* These are for internal use only and are managed by the omap_hwmod code.
|
|
|
|
*
|
|
|
|
* _HWMOD_NO_MPU_PORT: no path exists for the MPU to write to this module
|
|
|
|
* _HWMOD_SYSCONFIG_LOADED: set when the OCP_SYSCONFIG value has been cached
|
2011-12-16 20:50:12 +08:00
|
|
|
* _HWMOD_SKIP_ENABLE: set if hwmod enabled during init (HWMOD_INIT_NO_IDLE) -
|
|
|
|
* causes the first call to _enable() to only update the pinmux
|
2009-09-04 01:14:03 +08:00
|
|
|
*/
|
|
|
|
#define _HWMOD_NO_MPU_PORT (1 << 0)
|
2013-04-01 10:22:22 +08:00
|
|
|
#define _HWMOD_SYSCONFIG_LOADED (1 << 1)
|
|
|
|
#define _HWMOD_SKIP_ENABLE (1 << 2)
|
2009-09-04 01:14:03 +08:00
|
|
|
|
|
|
|
/*
|
|
|
|
* omap_hwmod._state definitions
|
|
|
|
*
|
|
|
|
* INITIALIZED: reset (optionally), initialized, enabled, disabled
|
|
|
|
* (optionally)
|
|
|
|
*
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
#define _HWMOD_STATE_UNKNOWN 0
|
|
|
|
#define _HWMOD_STATE_REGISTERED 1
|
|
|
|
#define _HWMOD_STATE_CLKS_INITED 2
|
|
|
|
#define _HWMOD_STATE_INITIALIZED 3
|
|
|
|
#define _HWMOD_STATE_ENABLED 4
|
|
|
|
#define _HWMOD_STATE_IDLE 5
|
|
|
|
#define _HWMOD_STATE_DISABLED 6
|
|
|
|
|
2010-02-23 13:09:34 +08:00
|
|
|
/**
|
|
|
|
* struct omap_hwmod_class - the type of an IP block
|
|
|
|
* @name: name of the hwmod_class
|
|
|
|
* @sysc: device SYSCONFIG/SYSSTATUS register data
|
|
|
|
* @rev: revision of the IP class
|
2010-12-15 03:42:34 +08:00
|
|
|
* @pre_shutdown: ptr to fn to be executed immediately prior to device shutdown
|
OMAP2+: hwmod: add support for per-class custom device reset functions
The standard omap_hwmod.c _reset() code relies on an IP block's
OCP_SYSCONFIG.SOFTRESET register bit to reset the IP block. This
works for most IP blocks on the chip, but unfortunately not all. For
example, initiator-only IP blocks often don't have any MPU-accessible
OCP-header registers, and therefore the MPU can't write to any
OCP_SYSCONFIG registers in that block. Other IP blocks, such as the
IVA and I2C, require a specialized reset sequence.
Since we need to be able to reset these IP blocks as well, allow
custom IP block reset functions to be passed into the hwmod code via a
per-hwmod-class reset function pointer, struct omap_hwmod_class.reset.
If .reset is non-null, then the hwmod _reset() code will call the custom
function instead of the standard OCP SOFTRESET-based code.
As part of this change, rename most of the existing _reset() function
code to _ocp_softreset(), to indicate more clearly that it does not work
for all cases.
Signed-off-by: Paul Walmsley <paul@pwsan.com>
Cc: Benoît Cousson <b-cousson@ti.com>
Cc: Paul Hunt <hunt@ti.com>
Cc: Stanley Liu <stanley_liu@ti.com>
2010-12-15 03:42:35 +08:00
|
|
|
* @reset: ptr to fn to be executed in place of the standard hwmod reset fn
|
2013-02-11 02:22:22 +08:00
|
|
|
* @enable_preprogram: ptr to fn to be executed during device enable
|
2010-02-23 13:09:34 +08:00
|
|
|
*
|
|
|
|
* Represent the class of a OMAP hardware "modules" (e.g. timer,
|
|
|
|
* smartreflex, gpio, uart...)
|
2010-12-15 03:42:34 +08:00
|
|
|
*
|
|
|
|
* @pre_shutdown is a function that will be run immediately before
|
|
|
|
* hwmod clocks are disabled, etc. It is intended for use for hwmods
|
|
|
|
* like the MPU watchdog, which cannot be disabled with the standard
|
|
|
|
* omap_hwmod_shutdown(). The function should return 0 upon success,
|
|
|
|
* or some negative error upon failure. Returning an error will cause
|
|
|
|
* omap_hwmod_shutdown() to abort the device shutdown and return an
|
|
|
|
* error.
|
OMAP2+: hwmod: add support for per-class custom device reset functions
The standard omap_hwmod.c _reset() code relies on an IP block's
OCP_SYSCONFIG.SOFTRESET register bit to reset the IP block. This
works for most IP blocks on the chip, but unfortunately not all. For
example, initiator-only IP blocks often don't have any MPU-accessible
OCP-header registers, and therefore the MPU can't write to any
OCP_SYSCONFIG registers in that block. Other IP blocks, such as the
IVA and I2C, require a specialized reset sequence.
Since we need to be able to reset these IP blocks as well, allow
custom IP block reset functions to be passed into the hwmod code via a
per-hwmod-class reset function pointer, struct omap_hwmod_class.reset.
If .reset is non-null, then the hwmod _reset() code will call the custom
function instead of the standard OCP SOFTRESET-based code.
As part of this change, rename most of the existing _reset() function
code to _ocp_softreset(), to indicate more clearly that it does not work
for all cases.
Signed-off-by: Paul Walmsley <paul@pwsan.com>
Cc: Benoît Cousson <b-cousson@ti.com>
Cc: Paul Hunt <hunt@ti.com>
Cc: Stanley Liu <stanley_liu@ti.com>
2010-12-15 03:42:35 +08:00
|
|
|
*
|
|
|
|
* If @reset is defined, then the function it points to will be
|
|
|
|
* executed in place of the standard hwmod _reset() code in
|
|
|
|
* mach-omap2/omap_hwmod.c. This is needed for IP blocks which have
|
|
|
|
* unusual reset sequences - usually processor IP blocks like the IVA.
|
2010-02-23 13:09:34 +08:00
|
|
|
*/
|
|
|
|
struct omap_hwmod_class {
|
|
|
|
const char *name;
|
|
|
|
struct omap_hwmod_class_sysconfig *sysc;
|
|
|
|
u32 rev;
|
2010-12-15 03:42:34 +08:00
|
|
|
int (*pre_shutdown)(struct omap_hwmod *oh);
|
OMAP2+: hwmod: add support for per-class custom device reset functions
The standard omap_hwmod.c _reset() code relies on an IP block's
OCP_SYSCONFIG.SOFTRESET register bit to reset the IP block. This
works for most IP blocks on the chip, but unfortunately not all. For
example, initiator-only IP blocks often don't have any MPU-accessible
OCP-header registers, and therefore the MPU can't write to any
OCP_SYSCONFIG registers in that block. Other IP blocks, such as the
IVA and I2C, require a specialized reset sequence.
Since we need to be able to reset these IP blocks as well, allow
custom IP block reset functions to be passed into the hwmod code via a
per-hwmod-class reset function pointer, struct omap_hwmod_class.reset.
If .reset is non-null, then the hwmod _reset() code will call the custom
function instead of the standard OCP SOFTRESET-based code.
As part of this change, rename most of the existing _reset() function
code to _ocp_softreset(), to indicate more clearly that it does not work
for all cases.
Signed-off-by: Paul Walmsley <paul@pwsan.com>
Cc: Benoît Cousson <b-cousson@ti.com>
Cc: Paul Hunt <hunt@ti.com>
Cc: Stanley Liu <stanley_liu@ti.com>
2010-12-15 03:42:35 +08:00
|
|
|
int (*reset)(struct omap_hwmod *oh);
|
2013-02-11 02:22:22 +08:00
|
|
|
int (*enable_preprogram)(struct omap_hwmod *oh);
|
2010-02-23 13:09:34 +08:00
|
|
|
};
|
|
|
|
|
2012-04-19 18:04:30 +08:00
|
|
|
/**
|
|
|
|
* struct omap_hwmod_link - internal structure linking hwmods with ocp_ifs
|
|
|
|
* @ocp_if: OCP interface structure record pointer
|
|
|
|
* @node: list_head pointing to next struct omap_hwmod_link in a list
|
|
|
|
*/
|
|
|
|
struct omap_hwmod_link {
|
|
|
|
struct omap_hwmod_ocp_if *ocp_if;
|
|
|
|
struct list_head node;
|
|
|
|
};
|
|
|
|
|
2009-09-04 01:14:03 +08:00
|
|
|
/**
|
|
|
|
* struct omap_hwmod - integration data for OMAP hardware "modules" (IP blocks)
|
|
|
|
* @name: name of the hwmod
|
2010-02-23 13:09:34 +08:00
|
|
|
* @class: struct omap_hwmod_class * to the class of this hwmod
|
2009-09-04 01:14:03 +08:00
|
|
|
* @od: struct omap_device currently associated with this hwmod (internal use)
|
2011-07-10 09:14:06 +08:00
|
|
|
* @mpu_irqs: ptr to an array of MPU IRQs
|
2011-07-10 09:14:07 +08:00
|
|
|
* @sdma_reqs: ptr to an array of System DMA request IDs
|
2009-09-04 01:14:03 +08:00
|
|
|
* @prcm: PRCM data pertaining to this hwmod
|
2010-02-23 13:09:31 +08:00
|
|
|
* @main_clk: main clock: OMAP clock name
|
2009-09-04 01:14:03 +08:00
|
|
|
* @_clk: pointer to the main struct clk (filled in at runtime)
|
|
|
|
* @opt_clks: other device clocks that drivers can request (0..*)
|
2010-08-18 18:51:58 +08:00
|
|
|
* @voltdm: pointer to voltage domain (filled in at runtime)
|
2009-09-04 01:14:03 +08:00
|
|
|
* @dev_attr: arbitrary device attributes that can be passed to the driver
|
|
|
|
* @_sysc_cache: internal-use hwmod flags
|
2013-07-05 23:13:00 +08:00
|
|
|
* @mpu_rt_idx: index of device address space for register target (for DT boot)
|
2010-07-27 06:34:33 +08:00
|
|
|
* @_mpu_rt_va: cached register target start address (internal use)
|
2012-04-19 18:04:30 +08:00
|
|
|
* @_mpu_port: cached MPU register target slave (internal use)
|
2009-09-04 01:14:03 +08:00
|
|
|
* @opt_clks_cnt: number of @opt_clks
|
|
|
|
* @master_cnt: number of @master entries
|
|
|
|
* @slaves_cnt: number of @slave entries
|
|
|
|
* @response_lat: device OCP response latency (in interface clock cycles)
|
|
|
|
* @_int_flags: internal-use hwmod flags
|
|
|
|
* @_state: internal-use hwmod state
|
2010-12-15 03:42:35 +08:00
|
|
|
* @_postsetup_state: internal-use state to leave the hwmod in after _setup()
|
2009-09-04 01:14:03 +08:00
|
|
|
* @flags: hwmod flags (documented below)
|
OMAP2+: hwmod: upgrade per-hwmod mutex to a spinlock
Change the per-hwmod mutex to a spinlock. (The per-hwmod lock
serializes most post-initialization hwmod operations such as enable,
idle, and shutdown.) Spinlocks are needed, because in some cases,
hwmods must be enabled from timer interrupt disabled-context, such as
an ISR. The current use-case that is driving this is the OMAP GPIO
block ISR: it can trigger interrupts even with its clocks disabled,
but these clocks are needed for register accesses in the ISR to succeed.
This patch also effectively reverts commit
848240223c35fcc71c424ad51a8e8aef42d3879c - this patch makes
_omap_hwmod_enable() and _omap_hwmod_init() static, renames them back
to _enable() and _idle(), and changes their callers to call the
spinlocking versions. Previously, since omap_hwmod_{enable,init}()
attempted to take mutexes, these functions could not be called while
the timer interrupt was disabled; but now that the functions use
spinlocks and save and restore the IRQ state, it is appropriate to
call them directly.
Kevin Hilman <khilman@deeprootsystems.com> originally proposed this
patch - thanks Kevin.
Signed-off-by: Paul Walmsley <paul@pwsan.com>
Cc: Kevin Hilman <khilman@deeprootsystems.com>
Cc: Benoît Cousson <b-cousson@ti.com>
2010-12-15 03:42:35 +08:00
|
|
|
* @_lock: spinlock serializing operations on this hwmod
|
2009-09-04 01:14:03 +08:00
|
|
|
* @node: list node for hwmod list (internal use)
|
2014-10-09 22:03:14 +08:00
|
|
|
* @parent_hwmod: (temporary) a pointer to the hierarchical parent of this hwmod
|
2009-09-04 01:14:03 +08:00
|
|
|
*
|
2010-02-23 13:09:31 +08:00
|
|
|
* @main_clk refers to this module's "main clock," which for our
|
|
|
|
* purposes is defined as "the functional clock needed for register
|
|
|
|
* accesses to complete." Modules may not have a main clock if the
|
|
|
|
* interface clock also serves as a main clock.
|
2009-09-04 01:14:03 +08:00
|
|
|
*
|
|
|
|
* Parameter names beginning with an underscore are managed internally by
|
|
|
|
* the omap_hwmod code and should not be set during initialization.
|
2012-04-19 18:04:30 +08:00
|
|
|
*
|
|
|
|
* @masters and @slaves are now deprecated.
|
2014-10-09 22:03:14 +08:00
|
|
|
*
|
|
|
|
* @parent_hwmod is temporary; there should be no need for it, as this
|
|
|
|
* information should already be expressed in the OCP interface
|
|
|
|
* structures. @parent_hwmod is present as a workaround until we improve
|
|
|
|
* handling for hwmods with multiple parents (e.g., OMAP4+ DSS with
|
|
|
|
* multiple register targets across different interconnects).
|
2009-09-04 01:14:03 +08:00
|
|
|
*/
|
|
|
|
struct omap_hwmod {
|
|
|
|
const char *name;
|
2010-02-23 13:09:34 +08:00
|
|
|
struct omap_hwmod_class *class;
|
2009-09-04 01:14:03 +08:00
|
|
|
struct omap_device *od;
|
2010-12-23 10:42:35 +08:00
|
|
|
struct omap_hwmod_mux_info *mux;
|
2009-12-09 07:34:16 +08:00
|
|
|
struct omap_hwmod_irq_info *mpu_irqs;
|
2010-09-22 00:34:08 +08:00
|
|
|
struct omap_hwmod_dma_info *sdma_reqs;
|
OMAP: hwmod: Add hardreset management support
Most processor IPs does have a hardreset signal controlled by the PRM.
This is different of the softreset used for local IP reset from the
SYSCONFIG register.
The granularity can be much finer than orginal HWMOD, for ex, the IVA
hwmod contains 3 reset lines, the IPU 3 as well, the DSP 2...
Since this granularity is needed by the driver, we have to ensure
than one hwmod exist for each hardreset line.
- Store reset lines as hwmod resources that a driver can query by name like
an irq or sdma line.
- Add two functions for asserting / deasserting reset lines in hwmods
processor that require manual reset control.
- Add one functions to get the current reset state.
- If an hwmod contains only one line, an automatic assertion / de-assertion
is done.
-> de-assert the hardreset line only during enable from disable transition
-> assert the hardreset line only during shutdown
Note: The hwmods with hardreset line and HWMOD_INIT_NO_RESET flag must be
kept in INITIALIZED state.
They can be properly enabled only if the hardreset line is de-asserted
before.
For information here is the list of IPs with HW reset control
on an OMAP4430 device:
RM_DSP_RSTCTRL
1,1,'RST2','RW','1','DSP - MMU, cache and slave interface reset control'
0,0,'RST1','RW','1','DSP - DSP reset control'
RM_IVA_RSTCTRL
2,2,'RST3','RW','1','IVA logic and SL2 reset control'
1,1,'RST2','RW','1','IVA Sequencer2 reset control'
0,0,'RST1','RW','1','IVA sequencer1 reset control'
RM_IPU_RSTCTRL
2,2,'RST3','RW','1','IPU MMU and CACHE interface reset control.'
1,1,'RST2','RW','1','IPU Cortex M3 CPU2 reset control.'
0,0,'RST1','RW','1','IPU Cortex M3 CPU1 reset control.'
PRM_RSTCTRL
1,1,'RST_GLOBAL_COLD_SW','RW','0','Global COLD software reset control.'
0,0,'RST_GLOBAL_WARM_SW','RW','0','Global WARM software reset control.'
RM_CPU0_CPU0_RSTCTRL
RM_CPU1_CPU1_RSTCTRL
0,0,'RST','RW','0','Cortex A9 CPU0&1 warm local reset control'
Signed-off-by: Benoit Cousson <b-cousson@ti.com>
[paul@pwsan.com: made the hardreset functions static; moved the register
twiddling into prm*.c functions in previous patches; changed the
function names to conform with hwmod practice]
Signed-off-by: Paul Walmsley <paul@pwsan.com>
Cc: Kevin Hilman <khilman@deeprootsystems.com>
Cc: Rajendra Nayak <rnayak@ti.com>
2010-09-22 00:34:11 +08:00
|
|
|
struct omap_hwmod_rst_info *rst_lines;
|
2009-09-04 01:14:03 +08:00
|
|
|
union {
|
|
|
|
struct omap_hwmod_omap2_prcm omap2;
|
|
|
|
struct omap_hwmod_omap4_prcm omap4;
|
|
|
|
} prcm;
|
2010-02-23 13:09:31 +08:00
|
|
|
const char *main_clk;
|
2009-09-04 01:14:03 +08:00
|
|
|
struct clk *_clk;
|
|
|
|
struct omap_hwmod_opt_clk *opt_clks;
|
2011-07-10 19:56:29 +08:00
|
|
|
char *clkdm_name;
|
2011-07-10 19:56:30 +08:00
|
|
|
struct clockdomain *clkdm;
|
2012-04-19 18:04:30 +08:00
|
|
|
struct list_head master_ports; /* connect to *_IA */
|
|
|
|
struct list_head slave_ports; /* connect to *_TA */
|
2009-09-04 01:14:03 +08:00
|
|
|
void *dev_attr;
|
|
|
|
u32 _sysc_cache;
|
2010-07-27 06:34:33 +08:00
|
|
|
void __iomem *_mpu_rt_va;
|
OMAP2+: hwmod: upgrade per-hwmod mutex to a spinlock
Change the per-hwmod mutex to a spinlock. (The per-hwmod lock
serializes most post-initialization hwmod operations such as enable,
idle, and shutdown.) Spinlocks are needed, because in some cases,
hwmods must be enabled from timer interrupt disabled-context, such as
an ISR. The current use-case that is driving this is the OMAP GPIO
block ISR: it can trigger interrupts even with its clocks disabled,
but these clocks are needed for register accesses in the ISR to succeed.
This patch also effectively reverts commit
848240223c35fcc71c424ad51a8e8aef42d3879c - this patch makes
_omap_hwmod_enable() and _omap_hwmod_init() static, renames them back
to _enable() and _idle(), and changes their callers to call the
spinlocking versions. Previously, since omap_hwmod_{enable,init}()
attempted to take mutexes, these functions could not be called while
the timer interrupt was disabled; but now that the functions use
spinlocks and save and restore the IRQ state, it is appropriate to
call them directly.
Kevin Hilman <khilman@deeprootsystems.com> originally proposed this
patch - thanks Kevin.
Signed-off-by: Paul Walmsley <paul@pwsan.com>
Cc: Kevin Hilman <khilman@deeprootsystems.com>
Cc: Benoît Cousson <b-cousson@ti.com>
2010-12-15 03:42:35 +08:00
|
|
|
spinlock_t _lock;
|
2015-02-26 15:00:51 +08:00
|
|
|
struct lock_class_key hwmod_key; /* unique lock class */
|
2009-09-04 01:14:03 +08:00
|
|
|
struct list_head node;
|
2012-04-19 18:04:30 +08:00
|
|
|
struct omap_hwmod_ocp_if *_mpu_port;
|
2015-01-17 18:21:08 +08:00
|
|
|
unsigned int (*xlate_irq)(unsigned int);
|
2009-09-04 01:14:03 +08:00
|
|
|
u16 flags;
|
2013-07-05 23:13:00 +08:00
|
|
|
u8 mpu_rt_idx;
|
2009-09-04 01:14:03 +08:00
|
|
|
u8 response_lat;
|
OMAP: hwmod: Add hardreset management support
Most processor IPs does have a hardreset signal controlled by the PRM.
This is different of the softreset used for local IP reset from the
SYSCONFIG register.
The granularity can be much finer than orginal HWMOD, for ex, the IVA
hwmod contains 3 reset lines, the IPU 3 as well, the DSP 2...
Since this granularity is needed by the driver, we have to ensure
than one hwmod exist for each hardreset line.
- Store reset lines as hwmod resources that a driver can query by name like
an irq or sdma line.
- Add two functions for asserting / deasserting reset lines in hwmods
processor that require manual reset control.
- Add one functions to get the current reset state.
- If an hwmod contains only one line, an automatic assertion / de-assertion
is done.
-> de-assert the hardreset line only during enable from disable transition
-> assert the hardreset line only during shutdown
Note: The hwmods with hardreset line and HWMOD_INIT_NO_RESET flag must be
kept in INITIALIZED state.
They can be properly enabled only if the hardreset line is de-asserted
before.
For information here is the list of IPs with HW reset control
on an OMAP4430 device:
RM_DSP_RSTCTRL
1,1,'RST2','RW','1','DSP - MMU, cache and slave interface reset control'
0,0,'RST1','RW','1','DSP - DSP reset control'
RM_IVA_RSTCTRL
2,2,'RST3','RW','1','IVA logic and SL2 reset control'
1,1,'RST2','RW','1','IVA Sequencer2 reset control'
0,0,'RST1','RW','1','IVA sequencer1 reset control'
RM_IPU_RSTCTRL
2,2,'RST3','RW','1','IPU MMU and CACHE interface reset control.'
1,1,'RST2','RW','1','IPU Cortex M3 CPU2 reset control.'
0,0,'RST1','RW','1','IPU Cortex M3 CPU1 reset control.'
PRM_RSTCTRL
1,1,'RST_GLOBAL_COLD_SW','RW','0','Global COLD software reset control.'
0,0,'RST_GLOBAL_WARM_SW','RW','0','Global WARM software reset control.'
RM_CPU0_CPU0_RSTCTRL
RM_CPU1_CPU1_RSTCTRL
0,0,'RST','RW','0','Cortex A9 CPU0&1 warm local reset control'
Signed-off-by: Benoit Cousson <b-cousson@ti.com>
[paul@pwsan.com: made the hardreset functions static; moved the register
twiddling into prm*.c functions in previous patches; changed the
function names to conform with hwmod practice]
Signed-off-by: Paul Walmsley <paul@pwsan.com>
Cc: Kevin Hilman <khilman@deeprootsystems.com>
Cc: Rajendra Nayak <rnayak@ti.com>
2010-09-22 00:34:11 +08:00
|
|
|
u8 rst_lines_cnt;
|
2009-09-04 01:14:03 +08:00
|
|
|
u8 opt_clks_cnt;
|
|
|
|
u8 masters_cnt;
|
|
|
|
u8 slaves_cnt;
|
|
|
|
u8 hwmods_cnt;
|
|
|
|
u8 _int_flags;
|
|
|
|
u8 _state;
|
2010-12-15 03:42:35 +08:00
|
|
|
u8 _postsetup_state;
|
2014-10-09 22:03:14 +08:00
|
|
|
struct omap_hwmod *parent_hwmod;
|
2009-09-04 01:14:03 +08:00
|
|
|
};
|
|
|
|
|
|
|
|
struct omap_hwmod *omap_hwmod_lookup(const char *name);
|
2010-07-27 06:34:30 +08:00
|
|
|
int omap_hwmod_for_each(int (*fn)(struct omap_hwmod *oh, void *data),
|
|
|
|
void *data);
|
2009-09-04 01:14:03 +08:00
|
|
|
|
2011-02-23 15:14:07 +08:00
|
|
|
int __init omap_hwmod_setup_one(const char *name);
|
2009-09-04 01:14:03 +08:00
|
|
|
|
|
|
|
int omap_hwmod_enable(struct omap_hwmod *oh);
|
|
|
|
int omap_hwmod_idle(struct omap_hwmod *oh);
|
|
|
|
int omap_hwmod_shutdown(struct omap_hwmod *oh);
|
|
|
|
|
2010-09-22 00:34:11 +08:00
|
|
|
int omap_hwmod_assert_hardreset(struct omap_hwmod *oh, const char *name);
|
|
|
|
int omap_hwmod_deassert_hardreset(struct omap_hwmod *oh, const char *name);
|
2009-09-04 01:14:03 +08:00
|
|
|
|
2010-10-09 01:23:22 +08:00
|
|
|
void omap_hwmod_write(u32 v, struct omap_hwmod *oh, u16 reg_offs);
|
|
|
|
u32 omap_hwmod_read(struct omap_hwmod *oh, u16 reg_offs);
|
2011-07-10 19:27:16 +08:00
|
|
|
int omap_hwmod_softreset(struct omap_hwmod *oh);
|
2009-09-04 01:14:03 +08:00
|
|
|
|
2012-11-22 07:15:17 +08:00
|
|
|
int omap_hwmod_count_resources(struct omap_hwmod *oh, unsigned long flags);
|
2009-09-04 01:14:03 +08:00
|
|
|
int omap_hwmod_fill_resources(struct omap_hwmod *oh, struct resource *res);
|
2012-08-29 17:48:11 +08:00
|
|
|
int omap_hwmod_fill_dma_resources(struct omap_hwmod *oh, struct resource *res);
|
2012-04-19 09:10:06 +08:00
|
|
|
int omap_hwmod_get_resource_byname(struct omap_hwmod *oh, unsigned int type,
|
|
|
|
const char *name, struct resource *res);
|
2009-09-04 01:14:03 +08:00
|
|
|
|
|
|
|
struct powerdomain *omap_hwmod_get_pwrdm(struct omap_hwmod *oh);
|
2010-07-27 06:34:33 +08:00
|
|
|
void __iomem *omap_hwmod_get_mpu_rt_va(struct omap_hwmod *oh);
|
2009-09-04 01:14:03 +08:00
|
|
|
|
|
|
|
int omap_hwmod_enable_wakeup(struct omap_hwmod *oh);
|
|
|
|
int omap_hwmod_disable_wakeup(struct omap_hwmod *oh);
|
|
|
|
|
2010-02-23 13:09:34 +08:00
|
|
|
int omap_hwmod_for_each_by_class(const char *classname,
|
|
|
|
int (*fn)(struct omap_hwmod *oh,
|
|
|
|
void *user),
|
|
|
|
void *user);
|
|
|
|
|
2010-12-15 03:42:35 +08:00
|
|
|
int omap_hwmod_set_postsetup_state(struct omap_hwmod *oh, u8 state);
|
2011-06-09 21:56:23 +08:00
|
|
|
int omap_hwmod_get_context_loss_count(struct omap_hwmod *oh);
|
2010-12-15 03:42:35 +08:00
|
|
|
|
2012-06-19 02:12:23 +08:00
|
|
|
extern void __init omap_hwmod_init(void);
|
|
|
|
|
2012-07-06 15:58:43 +08:00
|
|
|
const char *omap_hwmod_get_main_clk(struct omap_hwmod *oh);
|
|
|
|
|
2013-02-11 02:22:23 +08:00
|
|
|
/*
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
|
|
|
|
extern int omap_hwmod_aess_preprogram(struct omap_hwmod *oh);
|
|
|
|
|
2010-02-23 13:09:32 +08:00
|
|
|
/*
|
|
|
|
* Chip variant-specific hwmod init routines - XXX should be converted
|
|
|
|
* to use initcalls once the initial boot ordering is straightened out
|
|
|
|
*/
|
|
|
|
extern int omap2420_hwmod_init(void);
|
|
|
|
extern int omap2430_hwmod_init(void);
|
|
|
|
extern int omap3xxx_hwmod_init(void);
|
2010-05-12 23:54:36 +08:00
|
|
|
extern int omap44xx_hwmod_init(void);
|
2013-05-30 00:38:10 +08:00
|
|
|
extern int omap54xx_hwmod_init(void);
|
2012-07-26 03:51:13 +08:00
|
|
|
extern int am33xx_hwmod_init(void);
|
2015-01-27 01:26:32 +08:00
|
|
|
extern int ti81xx_hwmod_init(void);
|
2013-07-09 15:32:16 +08:00
|
|
|
extern int dra7xx_hwmod_init(void);
|
ARM: OMAP2+: hwmod: AM43x support
Add hwmod support for IP's that are present in AM43x, but not in AM335x.
AM43x additional ones added here are,
1. synctimer
2. timer8-11
3. ehrpwm3-5
4. spi2-4
5. gpio4-5
AM43x pruss interconnect which is different as compared to AM335x, has
been taken care.
And register offsets for same hwmod's shared with AM335x is different,
AM43x register offsets are updated appropriately.
ocp clock of those in l4_wkup is fed from "sys_clkin_ck" instead of
"dpll_core_m4_div2_ck", so "ocpif" for those in AM43x l4_wkup has been
added seperately.
hwmod's has been added for those that have main clock (wkup_m3, control,
gpio0) and clock domain (l4_hs) different from AM335x. debugss and
adc_tsc that have different clocks and clockdomains repectively has not
been added due to the reasons mentioned below.
AM43x also has IP's like qspi, hdq1w, vpfe, des, rng, usb, dss, debugss,
adc_tsc. These are not handled here due to both/either of following
reasons,
1. To avoid churn; most of them don't have DT bindings, which would
necessitate adding address space in hwmod, which any way would have
to be removed once DT bindings happen with driver support.
2. patches would come in from sources other than the author
Signed-off-by: Afzal Mohammed <afzal@ti.com>
Acked-by: Rajendra Nayak <rnayak@ti.com>
Acked-by: Tony Lindgren <tony@atomide.com>
Signed-off-by: Paul Walmsley <paul@pwsan.com>
2013-10-12 18:16:12 +08:00
|
|
|
int am43xx_hwmod_init(void);
|
2010-02-23 13:09:32 +08:00
|
|
|
|
2012-04-19 18:04:30 +08:00
|
|
|
extern int __init omap_hwmod_register_links(struct omap_hwmod_ocp_if **ois);
|
|
|
|
|
2009-09-04 01:14:03 +08:00
|
|
|
#endif
|