/******************************************************************************* * mvUsbPllInit - Initialize USB PLL * * DESCRIPTION: * This function initialize USB PLL * * INPUT: * None. * * OUTPUT: * None. * * RETURN: * MV_ERROR if setting fail. *******************************************************************************/ MV_STATUS mvUsbPllInit() { MV_U32 regVal; /******* Setup PLL frequency *******/ regVal = MV_REG_READ(MV_USB_PHY_PLL_REG(1)); regVal &= ~(0x3FF); regVal |= 0x605; /* USB REF frequency = 25 MHz */ MV_REG_WRITE(MV_USB_PHY_PLL_REG(1), regVal); /******* Power up PLL and PHY channel *******/ regVal = MV_REG_READ(MV_USB_PHY_PLL_REG(2)); regVal |= BIT9; MV_REG_WRITE(MV_USB_PHY_PLL_REG(2), regVal); /******* Assert VCOCAL_START *******/ regVal = MV_REG_READ(MV_USB_PHY_PLL_REG(1)); regVal |= BIT21; MV_REG_WRITE(MV_USB_PHY_PLL_REG(1), regVal); /* Wait 1 msec */ mvOsUDelay(1000); return 0; }
/* USB Phy init (change from defaults) specific for 40nm (78X30 78X60) */ static int mvUsbPhy40nmInit(int dev) { MV_U32 regVal; regVal = MV_REG_READ(MV_USB_PHY_CHANNEL_REG(dev, 3)); regVal |= BIT15; MV_REG_WRITE(MV_USB_PHY_CHANNEL_REG(dev, 3), regVal); /*-------------------------------------------------*/ /******* Assert REG_RCAL_START in Channel REG 1 *******/ regVal = MV_REG_READ(MV_USB_PHY_CHANNEL_REG(dev, 1)); regVal |= BIT12; MV_REG_WRITE(MV_USB_PHY_CHANNEL_REG(dev, 1), regVal); /* Wait 40 usec */ mvOsUDelay(40); regVal = MV_REG_READ(MV_USB_PHY_CHANNEL_REG(dev, 1)); regVal &= ~BIT12; MV_REG_WRITE(MV_USB_PHY_CHANNEL_REG(dev, 1), regVal); /*-------------------------------------------------*/ /* BTS #231 - for KW40 only */ if (usbHalData.ctrlFamily==MV_67XX) { MV_REG_WRITE(0x50850, 0x20000131); MV_REG_WRITE(0x50890, 0x20000131); } return 0; } /* End of mvUsbPhy40nmInit() */
/******************************************************************************* * mvAc97Reset * * DESCRIPTION: * Cold reset the AC'97 unit. * * INPUT: * None. * * OUTPUT: * None. * * RETURN: * MV_OK - On successfull init, * MV_FAIL - If initialization fails. *******************************************************************************/ MV_STATUS mvAc97Reset(MV_VOID) { //MV_U32 timeout = 1000; /* Hold CLKBPB for 100us */ MV_REG_BIT_RESET(MV_AC97_GLOBAL_CTRL_REG,AC97_GLB_CTRL_COLD_RESET_MASK); MV_REG_BIT_SET(MV_AC97_GLOBAL_CTRL_REG,AC97_GLB_CTRL_INT_CLK_EN_MASK); mvOsUDelay(100); MV_REG_BIT_RESET(MV_AC97_GLOBAL_CTRL_REG,AC97_GLB_CTRL_INT_CLK_EN_MASK); MV_REG_BIT_SET(MV_AC97_GLOBAL_CTRL_REG,AC97_GLB_CTRL_COLD_RESET_MASK); #if 0 /* Not sure if this is needed. */ MV_REG_BIT_SET(MV_AC97_GLOBAL_CTRL_REG, AC97_GLB_CTRL_COLD_RESET_MASK | AC97_GLB_CTRL_WARM_RESET_MASK); while(timeout > 0) { val = MV_REG_READ(MV_AC97_GLOBAL_STATUS_REG); if(val & (AC97_GLB_PCODEC_READY_MASK | AC97_GLB_SCODEC_READY_MASK)) break; timeout--; mvOsDelay(10); } if(timeout == 0) return MV_TIMEOUT; #endif /* 0 */ return MV_OK; }
/******************************************************************************* * mvNflashIdGet - Get Flash device and vendor ID. * * DESCRIPTION: * This function gets Flash device and vendor ID. * * INPUT: * pFlash - flash information. * * OUTPUT: * None * * RETURN: * None * *******************************************************************************/ MV_U16 mvNflashIdGet(MV_NFLASH_INFO *pFlash) { MV_U8 venId; MV_U8 devId; mvNflashCommandSet(&pFlash->nflashHwIf, READ_ID); mvNflashAddrSet(&pFlash->nflashHwIf, 0x00); /* Wait for Tr. */ mvOsUDelay(NFLASH_tAR_DELAY); mvNflash8bitDataGet(&pFlash->nflashHwIf, (void*)&venId, 1); mvNflash8bitDataGet(&pFlash->nflashHwIf, (void*)&devId, 1); return ((venId << VENDOR_ID_OFFS) | (devId << DEVICE_ID_OFFS)) & 0xFFFF; }
/******************************************************************************* * mvUsbHalInit - Initialize USB engine * * DESCRIPTION: * This function initialize USB unit. It set the default address decode * windows of the unit. * * INPUT: * None. * * OUTPUT: * None. * * RETURN: * MV_ERROR if setting fail. *******************************************************************************/ MV_STATUS mvUsbHalInit(int dev, MV_BOOL isHost, MV_USB_HAL_DATA *halData) { MV_U32 regVal; MV_STATUS status = MV_OK; mvOsMemcpy(&usbHalData, halData, sizeof(MV_USB_HAL_DATA)); /* Wait 100 usec */ mvOsUDelay(100); /* Clear Interrupt Cause and Mask registers */ MV_REG_WRITE(MV_USB_BRIDGE_INTR_CAUSE_REG(dev), 0); MV_REG_WRITE(MV_USB_BRIDGE_INTR_MASK_REG(dev), 0); /* Reset controller */ regVal = MV_REG_READ(MV_USB_CORE_CMD_REG(dev)); MV_REG_WRITE(MV_USB_CORE_CMD_REG(dev), regVal | MV_USB_CORE_CMD_RESET_MASK); while (MV_REG_READ(MV_USB_CORE_CMD_REG(dev)) & MV_USB_CORE_CMD_RESET_MASK) ; /* Clear bit 4 in USB bridge control register for enableing core byte swap */ if ((usbHalData.ctrlModel == MV64560_DEV_ID) || (usbHalData.ctrlModel == MV64660_DEV_ID)) { MV_REG_WRITE(MV_USB_BRIDGE_CTRL_REG(dev), (MV_REG_READ(MV_USB_BRIDGE_CTRL_REG(dev)) & ~MV_USB_BRIDGE_CORE_BYTE_SWAP_MASK)); } /* GL# USB-10 */ /* The new register 0x360 USB 2.0 IPG Metal Fix Register * dont' exists in the following chip revisions: * OrionN B1 (id=0x5180, rev 3) * Orion1 B1 (id=0x5181, rev=3) and before * Orion1-VoIP A0 (id=0x5181, rev=8) * Orion1-NAS A1 (id=0x5182, rev=1) and before * Orion2 B0 (id=0x5281, rev=1) and before */ if (((usbHalData.ctrlModel == MV_5181_DEV_ID) && ((usbHalData.ctrlRev <= MV_5181_B1_REV) || (usbHalData.ctrlRev == MV_5181L_A0_REV))) || ((usbHalData.ctrlModel == MV_5182_DEV_ID) && (usbHalData.ctrlRev <= MV_5182_A1_REV)) || ((usbHalData.ctrlModel == MV_5180_DEV_ID) && (usbHalData.ctrlRev <= MV_5180N_B1_REV))) { /* Do nothing */ } else if ((usbHalData.ctrlModel == MV_6510_DEV_ID) || (usbHalData.ctrlModel == MV_6530_DEV_ID) || (usbHalData.ctrlModel == MV_6550_DEV_ID) || (usbHalData.ctrlModel == MV_6560_DEV_ID)) { /* Change value of new register 0x360 */ regVal = MV_REG_READ(MV_USB_BRIDGE_IPG_REG(dev)); /* Change bits[14:8] - IPG for non Start of Frame Packets * from 0x9(default) to 0xD */ regVal &= ~(0x7F << 8); regVal |= (0xD << 8); MV_REG_WRITE(MV_USB_BRIDGE_IPG_REG(dev), regVal); } else { /* Change value of new register 0x360 */ regVal = MV_REG_READ(MV_USB_BRIDGE_IPG_REG(dev)); /* Change bits[14:8] - IPG for non Start of Frame Packets * from 0x9(default) to 0xD */ regVal &= ~(0x7F << 8); regVal |= (0xD << 8); MV_REG_WRITE(MV_USB_BRIDGE_IPG_REG(dev), regVal); } #ifndef MV_USB_PHY_DONT_OVERRIDE /********* Update USB PHY configuration **********/ if ((usbHalData.ctrlModel == MV_78100_DEV_ID) || (usbHalData.ctrlModel == MV_78200_DEV_ID) || (usbHalData.ctrlModel == MV_76100_DEV_ID) || (usbHalData.ctrlModel == MV_6281_DEV_ID) || (usbHalData.ctrlModel == MV_6282_DEV_ID) || (usbHalData.ctrlModel == MV_6280_DEV_ID) || (usbHalData.ctrlModel == MV_6192_DEV_ID) || (usbHalData.ctrlModel == MV_6190_DEV_ID) || (usbHalData.ctrlModel == MV_6180_DEV_ID) || (usbHalData.ctrlModel == MV_6321_DEV_ID) || (usbHalData.ctrlModel == MV_6322_DEV_ID) || (usbHalData.ctrlModel == MV_6323_DEV_ID)) { mvUsbPhy65nmNewInit(dev); } else if ((usbHalData.ctrlModel == MV_78XX0_DEV_ID)) { mvUsbPhy65nmInit(dev); } else if (usbHalData.ctrlModel == MV_6183_DEV_ID) { mvUsbPhy90nmInit(dev); } else if ((usbHalData.ctrlModel == MV_6510_DEV_ID) || (usbHalData.ctrlModel == MV_6530_DEV_ID) || (usbHalData.ctrlModel == MV_6550_DEV_ID) || (usbHalData.ctrlModel == MV_6560_DEV_ID)) { mvUsbPhy65nmNewInit(dev); /* mvUsbPhyKW6500Init(dev); */ } else if ((usbHalData.ctrlFamily==MV_67XX) || (usbHalData.ctrlFamily==MV_78XX0)) { if (mvUsbPhy40nmInit(dev)) status = MV_NOT_READY; } else mvUsbPhyInit(dev); #endif /* Set Mode register (Stop and Reset USB Core before) */ /* Stop the controller */ regVal = MV_REG_READ(MV_USB_CORE_CMD_REG(dev)); regVal &= ~MV_USB_CORE_CMD_RUN_MASK; MV_REG_WRITE(MV_USB_CORE_CMD_REG(dev), regVal); /* Reset the controller to get default values */ regVal = MV_REG_READ(MV_USB_CORE_CMD_REG(dev)); regVal |= MV_USB_CORE_CMD_RESET_MASK; MV_REG_WRITE(MV_USB_CORE_CMD_REG(dev), regVal); /* Wait for the controller reset to complete */ do { regVal = MV_REG_READ(MV_USB_CORE_CMD_REG(dev)); } while (regVal & MV_USB_CORE_CMD_RESET_MASK); /* Set USB_MODE register */ if (isHost) regVal = MV_USB_CORE_MODE_HOST; else regVal = MV_USB_CORE_MODE_DEVICE | MV_USB_CORE_SETUP_LOCK_DISABLE_MASK; #if (MV_USB_VERSION == 0) regVal |= MV_USB_CORE_STREAM_DISABLE_MASK; #endif MV_REG_WRITE(MV_USB_CORE_MODE_REG(dev), regVal); return status; }
/* USB Phy init (change from defaults) for 150nm chips: * - 645xx, 646xx * - 51xx, 52xx * - 6082 */ static void mvUsbPhyInit(int dev) { MV_U32 regVal; /* GL# USB-9 */ /******* USB 2.0 Power Control Register 0x400 *******/ regVal = MV_REG_READ(MV_USB_PHY_POWER_CTRL_REG(dev)); /* Bits 7:6 (BG_VSEL) = 0x1 */ regVal &= ~(0x3 << 6); regVal |= (0x1 << 6); MV_REG_WRITE(MV_USB_PHY_POWER_CTRL_REG(dev), regVal); /******* USB PHY PLL Control Register 0x410 *******/ regVal = MV_REG_READ(MV_USB_PHY_PLL_CTRL_REG(dev)); /* bit[21] (VCOCAL_ START) */ regVal |= (0x1 << 21); MV_REG_WRITE(MV_USB_PHY_PLL_CTRL_REG(dev), regVal); /* Wait 500 usec */ mvOsUDelay(500); regVal &= ~(0x1 << 21); MV_REG_WRITE(MV_USB_PHY_PLL_CTRL_REG(dev), regVal); /*-------------------------------------------------*/ /* GL# USB-1 */ /******* USB PHY Tx Control Register Register 0x420 *******/ regVal = MV_REG_READ(MV_USB_PHY_TX_CTRL_REG(dev)); if ((usbHalData.ctrlModel == MV_5181_DEV_ID) && (usbHalData.ctrlRev <= MV_5181_A1_REV)) { /* For OrionI A1/A0 rev: Bit[21] = 0 (TXDATA_BLOCK_EN = 0). */ regVal &= ~(1 << 21); } else { regVal |= (1 << 21); } /* Force Auto calibration */ /* Bit[13] = 0x1, (REG_EXT_RCAL_EN = 0x1) */ regVal |= (1 << 13); /* Bits[2:0] (TxAmp) * 64560, 64660, 6082, 5181, 5182, etc = 0x4 * 5281 = 0x3 */ if (usbHalData.ctrlModel == MV_5281_DEV_ID) { regVal &= ~(0x7 << 0); regVal |= (0x3 << 0); } else { regVal &= ~(0x7 << 0); regVal |= (0x4 << 0); } /* Bit[6:3] (IMP_CAL) * 64560, 64660 = 0xA * Others = 0x8 * */ regVal &= ~(0xf << 3); if ((usbHalData.ctrlModel == MV64560_DEV_ID) || (usbHalData.ctrlModel == MV64660_DEV_ID)) regVal |= (0xA << 3); else regVal |= (0x8 << 3); MV_REG_WRITE(MV_USB_PHY_TX_CTRL_REG(dev), regVal); mvOsUDelay(500); /* GL# USB-3 GL# USB-9 */ /******* USB PHY Rx Control Register 0x430 *******/ regVal = MV_REG_READ(MV_USB_PHY_RX_CTRL_REG(dev)); /* bit[8:9] - (DISCON_THRESHOLD ). */ /* 88F5181-A0/A1/B0 = 11, 88F5281-A0 = 10, all other 00 */ /* 64660-A0 = 10 */ regVal &= ~(0x3 << 8); if ((usbHalData.ctrlModel == MV_5181_DEV_ID) && (usbHalData.ctrlRev <= MV_5181_B0_REV)) regVal |= (0x3 << 8); else if (usbHalData.ctrlModel == MV64660_DEV_ID) regVal |= (0x2 << 8); /* bit[21] = 0 (CDR_FASTLOCK_EN = 0). */ regVal &= ~(1 << 21); /* bit[27:26] = 00 ( EDGE_DET_SEL = 00). */ regVal &= ~(0x3 << 26); /* Bits[31:30] = RXDATA_BLOCK_LENGHT = 0x3 */ regVal |= (0x3 << 30); /* Bits 7:4 (SQ_THRESH) * 64560, 64660 = 0x1 * 5181, 5182, 5281, 6082, etc = 0x0 */ regVal &= ~(0xf << 4); if ((usbHalData.ctrlModel == MV64560_DEV_ID) || (usbHalData.ctrlModel == MV64660_DEV_ID)) regVal |= (0x1 << 4); else regVal |= (0x3 << 4); MV_REG_WRITE(MV_USB_PHY_RX_CTRL_REG(dev), regVal); /* GL# USB-3 GL# USB-9 */ /******* USB PHY IVREF Control Register 0x440 *******/ regVal = MV_REG_READ(MV_USB_PHY_IVREF_CTRL_REG(dev)); /*Bits[1:0] = 0x2 (PLLVDD12 = 0x2) */ regVal &= ~(0x3 << 0); regVal |= (0x2 << 0); /* Bits 5:4 (RXVDD) = 0x3; */ regVal &= ~(0x3 << 4); regVal |= (0x3 << 4); /* <VPLLCAL> bits[17:16] = 0x1 */ if ((usbHalData.ctrlModel == MV64560_DEV_ID) || (usbHalData.ctrlModel == MV64660_DEV_ID)) { regVal &= ~(0x3 << 16); regVal |= (0x1 << 16); } /* <ISAMPLE_SEL> bits[19:18] = 0x2 */ regVal &= ~(0x3 << 18); regVal |= (0x2 << 18); /* <SAMPLER_CTRL> bit[20] = 0x0 */ regVal &= ~(0x1 << 20); /* <ICHGPBUF_SEL> bit[21] = 0x1 */ regVal |= (0x1 << 21); MV_REG_WRITE(MV_USB_PHY_IVREF_CTRL_REG(dev), regVal); /***** USB PHY TEST GROUP CONTROL Register: 0x450 *****/ regVal = MV_REG_READ(MV_USB_PHY_TEST_GROUP_CTRL_REG_0(dev)); /* bit[15] = 0 (REG_FIFO_SQ_RST = 0). */ regVal &= ~(1 << 15); /* <REG_FIFO_OVUF_SEL> bit[17] = 0x1 */ if ((usbHalData.ctrlModel == MV64560_DEV_ID) || (usbHalData.ctrlModel == MV64660_DEV_ID)) regVal |= (1 << 17); MV_REG_WRITE(MV_USB_PHY_TEST_GROUP_CTRL_REG_0(dev), regVal); }
/* USB Phy init (change from defaults) specific for 90nm (6183 and later) */ static void mvUsbPhy90nmInit(int dev) { MV_U32 regVal; /******* USB 2.0 Power Control Register 0x400 *******/ regVal = MV_REG_READ(MV_USB_PHY_POWER_CTRL_REG(dev)); /* Bits 7:6 (BG_VSEL) = 0x0 */ regVal &= ~(0x3 << 6); MV_REG_WRITE(MV_USB_PHY_POWER_CTRL_REG(dev), regVal); /*-------------------------------------------------*/ /******* USB PHY PLL Control Register 0x410 *******/ regVal = MV_REG_READ(MV_USB_PHY_PLL_CTRL_REG(dev)); /* bit[21] (VCOCAL_ START) */ regVal |= (0x1 << 21); MV_REG_WRITE(MV_USB_PHY_PLL_CTRL_REG(dev), regVal); /* Wait 500 usec */ mvOsUDelay(500); regVal &= ~(0x1 << 21); MV_REG_WRITE(MV_USB_PHY_PLL_CTRL_REG(dev), regVal); /*-------------------------------------------------*/ /******* USB PHY Tx Control Register Register 0x420 *******/ regVal = MV_REG_READ(MV_USB_PHY_TX_CTRL_REG(dev)); /* bit[21] (TX_BLK_EN) = 0 for B0 only */ if ((usbHalData.ctrlModel == MV_6183_DEV_ID)) regVal &= ~(0x1 << 21); /* Force Auto calibration */ /* Bit[13] = 0x1, (REG_EXT_RCAL_EN = 0x1) */ regVal |= (0x1 << 13); /* bit[11] (LOWVDD_EN) = 1 */ regVal |= (0x1 << 11); /* Bit[6:3] (IMP_CAL) = 0x8 for A0 and B0 */ /* Bit[6:3] (IMP_CAL) = 0xf for A1 */ regVal &= ~(0xf << 3); regVal |= (0x8 << 3); if ((usbHalData.ctrlModel == MV_6183_DEV_ID)) { regVal &= ~(0x7); regVal |= (0x4); } MV_REG_WRITE(MV_USB_PHY_TX_CTRL_REG(dev), regVal); /* Wait 500 usec */ mvOsUDelay(500); /*-------------------------------------------------*/ /******* USB PHY Rx Control Register 0x430 *******/ regVal = MV_REG_READ(MV_USB_PHY_RX_CTRL_REG(dev)); /* bits[3:2] LPF_COEF = 0x0 */ regVal &= ~(0x3 << 2); /* bits[7:4] SQ_THRESH = 0x0 */ /* bits[7:4] SQ_THRESH = 0x3 for A1 and above */ regVal &= ~(0xf << 4); /* bits[16:15] REG_SQ_LENGTH = 0x1 */ regVal &= ~(0x3 << 15); regVal |= (0x1 << 15); /* bit[21] CDR_FASTLOCK_EN = 0x0 */ regVal &= ~(0x1 << 21); /* bits[27:26] EDGE_DET_SEL = 0x0 */ regVal &= ~(0x3 << 26); MV_REG_WRITE(MV_USB_PHY_RX_CTRL_REG(dev), regVal); /*-------------------------------------------------*/ /******* USB PHY IVREF Control Register 0x440 *******/ regVal = MV_REG_READ(MV_USB_PHY_IVREF_CTRL_REG(dev)); /* bits[7:6] RXVDD18 = 0x0 */ regVal &= ~(0x3 << 6); /* bits[11] SQ_CM_SEL = 0x1 for 6183 B0 only */ if ((usbHalData.ctrlModel == MV_6183_DEV_ID)) regVal |= (0x1 << 11); /* bit[24] REG_TEST_SUSPENDM = 0x1 */ regVal |= (0x1 << 24); MV_REG_WRITE(MV_USB_PHY_IVREF_CTRL_REG(dev), regVal); /*-------------------------------------------------*/ /***** USB PHY TEST GROUP CONTROL Register: 0x450 *****/ regVal = MV_REG_READ(MV_USB_PHY_TEST_GROUP_CTRL_REG_0(dev)); /* bit[15] REG_FIFO_SQ_RST = 0x0 */ regVal &= ~(0x1 << 15); MV_REG_WRITE(MV_USB_PHY_TEST_GROUP_CTRL_REG_0(dev), regVal); /*-------------------------------------------------*/ }
/* USB Phy init (change from defaults) specific for 65nm (78100 78200 A0 and later) */ static void mvUsbPhy65nmNewInit(int dev) { MV_U32 regVal; if ((usbHalData.ctrlModel == MV_6281_DEV_ID) || (usbHalData.ctrlModel == MV_6280_DEV_ID) || (usbHalData.ctrlModel == MV_6282_DEV_ID) || (usbHalData.ctrlModel == MV_6192_DEV_ID) || (usbHalData.ctrlModel == MV_6190_DEV_ID) || (usbHalData.ctrlModel == MV_6180_DEV_ID)) { /******* USB PHY ANA Grp Config reg 0x1007c *******/ regVal = MV_REG_READ(0x1007c); /* bit[4:3] should be '01' */ regVal &= ~(0x3 << 3); regVal |= (0x1 << 3); MV_REG_WRITE(0x1007c, regVal); } /******* USB PHY PLL Control Register 0x410 *******/ regVal = MV_REG_READ(MV_USB_PHY_PLL_CTRL_REG(dev)); /* bit[21] (VCOCAL_ START) */ regVal |= (0x1 << 21); MV_REG_WRITE(MV_USB_PHY_PLL_CTRL_REG(dev), regVal); /* Wait 100 usec */ mvOsUDelay(100); regVal &= ~(0x1 << 21); MV_REG_WRITE(MV_USB_PHY_PLL_CTRL_REG(dev), regVal); /*-------------------------------------------------*/ /******* USB PHY Tx Control Register Register 0x420 *******/ regVal = MV_REG_READ(MV_USB_PHY_TX_CTRL_REG(dev)); /* Force impedance auto calibrate */ /* bit[12] (REG_RCAL_START) = 1 */ regVal |= (0x1 << 12); MV_REG_WRITE(MV_USB_PHY_TX_CTRL_REG(dev), regVal); /* Wait 100 usec */ mvOsUDelay(100); /* bit[12] (REG_RCAL_START) = 0 */ regVal &= ~(0x1 << 12); MV_REG_WRITE(MV_USB_PHY_TX_CTRL_REG(dev), regVal); /* bit[16:14] (IMPCAL_VTH) = 101 */ if (usbHalData.ctrlModel == MV_6280_DEV_ID) { regVal &= ~(0x7 << 14); regVal |= (0x5 << 14); } /* bits[2:0] (TX_AMP) = 0x4 */ regVal &= ~(0x7 << 0); if ((usbHalData.ctrlModel == MV_78100_DEV_ID || usbHalData.ctrlModel == MV_78200_DEV_ID || usbHalData.ctrlModel == MV_76100_DEV_ID || usbHalData.ctrlModel == MV_6321_DEV_ID || usbHalData.ctrlModel == MV_6322_DEV_ID || usbHalData.ctrlModel == MV_6323_DEV_ID) && usbHalData.ctrlRev == MV_78XX0_A0_REV) regVal |= (0x4 << 0); else regVal |= (0x3 << 0); MV_REG_WRITE(MV_USB_PHY_TX_CTRL_REG(dev), regVal); /*-------------------------------------------------*/ /******* USB PHY Rx Control Register 0x430 *******/ regVal = MV_REG_READ(MV_USB_PHY_RX_CTRL_REG(dev)); /* bits[3:2] LPF_COEF = 0x1 */ regVal &= ~(0x3 << 2); regVal |= (0x1 << 2); /* bits[7:4] SQ_THRESH = 0x8 */ regVal &= ~(0xf << 4); if (usbHalData.ctrlModel == MV_6282_DEV_ID) regVal |= (0xc << 4); else regVal |= (0x8 << 4); MV_REG_WRITE(MV_USB_PHY_RX_CTRL_REG(dev), regVal); /*-------------------------------------------------*/ /******* USB PHY IVREF Control Register 0x440 *******/ regVal = MV_REG_READ(MV_USB_PHY_IVREF_CTRL_REG(dev)); /* bits[9:8] TxVdd */ regVal &= ~(0x3 << 8); if (usbHalData.ctrlModel == MV_6281_DEV_ID || usbHalData.ctrlModel == MV_6280_DEV_ID || usbHalData.ctrlModel == MV_6282_DEV_ID || usbHalData.ctrlModel == MV_6192_DEV_ID || usbHalData.ctrlModel == MV_6190_DEV_ID || usbHalData.ctrlModel == MV_6180_DEV_ID) regVal |= (0x3 << 8); else regVal |= (0x1 << 8); MV_REG_WRITE(MV_USB_PHY_IVREF_CTRL_REG(dev), regVal); /*-------------------------------------------------*/ /***** USB PHY TEST GROUP CONTROL Register: 0x450 *****/ /* Nothing to change */ }
/******************************************************************************* * tpm_count_get_pnc_lu_entry() * * DESCRIPTION: The API get least used PnC rule by in specific PnC range * * INPUTS: owner_id - APP owner id should be used for all API calls * api_type - TPM API group type * lu_num - The required number of least used PnC entries * lu_reset - Whether need to reset counter after read LU * * * OUTPUTS: * valid_num - The valid number of least used PnC entries * count_array - The least used PnC entry index and hit counter array * unrelated_num - The unlelated number of least used PnC entries * * RETURNS: * On success, the function returns TPM_RC_OK. On error different types are returned * according to the case - see tpm_error_code_t. * * COMMENTS: * None * *******************************************************************************/ tpm_error_code_t tpm_count_get_pnc_lu_entry(uint32_t owner_id, tpm_api_type_t api_type, uint16_t lu_num, uint8_t lu_reset, uint16_t *valid_num, tpm_api_entry_count_t *count_array, uint16_t *unrelated_num) { tpm_api_lu_conf_t lu_conf; tpm_api_sections_t api_section; tpm_pnc_ranges_t range_id; int16_t l_lu_num = 0; uint16_t l_valid_num = 0; uint16_t l_invalid_num = 0; uint32_t l_rule_idx = 0; uint32_t l_tcam_val = 0; uint32_t l_tcam_num = 0; uint32_t range_start = 0; uint32_t range_end = 0; uint32_t w32 = 0; int32_t count_group = 0; int32_t ret_code = TPM_RC_OK; tpm_error_code_t tpm_ret_code = TPM_RC_OK; uint32_t l_retry_time = 0; #ifdef TPM_COUNTER_DEBUG_TIME unsigned long t_start; unsigned long t_dif; #endif TPM_OS_DEBUG(TPM_PNCL_MOD, "%s in, owner_id[%d], api_type[%d], lu_num[%d], lu_reset[%d]\n", __func__, owner_id, api_type, lu_num, lu_reset); /* Get API section and PnC range ID */ ret_code = tpm_count_get_api_section_range_id(owner_id, api_type, &api_section, &range_id); IF_ERROR(ret_code); /* Check the required number */ if ((lu_num < 0) || (lu_num > TPM_MAX_LU_ENTRY_NUM)) { TPM_OS_ERROR(TPM_PNCL_MOD, "lu_num[%d] is illegal, allowed number[1~%d] \n", lu_num, TPM_MAX_LU_ENTRY_NUM); return(ERR_GENERAL); } /* Get counter group number and mask all flag */ ret_code = tpm_db_pnc_get_lu_conf(range_id, &lu_conf); IF_ERROR(ret_code); count_group = lu_conf.cntr_grp; /* Get range start number */ ret_code = tpm_db_pnc_rng_get_range_start_end(range_id, &range_start, &range_end); IF_ERROR(ret_code); /* Get valid LU entries */ memset(gs_tcam_array, 0, sizeof(gs_tcam_array)); memset(gs_valid_tcam_array, 0, sizeof(gs_valid_tcam_array)); #ifdef TPM_COUNTER_DEBUG_TIME t_start = MV_REG_READ(0xAC40C); #endif #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 34) for (l_lu_num = 0; l_lu_num < CONFIG_MV_PNC_TCAM_LINES; l_lu_num++) { #else for (l_lu_num = 0; l_lu_num < MV_ETH_TCAM_LINES; l_lu_num++) { #endif w32 = tpm_tcam_get_lu_entry(count_group); if ((w32 & TPM_PNC_AGING_LOG_VALID_MASK) == 0) { l_retry_time++; if (l_retry_time > 1) break; tpm_tcam_set_triger(); mvOsUDelay(100); if (l_lu_num > 0) l_lu_num--; else l_lu_num = -1; continue; } else l_retry_time = 0; l_tcam_val = w32 & TPM_PNC_AGING_LOG_CNTR_IDX_MASK; gs_tcam_array[l_tcam_num++] = l_tcam_val; /*printk("l_tcam_val[%d], range_start[%d], range_end[%d] \n", l_tcam_val, range_start, range_end); */ /* Check whether the TCAM is in current PnC range */ if ((l_tcam_val < range_start) || (l_tcam_val > range_end)) l_invalid_num++; else { /* Get rule index */ ret_code = tpm_db_api_tcam_rule_idx_get(api_section, l_tcam_val, &l_rule_idx); if (ret_code == TPM_DB_OK) { /*IF_ERROR(ret_code); */ /* Save rule index, hit counter and valid TCAM index */ (count_array + l_valid_num)->rule_idx = l_rule_idx; (count_array + l_valid_num)->hit_count = tpm_tcam_get_aging_cntr(l_tcam_val)&TPM_PNC_AGING_CNTR_MASK; gs_valid_tcam_array[l_valid_num++] = l_tcam_val; /* The required number */ if (l_valid_num >= lu_num) break; } else { l_invalid_num++; } } /* Triger LU */ if (!((l_tcam_num) % TPM_PNC_AGING_TID_NUM_PER_SCAN)) { tpm_tcam_set_triger(); mvOsUDelay(100); } } /* Save valid and unrelated number */ *valid_num = l_valid_num; *unrelated_num = l_invalid_num; /* Clear LU read flag */ for (l_lu_num = 0; l_lu_num < l_tcam_num; l_lu_num++) tpm_tcam_clear_lu_read_flag(gs_tcam_array[l_lu_num]); /* Reset counter if needed */ if (lu_reset != 0) { tpm_ret_code = tpm_count_reset_pnc_age_group(owner_id, api_type); if ((TPM_RC_OK != tpm_ret_code)) { TPM_OS_ERROR(TPM_PNCL_MOD, "Failed to call tpm_count_reset_pnc_age_group, ret_code[%d] \n", tpm_ret_code); return(ERR_GENERAL); } /* Followings are old codes, just remain them for reference */ /* for(l_lu_num = 0; l_lu_num < l_valid_num; l_lu_num++) tpm_tcam_clear_lu_read_cntr(gs_valid_tcam_array[l_lu_num]); */ } #ifdef TPM_COUNTER_DEBUG_TIME t_dif = MV_REG_READ(0xAC40C) - t_start; printk(KERN_ERR "(victor) %s(%d): %ld\n", __func__, __LINE__, t_dif); #endif /* Debug info */ TPM_OS_DEBUG(TPM_PNCL_MOD, "%s out, valid_num[%d], unrelated_num[%d]\n", __func__, *valid_num, *unrelated_num); for (l_lu_num = 0; l_lu_num < *valid_num; l_lu_num++) { TPM_OS_DEBUG(TPM_PNCL_MOD, "Index[%d] rule_idx_array[%d], hit_count[%d]\n", l_lu_num, (count_array + l_lu_num)->rule_idx, (count_array + l_lu_num)->hit_count); } return(TPM_RC_OK); } /******************************************************************************* * tpm_count_get_pnc_all_hit_counters * * DESCRIPTION: The API returns all PnC hit counters per API type lower than a given threshold * * INPUTS: owner_id - APP owner id should be used for all API calls * api_type - TPM API group type * high_thresh_pkts - High threashold watermark, counters lower than will be returned * counters_reset - Reset API group type counters after read (0-false, 1-true) * valid_counters - The count_array size (entry number, not byte count) * * OUTPUTS: valid_counters - The valid number of entries copied to count_array * count_array - The PnC entries for the API type lower than high_thresh_pkts * * RETURNS: * On success, the function returns TPM_RC_OK. On error different types are returned * according to the case - see tpm_error_code_t. * * COMMENTS: * None * *******************************************************************************/ tpm_error_code_t tpm_count_get_pnc_all_hit_counters(uint32_t owner_id, tpm_api_type_t api_type, uint32_t high_thresh_pkts, uint8_t counters_reset, uint16_t *valid_counters, tpm_api_entry_count_t *count_array) { tpm_api_sections_t api_section; tpm_pnc_ranges_t range_id; uint16_t count_array_size; uint32_t rule_idx; uint32_t tcam_val; uint32_t range_start; uint32_t range_end; uint32_t hit_counter; uint16_t cntrs_nr; int32_t ret_code; TPM_OS_DEBUG(TPM_PNCL_MOD, "%s in, owner_id[%d], api_type[%d], counters_reset[%d] high_thresh_pkts[%d]\n", __func__, owner_id, api_type, counters_reset, high_thresh_pkts); /* Get API section and PnC range ID */ ret_code = tpm_count_get_api_section_range_id(owner_id, api_type, &api_section, &range_id); IF_ERROR(ret_code); /* Get range start number */ ret_code = tpm_db_pnc_rng_get_range_start_end(range_id, &range_start, &range_end); IF_ERROR(ret_code); if (*valid_counters > TPM_MAX_PNC_COUNTER_NUM) { TPM_OS_ERROR(TPM_PNCL_MOD, "valid_counters[%d] is illegal, allowed number[1~%d] \n", (*valid_counters), TPM_MAX_PNC_COUNTER_NUM); return(ERR_GENERAL); } /* save the array size */ count_array_size = *valid_counters; cntrs_nr = 0; /* traverse all pnc tcam lines */ for (tcam_val = range_start; tcam_val <= range_end; tcam_val++) { /* Get rule index */ ret_code = tpm_db_api_tcam_rule_idx_get(api_section, tcam_val, &rule_idx); if (ret_code == TPM_DB_OK) { /* read counter from HW */ hit_counter = tpm_tcam_get_aging_cntr(tcam_val); hit_counter = (hit_counter & PNC_AGING_CNTR_MASK) >> PNC_AGING_CNTR_OFFS; /* skip low counters */ if (hit_counter >= high_thresh_pkts) continue; /* Save rule index, hit counter and valid TCAM index */ count_array[cntrs_nr].rule_idx = rule_idx; count_array[cntrs_nr].hit_count = hit_counter; cntrs_nr++; /* The table is full */ if (count_array_size == cntrs_nr) break; } else { continue;
static INLINE MV_STATUS mvTdmChRxLow(MV_U8 ch) { MV_U32 max_poll = 0; MV_TDM_CH_INFO *chInfo = tdmChInfo[ch]; MV_TRC_REC("->%s ch%d\n",__FUNCTION__,ch); if(chInfo->rxFirst) chInfo->rxFirst = !FIRST_INT; else rxInt++; MV_TRC_REC("rxInt(%d)\n", rxInt); if(chInfo->rxBuffFull[chInfo->rxCurrBuff] == BUFF_IS_EMPTY) { MV_TRC_REC("curr buff empty for hw [MMP ok]\n"); } else { MV_TRC_REC("curr buf is full [MMP miss read]\n"); } /* Mark last buff that was received by HW as full. Give next buff to HW for */ /* next frame. The app need to read the data before next irq */ chInfo->rxBuffFull[chInfo->rxCurrBuff] = BUFF_IS_FULL; MV_TRC_REC("buff %d is FULL for ch%d\n", chInfo->rxCurrBuff, ch); /* Change buffers */ chInfo->rxCurrBuff = MV_TDM_NEXT_BUFFER(chInfo->rxCurrBuff); /* Poll on SW ownership (single check) */ MV_TRC_REC("start poll for ownership\n"); while( ((MV_REG_BYTE_READ(CH_BUFF_OWN_REG(chInfo->ch)+RX_OWN_BYTE_OFFS) & OWNER_MASK) == OWN_BY_HW) && (max_poll < 2000) ) { mvOsUDelay(1); max_poll++; } if(max_poll == 2000) { MV_TRC_REC("poll timeout (~2ms)\n"); return MV_TIMEOUT; } else { MV_TRC_REC("poll stop ok\n"); } MV_TRC_REC("%s ch%d, start rx buff %d\n",__FUNCTION__, ch, chInfo->rxCurrBuff); /* Set RX buff address (must be 32 byte aligned) */ MV_REG_WRITE(CH_RX_ADDR_REG(chInfo->ch),chInfo->rxBuffPhys[chInfo->rxCurrBuff]); /* Set HW ownership */ MV_REG_BYTE_WRITE(CH_BUFF_OWN_REG(chInfo->ch)+RX_OWN_BYTE_OFFS, OWN_BY_HW); /* Enable Rx */ MV_REG_BYTE_WRITE(CH_ENABLE_REG(chInfo->ch)+RX_ENABLE_BYTE_OFFS, CH_ENABLE); MV_TRC_REC("<-%s\n",__FUNCTION__); /* Did we get the required amount of irqs for Rx wakeup ? */ if(rxInt < MV_TDM_INT_COUNTER) { return MV_NOT_READY; } else { rxInt = 0; return MV_OK; } }
static INLINE MV_STATUS mvTdmChTxLow(MV_U8 ch) { MV_U32 max_poll = 0; MV_TDM_CH_INFO *chInfo = tdmChInfo[ch]; MV_TRC_REC("->%s ch%d\n",__FUNCTION__,ch); /* count tx interrupts */ txInt++; MV_TRC_REC("txInt(%d)\n", txInt); if(chInfo->txBuffFull[chInfo->txCurrBuff] == BUFF_IS_FULL) { MV_TRC_REC("curr buff full for hw [MMP ok]\n"); } else { MV_TRC_REC("curr buf is empty [MMP miss write]\n"); } /* Change buffers */ chInfo->txCurrBuff = MV_TDM_NEXT_BUFFER(chInfo->txCurrBuff); /* Mark next buff to be transmitted by HW as empty. Give it to the HW for next frame. The app need to write the data before HW takes it. */ chInfo->txBuffFull[chInfo->txCurrBuff] = BUFF_IS_EMPTY; MV_TRC_REC("->%s clear buf(%d) for channel(%d)\n",__FUNCTION__, chInfo->txCurrBuff, ch); /* Poll on SW ownership (single check) */ MV_TRC_REC("start poll for SW ownership\n"); while( ((MV_REG_BYTE_READ(CH_BUFF_OWN_REG(chInfo->ch)+TX_OWN_BYTE_OFFS) & OWNER_MASK) == OWN_BY_HW) && (max_poll < 2000) ) { mvOsUDelay(1); max_poll++; } if(max_poll == 2000) { MV_TRC_REC("poll timeout (~2ms)\n"); return MV_TIMEOUT; } else { MV_TRC_REC("tx-low poll stop ok\n"); } MV_TRC_REC("ch%d, start tx buff %d\n", ch, chInfo->txCurrBuff); /*Set TX buff address (must be 32 byte aligned) */ MV_REG_WRITE(CH_TX_ADDR_REG(chInfo->ch),chInfo->txBuffPhys[chInfo->txCurrBuff]); /* Set HW ownership */ MV_REG_BYTE_WRITE(CH_BUFF_OWN_REG(chInfo->ch)+TX_OWN_BYTE_OFFS, OWN_BY_HW); /* Enable Tx */ MV_REG_BYTE_WRITE(CH_ENABLE_REG(chInfo->ch)+TX_ENABLE_BYTE_OFFS, CH_ENABLE); MV_TRC_REC("<-%s\n",__FUNCTION__); /* Did we get the required amount of irqs for Tx wakeup ? */ if(txInt < MV_TDM_INT_COUNTER) { return MV_NOT_READY; } else { txInt = 0; return MV_OK; } }
/******************************************************************************* * mvCtrlHighSpeedSerdesPhyConfig * * DESCRIPTION: This is the main function which configure the * PU sequence of the ser-des * * INPUT: * None. * * OUTPUT: * None. * * RETURN: * MV_OK - success * MV_ERROR - failure *******************************************************************************/ MV_STATUS mvCtrlHighSpeedSerdesPhyConfig(MV_VOID) { MV_U32 serdesLaneNum, pexUnit; MV_U32 uiReg; MV_BIN_SERDES_UNIT_INDX serdesLaneCfg; MV_U32 regAddr[16][11], regVal[16][11]; /* addr/value for each line @ every setup step */ MV_U8 maxSerdesLanes; MV_U32 tmp; MV_U32 tempReg, tempPexReg; MV_U32 pexIf=0; MV_U32 first_busno, next_busno; MV_U32 addr; MV_TWSI_ADDR slave; MV_U32 boardId = mvBoardIdIndexGet(mvBoardIdGet()); maxSerdesLanes = mvCtrlSerdesMaxLanesGet(); if (maxSerdesLanes == 0) return MV_OK; /*Set MPP1 for twsi access */ uiReg = (MV_REG_READ(MPP_CONTROL_REG(1)) & 0x00FFFFFF) | 0x22000000; MV_REG_WRITE(MPP_CONTROL_REG(1), uiReg); /* TWSI init */ slave.type = ADDR7_BIT; slave.address = 0; mvTwsiInit(0, TWSI_SPEED, mvBoardTclkGet(), &slave, 0); mvUartInit(); /* update board configuration (serdes lane topology and speed), if needed */ mvBoardUpdateBoardTopologyConfig(boardId); /* Initialize board configuration database */ boardLaneConfig[0] = SERDES_UNIT_PEX; /* SerDes 0 is alwyas PCIe0*/ boardLaneConfig[1] = boardTopologyConfig[boardId].serdesTopology.lane1; boardLaneConfig[2] = boardTopologyConfig[boardId].serdesTopology.lane2; boardLaneConfig[3] = boardTopologyConfig[boardId].serdesTopology.lane3; memset(regAddr, 0, sizeof(regAddr)); memset(regVal, 0, sizeof(regVal)); /* Check if DRAM is already initialized */ if (MV_REG_READ(REG_BOOTROM_ROUTINE_ADDR) & (1 << REG_BOOTROM_ROUTINE_DRAM_INIT_OFFS)) { DEBUG_INIT_S("High speed PHY - Version: "); DEBUG_INIT_S(SERDES_VERION); DEBUG_INIT_S(" - 2nd boot - Skip \n"); return MV_OK; } DEBUG_INIT_S("High speed PHY - Version: "); DEBUG_INIT_S(SERDES_VERION); DEBUG_INIT_S(" (COM-PHY-V20) \n"); DEBUG_INIT_FULL_C("SERDES 0=",boardLaneConfig[0],2); DEBUG_INIT_FULL_C("SERDES 1=",boardLaneConfig[1],2); DEBUG_INIT_FULL_C("SERDES 2=",boardLaneConfig[2],2); DEBUG_INIT_FULL_C("SERDES 3=",boardLaneConfig[3],2); /*------------------------------------------*/ /* STEP - 1.5 Power Down PLL, RX, TX all phys */ /*------------------------------------------*/ for (serdesLaneNum = 0; serdesLaneNum < maxSerdesLanes; serdesLaneNum++) { uiReg=MV_REG_READ(COMMON_PHY_CONFIGURATION1_REG(serdesLaneNum)); uiReg &= ~PIN_TX_IDLE_MASK; uiReg &= ~(PHY_POWER_UP_PLL_MASK | PHY_POWER_UP_RX_MASK | PHY_POWER_UP_TX_MASK); MV_REG_WRITE(COMMON_PHY_CONFIGURATION1_REG(serdesLaneNum),uiReg); } mvOsUDelay(10000); /*--------------------------------------------------------*/ /* STEP - 2 Reset PHY and PIPE (Zx: Un-reset, Ax: Reset)*/ /*--------------------------------------------------------*/ for (serdesLaneNum = 0; serdesLaneNum < maxSerdesLanes; serdesLaneNum++) { #ifndef CONFIG_ALP_A375_ZX_REV resetPhyAndPipe(serdesLaneNum, MV_TRUE); #else resetPhyAndPipe(serdesLaneNum, MV_FALSE); #endif } /*--------------------------------*/ /* STEP - 2 Common PHYs Selectors */ /*--------------------------------*/ MV_REG_WRITE(COMMON_PHY_SELECTOR_REG, GetLaneSelectorConfig()); /*--------------------------------*/ /* STEP - 3 Configuration 1 */ /*--------------------------------*/ for (serdesLaneNum = 0; serdesLaneNum < maxSerdesLanes; serdesLaneNum++) { serdesLaneCfg = mvGetSerdesLaneCfg(serdesLaneNum); if(serdesLaneCfg >= SERDES_LAST_UNIT){ return MV_ERROR; } uiReg = MV_REG_READ(COMMON_PHY_CONFIGURATION1_REG(serdesLaneNum)); switch(serdesLaneCfg){ case SERDES_UNIT_USB3: #ifndef CONFIG_ALP_A375_ZX_REV A375_A0_COMMON_PHY_CONFIG(uiReg); #endif uiReg |= PHY_MODE_MASK; /* PHY Mode = USB */ uiReg |= PIPE_SELECT_MASK ; /* Select USB3_PEX */ break; case SERDES_UNIT_PEX: uiReg |= PIPE_SELECT_MASK ; /* Select USB3_PEX */ #ifndef CONFIG_ALP_A375_ZX_REV uiReg &= ~(PHY_MODE_MASK); /* PHY Mode = PEX */ A375_A0_COMMON_PHY_CONFIG(uiReg); #endif break; case SERDES_UNIT_SGMII: case SERDES_UNIT_SATA: #ifndef CONFIG_ALP_A375_ZX_REV A375_A0_COMMON_PHY_CONFIG(uiReg); #endif uiReg &= ~(PIPE_SELECT_MASK); /* Select SATA_SGMII */ uiReg |= POWER_UP_IVREF_MASK; /* Power UP IVREF = Power Up */ break; case SERDES_UNIT_UNCONNECTED: default: break; } /* Serdes speed config */ tmp = getSerdesSpeedConfig(boardId, serdesLaneCfg); uiReg &= ~(GEN_RX_MASK); /* SERDES RX Speed config */ uiReg |= tmp<<GEN_RX_OFFS; uiReg &= ~(GEN_TX_MASK); /* SERDES TX Speed config */ uiReg |= tmp<<GEN_TX_OFFS; MV_REG_WRITE(COMMON_PHY_CONFIGURATION1_REG(serdesLaneNum),uiReg); } #ifndef CONFIG_ALP_A375_ZX_REV /*------------------------------------------*/ /* STEP - 3.5 Unreset PHY and PIPE(only Ax)*/ /*------------------------------------------*/ for (serdesLaneNum = 0; serdesLaneNum < maxSerdesLanes; serdesLaneNum++) { resetPhyAndPipe(serdesLaneNum, MV_FALSE); } #endif /*----------------------------------------*/ /* STEP - 4 COMPHY register configuration */ /*----------------------------------------*/ for (serdesLaneNum = 0; serdesLaneNum < maxSerdesLanes; serdesLaneNum++) { serdesLaneCfg = mvGetSerdesLaneCfg(serdesLaneNum); if(serdesLaneCfg >= SERDES_LAST_UNIT){ return MV_ERROR; } switch(serdesLaneCfg){ case SERDES_UNIT_PEX: MV_REG_WRITE(RESET_AND_CLOCK_CONTROL_REG(serdesLaneNum),0x25); /* Enable soft_reset*/ MV_REG_WRITE(POWER_AND_PLL_CONTROL_REG(serdesLaneNum),0xFC60); /* PHY Mode = PEX */ #ifndef CONFIG_ALP_A375_ZX_REV MV_REG_WRITE(MISCELLANEOUS_CONTROL0_REG(serdesLaneNum),0x6017); /* REFCLK SEL =0x0 (100Mhz) */ MV_REG_WRITE(INTERFACE_REG1_REG(serdesLaneNum),0x1400); /* PHY_Gen_Max = 5G */ MV_REG_WRITE(DIGITAL_LOOPBACK_ENABLE_REG(serdesLaneNum),0x400); /* SEL_Bits = 20-Bit */ A375_A0_RESET_DFE_SEQUENCE(serdesLaneNum); #else MV_REG_WRITE(KVCO_CALOBRATION_CONTROL_REG(serdesLaneNum),0x40); /* use_max_pll_rate=0x0, ext_force_cal_done=0x0 */ #endif MV_REG_WRITE(RESET_AND_CLOCK_CONTROL_REG(serdesLaneNum),0x24); /* Release soft_reset */ break; case SERDES_UNIT_USB3: MV_REG_WRITE(RESET_AND_CLOCK_CONTROL_REG(serdesLaneNum),0x21); /* Enable soft_reset*/ MV_REG_WRITE(POWER_AND_PLL_CONTROL_REG(serdesLaneNum),0xFCA0); /* PHY Mode = USB3 */ #ifndef CONFIG_ALP_A375_ZX_REV MV_REG_WRITE(LANE_CONFIGURATION_4_REG(serdesLaneNum),0x13); /* Ref_Clk =100Mhz */ MV_REG_WRITE(MISCELLANEOUS_CONTROL0_REG(serdesLaneNum),0x6017); /* REFCLK SEL =0x0 (100Mhz) */ MV_REG_WRITE(INTERFACE_REG1_REG(serdesLaneNum),0x1400); /* PHY_Gen_Max = 5G */ MV_REG_WRITE(DIGITAL_LOOPBACK_ENABLE_REG(serdesLaneNum),0x400); /* SEL_Bits = 20-Bit */ A375_A0_RESET_DFE_SEQUENCE(serdesLaneNum); #else MV_REG_WRITE(KVCO_CALOBRATION_CONTROL_REG(serdesLaneNum),0x40); /* use_max_pll_rate=0x0, ext_force_cal_done=0x0 */ MV_REG_WRITE(GENERETION_2_SETTINGS_1_REG(serdesLaneNum),0x149); /* Mulitiple frequency setup */ #endif MV_REG_WRITE(RESET_AND_CLOCK_CONTROL_REG(serdesLaneNum),0x20); /* Release soft_reset */ break; case SERDES_UNIT_SATA: MV_REG_WRITE(POWER_AND_PLL_CONTROL_REG(serdesLaneNum),0xFC01); /* PHY Mode = SATA */ MV_REG_WRITE(MISCELLANEOUS_CONTROL0_REG(serdesLaneNum),0x6417); /* REFCLK SEL =0x1 (25Mhz) */ #ifndef CONFIG_ALP_A375_ZX_REV MV_REG_WRITE(INTERFACE_REG1_REG(serdesLaneNum),0x1400); /* PHY_Gen_Max = 5G */ MV_REG_WRITE(DIGITAL_LOOPBACK_ENABLE_REG(serdesLaneNum),0x400); /* SEL_Bits = 20-Bit */ MV_REG_WRITE(DIGITAL_RESERVED0_REG(serdesLaneNum),0xE); /* Reg_sq_de_glitch_en */ A375_A0_RESET_DFE_SEQUENCE(serdesLaneNum); #else MV_REG_WRITE(RESERVED_46_REG(serdesLaneNum),0xFF00); #endif break; case SERDES_UNIT_SGMII: MV_REG_WRITE(POWER_AND_PLL_CONTROL_REG(serdesLaneNum),0xFC81); /* PHY Mode = SGMII */ /*moti need to change offset*/ MV_REG_WRITE(DIGITAL_LOOPBACK_ENABLE_REG(serdesLaneNum),0x0); /* SEL_BITS = 0x0 (10-bits mode) */ MV_REG_WRITE(MISCELLANEOUS_CONTROL0_REG(serdesLaneNum),0x6417); /* REFCLK SEL =0x1 (25Mhz) */ #ifndef CONFIG_ALP_A375_ZX_REV MV_REG_WRITE(DIGITAL_RESERVED0_REG(serdesLaneNum),0xE); /* Reg_sq_de_glitch_en */ A375_A0_RESET_DFE_SEQUENCE(serdesLaneNum); #else MV_REG_WRITE(RESERVED_46_REG(serdesLaneNum),0xFF00); /* Enable soft_reset*/ #endif MV_REG_WRITE(PHY_ISOLATION_MODE_CONTROL_REG(serdesLaneNum),0x166); /* Set PHY_GEN_TX/RX to 1.25Gbps */ break; case SERDES_UNIT_UNCONNECTED: default: break; } } /*------------------------------------------*/ /* STEP - 4.5 Power up PLL, RX, TX all phys */ /*------------------------------------------*/ for (serdesLaneNum = 0; serdesLaneNum < maxSerdesLanes; serdesLaneNum++) { uiReg=MV_REG_READ(COMMON_PHY_CONFIGURATION1_REG(serdesLaneNum)); uiReg |= (PHY_POWER_UP_PLL_MASK | PHY_POWER_UP_RX_MASK | PHY_POWER_UP_TX_MASK); MV_REG_WRITE(COMMON_PHY_CONFIGURATION1_REG(serdesLaneNum),uiReg); } #ifndef CONFIG_ALP_A375_ZX_REV mvOsUDelay(5000); /*--------------------------------------------------------------------*/ /* STEP - 4.6 (Only SGMII/SATA): WAIT for PHY Power up sequence to finish */ /*--------------------------------------------------------------------*/ for (serdesLaneNum = 0; serdesLaneNum < maxSerdesLanes; serdesLaneNum++) { serdesLaneCfg = mvGetSerdesLaneCfg(serdesLaneNum); if(serdesLaneCfg >= SERDES_LAST_UNIT){ return MV_ERROR; } switch(serdesLaneCfg){ case SERDES_UNIT_SATA: case SERDES_UNIT_SGMII: uiReg = MV_REG_READ(COMMON_PHY_STATUS1_REG(serdesLaneNum)); if ((uiReg & 0x6) != 0x6) { DEBUG_INIT_S("Phy Power up did't finished\n"); return MV_ERROR; } case SERDES_UNIT_UNCONNECTED: default: break; } } #endif /*----------------------------------------*/ /* STEP - 5 PEX Only */ /*----------------------------------------*/ for (pexUnit = 0; pexUnit < 4; pexUnit++) { if (boardLaneConfig[pexUnit] != SERDES_UNIT_PEX) continue; tmp = MV_REG_READ(PEX_CAPABILITIES_REG(pexUnit)); DEBUG_RD_REG(PEX_CAPABILITIES_REG(pexUnit), tmp ); tmp &= ~(0xf<<20); tmp |= (0x4<<20); MV_REG_WRITE(PEX_CAPABILITIES_REG(pexUnit),tmp); DEBUG_WR_REG(PEX_CAPABILITIES_REG(pexUnit),tmp); } tmp = MV_REG_READ(SOC_CTRL_REG); DEBUG_RD_REG(SOC_CTRL_REG, tmp); tmp &= ~(0x03); tmp |= 0x1<<PCIE0_ENABLE_OFFS; if (boardLaneConfig[1] == SERDES_UNIT_PEX) tmp |= 0x1<<PCIE1_ENABLE_OFFS; MV_REG_WRITE(SOC_CTRL_REG, tmp); DEBUG_WR_REG(SOC_CTRL_REG, tmp); /*----------------------------------------*/ /* STEP - 6 PEX Only - support gen1/gen2 */ /*----------------------------------------*/ next_busno = 0; mvOsDelay(150); for (pexIf = 0; pexIf < 2; pexIf++) // only pexIf 0 on { if (boardLaneConfig[pexIf] != SERDES_UNIT_PEX) continue; tmp = MV_REG_READ(PEX_DBG_STATUS_REG(pexIf)); DEBUG_RD_REG(PEX_DBG_STATUS_REG(pexIf), tmp); first_busno = next_busno; if ((tmp & 0x7f) == 0x7E) { next_busno++; tempPexReg = MV_REG_READ((PEX_CFG_DIRECT_ACCESS(pexIf, PEX_LINK_CAPABILITY_REG))); DEBUG_RD_REG((PEX_CFG_DIRECT_ACCESS(pexIf, PEX_LINK_CAPABILITY_REG)),tempPexReg ); tempPexReg &= (0xF); if (tempPexReg == 0x2) { tempReg = (MV_REG_READ(PEX_CFG_DIRECT_ACCESS(pexIf, PEX_LINK_CTRL_STAT_REG)) & 0xF0000) >> 16; DEBUG_RD_REG(PEX_CFG_DIRECT_ACCESS(pexIf, PEX_LINK_CTRL_STAT_REG),tempReg ); /* check if the link established is GEN1 */ if (tempReg == 0x1) { mvPexLocalBusNumSet(pexIf, first_busno); mvPexLocalDevNumSet(pexIf, 1); DEBUG_INIT_FULL_S("PEX: pexIf "); DEBUG_INIT_FULL_D(pexIf, 1); DEBUG_INIT_FULL_S(", link is Gen1, checking the EP capability \n"); /* link is Gen1, check the EP capability */ addr = mvPexConfigRead(pexIf, first_busno, 0, 0, 0x34) & 0xFF; DEBUG_INIT_FULL_C("mvPexConfigRead: return addr=0x%x", addr,4); if (addr == 0xff) { DEBUG_INIT_FULL_C("mvPexConfigRead: return 0xff -->PEX (%d): Detected No Link.", pexIf,1); continue; } while ((mvPexConfigRead(pexIf, first_busno, 0, 0, addr) & 0xFF) != 0x10) { addr = (mvPexConfigRead(pexIf, first_busno, 0, 0, addr) & 0xFF00) >> 8; } if ((mvPexConfigRead(pexIf, first_busno, 0, 0, addr + 0xC) & 0xF) >= 0x2) { tmp = MV_REG_READ(PEX_LINK_CTRL_STATUS2_REG(pexIf)); DEBUG_RD_REG(PEX_LINK_CTRL_STATUS2_REG(pexIf),tmp ); tmp &=~(BIT0 | BIT1); tmp |= BIT1; MV_REG_WRITE(PEX_LINK_CTRL_STATUS2_REG(pexIf),tmp); DEBUG_WR_REG(PEX_LINK_CTRL_STATUS2_REG(pexIf),tmp); tmp = MV_REG_READ(PEX_CTRL_REG(pexIf)); DEBUG_RD_REG(PEX_CTRL_REG(pexIf), tmp ); tmp |= BIT10; MV_REG_WRITE(PEX_CTRL_REG(pexIf),tmp); DEBUG_WR_REG(PEX_CTRL_REG(pexIf),tmp); mvOsUDelay(10000);/* We need to wait 10ms before reading the PEX_DBG_STATUS_REG in order not to read the status of the former state*/ DEBUG_INIT_FULL_S("PEX: pexIf "); DEBUG_INIT_FULL_D(pexIf, 1); DEBUG_INIT_FULL_S(", Link upgraded to Gen2 based on client cpabilities \n"); } else { DEBUG_INIT_FULL_S("PEX: pexIf "); DEBUG_INIT_FULL_D(pexIf, 1); DEBUG_INIT_FULL_S(", remains Gen1\n"); } } }
/* USB Phy init (change from defaults) specific for 65nm (78100 78200 A0 and later) */ static void mvUsbPhy65nmNewInit(int dev) { MV_U32 regVal; if((mvCtrlModelGet() == MV_6281_DEV_ID) || (mvCtrlModelGet() == MV_6192_DEV_ID) || (mvCtrlModelGet() == MV_6190_DEV_ID) || (mvCtrlModelGet() == MV_6180_DEV_ID)) { /******* USB PHY ANA Grp Config reg 0x1007c *******/ regVal = MV_REG_READ(0x1007c); /* bit[4:3] should be '01' */ regVal &= ~(0x3 << 3); regVal |= (0x1 << 3); MV_REG_WRITE(0x1007c, regVal); } /******* USB PHY PLL Control Register 0x410 *******/ regVal = MV_REG_READ(MV_USB_PHY_PLL_CTRL_REG(dev)); /* bit[21] (VCOCAL_ START) */ regVal |= (0x1 << 21); MV_REG_WRITE(MV_USB_PHY_PLL_CTRL_REG(dev), regVal); /* Wait 100 usec */ mvOsUDelay(100); regVal &= ~(0x1 << 21); MV_REG_WRITE(MV_USB_PHY_PLL_CTRL_REG(dev), regVal); /*-------------------------------------------------*/ /******* USB PHY Tx Control Register Register 0x420 *******/ regVal = MV_REG_READ(MV_USB_PHY_TX_CTRL_REG(dev)); /* Force impedance auto calibrate */ /* bit[12] (REG_RCAL_START) = 1 */ regVal |= (0x1 << 12); MV_REG_WRITE(MV_USB_PHY_TX_CTRL_REG(dev), regVal); /* Wait 100 usec */ mvOsUDelay(100); /* bit[12] (REG_RCAL_START) = 0 */ regVal &= ~(0x1 << 12); MV_REG_WRITE(MV_USB_PHY_TX_CTRL_REG(dev), regVal); /* bits[2:0] (TX_AMP) = 0x4 */ regVal &= ~(0x7 << 0); regVal |= (0x4 << 0); MV_REG_WRITE(MV_USB_PHY_TX_CTRL_REG(dev), regVal); /*-------------------------------------------------*/ /******* USB PHY Rx Control Register 0x430 *******/ regVal = MV_REG_READ(MV_USB_PHY_RX_CTRL_REG(dev)); /* bits[7:4] SQ_THRESH = 0x8 */ regVal &= ~(0xf << 4); regVal |= (0x8 << 4); MV_REG_WRITE(MV_USB_PHY_RX_CTRL_REG(dev), regVal); /*-------------------------------------------------*/ /******* USB PHY IVREF Control Register 0x440 *******/ /* Nothing to change */ /*-------------------------------------------------*/ /***** USB PHY TEST GROUP CONTROL Register: 0x450 *****/ /* Nothing to change */ }