|
@@ -296,18 +296,23 @@ static uint64_t imx_gpt_read(void *opaque, hwaddr offset, unsigned size)
|
|
return reg_value;
|
|
return reg_value;
|
|
}
|
|
}
|
|
|
|
|
|
-static void imx_gpt_reset(DeviceState *dev)
|
|
|
|
-{
|
|
|
|
- IMXGPTState *s = IMX_GPT(dev);
|
|
|
|
|
|
|
|
|
|
+static void imx_gpt_reset_common(IMXGPTState *s, bool is_soft_reset)
|
|
|
|
+{
|
|
/* stop timer */
|
|
/* stop timer */
|
|
ptimer_stop(s->timer);
|
|
ptimer_stop(s->timer);
|
|
|
|
|
|
- /*
|
|
|
|
- * Soft reset doesn't touch some bits; hard reset clears them
|
|
|
|
|
|
+ /* Soft reset and hard reset differ only in their handling of the CR
|
|
|
|
+ * register -- soft reset preserves the values of some bits there.
|
|
*/
|
|
*/
|
|
- s->cr &= ~(GPT_CR_EN|GPT_CR_ENMOD|GPT_CR_STOPEN|GPT_CR_DOZEN|
|
|
|
|
- GPT_CR_WAITEN|GPT_CR_DBGEN);
|
|
|
|
|
|
+ if (is_soft_reset) {
|
|
|
|
+ /* Clear all CR bits except those that are preserved by soft reset. */
|
|
|
|
+ s->cr &= GPT_CR_EN | GPT_CR_ENMOD | GPT_CR_STOPEN | GPT_CR_DOZEN |
|
|
|
|
+ GPT_CR_WAITEN | GPT_CR_DBGEN |
|
|
|
|
+ (GPT_CR_CLKSRC_MASK << GPT_CR_CLKSRC_SHIFT);
|
|
|
|
+ } else {
|
|
|
|
+ s->cr = 0;
|
|
|
|
+ }
|
|
s->sr = 0;
|
|
s->sr = 0;
|
|
s->pr = 0;
|
|
s->pr = 0;
|
|
s->ir = 0;
|
|
s->ir = 0;
|
|
@@ -333,6 +338,18 @@ static void imx_gpt_reset(DeviceState *dev)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+static void imx_gpt_soft_reset(DeviceState *dev)
|
|
|
|
+{
|
|
|
|
+ IMXGPTState *s = IMX_GPT(dev);
|
|
|
|
+ imx_gpt_reset_common(s, true);
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+static void imx_gpt_reset(DeviceState *dev)
|
|
|
|
+{
|
|
|
|
+ IMXGPTState *s = IMX_GPT(dev);
|
|
|
|
+ imx_gpt_reset_common(s, false);
|
|
|
|
+}
|
|
|
|
+
|
|
static void imx_gpt_write(void *opaque, hwaddr offset, uint64_t value,
|
|
static void imx_gpt_write(void *opaque, hwaddr offset, uint64_t value,
|
|
unsigned size)
|
|
unsigned size)
|
|
{
|
|
{
|
|
@@ -348,7 +365,7 @@ static void imx_gpt_write(void *opaque, hwaddr offset, uint64_t value,
|
|
s->cr = value & ~0x7c14;
|
|
s->cr = value & ~0x7c14;
|
|
if (s->cr & GPT_CR_SWR) { /* force reset */
|
|
if (s->cr & GPT_CR_SWR) { /* force reset */
|
|
/* handle the reset */
|
|
/* handle the reset */
|
|
- imx_gpt_reset(DEVICE(s));
|
|
|
|
|
|
+ imx_gpt_soft_reset(DEVICE(s));
|
|
} else {
|
|
} else {
|
|
/* set our freq, as the source might have changed */
|
|
/* set our freq, as the source might have changed */
|
|
imx_gpt_set_freq(s);
|
|
imx_gpt_set_freq(s);
|