I am looking for a simple example of how to power up the PFE sub system and setting up the appropriate clocks. I have a driver that I have written that should work on a native A53 (no Linux). The clocks never come up. I know that prior to me working on this logic I could not get the PFE registers to even read now they read but not everything is working and I have traced it down to this.
Here is the basic code to init the subsystem (this is very fragmented and not clearly explain by NXP) so any source example would be appreciated.
pfe_init(void)
{
/* Enable */
/* Setup DMA coherency */
volatile uint32_t tries;
RDC.RD2_CTRL_REG.B.RD2_CTRL_UNLOCK = 1;
RDC.RD2_CTRL_REG.B.RD2_INTERCONNECT_INTERFACE_DISABLE = 0;
tries = 0;
while (RDC.RD2_STAT_REG.B.RD2_INTERCONNECT_INTERFACE_DISABLE_REQ_ACK_STAT != 0 )
{
tries++;
if (tries > MAX_TRIES)
{
break;
}
}
tries = 0;
while (RDC.RD2_STAT_REG.B.RD2_INTERCONNECT_INTERFACE_DISABLE_STAT != 0)
{
tries++;
if (tries > MAX_TRIES)
{
break;
}
}
/**((volatile unsigned int *)0x4007ca00) = 0x3f; */
S32G_GPR.PFE_COH_EN.B.DDR = true;
S32G_GPR.PFE_COH_EN.B.HIF0 = true;
S32G_GPR.PFE_COH_EN.B.HIF1 = true;
S32G_GPR.PFE_COH_EN.B.HIF2 = true;
S32G_GPR.PFE_COH_EN.B.HIF3 = true;
S32G_GPR.PFE_COH_EN.B.UTIL = true;
/* Setup EMAC modes -RGMII (ALL PFES)*/
S32G_GPR.PFE_EMACX_INTF_SEL.B.EMAC0 = 2;
S32G_GPR.PFE_EMACX_INTF_SEL.B.EMAC1 = 2;
S32G_GPR.PFE_EMACX_INTF_SEL.B.EMAC2 = 2;
/* Enable power for PFE */
S32G_GPR.PFE_PWR_CTRL.B.PWRACK = 0;
S32G_GPR.PFE_PWR_CTRL.B.PWRCLAMP = 0;
S32G_GPR.PFE_PWR_CTRL.B.PWRDWN = 0;
S32G_GPR.PFE_PWR_CTRL.B.PWRISO = 0;
S32G_GPR.GENCTRL1.B.CTRL = 1;
/* Setup & Enable the PFE Sys Clock */
/* Setup and Enable the PFE PE Clock */
S32G_GPR.LLCE_CTRL.B.EXEVENT = 0;
S32G_GPR.LLCE_CTRL.B.LINDIVSEL = 0;
S32G_GPR.LLCE_CTRL.B.LLCE_HTM0_TRC_DIS = 0;
S32G_GPR.LLCE_CTRL.B.LLCE_HTM1_TRC_DIS = 0;
S32G_GPR.LLCE_CTRL.B.LLCE_LSPI_TRIG_IN = 0;
S32G_GPR.LLCE_CTRL.B.PFE_2_LLCE_INT_HS_BP = 0;
S32G_GPR.GENCTRL1.B.CTRL = 1;
/* Setup EMAC Tx/RX clocks */
S32G_GPR.GENCTRL0.B.ACCEL_FLXNC_RD0_IDLEREQ = 0; /* normal operation */
S32G_GPR.GENCTRL0.B.ACCEL_FLXNC_REF_DIV = 0; /* Divide by 2 */
S32G_GPR.GENCTRL0.B.USBPWRFLT = 0;
tries = 0;
do {
MC_ME.PRTN2_COFB0_CLKEN.B.REQ0 = 1;
MC_ME.PRTN2_COFB0_CLKEN.B.REQ1 = 1;
MC_ME.PRTN2_COFB0_CLKEN.B.REQ2 = 1;
MC_ME.PRTN2_COFB0_CLKEN.B.REQ3 = 1;
Write_Control_Key();
MC_ME.PRTN2_PCONF.B.OSSE = 1;
MC_ME.PRTN2_PCONF.B.PCE = 1;
MC_ME.PRTN2_PUPD.B.OSSUD = 1;
MC_ME.PRTN2_PUPD.B.PCUD = 1;
/* Tell hardware to check above registers for changes */
Write_Control_Key();
tries++;
if (tries > MAX_TRIES)
{
break; /* code dies here - the clocks never get enabled
therefore it does not come out of reset */
}
} while (MC_ME.PRTN2_COFB0_STAT.R != 0xf);
/* Put PFE in reset */
MC_RGM.PRST_0[2].PRST_0.B.PERIPH_0_RST = 1;
tries = 0;
while (MC_RGM.PSTAT_0[2].PSTAT_0.B.PERIPH_0_STAT != 1)
{
tries++;
if (tries > MAX_TRIES)
{
break;
}
}
tries = 0;
do {
S32G_GPR.GENCTRL1.B.CTRL = 0;
/* Take the PFE out of reset */
MC_RGM.PRST_0[2].PRST_0.B.PERIPH_0_RST = 0;
MC_ME.PRTN2_PCONF.B.OSSE = 1;
MC_ME.PRTN2_PCONF.B.PCE = 1;
MC_ME.PRTN2_PUPD.B.OSSUD = 1;
MC_ME.PRTN2_PUPD.B.PCUD = 1;
/* Tell hardware to check above registers for changes */
Write_Control_Key();
tries++;
if (tries > MAX_TRIES)
{
break;
}
} while (MC_RGM.PSTAT_0[2].PSTAT_0.B.PERIPH_0_STAT == 1);
MC_ME.PRTN2_PCONF.B.OSSE = 0;
MC_ME.PRTN2_PCONF.B.PCE = 1;
MC_ME.PRTN2_PUPD.B.OSSUD = 1;
MC_ME.PRTN2_PUPD.B.PCUD = 1;
/* Tell hardware to check above registers for changes */
Write_Control_Key();
tries = 0;
while (MC_RGM.PSTAT_0[2].PSTAT_0.B.PERIPH_0_STAT != 0)
{
tries++;
if (tries > MAX_TRIES)
{
break;
}
}
}