Commit 4bdaa581 authored by Grzegorz Daniluk's avatar Grzegorz Daniluk

softpll: reset ext FPGA pll when 10mhz lost

Needed mainly for SPEC, where Spartan6 PLL does not report unlock when clk_in
(10MHz) is unplugged. In addition to that, datasheet says that PLL should be
reset after losing clk_in.
parent 5ab76f6e
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
* File : softpll_regs.h * File : softpll_regs.h
* Author : auto-generated by wbgen2 from spll_wb_slave.wb * Author : auto-generated by wbgen2 from spll_wb_slave.wb
* Created : Mon Jul 21 13:49:11 2014 * Created : Thu Dec 3 15:09:41 2015
* Standard : ANSI C * Standard : ANSI C
THIS FILE WAS GENERATED BY wbgen2 FROM SOURCE FILE spll_wb_slave.wb THIS FILE WAS GENERATED BY wbgen2 FROM SOURCE FILE spll_wb_slave.wb
...@@ -63,7 +63,13 @@ ...@@ -63,7 +63,13 @@
#define SPLL_ECCR_EXT_SUPPORTED WBGEN2_GEN_MASK(1, 1) #define SPLL_ECCR_EXT_SUPPORTED WBGEN2_GEN_MASK(1, 1)
/* definitions for field: External Clock Reference Present in reg: External Clock Control Register */ /* definitions for field: External Clock Reference Present in reg: External Clock Control Register */
#define SPLL_ECCR_EXT_REF_PRESENT WBGEN2_GEN_MASK(2, 1) #define SPLL_ECCR_EXT_REF_LOCKED WBGEN2_GEN_MASK(2, 1)
/* definitions for field: EXT_REF_STOPPED in reg: External Clock Control Register */
#define SPLL_ECCR_EXT_REF_STOPPED WBGEN2_GEN_MASK(3, 1)
/* definitions for field: EXT_PLL_RST in reg: External Clock Control Register */
#define SPLL_ECCR_EXT_REF_PLLRST WBGEN2_GEN_MASK(31, 1)
/* definitions for register: Aligner Control Register */ /* definitions for register: Aligner Control Register */
......
...@@ -26,6 +26,8 @@ ...@@ -26,6 +26,8 @@
#define ALIGN_STATE_COMPENSATE_DELAY 5 #define ALIGN_STATE_COMPENSATE_DELAY 5
#define ALIGN_STATE_LOCKED 6 #define ALIGN_STATE_LOCKED 6
#define ALIGN_STATE_START_MAIN 8 #define ALIGN_STATE_START_MAIN 8
#define ALIGN_STATE_WAIT_CLKIN 9
#define ALIGN_STATE_WAIT_PLOCK 10
#define ALIGN_SAMPLE_PERIOD 100000 #define ALIGN_SAMPLE_PERIOD 100000
#define ALIGN_TARGET 0 #define ALIGN_TARGET 0
...@@ -54,7 +56,7 @@ void external_start(struct spll_external_state *s) ...@@ -54,7 +56,7 @@ void external_start(struct spll_external_state *s)
SPLL->ECCR = SPLL_ECCR_EXT_EN; SPLL->ECCR = SPLL_ECCR_EXT_EN;
s->align_state = ALIGN_STATE_START; s->align_state = ALIGN_STATE_WAIT_CLKIN;
s->enabled = 1; s->enabled = 1;
spll_debug (DBG_EVENT | DBG_EXT, DBG_EVT_START, 1); spll_debug (DBG_EVENT | DBG_EXT, DBG_EVT_START, 1);
} }
...@@ -62,11 +64,14 @@ void external_start(struct spll_external_state *s) ...@@ -62,11 +64,14 @@ void external_start(struct spll_external_state *s)
int external_locked(volatile struct spll_external_state *s) int external_locked(volatile struct spll_external_state *s)
{ {
if (!s->helper->ld.locked || !s->main->ld.locked || if (!s->helper->ld.locked || !s->main->ld.locked ||
!(SPLL->ECCR & SPLL_ECCR_EXT_REF_PRESENT)) !(SPLL->ECCR & SPLL_ECCR_EXT_REF_LOCKED) || // ext PLL became unlocked
(SPLL->ECCR & SPLL_ECCR_EXT_REF_STOPPED)) // 10MHz unplugged (only SPEC)
return 0; return 0;
switch(s->align_state) { switch(s->align_state) {
case ALIGN_STATE_EXT_OFF: case ALIGN_STATE_EXT_OFF:
case ALIGN_STATE_WAIT_CLKIN:
case ALIGN_STATE_WAIT_PLOCK:
case ALIGN_STATE_START: case ALIGN_STATE_START:
case ALIGN_STATE_START_MAIN: case ALIGN_STATE_START_MAIN:
case ALIGN_STATE_INIT_CSYNC: case ALIGN_STATE_INIT_CSYNC:
...@@ -100,6 +105,21 @@ void external_align_fsm(volatile struct spll_external_state *s) ...@@ -100,6 +105,21 @@ void external_align_fsm(volatile struct spll_external_state *s)
case ALIGN_STATE_EXT_OFF: case ALIGN_STATE_EXT_OFF:
break; break;
case ALIGN_STATE_WAIT_CLKIN:
if( !(SPLL->ECCR & SPLL_ECCR_EXT_REF_STOPPED) ) {
SPLL->ECCR |= SPLL_ECCR_EXT_REF_PLLRST;
s->align_state = ALIGN_STATE_WAIT_PLOCK;
}
break;
case ALIGN_STATE_WAIT_PLOCK:
SPLL->ECCR &= (~SPLL_ECCR_EXT_REF_PLLRST);
if( SPLL->ECCR & SPLL_ECCR_EXT_REF_STOPPED )
s->align_state = ALIGN_STATE_WAIT_CLKIN;
else if( SPLL->ECCR & SPLL_ECCR_EXT_REF_LOCKED )
s->align_state = ALIGN_STATE_START;
break;
case ALIGN_STATE_START: case ALIGN_STATE_START:
if(s->helper->ld.locked) { if(s->helper->ld.locked) {
disable_irq(); disable_irq();
...@@ -175,7 +195,7 @@ void external_align_fsm(volatile struct spll_external_state *s) ...@@ -175,7 +195,7 @@ void external_align_fsm(volatile struct spll_external_state *s)
case ALIGN_STATE_LOCKED: case ALIGN_STATE_LOCKED:
if(!external_locked(s)) { if(!external_locked(s)) {
s->align_state = ALIGN_STATE_START; s->align_state = ALIGN_STATE_WAIT_CLKIN;
} }
break; break;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment