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 @@
* File : softpll_regs.h
* 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
THIS FILE WAS GENERATED BY wbgen2 FROM SOURCE FILE spll_wb_slave.wb
......@@ -63,7 +63,13 @@
#define SPLL_ECCR_EXT_SUPPORTED WBGEN2_GEN_MASK(1, 1)
/* 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 */
......
......@@ -26,6 +26,8 @@
#define ALIGN_STATE_COMPENSATE_DELAY 5
#define ALIGN_STATE_LOCKED 6
#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_TARGET 0
......@@ -54,7 +56,7 @@ void external_start(struct spll_external_state *s)
SPLL->ECCR = SPLL_ECCR_EXT_EN;
s->align_state = ALIGN_STATE_START;
s->align_state = ALIGN_STATE_WAIT_CLKIN;
s->enabled = 1;
spll_debug (DBG_EVENT | DBG_EXT, DBG_EVT_START, 1);
}
......@@ -62,11 +64,14 @@ void external_start(struct spll_external_state *s)
int external_locked(volatile struct spll_external_state *s)
{
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;
switch(s->align_state) {
case ALIGN_STATE_EXT_OFF:
case ALIGN_STATE_WAIT_CLKIN:
case ALIGN_STATE_WAIT_PLOCK:
case ALIGN_STATE_START:
case ALIGN_STATE_START_MAIN:
case ALIGN_STATE_INIT_CSYNC:
......@@ -100,6 +105,21 @@ void external_align_fsm(volatile struct spll_external_state *s)
case ALIGN_STATE_EXT_OFF:
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:
if(s->helper->ld.locked) {
disable_irq();
......@@ -175,7 +195,7 @@ void external_align_fsm(volatile struct spll_external_state *s)
case ALIGN_STATE_LOCKED:
if(!external_locked(s)) {
s->align_state = ALIGN_STATE_START;
s->align_state = ALIGN_STATE_WAIT_CLKIN;
}
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