/* * Table that determines the low power modes outputs, with actual settings * used in parentheses for don't-care values. Except for the float output, * the configured driven and pulled levels match, so if there is a need for * non-LPM pulled output, the same configuration could probably be used. * * Output value sleep_oe_n sleep_data pullup_en pulldown_en pull_sel * (bit 7) (bit 8) (bit 14) (bit 13) (bit 15) * * Input 0 X(0) X(0) X(0) 0 * Drive 0 0 0 0 X(1) 0 * Drive 1 0 1 X(1) 0 0 * Pull hi (1) 1 X(1) 1 0 0 * Pull lo (0) 1 X(0) 0 1 0 * Z (float) 1 X(0) 0 0 0
*/ #define MFPR_LPM_INPUT (0) #define MFPR_LPM_DRIVE_LOW (MFPR_SLEEP_DATA(0) | MFPR_PULLDOWN_EN) #define MFPR_LPM_DRIVE_HIGH (MFPR_SLEEP_DATA(1) | MFPR_PULLUP_EN) #define MFPR_LPM_PULL_LOW (MFPR_LPM_DRIVE_LOW | MFPR_SLEEP_OE_N) #define MFPR_LPM_PULL_HIGH (MFPR_LPM_DRIVE_HIGH | MFPR_SLEEP_OE_N) #define MFPR_LPM_FLOAT (MFPR_SLEEP_OE_N) #define MFPR_LPM_MASK (0xe080)
/* * The pullup and pulldown state of the MFP pin at run mode is by default * determined by the selected alternate function. In case that some buggy * devices need to override this default behavior, the definitions below * indicates the setting of corresponding MFPR bits * * Definition pull_sel pullup_en pulldown_en * MFPR_PULL_NONE 0 0 0 * MFPR_PULL_LOW 1 0 1 * MFPR_PULL_HIGH 1 1 0 * MFPR_PULL_BOTH 1 1 1 * MFPR_PULL_FLOAT 1 0 0
*/ #define MFPR_PULL_NONE (0) #define MFPR_PULL_LOW (MFPR_PULL_SEL | MFPR_PULLDOWN_EN) #define MFPR_PULL_BOTH (MFPR_PULL_LOW | MFPR_PULLUP_EN) #define MFPR_PULL_HIGH (MFPR_PULL_SEL | MFPR_PULLUP_EN) #define MFPR_PULL_FLOAT (MFPR_PULL_SEL)
/* mfp_spin_lock is used to ensure that MFP register configuration * (most likely a read-modify-write operation) is atomic, and that * mfp_table[] is consistent
*/ static DEFINE_SPINLOCK(mfp_spin_lock);
staticvoid __iomem *mfpr_mmio_base;
struct mfp_pin { unsignedlong config; /* -1 for not configured */ unsignedlong mfpr_off; /* MFPRxx Register offset */ unsignedlong mfpr_run; /* Run-Mode Register Value */ unsignedlong mfpr_lpm; /* Low Power Mode Register Value */
};
/* * perform a read-back of any valid MFPR register to make sure the * previous writings are finished
*/ staticunsignedlong mfpr_off_readback; #define mfpr_sync() (void)__raw_readl(mfpr_mmio_base + mfpr_off_readback)
staticinlinevoid __mfp_config_run(struct mfp_pin *p)
{ if (mfp_configured(p))
mfpr_writel(p->mfpr_off, p->mfpr_run);
}
staticinlinevoid __mfp_config_lpm(struct mfp_pin *p)
{ if (mfp_configured(p)) { unsignedlong mfpr_clr = (p->mfpr_run & ~MFPR_EDGE_BOTH) | MFPR_EDGE_CLEAR; if (mfpr_clr != p->mfpr_run)
mfpr_writel(p->mfpr_off, mfpr_clr); if (p->mfpr_lpm != mfpr_clr)
mfpr_writel(p->mfpr_off, p->mfpr_lpm);
}
}
void mfp_config(unsignedlong *mfp_cfgs, int num)
{ unsignedlong flags; int i;
spin_lock_irqsave(&mfp_spin_lock, flags);
for (i = 0; i < num; i++, mfp_cfgs++) { unsignedlong tmp, c = *mfp_cfgs; struct mfp_pin *p; int pin, af, drv, lpm, edge, pull;
pin = MFP_PIN(c);
BUG_ON(pin >= MFP_PIN_MAX);
p = &mfp_table[pin];
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.