linux/arch/arm/mach-omap2/powerdomain44xx.c
<<
>>
Prefs
   1/*
   2 * OMAP4 powerdomain control
   3 *
   4 * Copyright (C) 2009-2010 Texas Instruments, Inc.
   5 * Copyright (C) 2007-2009 Nokia Corporation
   6 *
   7 * Derived from mach-omap2/powerdomain.c written by Paul Walmsley
   8 * Rajendra Nayak <rnayak@ti.com>
   9 *
  10 * This program is free software; you can redistribute it and/or modify
  11 * it under the terms of the GNU General Public License version 2 as
  12 * published by the Free Software Foundation.
  13 */
  14
  15#include <linux/io.h>
  16#include <linux/errno.h>
  17#include <linux/delay.h>
  18#include <linux/bug.h>
  19
  20#include "powerdomain.h"
  21#include <plat/prcm.h>
  22#include "prm2xxx_3xxx.h"
  23#include "prm44xx.h"
  24#include "prminst44xx.h"
  25#include "prm-regbits-44xx.h"
  26
  27static int omap4_pwrdm_set_next_pwrst(struct powerdomain *pwrdm, u8 pwrst)
  28{
  29        omap4_prminst_rmw_inst_reg_bits(OMAP_POWERSTATE_MASK,
  30                                        (pwrst << OMAP_POWERSTATE_SHIFT),
  31                                        pwrdm->prcm_partition,
  32                                        pwrdm->prcm_offs, OMAP4_PM_PWSTCTRL);
  33        return 0;
  34}
  35
  36static int omap4_pwrdm_read_next_pwrst(struct powerdomain *pwrdm)
  37{
  38        u32 v;
  39
  40        v = omap4_prminst_read_inst_reg(pwrdm->prcm_partition, pwrdm->prcm_offs,
  41                                        OMAP4_PM_PWSTCTRL);
  42        v &= OMAP_POWERSTATE_MASK;
  43        v >>= OMAP_POWERSTATE_SHIFT;
  44
  45        return v;
  46}
  47
  48static int omap4_pwrdm_read_pwrst(struct powerdomain *pwrdm)
  49{
  50        u32 v;
  51
  52        v = omap4_prminst_read_inst_reg(pwrdm->prcm_partition, pwrdm->prcm_offs,
  53                                        OMAP4_PM_PWSTST);
  54        v &= OMAP_POWERSTATEST_MASK;
  55        v >>= OMAP_POWERSTATEST_SHIFT;
  56
  57        return v;
  58}
  59
  60static int omap4_pwrdm_read_prev_pwrst(struct powerdomain *pwrdm)
  61{
  62        u32 v;
  63
  64        v = omap4_prminst_read_inst_reg(pwrdm->prcm_partition, pwrdm->prcm_offs,
  65                                        OMAP4_PM_PWSTST);
  66        v &= OMAP4430_LASTPOWERSTATEENTERED_MASK;
  67        v >>= OMAP4430_LASTPOWERSTATEENTERED_SHIFT;
  68
  69        return v;
  70}
  71
  72static int omap4_pwrdm_set_lowpwrstchange(struct powerdomain *pwrdm)
  73{
  74        omap4_prminst_rmw_inst_reg_bits(OMAP4430_LOWPOWERSTATECHANGE_MASK,
  75                                        (1 << OMAP4430_LOWPOWERSTATECHANGE_SHIFT),
  76                                        pwrdm->prcm_partition,
  77                                        pwrdm->prcm_offs, OMAP4_PM_PWSTCTRL);
  78        return 0;
  79}
  80
  81static int omap4_pwrdm_clear_all_prev_pwrst(struct powerdomain *pwrdm)
  82{
  83        omap4_prminst_rmw_inst_reg_bits(OMAP4430_LASTPOWERSTATEENTERED_MASK,
  84                                        OMAP4430_LASTPOWERSTATEENTERED_MASK,
  85                                        pwrdm->prcm_partition,
  86                                        pwrdm->prcm_offs, OMAP4_PM_PWSTST);
  87        return 0;
  88}
  89
  90static int omap4_pwrdm_set_logic_retst(struct powerdomain *pwrdm, u8 pwrst)
  91{
  92        u32 v;
  93
  94        v = pwrst << __ffs(OMAP4430_LOGICRETSTATE_MASK);
  95        omap4_prminst_rmw_inst_reg_bits(OMAP4430_LOGICRETSTATE_MASK, v,
  96                                        pwrdm->prcm_partition, pwrdm->prcm_offs,
  97                                        OMAP4_PM_PWSTCTRL);
  98
  99        return 0;
 100}
 101
 102static int omap4_pwrdm_set_mem_onst(struct powerdomain *pwrdm, u8 bank,
 103                                    u8 pwrst)
 104{
 105        u32 m;
 106
 107        m = omap2_pwrdm_get_mem_bank_onstate_mask(bank);
 108
 109        omap4_prminst_rmw_inst_reg_bits(m, (pwrst << __ffs(m)),
 110                                        pwrdm->prcm_partition, pwrdm->prcm_offs,
 111                                        OMAP4_PM_PWSTCTRL);
 112
 113        return 0;
 114}
 115
 116static int omap4_pwrdm_set_mem_retst(struct powerdomain *pwrdm, u8 bank,
 117                                     u8 pwrst)
 118{
 119        u32 m;
 120
 121        m = omap2_pwrdm_get_mem_bank_retst_mask(bank);
 122
 123        omap4_prminst_rmw_inst_reg_bits(m, (pwrst << __ffs(m)),
 124                                        pwrdm->prcm_partition, pwrdm->prcm_offs,
 125                                        OMAP4_PM_PWSTCTRL);
 126
 127        return 0;
 128}
 129
 130static int omap4_pwrdm_read_logic_pwrst(struct powerdomain *pwrdm)
 131{
 132        u32 v;
 133
 134        v = omap4_prminst_read_inst_reg(pwrdm->prcm_partition, pwrdm->prcm_offs,
 135                                        OMAP4_PM_PWSTST);
 136        v &= OMAP4430_LOGICSTATEST_MASK;
 137        v >>= OMAP4430_LOGICSTATEST_SHIFT;
 138
 139        return v;
 140}
 141
 142static int omap4_pwrdm_read_logic_retst(struct powerdomain *pwrdm)
 143{
 144        u32 v;
 145
 146        v = omap4_prminst_read_inst_reg(pwrdm->prcm_partition, pwrdm->prcm_offs,
 147                                        OMAP4_PM_PWSTCTRL);
 148        v &= OMAP4430_LOGICRETSTATE_MASK;
 149        v >>= OMAP4430_LOGICRETSTATE_SHIFT;
 150
 151        return v;
 152}
 153
 154static int omap4_pwrdm_read_mem_pwrst(struct powerdomain *pwrdm, u8 bank)
 155{
 156        u32 m, v;
 157
 158        m = omap2_pwrdm_get_mem_bank_stst_mask(bank);
 159
 160        v = omap4_prminst_read_inst_reg(pwrdm->prcm_partition, pwrdm->prcm_offs,
 161                                        OMAP4_PM_PWSTST);
 162        v &= m;
 163        v >>= __ffs(m);
 164
 165        return v;
 166}
 167
 168static int omap4_pwrdm_read_mem_retst(struct powerdomain *pwrdm, u8 bank)
 169{
 170        u32 m, v;
 171
 172        m = omap2_pwrdm_get_mem_bank_retst_mask(bank);
 173
 174        v = omap4_prminst_read_inst_reg(pwrdm->prcm_partition, pwrdm->prcm_offs,
 175                                        OMAP4_PM_PWSTCTRL);
 176        v &= m;
 177        v >>= __ffs(m);
 178
 179        return v;
 180}
 181
 182static int omap4_pwrdm_wait_transition(struct powerdomain *pwrdm)
 183{
 184        u32 c = 0;
 185
 186        /*
 187         * REVISIT: pwrdm_wait_transition() may be better implemented
 188         * via a callback and a periodic timer check -- how long do we expect
 189         * powerdomain transitions to take?
 190         */
 191
 192        /* XXX Is this udelay() value meaningful? */
 193        while ((omap4_prminst_read_inst_reg(pwrdm->prcm_partition,
 194                                            pwrdm->prcm_offs,
 195                                            OMAP4_PM_PWSTST) &
 196                OMAP_INTRANSITION_MASK) &&
 197               (c++ < PWRDM_TRANSITION_BAILOUT))
 198                udelay(1);
 199
 200        if (c > PWRDM_TRANSITION_BAILOUT) {
 201                printk(KERN_ERR "powerdomain: waited too long for "
 202                       "powerdomain %s to complete transition\n", pwrdm->name);
 203                return -EAGAIN;
 204        }
 205
 206        pr_debug("powerdomain: completed transition in %d loops\n", c);
 207
 208        return 0;
 209}
 210
 211struct pwrdm_ops omap4_pwrdm_operations = {
 212        .pwrdm_set_next_pwrst   = omap4_pwrdm_set_next_pwrst,
 213        .pwrdm_read_next_pwrst  = omap4_pwrdm_read_next_pwrst,
 214        .pwrdm_read_pwrst       = omap4_pwrdm_read_pwrst,
 215        .pwrdm_read_prev_pwrst  = omap4_pwrdm_read_prev_pwrst,
 216        .pwrdm_set_lowpwrstchange       = omap4_pwrdm_set_lowpwrstchange,
 217        .pwrdm_clear_all_prev_pwrst     = omap4_pwrdm_clear_all_prev_pwrst,
 218        .pwrdm_set_logic_retst  = omap4_pwrdm_set_logic_retst,
 219        .pwrdm_read_logic_pwrst = omap4_pwrdm_read_logic_pwrst,
 220        .pwrdm_read_logic_retst = omap4_pwrdm_read_logic_retst,
 221        .pwrdm_read_mem_pwrst   = omap4_pwrdm_read_mem_pwrst,
 222        .pwrdm_read_mem_retst   = omap4_pwrdm_read_mem_retst,
 223        .pwrdm_set_mem_onst     = omap4_pwrdm_set_mem_onst,
 224        .pwrdm_set_mem_retst    = omap4_pwrdm_set_mem_retst,
 225        .pwrdm_wait_transition  = omap4_pwrdm_wait_transition,
 226};
 227