diff options
author | Eyal Harari <Eyal.Harari@freesacle.com> | 2014-05-23 07:57:56 (GMT) |
---|---|---|
committer | Jose Rivera <German.Rivera@freescale.com> | 2014-05-27 14:05:57 (GMT) |
commit | 49a1bd52cb9a328460ee793967249223e379b809 (patch) | |
tree | 76da20971b5022834d33a007ad2d4f72955cdc0c /drivers/net/ethernet/freescale/fman/Peripherals/FM/Port | |
parent | 8596def61c88a5dad865f82e0067b0a2dbe003f2 (diff) | |
download | linux-fsl-qoriq-49a1bd52cb9a328460ee793967249223e379b809.tar.xz |
FMD: DSAR: workaround patch which enables AR in DS
Signed-off-by: Eyal Harari <Eyal.Harari@freesacle.com>
Change-Id: I90e7e97c9ff8a149893c8244cb0e8376c66eb2ad
Reviewed-on: http://git.am.freescale.net:8181/12925
Reviewed-by: Cristian-Constantin Sovaiala <Cristian.Sovaiala@freescale.com>
Tested-by: Richard Schmitt <richard.schmitt@freescale.com>
Reviewed-by: Jose Rivera <German.Rivera@freescale.com>
Tested-by: Jose Rivera <German.Rivera@freescale.com>
Diffstat (limited to 'drivers/net/ethernet/freescale/fman/Peripherals/FM/Port')
-rw-r--r-- | drivers/net/ethernet/freescale/fman/Peripherals/FM/Port/fm_port.c | 91 |
1 files changed, 83 insertions, 8 deletions
diff --git a/drivers/net/ethernet/freescale/fman/Peripherals/FM/Port/fm_port.c b/drivers/net/ethernet/freescale/fman/Peripherals/FM/Port/fm_port.c index 00a3489..df05848 100644 --- a/drivers/net/ethernet/freescale/fman/Peripherals/FM/Port/fm_port.c +++ b/drivers/net/ethernet/freescale/fman/Peripherals/FM/Port/fm_port.c @@ -3166,10 +3166,13 @@ t_Error FM_PORT_Disable(t_Handle h_FmPort) return E_OK; } +t_FmPort* opXX; t_Error FM_PORT_Enable(t_Handle h_FmPort) { t_FmPort *p_FmPort = (t_FmPort*)h_FmPort; int err; + if (p_FmPort->portId == 0) // save HC port for DSAR disable + opXX = p_FmPort; SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE); SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE); @@ -5465,6 +5468,20 @@ static int GetBERLen(uint8_t* buf) } #define TOTAL_BER_LEN(len) (len < 128) ? len + 2 : len + 3 +#define SCFG_FMCLKDPSLPCR_ADDR 0xFFE0FC00C +#define SCFG_FMCLKDPSLPCR_DS_VAL 0x08402000 +#define SCFG_FMCLKDPSLPCR_NORMAL_VAL 0x00402000 +static int fm_soc_suspend(void) +{ + uint32_t *fmclk, tmp32; + fmclk = ioremap(SCFG_FMCLKDPSLPCR_ADDR, 4); + tmp32 = GET_UINT32(*fmclk); + WRITE_UINT32(*fmclk, SCFG_FMCLKDPSLPCR_DS_VAL); + tmp32 = GET_UINT32(*fmclk); + return 0; +} + +t_FmPort *g_DsarFmPortRx, *g_DsarFmPortTx; t_Error FM_PORT_EnterDsar(t_Handle h_FmPortRx, t_FmPortDsarParams *params) { int i,j; @@ -5481,12 +5498,14 @@ t_Error FM_PORT_EnterDsar(t_Handle h_FmPortRx, t_FmPortDsarParams *params) t_ArCommonDesc *ArCommonDescPtr = (t_ArCommonDesc*)(XX_PhysToVirt(p_FmPort->fmMuramPhysBaseAddr + GET_UINT32(*param_page))); struct arOffsets* of; uint8_t tmp = 0; - t_Handle *h_FmPcd; t_FmGetSetParams fmGetSetParams; memset(&fmGetSetParams, 0, sizeof (t_FmGetSetParams)); fmGetSetParams.setParams.type = UPDATE_FPM_BRKC_SLP; fmGetSetParams.setParams.sleep = 1; + g_DsarFmPortRx = p_FmPort; + g_DsarFmPortTx = p_FmPortTx; + err = DsarCheckParams(params, p_FmPort->deepSleepVars.autoResMaxSizes); if (err != E_OK) return err; @@ -5760,7 +5779,27 @@ t_Error FM_PORT_EnterDsar(t_Handle h_FmPortRx, t_FmPortDsarParams *params) WRITE_UINT32(ArCommonDescPtr->p_ArStats, PTR_TO_UINT(ArCommonDescPtr) + of->stats - fmMuramVirtBaseAddr); // get into Deep Sleep sequence: - // Stage 6: configure tx port to im + + // Ensures that FMan do not enter the idle state. This is done by programing + // FMDPSLPCR[FM_STOP] to one. + fm_soc_suspend(); + + ARDesc = UINT_TO_PTR(XX_VirtToPhys(ArCommonDescPtr)); + return E_OK; + +} + +void FM_PORT_Dsar_enter_final(void) +{ + t_Handle *h_FmPcd; + t_FmGetSetParams fmGetSetParams; + + t_FmPort *p_FmPort = g_DsarFmPortRx; + t_FmPort *p_FmPortTx = g_DsarFmPortTx; + // Issue graceful stop to HC port + FM_PORT_Disable(opXX); + + // config auto response p_FmPort->deepSleepVars.fmbm_tcfg = GET_UINT32(p_FmPortTx->p_FmPortBmiRegs->txPortBmiRegs.fmbm_tcfg); WRITE_UINT32(p_FmPortTx->p_FmPortBmiRegs->txPortBmiRegs.fmbm_tcfg, GET_UINT32(p_FmPortTx->p_FmPortBmiRegs->txPortBmiRegs.fmbm_tcfg) | BMI_PORT_CFG_IM); // ???? @@ -5780,20 +5819,55 @@ t_Error FM_PORT_EnterDsar(t_Handle h_FmPortRx, t_FmPortDsarParams *params) p_FmPort->deepSleepVars.dsarEnabledParser = FALSE; WRITE_UINT32(p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rfpne, 0x2E); - // Stage 8: We don't support magic packet for now. - // Stage 9: Accumulate mode + + // save rcfg for restoring: accumulate mode is changed by ucode p_FmPort->deepSleepVars.fmbm_rcfg = GET_UINT32(p_FmPort->port.bmi_regs->rx.fmbm_rcfg); WRITE_UINT32(p_FmPort->port.bmi_regs->rx.fmbm_rcfg, p_FmPort->deepSleepVars.fmbm_rcfg | BMI_PORT_CFG_AM); - FmGetSetParams(p_FmPort->h_Fm, &fmGetSetParams); +// ***** issue external request sync command + memset(&fmGetSetParams, 0, sizeof (t_FmGetSetParams)); + fmGetSetParams.setParams.type = UPDATE_FPM_EXTC; + FmGetSetParams(p_FmPort->h_Fm, &fmGetSetParams); + // get + memset(&fmGetSetParams, 0, sizeof (t_FmGetSetParams)); + fmGetSetParams.getParams.type = GET_FMFP_EXTC; + FmGetSetParams(p_FmPort->h_Fm, &fmGetSetParams); + if (fmGetSetParams.getParams.fmfp_extc != 0) + { + // clear + XX_Print("FM: Sync did not finish 0\n"); + memset(&fmGetSetParams, 0, sizeof (t_FmGetSetParams)); + fmGetSetParams.setParams.type = UPDATE_FPM_EXTC_CLEAR; + FmGetSetParams(p_FmPort->h_Fm, &fmGetSetParams); + } - ARDesc = UINT_TO_PTR(XX_VirtToPhys(ArCommonDescPtr)); - return E_OK; + // get + memset(&fmGetSetParams, 0, sizeof (t_FmGetSetParams)); + fmGetSetParams.getParams.type = GET_FMFP_EXTC; + FmGetSetParams(p_FmPort->h_Fm, &fmGetSetParams); + while (fmGetSetParams.getParams.fmfp_extc != 0) + { + // get + memset(&fmGetSetParams, 0, sizeof (t_FmGetSetParams)); + fmGetSetParams.getParams.type = GET_FMFP_EXTC; + FmGetSetParams(p_FmPort->h_Fm, &fmGetSetParams); + } + + // check that all stoped + memset(&fmGetSetParams, 0, sizeof (t_FmGetSetParams)); + fmGetSetParams.getParams.type = GET_FMQM_GS | GET_FM_NPI; + FmGetSetParams(p_FmPort->h_Fm, &fmGetSetParams); + while (fmGetSetParams.getParams.fmqm_gs & 0xF0000000) + FmGetSetParams(p_FmPort->h_Fm, &fmGetSetParams); + if (fmGetSetParams.getParams.fmqm_gs == 0 && fmGetSetParams.getParams.fm_npi == 0) + XX_Print("FM: Sleeping\n"); } +EXPORT_SYMBOL(FM_PORT_Dsar_enter_final); + void FM_PORT_Dsar_DumpRegs() { uint32_t* hh = XX_PhysToVirt(PTR_TO_UINT(ARDesc)); - DUMP_MEMORY(hh, 0x180); + DUMP_MEMORY(hh, 0x220); } void FM_PORT_ExitDsar(t_Handle h_FmPortRx, t_Handle h_FmPortTx) @@ -5823,6 +5897,7 @@ void FM_PORT_ExitDsar(t_Handle h_FmPortRx, t_Handle h_FmPortTx) FmGetSetParams(p_FmPort->h_Fm, &fmGetSetParams); WRITE_UINT32(p_FmPortTx->p_FmPortBmiRegs->txPortBmiRegs.fmbm_tcmne, p_FmPort->deepSleepVars.fmbm_tcmne); WRITE_UINT32(p_FmPortTx->p_FmPortBmiRegs->txPortBmiRegs.fmbm_tcfg, p_FmPort->deepSleepVars.fmbm_tcfg); + FM_PORT_Enable(opXX); } bool FM_PORT_IsInDsar(t_Handle h_FmPort) |