Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 184797
b: refs/heads/master
c: 358f0e6
h: refs/heads/master
i:
  184795: 8070472
v: v3
  • Loading branch information
Thara Gopinath authored and Paul Walmsley committed Feb 24, 2010
1 parent 2d15aab commit ad5bdd8
Show file tree
Hide file tree
Showing 5 changed files with 192 additions and 30 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: 5eb75f557843132da08938609def2774ee467d95
refs/heads/master: 358f0e630d5409ab3837b86db3595560eae773b6
3 changes: 2 additions & 1 deletion trunk/arch/arm/mach-omap2/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@
# Common support
obj-y := id.o io.o control.o mux.o devices.o serial.o gpmc.o timer-gp.o

omap-2-3-common = irq.o sdrc.o omap_hwmod.o
omap-2-3-common = irq.o sdrc.o omap_hwmod.o \
omap_hwmod_common_data.o
omap-3-4-common = dpll3xxx.o
prcm-common = prcm.o powerdomain.o
clock-common = clock.o clock_common_data.o \
Expand Down
100 changes: 87 additions & 13 deletions trunk/arch/arm/mach-omap2/omap_hwmod.c
Original file line number Diff line number Diff line change
Expand Up @@ -137,12 +137,24 @@ static void _write_sysconfig(u32 v, struct omap_hwmod *oh)
static int _set_master_standbymode(struct omap_hwmod *oh, u8 standbymode,
u32 *v)
{
u32 mstandby_mask;
u8 mstandby_shift;

if (!oh->sysconfig ||
!(oh->sysconfig->sysc_flags & SYSC_HAS_MIDLEMODE))
return -EINVAL;

*v &= ~SYSC_MIDLEMODE_MASK;
*v |= __ffs(standbymode) << SYSC_MIDLEMODE_SHIFT;
if (!oh->sysconfig->sysc_fields) {
WARN(!oh->sysconfig->sysc_fields, "offset struct for "
"sysconfig not provided!\n");
return -EINVAL;
}

mstandby_shift = oh->sysconfig->sysc_fields->midle_shift;
mstandby_mask = (0x3 << mstandby_shift);

*v &= ~mstandby_mask;
*v |= __ffs(standbymode) << mstandby_shift;

return 0;
}
Expand All @@ -159,12 +171,24 @@ static int _set_master_standbymode(struct omap_hwmod *oh, u8 standbymode,
*/
static int _set_slave_idlemode(struct omap_hwmod *oh, u8 idlemode, u32 *v)
{
u32 sidle_mask;
u8 sidle_shift;

if (!oh->sysconfig ||
!(oh->sysconfig->sysc_flags & SYSC_HAS_SIDLEMODE))
return -EINVAL;

*v &= ~SYSC_SIDLEMODE_MASK;
*v |= __ffs(idlemode) << SYSC_SIDLEMODE_SHIFT;
if (!oh->sysconfig->sysc_fields) {
WARN(!oh->sysconfig->sysc_fields, "offset struct for "
"sysconfig not provided!\n");
return -EINVAL;
}

sidle_shift = oh->sysconfig->sysc_fields->sidle_shift;
sidle_mask = (0x3 << sidle_shift);

*v &= ~sidle_mask;
*v |= __ffs(idlemode) << sidle_shift;

return 0;
}
Expand All @@ -182,12 +206,24 @@ static int _set_slave_idlemode(struct omap_hwmod *oh, u8 idlemode, u32 *v)
*/
static int _set_clockactivity(struct omap_hwmod *oh, u8 clockact, u32 *v)
{
u32 clkact_mask;
u8 clkact_shift;

if (!oh->sysconfig ||
!(oh->sysconfig->sysc_flags & SYSC_HAS_CLOCKACTIVITY))
return -EINVAL;

*v &= ~SYSC_CLOCKACTIVITY_MASK;
*v |= clockact << SYSC_CLOCKACTIVITY_SHIFT;
if (!oh->sysconfig->sysc_fields) {
WARN(!oh->sysconfig->sysc_fields, "offset struct for "
"sysconfig not provided!\n");
return -EINVAL;
}

clkact_shift = oh->sysconfig->sysc_fields->clkact_shift;
clkact_mask = (0x3 << clkact_shift);

*v &= ~clkact_mask;
*v |= clockact << clkact_shift;

return 0;
}
Expand All @@ -202,11 +238,21 @@ static int _set_clockactivity(struct omap_hwmod *oh, u8 clockact, u32 *v)
*/
static int _set_softreset(struct omap_hwmod *oh, u32 *v)
{
u32 softrst_mask;

if (!oh->sysconfig ||
!(oh->sysconfig->sysc_flags & SYSC_HAS_SOFTRESET))
return -EINVAL;

*v |= SYSC_SOFTRESET_MASK;
if (!oh->sysconfig->sysc_fields) {
WARN(!oh->sysconfig->sysc_fields, "offset struct for "
"sysconfig not provided!\n");
return -EINVAL;
}

softrst_mask = (0x1 << oh->sysconfig->sysc_fields->srst_shift);

*v |= softrst_mask;

return 0;
}
Expand All @@ -227,12 +273,24 @@ static int _set_softreset(struct omap_hwmod *oh, u32 *v)
static int _set_module_autoidle(struct omap_hwmod *oh, u8 autoidle,
u32 *v)
{
u32 autoidle_mask;
u8 autoidle_shift;

if (!oh->sysconfig ||
!(oh->sysconfig->sysc_flags & SYSC_HAS_AUTOIDLE))
return -EINVAL;

*v &= ~SYSC_AUTOIDLE_MASK;
*v |= autoidle << SYSC_AUTOIDLE_SHIFT;
if (!oh->sysconfig->sysc_fields) {
WARN(oh->sysconfig->sysc_fields, "offset struct for "
"sysconfig not provided!\n");
return -EINVAL;
}

autoidle_shift = oh->sysconfig->sysc_fields->autoidle_shift;
autoidle_mask = (0x3 << autoidle_shift);

*v &= ~autoidle_mask;
*v |= autoidle << autoidle_shift;

return 0;
}
Expand All @@ -246,14 +304,22 @@ static int _set_module_autoidle(struct omap_hwmod *oh, u8 autoidle,
*/
static int _enable_wakeup(struct omap_hwmod *oh)
{
u32 v;
u32 v, wakeup_mask;

if (!oh->sysconfig ||
!(oh->sysconfig->sysc_flags & SYSC_HAS_ENAWAKEUP))
return -EINVAL;

if (!oh->sysconfig->sysc_fields) {
WARN(!oh->sysconfig->sysc_fields, "offset struct for "
"sysconfig not provided!\n");
return -EINVAL;
}

wakeup_mask = (0x1 << oh->sysconfig->sysc_fields->enwkup_shift);

v = oh->_sysc_cache;
v |= SYSC_ENAWAKEUP_MASK;
v |= wakeup_mask;
_write_sysconfig(v, oh);

/* XXX test pwrdm_get_wken for this hwmod's subsystem */
Expand All @@ -272,14 +338,22 @@ static int _enable_wakeup(struct omap_hwmod *oh)
*/
static int _disable_wakeup(struct omap_hwmod *oh)
{
u32 v;
u32 v, wakeup_mask;

if (!oh->sysconfig ||
!(oh->sysconfig->sysc_flags & SYSC_HAS_ENAWAKEUP))
return -EINVAL;

if (!oh->sysconfig->sysc_fields) {
WARN(!oh->sysconfig->sysc_fields, "offset struct for "
"sysconfig not provided!\n");
return -EINVAL;
}

wakeup_mask = (0x1 << oh->sysconfig->sysc_fields->enwkup_shift);

v = oh->_sysc_cache;
v &= ~SYSC_ENAWAKEUP_MASK;
v &= ~wakeup_mask;
_write_sysconfig(v, oh);

/* XXX test pwrdm_get_wken for this hwmod's subsystem */
Expand Down
44 changes: 44 additions & 0 deletions trunk/arch/arm/mach-omap2/omap_hwmod_common_data.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
/*
* omap_hwmod common data structures
*
* Copyright (C) 2010 Texas Instruments, Inc.
* Thara Gopinath <thara@ti.com>
*
* 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.
*
* This data/structures are to be used while defining OMAP on-chip module
* data and their integration with other OMAP modules and Linux.
*/

#include <plat/omap_hwmod.h>

/**
* struct omap_hwmod_sysc_type1 - TYPE1 sysconfig scheme.
*
* To be used by hwmod structure to specify the sysconfig offsets
* if the device ip is compliant with the original PRCM protocol
* defined for OMAP2420.
*/
struct omap_hwmod_sysc_fields omap_hwmod_sysc_type1 = {
.midle_shift = SYSC_TYPE1_MIDLEMODE_SHIFT,
.clkact_shift = SYSC_TYPE1_CLOCKACTIVITY_SHIFT,
.sidle_shift = SYSC_TYPE1_SIDLEMODE_SHIFT,
.enwkup_shift = SYSC_TYPE1_ENAWAKEUP_SHIFT,
.srst_shift = SYSC_TYPE1_SOFTRESET_SHIFT,
.autoidle_shift = SYSC_TYPE1_AUTOIDLE_SHIFT,
};

/**
* struct omap_hwmod_sysc_type2 - TYPE2 sysconfig scheme.
*
* To be used by hwmod structure to specify the sysconfig offsets if the
* device ip is compliant with the new PRCM protocol defined for new
* OMAP4 IPs.
*/
struct omap_hwmod_sysc_fields omap_hwmod_sysc_type2 = {
.midle_shift = SYSC_TYPE2_MIDLEMODE_SHIFT,
.sidle_shift = SYSC_TYPE2_SIDLEMODE_SHIFT,
.srst_shift = SYSC_TYPE2_SOFTRESET_SHIFT,
};
73 changes: 58 additions & 15 deletions trunk/arch/arm/plat-omap/include/plat/omap_hwmod.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,25 +33,42 @@
#define __ARCH_ARM_PLAT_OMAP_INCLUDE_MACH_OMAP_HWMOD_H

#include <linux/kernel.h>
#include <linux/list.h>
#include <linux/ioport.h>

#include <plat/cpu.h>

struct omap_device;

/* OCP SYSCONFIG bit shifts/masks */
#define SYSC_MIDLEMODE_SHIFT 12
#define SYSC_MIDLEMODE_MASK (0x3 << SYSC_MIDLEMODE_SHIFT)
#define SYSC_CLOCKACTIVITY_SHIFT 8
#define SYSC_CLOCKACTIVITY_MASK (0x3 << SYSC_CLOCKACTIVITY_SHIFT)
#define SYSC_SIDLEMODE_SHIFT 3
#define SYSC_SIDLEMODE_MASK (0x3 << SYSC_SIDLEMODE_SHIFT)
#define SYSC_ENAWAKEUP_SHIFT 2
#define SYSC_ENAWAKEUP_MASK (1 << SYSC_ENAWAKEUP_SHIFT)
#define SYSC_SOFTRESET_SHIFT 1
#define SYSC_SOFTRESET_MASK (1 << SYSC_SOFTRESET_SHIFT)
#define SYSC_AUTOIDLE_SHIFT 0
#define SYSC_AUTOIDLE_MASK (1 << SYSC_AUTOIDLE_SHIFT)
extern struct omap_hwmod_sysc_fields omap_hwmod_sysc_type1;
extern struct omap_hwmod_sysc_fields omap_hwmod_sysc_type2;

/*
* 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
#define SYSC_TYPE1_MIDLEMODE_MASK (0x3 << SYSC_MIDLEMODE_SHIFT)
#define SYSC_TYPE1_CLOCKACTIVITY_SHIFT 8
#define SYSC_TYPE1_CLOCKACTIVITY_MASK (0x3 << SYSC_CLOCKACTIVITY_SHIFT)
#define SYSC_TYPE1_SIDLEMODE_SHIFT 3
#define SYSC_TYPE1_SIDLEMODE_MASK (0x3 << SYSC_SIDLEMODE_SHIFT)
#define SYSC_TYPE1_ENAWAKEUP_SHIFT 2
#define SYSC_TYPE1_ENAWAKEUP_MASK (1 << SYSC_ENAWAKEUP_SHIFT)
#define SYSC_TYPE1_SOFTRESET_SHIFT 1
#define SYSC_TYPE1_SOFTRESET_MASK (1 << SYSC_SOFTRESET_SHIFT)
#define SYSC_TYPE1_AUTOIDLE_SHIFT 0
#define SYSC_TYPE1_AUTOIDLE_MASK (1 << SYSC_AUTOIDLE_SHIFT)

/*
* 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)

/* OCP SYSSTATUS bit shifts/masks */
#define SYSS_RESETDONE_SHIFT 0
Expand All @@ -62,7 +79,6 @@ struct omap_device;
#define HWMOD_IDLEMODE_NO (1 << 1)
#define HWMOD_IDLEMODE_SMART (1 << 2)


/**
* struct omap_hwmod_irq_info - MPU IRQs used by the hwmod
* @name: name of the IRQ channel (module local name)
Expand Down Expand Up @@ -235,6 +251,24 @@ struct omap_hwmod_ocp_if {
#define CLOCKACT_TEST_ICLK 0x2
#define CLOCKACT_TEST_NONE 0x3

/**
* 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
* @autoidle_shift: Offset of the autoidle bit.
*/
struct omap_hwmod_sysc_fields {
u8 midle_shift;
u8 clkact_shift;
u8 sidle_shift;
u8 enwkup_shift;
u8 srst_shift;
u8 autoidle_shift;
};

/**
* struct omap_hwmod_sysconfig - hwmod OCP_SYSCONFIG/OCP_SYSSTATUS data
* @rev_offs: IP block revision register offset (from module base addr)
Expand All @@ -252,6 +286,14 @@ struct omap_hwmod_ocp_if {
* been associated with the clocks marked in @clockact. This field is
* only used if HWMOD_SET_DEFAULT_CLOCKACT is set (see below)
*
*
* @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
* defined for OMAP2420 or the new PRCM protocol for new OMAP4 IPs.
* If the device follows a differnt scheme for the sysconfig register ,
* then this field has to be populated with the correct offset structure.
*/
struct omap_hwmod_sysconfig {
u16 rev_offs;
Expand All @@ -260,6 +302,7 @@ struct omap_hwmod_sysconfig {
u8 idlemodes;
u8 sysc_flags;
u8 clockact;
struct omap_hwmod_sysc_fields *sysc_fields;
};

/**
Expand Down

0 comments on commit ad5bdd8

Please sign in to comment.