/* * cpu/spc300/spcpll.S * * Copyright (C) 2009 SPiDCOM Technologies * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of * the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, * MA 02111-1307 USA * * Author(s): * Drasko DRASKOVIC * */ #include #ifdef CONFIG_CHIP_FEATURE_SPCPLL #include #include /* counter to repeat group of NB_INSTR instructions to reach 200uS time */ /* ( ( (time_to_wait * Xclk) / 1000000 ) / nb_instr ) */ /* WARNING Xclk need to be equal or lower than 37.5MHZ */ #define PLL_WAIT_TIME 2500 /* ( ( (200 * 37500000) / 1000000 ) / 3 ) */ .file "spcpll.S" .text .arm @ This is ARM code; performs the same action as .code 32 .align 2 @ Align to word boundary; "2" means the number of bits that must be zero .globl pll_init .type pll_init, %function /* * PLL system set-up */ pll_init: /* * Switch OFF PLLs (before doing configuration) */ /* System PLL */ ldr r0, =MARIA_REGBANK_BASE ldr r1, =PLL_CMD_OFF str r1, [r0, #RB_SPLL_PD_OFFSET] /* Peripheral PLL */ ldr r0, =MARIA_REGBANK_BASE ldr r1, =PLL_CMD_OFF str r1, [r0, #RB_PPLL_PD_OFFSET] /* DSP PLL */ ldr r0, =MARIA_REGBANK_BASE ldr r1, =PLL_CMD_OFF str r1, [r0, #RB_DPLL_PD_OFFSET] /* * Configure PLLs (while switched off) */ /* Find Xclk and Freq parameters from NVRAM * (NVRAM struct adress was passed to this fnc in r10) */ ldr r1, [r10, #NVRAM_PKG_CFG_OFFSET] /* load pkg_cfg field into r1 */ and r2, r1, #NVRAM_XCLK_MASK /* r2 = Xclk */ lsr r3, r1, #NVRAM_FREQ_SHIFT and r3, r3, #NVRAM_FREQ_MASK lsl r3, r3, #2 /* r3 = Freq*4 */ mov r5, r3 /* store r3 for a future use. */ lsl r4, r2, #4 /* r4 = Xclk*16 */ lsl r2, r2, #2 /* r2 = Xclk*4 */ add r3, r3, r4 /* r3 = Xclk*16 + Freq*4; and this will be the index into our matrix */ /* System PLL */ /* config : fbdiv, prediv, lbws, sscg_enable, sscg_fcw, sscg_fmw, sscg_mdw */ /* PLL_CLK_600MHz */ ldr r0, =MARIA_REGBANK_BASE ldr r1, = 0 str r1, [r0, #RB_SPLL_EN_OFFSET] /* RB_SPLL_EN = 0 */ adr r4, .LpoolSYSfbdiv /* r4 points to the begining of the array */ ldr r1, [r4, r3] /* r1 = array[Xclk*16 + Freq*4]; we take the element of the array indexed with Xclk */ str r1, [r0, #RB_SPLL_FBDIV_OFFSET] adr r4, .LpoolSYSprediv /* r4 points to the begining of the array */ ldr r1, [r4, r3] /* r1 = array[Xclk*16 + Freq*4]; we take the element of the array indexed with Xclk */ str r1, [r0, #RB_SPLL_PREDIV_OFFSET] ldr r1, = PLL_LBWS_ON str r1, [r0, #RB_SPLL_LBWS_OFFSET] /* RB_SPLL_LBWS = 1 */ ldr r1, = 1 /* turn on spread spectrum */ str r1, [r0, #RB_SPLL_EN_OFFSET] /* RB_SPLL_EN = 1 */ adr r4, .LSpreadSpectrumFCW /* turn on spread spectrum */ ldr r1, [r4, r5] str r1, [r0, #RB_SPLL_FCW_OFFSET] /* RB_SPLL_FCW = See table... */ adr r4, .LSpreadSpectrumFMW ldr r1, [r4, r5] str r1, [r0, #RB_SPLL_FMW_OFFSET] /* RB_SPLL_FMW = See table... */ adr r4, .LSpreadSpectrumMDW ldr r1, [r4, r5] str r1, [r0, #RB_SPLL_MDW_OFFSET] /* RB_SPLL_MDW = See table... */ /* Peripheral PLL */ /* config : fbdiv, prediv, lbws, sscg_enable, sscg_fcw, sscg_fmw, sscg_mdw */ /* PLL_CLK_600MHz */ ldr r0, =MARIA_REGBANK_BASE adr r4, .LpoolPERIPHfbdiv /* r4 points to the begining of the array */ ldr r1, [r4, r2] /* r1 = array[Xclk*4]; we take the element of the array indexed with Xclk */ str r1, [r0, #RB_PPLL_FBDIV_OFFSET] adr r4, .LpoolPERIPHprediv /* r4 points to the begining of the array */ ldr r1, [r4, r2] /* r1 = array[Xclk*4]; we take the element of the array indexed with Xclk */ str r1, [r0, #RB_PPLL_PREDIV_OFFSET] ldr r1, = PLL_LBWS_OFF str r1, [r0, #RB_PPLL_LBWS_OFFSET] /* RB_PPLL_LBWS = 0 */ /* DSP PLL */ /* config : fbdiv, prediv, lbws, sscg_enable, sscg_fcw, sscg_fmw, sscg_mdw */ /* PLL_CLK_600MHz */ ldr r0, =MARIA_REGBANK_BASE adr r4, .LpoolDSPfbdiv /* r4 points to the begining of the array */ ldr r1, [r4, r2] /* r1 = array[Xclk*4]; we take the element of the array indexed with Xclk */ str r1, [r0, #RB_DPLL_FBDIV_OFFSET] adr r4, .LpoolDSPprediv /* r4 points to the begining of the array */ ldr r1, [r4, r2] /* r1 = array[Xclk*4]; we take the element of the array indexed with Xclk */ str r1, [r0, #RB_DPLL_PREDIV_OFFSET] ldr r1, = PLL_LBWS_OFF str r1, [r0, #RB_DPLL_LBWS_OFFSET] /* RB_DPLL_LBWS = 0 */ /* System PLL */ ldr r0, =MARIA_REGBANK_BASE /* Release spread spectrum reset */ ldr r1, = 1 str r1, [r0, #RB_SPLL_SSCGNRST_OFFSET] /* * Switch ON PLLs and wait 200uS (or more) * until they stabilize */ ldr r1, =PLL_CMD_ON str r1, [r0, #RB_SPLL_PD_OFFSET] /* Peripheral PLL */ ldr r0, =MARIA_REGBANK_BASE ldr r1, =PLL_CMD_ON str r1, [r0, #RB_PPLL_PD_OFFSET] /* DSP PLL */ ldr r0, =MARIA_REGBANK_BASE ldr r1, =PLL_CMD_ON str r1, [r0, #RB_DPLL_PD_OFFSET] /* active wait */ ldr r0, =PLL_WAIT_TIME .Lwaitpll: sub r0, r0, #1 cmp r0, #0 bne .Lwaitpll /* * Switch to PLL clock */ /* System PLL */ ldr r0, =MARIA_REGBANK_BASE ldr r1, =PLL_CMD_PLL str r1, [r0, #RB_SPLL_BYPASS_OFFSET] .LpollSPLLstat: ldr r1, [r0, #RB_SPLL_BYPASS_STAT_OFFSET] cmp r1, #PLL_IS_PLL bne .LpollSPLLstat /* Peripheral PLL */ ldr r0, =MARIA_REGBANK_BASE ldr r1, =PLL_CMD_PLL str r1, [r0, #RB_PPLL_BYPASS_OFFSET] .LpollPPLLstat: ldr r1, [r0, #RB_PPLL_BYPASS_STAT_OFFSET] cmp r1, #PLL_IS_PLL bne .LpollPPLLstat /* DSP PLL */ ldr r0, =MARIA_REGBANK_BASE ldr r1, =PLL_CMD_PLL str r1, [r0, #RB_DPLL_BYPASS_OFFSET] .LpollDPLLstat: ldr r1, [r0, #RB_DPLL_BYPASS_STAT_OFFSET] cmp r1, #PLL_IS_PLL bne .LpollDPLLstat /* back to my caller */ mov pc, lr /************************************************************** * * Data pools * **************************************************************/ /* * System PLL */ .LpoolSYSfbdiv: /* Xclk = 0 (18.75 MHz) */ .word 0x00000040 /* Freq = 0 (100 MHz) */ .word 0x00000050 /* Freq = 1 (125 MHz) */ .word 0x00000055 /* Freq = 2 (133 MHz) */ .word 0x0000003F /* Freq = 3 (150 MHz) */ /* Xclk = 1 (25 MHz) */ .word 0x00000010 /* Freq = 0 (100 MHz) */ .word 0x00000014 /* Freq = 1 (125 MHz) */ .word 0x00000040 /* Freq = 2 (133 MHz) */ .word 0x0000002F /* Freq = 3 (150 MHz) */ /* Xclk = 2 (37.5 MHz) */ .word 0x00000020 /* Freq = 0 (100 MHz) */ .word 0x00000028 /* Freq = 1 (125 MHz) */ .word 0x00000000 /* Freq = 2 (133 MHz) */ .word 0x0000003F /* Freq = 3 (150 MHz) */ .LpoolSYSprediv: /* Xclk = 0 (18.75 MHz) */ .word 0x00000003 /* Freq = 0 (100 MHz) */ .word 0x00000003 /* Freq = 1 (125 MHz) */ .word 0x00000003 /* Freq = 2 (133 MHz) */ .word 0x00000002 /* Freq = 3 (150 MHz) */ /* Xclk = 1 (25 MHz) */ .word 0x00000001 /* Freq = 0 (100 MHz) */ .word 0x00000001 /* Freq = 1 (125 MHz) */ .word 0x00000003 /* Freq = 2 (133 MHz) */ .word 0x00000002 /* Freq = 3 (150 MHz) */ /* Xclk = 2 (37.5 MHz) */ .word 0x00000003 /* Freq = 0 (100 MHz) */ .word 0x00000003 /* Freq = 1 (125 MHz) */ .word 0x00000009 /* Freq = 2 (133 MHz) */ .word 0x00000004 /* Freq = 3 (150 MHz) */ .LSpreadSpectrumFCW: .word 0x00000001 /* Freq 100 Mhz */ .word 0x00000002 /* Freq 125 Mhz */ .word 0x00000002 /* Freq 133 Mhz */ .word 0x00000003 /* Freq 150 Mhz */ .LSpreadSpectrumFMW: .word 0x00000005 /* Freq 100 Mhz */ .word 0x00000005 /* Freq 125 Mhz */ .word 0x00000005 /* Freq 133 Mhz */ .word 0x00000005 /* Freq 150 Mhz */ .LSpreadSpectrumMDW: .word 0x00000001 /* Freq 100 Mhz */ .word 0x00000001 /* Freq 125 Mhz */ .word 0x00000001 /* Freq 133 Mhz */ .word 0x00000001 /* Freq 150 Mhz */ /* * Peripheral PLL */ .LpoolPERIPHfbdiv: .word 0x00000028 /* Xclk = 0 (18.75 MHz) */ .word 0x0000000a /* Xclk = 1 (25 MHz) */ .word 0x00000014 /* Xclk = 2 (37.5 MHz) */ .LpoolPERIPHprediv: .word 0x00000003 /* Xclk = 0 (18.75 MHz) */ .word 0x00000001 /* Xclk = 1 (25 MHz) */ .word 0x00000003 /* Xclk = 2 (37.5 MHz) */ /* * DSP PLL */ .LpoolDSPfbdiv: .word 0x00000010 /* Xclk = 0 (18.75 MHz) */ .word 0x0000000c /* Xclk = 1 (25 MHz) */ .word 0x00000008 /* Xclk = 2 (37.5 MHz) */ .LpoolDSPprediv: .word 0x00000001 /* Xclk = 0 (18.75 MHz) */ .word 0x00000001 /* Xclk = 1 (25 MHz) */ .word 0x00000001 /* Xclk = 2 (37.5 MHz) */ #endif /* CONFIG_CHIP_FEATURE_SPCPLL */