/* * LMK_ClockTree.c * * Created on: 2019��3��5�� * Author: TiferKing */ #include "LMK_ClockTree.h" __weak int LMK_ConfigMake(LMK_Config *DevConfig, LMK_Simple *SimpleConfig) { int i; u64 ChMaxRate; u64 VCORate; u64 PLL1CommonRate; u64 PLL2CommonRate; u64 RootDiv; //u64 PLLDiv; u8 VCOSelect; DevConfig->InterfaceInst = SimpleConfig->InterfaceInst; PLL1CommonRate = GreatestCommonDivisor(SimpleConfig->RefClockRate, SimpleConfig->VCOXClockRate); /*if(PLL1CommonRate > LMK_PLL1_LFBAND) { PLLDiv = PLL1CommonRate / LMK_PLL1_LFBAND; PLL1CommonRate /= PLLDiv + 1; }*/ if(PLL1CommonRate < 1000) { return XST_FAILURE; } ChMaxRate = 0; for(i = 0; i < 7; i++) { if(SimpleConfig->DClockRate[i] != 0) { if(ChMaxRate != 0) { ChMaxRate = LeastCommonMultiple(ChMaxRate, SimpleConfig->DClockRate[i]); } else { ChMaxRate = SimpleConfig->DClockRate[i]; } } } if(ChMaxRate == 0) { return XST_FAILURE; } if((LMK_VCO0_RATE_L / ChMaxRate) < (LMK_VCO0_RATE_H / ChMaxRate)) { RootDiv = (LMK_VCO0_RATE_L / ChMaxRate) + 1; VCORate = RootDiv * ChMaxRate; VCOSelect = 0; } else if((LMK_VCO1_RATE_L / ChMaxRate) < (LMK_VCO1_RATE_H / ChMaxRate)) { RootDiv = (LMK_VCO1_RATE_L / ChMaxRate) + 1; VCORate = RootDiv * ChMaxRate; VCOSelect = 1; } else { return XST_FAILURE; } PLL2CommonRate = GreatestCommonDivisor(VCORate, SimpleConfig->VCOXClockRate * 2) / 2; /*if(PLL2CommonRate > LMK_PLL2_LFBAND) { PLLDiv = PLL2CommonRate / LMK_PLL2_LFBAND; PLL2CommonRate /= PLLDiv + 1; }*/ if(PLL2CommonRate < 1000) { return XST_FAILURE; } // Fixed Register Set DevConfig->Config.Fixed_0 = 0x7F; DevConfig->Config.Fixed_1 = 0x01; DevConfig->Config.Fixed_2 = 0xAA; DevConfig->Config.Fixed_3 = 0x02; // Calculate Register Value DevConfig->Config.OSCout_FMT = 0x00; DevConfig->Config.OSCout_MUX = 0; DevConfig->Config.VCO_MUX = VCOSelect; DevConfig->Config.SYSREF_MUX = 3; DevConfig->Config.SYSREF_CLKin0_MUX = 0; DevConfig->Config.SYSREF_DIVH = (VCORate / SimpleConfig->SYSREFRate) >> 8; DevConfig->Config.SYSREF_DIVL = (VCORate / SimpleConfig->SYSREFRate) & 0xFF; DevConfig->Config.SYSREF_DDLYH = 0; DevConfig->Config.SYSREF_DDLYL = 8; DevConfig->Config.SYSREF_PULSE_CNT = 0x03; DevConfig->Config.FB_MUX_EN = 0; DevConfig->Config.FB_MUX = 0; DevConfig->Config.PLL1_NCLK_MUX = 0; DevConfig->Config.PLL2_NCLK_MUX = 0; DevConfig->Config.SYSREF_PLSR_PD = 1; DevConfig->Config.SYSREF_DDLY_PD = 0; DevConfig->Config.SYSREF_PD = 1; DevConfig->Config.SYSREF_GBL_PD = 0; DevConfig->Config.OSCin_PD = 0; DevConfig->Config.VCO_PD = 0; DevConfig->Config.VCO_LDO_PD = 0; DevConfig->Config.PLL1_PD = 0; DevConfig->Config.DDLYd0_EN = 0; DevConfig->Config.DDLYd2_EN = 0; DevConfig->Config.DDLYd4_EN = 0; DevConfig->Config.DDLYd6_EN = 0; DevConfig->Config.DDLYd8_EN = 0; DevConfig->Config.DDLYd10_EN = 0; DevConfig->Config.DDLYd12_EN = 0; DevConfig->Config.DDLYd0_SYSREF_EN = 0; DevConfig->Config.DDLYd_STEP_CNT = 0; DevConfig->Config.SYNC_MODE = 1; DevConfig->Config.SYNC_PLL1_DLD = 0; DevConfig->Config.SYNC_PLL2_DLD = 0; DevConfig->Config.SYNC_EN = 1; DevConfig->Config.SYNC_POL = 0; DevConfig->Config.SYNC_1SHOT_EN = 0; DevConfig->Config.SYSREF_CLR = 1; DevConfig->Config.SYNC_DIS0 = 1; DevConfig->Config.SYNC_DIS2 = 1; DevConfig->Config.SYNC_DIS4 = 1; DevConfig->Config.SYNC_DIS6 = 1; DevConfig->Config.SYNC_DIS8 = 1; DevConfig->Config.SYNC_DIS10 = 1; DevConfig->Config.SYNC_DIS12 = 1; DevConfig->Config.SYNC_DISSYSREF = 1; DevConfig->Config.CLKin0_TYPE = 0; DevConfig->Config.CLKin1_TYPE = 0; DevConfig->Config.CLKin2_TYPE = 0; DevConfig->Config.CLKin0_EN = 0; DevConfig->Config.CLKin1_EN = 0; DevConfig->Config.CLKin2_EN = 0; DevConfig->Config.CLKin0_OUT_MUX = 3; DevConfig->Config.CLKin1_OUT_MUX = 3; DevConfig->Config.CLKin_SEL_MODE = 2; DevConfig->Config.CLKin_SEL_POL = 0; DevConfig->Config.CLKin_SEL0_TYPE = 3; DevConfig->Config.CLKin_SEL0_MUX = 6; DevConfig->Config.CLKin_SEL1_TYPE = 0; DevConfig->Config.CLKin_SEL1_MUX = 0; DevConfig->Config.SDIO_RDBK_TYPE = 0; DevConfig->Config.RESET_TYPE = 2; DevConfig->Config.RESET_MUX = 0; DevConfig->Config.MAN_DACH = 2; DevConfig->Config.MAN_DAC_EN = 1; DevConfig->Config.HOLDOVER_FORCE = 0; DevConfig->Config.TRACK_EN = 1; DevConfig->Config.LOS_EN = 0; DevConfig->Config.LOS_TIMEOUT = 0; DevConfig->Config.MAN_DACL = 0; DevConfig->Config.DAC_TRIP_LOW = 0; DevConfig->Config.DAC_TRIP_HIGH = 0; DevConfig->Config.DAC_CLK_MULT = 0; DevConfig->Config.DAC_CLK_CNTR = 0x7F; DevConfig->Config.HOLDOVER_EN = 1; DevConfig->Config.HOLDOVER_HITLESS_SW = 1; DevConfig->Config.HOLDOVER_VTUNE_DET = 0; DevConfig->Config.HOLDOVER_LOS_DET = 0; DevConfig->Config.HOLDOVER_PLL1_DET = 0; DevConfig->Config.CLKin_OVERRIDE = 0; DevConfig->Config.HOLDOVER_DLD_CNTH = 2; DevConfig->Config.HOLDOVER_DLD_CNTL = 0; DevConfig->Config.CLKin0_RH = 0; DevConfig->Config.CLKin0_RL = 120; DevConfig->Config.CLKin1_RH = 0; DevConfig->Config.CLKin1_RL = 150; DevConfig->Config.CLKin2_RH = (SimpleConfig->RefClockRate / PLL1CommonRate) >> 8; DevConfig->Config.CLKin2_RL = (SimpleConfig->RefClockRate / PLL1CommonRate) & 0xFF; DevConfig->Config.PLL1_NH = (SimpleConfig->VCOXClockRate / PLL1CommonRate) >> 8; DevConfig->Config.PLL1_NL = ((SimpleConfig->VCOXClockRate / PLL1CommonRate) & 0xFF); DevConfig->Config.PLL1_CP_GAIN = 15; DevConfig->Config.PLL1_CP_POL = 1; DevConfig->Config.PLL1_CP_TRI = 0; DevConfig->Config.PLL1_WND_SIZE = 3; DevConfig->Config.PLL1_DLD_CNTH = 32; DevConfig->Config.PLL1_DLD_CNTL = 0; DevConfig->Config.PLL1_N_DLY = 0; DevConfig->Config.PLL1_R_DLY = 0; DevConfig->Config.PLL1_LD_TYPE = 3; DevConfig->Config.PLL1_LD_MUX = 1; DevConfig->Config.PLL2_RH = (SimpleConfig->VCOXClockRate / PLL2CommonRate) >> 8; DevConfig->Config.PLL2_RL = (SimpleConfig->VCOXClockRate / PLL2CommonRate) & 0xFF; DevConfig->Config.PLL2_REF_2X_EN = 0; DevConfig->Config.PLL2_XTAL_EN = 0; DevConfig->Config.OSCin_FREQ = 4; DevConfig->Config.PLL2_P = 2; DevConfig->Config.PLL2_N_CALH = 0; DevConfig->Config.PLL2_N_CALM = 0; DevConfig->Config.PLL2_N_CALL = 12; DevConfig->Config.PLL2_NH = ((VCORate / PLL2CommonRate / 2) >> 16) & 0xFF; DevConfig->Config.PLL2_FCAL_DIS = 0; DevConfig->Config.PLL2_NM = ((VCORate / PLL2CommonRate / 2) >> 8) & 0xFF; DevConfig->Config.PLL2_NL = (VCORate / PLL2CommonRate / 2) & 0xFF; DevConfig->Config.PLL2_CP_TRI = 0; DevConfig->Config.PLL2_CP_POL = 0; DevConfig->Config.PLL2_CP_GAIN = 3; DevConfig->Config.PLL2_WND_SIZE = 2; DevConfig->Config.PLL2_DLD_CNTH = 32; DevConfig->Config.SYSREF_REQ_EN = 1; DevConfig->Config.PLL2_DLD_CNTL = 0; DevConfig->Config.PLL2_LF_R3 = 0; DevConfig->Config.PLL2_LF_R4 = 0; DevConfig->Config.PLL2_LF_C3 = 0; DevConfig->Config.PLL2_LF_C4 = 0; DevConfig->Config.PLL2_LD_TYPE = 3; DevConfig->Config.PLL2_LD_MUX = 2; DevConfig->Config.PLL2_PD = 0; DevConfig->Config.PLL2_PRE_PD = 0; DevConfig->Config.VCO1_DIV = 0; for(i = 0; i < 7; i++) { if(VCORate / SimpleConfig->DClockRate[i] != 0) { DevConfig->Config.Clock[i].DCLKout_Div = VCORate / SimpleConfig->DClockRate[i]; DevConfig->Config.Clock[i].CLKout_IDL = 0; DevConfig->Config.Clock[i].CLKout_ODL = 0; DevConfig->Config.Clock[i].DCLKout_DDLY_CNTL = 2; DevConfig->Config.Clock[i].DCLKout_DDLY_CNTH = 2; DevConfig->Config.Clock[i].DCLKout_MUX = 1; DevConfig->Config.Clock[i].DCLKout_ADLY_MUX = 1; DevConfig->Config.Clock[i].DCLKout_ALDY = 0; DevConfig->Config.Clock[i].SDCLKout_HS = 0; DevConfig->Config.Clock[i].SDCLKout_DDLY = 0; DevConfig->Config.Clock[i].SDCLKout_MUX = 1; DevConfig->Config.Clock[i].DCLKout_HS = 0; DevConfig->Config.Clock[i].SDCLK_ADLY = 0; DevConfig->Config.Clock[i].SDCLKout_ADLY_EN = 0; DevConfig->Config.Clock[i].SDCLKout_PD = 0; DevConfig->Config.Clock[i].SDCLKout_DIS_MODE = 0; DevConfig->Config.Clock[i].CLKout_PD = 0; DevConfig->Config.Clock[i].DCLKout_ADLY_PD = 1; DevConfig->Config.Clock[i].DCLKout_ADLYg_PD = 1; DevConfig->Config.Clock[i].DCLKout_HSg_PD = 0; DevConfig->Config.Clock[i].DCLKout_DDLY_PD = 0; DevConfig->Config.Clock[i].DCLKout_FMT = 1; DevConfig->Config.Clock[i].DCLKout_POL = 0; DevConfig->Config.Clock[i].SDCLKout_FMT = 1; DevConfig->Config.Clock[i].SDCLKout_POL = 0; } else { DevConfig->Config.Clock[i].DCLKout_Div = 0; DevConfig->Config.Clock[i].CLKout_IDL = 0; DevConfig->Config.Clock[i].CLKout_ODL = 0; DevConfig->Config.Clock[i].DCLKout_DDLY_CNTL = 5; DevConfig->Config.Clock[i].DCLKout_DDLY_CNTH = 5; DevConfig->Config.Clock[i].DCLKout_MUX = 1; DevConfig->Config.Clock[i].DCLKout_ADLY_MUX = 1; DevConfig->Config.Clock[i].DCLKout_ALDY = 0; DevConfig->Config.Clock[i].SDCLKout_HS = 0; DevConfig->Config.Clock[i].SDCLKout_DDLY = 0; DevConfig->Config.Clock[i].SDCLKout_MUX = 1; DevConfig->Config.Clock[i].DCLKout_HS = 0; DevConfig->Config.Clock[i].SDCLK_ADLY = 0; DevConfig->Config.Clock[i].SDCLKout_ADLY_EN = 0; DevConfig->Config.Clock[i].SDCLKout_PD = 1; DevConfig->Config.Clock[i].SDCLKout_DIS_MODE = 0; DevConfig->Config.Clock[i].CLKout_PD = 1; DevConfig->Config.Clock[i].DCLKout_ADLY_PD = 1; DevConfig->Config.Clock[i].DCLKout_ADLYg_PD = 1; DevConfig->Config.Clock[i].DCLKout_HSg_PD = 1; DevConfig->Config.Clock[i].DCLKout_DDLY_PD = 1; DevConfig->Config.Clock[i].DCLKout_FMT = 0; DevConfig->Config.Clock[i].DCLKout_POL = 0; DevConfig->Config.Clock[i].SDCLKout_FMT = 0; DevConfig->Config.Clock[i].SDCLKout_POL = 0; } } LMK_ConfigCustomize(DevConfig); return XST_SUCCESS; } __weak int LMK_ConfigCustomize(LMK_Config *DevConfig) { UNUSED(DevConfig); return XST_FAILURE; } int LMK_Init(LMK_Config *DevConfig) { int i; uint8_t tmp; uint8_t ld1, ld2; //Unlock SPI Register //LMK_WriteReg(DevConfig, 0x1FFD, 0); //LMK_WriteReg(DevConfig, 0x1FFE, 0); //LMK_WriteReg(DevConfig, 0x1FFF, 83); LMK_RegUnlock(DevConfig); //Reset Register LMK_WriteReg(DevConfig, 0x000, 0x80); //4-wire SPI LMK_WriteReg(DevConfig, 0x000, 0x10); //Reserved Register //LMK_WriteReg(DevConfig, 0x145, 0x7F); //LMK_WriteReg(DevConfig, 0x171, 0xAA); //LMK_WriteReg(DevConfig, 0x172, 0x02); //LMK_WriteReg(DevConfig, 0x17C, 21); //LMK_WriteReg(DevConfig, 0x17D, 51); //Sequence Program for(i = 0; i < sizeof(DevConfig->Config); i++) { LMK_WriteReg(DevConfig, 0x100 + i, ((u8*)(&DevConfig->Config))[i]); } tmp = 1; while(tmp) { LMK_ReadReg(DevConfig, 0x182, &ld1); LMK_ReadReg(DevConfig, 0x183, &ld2); tmp = (ld1 & 0x02) & (ld2 & 0x02) == 0x02 ? 1 : 0; } //Enable SYSREF LMK_WriteReg(DevConfig, 0x140, 0xFB & ((u8*)(&DevConfig->Config))[0x040]); //SYSREF_PD = 0 LMK_WriteReg(DevConfig, 0x143, 0x7F & ((u8*)(&DevConfig->Config))[0x043]); //SYSREF_CLR = 0 /*LMK_WriteReg(DevConfig, 0x143, 0x80 | ((u8*)(&DevConfig->Config))[0x043]); //SYSREF_CLR = 1 LMK_WriteReg(DevConfig, 0x144, 0x00); LMK_WriteReg(DevConfig, 0x143, 0x20 | ((u8*)(&DevConfig->Config))[0x043]); //SYNC_POL = 1 LMK_WriteReg(DevConfig, 0x143, 0xDF & ((u8*)(&DevConfig->Config))[0x043]); //SYNC_POL = 0 LMK_WriteReg(DevConfig, 0x144, 0xFF); LMK_WriteReg(DevConfig, 0x143, 0x7F & ((u8*)(&DevConfig->Config))[0x043]); //SYSREF_CLR = 0 LMK_WriteReg(DevConfig, 0x139, ((u8*)(&DevConfig->Config))[0x039]); //SYSREF_MUX*/ LMK_RegLock(DevConfig); //Lock SPI Register //LMK_WriteReg(DevConfig, 0x1FFD, 255); //LMK_WriteReg(DevConfig, 0x1FFE, 255); //LMK_WriteReg(DevConfig, 0x1FFF, 255); return XST_SUCCESS; } int LMK_StatusRead(LMK_Config *DevConfig) { return XST_SUCCESS; } int LMK_RegLock(LMK_Config *DevConfig) { LMK_WriteReg(DevConfig, 0x1FFD, 255); LMK_WriteReg(DevConfig, 0x1FFE, 255); LMK_WriteReg(DevConfig, 0x1FFF, 255); return XST_SUCCESS; } int LMK_RegUnlock(LMK_Config *DevConfig) { LMK_WriteReg(DevConfig, 0x1FFD, 0); LMK_WriteReg(DevConfig, 0x1FFE, 0); LMK_WriteReg(DevConfig, 0x1FFF, 83); return XST_SUCCESS; } #include "xspips.h" int LMK_WriteReg(LMK_Config *DevConfig, u16 RegisterAddress, u8 Value) { u8 buf[3]; buf[0] = 0x0 | ((RegisterAddress >> 8) & 0x1F); buf[1] = RegisterAddress & 0xFF; buf[2] = Value; XSpiPs_SetSlaveSelect((XSpiPs *)DevConfig->InterfaceInst, 0x00); XSpiPs_PolledTransfer((XSpiPs *)DevConfig->InterfaceInst, buf, NULL, 3); XSpiPs_SetSlaveSelect((XSpiPs *)DevConfig->InterfaceInst, 0x0F); return XST_SUCCESS; } int LMK_ReadReg(LMK_Config *DevConfig, u16 RegisterAddress, u8 *Value) { u8 buf[3]; buf[0] = 0x80 | ((RegisterAddress >> 8) & 0x1F); buf[1] = RegisterAddress & 0xFF; buf[2] = 0; XSpiPs_SetSlaveSelect((XSpiPs *)DevConfig->InterfaceInst, 0x00); XSpiPs_PolledTransfer((XSpiPs *)DevConfig->InterfaceInst, buf, buf, 3); XSpiPs_SetSlaveSelect((XSpiPs *)DevConfig->InterfaceInst, 0x0F); *Value = buf[2]; return XST_SUCCESS; }