Quantcast
Channel: Processors forum - Recent Threads
Viewing all articles
Browse latest Browse all 17527

Power Management

$
0
0
Dear TI.

We´re working in a video application and we´re using the C6748 (without DSP-BIOS or SYS-BIOS), we almost create the final product, there are few things left. One of those things is regarding with low power. We tried over and over and now we’re stuck and we need your help. In ordered to expose the problem and accelerate the solution we present the followed step that we did:

1. We followed the C6748 Technical Reference Manual” in order to decrease the power consumption. And according with it, we change the PLL0/PLL1 configuration (bypass/ power down). It works fine because in debug mode (CCS) the current descend from 110 mA to 55 mA and the rest of the consecutive instructions were executed at slowly rate.

2. We tried to restore the PLL0/PLL1 taking the procedure described in the Reference Manual for that, but fail. The system is stuck in some place.

3. We used the Core_300MHz_mDDR_150MHz function presented in the gel file (C6748_LCDK.gel) and we could restore the PLL0/PLL1 (at 300 MHz). How did we do this? In debug operation we put a breaking point after the PLL0/PLL1 bypass/power-down. Then we call the Core_300MHz_mDDR_150MHz (in CCS ->Scripts) and voila the system recovery to the original setup.

4. So, we copied the Core_300MHz_mDDR_150MHz from the C6748_LCDK.gel into our project (with minimum adaptation), but we can´t restore the PLL0/PLL1.

5. We tried in release mode and burning the flash and the problem remains, The DSP is still stuck in some point.

 

In order to clarify the point number 4 described above we present Fig. 1 with our functions. When the function LowPower is call everything seems to work fine the problem is when we try to call the RestorePower function.

 

  Fig. 1. Functions for power management.

 

The code for LowPower and RestorePower are presented in the next paragraphs.

 

voidLowPower()

{

                HWREG(KICK0R)=0x83E70B13;

                HWREG(KICK0R)=0x83E70B13;

                HWREG(KICK1R)=0x95A4F1E0;

                CFGCHIP0&=0xFFFFFFEF;

                CFGCHIP3&=0xFFFFFFDF;

                // Set PLLENSRC '0',bit 5, PLL Enable(PLLEN) selection is controlled through MMR

                PLL0_PLLCTL &= ~(0x00000020);

                // PLLCTL.EXTCLKSRC bit 9 should be left at 0 for Freon

                PLL0_PLLCTL &= ~(0x00000200);

                // Set PLLEN=0 to put in bypass mode

                PLL0_PLLCTL &= ~(0x00000001);

                //wait for 4 cycles to allow PLLEN mux switches properly to bypass clock

                for(int i=0; i<PLLEN_MUX_SWITCH; i++) { }

// Set PLLENSRC '0',bit 5, PLL Enable(PLLEN) selection is controlled through MMR

                PLL1_PLLCTL &= ~(0x00000020);

                // PLLCTL.EXTCLKSRC bit 9 should be left at 0 for Freon

                PLL1_PLLCTL &= ~(0x00000200);

                // Set PLLEN=0 to put in bypass mode

                PLL1_PLLCTL &= ~(0x00000001);

                //wait for 4 cycles to allow PLLEN mux switches properly to bypass clock

                for(int i=0; i<PLLEN_MUX_SWITCH; i++) { }

//PLL1 Power down

                PLL1_PLLCTL=PLL1_PLLCTL|0x2;    

//PLL0 Power down

PLL0_PLLCTL=PLL0_PLLCTL|0x2;   

}

voidRestorePower()

{

HWREG(KICK0R)=0x83E70B13;

                HWREG(KICK0R)=0x83E70B13;

                HWREG(KICK1R)=0x95A4F1E0;

                CFGCHIP0&=0xFFFFFFEF;

                CFGCHIP3&=0xFFFFFFDF;

Core_300MHz_mDDR_150MHz();

}

Our full code including the Core_300MHz_mDDR_150MHz function is taken from the gel file and is presented in the bottom of this post.

Would you like to help us to PLL bypass/power down and then restore the PLL?

 

One more last thing, we noted a current difference when the program is running in debug mode (CCS v5.1) and when the program is running from FLASH. The difference is 30 mA more (running in Flash). This is normal? We use the AISge tool with configurations file like the follow.

 

Boot Mode=NAND Flash
Boot Speed=115200
Flash Width=1
Flash Timing=3ffffffd
Configure Peripheral=False
Configure PLL0=True
Configure SDRAM=False
Configure PLL1=True
Configure DDR2=True
Configure LPSC=False
Configure Pinmux=False
Enable CRC=False
Specify Entrypoint=False
Enable Sequential Read=False
Use 4.5 Clock Divider=False
Use DDR2 Direct Clock=False
Use mDDR=False
ROM ID=3
Device Type=1
Input Clock Speed=24
Clock Type=0
PLL0 Pre Divider=1
PLL0 Multiplier=25
PLL0 Post Divider=2
PLL0 Div1=1
PLL0 Div3=3
PLL0 Div7=6
PLL1 Multiplier=25
PLL1 Post Divider=2
PLL1 Div1=1
PLL1 Div2=2
PLL1 Div3=3
Entrypoint=c1080000
SDRAM SDBCR=0
SDRAM SDTMR=0
SDRAM SDRSRPDEXIT=0
SDRAM SDRCR=0
DDR2 PHY=c5
DDR2 SDCR=134832
DDR2 SDCR2=0
DDR2 SDTIMR=264a3209
DDR2 SDTIMR2=3c14c722
DDR2 SDRCR=492
LPSC0 Enable=0+1+2+3+4+5+9+11+12+
LPSC0 Disable=
LPSC0 SyncRst=
LPSC1 Enable=0+1+2+3+4+5+7+9+10+11+12+13+14+15+16+18+
LPSC1 Disable=
LPSC1 SyncRst=
Pinmux=
App File String=C:\ti\C6748_StarterWare_1_20_03_03\build\c674x\cgt_ccs\c6748\lcdkC6748\vpif_lcd_loopback\Release\vpif_lcd_loopback.out;
AIS File Name=C:\temp\vpif_lcd_loopback.bin

 

Thank you in advance and we hope to find the answer for this issue.

 


FULL CODE:

#define LPSC_EDMA_CC0 0 #define LPSC_EDMA_TC0 1 #define LPSC_EDMA_TC1 2 #define LPSC_EMIFA 3 /*PSC0*/ #define LPSC_SPI0 4 /*PSC0*/ #define LPSC_MMCSD0 5 /*PSC0*/ #define LPSC_ARM_AINTC 6 #define LPSC_ARM_RAMROM 7 /*PSC0*/ // LPSC #8 not used #define LPSC_UART0 9 /*PSC0*/ #define LPSC_SCR0 10 #define LPSC_SCR1 11 #define LPSC_SCR2 12 // LPSC #13 not used #define LPSC_ARM 14 /*PSC0*/ #define LPSC_DSP 15 /*PSC0*/ #define LPSC_EDMA_CC1 0 #define LPSC_USB20 1 /*PSC1*/ #define LPSC_USB11 2 /*PSC1*/ #define LPSC_GPIO 3 /*PSC1*/ #define LPSC_UHPI 4 /*PSC1*/ #define LPSC_EMAC 5 /*PSC1*/ #define LPSC_DDR 6 /*PSC1*/ #define LPSC_MCASP0 7 /*PSC1*/ #define LPSC_SATA 8 /*PSC1*/ #define LPSC_VPIF 9 /*PSC1*/ #define LPSC_SPI1 10 /*PSC1*/ #define LPSC_I2C1 11 /*PSC1*/ #define LPSC_UART1 12 /*PSC1*/ #define LPSC_UART2 13 /*PSC1*/ #define LPSC_MCBSP0 14 /*PSC1*/ #define LPSC_MCBSP1 15 /*PSC1*/ #define LPSC_LCDC 16 /*PSC1*/ #define LPSC_EPWM 17 /*PSC1*/ #define LPSC_MMCSD1 18 #define LPSC_UPP 19 #define LPSC_ECAP 20 #define LPSC_EDMA_TC2 21 // LPSC #22-23 not used #define LPSC_SCR_F0 24 #define LPSC_SCR_F1 25 #define LPSC_SCR_F2 26 #define LPSC_SCR_F6 27 #define LPSC_SCR_F7 28 #define LPSC_SCR_F8 29 #define LPSC_BR_F7 30 #define LPSC_SHARED_RAM 31 /*PSC Module Related Registers*/ #define PSC0_BASE 0x01C10000 #define PSC1_BASE 0x01E27000 #define PSC0_MDCTL (PSC0_BASE+0xA00) #define PSC0_MDSTAT (PSC0_BASE+0x800) #define PSC0_PTCMD *(unsigned int*) (PSC0_BASE + 0x120) #define PSC0_PTSTAT *(unsigned int*) (PSC0_BASE + 0x128) #define PSC1_MDCTL (PSC1_BASE+0xA00) #define PSC1_MDSTAT (PSC1_BASE+0x800) #define PSC1_PTCMD *(volatile unsigned int*) (PSC1_BASE + 0x120) #define PSC1_PTSTAT *(volatile unsigned int*) (PSC1_BASE + 0x128) #define PSC_TIMEOUT 200 // This value can be optimized by the user #define PLL0_BASE 0x01C11000 /*SYSTEM PLL BASE ADDRESS*/ #define PLL0_PID *(volatile unsigned int*) (PLL0_BASE + 0x00) /*PID*/ #define PLL0_RSTYPE *(volatile unsigned int*) (PLL0_BASE + 0xE4) /*Reset Type status Reg*/ #define PLL0_PLLCTL *(volatile unsigned int*) (PLL0_BASE + 0x100) /*PLL Control Register*/ #define PLL0_OCSEL *(volatile unsigned int*) (PLL0_BASE + 0x104) /*OBSCLK Select Register*/ #define PLL0_SECCTL *(volatile unsigned int*) (PLL0_BASE + 0x108) /*PLL Secondary Control Register*/ #define PLL0_PLLM *(volatile unsigned int*) (PLL0_BASE + 0x110) /*PLL Multiplier*/ #define PLL0_PREDIV *(volatile unsigned int*) (PLL0_BASE + 0x114) /*Pre divider*/ #define PLL0_PLLDIV1 *(volatile unsigned int*) (PLL0_BASE + 0x118) /*Divider-1*/ #define PLL0_PLLDIV2 *(volatile unsigned int*) (PLL0_BASE + 0x11C) /*Divider-2*/ #define PLL0_PLLDIV3 *(volatile unsigned int*) (PLL0_BASE + 0x120) /*Divider-3*/ #define PLL0_OSCDIV1 *(volatile unsigned int*) (PLL0_BASE + 0x124) /*Oscilator Divider*/ #define PLL0_POSTDIV *(volatile unsigned int*) (PLL0_BASE + 0x128) /*Post Divider*/ #define PLL0_BPDIV *(volatile unsigned int*) (PLL0_BASE + 0x12C) /*Bypass Divider*/ #define PLL0_WAKEUP *(volatile unsigned int*) (PLL0_BASE + 0x130) /*Wakeup Reg*/ #define PLL0_PLLCMD *(volatile unsigned int*) (PLL0_BASE + 0x138) /*Command Reg*/ #define PLL0_PLLSTAT *(volatile unsigned int*) (PLL0_BASE + 0x13C) /*Status Reg*/ #define PLL0_ALNCTL *(volatile unsigned int*) (PLL0_BASE + 0x140) /*Clock Align Control Reg*/ #define PLL0_DCHANGE *(volatile unsigned int*) (PLL0_BASE + 0x144) /*PLLDIV Ratio Chnage status*/ #define PLL0_CKEN *(volatile unsigned int*) (PLL0_BASE + 0x148) /*Clock Enable Reg*/ #define PLL0_CKSTAT *(volatile unsigned int*) (PLL0_BASE + 0x14C) /*Clock Status Reg*/ #define PLL0_SYSTAT *(volatile unsigned int*) (PLL0_BASE + 0x150) /*Sysclk status reg*/ #define PLL0_PLLDIV4 *(volatile unsigned int*) (PLL0_BASE + 0x160) /*Divider 4*/ #define PLL0_PLLDIV5 *(volatile unsigned int*) (PLL0_BASE + 0x164) /*Divider 5*/ #define PLL0_PLLDIV6 *(volatile unsigned int*) (PLL0_BASE + 0x168) /*Divider 6*/ #define PLL0_PLLDIV7 *(volatile unsigned int*) (PLL0_BASE + 0x16C) /*Divider 7*/ #define PLL0_PLLDIV8 *(volatile unsigned int*) (PLL0_BASE + 0x170) /*Divider 8*/ #define PLL0_PLLDIV9 *(volatile unsigned int*) (PLL0_BASE + 0x174) /*Divider 9*/ #define PLL0_PLLDIV10 *(volatile unsigned int*) (PLL0_BASE + 0x178) /*Divider 10*/ #define PLL0_PLLDIV11 *(volatile unsigned int*) (PLL0_BASE + 0x17C) /*Divider 11*/ #define PLL0_PLLDIV12 *(volatile unsigned int*) (PLL0_BASE + 0x180) /*Divider 12*/ #define PLL0_PLLDIV13 *(volatile unsigned int*) (PLL0_BASE + 0x184) /*Divider 13*/ #define PLL0_PLLDIV14 *(volatile unsigned int*) (PLL0_BASE + 0x188) /*Divider 14*/ #define PLL0_PLLDIV15 *(volatile unsigned int*) (PLL0_BASE + 0x18C) /*Divider 15*/ #define PLL0_PLLDIV16 *(volatile unsigned int*) (PLL0_BASE + 0x190) /*Divider 16*/ #define PLL1_BASE 0x01E1A000 /*SYSTEM PLL1 BASE ADDRESS*/ #define PLL1_PID *(volatile unsigned int*) (PLL1_BASE + 0x00) /*PID*/ #define PLL1_RSTYPE *(volatile unsigned int*) (PLL1_BASE + 0xE4) /*Reset Type status Reg*/ #define PLL1_PLLCTL *(volatile unsigned int*) (PLL1_BASE + 0x100) /*PLL Control Register*/ #define PLL1_OCSEL *(volatile unsigned int*) (PLL1_BASE + 0x104) /*OBSCLK Select Register*/ #define PLL1_SECCTL *(volatile unsigned int*) (PLL1_BASE + 0x108) /*PLL Secondary Control Register*/ #define PLL1_PLLM *(volatile unsigned int*) (PLL1_BASE + 0x110) /*PLL Multiplier*/ #define PLL1_PREDIV *(volatile unsigned int*) (PLL1_BASE + 0x114) /*Pre divider*/ #define PLL1_PLLDIV1 *(volatile unsigned int*) (PLL1_BASE + 0x118) /*Divider-1*/ #define PLL1_PLLDIV2 *(volatile unsigned int*) (PLL1_BASE + 0x11C) /*Divider-2*/ #define PLL1_PLLDIV3 *(volatile unsigned int*) (PLL1_BASE + 0x120) /*Divider-3*/ #define PLL1_OSCDIV1 *(volatile unsigned int*) (PLL1_BASE + 0x124) /*Oscilator Divider*/ #define PLL1_POSTDIV *(volatile unsigned int*) (PLL1_BASE + 0x128) /*Post Divider*/ #define PLL1_BPDIV *(volatile unsigned int*) (PLL1_BASE + 0x12C) /*Bypass Divider*/ #define PLL1_WAKEUP *(volatile unsigned int*) (PLL1_BASE + 0x130) /*Wakeup Reg*/ #define PLL1_PLLCMD *(volatile unsigned int*) (PLL1_BASE + 0x138) /*Command Reg*/ #define PLL1_PLLSTAT *(volatile unsigned int*) (PLL1_BASE + 0x13C) /*Status Reg*/ #define PLL1_ALNCTL *(volatile unsigned int*) (PLL1_BASE + 0x140) /*Clock Align Control Reg*/ #define PLL1_DCHANGE *(volatile unsigned int*) (PLL1_BASE + 0x144) /*PLLDIV Ratio Chnage status*/ #define PLL1_CKEN *(volatile unsigned int*) (PLL1_BASE + 0x148) /*Clock Enable Reg*/ #define PLL1_CKSTAT *(volatile unsigned int*) (PLL1_BASE + 0x14C) /*Clock Status Reg*/ #define PLL1_SYSTAT *(volatile unsigned int*) (PLL1_BASE + 0x150) /*Sysclk status reg*/ #define PLL1_PLLDIV4 *(volatile unsigned int*) (PLL1_BASE + 0x160) /*Divider 4*/ #define PLL1_PLLDIV5 *(volatile unsigned int*) (PLL1_BASE + 0x164) /*Divider 5*/ #define PLL1_PLLDIV6 *(volatile unsigned int*) (PLL1_BASE + 0x168) /*Divider 6*/ #define PLL1_PLLDIV7 *(volatile unsigned int*) (PLL1_BASE + 0x16C) /*Divider 7*/ #define PLL1_PLLDIV8 *(volatile unsigned int*) (PLL1_BASE + 0x170) /*Divider 8*/ #define PLL1_PLLDIV9 *(volatile unsigned int*) (PLL1_BASE + 0x174) /*Divider 9*/ #define PLL1_PLLDIV10 *(volatile unsigned int*) (PLL1_BASE + 0x178) /*Divider 10*/ #define PLL1_PLLDIV11 *(volatile unsigned int*) (PLL1_BASE + 0x17C) /*Divider 11*/ #define PLL1_PLLDIV12 *(volatile unsigned int*) (PLL1_BASE + 0x180) /*Divider 12*/ #define PLL1_PLLDIV13 *(volatile unsigned int*) (PLL1_BASE + 0x184) /*Divider 13*/ #define PLL1_PLLDIV14 *(volatile unsigned int*) (PLL1_BASE + 0x188) /*Divider 14*/ #define PLL1_PLLDIV15 *(volatile unsigned int*) (PLL1_BASE + 0x18C) /*Divider 15*/ #define PLL1_PLLDIV16 *(volatile unsigned int*) (PLL1_BASE + 0x190) /*Divider 16*/ #define SYS_BASE 0x01C14000 #define CFGCHIP0 *(volatile unsigned int*)(SYS_BASE + 0x17C) #define CFGCHIP1 *(volatile unsigned int*)(SYS_BASE + 0x180) #define CFGCHIP2 *(volatile unsigned int*)(SYS_BASE + 0x184) #define CFGCHIP3 *(volatile unsigned int*)(SYS_BASE + 0x188) #define PD0 0 /*Power Domain-0*/ #define PLLEN_MUX_SWITCH 4 #define PLL_LOCK_TIME_CNT 2400 #define PLL_STABILIZATION_TIME 2000 #define PLL_RESET_TIME_CNT 200 #define DDR2 0 // Do not change this value #define DDR_DEBUG 1//0 // Set this to "1" to program DDR with more timing slack #define VTP_TIMEOUT 2000//200 // This value can be optimized by the user /*DDR MMR Declaration*/ #define VTPIO_CTL *(volatile unsigned int*)(0x01E2C000) // VTPIO_CTL Register #define EMIFDDR_SDRAM_CFG 0xB0000000 #define EMIFDDR_REVID *(volatile unsigned int*)(EMIFDDR_SDRAM_CFG + 0x00) //EMIF Module ID and Revision Register #define EMIFDDR_SDRSTAT *(volatile unsigned int*)(EMIFDDR_SDRAM_CFG + 0x04) //SDRAM Status Register #define EMIFDDR_SDCR *(volatile unsigned int*)(EMIFDDR_SDRAM_CFG + 0x08) //SDRAM Bank Config Register #define EMIFDDR_SDRCR *(volatile unsigned int*)(EMIFDDR_SDRAM_CFG + 0x0C) //SDRAM Refresh Control Register #define EMIFDDR_SDTIMR1 *(volatile unsigned int*)(EMIFDDR_SDRAM_CFG + 0x10) //SDRAM Timing Register1 #define EMIFDDR_SDTIMR2 *(volatile unsigned int*)(EMIFDDR_SDRAM_CFG + 0x14) //SDRAM Timing Register2 #define EMIFDDR_SDCR2 *(volatile unsigned int*)(EMIFDDR_SDRAM_CFG + 0x1C) //SDRAM Config Register2 #define EMIFDDR_PBBPR *(volatile unsigned int*)(EMIFDDR_SDRAM_CFG + 0x20) //VBUSM Burst Priority Register #define EMIFDDR_VBUSMCFG1 *(volatile unsigned int*)(EMIFDDR_SDRAM_CFG + 0x28) //VBUSM config Value1 Register #define EMIFDDR_VBUSMCFG2 *(volatile unsigned int*)(EMIFDDR_SDRAM_CFG + 0x2C) //VBUSM config Value2 Register #define EMIFDDR_IRR *(volatile unsigned int*)(EMIFDDR_SDRAM_CFG + 0xC0) //Interrupt Raw Register #define EMIFDDR_IMR *(volatile unsigned int*)(EMIFDDR_SDRAM_CFG + 0xC4) //Interrupt Masked Register #define EMIFDDR_IMSR *(volatile unsigned int*)(EMIFDDR_SDRAM_CFG + 0xC8) //Interrupt Mask Set Register #define EMIFDDR_IMCR *(volatile unsigned int*)(EMIFDDR_SDRAM_CFG + 0xCC) //Interrupt Mask Clear Register #define DDRPHYREV *(volatile unsigned int*)(EMIFDDR_SDRAM_CFG + 0xE0) //DDR PHY ID and Revision Register #define DRPYC1R *(volatile unsigned int*)(EMIFDDR_SDRAM_CFG + 0xE4) //DDR PHY Control 1 Register #define KICK0R 0x01C14038 #define KICK1R 0x01C1403C void LowPower() { HWREG(KICK0R)=0x83E70B13; HWREG(KICK1R)=0x95A4F1E0; CFGCHIP0&=0xFFFFFFEF; CFGCHIP3&=0xFFFFFFDF; /* Set PLLENSRC '0',bit 5, PLL Enable(PLLEN) selection is controlled through MMR */ PLL0_PLLCTL &= ~(0x00000020); /* PLLCTL.EXTCLKSRC bit 9 should be left at 0 for Freon */ PLL0_PLLCTL &= ~(0x00000200); /* Set PLLEN=0 to put in bypass mode*/ PLL0_PLLCTL &= ~(0x00000001); /*wait for 4 cycles to allow PLLEN mux switches properly to bypass clock*/ for(int i=0; i<PLLEN_MUX_SWITCH; i++) {;} /* Set PLLENSRC '0',bit 5, PLL Enable(PLLEN) selection is controlled through MMR */ PLL1_PLLCTL &= ~(0x00000020); /* PLLCTL.EXTCLKSRC bit 9 should be left at 0 for Freon */ PLL1_PLLCTL &= ~(0x00000200); /* Set PLLEN=0 to put in bypass mode*/ PLL1_PLLCTL &= ~(0x00000001); /*wait for 4 cycles to allow PLLEN mux switches properly to bypass clock*/ for(int i=0; i<PLLEN_MUX_SWITCH; i++) {;} //PLL1 Power down PLL1_PLLCTL=PLL1_PLLCTL|0x2; //Power down el PLL1 //PLL0 Power down PLL0_PLLCTL=PLL0_PLLCTL|0x2; //Power down el PLL0 } void RestorePower() { HWREG(KICK0R)=0x83E70B13; HWREG(KICK1R)=0x95A4F1E0; CFGCHIP0&=0xFFFFFFEF; CFGCHIP3&=0xFFFFFFDF; Core_300MHz_mDDR_150MHz(); } void Core_300MHz_mDDR_150MHz() { Set_Core_300MHz(); Set_DDR2_150MHz(); } void Set_Core_300MHz() { device_PLL0(0,24,1,0,1,11,5); } void Set_DDR2_150MHz() { Set_DDRPLL_150MHz(); DEVICE_DDRConfig(DDR2, 150); } void Set_DDRPLL_150MHz() { device_PLL1(24,1,0,1,2); } void device_PLL0(unsigned int CLKMODE, unsigned int PLLM, unsigned int POSTDIV,unsigned int PLLDIV1, unsigned int PLLDIV2, unsigned int PLLDIV3, unsigned int PLLDIV7 ) { unsigned int i=0; HWREG(KICK0R)=0x83E70B13; HWREG(KICK1R)=0x95A4F1E0; /* Clear PLL lock bit */ CFGCHIP0 &= ~(0x00000010); /* Set PLLENSRC '0',bit 5, PLL Enable(PLLEN) selection is controlled through MMR */ PLL0_PLLCTL &= ~(0x00000020); /* PLLCTL.EXTCLKSRC bit 9 should be left at 0 for Freon */ PLL0_PLLCTL &= ~(0x00000200); /* Set PLLEN=0 to put in bypass mode*/ PLL0_PLLCTL &= ~(0x00000001); /*wait for 4 cycles to allow PLLEN mux switches properly to bypass clock*/ for(i=0; i<PLLEN_MUX_SWITCH; i++) { } /* Select the Clock Mode bit 8 as External Clock or On Chip Oscilator*/ PLL0_PLLCTL &= 0xFFFFFEFF; PLL0_PLLCTL |= (CLKMODE << 8); /*Clear PLLRST bit to reset the PLL */ PLL0_PLLCTL &= ~(0x00000008); /* Disable the PLL output*/ PLL0_PLLCTL |= (0x00000010); /* PLL initialization sequence Power up the PLL by setting PWRDN bit set to 0 */ PLL0_PLLCTL &= ~(0x00000002); /* Enable the PLL output*/ PLL0_PLLCTL &= ~(0x00000010); /*PLL stabilisation time- take out this step , not required here when PLL in bypassmode*/ for(i=0; i<PLL_STABILIZATION_TIME; i++) { } /*Program the required multiplier value in PLLM*/ PLL0_PLLM = PLLM; /*If desired to scale all the SYSCLK frequencies of a given PLLC, program the POSTDIV ratio*/ PLL0_POSTDIV = 0x8000 | POSTDIV; /*Check for the GOSTAT bit in PLLSTAT to clear to 0 to indicate that no GO operation is currently in progress*/ while(PLL0_PLLSTAT & 0x1==1){} /*Program the RATIO field in PLLDIVx with the desired divide factors. In addition, make sure in this step you leave the PLLDIVx.DxEN bits set so clocks are still enabled (default).*/ PLL0_PLLDIV1 = 0x8000 | PLLDIV1; // Fixed Ratio /1 PLL0_PLLDIV2 = 0x8000 | PLLDIV2; // Fixed Ratio /2 PLL0_PLLDIV4 = 0x8000 | (((PLLDIV1+1)*4)-1); // Fixed Ratio /4 PLL0_PLLDIV6 = 0x8000 | PLLDIV1; // Fixed Ratio /1 PLL0_PLLDIV3 = 0x8000 | PLLDIV3; // Variable Ratio (EMIF) PLL0_PLLDIV7 = 0x8000 | PLLDIV7; // Variable Ratio (RMII) /*Set the GOSET bit in PLLCMD to 1 to initiate a new divider transition.*/ PLL0_PLLCMD |= 0x1; /*Wait for the GOSTAT bit in PLLSTAT to clear to 0 (completion of phase alignment).*/ while(PLL0_PLLSTAT & 0x1==1) { } /*Wait for PLL to reset properly.*/ for(i=0; i<PLL_RESET_TIME_CNT; i++) { } /*Set the PLLRST bit in PLLCTL to 1 to bring the PLL out of reset*/ PLL0_PLLCTL |= 0x8; /*Wait for PLL to lock.*/ for(i=0; i<PLL_LOCK_TIME_CNT; i++) { } /*Set the PLLEN bit in PLLCTL to 1 to remove the PLL from bypass mode*/ PLL0_PLLCTL |= 0x1; } void device_PLL1(unsigned int PLLM,unsigned int POSTDIV,unsigned int PLLDIV1, unsigned int PLLDIV2, unsigned int PLLDIV3 ) { unsigned int i=0; /* Clear PLL lock bit */ CFGCHIP3 &= ~(0x00000020); /* Set PLLENSRC '0',bit 5, PLL Enable(PLLEN) selection is controlled through MMR */ PLL1_PLLCTL &= ~(0x00000020); /* PLLCTL.EXTCLKSRC bit 9 should be left at 0 for Freon */ PLL1_PLLCTL &= ~(0x00000200); /* Set PLLEN=0 to put in bypass mode*/ PLL1_PLLCTL &= ~(0x00000001); /*wait for 4 cycles to allow PLLEN mux switches properly to bypass clock*/ for(i=0; i<PLLEN_MUX_SWITCH; i++) { } /*Clear PLLRST bit to reset the PLL */ PLL1_PLLCTL &= ~(0x00000008); /* Disable the PLL output*/ PLL1_PLLCTL |= (0x00000010); /* PLL initialization sequence Power up the PLL by setting PWRDN bit set to 0 */ PLL1_PLLCTL &= ~(0x00000002); /* Enable the PLL output*/ PLL1_PLLCTL &= ~(0x00000010); /*PLL stabilisation time- take out this step , not required here when PLL in bypassmode*/ for(i=0; i<PLL_STABILIZATION_TIME; i++) { } /*Program the required multiplier value in PLLM*/ PLL1_PLLM = PLLM; /*If desired to scale all the SYSCLK frequencies of a given PLLC, program the POSTDIV ratio*/ PLL1_POSTDIV = 0x8000 | POSTDIV; /*Check for the GOSTAT bit in PLLSTAT to clear to 0 to indicate that no GO operation is currently in progress*/ while(PLL1_PLLSTAT & 0x1==1){} /*Program the RATIO field in PLLDIVx with the desired divide factors. In addition, make sure in this step you leave the PLLDIVx.DxEN bits set so clocks are still enabled (default).*/ PLL1_PLLDIV1 = 0x8000 | PLLDIV1; // DDR frequency (aka 2X_CLK) PLL1_PLLDIV2 = 0x8000 | PLLDIV2; // Optional CFGCHIP3[ASYNC3_CLKSRC] clock source PLL1_PLLDIV3 = 0x8000 | PLLDIV3; // Optional PLL0 clock source /*Set the GOSET bit in PLLCMD to 1 to initiate a new divider transition.*/ PLL1_PLLCMD |= 0x1; /*Wait for the GOSTAT bit in PLLSTAT to clear to 0 (completion of phase alignment).*/ while(PLL1_PLLSTAT & 0x1==1) { } /*Wait for PLL to reset properly */ for(i=0; i<PLL_RESET_TIME_CNT; i++) { } /*Set the PLLRST bit in PLLCTL to 1 to bring the PLL out of reset*/ PLL1_PLLCTL |= 0x8; /*Wait for PLL to lock. See PLL spec for PLL lock time*/ for(i=0; i<PLL_LOCK_TIME_CNT; i++) { } /*Set the PLLEN bit in PLLCTL to 1 to remove the PLL from bypass mode*/ PLL1_PLLCTL |= 0x1; } void DEVICE_DDRConfig(unsigned int ddr_type, unsigned int freq) { unsigned int j; unsigned int tmp_SDCR; // Enable the Clock to EMIFDDR SDRAM PSC1_LPSC_enable(PD0, LPSC_DDR); // Begin VTP Calibration VTPIO_CTL &= ~0x00000040; // Clear POWERDN VTPIO_CTL &= ~0x00000080; // Clear LOCK VTPIO_CTL |= 0x00002000; // Set CLKRZ in case it was cleared before (VTP looks for CLKRZ edge transition) VTPIO_CTL &= ~0x00002000; // Clear CLKRZ (Use read-modify-write to ensure 1 VTP cycle wait for previous instruction) VTPIO_CTL |= 0x00002000; // Set CLKRZ (Use read-modify-write to ensure 1 VTP cycle wait for previous instruction) j = 0; // Polling READY bit to see when VTP calibration is done while((VTPIO_CTL & 0x00008000) == 0) { if( j++ > VTP_TIMEOUT ) { break; } } VTPIO_CTL |= 0x00000080; // Set LOCK bit for static calibration mode VTPIO_CTL |= 0x00000040; // Set POWERDN bit to power down VTP module // End VTP Calibration VTPIO_CTL |= 0x00004000; // Set IOPWRDN to allow powerdown of input receivers when PWRDNEN is set // ********************************************************************************************** // Setting based 1Gb DDR2 Samsung K4T1G164QF-BCF8 // Config DDR timings DRPYC1R = (0x0 << 8) | // Reserved (0x1 << 7) | // EXT_STRBEN (0x1 << 6) | // PWRDNEN (0x0 << 3) | // Reserved (0x4 << 0); // RL // DRPYC1R Value = 0x000000C4 if( DDR_DEBUG ) { // Configure EMIF with max timings for more slack // Try this if memory is not stable DRPYC1R |= 0x7; // RL } EMIFDDR_SDCR |= 0x00800000; // Set BOOTUNLOCK // Settings depending on DDR2 tmp_SDCR = (0x0 << 25) | // MSDRAMEN (0x1 << 20); // DDR2EN EMIFDDR_SDCR = tmp_SDCR | // Settings that change depending on DDR2 or MDDR (EMIFDDR_SDCR & 0xF0000000) | // Reserved (0x0 << 27) | // DDR2TERM1 (0x0 << 26) | // IBANK_POS (0x0 << 24) | // DDRDRIVE1 (0x0 << 23) | // BOOTUNLOCK (0x0 << 22) | // DDR2DDQS (0x0 << 21) | // DDR2TERM0 (0x0 << 19) | // DDRDLL_DIS (0x0 << 18) | // DDRDRIVE0 (0x1 << 17) | // DDREN (0x1 << 16) | // SDRAMEN (0x1 << 15) | // TIMUNLOCK (0x1 << 14) | // NM (0x0 << 12) | // Reserved (0x4 << 9) | // CL (0x0 << 7) | // Reserved (0x3 << 4) | // IBANK (0x0 << 3) | // Reserved (0x2 << 0); // PAGESIZE EMIFDDR_SDCR2 = 0x00000000; // IBANK_POS set to 0 so this register does not apply if( DDR_DEBUG ) { // Configure EMIF with max timings for more slack // Try this if memory is not stable EMIFDDR_SDTIMR1 = (0x7F << 25) | // tRFC (0x07 << 22) | // tRP (0x07 << 19) | // tRCD (0x07 << 16) | // tWR (0x1F << 11) | // tRAS (0x1F << 6) | // tRC (0x07 << 3) | // tRRD (EMIFDDR_SDTIMR1 & 0x4) | // Reserved (0x03 << 0); // tWTR EMIFDDR_SDTIMR2 = (EMIFDDR_SDTIMR2 & 0x80000000) | // Reserved (((unsigned int) ((70000 / 3400) - 0.5)) << 27) | // tRASMAX (original 7812.5) (0x3 << 25) | // tXP (0x0 << 23) | // tODT (Not supported) (0x7F << 16) | // tXSNR (0xFF << 8) | // tXSRD (0x07 << 5) | // tRTP (1 Cycle) (0x1F << 0); // tCKE } else { // Let float -> integer truncate handle minus 1; Safer to round up for timings EMIFDDR_SDTIMR1 = (((unsigned int) (127.5 * freq / 1000)) << 25) | // tRFC (((unsigned int) (13.13 * freq / 1000)) << 22) | // tRP (((unsigned int) (13.13 * freq / 1000)) << 19) | // tRCD (((unsigned int) ( 15.0 * freq / 1000)) << 16) | // tWR (((unsigned int) ( 45.0 * freq / 1000)) << 11) | // tRAS (((unsigned int) (58.13 * freq / 1000)) << 6) | // tRC (((unsigned int) ( 7.5 * freq / 1000)) << 3) | // tRRD (EMIFDDR_SDTIMR1 & 0x4) | // Reserved ((2 - 1) << 0); // tWTR EMIFDDR_SDTIMR2 = (EMIFDDR_SDTIMR2 & 0x80000000) | // Reserved (((unsigned int) ((70000 / 7800) - 1)) << 27) | // tRASMAX (original 3400) ((0x3-1) << 25) | // tXP (Should be 6-1 per MT46H64M16LFBF-6 datasheet, but field only goes up to 0b11) (0x0 << 23) | // tODT (Not supported) (((unsigned int) (137.5 * freq / 1000)) << 16) | // tXSNR (tXSR for mDDR) ((200-1) << 8) | // tXSRD (tXSR for mDDR) ((2 - 1) << 5) | // tRTP ((3 - 1) << 0); // tCKE } EMIFDDR_SDCR &= ~0x00008000; // Clear TIMUNLOCK // Let float -> integer truncate handle RR round-down; Safer to round down for refresh rate EMIFDDR_SDRCR = (0x1 << 31) | // LPMODEN (Required for LPSC SyncReset/Enable) (0x1 << 30) | // MCLKSTOPEN (Required for LPSC SyncReset/Enable) (0x0 << 24) | // Reserved (0x0 << 23) | // SR_PD (0x0 << 16) | // Reserved (((unsigned int) (7.8 * freq)) << 0); // RR (original 7.8125) // SyncReset the Clock to EMIFDDR SDRAM PSC1_LPSC_SyncReset(PD0, LPSC_DDR); // Enable the Clock to EMIFDDR SDRAM PSC1_LPSC_enable(PD0, LPSC_DDR); // Disable self-refresh EMIFDDR_SDRCR &= ~0xC0000000; // Set PBBPR to a value lower than default to prevent blocking EMIFDDR_PBBPR = 0x30; } /*SyncReset Function for PSC1*/ void PSC1_LPSC_SyncReset(unsigned int PD, unsigned int LPSC_num) { unsigned int j; if( (*(unsigned int*)(PSC1_MDSTAT+4 * LPSC_num) & 0x1F) != 0x1 ) { *(unsigned int*) (PSC1_MDCTL+4*LPSC_num) = (*(unsigned int*) (PSC1_MDCTL+4*LPSC_num) & 0xFFFFFFE0) | 0x0001; PSC1_PTCMD = 0x1<<PD; j = 0; /*Wait for power state transition to finish*/ while( (PSC1_PTSTAT & (0x1<<PD) ) !=0) { if( j++ > PSC_TIMEOUT ) { break; } } j = 0; while( (*(unsigned int*)(PSC1_MDSTAT+4 * LPSC_num) & 0x1F) !=0x1) { if( j++ > PSC_TIMEOUT ) { break; } } } } void PSC1_LPSC_enable(unsigned int PD, unsigned int LPSC_num) { unsigned int j; if( (*(unsigned int*)(PSC1_MDSTAT+4 * LPSC_num) & 0x1F) != 0x3 ) { *(unsigned int*) (PSC1_MDCTL+4*LPSC_num) = (*(unsigned int*) (PSC1_MDCTL+4*LPSC_num) & 0xFFFFFFE0) | 0x0003; PSC1_PTCMD = 0x1<<PD; j = 0; /*Wait for power state transition to finish*/ while( (PSC1_PTSTAT & (0x1<<PD) ) !=0) { if( j++ > PSC_TIMEOUT ) { break; } } j = 0; while( (*(unsigned int*)(PSC1_MDSTAT+4 * LPSC_num) & 0x1F) !=0x3) { if( j++ > PSC_TIMEOUT ) { break; } } } }

Viewing all articles
Browse latest Browse all 17527

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>