summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEyal Harari <Eyal.Harari@freesacle.com>2014-06-03 05:34:13 (GMT)
committerMandy Lavi <mandy.lavi@freescale.com>2014-07-21 06:15:16 (GMT)
commit087f4784b96585b712b62a110b0fe83e45ae4351 (patch)
tree02552af48768f80f5df999f50a77333c037a7108
parent1f8369e6c8f28c7f1667af3254de31ccb9eacde4 (diff)
downloadlinux-fsl-qoriq-087f4784b96585b712b62a110b0fe83e45ae4351.tar.xz
FMD: DSAR - fix deep sleep entry sequence
The current sequence fixes the order of operations executed when entering deep sleep state. It also implements a workaround for a hardware bug by writing to fm_cld register - disabling DMA after a short idle period. Signed-off-by: Eyal Harari <Eyal.Harari@freesacle.com> Change-Id: I2c73406543495dad5a7fb240a2e8fab01b81e05e
-rw-r--r--drivers/net/ethernet/freescale/fman/Peripherals/FM/HC/hc.c5
-rw-r--r--drivers/net/ethernet/freescale/fman/Peripherals/FM/MAC/memac.c5
-rw-r--r--drivers/net/ethernet/freescale/fman/Peripherals/FM/Pcd/fm_pcd.c5
-rw-r--r--drivers/net/ethernet/freescale/fman/Peripherals/FM/Port/fm_port.c71
-rw-r--r--drivers/net/ethernet/freescale/fman/Peripherals/FM/fm.c40
-rw-r--r--drivers/net/ethernet/freescale/fman/Peripherals/FM/fm.h1
-rw-r--r--drivers/net/ethernet/freescale/fman/Peripherals/FM/inc/fm_common.h4
-rw-r--r--drivers/net/ethernet/freescale/fman/Peripherals/FM/inc/fm_hc.h2
-rw-r--r--drivers/net/ethernet/freescale/fman/inc/Peripherals/fm_port_ext.h23
-rwxr-xr-xdrivers/net/ethernet/freescale/fman/src/wrapper/lnxwrp_fm.c51
-rw-r--r--drivers/net/ethernet/freescale/fman/src/wrapper/lnxwrp_fm.h3
11 files changed, 156 insertions, 54 deletions
diff --git a/drivers/net/ethernet/freescale/fman/Peripherals/FM/HC/hc.c b/drivers/net/ethernet/freescale/fman/Peripherals/FM/HC/hc.c
index 74047dd..9485caa 100644
--- a/drivers/net/ethernet/freescale/fman/Peripherals/FM/HC/hc.c
+++ b/drivers/net/ethernet/freescale/fman/Peripherals/FM/HC/hc.c
@@ -1223,3 +1223,8 @@ t_Error FmHcPcdSync(t_Handle h_FmHc)
return E_OK;
}
+t_Handle FmHcGetPort(t_Handle h_FmHc)
+{
+ t_FmHc *p_FmHc = (t_FmHc*)h_FmHc;
+ return p_FmHc->h_HcPortDev;
+}
diff --git a/drivers/net/ethernet/freescale/fman/Peripherals/FM/MAC/memac.c b/drivers/net/ethernet/freescale/fman/Peripherals/FM/MAC/memac.c
index 9169ff7..266716d 100644
--- a/drivers/net/ethernet/freescale/fman/Peripherals/FM/MAC/memac.c
+++ b/drivers/net/ethernet/freescale/fman/Peripherals/FM/MAC/memac.c
@@ -857,7 +857,7 @@ static t_Error MemacDumpRegs(t_Handle h_Memac)
/*****************************************************************************/
/* ......................................................................... */
-
+void *g_MemacRegs;
static t_Error MemacInit(t_Handle h_Memac)
{
t_Memac *p_Memac = (t_Memac *)h_Memac;
@@ -869,6 +869,9 @@ static t_Error MemacInit(t_Handle h_Memac)
e_FmMacType portType;
t_Error err;
+ if (p_Memac->macId == 3) /* This is a quick WA */
+ g_MemacRegs = p_Memac->p_MemMap;
+
SANITY_CHECK_RETURN_ERROR(p_Memac, E_INVALID_HANDLE);
SANITY_CHECK_RETURN_ERROR(p_Memac->p_MemacDriverParam, E_INVALID_STATE);
SANITY_CHECK_RETURN_ERROR(p_Memac->fmMacControllerDriver.h_Fm, E_INVALID_HANDLE);
diff --git a/drivers/net/ethernet/freescale/fman/Peripherals/FM/Pcd/fm_pcd.c b/drivers/net/ethernet/freescale/fman/Peripherals/FM/Pcd/fm_pcd.c
index 37ff0fd..ae87a36 100644
--- a/drivers/net/ethernet/freescale/fman/Peripherals/FM/Pcd/fm_pcd.c
+++ b/drivers/net/ethernet/freescale/fman/Peripherals/FM/Pcd/fm_pcd.c
@@ -2114,4 +2114,9 @@ t_Error FM_PCD_ModifyCounter(t_Handle h_FmPcd, e_FmPcdCounters counter, uint32_t
return E_OK;
}
+t_Handle FM_PCD_GetHcPort(t_Handle h_FmPcd)
+{
+ t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
+ return FmHcGetPort(p_FmPcd->h_Hc);
+}
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 7359001..a3fec5a 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
@@ -3143,7 +3143,6 @@ t_Error FM_PORT_Disable(t_Handle h_FmPort)
{
t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
int err;
-
SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE);
@@ -3166,13 +3165,10 @@ 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);
@@ -5354,6 +5350,7 @@ uint32_t* ARDesc;
void PrsEnable(t_Handle p_FmPcd);
void PrsDisable(t_Handle p_FmPcd);
int PrsIsEnabled(t_Handle p_FmPcd);
+t_Handle FM_PCD_GetHcPort(t_Handle h_FmPcd);
static t_Error DsarCheckParams(t_FmPortDsarParams *params, t_FmPortDsarTablesSizes *sizes)
{
@@ -5478,10 +5475,20 @@ static int fm_soc_suspend(void)
tmp32 = GET_UINT32(*fmclk);
WRITE_UINT32(*fmclk, SCFG_FMCLKDPSLPCR_DS_VAL);
tmp32 = GET_UINT32(*fmclk);
+ iounmap(fmclk);
return 0;
}
-t_FmPort *g_DsarFmPortRx, *g_DsarFmPortTx;
+void fm_clk_down(void)
+{
+ uint32_t *fmclk, tmp32;
+ fmclk = ioremap(SCFG_FMCLKDPSLPCR_ADDR, 4);
+ tmp32 = GET_UINT32(*fmclk);
+ WRITE_UINT32(*fmclk, SCFG_FMCLKDPSLPCR_DS_VAL | 0x40000000);
+ tmp32 = GET_UINT32(*fmclk);
+ iounmap(fmclk);
+}
+
t_Error FM_PORT_EnterDsar(t_Handle h_FmPortRx, t_FmPortDsarParams *params)
{
int i,j;
@@ -5493,6 +5500,7 @@ t_Error FM_PORT_EnterDsar(t_Handle h_FmPortRx, t_FmPortDsarParams *params)
t_DsarIcmpV4Descriptor* ICMPV4Descriptor;
t_DsarIcmpV6Descriptor* ICMPV6Descriptor;
t_DsarNdDescriptor* NDDescriptor;
+
uint64_t fmMuramVirtBaseAddr = (uint64_t)PTR_TO_UINT(XX_PhysToVirt(p_FmPort->fmMuramPhysBaseAddr));
uint32_t *param_page = XX_PhysToVirt(p_FmPort->fmMuramPhysBaseAddr + GET_UINT32(p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rgpr));
t_ArCommonDesc *ArCommonDescPtr = (t_ArCommonDesc*)(XX_PhysToVirt(p_FmPort->fmMuramPhysBaseAddr + GET_UINT32(*param_page)));
@@ -5503,9 +5511,6 @@ t_Error FM_PORT_EnterDsar(t_Handle h_FmPortRx, t_FmPortDsarParams *params)
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;
@@ -5789,28 +5794,31 @@ t_Error FM_PORT_EnterDsar(t_Handle h_FmPortRx, t_FmPortDsarParams *params)
}
-void FM_PORT_Dsar_enter_final(void)
+void FM_ChangeClock(t_Handle h_Fm, int hardwarePortId);
+t_Error FM_PORT_EnterDsarFinal(t_Handle h_DsarRxPort, t_Handle h_DsarTxPort)
{
- t_Handle *h_FmPcd;
- t_FmGetSetParams fmGetSetParams;
+ t_FmGetSetParams fmGetSetParams;
+ t_FmPort *p_FmPort = (t_FmPort *)h_DsarRxPort;
+ t_FmPort *p_FmPortTx = (t_FmPort *)h_DsarTxPort;
+ t_Handle *h_FmPcd = FmGetPcd(p_FmPort->h_Fm);
+ t_FmPort *p_FmPortHc = FM_PCD_GetHcPort(h_FmPcd);
+ memset(&fmGetSetParams, 0, sizeof (t_FmGetSetParams));
+ fmGetSetParams.setParams.type = UPDATE_FM_CLD;
+ FmGetSetParams(p_FmPort->h_Fm, &fmGetSetParams);
- t_FmPort *p_FmPort = g_DsarFmPortRx;
- t_FmPort *p_FmPortTx = g_DsarFmPortTx;
- // Issue graceful stop to HC port
- FM_PORT_Disable(opXX);
+ // Issue graceful stop to HC and DSAR Tx ports
+ FM_PORT_Disable(p_FmPortTx);
+ FM_PORT_Disable(p_FmPortHc);
// config tx port
p_FmPort->deepSleepVars.fmbm_tcfg = GET_UINT32(p_FmPortTx->p_FmPortBmiRegs->txPortBmiRegs.fmbm_tcfg);
- WRITE_UINT32(p_FmPortTx->p_FmPortBmiRegs->txPortBmiRegs.fmbm_tfdne, 0x005000C0);
WRITE_UINT32(p_FmPortTx->p_FmPortBmiRegs->txPortBmiRegs.fmbm_tcfg, GET_UINT32(p_FmPortTx->p_FmPortBmiRegs->txPortBmiRegs.fmbm_tcfg) | BMI_PORT_CFG_IM | BMI_PORT_CFG_EN);
// ????
p_FmPort->deepSleepVars.fmbm_tcmne = GET_UINT32(p_FmPortTx->p_FmPortBmiRegs->txPortBmiRegs.fmbm_tcmne);
WRITE_UINT32(p_FmPortTx->p_FmPortBmiRegs->txPortBmiRegs.fmbm_tcmne, 0xE);
// Stage 7:echo
- p_FmPort->deepSleepVars.fmbm_rfne = GET_UINT32(p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rfne);
- WRITE_UINT32(p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rfne, 0x440000);
p_FmPort->deepSleepVars.fmbm_rfpne = GET_UINT32(p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rfpne);
- h_FmPcd = FmGetPcd(p_FmPort->h_Fm);
+ WRITE_UINT32(p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rfpne, 0x2E);
if (!PrsIsEnabled(h_FmPcd))
{
p_FmPort->deepSleepVars.dsarEnabledParser = TRUE;
@@ -5818,12 +5826,18 @@ void FM_PORT_Dsar_enter_final(void)
}
else
p_FmPort->deepSleepVars.dsarEnabledParser = FALSE;
-
- WRITE_UINT32(p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rfpne, 0x2E);
+
+ p_FmPort->deepSleepVars.fmbm_rfne = GET_UINT32(p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rfne);
+ WRITE_UINT32(p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rfne, 0x440000);
// 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);
+ memset(&fmGetSetParams, 0, sizeof (t_FmGetSetParams));
+ fmGetSetParams.setParams.type = UPDATE_FPM_BRKC_SLP;
+ fmGetSetParams.setParams.sleep = 1;
+ FmGetSetParams(p_FmPort->h_Fm, &fmGetSetParams);
+
// ***** issue external request sync command
memset(&fmGetSetParams, 0, sizeof (t_FmGetSetParams));
fmGetSetParams.setParams.type = UPDATE_FPM_EXTC;
@@ -5857,9 +5871,12 @@ void FM_PORT_Dsar_enter_final(void)
FmGetSetParams(p_FmPort->h_Fm, &fmGetSetParams);
if (fmGetSetParams.getParams.fmqm_gs == 0 && fmGetSetParams.getParams.fm_npi == 0)
XX_Print("FM: Sleeping\n");
+// FM_ChangeClock(p_FmPort->h_Fm, p_FmPort->hardwarePortId);
+
+ return E_OK;
}
-EXPORT_SYMBOL(FM_PORT_Dsar_enter_final);
+EXPORT_SYMBOL(FM_PORT_EnterDsarFinal);
void FM_PORT_Dsar_DumpRegs()
{
@@ -5871,6 +5888,8 @@ void FM_PORT_ExitDsar(t_Handle h_FmPortRx, t_Handle h_FmPortTx)
{
t_FmPort *p_FmPort = (t_FmPort *)h_FmPortRx;
t_FmPort *p_FmPortTx = (t_FmPort *)h_FmPortTx;
+ t_Handle *h_FmPcd = FmGetPcd(p_FmPort->h_Fm);
+ t_FmPort *p_FmPortHc = FM_PCD_GetHcPort(h_FmPcd);
t_FmGetSetParams fmGetSetParams;
memset(&fmGetSetParams, 0, sizeof (t_FmGetSetParams));
fmGetSetParams.setParams.type = UPDATE_FPM_BRKC_SLP;
@@ -5880,11 +5899,6 @@ void FM_PORT_ExitDsar(t_Handle h_FmPortRx, t_Handle h_FmPortTx)
XX_Free(p_FmPort->deepSleepVars.autoResOffsets);
p_FmPort->deepSleepVars.autoResOffsets = 0;
}
- if (p_FmPort->deepSleepVars.autoResMaxSizes)
- {
- XX_Free(p_FmPort->deepSleepVars.autoResMaxSizes);
- p_FmPort->deepSleepVars.autoResMaxSizes = 0;
- }
if (p_FmPort->deepSleepVars.dsarEnabledParser)
PrsDisable(FmGetPcd(p_FmPort->h_Fm));
@@ -5894,7 +5908,8 @@ 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);
+ FM_PORT_Enable(p_FmPortTx);
+ FM_PORT_Enable(p_FmPortHc);
}
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 ccb6042..38cc89c 100644
--- a/drivers/net/ethernet/freescale/fman/Peripherals/FM/fm.c
+++ b/drivers/net/ethernet/freescale/fman/Peripherals/FM/fm.c
@@ -4185,7 +4185,16 @@ UNUSED(p_Fm);
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_FM_CLD)
+ {
+ WRITE_UINT32(p_Fm->p_FmFpmRegs->fm_cld, GET_UINT32(
+ p_Fm->p_FmFpmRegs->fm_cld) | 0x00000800);
+ }
+ if (p_Params->setParams.type & CLEAR_IRAM_READY)
+ {
+ t_FMIramRegs *p_Iram = (t_FMIramRegs *)UINT_TO_PTR(p_Fm->baseAddr + FM_MM_IMEM);
+ WRITE_UINT32(p_Iram->iready,GET_UINT32(p_Iram->iready) & ~IRAM_READY);
+ }
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)
@@ -4199,6 +4208,8 @@ t_Error FmGetSetParams(t_Handle h_Fm, t_FmGetSetParams *p_Params)
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_FM_CLD)
+ p_Params->getParams.fm_cld = GET_UINT32(p_Fm->p_FmFpmRegs->fm_cld);
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)
@@ -4242,7 +4253,7 @@ 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
+ if (pending & INTR_EN_WAKEUP) // this is a wake up from sleep interrupt
{
t_FmGetSetParams fmGetSetParams;
memset(&fmGetSetParams, 0, sizeof (t_FmGetSetParams));
@@ -5049,9 +5060,7 @@ t_Error FM_DumpRegs(t_Handle h_Fm)
{
t_Fm *p_Fm = (t_Fm *)h_Fm;
uint8_t i,j = 0;
-
DECLARE_DUMP;
-
SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
SANITY_CHECK_RETURN_ERROR(!p_Fm->p_FmDriverParam, E_INVALID_STATE);
SANITY_CHECK_RETURN_ERROR(((p_Fm->guestId == NCSW_MASTER_ID) ||
@@ -5245,4 +5254,25 @@ t_Handle FmGetPcd(t_Handle h_Fm)
{
return ((t_Fm*)h_Fm)->h_Pcd;
}
-
+extern void *g_MemacRegs;
+void fm_clk_down(void);
+uint32_t fman_memac_get_event(void *regs, uint32_t ev_mask);
+void FM_ChangeClock(t_Handle h_Fm, int hardwarePortId)
+{
+ int macId;
+ uint32_t event, rcr;
+ t_Fm *p_Fm = (t_Fm*)h_Fm;
+ rcr = GET_UINT32(p_Fm->p_FmFpmRegs->fm_rcr);
+ rcr |= 0x04000000;
+ WRITE_UINT32(p_Fm->p_FmFpmRegs->fm_rcr, rcr);
+
+ HW_PORT_ID_TO_SW_PORT_ID(macId, hardwarePortId);
+ do
+ {
+ event = fman_memac_get_event(g_MemacRegs, 0xFFFFFFFF);
+ } while ((event & 0x00000020) == 0);
+ fm_clk_down();
+ rcr = GET_UINT32(p_Fm->p_FmFpmRegs->fm_rcr);
+ rcr &= ~0x04000000;
+ WRITE_UINT32(p_Fm->p_FmFpmRegs->fm_rcr, rcr);
+}
diff --git a/drivers/net/ethernet/freescale/fman/Peripherals/FM/fm.h b/drivers/net/ethernet/freescale/fman/Peripherals/FM/fm.h
index 07431c3..ad391c8 100644
--- a/drivers/net/ethernet/freescale/fman/Peripherals/FM/fm.h
+++ b/drivers/net/ethernet/freescale/fman/Peripherals/FM/fm.h
@@ -425,6 +425,7 @@ switch (exception){ \
#define INTR_EN_QMI 0x40000000
#define INTR_EN_PRS 0x20000000
+#define INTR_EN_WAKEUP 0x10000000
#define INTR_EN_PLCR 0x08000000
#define INTR_EN_1G_MAC0 0x00080000
#define INTR_EN_1G_MAC1 0x00040000
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 00c5973..7343d6f 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
@@ -267,6 +267,7 @@ typedef struct {
uint32_t type;
uint32_t fmqm_gs;
uint32_t fm_npi;
+ uint32_t fm_cld;
uint32_t fmfp_extc;
} t_FmGetParams;
@@ -349,6 +350,9 @@ static __inline__ bool TRY_LOCK(t_Handle h_Spinlock, volatile bool *p_Flag)
#define GET_FMQM_GS 0x10000000
#define GET_FM_NPI 0x08000000
#define GET_FMFP_EXTC 0x04000000
+#define CLEAR_IRAM_READY 0x02000000
+#define UPDATE_FM_CLD 0x01000000
+#define GET_FM_CLD 0x00800000
#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 + \
diff --git a/drivers/net/ethernet/freescale/fman/Peripherals/FM/inc/fm_hc.h b/drivers/net/ethernet/freescale/fman/Peripherals/FM/inc/fm_hc.h
index f6a1bb2..099a238 100644
--- a/drivers/net/ethernet/freescale/fman/Peripherals/FM/inc/fm_hc.h
+++ b/drivers/net/ethernet/freescale/fman/Peripherals/FM/inc/fm_hc.h
@@ -85,6 +85,8 @@ t_Error FmHcPcdKgCcGetSetParams(t_Handle h_FmHc, t_Handle h_Scheme, uint32_
t_Error FmHcPcdPlcrCcGetSetParams(t_Handle h_FmHc,uint16_t absoluteProfileId, uint32_t requiredAction);
t_Error FmHcPcdSync(t_Handle h_FmHc);
+t_Handle FmHcGetPort(t_Handle h_FmHc);
+
diff --git a/drivers/net/ethernet/freescale/fman/inc/Peripherals/fm_port_ext.h b/drivers/net/ethernet/freescale/fman/inc/Peripherals/fm_port_ext.h
index 3a62b8d..3d5401c 100644
--- a/drivers/net/ethernet/freescale/fman/inc/Peripherals/fm_port_ext.h
+++ b/drivers/net/ethernet/freescale/fman/inc/Peripherals/fm_port_ext.h
@@ -1499,11 +1499,7 @@ typedef struct t_FmPortDsarParams
@Description Enter Deep Sleep Auto Response mode.
This function write the apropriate values to in the relevant
- tables in the MURAM. It then set the Tx port in independent
- mode as needed and redirect the receive flow to go through the
- Dsar Fman-ctrl code
-
- Calling this routine invalidates the descriptor.
+ tables in the MURAM.
@Param[in] h_FmPortRx - FM PORT module descriptor
@Param[in] params - Auto Response parameters
@@ -1515,6 +1511,23 @@ typedef struct t_FmPortDsarParams
t_Error FM_PORT_EnterDsar(t_Handle h_FmPortRx, t_FmPortDsarParams *params);
/**************************************************************************//**
+ @Function FM_PORT_EnterDsarFinal
+
+ @Description Enter Deep Sleep Auto Response mode.
+ This function sets the Tx port in independent mode as needed
+ and redirect the receive flow to go through the
+ Dsar Fman-ctrl code
+
+ @Param[in] h_DsarRxPort - FM Rx PORT module descriptor
+ @Param[in] h_DsarTxPort - FM Tx PORT module descriptor
+
+ @Return E_OK on success; Error code otherwise.
+
+ @Cautions Allowed only following FM_PORT_Init().
+*//***************************************************************************/
+t_Error FM_PORT_EnterDsarFinal(t_Handle h_DsarRxPort, t_Handle h_DsarTxPort);
+
+/**************************************************************************//**
@Function FM_PORT_ExitDsar
@Description Exit Deep Sleep Auto Response mode.
diff --git a/drivers/net/ethernet/freescale/fman/src/wrapper/lnxwrp_fm.c b/drivers/net/ethernet/freescale/fman/src/wrapper/lnxwrp_fm.c
index 600cbc5..e70c929 100755
--- a/drivers/net/ethernet/freescale/fman/src/wrapper/lnxwrp_fm.c
+++ b/drivers/net/ethernet/freescale/fman/src/wrapper/lnxwrp_fm.c
@@ -79,7 +79,8 @@
#include "lnxwrp_sysfs_fm.h"
#include "lnxwrp_sysfs_fm_port.h"
#include "lnxwrp_exp_sym.h"
-
+#include "fm_common.h"
+#include "../../fman/Peripherals/FM/fm.h"
#define __ERR_MODULE__ MODULE_FM
extern struct device_node *GetFmPortAdvArgsDevTreeNode (struct device_node *fm_node,
@@ -236,12 +237,17 @@ early_param(FSL_FM_RX_EXTRA_HEADROOM_BOOTARG, fm_set_rx_extra_headroom);
static irqreturn_t fm_irq(int irq, void *_dev)
{
t_LnxWrpFmDev *p_LnxWrpFmDev = (t_LnxWrpFmDev *)_dev;
-
+ t_Fm *p_Fm = (t_Fm*)p_LnxWrpFmDev->h_Dev;
if (!p_LnxWrpFmDev || !p_LnxWrpFmDev->h_Dev)
return IRQ_NONE;
+#ifdef CONFIG_PM_SLEEP
+ if (fman_get_normal_pending(p_Fm->p_FmFpmRegs) & INTR_EN_WAKEUP)
+ {
+ pm_wakeup_event(p_LnxWrpFmDev->dev, 200);
+ }
+#endif
FM_EventIsr(p_LnxWrpFmDev->h_Dev);
-
return IRQ_HANDLED;
}
@@ -1067,6 +1073,11 @@ static int /*__devinit*/ fm_probe(struct platform_device *of_dev)
return -EIO;
}
+#ifdef CONFIG_PM
+ device_set_wakeup_capable(p_LnxWrpFmDev->dev, true);
+ device_set_wakeup_enable(p_LnxWrpFmDev->dev, 1);
+#endif
+
DBG(TRACE, ("FM%d probed", p_LnxWrpFmDev->id));
return 0;
@@ -1114,38 +1125,45 @@ MODULE_DEVICE_TABLE(of, fm_match);
#define SCFG_FMCLKDPSLPCR_ADDR 0xFFE0FC00C
#define SCFG_FMCLKDPSLPCR_DS_VAL 0x48402000
#define SCFG_FMCLKDPSLPCR_NORMAL_VAL 0x00402000
-void FM_PORT_Dsar_enter_final(void);
-static bool started_ar_enter = false;
+
+struct device *g_fm_dev;
+
static int fm_soc_suspend(struct device *dev)
{
- if (started_ar_enter)
+ int err = 0;
+ t_LnxWrpFmDev *p_LnxWrpFmDev = dev_get_drvdata(get_device(dev));
+ g_fm_dev = dev;
+ if (p_LnxWrpFmDev->h_DsarRxPort)
{
uint32_t *fmclk;
#ifdef CONFIG_FSL_QORIQ_PM
fsl_set_power_except(dev,1);
#endif
- FM_PORT_Dsar_enter_final();
+ err = FM_PORT_EnterDsarFinal(p_LnxWrpFmDev->h_DsarRxPort,
+ p_LnxWrpFmDev->h_DsarTxPort);
fmclk = ioremap(SCFG_FMCLKDPSLPCR_ADDR, 4);
WRITE_UINT32(*fmclk, SCFG_FMCLKDPSLPCR_DS_VAL);
}
- return 0;
+ return err;
}
static int fm_soc_resume(struct device *dev)
{
- if (started_ar_enter)
+ t_LnxWrpFmDev *p_LnxWrpFmDev = dev_get_drvdata(get_device(dev));
+ if (p_LnxWrpFmDev->h_DsarRxPort)
{
uint32_t *fmclk;
fmclk = ioremap(SCFG_FMCLKDPSLPCR_ADDR, 4);
WRITE_UINT32(*fmclk, SCFG_FMCLKDPSLPCR_NORMAL_VAL);
- started_ar_enter = false;
+ p_LnxWrpFmDev->h_DsarRxPort = 0;
+ p_LnxWrpFmDev->h_DsarTxPort = 0;
}
return 0;
}
static const struct dev_pm_ops fm_pm_ops = {
- .suspend_noirq = fm_soc_suspend,
- .resume_noirq = fm_soc_resume,
+ .suspend = fm_soc_suspend,
+ .resume = fm_soc_resume,
};
#define FM_PM_OPS (&fm_pm_ops)
@@ -1379,14 +1397,15 @@ int fm_port_enter_autores_for_deepsleep(struct fm_port *port,
struct auto_res_port_params *params)
{
t_LnxWrpFmPortDev *p_LnxWrpFmPortDev = (t_LnxWrpFmPortDev *)port;
+ t_LnxWrpFmDev* p_LnxWrpFmDev = (t_LnxWrpFmDev*)p_LnxWrpFmPortDev->h_LnxWrpFmDev;
+ p_LnxWrpFmDev->h_DsarRxPort = p_LnxWrpFmPortDev->h_Dev;
+ p_LnxWrpFmDev->h_DsarTxPort = params->h_FmPortTx;
+
/*Register other under /proc/autoresponse */
if (WARN_ON(sizeof(t_FmPortDsarParams) != sizeof(struct auto_res_port_params)))
return -EFAULT;
FM_PORT_EnterDsar(p_LnxWrpFmPortDev->h_Dev, (t_FmPortDsarParams*)params);
-#ifdef CONFIG_PM
- started_ar_enter = true;
-#endif
return 0;
}
EXPORT_SYMBOL(fm_port_enter_autores_for_deepsleep);
@@ -1413,6 +1432,8 @@ EXPORT_SYMBOL(fm_port_get_autores_stats);
int fm_port_suspend(struct fm_port *port)
{
t_LnxWrpFmPortDev *p_LnxWrpFmPortDev = (t_LnxWrpFmPortDev *)port;
+ if (p_LnxWrpFmPortDev->id == 3)
+ return 0;
if (!FM_PORT_IsInDsar(p_LnxWrpFmPortDev->h_Dev))
return FM_PORT_Disable(p_LnxWrpFmPortDev->h_Dev);
else
diff --git a/drivers/net/ethernet/freescale/fman/src/wrapper/lnxwrp_fm.h b/drivers/net/ethernet/freescale/fman/src/wrapper/lnxwrp_fm.h
index 9c657ac..05202a2 100644
--- a/drivers/net/ethernet/freescale/fman/src/wrapper/lnxwrp_fm.h
+++ b/drivers/net/ethernet/freescale/fman/src/wrapper/lnxwrp_fm.h
@@ -217,6 +217,9 @@ typedef struct {
t_Handle h_PcdDev;
t_Handle h_RtcDev;
+ t_Handle h_DsarRxPort;
+ t_Handle h_DsarTxPort;
+
t_LnxWrpFmPortDev hcPort;
t_LnxWrpFmPortDev opPorts[FM_MAX_NUM_OF_OH_PORTS-1];
t_LnxWrpFmPortDev rxPorts[FM_MAX_NUM_OF_RX_PORTS];