Commit e6d3a8b0bdcd8f323488a52927682190aee5488e

Authored by Rajendra Nayak
Committed by Paul Walmsley
1 parent 63a293e000

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>

Showing 5 changed files with 146 additions and 8 deletions Side-by-side Diff

arch/arm/mach-omap2/omap_hwmod.c
... ... @@ -187,6 +187,8 @@
187 187 int (*is_hardreset_asserted)(struct omap_hwmod *oh,
188 188 struct omap_hwmod_rst_info *ohri);
189 189 int (*init_clkdm)(struct omap_hwmod *oh);
  190 + void (*update_context_lost)(struct omap_hwmod *oh);
  191 + int (*get_context_lost)(struct omap_hwmod *oh);
190 192 };
191 193  
192 194 /* soc_ops: adapts the omap_hwmod code to the currently-booted SoC */
... ... @@ -1983,6 +1985,42 @@
1983 1985 }
1984 1986  
1985 1987 /**
  1988 + * _omap4_update_context_lost - increment hwmod context loss counter if
  1989 + * hwmod context was lost, and clear hardware context loss reg
  1990 + * @oh: hwmod to check for context loss
  1991 + *
  1992 + * If the PRCM indicates that the hwmod @oh lost context, increment
  1993 + * our in-memory context loss counter, and clear the RM_*_CONTEXT
  1994 + * bits. No return value.
  1995 + */
  1996 +static void _omap4_update_context_lost(struct omap_hwmod *oh)
  1997 +{
  1998 + if (oh->prcm.omap4.flags & HWMOD_OMAP4_NO_CONTEXT_LOSS_BIT)
  1999 + return;
  2000 +
  2001 + if (!prm_was_any_context_lost_old(oh->clkdm->pwrdm.ptr->prcm_partition,
  2002 + oh->clkdm->pwrdm.ptr->prcm_offs,
  2003 + oh->prcm.omap4.context_offs))
  2004 + return;
  2005 +
  2006 + oh->prcm.omap4.context_lost_counter++;
  2007 + prm_clear_context_loss_flags_old(oh->clkdm->pwrdm.ptr->prcm_partition,
  2008 + oh->clkdm->pwrdm.ptr->prcm_offs,
  2009 + oh->prcm.omap4.context_offs);
  2010 +}
  2011 +
  2012 +/**
  2013 + * _omap4_get_context_lost - get context loss counter for a hwmod
  2014 + * @oh: hwmod to get context loss counter for
  2015 + *
  2016 + * Returns the in-memory context loss counter for a hwmod.
  2017 + */
  2018 +static int _omap4_get_context_lost(struct omap_hwmod *oh)
  2019 +{
  2020 + return oh->prcm.omap4.context_lost_counter;
  2021 +}
  2022 +
  2023 +/**
1986 2024 * _enable - enable an omap_hwmod
1987 2025 * @oh: struct omap_hwmod *
1988 2026 *
... ... @@ -2065,6 +2103,9 @@
2065 2103 if (soc_ops.enable_module)
2066 2104 soc_ops.enable_module(oh);
2067 2105  
  2106 + if (soc_ops.update_context_lost)
  2107 + soc_ops.update_context_lost(oh);
  2108 +
2068 2109 r = (soc_ops.wait_target_ready) ? soc_ops.wait_target_ready(oh) :
2069 2110 -EINVAL;
2070 2111 if (!r) {
2071 2112  
2072 2113  
... ... @@ -3907,17 +3948,21 @@
3907 3948 * omap_hwmod_get_context_loss_count - get lost context count
3908 3949 * @oh: struct omap_hwmod *
3909 3950 *
3910   - * Query the powerdomain of of @oh to get the context loss
3911   - * count for this device.
  3951 + * Returns the context loss count of associated @oh
  3952 + * upon success, or zero if no context loss data is available.
3912 3953 *
3913   - * Returns the context loss count of the powerdomain assocated with @oh
3914   - * upon success, or zero if no powerdomain exists for @oh.
  3954 + * On OMAP4, this queries the per-hwmod context loss register,
  3955 + * assuming one exists. If not, or on OMAP2/3, this queries the
  3956 + * enclosing powerdomain context loss count.
3915 3957 */
3916 3958 int omap_hwmod_get_context_loss_count(struct omap_hwmod *oh)
3917 3959 {
3918 3960 struct powerdomain *pwrdm;
3919 3961 int ret = 0;
3920 3962  
  3963 + if (soc_ops.get_context_lost)
  3964 + return soc_ops.get_context_lost(oh);
  3965 +
3921 3966 pwrdm = omap_hwmod_get_pwrdm(oh);
3922 3967 if (pwrdm)
3923 3968 ret = pwrdm_get_context_loss_count(pwrdm);
... ... @@ -4032,6 +4077,8 @@
4032 4077 soc_ops.deassert_hardreset = _omap4_deassert_hardreset;
4033 4078 soc_ops.is_hardreset_asserted = _omap4_is_hardreset_asserted;
4034 4079 soc_ops.init_clkdm = _init_clkdm;
  4080 + soc_ops.update_context_lost = _omap4_update_context_lost;
  4081 + soc_ops.get_context_lost = _omap4_get_context_lost;
4035 4082 } else if (soc_is_am33xx()) {
4036 4083 soc_ops.enable_module = _am33xx_enable_module;
4037 4084 soc_ops.disable_module = _am33xx_disable_module;
arch/arm/mach-omap2/omap_hwmod.h
... ... @@ -2,7 +2,7 @@
2 2 * omap_hwmod macros, structures
3 3 *
4 4 * Copyright (C) 2009-2011 Nokia Corporation
5   - * Copyright (C) 2012 Texas Instruments, Inc.
  5 + * Copyright (C) 2011-2012 Texas Instruments, Inc.
6 6 * Paul Walmsley
7 7 *
8 8 * Created in collaboration with (alphabetical order): Benoรฎt Cousson,
9 9  
... ... @@ -394,12 +394,15 @@
394 394  
395 395 /**
396 396 * struct omap_hwmod_omap4_prcm - OMAP4-specific PRCM data
397   - * @clkctrl_reg: PRCM address of the clock control register
398   - * @rstctrl_reg: address of the XXX_RSTCTRL register located in the PRM
  397 + * @clkctrl_offs: offset of the PRCM clock control register
  398 + * @rstctrl_offs: offset of the XXX_RSTCTRL register located in the PRM
  399 + * @context_offs: offset of the RM_*_CONTEXT register
399 400 * @lostcontext_mask: bitmask for selecting bits from RM_*_CONTEXT register
400 401 * @rstst_reg: (AM33XX only) address of the XXX_RSTST register in the PRM
401 402 * @submodule_wkdep_bit: bit shift of the WKDEP range
402 403 * @flags: PRCM register capabilities for this IP block
  404 + * @modulemode: allowable modulemodes
  405 + * @context_lost_counter: Count of module level context lost
403 406 *
404 407 * If @lostcontext_mask is not defined, context loss check code uses
405 408 * whole register without masking. @lostcontext_mask should only be
... ... @@ -415,6 +418,7 @@
415 418 u8 submodule_wkdep_bit;
416 419 u8 modulemode;
417 420 u8 flags;
  421 + int context_lost_counter;
418 422 };
419 423  
420 424  
arch/arm/mach-omap2/prm.h
... ... @@ -114,16 +114,25 @@
114 114  
115 115 /**
116 116 * struct prm_ll_data - fn ptrs to per-SoC PRM function implementations
117   - * @read_reset_sources: ptr to the Soc PRM-specific get_reset_source impl
  117 + * @read_reset_sources: ptr to the SoC PRM-specific get_reset_source impl
  118 + * @was_any_context_lost_old: ptr to the SoC PRM context loss test fn
  119 + * @clear_context_loss_flags_old: ptr to the SoC PRM context loss flag clear fn
  120 + *
  121 + * XXX @was_any_context_lost_old and @clear_context_loss_flags_old are
  122 + * deprecated.
118 123 */
119 124 struct prm_ll_data {
120 125 u32 (*read_reset_sources)(void);
  126 + bool (*was_any_context_lost_old)(u8 part, s16 inst, u16 idx);
  127 + void (*clear_context_loss_flags_old)(u8 part, s16 inst, u16 idx);
121 128 };
122 129  
123 130 extern int prm_register(struct prm_ll_data *pld);
124 131 extern int prm_unregister(struct prm_ll_data *pld);
125 132  
126 133 extern u32 prm_read_reset_sources(void);
  134 +extern bool prm_was_any_context_lost_old(u8 part, s16 inst, u16 idx);
  135 +extern void prm_clear_context_loss_flags_old(u8 part, s16 inst, u16 idx);
127 136  
128 137 #endif
129 138  
arch/arm/mach-omap2/prm44xx.c
... ... @@ -346,6 +346,37 @@
346 346 return r;
347 347 }
348 348  
  349 +/**
  350 + * omap44xx_prm_was_any_context_lost_old - was module hardware context lost?
  351 + * @part: PRM partition ID (e.g., OMAP4430_PRM_PARTITION)
  352 + * @inst: PRM instance offset (e.g., OMAP4430_PRM_MPU_INST)
  353 + * @idx: CONTEXT register offset
  354 + *
  355 + * Return 1 if any bits were set in the *_CONTEXT_* register
  356 + * identified by (@part, @inst, @idx), which means that some context
  357 + * was lost for that module; otherwise, return 0.
  358 + */
  359 +static bool omap44xx_prm_was_any_context_lost_old(u8 part, s16 inst, u16 idx)
  360 +{
  361 + return (omap4_prminst_read_inst_reg(part, inst, idx)) ? 1 : 0;
  362 +}
  363 +
  364 +/**
  365 + * omap44xx_prm_clear_context_lost_flags_old - clear context loss flags
  366 + * @part: PRM partition ID (e.g., OMAP4430_PRM_PARTITION)
  367 + * @inst: PRM instance offset (e.g., OMAP4430_PRM_MPU_INST)
  368 + * @idx: CONTEXT register offset
  369 + *
  370 + * Clear hardware context loss bits for the module identified by
  371 + * (@part, @inst, @idx). No return value. XXX Writes to reserved bits;
  372 + * is there a way to avoid this?
  373 + */
  374 +static void omap44xx_prm_clear_context_loss_flags_old(u8 part, s16 inst,
  375 + u16 idx)
  376 +{
  377 + omap4_prminst_write_inst_reg(0xffffffff, part, inst, idx);
  378 +}
  379 +
349 380 /* Powerdomain low-level functions */
350 381  
351 382 static int omap4_pwrdm_set_next_pwrst(struct powerdomain *pwrdm, u8 pwrst)
... ... @@ -613,6 +644,8 @@
613 644 */
614 645 static struct prm_ll_data omap44xx_prm_ll_data = {
615 646 .read_reset_sources = &omap44xx_prm_read_reset_sources,
  647 + .was_any_context_lost_old = &omap44xx_prm_was_any_context_lost_old,
  648 + .clear_context_loss_flags_old = &omap44xx_prm_clear_context_loss_flags_old,
616 649 };
617 650  
618 651 int __init omap44xx_prm_init(void)
arch/arm/mach-omap2/prm_common.c
... ... @@ -367,6 +367,51 @@
367 367 }
368 368  
369 369 /**
  370 + * prm_was_any_context_lost_old - was device context lost? (old API)
  371 + * @part: PRM partition ID (e.g., OMAP4430_PRM_PARTITION)
  372 + * @inst: PRM instance offset (e.g., OMAP4430_PRM_MPU_INST)
  373 + * @idx: CONTEXT register offset
  374 + *
  375 + * Return 1 if any bits were set in the *_CONTEXT_* register
  376 + * identified by (@part, @inst, @idx), which means that some context
  377 + * was lost for that module; otherwise, return 0. XXX Deprecated;
  378 + * callers need to use a less-SoC-dependent way to identify hardware
  379 + * IP blocks.
  380 + */
  381 +bool prm_was_any_context_lost_old(u8 part, s16 inst, u16 idx)
  382 +{
  383 + bool ret = true;
  384 +
  385 + if (prm_ll_data->was_any_context_lost_old)
  386 + ret = prm_ll_data->was_any_context_lost_old(part, inst, idx);
  387 + else
  388 + WARN_ONCE(1, "prm: %s: no mapping function defined\n",
  389 + __func__);
  390 +
  391 + return ret;
  392 +}
  393 +
  394 +/**
  395 + * prm_clear_context_lost_flags_old - clear context loss flags (old API)
  396 + * @part: PRM partition ID (e.g., OMAP4430_PRM_PARTITION)
  397 + * @inst: PRM instance offset (e.g., OMAP4430_PRM_MPU_INST)
  398 + * @idx: CONTEXT register offset
  399 + *
  400 + * Clear hardware context loss bits for the module identified by
  401 + * (@part, @inst, @idx). No return value. XXX Deprecated; callers
  402 + * need to use a less-SoC-dependent way to identify hardware IP
  403 + * blocks.
  404 + */
  405 +void prm_clear_context_loss_flags_old(u8 part, s16 inst, u16 idx)
  406 +{
  407 + if (prm_ll_data->clear_context_loss_flags_old)
  408 + prm_ll_data->clear_context_loss_flags_old(part, inst, idx);
  409 + else
  410 + WARN_ONCE(1, "prm: %s: no mapping function defined\n",
  411 + __func__);
  412 +}
  413 +
  414 +/**
370 415 * prm_register - register per-SoC low-level data with the PRM
371 416 * @pld: low-level per-SoC OMAP PRM data & function pointers to register
372 417 *