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 | |
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')
3 files changed, 131 insertions, 23 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) diff --git a/drivers/net/ethernet/freescale/fman/Peripherals/FM/fm.c b/drivers/net/ethernet/freescale/fman/Peripherals/FM/fm.c index 811c4f2..3f569b8 100644 --- a/drivers/net/ethernet/freescale/fman/Peripherals/FM/fm.c +++ b/drivers/net/ethernet/freescale/fman/Peripherals/FM/fm.c @@ -4182,6 +4182,33 @@ UNUSED(p_Fm); return E_OK; } +t_Error FmGetSetParams(t_Handle h_Fm, t_FmGetSetParams *p_Params) +{ + t_Fm* p_Fm = (t_Fm*)h_Fm; + + if (p_Params->setParams.type & UPDATE_FPM_EXTC) + WRITE_UINT32(p_Fm->p_FmFpmRegs->fmfp_extc,0x80000000); + if (p_Params->setParams.type & UPDATE_FPM_EXTC_CLEAR) + WRITE_UINT32(p_Fm->p_FmFpmRegs->fmfp_extc,0x08000000); + if (p_Params->setParams.type & UPDATE_FPM_BRKC_SLP) + { + if (p_Params->setParams.sleep) + WRITE_UINT32(p_Fm->p_FmFpmRegs->fmfp_brkc, GET_UINT32( + p_Fm->p_FmFpmRegs->fmfp_brkc) | FPM_BRKC_SLP); + else + WRITE_UINT32(p_Fm->p_FmFpmRegs->fmfp_brkc, GET_UINT32( + p_Fm->p_FmFpmRegs->fmfp_brkc) & ~FPM_BRKC_SLP); + } + if (p_Params->getParams.type & GET_FMQM_GS) + p_Params->getParams.fmqm_gs = GET_UINT32(p_Fm->p_FmQmiRegs->fmqm_gs); + if (p_Params->getParams.type & GET_FM_NPI) + p_Params->getParams.fm_npi = GET_UINT32(p_Fm->p_FmFpmRegs->fm_npi); + if (p_Params->getParams.type & GET_FMFP_EXTC) + p_Params->getParams.fmfp_extc = GET_UINT32(p_Fm->p_FmFpmRegs->fmfp_extc); + return E_OK; +} + + /****************************************************/ /* API Run-time Control uint functions */ /****************************************************/ @@ -4215,7 +4242,14 @@ void FM_EventIsr(t_Handle h_Fm) pending = fman_get_normal_pending(fpm_rg); if (!pending) return; - + if (pending & 0x10000000) // this is a wake up from sleep interrupt + { + t_FmGetSetParams fmGetSetParams; + memset(&fmGetSetParams, 0, sizeof (t_FmGetSetParams)); + fmGetSetParams.setParams.type = UPDATE_FPM_BRKC_SLP; + fmGetSetParams.setParams.sleep = 0; + FmGetSetParams(h_Fm, &fmGetSetParams); + } if (pending & INTR_EN_QMI) QmiEvent(p_Fm); if (pending & INTR_EN_PRS) @@ -5212,17 +5246,3 @@ t_Handle FmGetPcd(t_Handle h_Fm) return ((t_Fm*)h_Fm)->h_Pcd; } -t_Error FmGetSetParams(t_Handle h_Fm, t_FmGetSetParams *p_Params) -{ - t_Fm* p_Fm = (t_Fm*)h_Fm; - if (p_Params->setParams.type == UPDATE_FPM_BRKC_SLP) - { - if (p_Params->setParams.sleep) - WRITE_UINT32(p_Fm->p_FmFpmRegs->fmfp_brkc, GET_UINT32( - p_Fm->p_FmFpmRegs->fmfp_brkc) | FPM_BRKC_SLP); - else - WRITE_UINT32(p_Fm->p_FmFpmRegs->fmfp_brkc, GET_UINT32( - p_Fm->p_FmFpmRegs->fmfp_brkc) & ~FPM_BRKC_SLP); - } - return E_OK; -} diff --git a/drivers/net/ethernet/freescale/fman/Peripherals/FM/inc/fm_common.h b/drivers/net/ethernet/freescale/fman/Peripherals/FM/inc/fm_common.h index c9c963a..f5f5428 100644 --- a/drivers/net/ethernet/freescale/fman/Peripherals/FM/inc/fm_common.h +++ b/drivers/net/ethernet/freescale/fman/Peripherals/FM/inc/fm_common.h @@ -264,7 +264,15 @@ typedef struct { } t_FmSetParams; typedef struct { + uint32_t type; + uint32_t fmqm_gs; + uint32_t fm_npi; + uint32_t fmfp_extc; +} t_FmGetParams; + +typedef struct { t_FmSetParams setParams; + t_FmGetParams getParams; } t_FmGetSetParams; t_Error FmGetSetParams(t_Handle h_Fm, t_FmGetSetParams *p_Params); @@ -335,6 +343,11 @@ static __inline__ bool TRY_LOCK(t_Handle h_Spinlock, volatile bool *p_Flag) /* @} */ #define UPDATE_FPM_BRKC_SLP 0x80000000 +#define UPDATE_FPM_EXTC 0x40000000 +#define UPDATE_FPM_EXTC_CLEAR 0x20000000 +#define GET_FMQM_GS 0x10000000 +#define GET_FM_NPI 0x08000000 +#define GET_FMFP_EXTC 0x04000000 #define FM_MAX_NUM_OF_PORTS (FM_MAX_NUM_OF_OH_PORTS + \ FM_MAX_NUM_OF_1G_RX_PORTS + \ FM_MAX_NUM_OF_10G_RX_PORTS + \ |